⚡ Upgrade design & moved backend here & login and settings work with api
This commit is contained in:
@@ -0,0 +1,71 @@
|
|||||||
|
import { NextRequest, NextResponse } from 'next/server';
|
||||||
|
import { getDBConnexion } from '../../utils';
|
||||||
|
import { compareSync } from 'bcrypt';
|
||||||
|
|
||||||
|
type RequestBody = {
|
||||||
|
username?: string;
|
||||||
|
password?: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const POST = async (req: NextRequest) => {
|
||||||
|
const { username, password }: RequestBody = await req.json();
|
||||||
|
|
||||||
|
if (!username || !password) {
|
||||||
|
return NextResponse.json(
|
||||||
|
{
|
||||||
|
error: true,
|
||||||
|
message: 'Missing username or password field in request body',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
status: 400,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const pool = getDBConnexion();
|
||||||
|
|
||||||
|
const { rows } = await pool.query(
|
||||||
|
`SELECT * FROM "user" WHERE "username"=$1 LIMIT 1;`,
|
||||||
|
[username]
|
||||||
|
);
|
||||||
|
|
||||||
|
await pool.end();
|
||||||
|
|
||||||
|
if (rows.length != 1) {
|
||||||
|
return NextResponse.json({
|
||||||
|
error: true,
|
||||||
|
message: 'User not found',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const { id, password: hashedPassword } = rows[0];
|
||||||
|
|
||||||
|
if (!compareSync(password, hashedPassword)) {
|
||||||
|
return NextResponse.json(
|
||||||
|
{
|
||||||
|
error: true,
|
||||||
|
message: 'Wrong password',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
status: 403,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return NextResponse.json({
|
||||||
|
token: id,
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
return NextResponse.json(
|
||||||
|
{
|
||||||
|
error: true,
|
||||||
|
message: 'Internal error',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
status: 500,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -0,0 +1,285 @@
|
|||||||
|
import { NextRequest, NextResponse } from 'next/server';
|
||||||
|
import { getDBConnexion } from '../utils';
|
||||||
|
import { compareSync, hashSync } from 'bcrypt';
|
||||||
|
|
||||||
|
export const GET = async (req: NextRequest) => {
|
||||||
|
const userID = req.headers.get('Authorization');
|
||||||
|
|
||||||
|
if (!userID) {
|
||||||
|
return NextResponse.json(
|
||||||
|
{
|
||||||
|
error: true,
|
||||||
|
message: 'Unauthorized request',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
status: 403,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const pool = getDBConnexion();
|
||||||
|
|
||||||
|
const { rows } = await pool.query(
|
||||||
|
`SELECT * FROM "user" WHERE "id"=$1 LIMIT 1;`,
|
||||||
|
[userID]
|
||||||
|
);
|
||||||
|
|
||||||
|
if (rows.length != 1) {
|
||||||
|
return NextResponse.json(
|
||||||
|
{
|
||||||
|
error: true,
|
||||||
|
message: 'User not found',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
status: 404,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
await pool.end();
|
||||||
|
|
||||||
|
return NextResponse.json(rows[0]);
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
return NextResponse.json(
|
||||||
|
{
|
||||||
|
error: true,
|
||||||
|
message: 'Internal error',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
status: 500,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
type RequestBody = {
|
||||||
|
type?: 'username' | 'password';
|
||||||
|
username?: string;
|
||||||
|
currentPassword?: string;
|
||||||
|
newPassword?: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const PUT = async (req: NextRequest) => {
|
||||||
|
const userID = req.headers.get('Authorization');
|
||||||
|
|
||||||
|
const { type, username, currentPassword, newPassword }: RequestBody =
|
||||||
|
await req.json();
|
||||||
|
|
||||||
|
if (!userID) {
|
||||||
|
return NextResponse.json(
|
||||||
|
{
|
||||||
|
error: true,
|
||||||
|
message: 'Unauthorized request',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
status: 403,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!type) {
|
||||||
|
return NextResponse.json(
|
||||||
|
{
|
||||||
|
error: true,
|
||||||
|
message: 'Missing type field in request body',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
status: 400,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type == 'username') {
|
||||||
|
if (!username) {
|
||||||
|
return NextResponse.json(
|
||||||
|
{
|
||||||
|
error: true,
|
||||||
|
message: 'Missing username field in request body',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
status: 400,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const pool = getDBConnexion();
|
||||||
|
|
||||||
|
const { rowCount } = await pool.query(
|
||||||
|
`SELECT COUNT(*) FROM "user" WHERE "username"=$1 LIMIT 1;`,
|
||||||
|
[username]
|
||||||
|
);
|
||||||
|
|
||||||
|
if (rowCount > 0) {
|
||||||
|
return NextResponse.json(
|
||||||
|
{
|
||||||
|
error: true,
|
||||||
|
message: 'Username already used',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
status: 409,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const { rows } = await pool.query(
|
||||||
|
`SELECT * FROM "user" WHERE "id"=$1 LIMIT 1;`,
|
||||||
|
[userID]
|
||||||
|
);
|
||||||
|
|
||||||
|
if (rows.length != 1) {
|
||||||
|
return NextResponse.json(
|
||||||
|
{
|
||||||
|
error: true,
|
||||||
|
message: 'User not found',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
status: 404,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
await pool.query(`UPDATE "user" SET "username"=$1 WHERE "id"=$2;`, [
|
||||||
|
username,
|
||||||
|
userID,
|
||||||
|
]);
|
||||||
|
|
||||||
|
await pool.end();
|
||||||
|
|
||||||
|
return NextResponse.json({
|
||||||
|
message: 'Successfully updated username',
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
return NextResponse.json(
|
||||||
|
{
|
||||||
|
error: true,
|
||||||
|
message: 'Internal error',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
status: 500,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type == 'password') {
|
||||||
|
if (!currentPassword || !newPassword) {
|
||||||
|
return NextResponse.json(
|
||||||
|
{
|
||||||
|
error: true,
|
||||||
|
message:
|
||||||
|
'Missing currentPassword and/or newPassword field(s) in request body',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
status: 400,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const pool = getDBConnexion();
|
||||||
|
|
||||||
|
const { rows } = await pool.query(
|
||||||
|
`SELECT * FROM "user" WHERE "id"=$1 LIMIT 1;`,
|
||||||
|
[userID]
|
||||||
|
);
|
||||||
|
|
||||||
|
if (rows.length != 1) {
|
||||||
|
return NextResponse.json(
|
||||||
|
{
|
||||||
|
error: true,
|
||||||
|
message: 'User not found',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
status: 404,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const { password: currentHashedPassword } = rows[0];
|
||||||
|
|
||||||
|
if (!compareSync(currentPassword, currentHashedPassword)) {
|
||||||
|
return NextResponse.json(
|
||||||
|
{
|
||||||
|
error: true,
|
||||||
|
message: 'Wrong password',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
status: 403,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const newHashedPassword = hashSync(newPassword, 10);
|
||||||
|
|
||||||
|
await pool.query(`UPDATE "user" SET "password"=$1 WHERE "id"=$2`, [
|
||||||
|
newHashedPassword,
|
||||||
|
userID,
|
||||||
|
]);
|
||||||
|
|
||||||
|
await pool.end();
|
||||||
|
|
||||||
|
return NextResponse.json({
|
||||||
|
message: 'Successfully updated password',
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
return NextResponse.json(
|
||||||
|
{
|
||||||
|
error: true,
|
||||||
|
message: 'Internal error',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
status: 500,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const DELETE = async (req: NextRequest) => {
|
||||||
|
const userID = req.headers.get('Authorization');
|
||||||
|
|
||||||
|
try {
|
||||||
|
const pool = getDBConnexion();
|
||||||
|
|
||||||
|
const { rows } = await pool.query(
|
||||||
|
`SELECT * FROM "user" WHERE "id"=$1 LIMIT 1;`,
|
||||||
|
[userID]
|
||||||
|
);
|
||||||
|
|
||||||
|
if (rows.length != 1) {
|
||||||
|
return NextResponse.json(
|
||||||
|
{
|
||||||
|
error: true,
|
||||||
|
message: 'User not found',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
status: 404,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
await pool.query(`DELETE FROM "user" WHERE "id"=$1 LIMIT 1;`, [userID]);
|
||||||
|
|
||||||
|
await pool.end();
|
||||||
|
|
||||||
|
return NextResponse.json({
|
||||||
|
message: 'Successfully delete user',
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
return NextResponse.json(
|
||||||
|
{
|
||||||
|
error: true,
|
||||||
|
message: 'Internal error',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
status: 500,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
import { createPool } from '@vercel/postgres';
|
||||||
|
|
||||||
|
export const getDBConnexion = () => {
|
||||||
|
const pool = createPool({
|
||||||
|
connectionString: process.env.POSTGRES_URL,
|
||||||
|
});
|
||||||
|
|
||||||
|
return pool;
|
||||||
|
};
|
||||||
@@ -17,9 +17,7 @@ export const useActions = ({ setError, setIsLoading }) => {
|
|||||||
|
|
||||||
setIsLoading(true);
|
setIsLoading(true);
|
||||||
try {
|
try {
|
||||||
const request = await fetch(
|
const request = await fetch('/api/auth/login', {
|
||||||
'https://lovemap-backend.vercel.app/auth/login',
|
|
||||||
{
|
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
@@ -28,8 +26,7 @@ export const useActions = ({ setError, setIsLoading }) => {
|
|||||||
username,
|
username,
|
||||||
password,
|
password,
|
||||||
}),
|
}),
|
||||||
}
|
});
|
||||||
);
|
|
||||||
|
|
||||||
const response = await request.json();
|
const response = await request.json();
|
||||||
|
|
||||||
@@ -44,7 +41,6 @@ export const useActions = ({ setError, setIsLoading }) => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (request.status == 500) {
|
if (request.status == 500) {
|
||||||
console.log('request.status: ', request.status);
|
|
||||||
setError('Erreur interne. Veuillez réessayer');
|
setError('Erreur interne. Veuillez réessayer');
|
||||||
setIsLoading(false);
|
setIsLoading(false);
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ import { useActions } from './hooks/useActions';
|
|||||||
|
|
||||||
// ------------------------------------------------- Assets & Styles ---------------------------------------------------
|
// ------------------------------------------------- Assets & Styles ---------------------------------------------------
|
||||||
import Loader from '@/assets/Loader';
|
import Loader from '@/assets/Loader';
|
||||||
import '../styles.scss';
|
import './styles.scss';
|
||||||
// ---------------------------------------------------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
const Login = () => {
|
const Login = () => {
|
||||||
|
|||||||
@@ -39,7 +39,7 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: stretch;
|
align-items: stretch;
|
||||||
gap: 15px;
|
gap: 20px;
|
||||||
|
|
||||||
& > .error {
|
& > .error {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
+1
-1
@@ -18,7 +18,7 @@ body {
|
|||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
width: 100svw;
|
width: 100svw;
|
||||||
height: 100svh;
|
height: 100svh;
|
||||||
background-color: #d94253;
|
background-color: #ffffff;
|
||||||
}
|
}
|
||||||
|
|
||||||
a {
|
a {
|
||||||
|
|||||||
@@ -1,21 +0,0 @@
|
|||||||
import { Inter } from 'next/font/google';
|
|
||||||
import Provider from './provider';
|
|
||||||
import './globals.scss';
|
|
||||||
|
|
||||||
const inter = Inter({ subsets: ['latin'] });
|
|
||||||
|
|
||||||
export const metadata = {
|
|
||||||
title: 'Lovemap ❤️',
|
|
||||||
};
|
|
||||||
|
|
||||||
const RootLayout = ({ children }) => {
|
|
||||||
return (
|
|
||||||
<html lang='fr'>
|
|
||||||
<body className={inter.className}>
|
|
||||||
<Provider>{children}</Provider>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default RootLayout;
|
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
// ---------------------------------------------------------------------------------------------------------------------
|
||||||
|
//! Imports
|
||||||
|
// ---------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// ------------------------------------------------------ Next ---------------------------------------------------------
|
||||||
|
import { Metadata } from 'next';
|
||||||
|
// ---------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// --------------------------------------------------- Components ------------------------------------------------------
|
||||||
|
import Provider from './provider';
|
||||||
|
// ---------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// ------------------------------------------------- Assets & Styles ---------------------------------------------------
|
||||||
|
import { Inter } from 'next/font/google';
|
||||||
|
import './globals.scss';
|
||||||
|
// ---------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
const inter = Inter({ subsets: ['latin'] });
|
||||||
|
|
||||||
|
export const metadata: Metadata = {
|
||||||
|
title: 'Lovemap ❤️',
|
||||||
|
robots: 'none',
|
||||||
|
};
|
||||||
|
|
||||||
|
const RootLayout = ({ children }) => {
|
||||||
|
return (
|
||||||
|
<html lang='fr'>
|
||||||
|
<body className={inter.className}>
|
||||||
|
<Provider>{children}</Provider>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default RootLayout;
|
||||||
@@ -0,0 +1,159 @@
|
|||||||
|
// ---------------------------------------------------------------------------------------------------------------------
|
||||||
|
//! Imports
|
||||||
|
// ---------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// -------------------------------------------------- Hooks & Utils ----------------------------------------------------
|
||||||
|
import { useRouter } from 'next/navigation';
|
||||||
|
import { FormEvent } from 'react';
|
||||||
|
// ---------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
export const useActions = ({
|
||||||
|
userData,
|
||||||
|
setIsPopupDisplayed,
|
||||||
|
setUsernameMessage,
|
||||||
|
setPasswordMessage,
|
||||||
|
}) => {
|
||||||
|
const router = useRouter();
|
||||||
|
|
||||||
|
const resetMessage = () => {
|
||||||
|
setUsernameMessage(null);
|
||||||
|
setPasswordMessage(null);
|
||||||
|
};
|
||||||
|
|
||||||
|
const updateUsername = async (value: string) => {
|
||||||
|
resetMessage();
|
||||||
|
|
||||||
|
if (value == userData.username) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const token = localStorage.getItem('token');
|
||||||
|
|
||||||
|
try {
|
||||||
|
const request = await fetch('/api/user', {
|
||||||
|
method: 'PUT',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
Authorization: token,
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
type: 'username',
|
||||||
|
username: value,
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
if (request.status == 409) {
|
||||||
|
setUsernameMessage("Nom d'utilisateur déjà pris");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (request.status != 200) {
|
||||||
|
setUsernameMessage('Erreur interne. Veuillez réessayer');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setUsernameMessage("Nom d'utilisateur modifié");
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
|
||||||
|
setUsernameMessage('Erreur interne. Veuillez réessayer');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const updatePassword = async (ev: FormEvent<HTMLFormElement>) => {
|
||||||
|
ev.preventDefault();
|
||||||
|
|
||||||
|
if (!ev.currentTarget.reportValidity()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
resetMessage();
|
||||||
|
|
||||||
|
const formData = new FormData(ev.currentTarget);
|
||||||
|
const currentPassword = formData.get('currentPassword');
|
||||||
|
const newPassword = formData.get('newPassword');
|
||||||
|
const confirmNewPassword = formData.get('confirmNewPassword');
|
||||||
|
|
||||||
|
const token = localStorage.getItem('token');
|
||||||
|
|
||||||
|
if (newPassword != confirmNewPassword) {
|
||||||
|
setPasswordMessage('Les mots de passes ne correspondent pas');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const request = await fetch('/api/user', {
|
||||||
|
method: 'PUT',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
Authorization: token,
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
type: 'password',
|
||||||
|
currentPassword,
|
||||||
|
newPassword,
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
if (request.status == 403) {
|
||||||
|
setPasswordMessage('Mauvais mot de passe');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (request.status == 500) {
|
||||||
|
setPasswordMessage('Erreur interne. Veuillez réessayer');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setPasswordMessage('Mot de passe modifié');
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
|
||||||
|
setPasswordMessage('Erreur interne. Veuillez réessayer');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleClosePopup = (ev) => {
|
||||||
|
ev.stopPropagation();
|
||||||
|
setIsPopupDisplayed(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleDeleteUser = (ev) => {
|
||||||
|
ev.stopPropagation();
|
||||||
|
resetMessage();
|
||||||
|
setIsPopupDisplayed(true);
|
||||||
|
};
|
||||||
|
|
||||||
|
const deleteUser = async () => {
|
||||||
|
resetMessage();
|
||||||
|
const token = localStorage.getItem('token');
|
||||||
|
|
||||||
|
try {
|
||||||
|
const request = await fetch(
|
||||||
|
'https://lovemap-backend.vercel.app/user/delete',
|
||||||
|
{
|
||||||
|
method: 'DELETE',
|
||||||
|
headers: {
|
||||||
|
Authorization: token,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
if (request.status != 200) {
|
||||||
|
// setMessage('Erreur interne. Veuillez réessayer');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
localStorage.clear();
|
||||||
|
router.push('/auth/login');
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
// setMessage('Erreur interne. Veuillez réessayer');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
updateUsername,
|
||||||
|
updatePassword,
|
||||||
|
handleClosePopup,
|
||||||
|
handleDeleteUser,
|
||||||
|
deleteUser,
|
||||||
|
};
|
||||||
|
};
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
import { useEffect, useState } from 'react';
|
||||||
|
|
||||||
|
export const useData = () => {
|
||||||
|
const [userData, setUserData] = useState(null);
|
||||||
|
const [isPopupDisplayed, setIsPopupDisplayed] = useState(false);
|
||||||
|
const [usernameMessage, setUsernameMessage] = useState(null);
|
||||||
|
const [passwordMessage, setPasswordMessage] = useState(null);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
(async () => {
|
||||||
|
const token = localStorage.getItem('token');
|
||||||
|
|
||||||
|
const request = await fetch('/api/user', {
|
||||||
|
method: 'GET',
|
||||||
|
headers: {
|
||||||
|
Authorization: token,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const response = await request.json();
|
||||||
|
|
||||||
|
const formattedResponse = {
|
||||||
|
...response,
|
||||||
|
createdat: new Date(response.createdat).toLocaleDateString(
|
||||||
|
'fr-FR'
|
||||||
|
),
|
||||||
|
};
|
||||||
|
|
||||||
|
setUserData(formattedResponse);
|
||||||
|
})();
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return {
|
||||||
|
userData,
|
||||||
|
isPopupDisplayed,
|
||||||
|
setIsPopupDisplayed,
|
||||||
|
usernameMessage,
|
||||||
|
setUsernameMessage,
|
||||||
|
passwordMessage,
|
||||||
|
setPasswordMessage,
|
||||||
|
};
|
||||||
|
};
|
||||||
@@ -1,73 +0,0 @@
|
|||||||
// ---------------------------------------------------------------------------------------------------------------------
|
|
||||||
//! Imports
|
|
||||||
// ---------------------------------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
// --------------------------------------------------- Components ------------------------------------------------------
|
|
||||||
import Link from 'next/link';
|
|
||||||
import Input from '@/components/Input/Input';
|
|
||||||
// ---------------------------------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
// ------------------------------------------------- Assets & Styles ---------------------------------------------------
|
|
||||||
import ArrowRightIcon from '@/assets/ArrowRightIcon';
|
|
||||||
import './styles.scss';
|
|
||||||
// ---------------------------------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
const Settings = () => {
|
|
||||||
return (
|
|
||||||
<div className='settings'>
|
|
||||||
<div className='header'>
|
|
||||||
<Link
|
|
||||||
href={'/statistics'}
|
|
||||||
className='backButton'
|
|
||||||
>
|
|
||||||
<ArrowRightIcon
|
|
||||||
style={{
|
|
||||||
rotate: '180deg',
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</Link>
|
|
||||||
<p className='title'>Éditer le profil</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<form className='form'>
|
|
||||||
<Input
|
|
||||||
label="Nom d'utilisateur"
|
|
||||||
type='text'
|
|
||||||
name='username'
|
|
||||||
defaultValue='Un Épicier'
|
|
||||||
autoComplete='off'
|
|
||||||
required
|
|
||||||
/>
|
|
||||||
<Input
|
|
||||||
label='Mot de passe'
|
|
||||||
type='password'
|
|
||||||
name='password'
|
|
||||||
defaultValue='********'
|
|
||||||
autoComplete='off'
|
|
||||||
required
|
|
||||||
/>
|
|
||||||
|
|
||||||
<div className='buttonsContainer'>
|
|
||||||
<button
|
|
||||||
type='reset'
|
|
||||||
className='resetButton'
|
|
||||||
>
|
|
||||||
Annuler
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
type='submit'
|
|
||||||
className='submitButton'
|
|
||||||
>
|
|
||||||
Appliquer
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
|
|
||||||
<div className='separator' />
|
|
||||||
|
|
||||||
<button className='deleteButton'>Supprimer mon compte</button>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default Settings;
|
|
||||||
@@ -0,0 +1,187 @@
|
|||||||
|
'use client';
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------------------------------------------------
|
||||||
|
//! Imports
|
||||||
|
// ---------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// --------------------------------------------------- Components ------------------------------------------------------
|
||||||
|
import Link from 'next/link';
|
||||||
|
import Input from '@/components/Input/Input';
|
||||||
|
import InlineInput from '@/components/InlineInput/InlineInput';
|
||||||
|
// ---------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// -------------------------------------------------- Hooks & Utils ----------------------------------------------------
|
||||||
|
import { useData } from './hooks/useData';
|
||||||
|
import { useActions } from './hooks/useActions';
|
||||||
|
// ---------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// ------------------------------------------------- Assets & Styles ---------------------------------------------------
|
||||||
|
import ArrowRightIcon from '@/assets/ArrowRightIcon';
|
||||||
|
import TrashIcon from '@/assets/TrashIcon';
|
||||||
|
import CloseIcon from '@/assets/CloseIcon';
|
||||||
|
import CheckIcon from '@/assets/CheckIcon';
|
||||||
|
import './styles.scss';
|
||||||
|
// ---------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
const Settings = () => {
|
||||||
|
const {
|
||||||
|
userData,
|
||||||
|
isPopupDisplayed,
|
||||||
|
setIsPopupDisplayed,
|
||||||
|
usernameMessage,
|
||||||
|
setUsernameMessage,
|
||||||
|
passwordMessage,
|
||||||
|
setPasswordMessage,
|
||||||
|
} = useData();
|
||||||
|
|
||||||
|
const {
|
||||||
|
updateUsername,
|
||||||
|
updatePassword,
|
||||||
|
handleClosePopup,
|
||||||
|
handleDeleteUser,
|
||||||
|
deleteUser,
|
||||||
|
} = useActions({
|
||||||
|
userData,
|
||||||
|
setIsPopupDisplayed,
|
||||||
|
setUsernameMessage,
|
||||||
|
setPasswordMessage,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!userData) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className='settings'>
|
||||||
|
<div className='header'>
|
||||||
|
<Link
|
||||||
|
href={'/statistics'}
|
||||||
|
className='backButton'
|
||||||
|
>
|
||||||
|
<ArrowRightIcon
|
||||||
|
style={{
|
||||||
|
rotate: '180deg',
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</Link>
|
||||||
|
<p className='title'>Éditer le profil</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className='settingsContainer'>
|
||||||
|
{usernameMessage && (
|
||||||
|
<p className='message'>{usernameMessage}</p>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<InlineInput
|
||||||
|
label="Nom d'utilisateur"
|
||||||
|
type='text'
|
||||||
|
name='username'
|
||||||
|
placeholder="Nom d'utilisateur"
|
||||||
|
defaultValue={userData.username}
|
||||||
|
autoComplete='username'
|
||||||
|
onSubmit={updateUsername}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<div className='separator' />
|
||||||
|
|
||||||
|
<form
|
||||||
|
className='passwordForm'
|
||||||
|
onSubmit={updatePassword}
|
||||||
|
>
|
||||||
|
{passwordMessage && (
|
||||||
|
<p className='message'>{passwordMessage}</p>
|
||||||
|
)}
|
||||||
|
<Input
|
||||||
|
type='password'
|
||||||
|
name='currentPassword'
|
||||||
|
placeholder='Mot de passe actuel'
|
||||||
|
autoComplete='password'
|
||||||
|
required
|
||||||
|
/>
|
||||||
|
<Input
|
||||||
|
type='password'
|
||||||
|
name='newPassword'
|
||||||
|
placeholder='Nouveau mot de passe'
|
||||||
|
autoComplete='off'
|
||||||
|
required
|
||||||
|
/>
|
||||||
|
<Input
|
||||||
|
type='password'
|
||||||
|
name='confirmNewPassword'
|
||||||
|
placeholder='Confirmer le nouveau mot de passe'
|
||||||
|
autoComplete='off'
|
||||||
|
required
|
||||||
|
/>
|
||||||
|
|
||||||
|
<button
|
||||||
|
type='submit'
|
||||||
|
className='submitButton'
|
||||||
|
>
|
||||||
|
Appliquer
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<div className='separator'></div>
|
||||||
|
|
||||||
|
<button
|
||||||
|
className='deleteButton'
|
||||||
|
onClick={handleDeleteUser}
|
||||||
|
>
|
||||||
|
<TrashIcon />
|
||||||
|
Supprimer mon compte
|
||||||
|
</button>
|
||||||
|
|
||||||
|
{isPopupDisplayed && (
|
||||||
|
<div
|
||||||
|
className='popupOverlay'
|
||||||
|
onClick={handleClosePopup}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className='popup'
|
||||||
|
onClick={(ev) => ev.stopPropagation()}
|
||||||
|
>
|
||||||
|
<div className='popupHeader'>
|
||||||
|
<p className='popupTitle'>
|
||||||
|
Supprimer le compte ?
|
||||||
|
</p>
|
||||||
|
<button
|
||||||
|
className='popupCloseButton'
|
||||||
|
onClick={handleClosePopup}
|
||||||
|
>
|
||||||
|
<CloseIcon />
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div className='popupContent'>
|
||||||
|
<p>
|
||||||
|
Êtes-vous sûr de vouloir supprimer votre
|
||||||
|
compte ? Cette action est irréversible.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div className='popupButtonsContainer'>
|
||||||
|
<button
|
||||||
|
type='button'
|
||||||
|
className='popupButton'
|
||||||
|
onClick={handleClosePopup}
|
||||||
|
>
|
||||||
|
<CloseIcon />
|
||||||
|
Non
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<button
|
||||||
|
type='button'
|
||||||
|
className='popupButton'
|
||||||
|
onClick={deleteUser}
|
||||||
|
>
|
||||||
|
<CheckIcon />
|
||||||
|
Oui
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Settings;
|
||||||
+122
-43
@@ -4,7 +4,6 @@
|
|||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 20px;
|
gap: 20px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
background-color: #d94253;
|
|
||||||
|
|
||||||
& > .header {
|
& > .header {
|
||||||
display: grid;
|
display: grid;
|
||||||
@@ -12,6 +11,7 @@
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 15px;
|
gap: 15px;
|
||||||
padding: 15px;
|
padding: 15px;
|
||||||
|
background-color: #d94253;
|
||||||
color: #ffffff;
|
color: #ffffff;
|
||||||
box-shadow: 0 0 6px rgba(255, 255, 255, 0.2);
|
box-shadow: 0 0 6px rgba(255, 255, 255, 0.2);
|
||||||
|
|
||||||
@@ -26,68 +26,147 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
& > .form {
|
& > .settingsContainer {
|
||||||
display: grid;
|
flex-grow: 1;
|
||||||
grid-template-rows: repeat(2, 1fr);
|
position: relative;
|
||||||
align-items: center;
|
|
||||||
gap: 20px;
|
|
||||||
padding: 20px;
|
|
||||||
padding-bottom: 0;
|
|
||||||
|
|
||||||
& > .buttonsContainer {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: repeat(2, 1fr);
|
|
||||||
gap: 20px;
|
|
||||||
|
|
||||||
& > .submitButton,
|
|
||||||
& > .resetButton {
|
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
flex-direction: column;
|
||||||
align-items: center;
|
gap: 20px;
|
||||||
gap: 5px;
|
padding: 0 20px;
|
||||||
padding: 10px;
|
|
||||||
border: 1px solid #ffffff;
|
|
||||||
border-radius: 5px;
|
|
||||||
background-color: #ffffff;
|
|
||||||
font-size: 1rem;
|
|
||||||
color: #d94253;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
& > .resetButton {
|
& .message {
|
||||||
|
padding: 5px;
|
||||||
|
border-radius: 5px;
|
||||||
background-color: #d94253;
|
background-color: #d94253;
|
||||||
|
font-size: 1rem;
|
||||||
|
text-align: center;
|
||||||
color: #ffffff;
|
color: #ffffff;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
& > .separator {
|
& > .separator {
|
||||||
display: block;
|
display: block;
|
||||||
margin: 20px auto;
|
margin: 20px auto;
|
||||||
width: 90%;
|
width: 90%;
|
||||||
height: 1px;
|
height: 1px;
|
||||||
background-color: rgb(254, 254, 250);
|
background-color: #d94253;
|
||||||
background: linear-gradient(
|
background: linear-gradient(
|
||||||
90deg,
|
90deg,
|
||||||
rgba(254, 254, 250, 0) 0%,
|
rgba(#d94253, 0) 0%,
|
||||||
rgba(254, 254, 250, 1) 10%,
|
rgba(#d94253, 1) 10%,
|
||||||
rgba(254, 254, 250, 1) 90%,
|
rgba(#d94253, 1) 90%,
|
||||||
rgba(254, 254, 250, 0) 100%
|
rgba(#d94253, 0) 100%
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
& > .deleteButton {
|
& > .passwordForm {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
flex-direction: column;
|
||||||
align-items: center;
|
gap: 10px;
|
||||||
gap: 5px;
|
|
||||||
margin: 0 20px;
|
& > .submitButton {
|
||||||
padding: 10px;
|
padding: 7px 21px;
|
||||||
border: 1px solid #d80135;
|
border: none;
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
background-color: #d80135;
|
background-color: #d94253;
|
||||||
font-size: 1rem;
|
font-size: 1rem;
|
||||||
color: #ffffff;
|
color: #ffffff;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
& > .deleteButton {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 20px max-content;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
gap: 10px;
|
||||||
|
padding: 7px 21px;
|
||||||
|
border: 1px solid #d94253;
|
||||||
|
border-radius: 5px;
|
||||||
|
background-color: #d94253;
|
||||||
|
font-size: 1rem;
|
||||||
|
color: #ffffff;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
& > .popupOverlay {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background-color: rgba(#ffffff, 0.5);
|
||||||
|
backdrop-filter: blur(5px);
|
||||||
|
|
||||||
|
& > .popup {
|
||||||
|
z-index: 1;
|
||||||
|
position: relative;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
margin: 10px;
|
||||||
|
background-color: #ffffff;
|
||||||
|
border: 1px solid #d94253;
|
||||||
|
border-radius: 5px;
|
||||||
|
|
||||||
|
& > .popupHeader {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1fr 20px;
|
||||||
|
align-items: center;
|
||||||
|
gap: 20px;
|
||||||
|
padding: 10px;
|
||||||
|
|
||||||
|
& > .popupTitle {
|
||||||
|
font-size: 1.2rem;
|
||||||
|
color: #d94253;
|
||||||
|
}
|
||||||
|
|
||||||
|
& > .popupCloseButton {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
border: none;
|
||||||
|
border-radius: 5px;
|
||||||
|
background-color: transparent;
|
||||||
|
color: #d94253;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: background-color 0.3s ease;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: rgba(#d94253, 0.2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
& > .popupContent {
|
||||||
|
padding: 10px;
|
||||||
|
color: #d94253;
|
||||||
|
}
|
||||||
|
|
||||||
|
& > .popupButtonsContainer {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: nowrap;
|
||||||
|
justify-content: space-evenly;
|
||||||
|
align-items: center;
|
||||||
|
padding: 10px;
|
||||||
|
|
||||||
|
& > .popupButton {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 20px 1fr;
|
||||||
|
align-items: center;
|
||||||
|
gap: 5px;
|
||||||
|
padding: 5px 15px;
|
||||||
|
border: none;
|
||||||
|
border-radius: 5px;
|
||||||
|
background-color: #d94253;
|
||||||
|
font-size: 1rem;
|
||||||
|
color: #ffffff;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -7,21 +7,18 @@ export const useData = () => {
|
|||||||
(async () => {
|
(async () => {
|
||||||
const token = localStorage.getItem('token');
|
const token = localStorage.getItem('token');
|
||||||
|
|
||||||
const request = await fetch(
|
const request = await fetch('/api/user', {
|
||||||
'https://lovemap-backend.vercel.app/user',
|
|
||||||
{
|
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
headers: {
|
headers: {
|
||||||
Authorization: token,
|
Authorization: token,
|
||||||
},
|
},
|
||||||
}
|
});
|
||||||
);
|
|
||||||
|
|
||||||
const response = await request.json();
|
const response = await request.json();
|
||||||
|
|
||||||
const formattedResponse = {
|
const formattedResponse = {
|
||||||
...response.user,
|
...response,
|
||||||
createdat: new Date(response.user.createdat).toLocaleDateString(
|
createdat: new Date(response.createdat).toLocaleDateString(
|
||||||
'fr-FR'
|
'fr-FR'
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -10,21 +10,29 @@ import SlotCounter from 'react-slot-counter';
|
|||||||
// ---------------------------------------------------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
// -------------------------------------------------- Hooks & Utils ----------------------------------------------------
|
// -------------------------------------------------- Hooks & Utils ----------------------------------------------------
|
||||||
|
import { useRouter } from 'next/navigation';
|
||||||
import { useData } from './hooks/useData';
|
import { useData } from './hooks/useData';
|
||||||
// ---------------------------------------------------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
// ------------------------------------------------- Assets & Styles ---------------------------------------------------
|
// ------------------------------------------------- Assets & Styles ---------------------------------------------------
|
||||||
import SettingsIcon from '@/assets/SettingsIcon';
|
import SettingsIcon from '@/assets/SettingsIcon';
|
||||||
|
import { Logout } from '@/assets/Logout';
|
||||||
import './styles.scss';
|
import './styles.scss';
|
||||||
// ---------------------------------------------------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
const Statistics = () => {
|
const Statistics = () => {
|
||||||
|
const router = useRouter();
|
||||||
const { userData } = useData();
|
const { userData } = useData();
|
||||||
|
|
||||||
if (!userData) {
|
if (!userData) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const logout = () => {
|
||||||
|
localStorage.clear();
|
||||||
|
router.push('/auth/login');
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='accountContainer'>
|
<div className='accountContainer'>
|
||||||
<div className='header'>
|
<div className='header'>
|
||||||
@@ -33,13 +41,22 @@ const Statistics = () => {
|
|||||||
<p className='sinceDate'>Créé le: {userData.createdat}</p>
|
<p className='sinceDate'>Créé le: {userData.createdat}</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div className='buttonsContainer'>
|
||||||
|
<button
|
||||||
|
type='button'
|
||||||
|
className='button'
|
||||||
|
onClick={logout}
|
||||||
|
>
|
||||||
|
<Logout />
|
||||||
|
</button>
|
||||||
<Link
|
<Link
|
||||||
href={'/settings'}
|
href={'/settings'}
|
||||||
className='settingsButton'
|
className='button'
|
||||||
>
|
>
|
||||||
<SettingsIcon />
|
<SettingsIcon />
|
||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
<div className='separator' />
|
<div className='separator' />
|
||||||
<div className='statistics'>
|
<div className='statistics'>
|
||||||
<div className='statistic'>
|
<div className='statistic'>
|
||||||
@@ -48,7 +65,7 @@ const Statistics = () => {
|
|||||||
startValue={'00'}
|
startValue={'00'}
|
||||||
startValueOnce
|
startValueOnce
|
||||||
dummyCharacterCount={10}
|
dummyCharacterCount={10}
|
||||||
direction='top-bottom'
|
direction='top-down'
|
||||||
containerClassName='slotCounter'
|
containerClassName='slotCounter'
|
||||||
/>
|
/>
|
||||||
<p className='statName'>Loves par semaine</p>
|
<p className='statName'>Loves par semaine</p>
|
||||||
@@ -59,7 +76,7 @@ const Statistics = () => {
|
|||||||
startValue={'00'}
|
startValue={'00'}
|
||||||
startValueOnce
|
startValueOnce
|
||||||
dummyCharacterCount={10}
|
dummyCharacterCount={10}
|
||||||
direction='top-bottom'
|
direction='top-down'
|
||||||
containerClassName='slotCounter'
|
containerClassName='slotCounter'
|
||||||
/>
|
/>
|
||||||
<p className='statName'>Loves par mois</p>
|
<p className='statName'>Loves par mois</p>
|
||||||
@@ -70,7 +87,7 @@ const Statistics = () => {
|
|||||||
startValue={'00'}
|
startValue={'00'}
|
||||||
startValueOnce
|
startValueOnce
|
||||||
dummyCharacterCount={10}
|
dummyCharacterCount={10}
|
||||||
direction='top-bottom'
|
direction='top-down'
|
||||||
containerClassName='slotCounter'
|
containerClassName='slotCounter'
|
||||||
/>
|
/>
|
||||||
<p className='statName'>Loves par an</p>
|
<p className='statName'>Loves par an</p>
|
||||||
@@ -81,7 +98,7 @@ const Statistics = () => {
|
|||||||
startValue={'00'}
|
startValue={'00'}
|
||||||
startValueOnce
|
startValueOnce
|
||||||
dummyCharacterCount={10}
|
dummyCharacterCount={10}
|
||||||
direction='top-bottom'
|
direction='top-down'
|
||||||
containerClassName='slotCounter'
|
containerClassName='slotCounter'
|
||||||
/>
|
/>
|
||||||
<p className='statName'>Loves total</p>
|
<p className='statName'>Loves total</p>
|
||||||
+21
-42
@@ -21,21 +21,31 @@
|
|||||||
|
|
||||||
& > .username {
|
& > .username {
|
||||||
font-size: 1.1rem;
|
font-size: 1.1rem;
|
||||||
color: #ffffff;
|
color: #d94253;
|
||||||
}
|
}
|
||||||
|
|
||||||
& > .sinceDate {
|
& > .sinceDate {
|
||||||
font-size: 0.9rem;
|
font-size: 0.9rem;
|
||||||
font-weight: 300;
|
font-weight: 300;
|
||||||
color: #eee;
|
color: #d94253;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
& > .settingsButton {
|
& > .buttonsContainer {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: nowrap;
|
||||||
|
align-items: center;
|
||||||
|
gap: 10px;
|
||||||
|
|
||||||
|
& > .button {
|
||||||
$size: 25px;
|
$size: 25px;
|
||||||
width: $size;
|
width: $size;
|
||||||
height: $size;
|
height: $size;
|
||||||
color: #ffffff;
|
border: none;
|
||||||
|
background-color: transparent;
|
||||||
|
color: #d94253;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -43,13 +53,13 @@
|
|||||||
display: block;
|
display: block;
|
||||||
width: 90%;
|
width: 90%;
|
||||||
height: 1px;
|
height: 1px;
|
||||||
background-color: rgb(254, 254, 250);
|
background-color: #d94253;
|
||||||
background: linear-gradient(
|
background: linear-gradient(
|
||||||
90deg,
|
90deg,
|
||||||
rgba(254, 254, 250, 0) 0%,
|
rgba(#d94253, 0) 0%,
|
||||||
rgba(254, 254, 250, 1) 10%,
|
rgba(#d94253, 1) 10%,
|
||||||
rgba(254, 254, 250, 1) 90%,
|
rgba(#d94253, 1) 90%,
|
||||||
rgba(254, 254, 250, 0) 100%
|
rgba(#d94253, 0) 100%
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -68,45 +78,14 @@
|
|||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
font-weight: 300;
|
font-weight: 300;
|
||||||
color: #ffffff;
|
color: #d94253;
|
||||||
|
|
||||||
& > .slotCounter {
|
& > .slotCounter {
|
||||||
font-size: 3rem;
|
font-size: 3rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
& > .statName {
|
& > .statName {
|
||||||
color: #eee;
|
color: #d94253;
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
& > .buttonsContainer {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: stretch;
|
|
||||||
gap: 2px;
|
|
||||||
width: 100%;
|
|
||||||
box-shadow: 0 0 6px rgba(255, 255, 255, 0.2);
|
|
||||||
|
|
||||||
& > .button {
|
|
||||||
display: flex;
|
|
||||||
flex-wrap: nowrap;
|
|
||||||
justify-content: space-between;
|
|
||||||
gap: 20px;
|
|
||||||
padding: 15px 20px;
|
|
||||||
border: none;
|
|
||||||
background-color: #d94253;
|
|
||||||
font-size: 1rem;
|
|
||||||
color: #ffffff;
|
|
||||||
filter: brightness(1.1);
|
|
||||||
transition: filter 0.3s ease;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
filter: brightness(1.3);
|
|
||||||
}
|
|
||||||
|
|
||||||
& > svg {
|
|
||||||
width: 1.2em;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
const ArrowRightIcon = (props) => {
|
import { SVGProps } from 'react';
|
||||||
|
|
||||||
|
const ArrowRightIcon = (props?: SVGProps<SVGSVGElement>) => {
|
||||||
return (
|
return (
|
||||||
<svg
|
<svg
|
||||||
xmlns='http://www.w3.org/2000/svg'
|
xmlns='http://www.w3.org/2000/svg'
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
import { SVGProps } from 'react';
|
||||||
|
|
||||||
|
const CheckIcon = (props: SVGProps<SVGSVGElement>) => {
|
||||||
|
return (
|
||||||
|
<svg
|
||||||
|
xmlns='http://www.w3.org/2000/svg'
|
||||||
|
viewBox='0 0 512 512'
|
||||||
|
{...props}
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
fill='none'
|
||||||
|
stroke='currentColor'
|
||||||
|
strokeLinecap='round'
|
||||||
|
strokeLinejoin='round'
|
||||||
|
strokeWidth='32'
|
||||||
|
d='M416 128L192 384l-96-96'
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default CheckIcon;
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
import { SVGProps } from 'react';
|
||||||
|
|
||||||
|
const CloseIcon = (props: SVGProps<SVGSVGElement>) => {
|
||||||
|
return (
|
||||||
|
<svg
|
||||||
|
xmlns='http://www.w3.org/2000/svg'
|
||||||
|
viewBox='0 0 512 512'
|
||||||
|
{...props}
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
fill='none'
|
||||||
|
stroke='currentColor'
|
||||||
|
strokeLinecap='round'
|
||||||
|
strokeLinejoin='round'
|
||||||
|
strokeWidth='32'
|
||||||
|
d='M368 368L144 144M368 144L144 368'
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default CloseIcon;
|
||||||
@@ -1,4 +1,6 @@
|
|||||||
const EyeIcon = (props) => {
|
import { SVGProps } from 'react';
|
||||||
|
|
||||||
|
const EyeIcon = (props?: SVGProps<SVGSVGElement>) => {
|
||||||
return (
|
return (
|
||||||
<svg
|
<svg
|
||||||
xmlns='http://www.w3.org/2000/svg'
|
xmlns='http://www.w3.org/2000/svg'
|
||||||
@@ -1,10 +1,12 @@
|
|||||||
const EyeSlashIcon = (props) => {
|
import { SVGProps } from 'react';
|
||||||
|
|
||||||
|
const EyeSlashIcon = (props?: SVGProps<SVGSVGElement>) => {
|
||||||
return (
|
return (
|
||||||
<svg
|
<svg
|
||||||
xmlns='http://www.w3.org/2000/svg'
|
xmlns='http://www.w3.org/2000/svg'
|
||||||
viewBox='0 0 512 512'
|
viewBox='0 0 512 512'
|
||||||
{...props}
|
|
||||||
fill='currentColor'
|
fill='currentColor'
|
||||||
|
{...props}
|
||||||
>
|
>
|
||||||
<path d='M432 448a15.92 15.92 0 01-11.31-4.69l-352-352a16 16 0 0122.62-22.62l352 352A16 16 0 01432 448zM255.66 384c-41.49 0-81.5-12.28-118.92-36.5-34.07-22-64.74-53.51-88.7-91v-.08c19.94-28.57 41.78-52.73 65.24-72.21a2 2 0 00.14-2.94L93.5 161.38a2 2 0 00-2.71-.12c-24.92 21-48.05 46.76-69.08 76.92a31.92 31.92 0 00-.64 35.54c26.41 41.33 60.4 76.14 98.28 100.65C162 402 207.9 416 255.66 416a239.13 239.13 0 0075.8-12.58 2 2 0 00.77-3.31l-21.58-21.58a4 4 0 00-3.83-1 204.8 204.8 0 01-51.16 6.47zM490.84 238.6c-26.46-40.92-60.79-75.68-99.27-100.53C349 110.55 302 96 255.66 96a227.34 227.34 0 00-74.89 12.83 2 2 0 00-.75 3.31l21.55 21.55a4 4 0 003.88 1 192.82 192.82 0 0150.21-6.69c40.69 0 80.58 12.43 118.55 37 34.71 22.4 65.74 53.88 89.76 91a.13.13 0 010 .16 310.72 310.72 0 01-64.12 72.73 2 2 0 00-.15 2.95l19.9 19.89a2 2 0 002.7.13 343.49 343.49 0 0068.64-78.48 32.2 32.2 0 00-.1-34.78z' />
|
<path d='M432 448a15.92 15.92 0 01-11.31-4.69l-352-352a16 16 0 0122.62-22.62l352 352A16 16 0 01432 448zM255.66 384c-41.49 0-81.5-12.28-118.92-36.5-34.07-22-64.74-53.51-88.7-91v-.08c19.94-28.57 41.78-52.73 65.24-72.21a2 2 0 00.14-2.94L93.5 161.38a2 2 0 00-2.71-.12c-24.92 21-48.05 46.76-69.08 76.92a31.92 31.92 0 00-.64 35.54c26.41 41.33 60.4 76.14 98.28 100.65C162 402 207.9 416 255.66 416a239.13 239.13 0 0075.8-12.58 2 2 0 00.77-3.31l-21.58-21.58a4 4 0 00-3.83-1 204.8 204.8 0 01-51.16 6.47zM490.84 238.6c-26.46-40.92-60.79-75.68-99.27-100.53C349 110.55 302 96 255.66 96a227.34 227.34 0 00-74.89 12.83 2 2 0 00-.75 3.31l21.55 21.55a4 4 0 003.88 1 192.82 192.82 0 0150.21-6.69c40.69 0 80.58 12.43 118.55 37 34.71 22.4 65.74 53.88 89.76 91a.13.13 0 010 .16 310.72 310.72 0 01-64.12 72.73 2 2 0 00-.15 2.95l19.9 19.89a2 2 0 002.7.13 343.49 343.49 0 0068.64-78.48 32.2 32.2 0 00-.1-34.78z' />
|
||||||
<path d='M256 160a95.88 95.88 0 00-21.37 2.4 2 2 0 00-1 3.38l112.59 112.56a2 2 0 003.38-1A96 96 0 00256 160zM165.78 233.66a2 2 0 00-3.38 1 96 96 0 00115 115 2 2 0 001-3.38z' />
|
<path d='M256 160a95.88 95.88 0 00-21.37 2.4 2 2 0 00-1 3.38l112.59 112.56a2 2 0 003.38-1A96 96 0 00256 160zM165.78 233.66a2 2 0 00-3.38 1 96 96 0 00115 115 2 2 0 001-3.38z' />
|
||||||
@@ -1,4 +1,6 @@
|
|||||||
const HeartIcon = (props) => {
|
import { SVGProps } from 'react';
|
||||||
|
|
||||||
|
const HeartIcon = (props?: SVGProps<SVGSVGElement>) => {
|
||||||
return (
|
return (
|
||||||
<svg
|
<svg
|
||||||
xmlns='http://www.w3.org/2000/svg'
|
xmlns='http://www.w3.org/2000/svg'
|
||||||
@@ -1,4 +1,6 @@
|
|||||||
const Loader = (props) => {
|
import { SVGProps } from 'react';
|
||||||
|
|
||||||
|
const Loader = (props?: SVGProps<SVGSVGElement>) => {
|
||||||
return (
|
return (
|
||||||
<svg
|
<svg
|
||||||
viewBox='0 0 57 57'
|
viewBox='0 0 57 57'
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
import { SVGProps } from 'react';
|
||||||
|
|
||||||
|
export const Logout = (props?: SVGProps<SVGSVGElement>) => {
|
||||||
|
return (
|
||||||
|
<svg
|
||||||
|
xmlns='http://www.w3.org/2000/svg'
|
||||||
|
viewBox='0 0 512 512'
|
||||||
|
{...props}
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d='M304 336v40a40 40 0 01-40 40H104a40 40 0 01-40-40V136a40 40 0 0140-40h152c22.09 0 48 17.91 48 40v40M368 336l80-80-80-80M176 256h256'
|
||||||
|
fill='none'
|
||||||
|
stroke='currentColor'
|
||||||
|
strokeLinecap='round'
|
||||||
|
strokeLinejoin='round'
|
||||||
|
strokeWidth='32'
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
);
|
||||||
|
};
|
||||||
@@ -1,4 +1,6 @@
|
|||||||
const MapIcon = (props) => {
|
import { SVGProps } from 'react';
|
||||||
|
|
||||||
|
const MapIcon = (props?: SVGProps<SVGSVGElement>) => {
|
||||||
return (
|
return (
|
||||||
<svg
|
<svg
|
||||||
xmlns='http://www.w3.org/2000/svg'
|
xmlns='http://www.w3.org/2000/svg'
|
||||||
@@ -1,4 +1,6 @@
|
|||||||
const SettingsIcon = (props) => {
|
import { SVGProps } from 'react';
|
||||||
|
|
||||||
|
const SettingsIcon = (props?: SVGProps<SVGSVGElement>) => {
|
||||||
return (
|
return (
|
||||||
<svg
|
<svg
|
||||||
xmlns='http://www.w3.org/2000/svg'
|
xmlns='http://www.w3.org/2000/svg'
|
||||||
@@ -1,4 +1,6 @@
|
|||||||
const StatsIcon = (props) => {
|
import { SVGProps } from 'react';
|
||||||
|
|
||||||
|
const StatsIcon = (props?: SVGProps<SVGSVGElement>) => {
|
||||||
return (
|
return (
|
||||||
<svg
|
<svg
|
||||||
xmlns='http://www.w3.org/2000/svg'
|
xmlns='http://www.w3.org/2000/svg'
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
import { SVGProps } from 'react';
|
||||||
|
|
||||||
|
const TrashIcon = (props: SVGProps<SVGSVGElement>) => {
|
||||||
|
return (
|
||||||
|
<svg
|
||||||
|
xmlns='http://www.w3.org/2000/svg'
|
||||||
|
viewBox='0 0 512 512'
|
||||||
|
{...props}
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d='M112 112l20 320c.95 18.49 14.4 32 32 32h184c17.67 0 30.87-13.51 32-32l20-320'
|
||||||
|
fill='none'
|
||||||
|
stroke='currentColor'
|
||||||
|
strokeLinecap='round'
|
||||||
|
strokeLinejoin='round'
|
||||||
|
strokeWidth='32'
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
stroke='currentColor'
|
||||||
|
strokeLinecap='round'
|
||||||
|
stroke-miterlimit='10'
|
||||||
|
strokeWidth='32'
|
||||||
|
d='M80 112h352'
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
d='M192 112V72h0a23.93 23.93 0 0124-24h80a23.93 23.93 0 0124 24h0v40M256 176v224M184 176l8 224M328 176l-8 224'
|
||||||
|
fill='none'
|
||||||
|
stroke='currentColor'
|
||||||
|
strokeLinecap='round'
|
||||||
|
strokeLinejoin='round'
|
||||||
|
strokeWidth='32'
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default TrashIcon;
|
||||||
@@ -0,0 +1,80 @@
|
|||||||
|
'use client';
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------------------------------------------------
|
||||||
|
//! Imports
|
||||||
|
// ---------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// ------------------------------------------------------ React --------------------------------------------------------
|
||||||
|
import { FormEvent } from 'react';
|
||||||
|
// ---------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// ------------------------------------------------- Assets & Styles ---------------------------------------------------
|
||||||
|
import CheckIcon from '@/assets/CheckIcon';
|
||||||
|
import CloseIcon from '@/assets/CloseIcon';
|
||||||
|
import './styles.scss';
|
||||||
|
// ---------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
const InlineInput = ({
|
||||||
|
label = '',
|
||||||
|
name = '',
|
||||||
|
type = 'text',
|
||||||
|
placeholder = '',
|
||||||
|
defaultValue = '',
|
||||||
|
autoComplete = 'off',
|
||||||
|
onSubmit = (value?: string) => {},
|
||||||
|
}) => {
|
||||||
|
const handleSubmit = (ev: FormEvent<HTMLFormElement>) => {
|
||||||
|
ev.preventDefault();
|
||||||
|
|
||||||
|
if (!ev.currentTarget.reportValidity()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const formData = new FormData(ev.currentTarget);
|
||||||
|
|
||||||
|
const value = formData.get(name);
|
||||||
|
|
||||||
|
onSubmit(value ? value.toString() : null);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<form
|
||||||
|
className='inlineInputContainer'
|
||||||
|
onSubmit={handleSubmit}
|
||||||
|
>
|
||||||
|
<label
|
||||||
|
htmlFor={name}
|
||||||
|
className='inlineInputLabel'
|
||||||
|
>
|
||||||
|
{label}
|
||||||
|
</label>
|
||||||
|
|
||||||
|
<div className='inlineInputRow'>
|
||||||
|
<input
|
||||||
|
type={type}
|
||||||
|
name={name}
|
||||||
|
id={name}
|
||||||
|
defaultValue={defaultValue}
|
||||||
|
placeholder={placeholder}
|
||||||
|
autoComplete={autoComplete}
|
||||||
|
className='inlineInput'
|
||||||
|
required
|
||||||
|
/>
|
||||||
|
<button
|
||||||
|
type='reset'
|
||||||
|
className='inlineInputButton'
|
||||||
|
>
|
||||||
|
<CloseIcon />
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
type='submit'
|
||||||
|
className='inlineInputButton'
|
||||||
|
>
|
||||||
|
<CheckIcon />
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default InlineInput;
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
.inlineInputContainer {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 5px;
|
||||||
|
|
||||||
|
& > .inlineInputLabel {
|
||||||
|
margin-left: 5px;
|
||||||
|
font-size: 1.1rem;
|
||||||
|
color: #d94253;
|
||||||
|
}
|
||||||
|
|
||||||
|
& > .inlineInputRow {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1fr repeat(2, calc(1rem + 14px));
|
||||||
|
align-items: center;
|
||||||
|
gap: 5px;
|
||||||
|
|
||||||
|
& > .inlineInput {
|
||||||
|
padding: 7px 14px;
|
||||||
|
border: 1px solid #d94253;
|
||||||
|
border-radius: 5px;
|
||||||
|
background-color: #f5cfd3;
|
||||||
|
outline: none;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
color: #d94253;
|
||||||
|
outline: none;
|
||||||
|
|
||||||
|
&::placeholder {
|
||||||
|
color: #d94253;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
& > .inlineInputButton {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
padding: 5px;
|
||||||
|
border: none;
|
||||||
|
border-radius: 5px;
|
||||||
|
background-color: transparent;
|
||||||
|
color: #d94253;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: background-color 0.3s ease;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: rgba(#d94253, 0.5);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -5,7 +5,7 @@
|
|||||||
// ---------------------------------------------------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
// ------------------------------------------------------ React --------------------------------------------------------
|
// ------------------------------------------------------ React --------------------------------------------------------
|
||||||
import { forwardRef, useState } from 'react';
|
import { forwardRef, MouseEvent, useState } from 'react';
|
||||||
// ---------------------------------------------------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
// ------------------------------------------------- Assets & Styles ---------------------------------------------------
|
// ------------------------------------------------- Assets & Styles ---------------------------------------------------
|
||||||
@@ -14,75 +14,51 @@ import EyeIcon from '@/assets/EyeIcon';
|
|||||||
import './styles.scss';
|
import './styles.scss';
|
||||||
// ---------------------------------------------------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
const Input = forwardRef(function InputComponent(
|
const Input = ({
|
||||||
{
|
name = '',
|
||||||
type = 'text',
|
type = '',
|
||||||
label,
|
placeholder = '',
|
||||||
name,
|
defaultValue = '',
|
||||||
value,
|
|
||||||
defaultValue,
|
|
||||||
autoComplete,
|
|
||||||
required = false,
|
required = false,
|
||||||
onChange,
|
autoComplete = 'off',
|
||||||
onKeyUp,
|
}) => {
|
||||||
onKeyDown,
|
const [isPasswordVisible, setIsPasswordVisible] = useState(false);
|
||||||
},
|
|
||||||
ref
|
|
||||||
) {
|
|
||||||
const [isFocused, setIsFocused] = useState(
|
|
||||||
defaultValue || value ? true : false
|
|
||||||
);
|
|
||||||
const [passwordVisibility, setPasswordVisibility] = useState(false);
|
|
||||||
|
|
||||||
const defaultOnBlur = (ev) => {
|
const togglePasswordVisibility = (ev: MouseEvent) => {
|
||||||
if (ev.currentTarget.value != '') {
|
ev.stopPropagation();
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
setIsFocused(false);
|
setIsPasswordVisible((prev) => !prev);
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='inputContainer'>
|
<div className='inputContainer'>
|
||||||
<input
|
<input
|
||||||
ref={ref}
|
|
||||||
type={
|
type={
|
||||||
type == 'password'
|
type == 'password'
|
||||||
? passwordVisibility
|
? isPasswordVisible
|
||||||
? 'text'
|
? 'text'
|
||||||
: 'password'
|
: 'password'
|
||||||
: type
|
: type
|
||||||
}
|
}
|
||||||
name={name}
|
name={name}
|
||||||
id={name}
|
id={name}
|
||||||
value={value}
|
placeholder={placeholder}
|
||||||
defaultValue={defaultValue}
|
defaultValue={defaultValue}
|
||||||
autoComplete={autoComplete}
|
autoComplete={autoComplete}
|
||||||
required={required}
|
required={required}
|
||||||
onChange={onChange}
|
|
||||||
onKeyUp={onKeyUp}
|
|
||||||
onKeyDown={onKeyDown}
|
|
||||||
className='input'
|
className='input'
|
||||||
onFocus={() => setIsFocused(true)}
|
|
||||||
onBlur={defaultOnBlur}
|
|
||||||
/>
|
/>
|
||||||
<label
|
|
||||||
htmlFor={name}
|
|
||||||
className={`inputLabel ${isFocused ? 'focused' : ''}`}
|
|
||||||
>
|
|
||||||
{label}
|
|
||||||
</label>
|
|
||||||
{type == 'password' && (
|
{type == 'password' && (
|
||||||
<button
|
<button
|
||||||
type='button'
|
type='button'
|
||||||
className='passwordToggleButton'
|
className='passwordToggleButton'
|
||||||
onClick={() => setPasswordVisibility((prev) => !prev)}
|
onClick={togglePasswordVisibility}
|
||||||
>
|
>
|
||||||
{passwordVisibility ? <EyeSlashIcon /> : <EyeIcon />}
|
{isPasswordVisible ? <EyeSlashIcon /> : <EyeIcon />}
|
||||||
</button>
|
</button>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
});
|
};
|
||||||
|
|
||||||
export default Input;
|
export default Input;
|
||||||
@@ -2,35 +2,19 @@
|
|||||||
position: relative;
|
position: relative;
|
||||||
font-size: 1.1rem;
|
font-size: 1.1rem;
|
||||||
|
|
||||||
& > .inputLabel {
|
|
||||||
position: absolute;
|
|
||||||
top: 48%;
|
|
||||||
left: 10px;
|
|
||||||
transform: translateY(-50%);
|
|
||||||
padding: 0 4px;
|
|
||||||
background-color: #d94253;
|
|
||||||
font-size: 1em;
|
|
||||||
font-weight: 300;
|
|
||||||
color: #ffffff;
|
|
||||||
transition: top 0.3s ease, font-size 0.3s ease;
|
|
||||||
pointer-events: none;
|
|
||||||
|
|
||||||
&.focused {
|
|
||||||
top: 0;
|
|
||||||
font-size: 0.8em;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
& > .input {
|
& > .input {
|
||||||
padding: 10px 20px;
|
padding: 7px 14px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
border: 1px solid #ffffff;
|
border: 1px solid #d94253;
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
background-color: #d94253;
|
background-color: #f5cfd3;
|
||||||
font-size: 1em;
|
font-size: 0.9rem;
|
||||||
font-weight: 300;
|
color: #d94253;
|
||||||
color: #ffffff;
|
|
||||||
outline: none;
|
outline: none;
|
||||||
|
|
||||||
|
&::placeholder {
|
||||||
|
color: #d94253;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
& > .passwordToggleButton {
|
& > .passwordToggleButton {
|
||||||
@@ -45,6 +29,6 @@
|
|||||||
height: 100%;
|
height: 100%;
|
||||||
border: none;
|
border: none;
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
color: #ffffff;
|
color: #d94253;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,34 +0,0 @@
|
|||||||
'use client';
|
|
||||||
|
|
||||||
import Link from 'next/link';
|
|
||||||
import config from './config';
|
|
||||||
import './styles.scss';
|
|
||||||
import { usePathname } from 'next/navigation';
|
|
||||||
|
|
||||||
const Navbar = () => {
|
|
||||||
const pathname = usePathname();
|
|
||||||
|
|
||||||
return (
|
|
||||||
<nav
|
|
||||||
className='navbar'
|
|
||||||
style={{
|
|
||||||
gridTemplateColumns: `repeat(${config.length}, 1fr)`,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{config.map((element) => (
|
|
||||||
<Link
|
|
||||||
key={element.title}
|
|
||||||
href={element.link}
|
|
||||||
className={`navButton ${
|
|
||||||
element.link == pathname ? 'selected' : ''
|
|
||||||
}`}
|
|
||||||
>
|
|
||||||
{element.icon()}
|
|
||||||
<span className='navButtonLabel'>{element.title}</span>
|
|
||||||
</Link>
|
|
||||||
))}
|
|
||||||
</nav>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default Navbar;
|
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
'use client';
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------------------------------------------------
|
||||||
|
//! Imports
|
||||||
|
// ---------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// --------------------------------------------------- Components ------------------------------------------------------
|
||||||
|
import Link from 'next/link';
|
||||||
|
// ---------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// -------------------------------------------------- Hooks & Utils ----------------------------------------------------
|
||||||
|
import { usePathname } from 'next/navigation';
|
||||||
|
import config from './config';
|
||||||
|
// ---------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// ------------------------------------------------- Assets & Styles ---------------------------------------------------
|
||||||
|
import './styles.scss';
|
||||||
|
// ---------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
const Navbar = () => {
|
||||||
|
const pathname = usePathname();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<nav
|
||||||
|
className='navbar'
|
||||||
|
style={{
|
||||||
|
gridTemplateColumns: `repeat(${config.length}, 1fr)`,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{config.map((element) => (
|
||||||
|
<Link
|
||||||
|
key={element.title}
|
||||||
|
href={element.link}
|
||||||
|
className={`navButton ${
|
||||||
|
element.link == pathname ? 'selected' : ''
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
{element.icon()}
|
||||||
|
<span className='navButtonLabel'>{element.title}</span>
|
||||||
|
</Link>
|
||||||
|
))}
|
||||||
|
</nav>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Navbar;
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
{
|
|
||||||
"compilerOptions": {
|
|
||||||
"paths": {
|
|
||||||
"@/*": ["./*"]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Generated
+528
-10
@@ -11,6 +11,8 @@
|
|||||||
"@capacitor/android": "^6.1.2",
|
"@capacitor/android": "^6.1.2",
|
||||||
"@capacitor/cli": "^6.1.2",
|
"@capacitor/cli": "^6.1.2",
|
||||||
"@capacitor/core": "^6.1.2",
|
"@capacitor/core": "^6.1.2",
|
||||||
|
"@vercel/postgres": "^0.10.0",
|
||||||
|
"bcrypt": "^5.1.1",
|
||||||
"deck.gl": "^9.0.28",
|
"deck.gl": "^9.0.28",
|
||||||
"mapbox-gl": "^3.6.0",
|
"mapbox-gl": "^3.6.0",
|
||||||
"next": "14.2.7",
|
"next": "14.2.7",
|
||||||
@@ -20,6 +22,8 @@
|
|||||||
"react-slot-counter": "^3.0.1"
|
"react-slot-counter": "^3.0.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@types/bcrypt": "^5.0.2",
|
||||||
|
"@types/react": "18.3.10",
|
||||||
"eslint": "^8",
|
"eslint": "^8",
|
||||||
"eslint-config-next": "14.2.7",
|
"eslint-config-next": "14.2.7",
|
||||||
"sass": "^1.77.8"
|
"sass": "^1.77.8"
|
||||||
@@ -1369,6 +1373,26 @@
|
|||||||
"integrity": "sha512-7hFhtkb0KTLEls+TRw/rWayq5EeHtTaErgm/NskVoXmtgAQu/9D299aeyj6mzAR/6XUnYRp2lU+4IcrYRFjVsQ==",
|
"integrity": "sha512-7hFhtkb0KTLEls+TRw/rWayq5EeHtTaErgm/NskVoXmtgAQu/9D299aeyj6mzAR/6XUnYRp2lU+4IcrYRFjVsQ==",
|
||||||
"license": "ISC"
|
"license": "ISC"
|
||||||
},
|
},
|
||||||
|
"node_modules/@mapbox/node-pre-gyp": {
|
||||||
|
"version": "1.0.11",
|
||||||
|
"resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.11.tgz",
|
||||||
|
"integrity": "sha512-Yhlar6v9WQgUp/He7BdgzOz8lqMQ8sU+jkCq7Wx8Myc5YFJLbEe7lgui/V7G1qB1DJykHSGwreceSaD60Y0PUQ==",
|
||||||
|
"license": "BSD-3-Clause",
|
||||||
|
"dependencies": {
|
||||||
|
"detect-libc": "^2.0.0",
|
||||||
|
"https-proxy-agent": "^5.0.0",
|
||||||
|
"make-dir": "^3.1.0",
|
||||||
|
"node-fetch": "^2.6.7",
|
||||||
|
"nopt": "^5.0.0",
|
||||||
|
"npmlog": "^5.0.1",
|
||||||
|
"rimraf": "^3.0.2",
|
||||||
|
"semver": "^7.3.5",
|
||||||
|
"tar": "^6.1.11"
|
||||||
|
},
|
||||||
|
"bin": {
|
||||||
|
"node-pre-gyp": "bin/node-pre-gyp"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@mapbox/point-geometry": {
|
"node_modules/@mapbox/point-geometry": {
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/@mapbox/point-geometry/-/point-geometry-0.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@mapbox/point-geometry/-/point-geometry-0.1.0.tgz",
|
||||||
@@ -1487,6 +1511,15 @@
|
|||||||
"integrity": "sha512-eJ0nDw8140kJorf8ASyKRC53rI+UG6vPxpsKJiGRD6lXsoKTeKYebeEAXiGDWTvi2AMe6+xngxTqqwm58fL3Fw==",
|
"integrity": "sha512-eJ0nDw8140kJorf8ASyKRC53rI+UG6vPxpsKJiGRD6lXsoKTeKYebeEAXiGDWTvi2AMe6+xngxTqqwm58fL3Fw==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/@neondatabase/serverless": {
|
||||||
|
"version": "0.9.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/@neondatabase/serverless/-/serverless-0.9.5.tgz",
|
||||||
|
"integrity": "sha512-siFas6gItqv6wD/pZnvdu34wEqgG3nSE6zWZdq5j2DEsa+VvX8i/5HXJOo06qrw5axPXn+lGCxeR+NLaSPIXug==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@types/pg": "8.11.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@next/env": {
|
"node_modules/@next/env": {
|
||||||
"version": "14.2.7",
|
"version": "14.2.7",
|
||||||
"resolved": "https://registry.npmjs.org/@next/env/-/env-14.2.7.tgz",
|
"resolved": "https://registry.npmjs.org/@next/env/-/env-14.2.7.tgz",
|
||||||
@@ -1837,6 +1870,16 @@
|
|||||||
"@turf/meta": "^5.1.5"
|
"@turf/meta": "^5.1.5"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@types/bcrypt": {
|
||||||
|
"version": "5.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/bcrypt/-/bcrypt-5.0.2.tgz",
|
||||||
|
"integrity": "sha512-6atioO8Y75fNcbmj0G7UjI9lXN2pQ/IGJ2FWT4a/btd0Lk9lQalHLKhkgKVZ3r+spnmWUKfbMi1GEe9wyHQfNQ==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@types/node": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@types/brotli": {
|
"node_modules/@types/brotli": {
|
||||||
"version": "1.3.4",
|
"version": "1.3.4",
|
||||||
"resolved": "https://registry.npmjs.org/@types/brotli/-/brotli-1.3.4.tgz",
|
"resolved": "https://registry.npmjs.org/@types/brotli/-/brotli-1.3.4.tgz",
|
||||||
@@ -1993,6 +2036,35 @@
|
|||||||
"integrity": "sha512-j3pOPiEcWZ34R6a6mN07mUkM4o4Lwf6hPNt8eilOeZhTFbxFXmKhvXl9Y28jotFPaI1bpPDJsbCprUoNke6OrA==",
|
"integrity": "sha512-j3pOPiEcWZ34R6a6mN07mUkM4o4Lwf6hPNt8eilOeZhTFbxFXmKhvXl9Y28jotFPaI1bpPDJsbCprUoNke6OrA==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/@types/pg": {
|
||||||
|
"version": "8.11.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/pg/-/pg-8.11.6.tgz",
|
||||||
|
"integrity": "sha512-/2WmmBXHLsfRqzfHW7BNZ8SbYzE8OSk7i3WjFYvfgRHj7S1xj+16Je5fUKv3lVdVzk/zn9TXOqf+avFCFIE0yQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@types/node": "*",
|
||||||
|
"pg-protocol": "*",
|
||||||
|
"pg-types": "^4.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@types/prop-types": {
|
||||||
|
"version": "15.7.13",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.13.tgz",
|
||||||
|
"integrity": "sha512-hCZTSvwbzWGvhqxp/RqVqwU999pBf2vp7hzIjiYOsl8wqOmUxkQ6ddw1cV3l8811+kdUFus/q4d1Y3E3SyEifA==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/@types/react": {
|
||||||
|
"version": "18.3.10",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.10.tgz",
|
||||||
|
"integrity": "sha512-02sAAlBnP39JgXwkAq3PeU9DVaaGpZyF3MGcC0MKgQVkZor5IiiDAipVaxQHtDJAmO4GIy/rVBy/LzVj76Cyqg==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@types/prop-types": "*",
|
||||||
|
"csstype": "^3.0.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@types/slice-ansi": {
|
"node_modules/@types/slice-ansi": {
|
||||||
"version": "4.0.0",
|
"version": "4.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/@types/slice-ansi/-/slice-ansi-4.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/@types/slice-ansi/-/slice-ansi-4.0.0.tgz",
|
||||||
@@ -2348,6 +2420,20 @@
|
|||||||
"node": "^12.20.0 || ^14.13.1 || >=16.0.0"
|
"node": "^12.20.0 || ^14.13.1 || >=16.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@vercel/postgres": {
|
||||||
|
"version": "0.10.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@vercel/postgres/-/postgres-0.10.0.tgz",
|
||||||
|
"integrity": "sha512-fSD23DxGND40IzSkXjcFcxr53t3Tiym59Is0jSYIFpG4/0f0KO9SGtcp1sXiebvPaGe7N/tU05cH4yt2S6/IPg==",
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"dependencies": {
|
||||||
|
"@neondatabase/serverless": "^0.9.3",
|
||||||
|
"bufferutil": "^4.0.8",
|
||||||
|
"ws": "^8.17.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18.14"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@webcomponents/shadycss": {
|
"node_modules/@webcomponents/shadycss": {
|
||||||
"version": "1.11.2",
|
"version": "1.11.2",
|
||||||
"resolved": "https://registry.npmjs.org/@webcomponents/shadycss/-/shadycss-1.11.2.tgz",
|
"resolved": "https://registry.npmjs.org/@webcomponents/shadycss/-/shadycss-1.11.2.tgz",
|
||||||
@@ -2376,6 +2462,12 @@
|
|||||||
"node": ">=16.5.0"
|
"node": ">=16.5.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/abbrev": {
|
||||||
|
"version": "1.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
|
||||||
|
"integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==",
|
||||||
|
"license": "ISC"
|
||||||
|
},
|
||||||
"node_modules/acorn": {
|
"node_modules/acorn": {
|
||||||
"version": "8.12.1",
|
"version": "8.12.1",
|
||||||
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz",
|
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz",
|
||||||
@@ -2399,6 +2491,18 @@
|
|||||||
"acorn": "^6.0.0 || ^7.0.0 || ^8.0.0"
|
"acorn": "^6.0.0 || ^7.0.0 || ^8.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/agent-base": {
|
||||||
|
"version": "6.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
|
||||||
|
"integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"debug": "4"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 6.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/ajv": {
|
"node_modules/ajv": {
|
||||||
"version": "6.12.6",
|
"version": "6.12.6",
|
||||||
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
|
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
|
||||||
@@ -2454,6 +2558,40 @@
|
|||||||
"node": ">= 8"
|
"node": ">= 8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/aproba": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==",
|
||||||
|
"license": "ISC"
|
||||||
|
},
|
||||||
|
"node_modules/are-we-there-yet": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==",
|
||||||
|
"deprecated": "This package is no longer supported.",
|
||||||
|
"license": "ISC",
|
||||||
|
"dependencies": {
|
||||||
|
"delegates": "^1.0.0",
|
||||||
|
"readable-stream": "^3.6.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/are-we-there-yet/node_modules/readable-stream": {
|
||||||
|
"version": "3.6.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
|
||||||
|
"integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"inherits": "^2.0.3",
|
||||||
|
"string_decoder": "^1.1.1",
|
||||||
|
"util-deprecate": "^1.0.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 6"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/argparse": {
|
"node_modules/argparse": {
|
||||||
"version": "2.0.1",
|
"version": "2.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
|
||||||
@@ -2744,6 +2882,20 @@
|
|||||||
],
|
],
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/bcrypt": {
|
||||||
|
"version": "5.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/bcrypt/-/bcrypt-5.1.1.tgz",
|
||||||
|
"integrity": "sha512-AGBHOG5hPYZ5Xl9KXzU5iKq9516yEmvCKDg3ecP5kX2aB6UqTeXZxk2ELnDgDm6BQSMlLt9rDB4LoSMx0rYwww==",
|
||||||
|
"hasInstallScript": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@mapbox/node-pre-gyp": "^1.0.11",
|
||||||
|
"node-addon-api": "^5.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 10.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/big-integer": {
|
"node_modules/big-integer": {
|
||||||
"version": "1.6.52",
|
"version": "1.6.52",
|
||||||
"resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.52.tgz",
|
"resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.52.tgz",
|
||||||
@@ -2782,7 +2934,6 @@
|
|||||||
"version": "1.1.11",
|
"version": "1.1.11",
|
||||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
|
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
|
||||||
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
|
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"balanced-match": "^1.0.0",
|
"balanced-match": "^1.0.0",
|
||||||
@@ -2830,6 +2981,19 @@
|
|||||||
"node": "*"
|
"node": "*"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/bufferutil": {
|
||||||
|
"version": "4.0.8",
|
||||||
|
"resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.8.tgz",
|
||||||
|
"integrity": "sha512-4T53u4PdgsXqKaIctwF8ifXlRTTmEPJ8iEPWFdGZvcf7sbwYo6FKFEX9eNNAnzFZ7EzJAQ3CJeOtCRA4rDp7Pw==",
|
||||||
|
"hasInstallScript": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"node-gyp-build": "^4.3.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6.14.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/busboy": {
|
"node_modules/busboy": {
|
||||||
"version": "1.6.0",
|
"version": "1.6.0",
|
||||||
"resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz",
|
"resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz",
|
||||||
@@ -3047,6 +3211,15 @@
|
|||||||
"simple-swizzle": "^0.2.2"
|
"simple-swizzle": "^0.2.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/color-support": {
|
||||||
|
"version": "1.1.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz",
|
||||||
|
"integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==",
|
||||||
|
"license": "ISC",
|
||||||
|
"bin": {
|
||||||
|
"color-support": "bin.js"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/colorbrewer": {
|
"node_modules/colorbrewer": {
|
||||||
"version": "1.5.6",
|
"version": "1.5.6",
|
||||||
"resolved": "https://registry.npmjs.org/colorbrewer/-/colorbrewer-1.5.6.tgz",
|
"resolved": "https://registry.npmjs.org/colorbrewer/-/colorbrewer-1.5.6.tgz",
|
||||||
@@ -3079,9 +3252,14 @@
|
|||||||
"version": "0.0.1",
|
"version": "0.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
|
||||||
"integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
|
"integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/console-control-strings": {
|
||||||
|
"version": "1.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz",
|
||||||
|
"integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==",
|
||||||
|
"license": "ISC"
|
||||||
|
},
|
||||||
"node_modules/core-assert": {
|
"node_modules/core-assert": {
|
||||||
"version": "0.2.1",
|
"version": "0.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/core-assert/-/core-assert-0.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/core-assert/-/core-assert-0.2.1.tgz",
|
||||||
@@ -3137,6 +3315,13 @@
|
|||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"peer": true
|
"peer": true
|
||||||
},
|
},
|
||||||
|
"node_modules/csstype": {
|
||||||
|
"version": "3.1.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
|
||||||
|
"integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/d3-array": {
|
"node_modules/d3-array": {
|
||||||
"version": "3.2.4",
|
"version": "3.2.4",
|
||||||
"resolved": "https://registry.npmjs.org/d3-array/-/d3-array-3.2.4.tgz",
|
"resolved": "https://registry.npmjs.org/d3-array/-/d3-array-3.2.4.tgz",
|
||||||
@@ -3447,6 +3632,21 @@
|
|||||||
"url": "https://github.com/sponsors/ljharb"
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/delegates": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/detect-libc": {
|
||||||
|
"version": "2.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz",
|
||||||
|
"integrity": "sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==",
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/dir-glob": {
|
"node_modules/dir-glob": {
|
||||||
"version": "3.0.1",
|
"version": "3.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz",
|
||||||
@@ -4508,6 +4708,53 @@
|
|||||||
"url": "https://github.com/sponsors/ljharb"
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/gauge": {
|
||||||
|
"version": "3.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/gauge/-/gauge-3.0.2.tgz",
|
||||||
|
"integrity": "sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==",
|
||||||
|
"deprecated": "This package is no longer supported.",
|
||||||
|
"license": "ISC",
|
||||||
|
"dependencies": {
|
||||||
|
"aproba": "^1.0.3 || ^2.0.0",
|
||||||
|
"color-support": "^1.1.2",
|
||||||
|
"console-control-strings": "^1.0.0",
|
||||||
|
"has-unicode": "^2.0.1",
|
||||||
|
"object-assign": "^4.1.1",
|
||||||
|
"signal-exit": "^3.0.0",
|
||||||
|
"string-width": "^4.2.3",
|
||||||
|
"strip-ansi": "^6.0.1",
|
||||||
|
"wide-align": "^1.1.2"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/gauge/node_modules/emoji-regex": {
|
||||||
|
"version": "8.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
|
||||||
|
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/gauge/node_modules/signal-exit": {
|
||||||
|
"version": "3.0.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
|
||||||
|
"integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==",
|
||||||
|
"license": "ISC"
|
||||||
|
},
|
||||||
|
"node_modules/gauge/node_modules/string-width": {
|
||||||
|
"version": "4.2.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
|
||||||
|
"integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"emoji-regex": "^8.0.0",
|
||||||
|
"is-fullwidth-code-point": "^3.0.0",
|
||||||
|
"strip-ansi": "^6.0.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/geojson-vt": {
|
"node_modules/geojson-vt": {
|
||||||
"version": "4.0.2",
|
"version": "4.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/geojson-vt/-/geojson-vt-4.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/geojson-vt/-/geojson-vt-4.0.2.tgz",
|
||||||
@@ -4823,6 +5070,12 @@
|
|||||||
"url": "https://github.com/sponsors/ljharb"
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/has-unicode": {
|
||||||
|
"version": "2.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz",
|
||||||
|
"integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==",
|
||||||
|
"license": "ISC"
|
||||||
|
},
|
||||||
"node_modules/hasown": {
|
"node_modules/hasown": {
|
||||||
"version": "2.0.2",
|
"version": "2.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
|
||||||
@@ -4836,6 +5089,19 @@
|
|||||||
"node": ">= 0.4"
|
"node": ">= 0.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/https-proxy-agent": {
|
||||||
|
"version": "5.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz",
|
||||||
|
"integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"agent-base": "6",
|
||||||
|
"debug": "4"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 6"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/ieee754": {
|
"node_modules/ieee754": {
|
||||||
"version": "1.2.1",
|
"version": "1.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
|
||||||
@@ -4923,7 +5189,6 @@
|
|||||||
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
|
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
|
||||||
"integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
|
"integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
|
||||||
"deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.",
|
"deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.",
|
||||||
"dev": true,
|
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"once": "^1.3.0",
|
"once": "^1.3.0",
|
||||||
@@ -5821,6 +6086,30 @@
|
|||||||
"integrity": "sha512-VKlnoJRFrB8SdJhlVKvW5vI1gGwcZ+mvChEXcSX6r2xDNc/Q2FD9esfBmGCuPZdrJ1feO+YcVFd2PTk0c137Gw==",
|
"integrity": "sha512-VKlnoJRFrB8SdJhlVKvW5vI1gGwcZ+mvChEXcSX6r2xDNc/Q2FD9esfBmGCuPZdrJ1feO+YcVFd2PTk0c137Gw==",
|
||||||
"license": "BSD-2-Clause"
|
"license": "BSD-2-Clause"
|
||||||
},
|
},
|
||||||
|
"node_modules/make-dir": {
|
||||||
|
"version": "3.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz",
|
||||||
|
"integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"semver": "^6.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/make-dir/node_modules/semver": {
|
||||||
|
"version": "6.3.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
|
||||||
|
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
|
||||||
|
"license": "ISC",
|
||||||
|
"bin": {
|
||||||
|
"semver": "bin/semver.js"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/mapbox-gl": {
|
"node_modules/mapbox-gl": {
|
||||||
"version": "3.6.0",
|
"version": "3.6.0",
|
||||||
"resolved": "https://registry.npmjs.org/mapbox-gl/-/mapbox-gl-3.6.0.tgz",
|
"resolved": "https://registry.npmjs.org/mapbox-gl/-/mapbox-gl-3.6.0.tgz",
|
||||||
@@ -5924,7 +6213,6 @@
|
|||||||
"version": "3.1.2",
|
"version": "3.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
|
||||||
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
|
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
|
||||||
"dev": true,
|
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"brace-expansion": "^1.1.7"
|
"brace-expansion": "^1.1.7"
|
||||||
@@ -6135,6 +6423,58 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/node-addon-api": {
|
||||||
|
"version": "5.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-5.1.0.tgz",
|
||||||
|
"integrity": "sha512-eh0GgfEkpnoWDq+VY8OyvYhFEzBk6jIYbRKdIlyTiAXIVJ8PyBaKb0rp7oDtoddbdoHWhq8wwr+XZ81F1rpNdA==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/node-fetch": {
|
||||||
|
"version": "2.7.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
|
||||||
|
"integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"whatwg-url": "^5.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": "4.x || >=6.0.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"encoding": "^0.1.0"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"encoding": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/node-gyp-build": {
|
||||||
|
"version": "4.8.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.2.tgz",
|
||||||
|
"integrity": "sha512-IRUxE4BVsHWXkV/SFOut4qTlagw2aM8T5/vnTsmrHJvVoKueJHRc/JaFND7QDDc61kLYUJ6qlZM3sqTSyx2dTw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"bin": {
|
||||||
|
"node-gyp-build": "bin.js",
|
||||||
|
"node-gyp-build-optional": "optional.js",
|
||||||
|
"node-gyp-build-test": "build-test.js"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/nopt": {
|
||||||
|
"version": "5.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz",
|
||||||
|
"integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==",
|
||||||
|
"license": "ISC",
|
||||||
|
"dependencies": {
|
||||||
|
"abbrev": "1"
|
||||||
|
},
|
||||||
|
"bin": {
|
||||||
|
"nopt": "bin/nopt.js"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/normalize-path": {
|
"node_modules/normalize-path": {
|
||||||
"version": "3.0.0",
|
"version": "3.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
|
||||||
@@ -6145,11 +6485,23 @@
|
|||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/npmlog": {
|
||||||
|
"version": "5.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/npmlog/-/npmlog-5.0.1.tgz",
|
||||||
|
"integrity": "sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==",
|
||||||
|
"deprecated": "This package is no longer supported.",
|
||||||
|
"license": "ISC",
|
||||||
|
"dependencies": {
|
||||||
|
"are-we-there-yet": "^2.0.0",
|
||||||
|
"console-control-strings": "^1.1.0",
|
||||||
|
"gauge": "^3.0.0",
|
||||||
|
"set-blocking": "^2.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/object-assign": {
|
"node_modules/object-assign": {
|
||||||
"version": "4.1.1",
|
"version": "4.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
|
||||||
"integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
|
"integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
@@ -6281,11 +6633,16 @@
|
|||||||
"url": "https://github.com/sponsors/ljharb"
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/obuf": {
|
||||||
|
"version": "1.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz",
|
||||||
|
"integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/once": {
|
"node_modules/once": {
|
||||||
"version": "1.4.0",
|
"version": "1.4.0",
|
||||||
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
|
||||||
"integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
|
"integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
|
||||||
"dev": true,
|
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"wrappy": "1"
|
"wrappy": "1"
|
||||||
@@ -6391,7 +6748,6 @@
|
|||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
|
||||||
"integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
|
"integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
@@ -6458,6 +6814,48 @@
|
|||||||
"integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==",
|
"integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/pg-int8": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz",
|
||||||
|
"integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==",
|
||||||
|
"license": "ISC",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=4.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/pg-numeric": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/pg-numeric/-/pg-numeric-1.0.2.tgz",
|
||||||
|
"integrity": "sha512-BM/Thnrw5jm2kKLE5uJkXqqExRUY/toLHda65XgFTBTFYZyopbKjBe29Ii3RbkvlsMoFwD+tHeGaCjjv0gHlyw==",
|
||||||
|
"license": "ISC",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/pg-protocol": {
|
||||||
|
"version": "1.7.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.7.0.tgz",
|
||||||
|
"integrity": "sha512-hTK/mE36i8fDDhgDFjy6xNOG+LCorxLG3WO17tku+ij6sVHXh1jQUJ8hYAnRhNla4QVD2H8er/FOjc/+EgC6yQ==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/pg-types": {
|
||||||
|
"version": "4.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/pg-types/-/pg-types-4.0.2.tgz",
|
||||||
|
"integrity": "sha512-cRL3JpS3lKMGsKaWndugWQoLOCoP+Cic8oseVcbr0qhPzYD5DWXK+RZ9LY9wxRf7RQia4SCwQlXk0q6FCPrVng==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"pg-int8": "1.0.1",
|
||||||
|
"pg-numeric": "1.0.2",
|
||||||
|
"postgres-array": "~3.0.1",
|
||||||
|
"postgres-bytea": "~3.0.0",
|
||||||
|
"postgres-date": "~2.1.0",
|
||||||
|
"postgres-interval": "^3.0.0",
|
||||||
|
"postgres-range": "^1.1.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/picocolors": {
|
"node_modules/picocolors": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz",
|
||||||
@@ -6529,6 +6927,51 @@
|
|||||||
"node": "^10 || ^12 || >=14"
|
"node": "^10 || ^12 || >=14"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/postgres-array": {
|
||||||
|
"version": "3.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-3.0.2.tgz",
|
||||||
|
"integrity": "sha512-6faShkdFugNQCLwucjPcY5ARoW1SlbnrZjmGl0IrrqewpvxvhSLHimCVzqeuULCbG0fQv7Dtk1yDbG3xv7Veog==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/postgres-bytea": {
|
||||||
|
"version": "3.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-3.0.0.tgz",
|
||||||
|
"integrity": "sha512-CNd4jim9RFPkObHSjVHlVrxoVQXz7quwNFpz7RY1okNNme49+sVyiTvTRobiLV548Hx/hb1BG+iE7h9493WzFw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"obuf": "~1.1.2"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/postgres-date": {
|
||||||
|
"version": "2.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-2.1.0.tgz",
|
||||||
|
"integrity": "sha512-K7Juri8gtgXVcDfZttFKVmhglp7epKb1K4pgrkLxehjqkrgPhfG6OO8LHLkfaqkbpjNRnra018XwAr1yQFWGcA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/postgres-interval": {
|
||||||
|
"version": "3.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-3.0.0.tgz",
|
||||||
|
"integrity": "sha512-BSNDnbyZCXSxgA+1f5UU2GmwhoI0aU5yMxRGO8CdFEcY2BQF9xm/7MqKnYoM1nJDk8nONNWDk9WeSmePFhQdlw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/postgres-range": {
|
||||||
|
"version": "1.1.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/postgres-range/-/postgres-range-1.1.4.tgz",
|
||||||
|
"integrity": "sha512-i/hbxIE9803Alj/6ytL7UHQxRvZkI9O4Sy+J3HGc4F4oo/2eQAjTSNJ0bfxyse3bH0nuVesCk+3IRLaMtG3H6w==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/potpack": {
|
"node_modules/potpack": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/potpack/-/potpack-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/potpack/-/potpack-2.0.0.tgz",
|
||||||
@@ -6857,7 +7300,6 @@
|
|||||||
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
|
||||||
"integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
|
"integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
|
||||||
"deprecated": "Rimraf versions prior to v4 are no longer supported",
|
"deprecated": "Rimraf versions prior to v4 are no longer supported",
|
||||||
"dev": true,
|
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"glob": "^7.1.3"
|
"glob": "^7.1.3"
|
||||||
@@ -6874,7 +7316,6 @@
|
|||||||
"resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
|
"resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
|
||||||
"integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
|
"integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
|
||||||
"deprecated": "Glob versions prior to v9 are no longer supported",
|
"deprecated": "Glob versions prior to v9 are no longer supported",
|
||||||
"dev": true,
|
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"fs.realpath": "^1.0.0",
|
"fs.realpath": "^1.0.0",
|
||||||
@@ -7018,6 +7459,12 @@
|
|||||||
"node": ">=4.0.0"
|
"node": ">=4.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/set-blocking": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==",
|
||||||
|
"license": "ISC"
|
||||||
|
},
|
||||||
"node_modules/set-function-length": {
|
"node_modules/set-function-length": {
|
||||||
"version": "1.2.2",
|
"version": "1.2.2",
|
||||||
"resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz",
|
"resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz",
|
||||||
@@ -7723,6 +8170,12 @@
|
|||||||
"node": ">=8.0"
|
"node": ">=8.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/tr46": {
|
||||||
|
"version": "0.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
|
||||||
|
"integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/tree-kill": {
|
"node_modules/tree-kill": {
|
||||||
"version": "1.2.2",
|
"version": "1.2.2",
|
||||||
"resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz",
|
"resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz",
|
||||||
@@ -7988,12 +8441,28 @@
|
|||||||
"pbf": "^3.2.1"
|
"pbf": "^3.2.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/webidl-conversions": {
|
||||||
|
"version": "3.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
|
||||||
|
"integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==",
|
||||||
|
"license": "BSD-2-Clause"
|
||||||
|
},
|
||||||
"node_modules/wgsl_reflect": {
|
"node_modules/wgsl_reflect": {
|
||||||
"version": "1.0.10",
|
"version": "1.0.10",
|
||||||
"resolved": "https://registry.npmjs.org/wgsl_reflect/-/wgsl_reflect-1.0.10.tgz",
|
"resolved": "https://registry.npmjs.org/wgsl_reflect/-/wgsl_reflect-1.0.10.tgz",
|
||||||
"integrity": "sha512-70yzTaAhLFvasD+awEdHmgqKk3Qm2y6CVUU4OiS1rokB/TGi8CFEweUzDIfYn5pt6qhRdi9uArNykKaJy+CnwQ==",
|
"integrity": "sha512-70yzTaAhLFvasD+awEdHmgqKk3Qm2y6CVUU4OiS1rokB/TGi8CFEweUzDIfYn5pt6qhRdi9uArNykKaJy+CnwQ==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/whatwg-url": {
|
||||||
|
"version": "5.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
|
||||||
|
"integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"tr46": "~0.0.3",
|
||||||
|
"webidl-conversions": "^3.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/which": {
|
"node_modules/which": {
|
||||||
"version": "2.0.2",
|
"version": "2.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
|
||||||
@@ -8092,6 +8561,35 @@
|
|||||||
"url": "https://github.com/sponsors/ljharb"
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/wide-align": {
|
||||||
|
"version": "1.1.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz",
|
||||||
|
"integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==",
|
||||||
|
"license": "ISC",
|
||||||
|
"dependencies": {
|
||||||
|
"string-width": "^1.0.2 || 2 || 3 || 4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/wide-align/node_modules/emoji-regex": {
|
||||||
|
"version": "8.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
|
||||||
|
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/wide-align/node_modules/string-width": {
|
||||||
|
"version": "4.2.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
|
||||||
|
"integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"emoji-regex": "^8.0.0",
|
||||||
|
"is-fullwidth-code-point": "^3.0.0",
|
||||||
|
"strip-ansi": "^6.0.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/word-wrap": {
|
"node_modules/word-wrap": {
|
||||||
"version": "1.2.5",
|
"version": "1.2.5",
|
||||||
"resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz",
|
"resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz",
|
||||||
@@ -8207,9 +8705,29 @@
|
|||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
|
||||||
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
|
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
|
||||||
"dev": true,
|
|
||||||
"license": "ISC"
|
"license": "ISC"
|
||||||
},
|
},
|
||||||
|
"node_modules/ws": {
|
||||||
|
"version": "8.18.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz",
|
||||||
|
"integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10.0.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"bufferutil": "^4.0.1",
|
||||||
|
"utf-8-validate": ">=5.0.2"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"bufferutil": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"utf-8-validate": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/xml2js": {
|
"node_modules/xml2js": {
|
||||||
"version": "0.5.0",
|
"version": "0.5.0",
|
||||||
"resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.5.0.tgz",
|
"resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.5.0.tgz",
|
||||||
|
|||||||
@@ -12,6 +12,8 @@
|
|||||||
"@capacitor/android": "^6.1.2",
|
"@capacitor/android": "^6.1.2",
|
||||||
"@capacitor/cli": "^6.1.2",
|
"@capacitor/cli": "^6.1.2",
|
||||||
"@capacitor/core": "^6.1.2",
|
"@capacitor/core": "^6.1.2",
|
||||||
|
"@vercel/postgres": "^0.10.0",
|
||||||
|
"bcrypt": "^5.1.1",
|
||||||
"deck.gl": "^9.0.28",
|
"deck.gl": "^9.0.28",
|
||||||
"mapbox-gl": "^3.6.0",
|
"mapbox-gl": "^3.6.0",
|
||||||
"next": "14.2.7",
|
"next": "14.2.7",
|
||||||
@@ -21,6 +23,8 @@
|
|||||||
"react-slot-counter": "^3.0.1"
|
"react-slot-counter": "^3.0.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@types/bcrypt": "^5.0.2",
|
||||||
|
"@types/react": "18.3.10",
|
||||||
"eslint": "^8",
|
"eslint": "^8",
|
||||||
"eslint-config-next": "14.2.7",
|
"eslint-config-next": "14.2.7",
|
||||||
"sass": "^1.77.8"
|
"sass": "^1.77.8"
|
||||||
|
|||||||
@@ -0,0 +1,26 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"paths": {
|
||||||
|
"@/*": ["./*"]
|
||||||
|
},
|
||||||
|
"lib": ["dom", "dom.iterable", "esnext"],
|
||||||
|
"allowJs": true,
|
||||||
|
"skipLibCheck": true,
|
||||||
|
"strict": false,
|
||||||
|
"noEmit": true,
|
||||||
|
"incremental": true,
|
||||||
|
"module": "esnext",
|
||||||
|
"esModuleInterop": true,
|
||||||
|
"moduleResolution": "node",
|
||||||
|
"resolveJsonModule": true,
|
||||||
|
"isolatedModules": true,
|
||||||
|
"jsx": "preserve",
|
||||||
|
"plugins": [
|
||||||
|
{
|
||||||
|
"name": "next"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"include": ["next-env.d.ts", ".next/types/**/*.ts", "**/*.ts", "**/*.tsx"],
|
||||||
|
"exclude": ["node_modules"]
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user