diff --git a/mdm-front/index.html b/mdm-front/index.html index 9b4cb92..b293216 100644 --- a/mdm-front/index.html +++ b/mdm-front/index.html @@ -4,7 +4,7 @@ - mdm-front + MDM
diff --git a/mdm-front/package-lock.json b/mdm-front/package-lock.json index 16714bc..a2d1cf2 100644 --- a/mdm-front/package-lock.json +++ b/mdm-front/package-lock.json @@ -9,14 +9,20 @@ "version": "0.0.0", "dependencies": { "@apollo/client": "^4.1.9", + "@heroui/react": "^3.0.3", "@hookform/resolvers": "^5.2.2", + "@internationalized/date": "^3.12.1", + "@radix-ui/react-accordion": "^1.2.12", "@tanstack/react-table": "^8.21.3", + "date-fns": "^4.1.0", "echarts": "^6.0.0", "echarts-for-react": "^3.0.6", + "framer-motion": "^12.38.0", "graphql": "^16.13.2", "leaflet": "^1.9.4", "lucide-react": "^1.9.0", "react": "^19.2.5", + "react-datepicker": "^9.1.0", "react-dom": "^19.2.5", "react-hook-form": "^7.73.1", "react-leaflet": "^5.0.0", @@ -30,6 +36,7 @@ "@types/leaflet": "^1.9.21", "@types/node": "^24.12.2", "@types/react": "^19.2.14", + "@types/react-datepicker": "^6.2.0", "@types/react-dom": "^19.2.3", "@vitejs/plugin-react": "^6.0.1", "eslint": "^10.2.1", @@ -41,6 +48,50 @@ "vite": "^8.0.10" } }, + "node_modules/@adobe/react-spectrum": { + "version": "3.47.0", + "resolved": "https://registry.npmjs.org/@adobe/react-spectrum/-/react-spectrum-3.47.0.tgz", + "integrity": "sha512-EDQuMzz0kUeiMUUlxoeLFQyyxOXaAC7qlBw2PYOUfFLYd87xcV7VVV0JxiYx8zGk1IIY3UgQHgXrS1fv7CgezQ==", + "license": "Apache-2.0", + "dependencies": { + "@internationalized/date": "^3.12.1", + "@react-types/shared": "^3.34.0", + "@spectrum-icons/ui": "^3.7.0", + "@spectrum-icons/workflow": "^4.3.0", + "@swc/helpers": "^0.5.0", + "client-only": "^0.0.1", + "clsx": "^2.0.0", + "react-aria": "3.48.0", + "react-aria-components": "1.17.0", + "react-stately": "3.46.0", + "react-transition-group": "^4.4.5", + "use-sync-external-store": "^1.6.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/@adobe/react-spectrum-ui": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@adobe/react-spectrum-ui/-/react-spectrum-ui-1.2.1.tgz", + "integrity": "sha512-wcrbEE2O/9WnEn6avBnaVRRx88S5PLFsPLr4wffzlbMfXeQsy+RMQwaJd3cbzrn18/j04Isit7f7Emfn0dhrJA==", + "license": "Apache-2.0", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/@adobe/react-spectrum-workflow": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@adobe/react-spectrum-workflow/-/react-spectrum-workflow-2.3.5.tgz", + "integrity": "sha512-b53VIPwPWKb/T5gzE3qs+QlGP5gVrw/LnWV3xMksDU+CRl3rzOKUwxIGiZO8ICyYh1WiyqY4myGlPU/nAynBUg==", + "license": "Apache-2.0", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" + } + }, "node_modules/@apollo/client": { "version": "4.1.9", "resolved": "https://registry.npmjs.org/@apollo/client/-/client-4.1.9.tgz", @@ -270,6 +321,15 @@ "node": ">=6.0.0" } }, + "node_modules/@babel/runtime": { + "version": "7.29.2", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.29.2.tgz", + "integrity": "sha512-JiDShH45zKHWyGe4ZNVRrCjBz8Nh9TMmZG1kh4QTK8hCBTWBi8Da+i7s1fJw7/lYpM4ccepSNfqzZ/QvABBi5g==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@babel/template": { "version": "7.28.6", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.28.6.tgz", @@ -480,6 +540,110 @@ "node": "^20.19.0 || ^22.13.0 || >=24" } }, + "node_modules/@floating-ui/core": { + "version": "1.7.5", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.7.5.tgz", + "integrity": "sha512-1Ih4WTWyw0+lKyFMcBHGbb5U5FtuHJuujoyyr5zTaWS5EYMeT6Jb2AuDeftsCsEuchO+mM2ij5+q9crhydzLhQ==", + "license": "MIT", + "dependencies": { + "@floating-ui/utils": "^0.2.11" + } + }, + "node_modules/@floating-ui/dom": { + "version": "1.7.6", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.7.6.tgz", + "integrity": "sha512-9gZSAI5XM36880PPMm//9dfiEngYoC6Am2izES1FF406YFsjvyBMmeJ2g4SAju3xWwtuynNRFL2s9hgxpLI5SQ==", + "license": "MIT", + "dependencies": { + "@floating-ui/core": "^1.7.5", + "@floating-ui/utils": "^0.2.11" + } + }, + "node_modules/@floating-ui/react": { + "version": "0.27.19", + "resolved": "https://registry.npmjs.org/@floating-ui/react/-/react-0.27.19.tgz", + "integrity": "sha512-31B8h5mm8YxotlE7/AU/PhNAl8eWxAmjL/v2QOxroDNkTFLk3Uu82u63N3b6TXa4EGJeeZLVcd/9AlNlVqzeog==", + "license": "MIT", + "dependencies": { + "@floating-ui/react-dom": "^2.1.8", + "@floating-ui/utils": "^0.2.11", + "tabbable": "^6.0.0" + }, + "peerDependencies": { + "react": ">=17.0.0", + "react-dom": ">=17.0.0" + } + }, + "node_modules/@floating-ui/react-dom": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.8.tgz", + "integrity": "sha512-cC52bHwM/n/CxS87FH0yWdngEZrjdtLW/qVruo68qg+prK7ZQ4YGdut2GyDVpoGeAYe/h899rVeOVm6Oi40k2A==", + "license": "MIT", + "dependencies": { + "@floating-ui/dom": "^1.7.6" + }, + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, + "node_modules/@floating-ui/utils": { + "version": "0.2.11", + "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.11.tgz", + "integrity": "sha512-RiB/yIh78pcIxl6lLMG0CgBXAZ2Y0eVHqMPYugu+9U0AeT6YBeiJpf7lbdJNIugFP5SIjwNRgo4DhR1Qxi26Gg==", + "license": "MIT" + }, + "node_modules/@formatjs/ecma402-abstract": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/@formatjs/ecma402-abstract/-/ecma402-abstract-2.3.6.tgz", + "integrity": "sha512-HJnTFeRM2kVFVr5gr5kH1XP6K0JcJtE7Lzvtr3FS/so5f1kpsqqqxy5JF+FRaO6H2qmcMfAUIox7AJteieRtVw==", + "license": "MIT", + "dependencies": { + "@formatjs/fast-memoize": "2.2.7", + "@formatjs/intl-localematcher": "0.6.2", + "decimal.js": "^10.4.3", + "tslib": "^2.8.0" + } + }, + "node_modules/@formatjs/fast-memoize": { + "version": "2.2.7", + "resolved": "https://registry.npmjs.org/@formatjs/fast-memoize/-/fast-memoize-2.2.7.tgz", + "integrity": "sha512-Yabmi9nSvyOMrlSeGGWDiH7rf3a7sIwplbvo/dlz9WCIjzIQAfy1RMf4S0X3yG724n5Ghu2GmEl5NJIV6O9sZQ==", + "license": "MIT", + "dependencies": { + "tslib": "^2.8.0" + } + }, + "node_modules/@formatjs/icu-messageformat-parser": { + "version": "2.11.4", + "resolved": "https://registry.npmjs.org/@formatjs/icu-messageformat-parser/-/icu-messageformat-parser-2.11.4.tgz", + "integrity": "sha512-7kR78cRrPNB4fjGFZg3Rmj5aah8rQj9KPzuLsmcSn4ipLXQvC04keycTI1F7kJYDwIXtT2+7IDEto842CfZBtw==", + "license": "MIT", + "dependencies": { + "@formatjs/ecma402-abstract": "2.3.6", + "@formatjs/icu-skeleton-parser": "1.8.16", + "tslib": "^2.8.0" + } + }, + "node_modules/@formatjs/icu-skeleton-parser": { + "version": "1.8.16", + "resolved": "https://registry.npmjs.org/@formatjs/icu-skeleton-parser/-/icu-skeleton-parser-1.8.16.tgz", + "integrity": "sha512-H13E9Xl+PxBd8D5/6TVUluSpxGNvFSlN/b3coUp0e0JpuWXXnQDiavIpY3NnvSp4xhEMoXyyBvVfdFX8jglOHQ==", + "license": "MIT", + "dependencies": { + "@formatjs/ecma402-abstract": "2.3.6", + "tslib": "^2.8.0" + } + }, + "node_modules/@formatjs/intl-localematcher": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/@formatjs/intl-localematcher/-/intl-localematcher-0.6.2.tgz", + "integrity": "sha512-XOMO2Hupl0wdd172Y06h6kLpBz6Dv+J4okPLl4LPtzbr8f66WbIoy4ev98EBuZ6ZK4h5ydTN6XneT4QVpD7cdA==", + "license": "MIT", + "dependencies": { + "tslib": "^2.8.0" + } + }, "node_modules/@graphql-typed-document-node/core": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/@graphql-typed-document-node/core/-/core-3.2.0.tgz", @@ -489,6 +653,44 @@ "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, + "node_modules/@heroui/react": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@heroui/react/-/react-3.0.3.tgz", + "integrity": "sha512-UJPOxg3IbS5KtI2GLP7S56KrSBn/r4xQyntCVpnPzgoT7JuciB4dq7IhckuDNHcrdIPO45JrKHGJz2hiYxaRGg==", + "license": "MIT", + "dependencies": { + "@heroui/styles": "3.0.3", + "@radix-ui/react-avatar": "1.1.11", + "@react-aria/i18n": "3.13.0", + "@react-aria/ssr": "3.10.0", + "@react-aria/utils": "3.34.0", + "@react-stately/utils": "3.12.0", + "@react-types/color": "3.2.0", + "@react-types/shared": "3.34.0", + "input-otp": "1.4.2", + "react-aria-components": "1.17.0", + "tailwind-merge": "3.4.0", + "tailwind-variants": "3.2.2" + }, + "peerDependencies": { + "react": ">=19.0.0", + "react-dom": ">=19.0.0", + "tailwindcss": ">=4.0.0" + } + }, + "node_modules/@heroui/styles": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@heroui/styles/-/styles-3.0.3.tgz", + "integrity": "sha512-DtN5QWfLVxy6DSDNgtUuHVU/h4G+dfoDHHxGVZRW6plCEh1Rc5Yc7YW7b8JBiYCknSRx/fqLXpas3Fe5Q5XJSw==", + "license": "MIT", + "dependencies": { + "tailwind-variants": "3.2.2", + "tw-animate-css": "1.4.0" + }, + "peerDependencies": { + "tailwindcss": ">=4.0.0" + } + }, "node_modules/@hookform/resolvers": { "version": "5.2.2", "resolved": "https://registry.npmjs.org/@hookform/resolvers/-/resolvers-5.2.2.tgz", @@ -567,6 +769,43 @@ "url": "https://github.com/sponsors/nzakas" } }, + "node_modules/@internationalized/date": { + "version": "3.12.1", + "resolved": "https://registry.npmjs.org/@internationalized/date/-/date-3.12.1.tgz", + "integrity": "sha512-6IedsVWXyq4P9Tj+TxuU8WGWM70hYLl12nbYU8jkikVpa6WXapFazPUcHUMDMoWftIDE2ILDkFFte6W2nFCkRQ==", + "license": "Apache-2.0", + "dependencies": { + "@swc/helpers": "^0.5.0" + } + }, + "node_modules/@internationalized/message": { + "version": "3.1.9", + "resolved": "https://registry.npmjs.org/@internationalized/message/-/message-3.1.9.tgz", + "integrity": "sha512-x03MSVTaB/4JHtW1VAYaY/2cCuBrHbWM6ZvlgpKdnSdW28tZbqpR673RJrVJyXWRw1bpgYN89Tz7ohX5tgNgPA==", + "license": "Apache-2.0", + "dependencies": { + "@swc/helpers": "^0.5.0", + "intl-messageformat": "^10.1.0" + } + }, + "node_modules/@internationalized/number": { + "version": "3.6.6", + "resolved": "https://registry.npmjs.org/@internationalized/number/-/number-3.6.6.tgz", + "integrity": "sha512-iFgmQaXHE0vytNfpLZWOC2mEJCBRzcUxt53Xf/yCXG93lRvqas237i3r7X4RKMwO3txiyZD4mQjKAByFv6UGSQ==", + "license": "Apache-2.0", + "dependencies": { + "@swc/helpers": "^0.5.0" + } + }, + "node_modules/@internationalized/string": { + "version": "3.2.8", + "resolved": "https://registry.npmjs.org/@internationalized/string/-/string-3.2.8.tgz", + "integrity": "sha512-NdbMQUSfXLYIQol5VyMtinm9pZDciiMfN7RtmSuSB78io1hqwJ0naYfxyW6vgxWBkzWymQa/3uLDlbfmshtCaA==", + "license": "Apache-2.0", + "dependencies": { + "@swc/helpers": "^0.5.0" + } + }, "node_modules/@jridgewell/gen-mapping": { "version": "0.3.13", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", @@ -960,6 +1199,458 @@ "url": "https://opencollective.com/parcel" } }, + "node_modules/@radix-ui/primitive": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.3.tgz", + "integrity": "sha512-JTF99U/6XIjCBo0wqkU5sK10glYe27MRRsfwoiq5zzOEZLHU3A3KCMa5X/azekYRCJ0HlwI0crAXS/5dEHTzDg==", + "license": "MIT" + }, + "node_modules/@radix-ui/react-accordion": { + "version": "1.2.12", + "resolved": "https://registry.npmjs.org/@radix-ui/react-accordion/-/react-accordion-1.2.12.tgz", + "integrity": "sha512-T4nygeh9YE9dLRPhAHSeOZi7HBXo+0kYIPJXayZfvWOWA0+n3dESrZbjfDPUABkUNym6Hd+f2IR113To8D2GPA==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-collapsible": "1.1.12", + "@radix-ui/react-collection": "1.1.7", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-direction": "1.1.1", + "@radix-ui/react-id": "1.1.1", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-controllable-state": "1.2.2" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-avatar": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/@radix-ui/react-avatar/-/react-avatar-1.1.11.tgz", + "integrity": "sha512-0Qk603AHGV28BOBO34p7IgD5m+V5Sg/YovfayABkoDDBM5d3NCx0Mp4gGrjzLGes1jV5eNOE1r3itqOR33VC6Q==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-context": "1.1.3", + "@radix-ui/react-primitive": "2.1.4", + "@radix-ui/react-use-callback-ref": "1.1.1", + "@radix-ui/react-use-is-hydrated": "0.1.0", + "@radix-ui/react-use-layout-effect": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-avatar/node_modules/@radix-ui/react-context": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.3.tgz", + "integrity": "sha512-ieIFACdMpYfMEjF0rEf5KLvfVyIkOz6PDGyNnP+u+4xQ6jny3VCgA4OgXOwNx2aUkxn8zx9fiVcM8CfFYv9Lxw==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-avatar/node_modules/@radix-ui/react-primitive": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.4.tgz", + "integrity": "sha512-9hQc4+GNVtJAIEPEqlYqW5RiYdrr8ea5XQ0ZOnD6fgru+83kqT15mq2OCcbe8KnjRZl5vF3ks69AKz3kh1jrhg==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-slot": "1.2.4" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-avatar/node_modules/@radix-ui/react-slot": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.4.tgz", + "integrity": "sha512-Jl+bCv8HxKnlTLVrcDE8zTMJ09R9/ukw4qBs/oZClOfoQk/cOTbDn+NceXfV7j09YPVQUryJPHurafcSg6EVKA==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-collapsible": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/@radix-ui/react-collapsible/-/react-collapsible-1.1.12.tgz", + "integrity": "sha512-Uu+mSh4agx2ib1uIGPP4/CKNULyajb3p92LsVXmH2EHVMTfZWpll88XJ0j4W0z3f8NK1eYl1+Mf/szHPmcHzyA==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-id": "1.1.1", + "@radix-ui/react-presence": "1.1.5", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-controllable-state": "1.2.2", + "@radix-ui/react-use-layout-effect": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-collection": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-1.1.7.tgz", + "integrity": "sha512-Fh9rGN0MoI4ZFUNyfFVNU4y9LUz93u9/0K+yLgA2bwRojxM8JU1DyvvMBabnZPBgMWREAJvU2jjVzq+LrFUglw==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-slot": "1.2.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-compose-refs": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.2.tgz", + "integrity": "sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-context": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.2.tgz", + "integrity": "sha512-jCi/QKUM2r1Ju5a3J64TH2A5SpKAgh0LpknyqdQ4m6DCV0xJ2HG1xARRwNGPQfi1SLdLWZ1OJz6F4OMBBNiGJA==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-direction": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-direction/-/react-direction-1.1.1.tgz", + "integrity": "sha512-1UEWRX6jnOA2y4H5WczZ44gOOjTEmlqv1uNW4GAJEO5+bauCBhv8snY65Iw5/VOS/ghKN9gr2KjnLKxrsvoMVw==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-id": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.1.1.tgz", + "integrity": "sha512-kGkGegYIdQsOb4XjsfM97rXsiHaBwco+hFI66oO4s9LU+PLAC5oJ7khdOVFxkhsmlbpUqDAvXw11CluXP+jkHg==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-use-layout-effect": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-presence": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.5.tgz", + "integrity": "sha512-/jfEwNDdQVBCNvjkGit4h6pMOzq8bHkopq458dPt2lMjx+eBQUohZNG9A7DtO/O5ukSbxuaNGXMjHicgwy6rQQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-use-layout-effect": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-primitive": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz", + "integrity": "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-slot": "1.2.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-slot": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", + "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-callback-ref": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.1.tgz", + "integrity": "sha512-FkBMwD+qbGQeMu1cOHnuGB6x4yzPjho8ap5WtbEJ26umhgqVXbhekKUQO+hZEL1vU92a3wHwdp0HAcqAUF5iDg==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-controllable-state": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.2.2.tgz", + "integrity": "sha512-BjasUjixPFdS+NKkypcyyN5Pmg83Olst0+c6vGov0diwTEo6mgdqVR6hxcEgFuh4QrAs7Rc+9KuGJ9TVCj0Zzg==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-use-effect-event": "0.0.2", + "@radix-ui/react-use-layout-effect": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-effect-event": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-effect-event/-/react-use-effect-event-0.0.2.tgz", + "integrity": "sha512-Qp8WbZOBe+blgpuUT+lw2xheLP8q0oatc9UpmiemEICxGvFLYmHm9QowVZGHtJlGbS6A6yJ3iViad/2cVjnOiA==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-use-layout-effect": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-is-hydrated": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-is-hydrated/-/react-use-is-hydrated-0.1.0.tgz", + "integrity": "sha512-U+UORVEq+cTnRIaostJv9AGdV3G6Y+zbVd+12e18jQ5A3c0xL03IhnHuiU4UV69wolOQp5GfR58NW/EgdQhwOA==", + "license": "MIT", + "dependencies": { + "use-sync-external-store": "^1.5.0" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-layout-effect": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.1.1.tgz", + "integrity": "sha512-RbJRS4UWQFkzHTTwVymMTUv8EqYhOp8dOOviLj2ugtTiXRaRQS7GLGxZTLL1jWhMeoSCf5zmcZkqTl9IiYfXcQ==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@react-aria/color": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@react-aria/color/-/color-3.2.0.tgz", + "integrity": "sha512-Qw1TySxXnGlE4L7kzsi8v86U1yFs9FtonqsbySFzLPzsMV1Oar+rtkYHI5vwNSyNNF6TBJJikJNocS9Fi8xXwA==", + "license": "Apache-2.0", + "dependencies": { + "@swc/helpers": "^0.5.0", + "react-aria": "3.48.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/@react-aria/i18n": { + "version": "3.13.0", + "resolved": "https://registry.npmjs.org/@react-aria/i18n/-/i18n-3.13.0.tgz", + "integrity": "sha512-APjw4EwmvlnIyDxixSWfjHvOFFkW2rVTyKZ4l9FV0v7hOerh+FWLE6mF1XnnX3pgz3yARkKWwhSR9xYcRK6tpg==", + "license": "Apache-2.0", + "dependencies": { + "@internationalized/date": "^3.12.1", + "@internationalized/message": "^3.1.9", + "@internationalized/string": "^3.2.8", + "@swc/helpers": "^0.5.0", + "react-aria": "3.48.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/@react-aria/ssr": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/@react-aria/ssr/-/ssr-3.10.0.tgz", + "integrity": "sha512-mnelvACtfNWWKFCT1YHebxJRmfBmmANGwHQhCFPByMVTx1L8RumcaLxChYkE87g2KPuP5xX2il/oRn1DytW+qQ==", + "license": "Apache-2.0", + "dependencies": { + "@swc/helpers": "^0.5.0", + "react-aria": "3.48.0" + }, + "engines": { + "node": ">= 12" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/@react-aria/utils": { + "version": "3.34.0", + "resolved": "https://registry.npmjs.org/@react-aria/utils/-/utils-3.34.0.tgz", + "integrity": "sha512-ZM1ZXIqpwGTJjjL6o3JhlZkEaBpQdxuOCqLEvwEwooaj5GsYI3E9UfOl5vy3UW6bYiEEWl9pNBntrb9CR9kItQ==", + "license": "Apache-2.0", + "dependencies": { + "@swc/helpers": "^0.5.0", + "react-aria": "3.48.0", + "react-stately": "3.46.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, "node_modules/@react-leaflet/core": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/@react-leaflet/core/-/core-3.0.0.tgz", @@ -971,6 +1662,89 @@ "react-dom": "^19.0.0" } }, + "node_modules/@react-spectrum/color": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@react-spectrum/color/-/color-3.2.0.tgz", + "integrity": "sha512-Xg/U8+l1CQdvPRF4Zrv7AvtqsjuYUNkMxJMG0cIug9RKtIfEoyh7VR4Xg3FNd4Y/AwKXNJZZN4l94qz4WlK23Q==", + "license": "Apache-2.0", + "dependencies": { + "@adobe/react-spectrum": "3.47.0", + "@swc/helpers": "^0.5.0", + "react-stately": "3.46.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/@react-spectrum/provider": { + "version": "3.11.0", + "resolved": "https://registry.npmjs.org/@react-spectrum/provider/-/provider-3.11.0.tgz", + "integrity": "sha512-W2Gxbj8AcG5OR2K5Ua3K8qQqxdsiytEiz+2rhr6oQyBM8VafEgDcNPYSOTtfjrQM3snl2Uhp8LzwN0jwQe/6nQ==", + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "@adobe/react-spectrum": "3.47.0", + "@swc/helpers": "^0.5.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/@react-stately/color": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/@react-stately/color/-/color-3.10.0.tgz", + "integrity": "sha512-P4tlvOYFA8hl/NXiMyPxfM+7rXV01hnwlvGCwbZqUK1aRv0Ry0yGCj2AbSzhYHx7i4J4+CVUJUYozNLzhm+6Sw==", + "license": "Apache-2.0", + "dependencies": { + "@swc/helpers": "^0.5.0", + "react-stately": "3.46.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/@react-stately/utils": { + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/@react-stately/utils/-/utils-3.12.0.tgz", + "integrity": "sha512-7q+iHz9cENvro1dVKgdTxNh1i1mtWuLUI6UHp10TAgpxM9DyRDvmuN35zLXYCmMDgx3WLY2xkwqoez8xd+CdxQ==", + "license": "Apache-2.0", + "dependencies": { + "@swc/helpers": "^0.5.0", + "react-stately": "3.46.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/@react-types/color": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@react-types/color/-/color-3.2.0.tgz", + "integrity": "sha512-beV3vz80nzZ1EuYUM7296Kyi3AHcMrbQw0qub/9yzHWVTKKc5sy/e4dCMKcWL/ArkeAyc7jDOiui190RQ4l0Fw==", + "license": "Apache-2.0", + "dependencies": { + "@react-aria/color": "^3.2.0", + "@react-spectrum/color": "^3.2.0", + "@react-stately/color": "^3.10.0" + }, + "peerDependencies": { + "@react-spectrum/provider": "^3.0.0", + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/@react-types/shared": { + "version": "3.34.0", + "resolved": "https://registry.npmjs.org/@react-types/shared/-/shared-3.34.0.tgz", + "integrity": "sha512-gp6xo/s2lX54AlTjOiqwDnxA7UW79BNvI9dB9pr3LZTzRKCd1ZA+ZbgKw/ReIiWuvvVw/8QFJpnqeeFyLocMcQ==", + "license": "Apache-2.0", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, "node_modules/@rolldown/binding-android-arm64": { "version": "1.0.0-rc.17", "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.0.0-rc.17.tgz", @@ -1253,12 +2027,52 @@ "dev": true, "license": "MIT" }, + "node_modules/@spectrum-icons/ui": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/@spectrum-icons/ui/-/ui-3.7.0.tgz", + "integrity": "sha512-86iQSDfJb3Ama1WSJ/mEiFy4DJT7e/v4pSmEuX4aKKMzbNYft+O40N18S2POUnmblrb7MQneLC/pgIp1SDBwEQ==", + "license": "Apache-2.0", + "dependencies": { + "@adobe/react-spectrum-ui": "1.2.1", + "@babel/runtime": "^7.24.4", + "@swc/helpers": "^0.5.0" + }, + "peerDependencies": { + "@adobe/react-spectrum": "^3.47.0", + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/@spectrum-icons/workflow": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@spectrum-icons/workflow/-/workflow-4.3.0.tgz", + "integrity": "sha512-ILuhgWh9jMXaEVMRuOYgTAjMc22cKyvCtUDyZmc8OEMfOYuejj+Gcp5t6DhaCfE0M9rORtVxCrRgsO2WyEgfUw==", + "license": "Apache-2.0", + "dependencies": { + "@adobe/react-spectrum-workflow": "2.3.5", + "@swc/helpers": "^0.5.0" + }, + "peerDependencies": { + "@adobe/react-spectrum": "^3.47.0", + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, "node_modules/@standard-schema/utils": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/@standard-schema/utils/-/utils-0.3.0.tgz", "integrity": "sha512-e7Mew686owMaPJVNNLs55PUvgz371nKgwsc4vxE49zsODpJEnxgxRo2y/OKrqueavXgZNMDVj3DdHFlaSAeU8g==", "license": "MIT" }, + "node_modules/@swc/helpers": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.21.tgz", + "integrity": "sha512-jI/VAmtdjB/RnI8GTnokyX7Ug8c+g+ffD6QRLa6XQewtnGyukKkKSk3wLTM3b5cjt1jNh9x0jfVlagdN2gDKQg==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.8.0" + } + }, "node_modules/@tanstack/react-table": { "version": "8.21.3", "resolved": "https://registry.npmjs.org/@tanstack/react-table/-/react-table-8.21.3.tgz", @@ -1361,11 +2175,50 @@ "csstype": "^3.2.2" } }, + "node_modules/@types/react-datepicker": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/@types/react-datepicker/-/react-datepicker-6.2.0.tgz", + "integrity": "sha512-+JtO4Fm97WLkJTH8j8/v3Ldh7JCNRwjMYjRaKh4KHH0M3jJoXtwiD3JBCsdlg3tsFIw9eQSqyAPeVDN2H2oM9Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@floating-ui/react": "^0.26.2", + "@types/react": "*", + "date-fns": "^3.3.1" + } + }, + "node_modules/@types/react-datepicker/node_modules/@floating-ui/react": { + "version": "0.26.28", + "resolved": "https://registry.npmjs.org/@floating-ui/react/-/react-0.26.28.tgz", + "integrity": "sha512-yORQuuAtVpiRjpMhdc0wJj06b9JFjrYF4qp96j++v2NBpbi6SEGF7donUJ3TMieerQ6qVkAv1tgr7L4r5roTqw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@floating-ui/react-dom": "^2.1.2", + "@floating-ui/utils": "^0.2.8", + "tabbable": "^6.0.0" + }, + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, + "node_modules/@types/react-datepicker/node_modules/date-fns": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-3.6.0.tgz", + "integrity": "sha512-fRHTG8g/Gif+kSh50gaGEdToemgfj74aRX3swtiouboip5JDLAyDE9F11nHMIcvOaXeOC6D7SpNhi7uFyB7Uww==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/kossnocorp" + } + }, "node_modules/@types/react-dom": { "version": "19.2.3", "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.2.3.tgz", "integrity": "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==", - "dev": true, + "devOptional": true, "license": "MIT", "peerDependencies": { "@types/react": "^19.2.0" @@ -1728,6 +2581,18 @@ "url": "https://github.com/sponsors/epoberezkin" } }, + "node_modules/aria-hidden": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/aria-hidden/-/aria-hidden-1.2.6.tgz", + "integrity": "sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA==", + "license": "MIT", + "dependencies": { + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/balanced-match": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", @@ -1834,6 +2699,21 @@ "url": "https://paulmillr.com/funding/" } }, + "node_modules/client-only": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz", + "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==", + "license": "MIT" + }, + "node_modules/clsx": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", + "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/convert-source-map": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", @@ -1873,9 +2753,18 @@ "version": "3.2.3", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", - "devOptional": true, "license": "MIT" }, + "node_modules/date-fns": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-4.1.0.tgz", + "integrity": "sha512-Ukq0owbQXxa/U3EGtsdVBkR1w7KOQ5gIBqdH2hkvknzZPYvBxb/aa6E8L7tmjFtkwZBu3UXBbjIgPo/Ez4xaNg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/kossnocorp" + } + }, "node_modules/debug": { "version": "4.4.3", "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", @@ -1894,6 +2783,12 @@ } } }, + "node_modules/decimal.js": { + "version": "10.6.0", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.6.0.tgz", + "integrity": "sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==", + "license": "MIT" + }, "node_modules/deep-is": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", @@ -1911,6 +2806,16 @@ "node": ">=8" } }, + "node_modules/dom-helpers": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz", + "integrity": "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.8.7", + "csstype": "^3.0.2" + } + }, "node_modules/echarts": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/echarts/-/echarts-6.0.0.tgz", @@ -2242,6 +3147,33 @@ "dev": true, "license": "ISC" }, + "node_modules/framer-motion": { + "version": "12.38.0", + "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-12.38.0.tgz", + "integrity": "sha512-rFYkY/pigbcswl1XQSb7q424kSTQ8q6eAC+YUsSKooHQYuLdzdHjrt6uxUC+PRAO++q5IS7+TamgIw1AphxR+g==", + "license": "MIT", + "dependencies": { + "motion-dom": "^12.38.0", + "motion-utils": "^12.36.0", + "tslib": "^2.4.0" + }, + "peerDependencies": { + "@emotion/is-prop-valid": "*", + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@emotion/is-prop-valid": { + "optional": true + }, + "react": { + "optional": true + }, + "react-dom": { + "optional": true + } + } + }, "node_modules/fsevents": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", @@ -2360,6 +3292,28 @@ "node": ">=0.8.19" } }, + "node_modules/input-otp": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/input-otp/-/input-otp-1.4.2.tgz", + "integrity": "sha512-l3jWwYNvrEa6NTCt7BECfCm48GvwuZzkoeG3gBL2w4CHeOXW3eKFmf9UNYkNfYc3mxMrthMnxjIE07MT0zLBQA==", + "license": "MIT", + "peerDependencies": { + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0.0 || ^19.0.0-rc" + } + }, + "node_modules/intl-messageformat": { + "version": "10.7.18", + "resolved": "https://registry.npmjs.org/intl-messageformat/-/intl-messageformat-10.7.18.tgz", + "integrity": "sha512-m3Ofv/X/tV8Y3tHXLohcuVuhWKo7BBq62cqY15etqmLxg2DZ34AGGgQDeR+SCta2+zICb1NX83af0GJmbQ1++g==", + "license": "BSD-3-Clause", + "dependencies": { + "@formatjs/ecma402-abstract": "2.3.6", + "@formatjs/fast-memoize": "2.2.7", + "@formatjs/icu-messageformat-parser": "2.11.4", + "tslib": "^2.8.0" + } + }, "node_modules/is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", @@ -2394,7 +3348,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true, "license": "MIT" }, "node_modules/jsesc": { @@ -2763,6 +3716,18 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "license": "MIT", + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, "node_modules/lru-cache": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", @@ -2798,6 +3763,21 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/motion-dom": { + "version": "12.38.0", + "resolved": "https://registry.npmjs.org/motion-dom/-/motion-dom-12.38.0.tgz", + "integrity": "sha512-pdkHLD8QYRp8VfiNLb8xIBJis1byQ9gPT3Jnh2jqfFtAsWUA3dEepDlsWe/xMpO8McV+VdpKVcp+E+TGJEtOoA==", + "license": "MIT", + "dependencies": { + "motion-utils": "^12.36.0" + } + }, + "node_modules/motion-utils": { + "version": "12.36.0", + "resolved": "https://registry.npmjs.org/motion-utils/-/motion-utils-12.36.0.tgz", + "integrity": "sha512-eHWisygbiwVvf6PZ1vhaHCLamvkSbPIeAYxWUuL3a2PD/TROgE7FvfHWTIH4vMl798QLfMw15nRqIaRDXTlYRg==", + "license": "MIT" + }, "node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", @@ -2845,6 +3825,15 @@ "dev": true, "license": "MIT" }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/optimism": { "version": "0.18.1", "resolved": "https://registry.npmjs.org/optimism/-/optimism-0.18.1.tgz", @@ -2986,6 +3975,17 @@ "node": ">= 0.8.0" } }, + "node_modules/prop-types": { + "version": "15.8.1", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", + "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.1" + } + }, "node_modules/punycode": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", @@ -3005,6 +4005,66 @@ "node": ">=0.10.0" } }, + "node_modules/react-aria": { + "version": "3.48.0", + "resolved": "https://registry.npmjs.org/react-aria/-/react-aria-3.48.0.tgz", + "integrity": "sha512-jQjd4rBEIMqecBaAKYJbVGK6EqIHLa5znVQ7jwFyK5vCyljoj6KhgtiahmcIPsG5vG5vEDLw+ba+bEWn6A2P4w==", + "license": "Apache-2.0", + "dependencies": { + "@internationalized/date": "^3.12.1", + "@internationalized/number": "^3.6.6", + "@internationalized/string": "^3.2.8", + "@react-types/shared": "^3.34.0", + "@swc/helpers": "^0.5.0", + "aria-hidden": "^1.2.3", + "clsx": "^2.0.0", + "react-stately": "3.46.0", + "use-sync-external-store": "^1.6.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/react-aria-components": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/react-aria-components/-/react-aria-components-1.17.0.tgz", + "integrity": "sha512-0EyisMgvsFJ2aML3crDYv2tW5vT2Ryf8PGzY/g63JjDdCbLshlwazhS8JNtPF1vkTkungJJ6sVJbKyX+YKSoFA==", + "license": "Apache-2.0", + "dependencies": { + "@internationalized/date": "^3.12.1", + "@react-types/shared": "^3.34.0", + "@swc/helpers": "^0.5.0", + "client-only": "^0.0.1", + "react-aria": "3.48.0", + "react-stately": "3.46.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/react-datepicker": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/react-datepicker/-/react-datepicker-9.1.0.tgz", + "integrity": "sha512-lOp+m5bc+ttgtB5MHEjwiVu4nlp4CvJLS/PG1OiOe5pmg9kV73pEqO8H0Geqvg2E8gjqTaL9eRhSe+ZpeKP3nA==", + "license": "MIT", + "dependencies": { + "@floating-ui/react": "^0.27.15", + "clsx": "^2.1.1", + "date-fns": "^4.1.0" + }, + "peerDependencies": { + "date-fns-tz": "^3.0.0", + "react": "^16.9.0 || ^17 || ^18 || ^19 || ^19.0.0-rc", + "react-dom": "^16.9.0 || ^17 || ^18 || ^19 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "date-fns-tz": { + "optional": true + } + } + }, "node_modules/react-dom": { "version": "19.2.5", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.5.tgz", @@ -3033,6 +4093,12 @@ "react": "^16.8.0 || ^17 || ^18 || ^19" } }, + "node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "license": "MIT" + }, "node_modules/react-leaflet": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/react-leaflet/-/react-leaflet-5.0.0.tgz", @@ -3085,6 +4151,39 @@ "react-dom": ">=18" } }, + "node_modules/react-stately": { + "version": "3.46.0", + "resolved": "https://registry.npmjs.org/react-stately/-/react-stately-3.46.0.tgz", + "integrity": "sha512-OdxhWvHgs2L4OJGIs7hnuTr5WjjMM6enhNEAMRqiekhF8+ITvA2LRwNftOZwcogaoCslGYq5S2VQTQwnm0GbCA==", + "license": "Apache-2.0", + "dependencies": { + "@internationalized/date": "^3.12.1", + "@internationalized/number": "^3.6.6", + "@internationalized/string": "^3.2.8", + "@react-types/shared": "^3.34.0", + "@swc/helpers": "^0.5.0", + "use-sync-external-store": "^1.6.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/react-transition-group": { + "version": "4.4.5", + "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz", + "integrity": "sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==", + "license": "BSD-3-Clause", + "dependencies": { + "@babel/runtime": "^7.5.5", + "dom-helpers": "^5.0.1", + "loose-envify": "^1.4.0", + "prop-types": "^15.6.2" + }, + "peerDependencies": { + "react": ">=16.6.0", + "react-dom": ">=16.6.0" + } + }, "node_modules/readdirp": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", @@ -3229,6 +4328,48 @@ "node": ">=0.10.0" } }, + "node_modules/tabbable": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/tabbable/-/tabbable-6.4.0.tgz", + "integrity": "sha512-05PUHKSNE8ou2dwIxTngl4EzcnsCDZGJ/iCLtDflR/SHB/ny14rXc+qU5P4mG9JkusiV7EivzY9Mhm55AzAvCg==", + "license": "MIT" + }, + "node_modules/tailwind-merge": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-3.4.0.tgz", + "integrity": "sha512-uSaO4gnW+b3Y2aWoWfFpX62vn2sR3skfhbjsEnaBI81WD1wBLlHZe5sWf0AqjksNdYTbGBEd0UasQMT3SNV15g==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/dcastil" + } + }, + "node_modules/tailwind-variants": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/tailwind-variants/-/tailwind-variants-3.2.2.tgz", + "integrity": "sha512-Mi4kHeMTLvKlM98XPnK+7HoBPmf4gygdFmqQPaDivc3DpYS6aIY6KiG/PgThrGvii5YZJqRsPz0aPyhoFzmZgg==", + "license": "MIT", + "engines": { + "node": ">=16.x", + "pnpm": ">=7.x" + }, + "peerDependencies": { + "tailwind-merge": ">=3.0.0", + "tailwindcss": "*" + }, + "peerDependenciesMeta": { + "tailwind-merge": { + "optional": true + } + } + }, + "node_modules/tailwindcss": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.2.4.tgz", + "integrity": "sha512-HhKppgO81FQof5m6TEnuBWCZGgfRAWbaeOaGT00KOy/Pf/j6oUihdvBpA7ltCeAvZpFhW3j0PTclkxsd4IXYDA==", + "license": "MIT", + "peer": true + }, "node_modules/tinyglobby": { "version": "0.2.16", "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.16.tgz", @@ -3265,6 +4406,15 @@ "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", "license": "0BSD" }, + "node_modules/tw-animate-css": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/tw-animate-css/-/tw-animate-css-1.4.0.tgz", + "integrity": "sha512-7bziOlRqH0hJx80h/3mbicLW7o8qLsH5+RaLR2t+OHM3D0JlWGODQKQ4cxbK7WlvmUxpcj6Kgu6EKqjrGFe3QQ==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/Wombosvideo" + } + }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -3364,6 +4514,15 @@ "punycode": "^2.1.0" } }, + "node_modules/use-sync-external-store": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.6.0.tgz", + "integrity": "sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w==", + "license": "MIT", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, "node_modules/vite": { "version": "8.0.10", "resolved": "https://registry.npmjs.org/vite/-/vite-8.0.10.tgz", diff --git a/mdm-front/package.json b/mdm-front/package.json index 8d89d5d..9e56ca4 100644 --- a/mdm-front/package.json +++ b/mdm-front/package.json @@ -11,14 +11,20 @@ }, "dependencies": { "@apollo/client": "^4.1.9", + "@heroui/react": "^3.0.3", "@hookform/resolvers": "^5.2.2", + "@internationalized/date": "^3.12.1", + "@radix-ui/react-accordion": "^1.2.12", "@tanstack/react-table": "^8.21.3", + "date-fns": "^4.1.0", "echarts": "^6.0.0", "echarts-for-react": "^3.0.6", + "framer-motion": "^12.38.0", "graphql": "^16.13.2", "leaflet": "^1.9.4", "lucide-react": "^1.9.0", "react": "^19.2.5", + "react-datepicker": "^9.1.0", "react-dom": "^19.2.5", "react-hook-form": "^7.73.1", "react-leaflet": "^5.0.0", @@ -32,6 +38,7 @@ "@types/leaflet": "^1.9.21", "@types/node": "^24.12.2", "@types/react": "^19.2.14", + "@types/react-datepicker": "^6.2.0", "@types/react-dom": "^19.2.3", "@vitejs/plugin-react": "^6.0.1", "eslint": "^10.2.1", diff --git a/mdm-front/public/favicon.svg b/mdm-front/public/favicon.svg index 6893eb1..7ea007a 100644 --- a/mdm-front/public/favicon.svg +++ b/mdm-front/public/favicon.svg @@ -1 +1,17 @@ - \ No newline at end of file + + + + + + + + + + + + + + + + + diff --git a/mdm-front/public/icons.svg b/mdm-front/public/icons.svg deleted file mode 100644 index e952219..0000000 --- a/mdm-front/public/icons.svg +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/mdm-front/src/App.css b/mdm-front/src/App.scss similarity index 100% rename from mdm-front/src/App.css rename to mdm-front/src/App.scss diff --git a/mdm-front/src/App.tsx b/mdm-front/src/App.tsx index a66b5ef..1d01b9e 100644 --- a/mdm-front/src/App.tsx +++ b/mdm-front/src/App.tsx @@ -1,116 +1,16 @@ import { useState } from 'react' -import reactLogo from './assets/react.svg' -import viteLogo from './assets/vite.svg' -import heroImg from './assets/hero.png' -import './App.css' +//import reactLogo from './assets/react.svg' +//import viteLogo from './assets/vite.svg' +//import heroImg from './assets/hero.png' +import './App.scss' function App() { - const [count, setCount] = useState(0) + //const [count, setCount] = useState(0) return ( <>
-
- - React logo - Vite logo -
-
-

