diff --git a/client/jsconfig.json b/client/jsconfig.json
index c205775..1542a85 100644
--- a/client/jsconfig.json
+++ b/client/jsconfig.json
@@ -6,6 +6,7 @@
"skipLibCheck": true,
"paths": {
"@/*": ["./src/*"]
- }
+ },
+ "jsx": "react"
}
}
\ No newline at end of file
diff --git a/client/package-lock.json b/client/package-lock.json
index 794430d..8497895 100644
--- a/client/package-lock.json
+++ b/client/package-lock.json
@@ -11,7 +11,6 @@
"@chakra-ui/react": "^3.22.0",
"@emotion/react": "^11.14.0",
"@emotion/styled": "^11.14.1",
- "@tailwindcss/vite": "^4.1.11",
"framer-motion": "^12.23.0",
"leaflet": "^1.9.4",
"lucide-react": "^0.539.0",
@@ -20,10 +19,9 @@
"react-dom": "^19.1.0",
"react-grid-layout": "^1.5.2",
"react-hook-form": "^7.62.0",
- "react-icons": "^5.5.0",
"react-leaflet": "^5.0.0",
"react-resizable": "^3.0.5",
- "tailwindcss": "^4.1.11",
+ "react-router-dom": "^7.16.0",
"uuid": "^11.1.0"
},
"devDependencies": {
@@ -39,18 +37,6 @@
"vite-jsconfig-paths": "^2.0.1"
}
},
- "node_modules/@ampproject/remapping": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz",
- "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==",
- "dependencies": {
- "@jridgewell/gen-mapping": "^0.3.5",
- "@jridgewell/trace-mapping": "^0.3.24"
- },
- "engines": {
- "node": ">=6.0.0"
- }
- },
"node_modules/@ark-ui/react": {
"version": "5.16.1",
"resolved": "https://registry.npmjs.org/@ark-ui/react/-/react-5.16.1.tgz",
@@ -414,6 +400,7 @@
"cpu": [
"ppc64"
],
+ "dev": true,
"optional": true,
"os": [
"aix"
@@ -429,6 +416,7 @@
"cpu": [
"arm"
],
+ "dev": true,
"optional": true,
"os": [
"android"
@@ -444,6 +432,7 @@
"cpu": [
"arm64"
],
+ "dev": true,
"optional": true,
"os": [
"android"
@@ -459,6 +448,7 @@
"cpu": [
"x64"
],
+ "dev": true,
"optional": true,
"os": [
"android"
@@ -474,6 +464,7 @@
"cpu": [
"arm64"
],
+ "dev": true,
"optional": true,
"os": [
"darwin"
@@ -489,6 +480,7 @@
"cpu": [
"x64"
],
+ "dev": true,
"optional": true,
"os": [
"darwin"
@@ -504,6 +496,7 @@
"cpu": [
"arm64"
],
+ "dev": true,
"optional": true,
"os": [
"freebsd"
@@ -519,6 +512,7 @@
"cpu": [
"x64"
],
+ "dev": true,
"optional": true,
"os": [
"freebsd"
@@ -534,6 +528,7 @@
"cpu": [
"arm"
],
+ "dev": true,
"optional": true,
"os": [
"linux"
@@ -549,6 +544,7 @@
"cpu": [
"arm64"
],
+ "dev": true,
"optional": true,
"os": [
"linux"
@@ -564,6 +560,7 @@
"cpu": [
"ia32"
],
+ "dev": true,
"optional": true,
"os": [
"linux"
@@ -579,6 +576,7 @@
"cpu": [
"loong64"
],
+ "dev": true,
"optional": true,
"os": [
"linux"
@@ -594,6 +592,7 @@
"cpu": [
"mips64el"
],
+ "dev": true,
"optional": true,
"os": [
"linux"
@@ -609,6 +608,7 @@
"cpu": [
"ppc64"
],
+ "dev": true,
"optional": true,
"os": [
"linux"
@@ -624,6 +624,7 @@
"cpu": [
"riscv64"
],
+ "dev": true,
"optional": true,
"os": [
"linux"
@@ -639,6 +640,7 @@
"cpu": [
"s390x"
],
+ "dev": true,
"optional": true,
"os": [
"linux"
@@ -654,6 +656,7 @@
"cpu": [
"x64"
],
+ "dev": true,
"optional": true,
"os": [
"linux"
@@ -669,6 +672,7 @@
"cpu": [
"arm64"
],
+ "dev": true,
"optional": true,
"os": [
"netbsd"
@@ -684,6 +688,7 @@
"cpu": [
"x64"
],
+ "dev": true,
"optional": true,
"os": [
"netbsd"
@@ -699,6 +704,7 @@
"cpu": [
"arm64"
],
+ "dev": true,
"optional": true,
"os": [
"openbsd"
@@ -714,6 +720,7 @@
"cpu": [
"x64"
],
+ "dev": true,
"optional": true,
"os": [
"openbsd"
@@ -729,6 +736,7 @@
"cpu": [
"x64"
],
+ "dev": true,
"optional": true,
"os": [
"sunos"
@@ -744,6 +752,7 @@
"cpu": [
"arm64"
],
+ "dev": true,
"optional": true,
"os": [
"win32"
@@ -759,6 +768,7 @@
"cpu": [
"ia32"
],
+ "dev": true,
"optional": true,
"os": [
"win32"
@@ -774,6 +784,7 @@
"cpu": [
"x64"
],
+ "dev": true,
"optional": true,
"os": [
"win32"
@@ -1053,17 +1064,6 @@
"node": ">=12"
}
},
- "node_modules/@isaacs/fs-minipass": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz",
- "integrity": "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==",
- "dependencies": {
- "minipass": "^7.0.4"
- },
- "engines": {
- "node": ">=18.0.0"
- }
- },
"node_modules/@jridgewell/gen-mapping": {
"version": "0.3.12",
"resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.12.tgz",
@@ -1134,6 +1134,7 @@
"cpu": [
"arm"
],
+ "dev": true,
"optional": true,
"os": [
"android"
@@ -1146,6 +1147,7 @@
"cpu": [
"arm64"
],
+ "dev": true,
"optional": true,
"os": [
"android"
@@ -1158,6 +1160,7 @@
"cpu": [
"arm64"
],
+ "dev": true,
"optional": true,
"os": [
"darwin"
@@ -1170,6 +1173,7 @@
"cpu": [
"x64"
],
+ "dev": true,
"optional": true,
"os": [
"darwin"
@@ -1182,6 +1186,7 @@
"cpu": [
"arm64"
],
+ "dev": true,
"optional": true,
"os": [
"freebsd"
@@ -1194,6 +1199,7 @@
"cpu": [
"x64"
],
+ "dev": true,
"optional": true,
"os": [
"freebsd"
@@ -1206,6 +1212,7 @@
"cpu": [
"arm"
],
+ "dev": true,
"optional": true,
"os": [
"linux"
@@ -1218,6 +1225,7 @@
"cpu": [
"arm"
],
+ "dev": true,
"optional": true,
"os": [
"linux"
@@ -1230,6 +1238,7 @@
"cpu": [
"arm64"
],
+ "dev": true,
"optional": true,
"os": [
"linux"
@@ -1242,6 +1251,7 @@
"cpu": [
"arm64"
],
+ "dev": true,
"optional": true,
"os": [
"linux"
@@ -1254,6 +1264,7 @@
"cpu": [
"loong64"
],
+ "dev": true,
"optional": true,
"os": [
"linux"
@@ -1266,6 +1277,7 @@
"cpu": [
"ppc64"
],
+ "dev": true,
"optional": true,
"os": [
"linux"
@@ -1278,6 +1290,7 @@
"cpu": [
"riscv64"
],
+ "dev": true,
"optional": true,
"os": [
"linux"
@@ -1290,6 +1303,7 @@
"cpu": [
"riscv64"
],
+ "dev": true,
"optional": true,
"os": [
"linux"
@@ -1302,6 +1316,7 @@
"cpu": [
"s390x"
],
+ "dev": true,
"optional": true,
"os": [
"linux"
@@ -1314,6 +1329,7 @@
"cpu": [
"x64"
],
+ "dev": true,
"optional": true,
"os": [
"linux"
@@ -1326,6 +1342,7 @@
"cpu": [
"x64"
],
+ "dev": true,
"optional": true,
"os": [
"linux"
@@ -1338,6 +1355,7 @@
"cpu": [
"arm64"
],
+ "dev": true,
"optional": true,
"os": [
"win32"
@@ -1350,6 +1368,7 @@
"cpu": [
"ia32"
],
+ "dev": true,
"optional": true,
"os": [
"win32"
@@ -1362,6 +1381,7 @@
"cpu": [
"x64"
],
+ "dev": true,
"optional": true,
"os": [
"win32"
@@ -1588,257 +1608,11 @@
"@swc/counter": "^0.1.3"
}
},
- "node_modules/@tailwindcss/node": {
- "version": "4.1.11",
- "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.1.11.tgz",
- "integrity": "sha512-yzhzuGRmv5QyU9qLNg4GTlYI6STedBWRE7NjxP45CsFYYq9taI0zJXZBMqIC/c8fViNLhmrbpSFS57EoxUmD6Q==",
- "dependencies": {
- "@ampproject/remapping": "^2.3.0",
- "enhanced-resolve": "^5.18.1",
- "jiti": "^2.4.2",
- "lightningcss": "1.30.1",
- "magic-string": "^0.30.17",
- "source-map-js": "^1.2.1",
- "tailwindcss": "4.1.11"
- }
- },
- "node_modules/@tailwindcss/oxide": {
- "version": "4.1.11",
- "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.1.11.tgz",
- "integrity": "sha512-Q69XzrtAhuyfHo+5/HMgr1lAiPP/G40OMFAnws7xcFEYqcypZmdW8eGXaOUIeOl1dzPJBPENXgbjsOyhg2nkrg==",
- "hasInstallScript": true,
- "dependencies": {
- "detect-libc": "^2.0.4",
- "tar": "^7.4.3"
- },
- "engines": {
- "node": ">= 10"
- },
- "optionalDependencies": {
- "@tailwindcss/oxide-android-arm64": "4.1.11",
- "@tailwindcss/oxide-darwin-arm64": "4.1.11",
- "@tailwindcss/oxide-darwin-x64": "4.1.11",
- "@tailwindcss/oxide-freebsd-x64": "4.1.11",
- "@tailwindcss/oxide-linux-arm-gnueabihf": "4.1.11",
- "@tailwindcss/oxide-linux-arm64-gnu": "4.1.11",
- "@tailwindcss/oxide-linux-arm64-musl": "4.1.11",
- "@tailwindcss/oxide-linux-x64-gnu": "4.1.11",
- "@tailwindcss/oxide-linux-x64-musl": "4.1.11",
- "@tailwindcss/oxide-wasm32-wasi": "4.1.11",
- "@tailwindcss/oxide-win32-arm64-msvc": "4.1.11",
- "@tailwindcss/oxide-win32-x64-msvc": "4.1.11"
- }
- },
- "node_modules/@tailwindcss/oxide-android-arm64": {
- "version": "4.1.11",
- "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.1.11.tgz",
- "integrity": "sha512-3IfFuATVRUMZZprEIx9OGDjG3Ou3jG4xQzNTvjDoKmU9JdmoCohQJ83MYd0GPnQIu89YoJqvMM0G3uqLRFtetg==",
- "cpu": [
- "arm64"
- ],
- "optional": true,
- "os": [
- "android"
- ],
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/@tailwindcss/oxide-darwin-arm64": {
- "version": "4.1.11",
- "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.1.11.tgz",
- "integrity": "sha512-ESgStEOEsyg8J5YcMb1xl8WFOXfeBmrhAwGsFxxB2CxY9evy63+AtpbDLAyRkJnxLy2WsD1qF13E97uQyP1lfQ==",
- "cpu": [
- "arm64"
- ],
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/@tailwindcss/oxide-darwin-x64": {
- "version": "4.1.11",
- "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.1.11.tgz",
- "integrity": "sha512-EgnK8kRchgmgzG6jE10UQNaH9Mwi2n+yw1jWmof9Vyg2lpKNX2ioe7CJdf9M5f8V9uaQxInenZkOxnTVL3fhAw==",
- "cpu": [
- "x64"
- ],
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/@tailwindcss/oxide-freebsd-x64": {
- "version": "4.1.11",
- "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.1.11.tgz",
- "integrity": "sha512-xdqKtbpHs7pQhIKmqVpxStnY1skuNh4CtbcyOHeX1YBE0hArj2romsFGb6yUmzkq/6M24nkxDqU8GYrKrz+UcA==",
- "cpu": [
- "x64"
- ],
- "optional": true,
- "os": [
- "freebsd"
- ],
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/@tailwindcss/oxide-linux-arm-gnueabihf": {
- "version": "4.1.11",
- "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.1.11.tgz",
- "integrity": "sha512-ryHQK2eyDYYMwB5wZL46uoxz2zzDZsFBwfjssgB7pzytAeCCa6glsiJGjhTEddq/4OsIjsLNMAiMlHNYnkEEeg==",
- "cpu": [
- "arm"
- ],
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/@tailwindcss/oxide-linux-arm64-gnu": {
- "version": "4.1.11",
- "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.1.11.tgz",
- "integrity": "sha512-mYwqheq4BXF83j/w75ewkPJmPZIqqP1nhoghS9D57CLjsh3Nfq0m4ftTotRYtGnZd3eCztgbSPJ9QhfC91gDZQ==",
- "cpu": [
- "arm64"
- ],
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/@tailwindcss/oxide-linux-arm64-musl": {
- "version": "4.1.11",
- "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.1.11.tgz",
- "integrity": "sha512-m/NVRFNGlEHJrNVk3O6I9ggVuNjXHIPoD6bqay/pubtYC9QIdAMpS+cswZQPBLvVvEF6GtSNONbDkZrjWZXYNQ==",
- "cpu": [
- "arm64"
- ],
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/@tailwindcss/oxide-linux-x64-gnu": {
- "version": "4.1.11",
- "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.1.11.tgz",
- "integrity": "sha512-YW6sblI7xukSD2TdbbaeQVDysIm/UPJtObHJHKxDEcW2exAtY47j52f8jZXkqE1krdnkhCMGqP3dbniu1Te2Fg==",
- "cpu": [
- "x64"
- ],
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/@tailwindcss/oxide-linux-x64-musl": {
- "version": "4.1.11",
- "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.1.11.tgz",
- "integrity": "sha512-e3C/RRhGunWYNC3aSF7exsQkdXzQ/M+aYuZHKnw4U7KQwTJotnWsGOIVih0s2qQzmEzOFIJ3+xt7iq67K/p56Q==",
- "cpu": [
- "x64"
- ],
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/@tailwindcss/oxide-wasm32-wasi": {
- "version": "4.1.11",
- "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.1.11.tgz",
- "integrity": "sha512-Xo1+/GU0JEN/C/dvcammKHzeM6NqKovG+6921MR6oadee5XPBaKOumrJCXvopJ/Qb5TH7LX/UAywbqrP4lax0g==",
- "bundleDependencies": [
- "@napi-rs/wasm-runtime",
- "@emnapi/core",
- "@emnapi/runtime",
- "@tybys/wasm-util",
- "@emnapi/wasi-threads",
- "tslib"
- ],
- "cpu": [
- "wasm32"
- ],
- "optional": true,
- "dependencies": {
- "@emnapi/core": "^1.4.3",
- "@emnapi/runtime": "^1.4.3",
- "@emnapi/wasi-threads": "^1.0.2",
- "@napi-rs/wasm-runtime": "^0.2.11",
- "@tybys/wasm-util": "^0.9.0",
- "tslib": "^2.8.0"
- },
- "engines": {
- "node": ">=14.0.0"
- }
- },
- "node_modules/@tailwindcss/oxide-win32-arm64-msvc": {
- "version": "4.1.11",
- "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.1.11.tgz",
- "integrity": "sha512-UgKYx5PwEKrac3GPNPf6HVMNhUIGuUh4wlDFR2jYYdkX6pL/rn73zTq/4pzUm8fOjAn5L8zDeHp9iXmUGOXZ+w==",
- "cpu": [
- "arm64"
- ],
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/@tailwindcss/oxide-win32-x64-msvc": {
- "version": "4.1.11",
- "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.1.11.tgz",
- "integrity": "sha512-YfHoggn1j0LK7wR82TOucWc5LDCguHnoS879idHekmmiR7g9HUtMw9MI0NHatS28u/Xlkfi9w5RJWgz2Dl+5Qg==",
- "cpu": [
- "x64"
- ],
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/@tailwindcss/vite": {
- "version": "4.1.11",
- "resolved": "https://registry.npmjs.org/@tailwindcss/vite/-/vite-4.1.11.tgz",
- "integrity": "sha512-RHYhrR3hku0MJFRV+fN2gNbDNEh3dwKvY8XJvTxCSXeMOsCRSr+uKvDWQcbizrHgjML6ZmTE5OwMrl5wKcujCw==",
- "dependencies": {
- "@tailwindcss/node": "4.1.11",
- "@tailwindcss/oxide": "4.1.11",
- "tailwindcss": "4.1.11"
- },
- "peerDependencies": {
- "vite": "^5.2.0 || ^6 || ^7"
- }
- },
"node_modules/@types/estree": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz",
- "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w=="
+ "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==",
+ "dev": true
},
"node_modules/@types/json-schema": {
"version": "7.0.15",
@@ -2785,14 +2559,6 @@
"url": "https://github.com/chalk/chalk?sponsor=1"
}
},
- "node_modules/chownr": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/chownr/-/chownr-3.0.0.tgz",
- "integrity": "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==",
- "engines": {
- "node": ">=18"
- }
- },
"node_modules/clsx": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz",
@@ -2840,6 +2606,19 @@
"resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz",
"integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A=="
},
+ "node_modules/cookie": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/cookie/-/cookie-1.1.1.tgz",
+ "integrity": "sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/express"
+ }
+ },
"node_modules/cosmiconfig": {
"version": "7.1.0",
"resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz",
@@ -2904,14 +2683,6 @@
"integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==",
"dev": true
},
- "node_modules/detect-libc": {
- "version": "2.0.4",
- "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.4.tgz",
- "integrity": "sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==",
- "engines": {
- "node": ">=8"
- }
- },
"node_modules/eastasianwidth": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz",
@@ -2924,18 +2695,6 @@
"integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==",
"dev": true
},
- "node_modules/enhanced-resolve": {
- "version": "5.18.2",
- "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.2.tgz",
- "integrity": "sha512-6Jw4sE1maoRJo3q8MsSIn2onJFbLTOjY9hlx4DZXmOKvLRd1Ok2kXmAGXaafL2+ijsJZ1ClYbl/pmqr9+k4iUQ==",
- "dependencies": {
- "graceful-fs": "^4.2.4",
- "tapable": "^2.2.0"
- },
- "engines": {
- "node": ">=10.13.0"
- }
- },
"node_modules/error-ex": {
"version": "1.3.2",
"resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
@@ -2948,6 +2707,7 @@
"version": "0.25.5",
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.5.tgz",
"integrity": "sha512-P8OtKZRv/5J5hhz0cUAdu/cLuPIKXpQl1R9pZtvmHWQvrAUVd0UNIPT4IB4W3rNOqVO0rlqHmCIbSwxh/c9yUQ==",
+ "dev": true,
"hasInstallScript": true,
"bin": {
"esbuild": "bin/esbuild"
@@ -3195,6 +2955,7 @@
"version": "6.4.6",
"resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.6.tgz",
"integrity": "sha512-hiFoqpyZcfNm1yc4u8oWCf9A2c4D3QjCrks3zmoVKVxpQRzmPNar1hUJcBG2RQHvEVGDN+Jm81ZheVLAQMK6+w==",
+ "dev": true,
"peerDependencies": {
"picomatch": "^3 || ^4"
},
@@ -3302,6 +3063,7 @@
"version": "2.3.3",
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
"integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
+ "dev": true,
"hasInstallScript": true,
"optional": true,
"os": [
@@ -3399,11 +3161,6 @@
"integrity": "sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==",
"dev": true
},
- "node_modules/graceful-fs": {
- "version": "4.2.11",
- "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
- "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ=="
- },
"node_modules/has-flag": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
@@ -3535,14 +3292,6 @@
"@pkgjs/parseargs": "^0.11.0"
}
},
- "node_modules/jiti": {
- "version": "2.4.2",
- "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.4.2.tgz",
- "integrity": "sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==",
- "bin": {
- "jiti": "lib/jiti-cli.mjs"
- }
- },
"node_modules/js-tokens": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
@@ -3634,223 +3383,6 @@
"node": ">= 0.8.0"
}
},
- "node_modules/lightningcss": {
- "version": "1.30.1",
- "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.30.1.tgz",
- "integrity": "sha512-xi6IyHML+c9+Q3W0S4fCQJOym42pyurFiJUHEcEyHS0CeKzia4yZDEsLlqOFykxOdHpNy0NmvVO31vcSqAxJCg==",
- "dependencies": {
- "detect-libc": "^2.0.3"
- },
- "engines": {
- "node": ">= 12.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- },
- "optionalDependencies": {
- "lightningcss-darwin-arm64": "1.30.1",
- "lightningcss-darwin-x64": "1.30.1",
- "lightningcss-freebsd-x64": "1.30.1",
- "lightningcss-linux-arm-gnueabihf": "1.30.1",
- "lightningcss-linux-arm64-gnu": "1.30.1",
- "lightningcss-linux-arm64-musl": "1.30.1",
- "lightningcss-linux-x64-gnu": "1.30.1",
- "lightningcss-linux-x64-musl": "1.30.1",
- "lightningcss-win32-arm64-msvc": "1.30.1",
- "lightningcss-win32-x64-msvc": "1.30.1"
- }
- },
- "node_modules/lightningcss-darwin-arm64": {
- "version": "1.30.1",
- "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.30.1.tgz",
- "integrity": "sha512-c8JK7hyE65X1MHMN+Viq9n11RRC7hgin3HhYKhrMyaXflk5GVplZ60IxyoVtzILeKr+xAJwg6zK6sjTBJ0FKYQ==",
- "cpu": [
- "arm64"
- ],
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": ">= 12.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/lightningcss-darwin-x64": {
- "version": "1.30.1",
- "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.30.1.tgz",
- "integrity": "sha512-k1EvjakfumAQoTfcXUcHQZhSpLlkAuEkdMBsI/ivWw9hL+7FtilQc0Cy3hrx0AAQrVtQAbMI7YjCgYgvn37PzA==",
- "cpu": [
- "x64"
- ],
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": ">= 12.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/lightningcss-freebsd-x64": {
- "version": "1.30.1",
- "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.30.1.tgz",
- "integrity": "sha512-kmW6UGCGg2PcyUE59K5r0kWfKPAVy4SltVeut+umLCFoJ53RdCUWxcRDzO1eTaxf/7Q2H7LTquFHPL5R+Gjyig==",
- "cpu": [
- "x64"
- ],
- "optional": true,
- "os": [
- "freebsd"
- ],
- "engines": {
- "node": ">= 12.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/lightningcss-linux-arm-gnueabihf": {
- "version": "1.30.1",
- "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.30.1.tgz",
- "integrity": "sha512-MjxUShl1v8pit+6D/zSPq9S9dQ2NPFSQwGvxBCYaBYLPlCWuPh9/t1MRS8iUaR8i+a6w7aps+B4N0S1TYP/R+Q==",
- "cpu": [
- "arm"
- ],
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 12.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/lightningcss-linux-arm64-gnu": {
- "version": "1.30.1",
- "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.30.1.tgz",
- "integrity": "sha512-gB72maP8rmrKsnKYy8XUuXi/4OctJiuQjcuqWNlJQ6jZiWqtPvqFziskH3hnajfvKB27ynbVCucKSm2rkQp4Bw==",
- "cpu": [
- "arm64"
- ],
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 12.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/lightningcss-linux-arm64-musl": {
- "version": "1.30.1",
- "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.30.1.tgz",
- "integrity": "sha512-jmUQVx4331m6LIX+0wUhBbmMX7TCfjF5FoOH6SD1CttzuYlGNVpA7QnrmLxrsub43ClTINfGSYyHe2HWeLl5CQ==",
- "cpu": [
- "arm64"
- ],
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 12.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/lightningcss-linux-x64-gnu": {
- "version": "1.30.1",
- "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.30.1.tgz",
- "integrity": "sha512-piWx3z4wN8J8z3+O5kO74+yr6ze/dKmPnI7vLqfSqI8bccaTGY5xiSGVIJBDd5K5BHlvVLpUB3S2YCfelyJ1bw==",
- "cpu": [
- "x64"
- ],
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 12.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/lightningcss-linux-x64-musl": {
- "version": "1.30.1",
- "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.30.1.tgz",
- "integrity": "sha512-rRomAK7eIkL+tHY0YPxbc5Dra2gXlI63HL+v1Pdi1a3sC+tJTcFrHX+E86sulgAXeI7rSzDYhPSeHHjqFhqfeQ==",
- "cpu": [
- "x64"
- ],
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 12.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/lightningcss-win32-arm64-msvc": {
- "version": "1.30.1",
- "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.30.1.tgz",
- "integrity": "sha512-mSL4rqPi4iXq5YVqzSsJgMVFENoa4nGTT/GjO2c0Yl9OuQfPsIfncvLrEW6RbbB24WtZ3xP/2CCmI3tNkNV4oA==",
- "cpu": [
- "arm64"
- ],
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": ">= 12.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/lightningcss-win32-x64-msvc": {
- "version": "1.30.1",
- "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.30.1.tgz",
- "integrity": "sha512-PVqXh48wh4T53F/1CCu8PIPCxLzWyCnn/9T5W1Jpmdy5h9Cwd+0YQS6/LwhHXSafuc61/xg9Lv5OrCby6a++jg==",
- "cpu": [
- "x64"
- ],
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": ">= 12.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
"node_modules/lines-and-columns": {
"version": "1.2.4",
"resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
@@ -3904,14 +3436,6 @@
"react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0"
}
},
- "node_modules/magic-string": {
- "version": "0.30.17",
- "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.17.tgz",
- "integrity": "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==",
- "dependencies": {
- "@jridgewell/sourcemap-codec": "^1.5.0"
- }
- },
"node_modules/minimatch": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
@@ -3937,35 +3461,11 @@
"version": "7.1.2",
"resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz",
"integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==",
+ "dev": true,
"engines": {
"node": ">=16 || 14 >=14.17"
}
},
- "node_modules/minizlib": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-3.0.2.tgz",
- "integrity": "sha512-oG62iEk+CYt5Xj2YqI5Xi9xWUeZhDI8jjQmC5oThVH5JGCTgIjr7ciJDzC7MBzYd//WvR1OTmP5Q38Q8ShQtVA==",
- "dependencies": {
- "minipass": "^7.1.2"
- },
- "engines": {
- "node": ">= 18"
- }
- },
- "node_modules/mkdirp": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-3.0.1.tgz",
- "integrity": "sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==",
- "bin": {
- "mkdirp": "dist/cjs/src/bin.js"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- }
- },
"node_modules/motion-dom": {
"version": "12.22.0",
"resolved": "https://registry.npmjs.org/motion-dom/-/motion-dom-12.22.0.tgz",
@@ -3999,6 +3499,7 @@
"version": "3.3.11",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz",
"integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==",
+ "dev": true,
"funding": [
{
"type": "github",
@@ -4177,6 +3678,7 @@
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz",
"integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==",
+ "dev": true,
"engines": {
"node": ">=12"
},
@@ -4197,6 +3699,7 @@
"version": "8.5.6",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz",
"integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==",
+ "dev": true,
"funding": [
{
"type": "opencollective",
@@ -4329,15 +3832,6 @@
"react": "^16.8.0 || ^17 || ^18 || ^19"
}
},
- "node_modules/react-icons": {
- "version": "5.5.0",
- "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-5.5.0.tgz",
- "integrity": "sha512-MEFcXdkP3dLo8uumGI5xN3lDFNsRtrjbOEKDLD7yv76v4wpnEq2Lt2qeHaQOr34I/wPN3s3+N08WkQ+CW37Xiw==",
- "license": "MIT",
- "peerDependencies": {
- "react": "*"
- }
- },
"node_modules/react-is": {
"version": "16.13.1",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
@@ -4370,6 +3864,44 @@
"react": ">= 16.3"
}
},
+ "node_modules/react-router": {
+ "version": "7.16.0",
+ "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.16.0.tgz",
+ "integrity": "sha512-wArC8lVyJb3+jM9OpDyW6hLCizACWkvQR/sSGqSs+o5uEXEtGlqdZ4v8hENR3Jad6i+LRkK93q/+bQAcvl6V1A==",
+ "license": "MIT",
+ "dependencies": {
+ "cookie": "^1.0.1",
+ "set-cookie-parser": "^2.6.0"
+ },
+ "engines": {
+ "node": ">=20.0.0"
+ },
+ "peerDependencies": {
+ "react": ">=18",
+ "react-dom": ">=18"
+ },
+ "peerDependenciesMeta": {
+ "react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/react-router-dom": {
+ "version": "7.16.0",
+ "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-7.16.0.tgz",
+ "integrity": "sha512-kMUAbimWB5FVbF4Bce4bJsiKJWLIUHq/mEG8+CFDnCSgltptBiG5nguducmsJeGKytlCvQud9Qhzpn49iduTlA==",
+ "license": "MIT",
+ "dependencies": {
+ "react-router": "7.16.0"
+ },
+ "engines": {
+ "node": ">=20.0.0"
+ },
+ "peerDependencies": {
+ "react": ">=18",
+ "react-dom": ">=18"
+ }
+ },
"node_modules/recrawl-sync": {
"version": "2.2.3",
"resolved": "https://registry.npmjs.org/recrawl-sync/-/recrawl-sync-2.2.3.tgz",
@@ -4426,6 +3958,7 @@
"version": "4.44.1",
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.44.1.tgz",
"integrity": "sha512-x8H8aPvD+xbl0Do8oez5f5o8eMS3trfCghc4HhLAnCkj7Vl0d1JWGs0UF/D886zLW2rOj2QymV/JcSSsw+XDNg==",
+ "dev": true,
"dependencies": {
"@types/estree": "1.0.8"
},
@@ -4465,6 +3998,12 @@
"resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.26.0.tgz",
"integrity": "sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA=="
},
+ "node_modules/set-cookie-parser": {
+ "version": "2.7.2",
+ "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.2.tgz",
+ "integrity": "sha512-oeM1lpU/UvhTxw+g3cIfxXHyJRc/uidd3yK1P242gzHds0udQBYzs3y8j4gCCW+ZJ7ad0yctld8RYO+bdurlvw==",
+ "license": "MIT"
+ },
"node_modules/shebang-command": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
@@ -4519,6 +4058,7 @@
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
"integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
+ "dev": true,
"engines": {
"node": ">=0.10.0"
}
@@ -4690,35 +4230,6 @@
"url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/tailwindcss": {
- "version": "4.1.11",
- "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.1.11.tgz",
- "integrity": "sha512-2E9TBm6MDD/xKYe+dvJZAmg3yxIEDNRc0jwlNyDg/4Fil2QcSLjFKGVff0lAf1jjeaArlG/M75Ey/EYr/OJtBA=="
- },
- "node_modules/tapable": {
- "version": "2.2.2",
- "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.2.tgz",
- "integrity": "sha512-Re10+NauLTMCudc7T5WLFLAwDhQ0JWdrMK+9B2M8zR5hRExKmsRDCBA7/aV/pNJFltmBFO5BAMlQFi/vq3nKOg==",
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/tar": {
- "version": "7.4.3",
- "resolved": "https://registry.npmjs.org/tar/-/tar-7.4.3.tgz",
- "integrity": "sha512-5S7Va8hKfV7W5U6g3aYxXmlPoZVAwUMy9AOKyF2fVuZa2UD3qZjg578OrLRt8PcNN1PleVaL/5/yYATNL0ICUw==",
- "dependencies": {
- "@isaacs/fs-minipass": "^4.0.0",
- "chownr": "^3.0.0",
- "minipass": "^7.1.2",
- "minizlib": "^3.0.1",
- "mkdirp": "^3.0.1",
- "yallist": "^5.0.0"
- },
- "engines": {
- "node": ">=18"
- }
- },
"node_modules/thenify": {
"version": "3.3.1",
"resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz",
@@ -4744,6 +4255,7 @@
"version": "0.2.14",
"resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.14.tgz",
"integrity": "sha512-tX5e7OM1HnYr2+a2C/4V0htOcSQcoSTH9KgJnVvNm5zm/cyEWKJ7j7YutsH9CxMdtOkkLFy2AHrMci9IM8IPZQ==",
+ "dev": true,
"dependencies": {
"fdir": "^6.4.4",
"picomatch": "^4.0.2"
@@ -4821,6 +4333,7 @@
"version": "6.3.5",
"resolved": "https://registry.npmjs.org/vite/-/vite-6.3.5.tgz",
"integrity": "sha512-cZn6NDFE7wdTpINgs++ZJ4N49W2vRp8LCKrn3Ob1kYNtOo21vfDoaV5GzBfLU4MovSAB8uNRm4jgzVQZ+mBzPQ==",
+ "dev": true,
"dependencies": {
"esbuild": "^0.25.0",
"fdir": "^6.4.4",
@@ -5017,27 +4530,6 @@
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
}
},
- "node_modules/yallist": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/yallist/-/yallist-5.0.0.tgz",
- "integrity": "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==",
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/yaml": {
- "version": "2.8.0",
- "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.0.tgz",
- "integrity": "sha512-4lLa/EcQCB0cJkyts+FpIRx5G/llPxfP6VQU5KByHEhLxY3IJCH0f0Hy1MHI8sClTvsIb8qwRJ6R/ZdlDJ/leQ==",
- "optional": true,
- "peer": true,
- "bin": {
- "yaml": "bin.mjs"
- },
- "engines": {
- "node": ">= 14.6"
- }
- },
"node_modules/yocto-queue": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
diff --git a/client/package.json b/client/package.json
index 5185486..df9ea57 100644
--- a/client/package.json
+++ b/client/package.json
@@ -13,7 +13,6 @@
"@chakra-ui/react": "^3.22.0",
"@emotion/react": "^11.14.0",
"@emotion/styled": "^11.14.1",
- "@tailwindcss/vite": "^4.1.11",
"framer-motion": "^12.23.0",
"leaflet": "^1.9.4",
"lucide-react": "^0.539.0",
@@ -22,10 +21,9 @@
"react-dom": "^19.1.0",
"react-grid-layout": "^1.5.2",
"react-hook-form": "^7.62.0",
- "react-icons": "^5.5.0",
"react-leaflet": "^5.0.0",
"react-resizable": "^3.0.5",
- "tailwindcss": "^4.1.11",
+ "react-router-dom": "^7.16.0",
"uuid": "^11.1.0"
},
"devDependencies": {
diff --git a/client/src/App.jsx b/client/src/App.jsx
index af7991e..a19dcd0 100644
--- a/client/src/App.jsx
+++ b/client/src/App.jsx
@@ -1,10 +1,59 @@
-import Dashboard from './components/Dashboard.jsx'
import 'leaflet/dist/leaflet.css';
+import { Routes, Route } from 'react-router-dom';
+import { useRecipe, Grid, GridItem, useDialog } from "@chakra-ui/react";
+import { createContext } from "react";
+import Login from "@/Login.jsx";
+import Sidebar from "./components/Sidebar/Sidebar.jsx";
+import DialogPopup from "@/components/Canvas/CanvasComponents/DialogPopup.jsx";
+import Header from "@/components/Header/Header.jsx";
+import Home from "./components/Canvas/views/Home.jsx";
+import RegionalMap from "./components/Canvas/views/RegionalMap.jsx";
+import Volcano from "@/components/Canvas/views/Volcano.jsx";
+function AppFoundation({children}) {
+ const recipe = useRecipe({ key: "dashboard" });
+ const styles = recipe();
+ const dialog = useDialog();
+
+ return (
+ <>
+
+
+
+
+
+
+
+
+
+ {children}
+
+
+ >
+ )
+}
+
+// function ProtectedRoute({ user, children }) {
+// if (user) return children;
+// else return ;
+// }
function App() {
+ const sidebarContext = createContext(["Home", "Global Map", "Regional Map", "Volcano", "Admin"]);
+ // const [user, setUser] = useState(null);
+
return (
-
+
+ } />
+ } />
+ } />
+ } />
+
);
}
diff --git a/client/src/Login.jsx b/client/src/Login.jsx
new file mode 100644
index 0000000..6f71d4c
--- /dev/null
+++ b/client/src/Login.jsx
@@ -0,0 +1,91 @@
+import { useContext } from 'react';
+import { useForm } from 'react-hook-form';
+import {
+ Button,
+ Field,
+ Input,
+ Stack,
+ useRecipe,
+ Center,
+ Text,
+ Flex,
+ Heading,
+ Highlight,
+ GridItem,
+ Grid
+} from "@chakra-ui/react"
+import { PasswordInput } from "@/components/ui/password-input.jsx";
+
+export default function Login( signedIn, setSignedIn) {
+ const recipe = useRecipe({ key: "dashboard" }); // styling recipes option
+ const styles = recipe(); // use style
+
+ const {
+ register,
+ handleSubmit,
+ formState: { errors, isSubmitSuccessful },
+ } = useForm({
+ defaultValues: {
+ username: "",
+ password: "",
+ }
+ });
+
+ const onSubmit = (data) => {
+ console.log(data);
+ // setUser(data.username);
+ };
+
+ return (
+
+
+
+
+
+
+ VDAP
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
\ No newline at end of file
diff --git a/client/src/components/Canvas/CanvasComponents/AlertLevelWidget.jsx b/client/src/components/Canvas/CanvasComponents/AlertLevelWidget.jsx
index 4f7fd2c..c976876 100644
--- a/client/src/components/Canvas/CanvasComponents/AlertLevelWidget.jsx
+++ b/client/src/components/Canvas/CanvasComponents/AlertLevelWidget.jsx
@@ -2,7 +2,7 @@ import Widget from "./Widget";
import { Stack, Box, Field, Input, Button, Text, Flex } from "@chakra-ui/react";
import { useForm } from "react-hook-form";
import { useState } from "react";
-import { LuAsterisk } from "react-icons/lu";
+import { Asterisk } from 'lucide-react';
export default function AlertLevel({id, isEditable, isDelete, DeleteWidget}) {
const { register, handleSubmit, reset, formState: {errors} } = useForm();
@@ -44,7 +44,7 @@ export default function AlertLevel({id, isEditable, isDelete, DeleteWidget}) {
- Volcano Name
+ Volcano Name
{
@@ -19,7 +19,7 @@ const CustomResizeHandle = React.forwardRef((props, ref) => {
zIndex: "1",
}}
>
-
+
);
});
diff --git a/client/src/components/Canvas/CanvasComponents/FirstWidgetButton.jsx b/client/src/components/Canvas/CanvasComponents/FirstWidgetButton.jsx
index 83c7c9e..53816a5 100644
--- a/client/src/components/Canvas/CanvasComponents/FirstWidgetButton.jsx
+++ b/client/src/components/Canvas/CanvasComponents/FirstWidgetButton.jsx
@@ -1,36 +1,58 @@
import { Box, Menu, Portal } from '@chakra-ui/react'
import WidgetMenu from './WidgetMenu';
+import AlertLevel from "@/components/Canvas/CanvasComponents/AlertLevelWidget.jsx";
export default function FirstWidgetButton({ appendWidget }) {
- const triggerItem = (<>
-
-
- Add Your First Widget
-
-
- >);
+ const triggerItem = (
+ <>
+
+
+ Add Your First Widget
+
+
+ >
+ );
const positioning = { placement: "bottom-middle" };
- const WidgetMenuProps = { appendWidget, triggerItem, positioning };
+ // const WidgetMenuProps = { appendWidget, triggerItem, positioning };
return (
-
+ //
+
+ {triggerItem}
+
+
+
+ appendWidget(AlertLevel, 4, 7, 4, 7, 8, 14)} // width and height are passed through here for each widget
+ >
+ Alert Level
+
+ CO2
+ IVANS
+ Plume Heights
+ Alert Level Changes
+
+
+
+
);
}
\ No newline at end of file
diff --git a/client/src/components/Canvas/CanvasComponents/MapSettingsButton.jsx b/client/src/components/Canvas/CanvasComponents/MapSettingsButton.jsx
index 0011f88..1cb87e3 100644
--- a/client/src/components/Canvas/CanvasComponents/MapSettingsButton.jsx
+++ b/client/src/components/Canvas/CanvasComponents/MapSettingsButton.jsx
@@ -1,8 +1,7 @@
import { Box, Checkbox, Separator , CloseButton, Text, chakra, Field, IconButton, Icon, Input, Fieldset, Flex } from "@chakra-ui/react";
import { useState } from "react";
-import { FiSettings } from "react-icons/fi";
-import { IoIosArrowDown } from "react-icons/io";
-import { IoIosArrowUp } from "react-icons/io";
+import { ChevronDown } from 'lucide-react';
+import { ChevronUp } from 'lucide-react';
export default function MapSettingsButton() {
const [open, setOpen] = useState(false);
@@ -16,7 +15,7 @@ export default function MapSettingsButton() {
):(
setOpen(true)}>
-
+
);
}
@@ -57,7 +56,7 @@ function Lightning() {
Lightning
setOpen(!open)}>
- {open ? ():()}
+ {open ? ():()}
{open && ()}
diff --git a/client/src/components/Canvas/CanvasComponents/SearchBar.jsx b/client/src/components/Canvas/CanvasComponents/SearchBar.jsx
index 5d116a4..8c4c3e9 100644
--- a/client/src/components/Canvas/CanvasComponents/SearchBar.jsx
+++ b/client/src/components/Canvas/CanvasComponents/SearchBar.jsx
@@ -1,9 +1,9 @@
import { Input, InputGroup } from "@chakra-ui/react";
-import { FiSearch } from "react-icons/fi"
+import { Search } from 'lucide-react';
export function SearchBar({ placeholder="Enter a volcano to search", size="sm", width="210px" }) {
return (
- }>
+ }>
Add Widget >);
+ const triggerItem = (<> Add Widget >);
const WidgetMenuProps = { appendWidget, triggerItem }
return (
-
+
diff --git a/client/src/components/Canvas/CanvasComponents/Tooltip.jsx b/client/src/components/Canvas/CanvasComponents/Tooltip.jsx
index 4c73b74..0037254 100644
--- a/client/src/components/Canvas/CanvasComponents/Tooltip.jsx
+++ b/client/src/components/Canvas/CanvasComponents/Tooltip.jsx
@@ -1,11 +1,9 @@
import { useState, useRef } from "react";
-import { chakra, useSlotRecipe } from "@chakra-ui/react";
+import { chakra } from "@chakra-ui/react";
export default function Tooltip ({tooltipkey, content, sidebarIsOpen, children}) {
const [isVisible, setIsVisible] = useState(false);
- const recipe = useSlotRecipe({ key: "sidebar" });
- const styles = recipe();
const timeoutId = useRef(null);
return (
@@ -30,22 +28,20 @@ export default function Tooltip ({tooltipkey, content, sidebarIsOpen, children})
>
{children}
{isVisible && !sidebarIsOpen && (
- <>
-
- {content}
-
- >
+
+ {content}
+
)}
)
diff --git a/client/src/components/Canvas/CanvasComponents/Widget.jsx b/client/src/components/Canvas/CanvasComponents/Widget.jsx
index f9fc0d1..b67ce29 100644
--- a/client/src/components/Canvas/CanvasComponents/Widget.jsx
+++ b/client/src/components/Canvas/CanvasComponents/Widget.jsx
@@ -1,37 +1,30 @@
import { useSlotRecipe, chakra, Flex, CloseButton, Text, IconButton } from "@chakra-ui/react"
-import { GrUndo } from "react-icons/gr";
+import { Undo } from 'lucide-react';
export default function Widget(props) {
// deconstructing props
const { id, title, isEditable, isDelete, DeleteWidget, isSubmit, setIsSubmit, children } = props;
+
const recipe = useSlotRecipe({ key: "widget" });
const styles = recipe();
-
return (
<>
- {isDelete ? (
- <>
-
- {title}
- DeleteWidget(id)} size="xs" _hover={{bg: "tomato", color: "white"}}/>
-
- >
- ):(
- <>
-
- {title}
- {isSubmit ? (
- setIsSubmit(false)} size="xs" bg="base300" cursor="pointer">
- ):(null)}
-
- >
- )}
+
+ {title}
+ {isDelete ? (
+ DeleteWidget(id)} size="xs" _hover={{bg: "tomato", color: "white"}}/>
+ ):(
+ isSubmit ? (
+ setIsSubmit(false)} size="xs" bg="base300" cursor="pointer">
+ ):null
+ )}
+
-
+
{children}
-
+
>
);
}
diff --git a/client/src/components/Canvas/views/Home.jsx b/client/src/components/Canvas/views/Home.jsx
index a04309f..b8214b6 100644
--- a/client/src/components/Canvas/views/Home.jsx
+++ b/client/src/components/Canvas/views/Home.jsx
@@ -1,4 +1,5 @@
import { HStack, Flex, Tabs } from "@chakra-ui/react";
+import { useState } from "react";
import MyDashboard from "./HomeTabs/MyDashboard";
import { SearchBar } from "../CanvasComponents/SearchBar";
import { SettingsButton } from "../CanvasComponents/SettingsButton";
@@ -13,14 +14,17 @@ import { v4 as uuid } from 'uuid';
import { CanvasHeaderTabs } from '../CanvasComponents/CanvasHeaderTabs';
import { DASHBOARD_TABS } from "@/constants/viewKeys";
-export default function Home(props) {
- // deconstructing props
- const { view, layout, setLayout, setOriginalLayout, onLayoutChange, onChangeView, onCancel, setOriginalWidgets,
- isDelete, setIsDelete, beginEditIfNeeded, isEditable, setIsEditable, widgetArray, setWidgetArray } = props;
+export default function Home() {
+ const [isEditable, setIsEditable] = useState(false); // editable=true means static=false (vice versa)
+ const [isDelete, setIsDelete] = useState(false);
+ const [originalLayout, setOriginalLayout] = useState([]);
+ const [originalWidgets, setOriginalWidgets] = useState([]);
+ const [layout, setLayout] = useState([]);
+ const [widgetArray, setWidgetArray] = useState([]);
+
+ function appendWidget(name, w, h, min_w, minh, max_w, max_h) {
+ saveLayoutState(); // Save state before anything else
- function appendWidget(name, w, h, minw, minh, maxw, maxh) {
- beginEditIfNeeded(); // Save state before anything else
-
const newID = uuid(); // could be replaced with something else like guid
const COLS = 16;
const W = w ?? 3;
@@ -30,7 +34,7 @@ export default function Home(props) {
...widgetArray,
{i: newID, widget: name }
]);
- // onAddWidget(newID, w, h, minw, minh, maxw, maxh); // updating array containing info on layout of widgets
+ // onAddWidget(newID, w, h, min_w, minh, max_w, max_h); // updating array containing info on layout of widgets
setLayout(prev => [
...prev,
@@ -40,10 +44,10 @@ export default function Home(props) {
y: 0,
w: w,
h: h,
- minW: minw,
+ minW: min_w,
minH: minh,
- maxW: maxw,
- maxH: maxh,
+ maxW: max_w,
+ maxH: max_h,
static: false,
resizeHandles: ['se']
},
@@ -67,7 +71,7 @@ export default function Home(props) {
const onEditWidgets = () => {
console.log("Start deleting widgets...");
- beginEditIfNeeded(); // Save state before anything else
+ saveLayoutState(); // Save state before anything else
setLayout(prevLayout =>
prevLayout.map(item => ({
...item,
@@ -96,39 +100,52 @@ export default function Home(props) {
else return;
}
+
+ const saveLayoutState = () => {
+ if ( !isEditable ) {
+ setOriginalLayout(layout);
+ setOriginalWidgets(widgetArray);
+ }
+ };
+
+ const onCancel = () => {
+ console.log("canceling changes...");
+ console.log(originalWidgets);
+ if (originalLayout.length) {
+ setLayout(originalLayout.map(item => ({
+ ...item,
+ static: true
+ })));
+ }
+ setWidgetArray(originalWidgets);
+ setIsEditable(false);
+ setIsDelete(false);
+ setOriginalLayout([]);
+ setOriginalWidgets([]);
+ }
+
+ const onLayoutChange = (newLayout) => setLayout(newLayout);
+
+
// Prop Forwarding
- const MyDashboardProps = { layout, onLayoutChange, isEditable, beginEditIfNeeded, isDelete, DeleteWidget, widgetArray, appendWidget };
+ const MyDashboardProps = { layout, onLayoutChange, isEditable, saveLayoutState, isDelete, DeleteWidget, widgetArray, appendWidget };
const settingsButtonProps = { onEditWidgets, appendWidget };
return (
- /* HEADER */
- {
- const nextView = e.value;
- onChangeView(nextView);
- }}
- >
-
-
+ /* SUB HEADER */
+
+
+ {/* TABS */}
+ {/* */} {/* TODO: rename to SubHeaderTabs */}
+
+ {DASHBOARD_TABS.map(({ value, label }) =>
+
+ { label }
+
+ )}
+
+
+ {/* EDIT MODE BUTTONS */}
{isEditable ? (
<>
diff --git a/client/src/components/Canvas/views/HomeTabs/MyDashboard.jsx b/client/src/components/Canvas/views/HomeTabs/MyDashboard.jsx
index 91364e2..a88be56 100644
--- a/client/src/components/Canvas/views/HomeTabs/MyDashboard.jsx
+++ b/client/src/components/Canvas/views/HomeTabs/MyDashboard.jsx
@@ -4,7 +4,6 @@ import CustomResizeHandle from '../../CanvasComponents/CustomResizeHandle';
import FirstWidgetButton from '../../CanvasComponents/FirstWidgetButton';
export default function MyDashboard({layout, onLayoutChange, isEditable, isDelete, DeleteWidget, widgetArray, appendWidget}) {
- console.log("rendering MyDashboard");
const recipe = useSlotRecipe({ key: "widget" });
const styles = recipe(); // using root recipe for widget below
const ResponsiveGridLayout = WidthProvider(GridLayout); // canvas width now adjusts to window size
@@ -12,9 +11,6 @@ export default function MyDashboard({layout, onLayoutChange, isEditable, isDelet
const handleDragStop = () => { document.body.style.userSelect = ""; }; // allow text highlighting all other times
let merged = [];
- console.log("widgetArray: ", widgetArray);
- console.log("layout: ", layout);
-
if (widgetArray.length && layout.length) {
const widgetMap = new Map(widgetArray.map(item => [item.i, item]));
merged = layout.map(item => {
@@ -23,7 +19,7 @@ export default function MyDashboard({layout, onLayoutChange, isEditable, isDelet
...widgetMap.get(item.i)
};
});
- };
+ }
// Show large 'Add Widget' button when dashboard is empty
if ( !layout.length ) {
@@ -36,39 +32,43 @@ export default function MyDashboard({layout, onLayoutChange, isEditable, isDelet
bg="gray.150"
borderRadius="md"
>
-
+
);
}
// Show responsive grid of widgets
return (
-
- }
- >
- { merged.map((item) => {
- const Widget = item.widget;
- return (
-
-
-
- );
- })
- }
-
-
+ }
+ >
+ { merged.map((item) => {
+ const Widget = item.widget;
+ return (
+
+
+
+ );
+ })
+ }
+
);
}
diff --git a/client/src/components/Header/Header.jsx b/client/src/components/Header/Header.jsx
index a89eed9..60fa076 100644
--- a/client/src/components/Header/Header.jsx
+++ b/client/src/components/Header/Header.jsx
@@ -1,5 +1,7 @@
-import { chakra, useRecipe, Box, Button, Stack, Text, Flex } from "@chakra-ui/react"
+import { useRecipe, Button, Stack, Text, Flex } from "@chakra-ui/react"
import UserAvatarMenu from "./UserAvatarMenu.jsx";
+import { useNavigate } from "react-router-dom";
+import { NavLink } from "react-router-dom";
//TODO: Dynamically populate per each user
const user = {
@@ -8,13 +10,16 @@ const user = {
// avatar: "src\\assets\\user_profile.svg"
}
-export default function Header({ onChangeView }) {
+export default function Header() {
+ const navigate = useNavigate();
const recipe = useRecipe({ key: "header" });
const styles = recipe();
return (
-
-
+
+
{user.name}
@@ -23,10 +28,9 @@ export default function Header({ onChangeView }) {
-
+
);
}
diff --git a/client/src/components/Header/UserAvatarMenu.jsx b/client/src/components/Header/UserAvatarMenu.jsx
index 14bbdc9..7741183 100644
--- a/client/src/components/Header/UserAvatarMenu.jsx
+++ b/client/src/components/Header/UserAvatarMenu.jsx
@@ -1,7 +1,8 @@
-import { Avatar, Menu, Portal, Box } from "@chakra-ui/react"
+import { Avatar, Menu, Portal, Box } from "@chakra-ui/react";
+import { NavLink } from "react-router-dom";
-export default function UserAvatarMenu({ onChangeView, name, avatar }) {
+export default function UserAvatarMenu({ name, avatar }) {
return (
@@ -21,7 +22,7 @@ export default function UserAvatarMenu({ onChangeView, name, avatar }) {
{/* zIndex: overlay = 1300 */}
- onChangeView("personal")}>
+
Settings
console.log("Log out triggered")}>
diff --git a/client/src/components/Sidebar/Sidebar.jsx b/client/src/components/Sidebar/Sidebar.jsx
index 4829f91..7fe5267 100644
--- a/client/src/components/Sidebar/Sidebar.jsx
+++ b/client/src/components/Sidebar/Sidebar.jsx
@@ -1,89 +1,61 @@
import { useSlotRecipe, Box, Button, IconButton } from "@chakra-ui/react";
import { ColorModeButton, useColorMode } from "@/components/ui/color-mode";
+import { useState } from "react";
+import { NavLink } from "react-router-dom";
import Tooltip from "../Canvas/CanvasComponents/Tooltip.jsx";
-import { FaVolcano } from "react-icons/fa6";
-import { FaHome } from "react-icons/fa";
-import { FaGlobeAmericas } from "react-icons/fa";
-import { FaMapMarkerAlt } from "react-icons/fa";
-import { HiUsers } from "react-icons/hi2";
-import { VscThreeBars } from "react-icons/vsc";
-import { MdOutlineSecurity } from "react-icons/md";
-import { IoPersonCircleSharp } from "react-icons/io5";
-import { useState, useEffect, useMemo } from "react";
-import { DASHBOARD_VIEWS } from "@/constants/viewKeys";
-import { KeyRound } from 'lucide-react';
+import { Mountain, House, Earth, MapPin, ShieldUser, Menu, CircleUserRound, KeyRound } from 'lucide-react';
-export default function Sidebar({ view, onChangeView, darkMode, setDarkMode }) {
+export default function Sidebar() {
+ const { toggleColorMode } = useColorMode();
const [isOpen, setIsOpen] = useState(true);
const [activeButton, setActiveButton] = useState(0)
const recipe = useSlotRecipe({ key: "sidebar" });
const styles = recipe();
- const { toggleColorMode } = useColorMode();
- const buttons = useMemo(() => {
- if (["settings", "personal", "security"].includes(view)) {
- return [
- {icon: IoPersonCircleSharp, name: "Personal Info", view: "personal"},
- {icon: KeyRound, name: "Security", view: "security"},
- ];
- }
- return [
- {icon: FaHome, name: "Home", view: "mydashboard"},
- {icon: FaGlobeAmericas, name: "Global Map", view: "global"},
- {icon: FaMapMarkerAlt, name: "Regional Map", view: "regional"},
- {icon: FaVolcano, name: "Volcano", view: "volcanohome"},
- {icon: HiUsers, name: "Admin", view: "medataentry"}
- ];
- }, [view]);
+ // const buttons = useMemo(() => {
+ // if (["settings", "personal", "security"].includes(view)) {
+ // return [
+ // {icon: CircleUserRound, name: "Personal Info", url: "/personal"},
+ // {icon: KeyRound, name: "Security", url: "/security"},
+ // ];
+ // }
+ // return [
+ // {icon: House, name: "Home", url: "/mydashboard"},
+ // {icon: Earth, name: "Global Map", url: "/global"},
+ // {icon: MapPin, name: "Regional Map", url: "/regional"},
+ // {icon: Mountain, name: "Volcano", url: "/volcanohome"},
+ // {icon: ShieldUser, name: "Admin", url: "/medataentry"}
+ // ];
+ // }, [view]);
+
+ const buttons = [
+ {icon: House, name: "Home", url: "/home"},
+ {icon: Earth, name: "Global Map", url: "/GlobalMap"},
+ {icon: MapPin, name: "Regional Map", url: "/regional-map"},
+ {icon: Mountain, name: "Volcano", url: "/volcano"},
+ {icon: ShieldUser, name: "Admin", url: "/medataentry"}
+ ];
const toggleSidebar = () => {
if (isOpen) setIsOpen(false);
else setIsOpen(true);
};
- // Track currrent view from both Sidebar and Canvas when 'view' changes
- useEffect(() => {
- console.log("Current view = ", view);
- const newIndex = buttons.findIndex((btn) => {
- if (btn.view === "mydashboard") {
- return DASHBOARD_VIEWS.includes(view);
- }
- return btn.view === view;
- });
- if (newIndex !== -1 ) {
- setActiveButton(newIndex);
- }
- }, [view]);
-
return (
-
-
-
+
+
+
{buttons.map((button, idx) => {
const Icon = button.icon;
return (
-
-