diff --git a/package.json b/package.json
index 9d131ca..f90a0f5 100644
--- a/package.json
+++ b/package.json
@@ -14,8 +14,11 @@
"@tanstack/react-query": "^5.69.0",
"@tanstack/react-table": "^8.21.2",
"axios": "^1.8.4",
+ "bootstrap": "^5.3.3",
"clsx": "^2.1.1",
+ "declarations": "link:@/lib/declarations",
"jwt-decode": "^4.0.0",
+ "leaflet": "^1.9.4",
"next": "15.2.3",
"next-auth": "^4.24.11",
"nextjs-toploader": "^3.8.15",
@@ -32,6 +35,7 @@
"@eslint/eslintrc": "^3",
"@svgr/webpack": "^8.1.0",
"@tailwindcss/postcss": "^4",
+ "@types/leaflet": "^1.9.17",
"@types/node": "^20",
"@types/react": "^19",
"@types/react-dom": "^19",
@@ -39,7 +43,6 @@
"eslint-config-next": "15.2.3",
"install": "^0.13.0",
"npm": "^11.2.0",
- "tailwindcss": "^4",
"typescript": "^5"
}
}
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 3fab4d4..6bab45e 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -23,12 +23,21 @@ importers:
axios:
specifier: ^1.8.4
version: 1.8.4
+ bootstrap:
+ specifier: ^5.3.3
+ version: 5.3.3(@popperjs/core@2.11.8)
clsx:
specifier: ^2.1.1
version: 2.1.1
+ declarations:
+ specifier: link:@/lib/declarations
+ version: link:@/lib/declarations
jwt-decode:
specifier: ^4.0.0
version: 4.0.0
+ leaflet:
+ specifier: ^1.9.4
+ version: 1.9.4
next:
specifier: 15.2.3
version: 15.2.3(@babel/core@7.26.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(sass@1.86.0)
@@ -72,6 +81,9 @@ importers:
'@tailwindcss/postcss':
specifier: ^4
version: 4.0.15
+ '@types/leaflet':
+ specifier: ^1.9.17
+ version: 1.9.17
'@types/node':
specifier: ^20
version: 20.17.27
@@ -93,9 +105,6 @@ importers:
npm:
specifier: ^11.2.0
version: 11.2.0
- tailwindcss:
- specifier: ^4
- version: 4.0.15
typescript:
specifier: ^5
version: 5.8.2
@@ -1018,6 +1027,9 @@ packages:
resolution: {integrity: sha512-dfUnCxiN9H4ap84DvD2ubjw+3vUNpstxa0TneY/Paat8a3R4uQZDLSvWjmznAY/DoahqTHl9V46HF/Zs3F29pg==}
engines: {node: '>= 10.0.0'}
+ '@popperjs/core@2.11.8':
+ resolution: {integrity: sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==}
+
'@radix-ui/colors@3.0.0':
resolution: {integrity: sha512-FUOsGBkHrYJwCSEtWRCIfQbZG7q1e6DgxCIOe1SUQzDe/7rXXeA47s8yCn6fuTNQAj1Zq4oTFi9Yjp3wzElcxg==}
@@ -1875,12 +1887,18 @@ packages:
'@types/estree@1.0.7':
resolution: {integrity: sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==}
+ '@types/geojson@7946.0.16':
+ resolution: {integrity: sha512-6C8nqWur3j98U6+lXDfTUWIfgvZU+EumvpHKcYjujKH7woYyLj2sUmff0tRhrqM7BohUw7Pz3ZB1jj2gW9Fvmg==}
+
'@types/json-schema@7.0.15':
resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==}
'@types/json5@0.0.29':
resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==}
+ '@types/leaflet@1.9.17':
+ resolution: {integrity: sha512-IJ4K6t7I3Fh5qXbQ1uwL3CFVbCi6haW9+53oLWgdKlLP7EaS21byWFJxxqOx9y8I0AP0actXSJLVMbyvxhkUTA==}
+
'@types/node@20.17.27':
resolution: {integrity: sha512-U58sbKhDrthHlxHRJw7ZLiLDZGmAUOZUbpw0S6nL27sYUdhvgBLCRu/keSd6qcTsfArd1sRFCCBxzWATGr/0UA==}
@@ -2100,6 +2118,11 @@ packages:
boolbase@1.0.0:
resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==}
+ bootstrap@5.3.3:
+ resolution: {integrity: sha512-8HLCdWgyoMguSO9o+aH+iuZ+aht+mzW0u3HIMzVu7Srrpv7EBBxTnrFlSCskwdY1+EOFQSm7uMJhNQHkdPcmjg==}
+ peerDependencies:
+ '@popperjs/core': ^2.11.8
+
brace-expansion@1.1.11:
resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==}
@@ -2845,6 +2868,9 @@ packages:
resolution: {integrity: sha512-MbjN408fEndfiQXbFQ1vnd+1NoLDsnQW41410oQBXiyXDMYH5z505juWa4KUE1LqxRC7DgOgZDbKLxHIwm27hA==}
engines: {node: '>=0.10'}
+ leaflet@1.9.4:
+ resolution: {integrity: sha512-nxS1ynzJOmOlHp+iL3FyWqK89GtNL8U8rvlMOsQdTTssxZwCXh8N2NB3GDQOL+YR3XnWyZAxwQixURb+FA74PA==}
+
levn@0.4.1:
resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==}
engines: {node: '>= 0.8.0'}
@@ -4716,6 +4742,8 @@ snapshots:
'@parcel/watcher-win32-x64': 2.5.1
optional: true
+ '@popperjs/core@2.11.8': {}
+
'@radix-ui/colors@3.0.0': {}
'@radix-ui/number@1.1.0': {}
@@ -5614,10 +5642,16 @@ snapshots:
'@types/estree@1.0.7': {}
+ '@types/geojson@7946.0.16': {}
+
'@types/json-schema@7.0.15': {}
'@types/json5@0.0.29': {}
+ '@types/leaflet@1.9.17':
+ dependencies:
+ '@types/geojson': 7946.0.16
+
'@types/node@20.17.27':
dependencies:
undici-types: 6.19.8
@@ -5882,6 +5916,10 @@ snapshots:
boolbase@1.0.0: {}
+ bootstrap@5.3.3(@popperjs/core@2.11.8):
+ dependencies:
+ '@popperjs/core': 2.11.8
+
brace-expansion@1.1.11:
dependencies:
balanced-match: 1.0.2
@@ -6765,6 +6803,8 @@ snapshots:
dependencies:
language-subtag-registry: 0.3.23
+ leaflet@1.9.4: {}
+
levn@0.4.1:
dependencies:
prelude-ls: 1.2.1
diff --git a/src/app/(auth)/login/page.tsx b/src/app/(auth)/login/page.tsx
index 1bf1293..5246d7c 100644
--- a/src/app/(auth)/login/page.tsx
+++ b/src/app/(auth)/login/page.tsx
@@ -7,71 +7,77 @@ import { signIn } from "next-auth/react"
import { useRouter, useSearchParams } from "next/navigation";
export default function LoginPage() {
- const router = useRouter()
- const params = useSearchParams().get("redirect_to");
+ const router = useRouter()
+ const params = useSearchParams().get("redirect_to");
- const mutation = useMutation({
- mutationKey: ['login'],
- mutationFn: async (data: { email: string; password: string }) => {
- try {
- const result = await signIn("credentials", {
- email: data.email,
- password: data.password,
- redirect: false,
- })
-
- if (result?.error) {
- const errorMessage = result.error.includes("CredentialsSignin")
- ? "Email ou mot de passe incorrect"
- : result.error;
- console.error(errorMessage)
- throw new Error(result.error)
- } else {
- if (params) {
- router.push(params);
- } else {
- router.push('/admin/home')
- }
- }
- return result
- } catch (error: unknown) {
- if (error instanceof Error && error.message.includes("Network Error")) {
- console.error("Problème de connexion au serveur");
- }
- console.error("Autre = ", error);
- }
-
+ const mutation = useMutation({
+ mutationKey: ['login'],
+ mutationFn: async (data: { email: string; password: string }) => {
+ try {
+ const result = await signIn("credentials", {
+ email: data.email,
+ password: data.password,
+ redirect: false,
+ })
- },
- onError: (error: Error) => {
- console.error(error.message)
- },
- })
+ if (result?.error) {
+ const errorMessage = result.error.includes("CredentialsSignin")
+ ? "Email ou mot de passe incorrect"
+ : result.error;
+ console.error(errorMessage)
+ throw new Error(result.error)
+ } else {
+ if (params) {
+ router.push(params);
+ } else {
+ router.push('/admin/home')
+ }
+ }
+ return result
+ } catch (error: unknown) {
+ if (error instanceof Error && error.message.includes("Network Error")) {
+ console.error("Problème de connexion au serveur");
+ }
+ console.error("Autre = ", error);
+ }
- return(
-
-
- )
+
+ },
+ onError: (error: Error) => {
+ console.error(error.message)
+ },
+ })
+
+ return (
+
+
+
+
+ )
}
\ No newline at end of file
diff --git a/src/app/globals.css b/src/app/globals.css
index 627de23..23a2526 100644
--- a/src/app/globals.css
+++ b/src/app/globals.css
@@ -1,8 +1,6 @@
-@import "tailwindcss";
-
@font-face {
- font-family: 'Urbanist'; /* Nom que vous donnerez à votre police */
- src: url('../assets/fonts/Urbanist.ttf') format('truetype'); /* Chemin vers votre fichier */
+ font-family: 'Urbanist';
+ src: url('../assets/fonts/Urbanist.ttf') format('truetype');
font-weight: normal;
font-style: normal;
}
@@ -29,15 +27,18 @@
--background: #ffffff;
--cinder: #999;
--bluegray: --primary;
-}
+ }
}
body {
background: var(--background);
color: var(--foreground);
- font-family: Urbanist, sans-serif;
+ font-family: Urbanist, sans-serif !important;
+}
+*{
+ margin: 0;
+ padding: 0;
}
-
.input-form {
width: 100%;
padding: 12px;
@@ -54,14 +55,22 @@ body {
position: absolute;
left: 12px;
top: -0.45rem;
- background-color: white;
- padding-inline: 4px;
+ padding: 1px 5px;
+ line-height: normal;
+ color: var(--secondary);
+ background-color: var(--background);
+ border-radius: 400px;
z-index: 1;
}
+.form-error {
+ font-size: 14px;
+ color: var(--danger);
+}
+
.btn-floating-right {
position: absolute;
- right: 8px;
+ right: 12px;
top: 50%;
transform: translateY(-50%);
}
@@ -102,7 +111,12 @@ body {
transition: width 0.2s, height 0.2s;
}
-.cta{
+button {
+ background-color: transparent;
+ border: none;
+}
+
+.cta {
padding: 10px 24px;
width: max-content;
height: max-content;
@@ -116,35 +130,38 @@ body {
text-wrap: nowrap;
}
-.cta.modal-cta{
+.cta.modal-cta {
+ padding: 9px;
+ margin-top: 32px;
width: 240px;
- height: 40px;
}
-.cta.cancel{
+.cta.cancel {
color: var(--secondary);
border: 1px solid var(--gray);
background-color: var(--gray);
}
-.cta.info{
+.cta.info {
color: var(--primary);
background-color: var(--background);
}
-.cta.danger{
+.cta.danger {
border: 1px solid var(--danger);
background-color: var(--danger);
}
-.bg-bluegray{
+.bg-bluegray {
background-color: var(--bluegray);
}
-.bg-gray{
+
+.bg-gray {
background-color: var(--gray);
}
-hr{
+
+hr {
color: var(--gray);
}
@@ -155,10 +172,10 @@ input[type="checkbox"] {
width: 24px;
height: 24px;
- border: 1px solid var(--secondary) !important;
- border-radius: 6px !important;
- background-color: transparent;
- cursor: pointer;
+ border: 1px solid var(--secondary) !important;
+ border-radius: 6px !important;
+ background-color: transparent;
+ cursor: pointer;
position: relative;
}
@@ -170,7 +187,7 @@ input[type="checkbox"]:checked {
input[type="checkbox"]:checked::before {
- content: "✔";
+ content: "✔";
font-size: 18px;
color: white;
position: absolute;
@@ -179,7 +196,7 @@ input[type="checkbox"]:checked::before {
transform: translate(-50%, -50%);
}
-.modal-input{
+.modal-input {
width: 490px;
margin-left: auto;
margin-right: auto;
@@ -189,7 +206,7 @@ input[type="checkbox"]:checked::before {
/* Scroll Bar */
::-webkit-scrollbar {
- width: 4px;
+ width: 7px;
padding: 0;
margin: 0;
}
@@ -224,4 +241,95 @@ input[type="checkbox"]:checked::before {
width: 16px;
height: 16px;
}
+}
+
+
+
+
+/* Login Header */
+.login-header {
+ padding: 20px 0;
+ box-shadow: 0 0 24px #0000001A;
+}
+
+.word {
+ font-size: 24px;
+ font-weight: bold;
+ color: black;
+ position: relative;
+ line-height: normal;
+}
+
+.dot {
+ /* font-size: 14px; */
+ color: blue;
+ position: absolute;
+ top: -10px;
+ left: 22px;
+ animation: bounce 1s infinite ease-in-out;
+}
+
+@keyframes bounce {
+
+ 0%,
+ 100% {
+ transform: translateY(0);
+ }
+
+ 50% {
+ transform: translateY(-3px);
+ }
+}
+
+.login-main {
+ min-height: 100vh;
+}
+
+
+.form-container {
+ padding: 48px 64px;
+ margin: auto;
+ width: max-content;
+ max-width: 624px;
+ border-radius: 8px;
+ box-shadow: 0 0 24px #0000001A;
+}
+
+.form-fields {
+ gap: 24px;
+}
+
+
+
+
+@media (max-width: 768px) {
+
+
+ .login-main{
+ width: 100%;
+ }
+ .form-container {
+ padding: 24px 32px;
+ margin: 0 4%;
+ width: 80%;
+ }
+
+ .form-fields {
+ gap: 12px;
+ }
+
+ .modal-input {
+ width: 100%;
+ min-width: 100%;
+ }
+ .form-title{
+ margin-bottom: 2px!important;
+ }
+
+ .cta.modal-cta{
+ margin: 0!important;
+ }
+ .input-form{
+ margin: 0 auto;
+ }
}
\ No newline at end of file
diff --git a/src/app/layout.tsx b/src/app/layout.tsx
index ba57bb2..6f913f0 100644
--- a/src/app/layout.tsx
+++ b/src/app/layout.tsx
@@ -21,6 +21,8 @@ export default function RootLayout({
+
+
diff --git a/src/assets/icons/final-index.tsx b/src/assets/icons/final-index.tsx
new file mode 100644
index 0000000..c2f7c53
--- /dev/null
+++ b/src/assets/icons/final-index.tsx
@@ -0,0 +1,16 @@
+import React from "react";
+
+//import { GeneralHtmlAttr } from "@/lib/declarations";
+//export type GeneralHtmlAttr = React.HTMLAttributes;
+
+import L from "leaflet";
+
+export const HomeIcon = (props) => {
+ return (
+
+ );
+}
\ No newline at end of file
diff --git a/src/assets/icons/full-logo.svg b/src/assets/icons/full-logo.svg
new file mode 100644
index 0000000..49ab970
--- /dev/null
+++ b/src/assets/icons/full-logo.svg
@@ -0,0 +1,9 @@
+
diff --git a/src/components/floatingLabelInput.tsx b/src/components/floatingLabelInput.tsx
index 8e3b1e8..37499f8 100644
--- a/src/components/floatingLabelInput.tsx
+++ b/src/components/floatingLabelInput.tsx
@@ -30,7 +30,7 @@ export default function FloatingLabelInput({
switch(type) {
case 'select':
return (
-
+