Get started

-

- Edit src/App.tsx and save to test HMR -

-
- -
- -
- -
-
- -

Documentation

-

Your questions, answered

- -
-
- -

Connect with us

-

Join the Vite community

- -
+
diff --git a/mdm-front/src/app/layouts/AppLayout.scss b/mdm-front/src/app/layouts/AppLayout.scss new file mode 100644 index 0000000..bb00f11 --- /dev/null +++ b/mdm-front/src/app/layouts/AppLayout.scss @@ -0,0 +1,12 @@ +.app-layout { + display: flex; + min-height: 100vh; + background: #EFF2F7; +} + +.app-layout__content { + display: flex; + flex-direction: column; + flex: 1; + padding: 20px 36px 36px 0; +} \ No newline at end of file diff --git a/mdm-front/src/app/layouts/AppLayout.tsx b/mdm-front/src/app/layouts/AppLayout.tsx new file mode 100644 index 0000000..35dcbb0 --- /dev/null +++ b/mdm-front/src/app/layouts/AppLayout.tsx @@ -0,0 +1,16 @@ +import { Outlet } from 'react-router-dom' +import { Sidebar } from '../../widgets/Sidebar/Sidebar' +import './AppLayout.scss' +import { Navbar } from '../../widgets/Navbar/Navbar' + +export function AppLayout() { + return ( +
+ +
+ + +
+
+ ) +} \ No newline at end of file diff --git a/mdm-front/src/app/router/router.tsx b/mdm-front/src/app/router/router.tsx new file mode 100644 index 0000000..7d60087 --- /dev/null +++ b/mdm-front/src/app/router/router.tsx @@ -0,0 +1,37 @@ +// src/app/router/router.tsx +import { createBrowserRouter, Navigate } from 'react-router-dom' + +import { AppLayout } from '../layouts/AppLayout' +import { DevicesPage } from '../../pages/DevicesPage/DevicesPage' +//import { DevicePage } from '../../pages/DevicePage/DevicePage' +import { MapPage } from '../../pages/MapPage/MapPage' +import { EmployeesPage } from '../../pages/EmployeesPage/EmployeesPage' + +export const router = createBrowserRouter([ + { + path: '/', + element: , + children: [ + { + index: true, + element: , + }, + { + path: 'devices', + element: , + },/* + { + path: 'devices/:deviceId', + element: , + }, */ + { + path: 'map', + element: , + }, + { + path: 'employees', + element: , + }, + ], + }, +]) \ No newline at end of file diff --git a/mdm-front/src/assets/Logo.svg b/mdm-front/src/assets/Logo.svg new file mode 100644 index 0000000..529828a --- /dev/null +++ b/mdm-front/src/assets/Logo.svg @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mdm-front/src/assets/LogoIcon.svg b/mdm-front/src/assets/LogoIcon.svg new file mode 100644 index 0000000..7ea007a --- /dev/null +++ b/mdm-front/src/assets/LogoIcon.svg @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/mdm-front/src/assets/fonts/Montserrat-VariableFont_wght.ttf b/mdm-front/src/assets/fonts/Montserrat-VariableFont_wght.ttf new file mode 100644 index 0000000..451e692 Binary files /dev/null and b/mdm-front/src/assets/fonts/Montserrat-VariableFont_wght.ttf differ diff --git a/mdm-front/src/assets/hero.png b/mdm-front/src/assets/hero.png deleted file mode 100644 index 02251f4..0000000 Binary files a/mdm-front/src/assets/hero.png and /dev/null differ diff --git a/mdm-front/src/assets/react.svg b/mdm-front/src/assets/react.svg deleted file mode 100644 index 6c87de9..0000000 --- a/mdm-front/src/assets/react.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/mdm-front/src/assets/vite.svg b/mdm-front/src/assets/vite.svg deleted file mode 100644 index 5101b67..0000000 --- a/mdm-front/src/assets/vite.svg +++ /dev/null @@ -1 +0,0 @@ -Vite diff --git a/mdm-front/src/index.css b/mdm-front/src/index.scss similarity index 76% rename from mdm-front/src/index.css rename to mdm-front/src/index.scss index 5fb3313..79da82c 100644 --- a/mdm-front/src/index.css +++ b/mdm-front/src/index.scss @@ -1,3 +1,13 @@ +@use './shared/styles/variables' as *; + +@font-face { + font-family: 'Montserrat'; + src: url('../assets/fonts/montserrat/Montserrat-VariableFont_wght.ttf') format('truetype'); + font-weight: 100 900; + font-style: normal; + font-display: swap; +} + :root { --text: #6b6375; --text-h: #08060d; @@ -11,9 +21,9 @@ --shadow: rgba(0, 0, 0, 0.1) 0 10px 15px -3px, rgba(0, 0, 0, 0.05) 0 4px 6px -2px; - --sans: system-ui, 'Segoe UI', Roboto, sans-serif; - --heading: system-ui, 'Segoe UI', Roboto, sans-serif; - --mono: ui-monospace, Consolas, monospace; + --sans: 'Montserrat', system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;; + --heading: 'Montserrat', system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;; + --mono: 'Montserrat', system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;; font: 18px/145% var(--sans); letter-spacing: 0.18px; @@ -51,7 +61,7 @@ } #root { - width: 1126px; + //width: 1126px; max-width: 100%; margin: 0 auto; text-align: center; @@ -70,13 +80,12 @@ h1, h2 { font-family: var(--heading); font-weight: 500; - color: var(--text-h); + color: black; } h1 { - font-size: 56px; - letter-spacing: -1.68px; - margin: 32px 0; + font-size: 32px; + margin: 0; @media (max-width: 1024px) { font-size: 36px; margin: 20px 0; diff --git a/mdm-front/src/main.tsx b/mdm-front/src/main.tsx index bef5202..86fbc7c 100644 --- a/mdm-front/src/main.tsx +++ b/mdm-front/src/main.tsx @@ -1,10 +1,12 @@ import { StrictMode } from 'react' import { createRoot } from 'react-dom/client' -import './index.css' -import App from './App.tsx' +import './index.scss' +import { RouterProvider } from 'react-router-dom' +import { router } from './app/router/router.tsx' +import 'react-datepicker/dist/react-datepicker.css' createRoot(document.getElementById('root')!).render( - + , ) diff --git a/mdm-front/src/pages/DevicesPage/DevicesPage.scss b/mdm-front/src/pages/DevicesPage/DevicesPage.scss new file mode 100644 index 0000000..d61766d --- /dev/null +++ b/mdm-front/src/pages/DevicesPage/DevicesPage.scss @@ -0,0 +1,242 @@ +@use '../../shared/styles/variables' as *; + +.devices-page { + display: flex; + flex-direction: column; + gap: 10px; + flex: 1; +} + +.devices-table-container { + display: flex; + flex: 1; + flex-direction: column; + //gap: 20px; +} + +.devices-table-filter-container { + display: flex; + flex: 1; +} + +.devices-table-card { + flex: 1; + overflow: auto; + border-radius: 20px; + background: #ffffff; +} + +.devices-table { + width: 100%; + border-collapse: collapse; + table-layout: fixed; + + th { + //height: 36px; + padding: 14px 20px; + line-height: 1; + border-bottom: 1px solid #e3e8f0; + + color: $gray50; + font-size: 16px; + font-weight: 450; + text-align: left; + } + + td { + height: 68px; + padding: 14px 20px; + border-bottom: 1px solid $gray20; + vertical-align: middle; + text-align: left; + + color: #151a24; + font-size: 18px; + font-weight: 400; + } + + th:nth-child(1), + td:nth-child(1) { + width: 52px; + } + + th:nth-child(2), + td:nth-child(2) { + width: 31%; + } + + th:nth-child(3), + td:nth-child(3) { + width: 23%; + } + + th:nth-child(4), + td:nth-child(4) { + width: 23%; + } + + th:nth-child(5), + td:nth-child(5) { + width: 146px; + } + + th:nth-child(6), + td:nth-child(6) { + width: 146px; + } +} + +.devices-table__id { + color: #1d2533; + text-align: left; +} + +.device-info { + display: flex; + flex-direction: column; + line-height: 1.3; +} + +.device-info__number { + color: #111827; + font-size: 18px; + font-weight: 600; +} + +.device-info__imei, +.device-info__employee { + color: #738098; + font-size: 18px; + font-weight: 400; +} + +.device-info__work { + display: flex; + align-items: center; + gap: 5px; + + color: #738098; + font-size: 18px; + font-weight: 400; +} + +.devices-status { + display: inline-flex; + align-items: center; + gap: 8px; + + color: #111827; + font-size: 18px; + font-weight: 400; +} + +.devices-dot { + width: 7px; + height: 7px; + border-radius: 50%; + flex: 0 0 7px; +} + +.devices-dot--green { + background: $green; +} + +.devices-dot--red { + background: $red; +} + +.devices-dot--gray { + background: $gray50; +} + +.device-icons { + display: grid; + grid-template-columns: repeat(4, 16px); + gap: 4px 8px; + align-items: center; + + color: $gray50; + + svg { + width: 20px; + height: auto; + color: $gray50; + stroke-width: 2; + } + + .is-active { + color: $blue; + } + + .is-danger { + color: $red; + } +} + +.devices-map-btn { + padding: 12px; + border: none; + border-radius: 12px; + background: $color-bg; + + display: inline-flex; + align-items: center; + gap: 8px; + + color: #151a24; + font-size: 18px; + font-weight: 500; + cursor: pointer; + transition: .2s ease; + + &:hover { + background-color: $gray20; + color: $blue; + } + + svg { + height: 18px; + width: auto; + } +} + +.devices-pagination { + padding: 12px 14px 0; + + display: flex; + align-items: center; + justify-content: space-between; + + color: #738098; + font-size: 13px; +} + +.devices-pagination__controls { + display: flex; + align-items: center; + gap: 6px; + + button { + min-width: 30px; + height: 30px; + padding: 0 12px; + + border: none; + border-radius: 10px; + background: #e9edf5; + + color: #738098; + font-size: 14px; + cursor: pointer; + + &.is-active { + background: #031d9a; + color: #ffffff; + } + + &:disabled { + opacity: 0.5; + cursor: default; + } + } +} \ No newline at end of file diff --git a/mdm-front/src/pages/DevicesPage/DevicesPage.tsx b/mdm-front/src/pages/DevicesPage/DevicesPage.tsx new file mode 100644 index 0000000..734a693 --- /dev/null +++ b/mdm-front/src/pages/DevicesPage/DevicesPage.tsx @@ -0,0 +1,180 @@ +import { useState } from 'react' +import { + Bluetooth, + Camera, + Map, + MapPin, + SlidersHorizontal, + Volume2, + Wifi, + Lock, + Store, +} from 'lucide-react' + +import devices from './devices.mock.json' +import './DevicesPage.scss' +import { DevicesTabs } from './components/DevicesTabs/DevicesTabs' +import { DevicesToolbar } from './components/DevicesToolbar/DevicesToolbar' +import { DevicesFiltersPanel } from './components/DevicesFiltersPanel/DevicesFiltersPanel' + +type DeviceCondition = 'ok' | 'inspection' +type DeviceConnection = 'online' | 'offline' | 'offlineDanger' + +type Device = { + id: number + factoryNumber: string + imei: string + workTime: string | null + employee: string | null + condition: DeviceCondition + connection: DeviceConnection + connectionText: string + statusIcons: { + gps: boolean + wifi: boolean + bluetooth: boolean + lock: boolean + camera: boolean + sim: boolean + sound: boolean + kiosk: boolean + } +} + +const typedDevices = devices as Device[] + +const conditionText: Record = { + ok: 'Исправно', + inspection: 'Требует осмотра', +} + +function getDotClass(status: DeviceCondition | DeviceConnection) { + if (status === 'ok' || status === 'online') return 'devices-dot devices-dot--green' + if (status === 'inspection' || status === 'offlineDanger') return 'devices-dot devices-dot--red' + + return 'devices-dot devices-dot--gray' +} + +export function DevicesPage() { + + const [isFiltersOpen, setIsFiltersOpen] = useState(true) + + return ( +
+ + + setIsFiltersOpen((prev) => !prev)} + /> +
+
+
+ + + + + + + + + + + + + {typedDevices.map((device) => ( + + + + + + + + + + + + + + ))} + +
IDИнформацияСостояниеСвязьСтатусы +
{device.id} +
+
{device.factoryNumber}
+
{device.imei}
+ + {device.workTime && ( +
+ + В работе: {device.workTime} +
+ )} + + {device.employee && ( +
{device.employee}
+ )} +
+
+
+ + {conditionText[device.condition]} +
+
+
+ + {device.connectionText} +
+
+
+ + + + + + + + + +
+
+ +
+
+ +
+ 1 из 10 + +
+ + + + +
+
+
+ +
+
+ ) +} \ No newline at end of file diff --git a/mdm-front/src/pages/DevicesPage/components/DevicesFiltersPanel/Datepicker.scss b/mdm-front/src/pages/DevicesPage/components/DevicesFiltersPanel/Datepicker.scss new file mode 100644 index 0000000..f5f1c7f --- /dev/null +++ b/mdm-front/src/pages/DevicesPage/components/DevicesFiltersPanel/Datepicker.scss @@ -0,0 +1,43 @@ +.react-datepicker { + border: none; + border-radius: 14px; + box-shadow: 0 10px 30px rgba(15, 23, 42, 0.15); + font-family: inherit; + overflow: hidden; +} + +.react-datepicker__header { + background: #f3f6fa; + border-bottom: 1px solid #e3e8f0; +} + +.react-datepicker__current-month, +.react-datepicker-time__header, +.react-datepicker-year-header { + color: #30394b; + font-weight: 600; +} + +.react-datepicker__day--selected, +.react-datepicker__day--keyboard-selected, +.react-datepicker__time-container + .react-datepicker__time + .react-datepicker__time-box + ul.react-datepicker__time-list + li.react-datepicker__time-list-item--selected { + background: #031d9a; + color: #ffffff; +} + +.react-datepicker__day--in-range, +.react-datepicker__day--in-selecting-range { + background: #e8edff; + color: #031d9a; +} + +.react-datepicker__day:hover, +.react-datepicker__month-text:hover, +.react-datepicker__quarter-text:hover, +.react-datepicker__year-text:hover { + background: #eef1f6; +} \ No newline at end of file diff --git a/mdm-front/src/pages/DevicesPage/components/DevicesFiltersPanel/DevicesFiltersPanel.scss b/mdm-front/src/pages/DevicesPage/components/DevicesFiltersPanel/DevicesFiltersPanel.scss new file mode 100644 index 0000000..75b44b1 --- /dev/null +++ b/mdm-front/src/pages/DevicesPage/components/DevicesFiltersPanel/DevicesFiltersPanel.scss @@ -0,0 +1,258 @@ +@use '../../../../shared/styles/variables' as *; + +.devices-filters { + width: 0; + flex: 0 0 0; + opacity: 0; + overflow: hidden; + pointer-events: none; + + transform: translateX(16px); + + transition: + width 0.25s ease, + flex-basis 0.25s ease, + opacity 0.2s ease, + transform 0.25s ease; +} + +.devices-filters--open { + width: 292px; + flex-basis: 292px; + opacity: 1; + pointer-events: auto; + transform: translateX(0); + padding-left: 20px; +} + +.devices-filters__accordion { + width: 292px; + display: flex; + flex-direction: column; + gap: 8px; +} + +.devices-filter-item { + border-radius: 14px; + background: #ffffff; + overflow: hidden; +} + +.devices-filter-item__header { + margin: 0; +} + +.devices-filter-item__trigger { + width: 100%; + min-height: 44px; + padding: 0 14px; + + border: none; + border-bottom: 1px solid transparent; + background: transparent; + + display: flex; + align-items: center; + justify-content: space-between; + gap: 12px; + + color: #30394b; + font-size: 15px; + font-weight: 500; + cursor: pointer; + + &[data-state='open'] { + color: #031d9a; + border-bottom-color: #e3e8f0; + } +} + +.devices-filter-item__chevron { + flex: 0 0 auto; + transition: transform 0.2s ease; +} + +.devices-filter-item__trigger[data-state='open'] .devices-filter-item__chevron { + transform: rotate(180deg); +} + +.devices-filter-item__content { + overflow: hidden; + + &[data-state='open'] { + animation: filterSlideDown 0.2s ease; + } + + &[data-state='closed'] { + animation: filterSlideUp 0.2s ease; + } +} + +.devices-filter-item__inner { + padding: 12px 14px 10px; +} + +.devices-period { + display: flex; + align-items: center; + gap: 6px; +} + +.devices-period__divider { + width: 12px; + height: 1px; + background: #8c96aa; + flex: 0 0 12px; +} + +.devices-period__input { + width: 126px; + min-height: 28px; + padding: 0 10px; + + border: none; + outline: none; + border-radius: 999px; + background: #eef1f6; + + color: #4f5b73; + font-size: 12px; + font-weight: 400; + cursor: pointer; +} + +.devices-filter-reset { + margin: 8px 0 0 auto; + padding: 0; + + display: block; + + border: none; + background: transparent; + + color: #031d9a; + font-size: 12px; + font-weight: 400; + text-decoration: underline; + cursor: pointer; +} + +.devices-filter-row { + display: grid; + grid-template-columns: 1fr auto auto; + align-items: center; + gap: 12px; + + min-height: 28px; + + color: #30394b; + font-size: 13px; + + & + & { + margin-top: 8px; + } +} + +.devices-filter-row__label { + color: #30394b; + font-size: 13px; + font-weight: 400; +} + +.devices-radio, +.devices-checkbox { + display: inline-flex; + align-items: center; + gap: 6px; + + color: #30394b; + font-size: 13px; + cursor: pointer; + user-select: none; + + input { + display: none; + } +} + +.devices-radio__control { + width: 18px; + height: 18px; + border-radius: 50%; + border: 2px solid #dfe5ef; + background: #f3f6fa; + position: relative; + flex: 0 0 18px; +} + +.devices-radio input:checked + .devices-radio__control { + border-color: #031d9a; + background: #031d9a; +} + +.devices-radio input:checked + .devices-radio__control::after { + content: ''; + position: absolute; + inset: 5px; + border-radius: 50%; + background: #ffffff; +} + +.devices-radio__label { + white-space: nowrap; +} + +.devices-checkbox { + min-height: 28px; + + & + & { + margin-top: 8px; + } +} + +.devices-checkbox__control { + width: 18px; + height: 18px; + border-radius: 5px; + border: 2px solid #dfe5ef; + background: #f3f6fa; + position: relative; + flex: 0 0 18px; +} + +.devices-checkbox input:checked + .devices-checkbox__control { + border-color: #031d9a; + background: #031d9a; +} + +.devices-checkbox input:checked + .devices-checkbox__control::after { + content: ''; + position: absolute; + left: 5px; + top: 2px; + width: 4px; + height: 8px; + border: solid #ffffff; + border-width: 0 2px 2px 0; + transform: rotate(45deg); +} + +@keyframes filterSlideDown { + from { + height: 0; + } + + to { + height: var(--radix-accordion-content-height); + } +} + +@keyframes filterSlideUp { + from { + height: var(--radix-accordion-content-height); + } + + to { + height: 0; + } +} \ No newline at end of file diff --git a/mdm-front/src/pages/DevicesPage/components/DevicesFiltersPanel/DevicesFiltersPanel.tsx b/mdm-front/src/pages/DevicesPage/components/DevicesFiltersPanel/DevicesFiltersPanel.tsx new file mode 100644 index 0000000..2bf267e --- /dev/null +++ b/mdm-front/src/pages/DevicesPage/components/DevicesFiltersPanel/DevicesFiltersPanel.tsx @@ -0,0 +1,234 @@ +import { useState } from 'react' +import DatePicker, { registerLocale } from 'react-datepicker' +import { ru } from 'date-fns/locale/ru' +import * as Accordion from '@radix-ui/react-accordion' +import { ChevronDown } from 'lucide-react' +import './Datepicker.scss' + +import './DevicesFiltersPanel.scss' + +registerLocale('ru', ru) + +type DevicesFiltersPanelProps = { + isOpen: boolean +} + +export function DevicesFiltersPanel({ isOpen }: DevicesFiltersPanelProps) { + + const [startDate, setStartDate] = useState( + new Date(2026, 3, 20, 7, 0), + ) + + const [endDate, setEndDate] = useState( + new Date(2026, 3, 22, 16, 0), + ) + + return ( + + ) +} \ No newline at end of file diff --git a/mdm-front/src/pages/DevicesPage/components/DevicesTabs/DevicesTabs.scss b/mdm-front/src/pages/DevicesPage/components/DevicesTabs/DevicesTabs.scss new file mode 100644 index 0000000..36f9a90 --- /dev/null +++ b/mdm-front/src/pages/DevicesPage/components/DevicesTabs/DevicesTabs.scss @@ -0,0 +1,39 @@ +@use '../../../../shared/styles/variables' as *; + +.devices-tabs { + display: flex; + align-items: center; + gap: 10px; +} + +.devices-tabs__item { + position: relative; + min-height: 36px; + padding: 8px 18px; + border: none; + border-radius: 10px; + background: #ffffff; + color: #4f5b73; + font-size: 16px; + font-weight: 400; + cursor: pointer; + + b { + font-weight: 700; + color: #1d2533; + } +} + +.devices-tabs__item--active { + color: #4f5b73; +} + +.devices-tabs__alert { + position: absolute; + top: -5px; + right: -5px; + width: 11px; + height: 11px; + border-radius: 50%; + background: $red; +} \ No newline at end of file diff --git a/mdm-front/src/pages/DevicesPage/components/DevicesTabs/DevicesTabs.tsx b/mdm-front/src/pages/DevicesPage/components/DevicesTabs/DevicesTabs.tsx new file mode 100644 index 0000000..89ea420 --- /dev/null +++ b/mdm-front/src/pages/DevicesPage/components/DevicesTabs/DevicesTabs.tsx @@ -0,0 +1,21 @@ +import './DevicesTabs.scss' + +export function DevicesTabs() { + return ( +
+ + + + + +
+ ) +} \ No newline at end of file diff --git a/mdm-front/src/pages/DevicesPage/components/DevicesToolbar/DevicesToolbar.scss b/mdm-front/src/pages/DevicesPage/components/DevicesToolbar/DevicesToolbar.scss new file mode 100644 index 0000000..833c984 --- /dev/null +++ b/mdm-front/src/pages/DevicesPage/components/DevicesToolbar/DevicesToolbar.scss @@ -0,0 +1,99 @@ +@use '../../../../shared/styles/variables' as *; + +.devices-toolbar { + display: flex; + align-items: center; + justify-content: space-between; + gap: 16px; + background-color: white; + border-radius: 100px; + padding: 4px; +} + +.devices-search { + width: 250px; + padding: 10px 12px; + border-radius: 20px; + background: $color-bg; + display: flex; + align-items: center; + gap: 8px; + color: $gray50; + + svg { + height: 16px; + width: auto; + } + + input { + width: 100%; + border: none; + outline: none; + background: transparent; + color: black; + font-size: 16px; + + &::placeholder { + color: $gray50; + } + } +} + +.devices-toolbar__right { + display: flex; + align-items: center; + gap: 6px; + + button { + padding: 12px; + font-size: 16px; + background-color: $color-bg; + border-radius: 20px; + border: none; + } + + .add-device { + background-color: $blue; + color: white; + } +} + + +.devices-sort { + display: flex; + flex-direction: row; + gap: 8px; + align-items: center; + background: #ffffff; + color: $gray50; + font-size: 16px; + cursor: pointer; +} + +.devices-filter { + position: relative; + border: none; + border-radius: 20px; + color: $blue; + + display: inline-flex; + align-items: center; + justify-content: center; + + cursor: pointer; + + svg { + height: 16px; + width: auto; + } +} + +.devices-filter__alert { + position: absolute; + top: -2px; + right: -1px; + width: 8px; + height: 8px; + border-radius: 50%; + background: $blue; +} \ No newline at end of file diff --git a/mdm-front/src/pages/DevicesPage/components/DevicesToolbar/DevicesToolbar.tsx b/mdm-front/src/pages/DevicesPage/components/DevicesToolbar/DevicesToolbar.tsx new file mode 100644 index 0000000..0596ed6 --- /dev/null +++ b/mdm-front/src/pages/DevicesPage/components/DevicesToolbar/DevicesToolbar.tsx @@ -0,0 +1,38 @@ +import { Search, SlidersHorizontal } from 'lucide-react' +import './DevicesToolbar.scss' + +type DevicesToolbarProps = { + isFiltersOpen: boolean + onToggleFilters: () => void +} + +export function DevicesToolbar({ isFiltersOpen, onToggleFilters }: DevicesToolbarProps) { + return ( +
+ + +
+ + + + +
+
+ ) +} \ No newline at end of file diff --git a/mdm-front/src/pages/DevicesPage/devices.mock.json b/mdm-front/src/pages/DevicesPage/devices.mock.json new file mode 100644 index 0000000..4a2d028 --- /dev/null +++ b/mdm-front/src/pages/DevicesPage/devices.mock.json @@ -0,0 +1,102 @@ +[ + { + "id": 1, + "factoryNumber": "Заводской номер", + "imei": "IMEI устройства", + "workTime": "4 ч 15 мин", + "employee": "Иванов Иван Иванович", + "condition": "ok", + "connection": "online", + "connectionText": "В сети", + "statusIcons": { + "gps": true, + "wifi": true, + "bluetooth": true, + "lock": false, + "camera": true, + "sim": true, + "sound": false, + "kiosk": false + } + }, + { + "id": 2, + "factoryNumber": "Заводской номер", + "imei": "IMEI устройства", + "workTime": null, + "employee": null, + "condition": "inspection", + "connection": "offline", + "connectionText": "Не в сети", + "statusIcons": { + "gps": true, + "wifi": true, + "bluetooth": true, + "lock": false, + "camera": true, + "sim": true, + "sound": false, + "kiosk": false + } + }, + { + "id": 3, + "factoryNumber": "Заводской номер", + "imei": "IMEI устройства", + "workTime": "14 ч 15 мин", + "employee": "Иванов Иван Иванович", + "condition": "inspection", + "connection": "offlineDanger", + "connectionText": "Не в сети 10 ч 5 мин", + "statusIcons": { + "gps": true, + "wifi": true, + "bluetooth": true, + "lock": false, + "camera": true, + "sim": true, + "sound": false, + "kiosk": false + } + }, + { + "id": 4, + "factoryNumber": "Заводской номер", + "imei": "IMEI устройства", + "workTime": null, + "employee": null, + "condition": "ok", + "connection": "online", + "connectionText": "В сети", + "statusIcons": { + "gps": true, + "wifi": true, + "bluetooth": true, + "lock": false, + "camera": true, + "sim": true, + "sound": false, + "kiosk": false + } + }, + { + "id": 5, + "factoryNumber": "Заводской номер", + "imei": "IMEI устройства", + "workTime": null, + "employee": null, + "condition": "ok", + "connection": "offline", + "connectionText": "Не в сети", + "statusIcons": { + "gps": true, + "wifi": false, + "bluetooth": false, + "lock": true, + "camera": false, + "sim": true, + "sound": false, + "kiosk": true + } + } +] \ No newline at end of file diff --git a/mdm-front/src/pages/EmployeesPage/EmployeesPage.tsx b/mdm-front/src/pages/EmployeesPage/EmployeesPage.tsx new file mode 100644 index 0000000..1bc9891 --- /dev/null +++ b/mdm-front/src/pages/EmployeesPage/EmployeesPage.tsx @@ -0,0 +1,3 @@ +export function EmployeesPage() { + return

Сотрудники

+} \ No newline at end of file diff --git a/mdm-front/src/pages/MapPage/MapPage.tsx b/mdm-front/src/pages/MapPage/MapPage.tsx new file mode 100644 index 0000000..bc2c9ef --- /dev/null +++ b/mdm-front/src/pages/MapPage/MapPage.tsx @@ -0,0 +1,3 @@ +export function MapPage() { + return

Карта

+} \ No newline at end of file diff --git a/mdm-front/src/shared/styles/_variables.scss b/mdm-front/src/shared/styles/_variables.scss new file mode 100644 index 0000000..e45e8a0 --- /dev/null +++ b/mdm-front/src/shared/styles/_variables.scss @@ -0,0 +1,11 @@ +// colors light +$color-bg: #EFF2F7; +$gray50: #6A768E; +$gray30: hsla(219, 32%, 76%, 0.2); +$gray20: #E2E7F0; +$color-text: #2F3747; +$red: #DD0000; +$red20: hsla(0, 100%, 43%, 0.2); +$green: #33B343; +$blue: #031D9A; +$blue20: hsla(230, 96%, 31%, 0.2); diff --git a/mdm-front/src/widgets/Navbar/Navbar.scss b/mdm-front/src/widgets/Navbar/Navbar.scss new file mode 100644 index 0000000..b18adc8 --- /dev/null +++ b/mdm-front/src/widgets/Navbar/Navbar.scss @@ -0,0 +1,9 @@ +@use '../../shared/styles/variables' as *; + +.navbar{ + display: flex; + flex-direction: row; + gap: 100px; + justify-content: space-between; + padding-bottom: 26px; +} \ No newline at end of file diff --git a/mdm-front/src/widgets/Navbar/Navbar.tsx b/mdm-front/src/widgets/Navbar/Navbar.tsx new file mode 100644 index 0000000..a4691d1 --- /dev/null +++ b/mdm-front/src/widgets/Navbar/Navbar.tsx @@ -0,0 +1,25 @@ +import { useLocation } from 'react-router-dom' +import './Navbar.scss' + +const pageTitles: Record = { + '/devices': 'Устройства', + '/employees': 'Сотрудники', + '/map': 'Карта', +} + +export function Navbar() { + const location = useLocation() + + const title = pageTitles[location.pathname] ?? '' + + return ( +
+
+

{title}

+
+
+ Администратор +
+
+ ) +} \ No newline at end of file diff --git a/mdm-front/src/widgets/Sidebar/Sidebar.scss b/mdm-front/src/widgets/Sidebar/Sidebar.scss new file mode 100644 index 0000000..e2db403 --- /dev/null +++ b/mdm-front/src/widgets/Sidebar/Sidebar.scss @@ -0,0 +1,191 @@ +@use '../../shared/styles/variables' as *; + +.sidebar { + width: 171px; + min-height: calc(100vh - 56px); + max-height: 100vh; + padding: 20px 20px 36px 20px; + background: transparent; + + display: flex; + flex-direction: column; + justify-content: space-between; + gap: 20px; + + overflow: hidden; + transition: + width 0.25s ease, + padding 0.25s ease; + + .wrap-btn { + width: 100%; + display: flex; + flex-direction: row; + align-items: center; + justify-content: flex-start; + gap: 8px; + + border-radius: 12px; + padding: 12px; + font-size: 20px; + line-height: 1; + cursor: pointer; + + background-color: transparent; + color: $gray50; + font-weight: 500; + border: none; + + transition: + background-color 0.2s ease, + color 0.2s ease; + + &:hover { + background-color: $gray30; + } + + svg { + height: 20px; + width: 20px; + flex: 0 0 20px; + } + } +} + +.sidebar__top { + display: flex; + flex-direction: column; +} + +.sidebar__logo { + margin-bottom: 20px; + display: flex; + align-items: center; + min-height: 32px; + + img { + height: 32px; + width: auto; + display: block; + } +} + +.sidebar__nav { + display: flex; + flex-direction: column; + gap: 4px; +} + +.sidebar__link { + display: flex; + flex-direction: row; + align-items: center; + justify-content: flex-start; + + gap: 8px; + padding: 12px; + border-radius: 12px; + + color: #6a768e; + text-decoration: none; + font-size: 20px; + transition: + background-color 0.2s ease, + color 0.2s ease; + font-weight: 500; + line-height: 1; + + svg { + height: 20px; + width: 20px; + flex: 0 0 20px; + } + + &:hover { + background-color: $gray30; + } +} + +.sidebar__icon { + width: 20px; + height: 20px; + flex: 0 0 20px; + + display: inline-flex; + align-items: center; + justify-content: center; +} + +.sidebar__label { + white-space: nowrap; + overflow: hidden; + transition: + width 0.2s ease, + opacity 0.2s ease; +} + +.sidebar__link--active { + background: white; + color: #031d9a; + + &:hover { + background-color: white; + } +} + +.wrap-btn__arrow { + transition: transform 0.25s ease; +} + +.wrap-btn__text { + white-space: nowrap; + overflow: hidden; + transition: + width 0.2s ease, + opacity 0.2s ease; +} + +/* Свернутое состояние */ + +.sidebar--collapsed { + width: 44px; + padding: 20px 20px 36px 20px; + + .sidebar__logo { + justify-content: center; + } + + .sidebar__nav { + //align-items: center; + } + + .sidebar__link { + //width: 44px; + //height: 44px; + justify-content: center; + padding: 12px; + gap: 0; + } + + .sidebar__label { + width: 0; + opacity: 0; + } + + .wrap-btn { + width: 44px; + height: 44px; + justify-content: center; + padding: 12px; + gap: 0; + } + + .wrap-btn__text { + width: 0; + opacity: 0; + } + + .wrap-btn__arrow { + transform: rotate(180deg); + } +} \ No newline at end of file diff --git a/mdm-front/src/widgets/Sidebar/Sidebar.tsx b/mdm-front/src/widgets/Sidebar/Sidebar.tsx new file mode 100644 index 0000000..e095feb --- /dev/null +++ b/mdm-front/src/widgets/Sidebar/Sidebar.tsx @@ -0,0 +1,75 @@ +import { useState } from 'react' +import { NavLink } from 'react-router-dom' +import './Sidebar.scss' +import Logo from '../../assets/Logo.svg' +import LogoCompact from '../../assets/LogoIcon.svg' + +const links = [ + { + to: '/devices', + label: 'Устройства', + icon: + + + + + }, + { + to: '/employees', + label: 'Сотрудники', + icon: + + + + }, + { + to: '/map', + label: 'Карта', + icon: + + + + + + + + }, +] + +export function Sidebar() { + const [collapsed, setCollapsed] = useState(false) + + return ( + + ) +} \ No newline at end of file