From 5248d51b057f0a26a1b6492352b7d9922e87424d Mon Sep 17 00:00:00 2001 From: p2405951 Date: Sun, 23 Nov 2025 18:11:16 +0100 Subject: [PATCH 01/31] add stat prototype --- package-lock.json | 2779 +++++++++++++++++++++++++++- src/pages/Stat/StatPage.jsx | 115 ++ src/pages/Stat/StatPage.module.css | 119 ++ src/router.js | 5 + 4 files changed, 3006 insertions(+), 12 deletions(-) create mode 100644 src/pages/Stat/StatPage.jsx create mode 100644 src/pages/Stat/StatPage.module.css diff --git a/package-lock.json b/package-lock.json index f735373..0591a36 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,17 +13,36 @@ "react-router": "^7.9.4" }, "devDependencies": { + "@chromatic-com/storybook": "^4.1.2", "@eslint/js": "^9.36.0", + "@storybook/addon-a11y": "^10.0.6", + "@storybook/addon-docs": "^10.0.6", + "@storybook/addon-vitest": "^10.0.6", + "@storybook/react-vite": "^10.0.6", "@types/react": "^19.1.16", "@types/react-dom": "^19.1.9", "@vitejs/plugin-react": "^5.0.4", + "@vitest/browser-playwright": "^4.0.8", + "@vitest/coverage-v8": "^4.0.8", "eslint": "^9.36.0", "eslint-plugin-react-hooks": "^5.2.0", "eslint-plugin-react-refresh": "^0.4.22", + "eslint-plugin-storybook": "^10.0.6", "globals": "^16.4.0", - "vite": "^7.1.7" + "playwright": "^1.56.1", + "prop-types": "^15.8.1", + "storybook": "^10.0.6", + "vite": "^7.1.7", + "vitest": "^4.0.8" } }, + "node_modules/@adobe/css-tools": { + "version": "4.4.4", + "resolved": "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.4.4.tgz", + "integrity": "sha512-Elp+iwUx5rN5+Y8xLt5/GRoG20WGoDCQ/1Fb+1LiGtvwbDavuSk0jhD/eZdckHAuzcDzccnkv+rEjyWfRx18gg==", + "dev": true, + "license": "MIT" + }, "node_modules/@babel/code-frame": { "version": "7.27.1", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz", @@ -177,9 +196,9 @@ } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz", - "integrity": "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==", + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", + "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", "dev": true, "license": "MIT", "engines": { @@ -211,13 +230,13 @@ } }, "node_modules/@babel/parser": { - "version": "7.28.4", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.4.tgz", - "integrity": "sha512-yZbBqeM6TkpP9du/I2pUZnJsRMGGvOuIrhjzC1AwHwW+6he4mni6Bp/m8ijn0iOuZuPI2BfkCoSRunpyjnrQKg==", + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.5.tgz", + "integrity": "sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ==", "dev": true, "license": "MIT", "dependencies": { - "@babel/types": "^7.28.4" + "@babel/types": "^7.28.5" }, "bin": { "parser": "bin/babel-parser.js" @@ -258,6 +277,17 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/@babel/runtime": { + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.4.tgz", + "integrity": "sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@babel/template": { "version": "7.27.2", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz", @@ -293,19 +323,50 @@ } }, "node_modules/@babel/types": { - "version": "7.28.4", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.4.tgz", - "integrity": "sha512-bkFqkLhh3pMBUQQkpVgWDWq/lqzc2678eUyDlTBhRqhCHFguYYGM0Efga7tYk4TogG/3x0EEl66/OQ+WGbWB/Q==", + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.5.tgz", + "integrity": "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==", "dev": true, "license": "MIT", "dependencies": { "@babel/helper-string-parser": "^7.27.1", - "@babel/helper-validator-identifier": "^7.27.1" + "@babel/helper-validator-identifier": "^7.28.5" }, "engines": { "node": ">=6.9.0" } }, + "node_modules/@bcoe/v8-coverage": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-1.0.2.tgz", + "integrity": "sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/@chromatic-com/storybook": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/@chromatic-com/storybook/-/storybook-4.1.3.tgz", + "integrity": "sha512-hc0HO9GAV9pxqDE6fTVOV5KeLpTiCfV8Jrpk5ogKLiIgeq2C+NPjpt74YnrZTjiK8E19fYcMP+2WY9ZtX7zHmw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@neoconfetti/react": "^1.0.0", + "chromatic": "^13.3.3", + "filesize": "^10.0.12", + "jsonfile": "^6.1.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=20.0.0", + "yarn": ">=1.22.18" + }, + "peerDependencies": { + "storybook": "^0.0.0-0 || ^9.0.0 || ^9.1.0-0 || ^9.2.0-0 || ^10.0.0-0 || ^10.1.0-0 || ^10.2.0-0 || ^10.3.0-0" + } + }, "node_modules/@esbuild/aix-ppc64": { "version": "0.25.10", "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.10.tgz", @@ -957,6 +1018,45 @@ "url": "https://github.com/sponsors/nzakas" } }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@joshwooding/vite-plugin-react-docgen-typescript": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/@joshwooding/vite-plugin-react-docgen-typescript/-/vite-plugin-react-docgen-typescript-0.6.1.tgz", + "integrity": "sha512-J4BaTocTOYFkMHIra1JDWrMWpNmBl4EkplIwHEsV8aeUOtdWjwSnln9U7twjMFTAEB7mptNtSKyVi1Y2W9sDJw==", + "dev": true, + "license": "MIT", + "dependencies": { + "glob": "^10.0.0", + "magic-string": "^0.30.0", + "react-docgen-typescript": "^2.2.2" + }, + "peerDependencies": { + "typescript": ">= 4.3.x", + "vite": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, "node_modules/@jridgewell/gen-mapping": { "version": "0.3.13", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", @@ -1007,6 +1107,87 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, + "node_modules/@mdx-js/react": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@mdx-js/react/-/react-3.1.1.tgz", + "integrity": "sha512-f++rKLQgUVYDAtECQ6fn/is15GkEH9+nZPM3MS0RcxVqoTfawHvDlSCH7JbMhAM6uJ32v3eXLvLmLvjGu7PTQw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdx": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + }, + "peerDependencies": { + "@types/react": ">=16", + "react": ">=16" + } + }, + "node_modules/@neoconfetti/react": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@neoconfetti/react/-/react-1.0.0.tgz", + "integrity": "sha512-klcSooChXXOzIm+SE5IISIAn3bYzYfPjbX7D7HoqZL84oAfgREeSg5vSIaSFH+DaGzzvImTyWe1OyrJ67vik4A==", + "dev": true, + "license": "MIT" + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@polka/url": { + "version": "1.0.0-next.29", + "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.29.tgz", + "integrity": "sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==", + "dev": true, + "license": "MIT" + }, "node_modules/@rolldown/pluginutils": { "version": "1.0.0-beta.38", "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.38.tgz", @@ -1014,6 +1195,29 @@ "dev": true, "license": "MIT" }, + "node_modules/@rollup/pluginutils": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.3.0.tgz", + "integrity": "sha512-5EdhGZtnu3V88ces7s53hhfK5KSASnJZv8Lulpc04cWO3REESroJXg73DFsOmgbU2BhwV0E20bu2IDZb3VKW4Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "estree-walker": "^2.0.2", + "picomatch": "^4.0.2" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, "node_modules/@rollup/rollup-android-arm-eabi": { "version": "4.52.4", "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.52.4.tgz", @@ -1322,6 +1526,307 @@ "win32" ] }, + "node_modules/@standard-schema/spec": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.0.0.tgz", + "integrity": "sha512-m2bOd0f2RT9k8QJx1JN85cZYyH1RqFBdlwtkSlf4tBDYLCiiZnv1fIIwacK6cqwXavOydf0NPToMQgpKq+dVlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@storybook/addon-a11y": { + "version": "10.0.8", + "resolved": "https://registry.npmjs.org/@storybook/addon-a11y/-/addon-a11y-10.0.8.tgz", + "integrity": "sha512-rXJuSfujuRqkz1v26wLttVRkXzZur3LtMTH1/K+rb1epXq305vRm/bYql0FYGvrq0idJWYo4WbU65YRig9sfuA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@storybook/global": "^5.0.0", + "axe-core": "^4.2.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "storybook": "^10.0.8" + } + }, + "node_modules/@storybook/addon-docs": { + "version": "10.0.8", + "resolved": "https://registry.npmjs.org/@storybook/addon-docs/-/addon-docs-10.0.8.tgz", + "integrity": "sha512-PYuaGXGycsamK/7OrFoE4syHGy22mdqqArl67cfosRwmRxZEI9ManQK0jTjNQM9ZX14NpThMOSWNGoWLckkxog==", + "dev": true, + "license": "MIT", + "dependencies": { + "@mdx-js/react": "^3.0.0", + "@storybook/csf-plugin": "10.0.8", + "@storybook/icons": "^1.6.0", + "@storybook/react-dom-shim": "10.0.8", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "ts-dedent": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "storybook": "^10.0.8" + } + }, + "node_modules/@storybook/addon-vitest": { + "version": "10.0.8", + "resolved": "https://registry.npmjs.org/@storybook/addon-vitest/-/addon-vitest-10.0.8.tgz", + "integrity": "sha512-f9LoBPNz3cLBUWbkeYV7OFSrcONKxVT/NXeMek0/H1VwRwU/caYMoIAQzQwK4AueXkMUeba4DZfB/FvzB8mM6A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@storybook/global": "^5.0.0", + "@storybook/icons": "^1.6.0", + "prompts": "^2.4.0", + "ts-dedent": "^2.2.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "@vitest/browser": "^3.0.0 || ^4.0.0", + "@vitest/browser-playwright": "^4.0.0", + "@vitest/runner": "^3.0.0 || ^4.0.0", + "storybook": "^10.0.8", + "vitest": "^3.0.0 || ^4.0.0" + }, + "peerDependenciesMeta": { + "@vitest/browser": { + "optional": true + }, + "@vitest/browser-playwright": { + "optional": true + }, + "@vitest/runner": { + "optional": true + }, + "vitest": { + "optional": true + } + } + }, + "node_modules/@storybook/builder-vite": { + "version": "10.0.8", + "resolved": "https://registry.npmjs.org/@storybook/builder-vite/-/builder-vite-10.0.8.tgz", + "integrity": "sha512-kaf/pUENzXxYgQMHGGPNiIk1ieb+SOMuSeLKx8wAUOlQOrzhtSH+ItACW/l43t+O6YZ8jYHoNBMF1kdQ1+Y5+w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@storybook/csf-plugin": "10.0.8", + "ts-dedent": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "storybook": "^10.0.8", + "vite": "^5.0.0 || ^6.0.0 || ^7.0.0" + } + }, + "node_modules/@storybook/csf-plugin": { + "version": "10.0.8", + "resolved": "https://registry.npmjs.org/@storybook/csf-plugin/-/csf-plugin-10.0.8.tgz", + "integrity": "sha512-OtLUWHIm3SDGtclQn6Mdd/YsWizLBgdEBRAdekGtwI/TvICfT7gpWYIycP53v2t9ufu2MIXjsxtV2maZKs8sZg==", + "dev": true, + "license": "MIT", + "dependencies": { + "unplugin": "^2.3.5" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "esbuild": "*", + "rollup": "*", + "storybook": "^10.0.8", + "vite": "*", + "webpack": "*" + }, + "peerDependenciesMeta": { + "esbuild": { + "optional": true + }, + "rollup": { + "optional": true + }, + "vite": { + "optional": true + }, + "webpack": { + "optional": true + } + } + }, + "node_modules/@storybook/global": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@storybook/global/-/global-5.0.0.tgz", + "integrity": "sha512-FcOqPAXACP0I3oJ/ws6/rrPT9WGhu915Cg8D02a9YxLo0DE9zI+a9A5gRGvmQ09fiWPukqI8ZAEoQEdWUKMQdQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@storybook/icons": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@storybook/icons/-/icons-1.6.0.tgz", + "integrity": "sha512-hcFZIjW8yQz8O8//2WTIXylm5Xsgc+lW9ISLgUk1xGmptIJQRdlhVIXCpSyLrQaaRiyhQRaVg7l3BD9S216BHw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta" + } + }, + "node_modules/@storybook/react": { + "version": "10.0.8", + "resolved": "https://registry.npmjs.org/@storybook/react/-/react-10.0.8.tgz", + "integrity": "sha512-PkuPb8sAqmjjkowSzm3rutiSuETvZI2F8SnjbHE6FRqZWWK4iFoaUrQbrg5kpPAtX//xIrqkdFwlbmQ3skhiPA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@storybook/global": "^5.0.0", + "@storybook/react-dom-shim": "10.0.8" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "storybook": "^10.0.8", + "typescript": ">= 4.9.x" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@storybook/react-dom-shim": { + "version": "10.0.8", + "resolved": "https://registry.npmjs.org/@storybook/react-dom-shim/-/react-dom-shim-10.0.8.tgz", + "integrity": "sha512-ojuH22MB9Sz6rWbhTmC5IErZr0ZADbZijtPteUdydezY7scORT00UtbNoBcG0V6iVjdChgDtSKw2KHUUfchKqg==", + "dev": true, + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "storybook": "^10.0.8" + } + }, + "node_modules/@storybook/react-vite": { + "version": "10.0.8", + "resolved": "https://registry.npmjs.org/@storybook/react-vite/-/react-vite-10.0.8.tgz", + "integrity": "sha512-HS2X4qlitrZr3/sN2+ollxAaNE813IasZRE8lOez1Ey1ISGBtYIb9rmJs82MK35+yDM0pHdiDjkFMD4SkNYh2g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@joshwooding/vite-plugin-react-docgen-typescript": "0.6.1", + "@rollup/pluginutils": "^5.0.2", + "@storybook/builder-vite": "10.0.8", + "@storybook/react": "10.0.8", + "empathic": "^2.0.0", + "magic-string": "^0.30.0", + "react-docgen": "^8.0.0", + "resolve": "^1.22.8", + "tsconfig-paths": "^4.2.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "storybook": "^10.0.8", + "vite": "^5.0.0 || ^6.0.0 || ^7.0.0" + } + }, + "node_modules/@testing-library/dom": { + "version": "10.4.1", + "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-10.4.1.tgz", + "integrity": "sha512-o4PXJQidqJl82ckFaXUeoAW+XysPLauYI43Abki5hABd853iMhitooc6znOnczgbTYmEP6U6/y1ZyKAIsvMKGg==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@babel/code-frame": "^7.10.4", + "@babel/runtime": "^7.12.5", + "@types/aria-query": "^5.0.1", + "aria-query": "5.3.0", + "dom-accessibility-api": "^0.5.9", + "lz-string": "^1.5.0", + "picocolors": "1.1.1", + "pretty-format": "^27.0.2" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@testing-library/jest-dom": { + "version": "6.9.1", + "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-6.9.1.tgz", + "integrity": "sha512-zIcONa+hVtVSSep9UT3jZ5rizo2BsxgyDYU7WFD5eICBE7no3881HGeb/QkGfsJs6JTkY1aQhT7rIPC7e+0nnA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@adobe/css-tools": "^4.4.0", + "aria-query": "^5.0.0", + "css.escape": "^1.5.1", + "dom-accessibility-api": "^0.6.3", + "picocolors": "^1.1.1", + "redent": "^3.0.0" + }, + "engines": { + "node": ">=14", + "npm": ">=6", + "yarn": ">=1" + } + }, + "node_modules/@testing-library/jest-dom/node_modules/dom-accessibility-api": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.6.3.tgz", + "integrity": "sha512-7ZgogeTnjuHbo+ct10G9Ffp0mif17idi0IyWNVA/wcwcm7NPOD/WEHVP3n7n3MhXqxoIYm8d6MuZohYWIZ4T3w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@testing-library/user-event": { + "version": "14.6.1", + "resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-14.6.1.tgz", + "integrity": "sha512-vq7fv0rnt+QTXgPxr5Hjc210p6YKq2kmdziLgnsZGgLJ9e6VAShx1pACLuRjd/AS/sr7phAR58OIIpf0LlmQNw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12", + "npm": ">=6" + }, + "peerDependencies": { + "@testing-library/dom": ">=7.21.4" + } + }, + "node_modules/@types/aria-query": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.4.tgz", + "integrity": "sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==", + "dev": true, + "license": "MIT", + "peer": true + }, "node_modules/@types/babel__core": { "version": "7.20.5", "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", @@ -1367,6 +1872,31 @@ "@babel/types": "^7.28.2" } }, + "node_modules/@types/chai": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-5.2.3.tgz", + "integrity": "sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/deep-eql": "*", + "assertion-error": "^2.0.1" + } + }, + "node_modules/@types/deep-eql": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/deep-eql/-/deep-eql-4.0.2.tgz", + "integrity": "sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/doctrine": { + "version": "0.0.9", + "resolved": "https://registry.npmjs.org/@types/doctrine/-/doctrine-0.0.9.tgz", + "integrity": "sha512-eOIHzCUSH7SMfonMG1LsC2f8vxBFtho6NGBznK41R84YzPuvSBzrhEps33IsQiOW9+VL6NQ9DbjQJznk/S4uRA==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/estree": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", @@ -1381,6 +1911,13 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/mdx": { + "version": "2.0.13", + "resolved": "https://registry.npmjs.org/@types/mdx/-/mdx-2.0.13.tgz", + "integrity": "sha512-+OWZQfAYyio6YkJb3HLxDrvnx6SWWDbC0zVPfBRzUk0/nqoDyf6dNxQi3eArPe8rJ473nobTMQ/8Zk+LxJ+Yuw==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/react": { "version": "19.2.2", "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.2.tgz", @@ -1401,6 +1938,194 @@ "@types/react": "^19.2.0" } }, + "node_modules/@types/resolve": { + "version": "1.20.6", + "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.6.tgz", + "integrity": "sha512-A4STmOXPhMUtHH+S6ymgE2GiBSMqf4oTvcQZMcHzokuTLVYzXTB8ttjcgxOVaAp2lGwEdzZ0J+cRbbeevQj1UQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@typescript-eslint/project-service": { + "version": "8.47.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.47.0.tgz", + "integrity": "sha512-2X4BX8hUeB5JcA1TQJ7GjcgulXQ+5UkNb0DL8gHsHUHdFoiCTJoYLTpib3LtSDPZsRET5ygN4qqIWrHyYIKERA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/tsconfig-utils": "^8.47.0", + "@typescript-eslint/types": "^8.47.0", + "debug": "^4.3.4" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "8.47.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.47.0.tgz", + "integrity": "sha512-a0TTJk4HXMkfpFkL9/WaGTNuv7JWfFTQFJd6zS9dVAjKsojmv9HT55xzbEpnZoY+VUb+YXLMp+ihMLz/UlZfDg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.47.0", + "@typescript-eslint/visitor-keys": "8.47.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/tsconfig-utils": { + "version": "8.47.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.47.0.tgz", + "integrity": "sha512-ybUAvjy4ZCL11uryalkKxuT3w3sXJAuWhOoGS3T/Wu+iUu1tGJmk5ytSY8gbdACNARmcYEB0COksD2j6hfGK2g==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/types": { + "version": "8.47.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.47.0.tgz", + "integrity": "sha512-nHAE6bMKsizhA2uuYZbEbmp5z2UpffNrPEqiKIeN7VsV6UY/roxanWfoRrf6x/k9+Obf+GQdkm0nPU+vnMXo9A==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "8.47.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.47.0.tgz", + "integrity": "sha512-k6ti9UepJf5NpzCjH31hQNLHQWupTRPhZ+KFF8WtTuTpy7uHPfeg2NM7cP27aCGajoEplxJDFVCEm9TGPYyiVg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/project-service": "8.47.0", + "@typescript-eslint/tsconfig-utils": "8.47.0", + "@typescript-eslint/types": "8.47.0", + "@typescript-eslint/visitor-keys": "8.47.0", + "debug": "^4.3.4", + "fast-glob": "^3.3.2", + "is-glob": "^4.0.3", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^2.1.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "8.47.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.47.0.tgz", + "integrity": "sha512-g7XrNf25iL4TJOiPqatNuaChyqt49a/onq5YsJ9+hXeugK+41LVg7AxikMfM02PC6jbNtZLCJj6AUcQXJS/jGQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.7.0", + "@typescript-eslint/scope-manager": "8.47.0", + "@typescript-eslint/types": "8.47.0", + "@typescript-eslint/typescript-estree": "8.47.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "8.47.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.47.0.tgz", + "integrity": "sha512-SIV3/6eftCy1bNzCQoPmbWsRLujS8t5iDIZ4spZOBHqrM+yfX2ogg8Tt3PDTAVKw3sSCiUgg30uOAvK2r9zGjQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.47.0", + "eslint-visitor-keys": "^4.2.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, "node_modules/@vitejs/plugin-react": { "version": "5.0.4", "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-5.0.4.tgz", @@ -1422,6 +2147,256 @@ "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0" } }, + "node_modules/@vitest/browser": { + "version": "4.0.13", + "resolved": "https://registry.npmjs.org/@vitest/browser/-/browser-4.0.13.tgz", + "integrity": "sha512-lruSgrYPVAJzKmX6EJYCg9nY+0A4VkeTLpTzf1jRD/XMjNbzD9yy7D499xmVKglwJczANYJXBvZSPGcRlon+0w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/mocker": "4.0.13", + "@vitest/utils": "4.0.13", + "magic-string": "^0.30.21", + "pixelmatch": "7.1.0", + "pngjs": "^7.0.0", + "sirv": "^3.0.2", + "tinyrainbow": "^3.0.3", + "ws": "^8.18.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "vitest": "4.0.13" + } + }, + "node_modules/@vitest/browser-playwright": { + "version": "4.0.13", + "resolved": "https://registry.npmjs.org/@vitest/browser-playwright/-/browser-playwright-4.0.13.tgz", + "integrity": "sha512-oaRY+/pvwS4/sN2rE2aZh9jdli8EkXm5AidmXEbWRu2wW0omG9PmgChWCX2jsD9qRLQxXTSLl5oKezANNF6LnQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/browser": "4.0.13", + "@vitest/mocker": "4.0.13", + "tinyrainbow": "^3.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "playwright": "*", + "vitest": "4.0.13" + }, + "peerDependenciesMeta": { + "playwright": { + "optional": false + } + } + }, + "node_modules/@vitest/coverage-v8": { + "version": "4.0.13", + "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-4.0.13.tgz", + "integrity": "sha512-w77N6bmtJ3CFnL/YHiYotwW/JI3oDlR3K38WEIqegRfdMSScaYxwYKB/0jSNpOTZzUjQkG8HHEz4sdWQMWpQ5g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@bcoe/v8-coverage": "^1.0.2", + "@vitest/utils": "4.0.13", + "ast-v8-to-istanbul": "^0.3.8", + "debug": "^4.4.3", + "istanbul-lib-coverage": "^3.2.2", + "istanbul-lib-report": "^3.0.1", + "istanbul-lib-source-maps": "^5.0.6", + "istanbul-reports": "^3.2.0", + "magicast": "^0.5.1", + "std-env": "^3.10.0", + "tinyrainbow": "^3.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "@vitest/browser": "4.0.13", + "vitest": "4.0.13" + }, + "peerDependenciesMeta": { + "@vitest/browser": { + "optional": true + } + } + }, + "node_modules/@vitest/expect": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-3.2.4.tgz", + "integrity": "sha512-Io0yyORnB6sikFlt8QW5K7slY4OjqNX9jmJQ02QDda8lyM6B5oNgVWoSoKPac8/kgnCUzuHQKrSLtu/uOqqrig==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/chai": "^5.2.2", + "@vitest/spy": "3.2.4", + "@vitest/utils": "3.2.4", + "chai": "^5.2.0", + "tinyrainbow": "^2.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/expect/node_modules/@vitest/pretty-format": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-3.2.4.tgz", + "integrity": "sha512-IVNZik8IVRJRTr9fxlitMKeJeXFFFN0JaB9PHPGQ8NKQbGpfjlTx9zO4RefN8gp7eqjNy8nyK3NZmBzOPeIxtA==", + "dev": true, + "license": "MIT", + "dependencies": { + "tinyrainbow": "^2.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/expect/node_modules/@vitest/spy": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-3.2.4.tgz", + "integrity": "sha512-vAfasCOe6AIK70iP5UD11Ac4siNUNJ9i/9PZ3NKx07sG6sUxeag1LWdNrMWeKKYBLlzuK+Gn65Yd5nyL6ds+nw==", + "dev": true, + "license": "MIT", + "dependencies": { + "tinyspy": "^4.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/expect/node_modules/@vitest/utils": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-3.2.4.tgz", + "integrity": "sha512-fB2V0JFrQSMsCo9HiSq3Ezpdv4iYaXRG1Sx8edX3MwxfyNn83mKiGzOcH+Fkxt4MHxr3y42fQi1oeAInqgX2QA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "3.2.4", + "loupe": "^3.1.4", + "tinyrainbow": "^2.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/expect/node_modules/tinyrainbow": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-2.0.0.tgz", + "integrity": "sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@vitest/mocker": { + "version": "4.0.13", + "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-4.0.13.tgz", + "integrity": "sha512-eNCwzrI5djoauklwP1fuslHBjrbR8rqIVbvNlAnkq1OTa6XT+lX68mrtPirNM9TnR69XUPt4puBCx2Wexseylg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/spy": "4.0.13", + "estree-walker": "^3.0.3", + "magic-string": "^0.30.21" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "msw": "^2.4.9", + "vite": "^6.0.0 || ^7.0.0-0" + }, + "peerDependenciesMeta": { + "msw": { + "optional": true + }, + "vite": { + "optional": true + } + } + }, + "node_modules/@vitest/mocker/node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0" + } + }, + "node_modules/@vitest/pretty-format": { + "version": "4.0.13", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.0.13.tgz", + "integrity": "sha512-ooqfze8URWbI2ozOeLDMh8YZxWDpGXoeY3VOgcDnsUxN0jPyPWSUvjPQWqDGCBks+opWlN1E4oP1UYl3C/2EQA==", + "dev": true, + "license": "MIT", + "dependencies": { + "tinyrainbow": "^3.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/runner": { + "version": "4.0.13", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-4.0.13.tgz", + "integrity": "sha512-9IKlAru58wcVaWy7hz6qWPb2QzJTKt+IOVKjAx5vb5rzEFPTL6H4/R9BMvjZ2ppkxKgTrFONEJFtzvnyEpiT+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/utils": "4.0.13", + "pathe": "^2.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/snapshot": { + "version": "4.0.13", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-4.0.13.tgz", + "integrity": "sha512-hb7Usvyika1huG6G6l191qu1urNPsq1iFc2hmdzQY3F5/rTgqQnwwplyf8zoYHkpt7H6rw5UfIw6i/3qf9oSxQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "4.0.13", + "magic-string": "^0.30.21", + "pathe": "^2.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/spy": { + "version": "4.0.13", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-4.0.13.tgz", + "integrity": "sha512-hSu+m4se0lDV5yVIcNWqjuncrmBgwaXa2utFLIrBkQCQkt+pSwyZTPFQAZiiF/63j8jYa8uAeUZ3RSfcdWaYWw==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/utils": { + "version": "4.0.13", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-4.0.13.tgz", + "integrity": "sha512-ydozWyQ4LZuu8rLp47xFUWis5VOKMdHjXCWhs1LuJsTNKww+pTHQNK4e0assIB9K80TxFyskENL6vCu3j34EYA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "4.0.13", + "tinyrainbow": "^3.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, "node_modules/acorn": { "version": "8.15.0", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", @@ -1462,6 +2437,16 @@ "url": "https://github.com/sponsors/epoberezkin" } }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", @@ -1485,6 +2470,78 @@ "dev": true, "license": "Python-2.0" }, + "node_modules/aria-query": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz", + "integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "dequal": "^2.0.3" + } + }, + "node_modules/assertion-error": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", + "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + } + }, + "node_modules/ast-types": { + "version": "0.16.1", + "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.16.1.tgz", + "integrity": "sha512-6t10qk83GOG8p0vKmaCr8eiilZwO171AvbROMtvvNiwrTly62t+7XkA8RdIIVbpMhCASAsxgAzdRSwh6nw/5Dg==", + "dev": true, + "license": "MIT", + "dependencies": { + "tslib": "^2.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/ast-v8-to-istanbul": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/ast-v8-to-istanbul/-/ast-v8-to-istanbul-0.3.8.tgz", + "integrity": "sha512-szgSZqUxI5T8mLKvS7WTjF9is+MVbOeLADU73IseOcrqhxr/VAvy6wfoVE39KnKzA7JRhjF5eUagNlHwvZPlKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.31", + "estree-walker": "^3.0.3", + "js-tokens": "^9.0.1" + } + }, + "node_modules/ast-v8-to-istanbul/node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0" + } + }, + "node_modules/ast-v8-to-istanbul/node_modules/js-tokens": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-9.0.1.tgz", + "integrity": "sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/axe-core": { + "version": "4.11.0", + "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.11.0.tgz", + "integrity": "sha512-ilYanEU8vxxBexpJd8cWM4ElSQq4QctCLKih0TSfjIfCQTeyH/6zVrmIJfLPrKTKJRbiG+cfnZbQIjAlJmF1jQ==", + "dev": true, + "license": "MPL-2.0", + "engines": { + "node": ">=4" + } + }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", @@ -1513,6 +2570,19 @@ "concat-map": "0.0.1" } }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/browserslist": { "version": "4.26.3", "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.26.3.tgz", @@ -1578,6 +2648,23 @@ ], "license": "CC-BY-4.0" }, + "node_modules/chai": { + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/chai/-/chai-5.3.3.tgz", + "integrity": "sha512-4zNhdJD/iOjSH0A05ea+Ke6MU5mmpQcbQsSOkgdaUMJ9zTlDTD/GYlwohmIE2u0gaxHYiVHEn1Fw9mZ/ktJWgw==", + "dev": true, + "license": "MIT", + "dependencies": { + "assertion-error": "^2.0.1", + "check-error": "^2.1.1", + "deep-eql": "^5.0.1", + "loupe": "^3.1.0", + "pathval": "^2.0.0" + }, + "engines": { + "node": ">=18" + } + }, "node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -1595,6 +2682,40 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, + "node_modules/check-error": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.1.tgz", + "integrity": "sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 16" + } + }, + "node_modules/chromatic": { + "version": "13.3.4", + "resolved": "https://registry.npmjs.org/chromatic/-/chromatic-13.3.4.tgz", + "integrity": "sha512-TR5rvyH0ESXobBB3bV8jc87AEAFQC7/n+Eb4XWhJz6hW3YNxIQPVjcbgLv+a4oKHEl1dUBueWSoIQsOVGTd+RQ==", + "dev": true, + "license": "MIT", + "bin": { + "chroma": "dist/bin.js", + "chromatic": "dist/bin.js", + "chromatic-cli": "dist/bin.js" + }, + "peerDependencies": { + "@chromatic-com/cypress": "^0.*.* || ^1.0.0", + "@chromatic-com/playwright": "^0.*.* || ^1.0.0" + }, + "peerDependenciesMeta": { + "@chromatic-com/cypress": { + "optional": true + }, + "@chromatic-com/playwright": { + "optional": true + } + } + }, "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -1653,6 +2774,13 @@ "node": ">= 8" } }, + "node_modules/css.escape": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/css.escape/-/css.escape-1.5.1.tgz", + "integrity": "sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==", + "dev": true, + "license": "MIT" + }, "node_modules/csstype": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", @@ -1678,6 +2806,16 @@ } } }, + "node_modules/deep-eql": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.2.tgz", + "integrity": "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/deep-is": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", @@ -1685,6 +2823,44 @@ "dev": true, "license": "MIT" }, + "node_modules/dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/dom-accessibility-api": { + "version": "0.5.16", + "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz", + "integrity": "sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true, + "license": "MIT" + }, "node_modules/electron-to-chromium": { "version": "1.5.234", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.234.tgz", @@ -1692,6 +2868,30 @@ "dev": true, "license": "ISC" }, + "node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true, + "license": "MIT" + }, + "node_modules/empathic": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/empathic/-/empathic-2.0.0.tgz", + "integrity": "sha512-i6UzDscO/XfAcNYD75CfICkmfLedpyPDdozrLMmQc5ORaQcdMoc21OnlEylMIqI7U8eniKrPMxxtj8k0vhmJhA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14" + } + }, + "node_modules/es-module-lexer": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.7.0.tgz", + "integrity": "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==", + "dev": true, + "license": "MIT" + }, "node_modules/esbuild": { "version": "0.25.10", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.10.tgz", @@ -1841,6 +3041,20 @@ "eslint": ">=8.40" } }, + "node_modules/eslint-plugin-storybook": { + "version": "10.0.8", + "resolved": "https://registry.npmjs.org/eslint-plugin-storybook/-/eslint-plugin-storybook-10.0.8.tgz", + "integrity": "sha512-ZKEMFhF/z/HRVvIgnEIYG2uAqmuLbkebUdHH3DpGHE64GPgk+KozcpqnD6zNk5vJ407bFmcWsGinBc2zi74f0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/utils": "^8.8.1" + }, + "peerDependencies": { + "eslint": ">=8", + "storybook": "^10.0.8" + } + }, "node_modules/eslint-scope": { "version": "8.4.0", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz", @@ -1889,6 +3103,20 @@ "url": "https://opencollective.com/eslint" } }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true, + "license": "BSD-2-Clause", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/esquery": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", @@ -1925,6 +3153,13 @@ "node": ">=4.0" } }, + "node_modules/estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", + "dev": true, + "license": "MIT" + }, "node_modules/esutils": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", @@ -1935,6 +3170,16 @@ "node": ">=0.10.0" } }, + "node_modules/expect-type": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.2.2.tgz", + "integrity": "sha512-JhFGDVJ7tmDJItKhYgJCGLOWjuK9vPxiXoUFLwLDc99NlmklilbiQJwoctZtt13+xMw91MCk/REan6MWHqDjyA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.0.0" + } + }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -1942,6 +3187,36 @@ "dev": true, "license": "MIT" }, + "node_modules/fast-glob": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.8" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", @@ -1956,6 +3231,16 @@ "dev": true, "license": "MIT" }, + "node_modules/fastq": { + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz", + "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" + } + }, "node_modules/fdir": { "version": "6.5.0", "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", @@ -1987,6 +3272,29 @@ "node": ">=16.0.0" } }, + "node_modules/filesize": { + "version": "10.1.6", + "resolved": "https://registry.npmjs.org/filesize/-/filesize-10.1.6.tgz", + "integrity": "sha512-sJslQKU2uM33qH5nqewAwVB2QgR6w1aMNsYUp3aN5rMRyXEwJGmZvaWzeJFNTOXWlHQyBFCWrdj3fV/fsTOX8w==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">= 10.4.0" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/find-up": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", @@ -2025,6 +3333,23 @@ "dev": true, "license": "ISC" }, + "node_modules/foreground-child": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", + "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", + "dev": true, + "license": "ISC", + "dependencies": { + "cross-spawn": "^7.0.6", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/fsevents": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", @@ -2040,6 +3365,16 @@ "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/gensync": { "version": "1.0.0-beta.2", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", @@ -2050,6 +3385,27 @@ "node": ">=6.9.0" } }, + "node_modules/glob": { + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", + "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==", + "dev": true, + "license": "ISC", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/glob-parent": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", @@ -2063,6 +3419,32 @@ "node": ">=10.13.0" } }, + "node_modules/glob/node_modules/brace-expansion": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/glob/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/globals": { "version": "16.4.0", "resolved": "https://registry.npmjs.org/globals/-/globals-16.4.0.tgz", @@ -2076,6 +3458,14 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "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==", + "dev": true, + "license": "ISC", + "optional": true + }, "node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -2086,6 +3476,26 @@ "node": ">=8" } }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "dev": true, + "license": "MIT" + }, "node_modules/ignore": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", @@ -2123,6 +3533,32 @@ "node": ">=0.8.19" } }, + "node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-core-module": { + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", + "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", + "dev": true, + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", @@ -2133,6 +3569,16 @@ "node": ">=0.10.0" } }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/is-glob": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", @@ -2146,6 +3592,16 @@ "node": ">=0.10.0" } }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", @@ -2153,6 +3609,76 @@ "dev": true, "license": "ISC" }, + "node_modules/istanbul-lib-coverage": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", + "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-report": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", + "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^4.0.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-source-maps": { + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-5.0.6.tgz", + "integrity": "sha512-yg2d+Em4KizZC5niWhQaIomgf5WlL4vOOjZ5xGCmF8SnPE/mDWWXgvRExdcpCgh9lLRRa1/fSYp2ymmbJ1pI+A==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.23", + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-reports": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.2.0.tgz", + "integrity": "sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jackspeak": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -2220,6 +3746,19 @@ "node": ">=6" } }, + "node_modules/jsonfile": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.0.tgz", + "integrity": "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==", + "dev": true, + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, "node_modules/keyv": { "version": "4.5.4", "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", @@ -2230,6 +3769,16 @@ "json-buffer": "3.0.1" } }, + "node_modules/kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/levn": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", @@ -2267,6 +3816,26 @@ "dev": true, "license": "MIT" }, + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, + "node_modules/loupe": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.2.1.tgz", + "integrity": "sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ==", + "dev": true, + "license": "MIT" + }, "node_modules/lru-cache": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", @@ -2277,6 +3846,115 @@ "yallist": "^3.0.2" } }, + "node_modules/lz-string": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.5.0.tgz", + "integrity": "sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==", + "dev": true, + "license": "MIT", + "peer": true, + "bin": { + "lz-string": "bin/bin.js" + } + }, + "node_modules/magic-string": { + "version": "0.30.21", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", + "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.5" + } + }, + "node_modules/magicast": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/magicast/-/magicast-0.5.1.tgz", + "integrity": "sha512-xrHS24IxaLrvuo613F719wvOIv9xPHFWQHuvGUBmPnCA/3MQxKI3b+r7n1jAoDHmsbC5bRhTZYR77invLAxVnw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.28.5", + "@babel/types": "^7.28.5", + "source-map-js": "^1.2.1" + } + }, + "node_modules/make-dir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", + "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^7.5.3" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/make-dir/node_modules/semver": { + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "dev": true, + "license": "MIT", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/micromatch/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/min-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", + "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, "node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", @@ -2290,6 +3968,36 @@ "node": "*" } }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/mrmime": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.1.tgz", + "integrity": "sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + } + }, "node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", @@ -2330,6 +4038,16 @@ "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/optionator": { "version": "0.9.4", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", @@ -2380,6 +4098,13 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/package-json-from-dist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", + "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", + "dev": true, + "license": "BlueOak-1.0.0" + }, "node_modules/parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", @@ -2413,6 +4138,54 @@ "node": ">=8" } }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true, + "license": "MIT" + }, + "node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-scurry/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/pathe": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", + "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", + "dev": true, + "license": "MIT" + }, + "node_modules/pathval": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-2.0.1.tgz", + "integrity": "sha512-//nshmD55c46FuFw26xV/xFAaB5HF9Xdap7HJBBnrKdAd6/GxDBaNA1870O79+9ueg61cZLSVc+OaFlfmObYVQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14.16" + } + }, "node_modules/picocolors": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", @@ -2433,6 +4206,76 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/pixelmatch": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/pixelmatch/-/pixelmatch-7.1.0.tgz", + "integrity": "sha512-1wrVzJ2STrpmONHKBy228LM1b84msXDUoAzVEl0R8Mz4Ce6EPr+IVtxm8+yvrqLYMHswREkjYFaMxnyGnaY3Ng==", + "dev": true, + "license": "ISC", + "dependencies": { + "pngjs": "^7.0.0" + }, + "bin": { + "pixelmatch": "bin/pixelmatch" + } + }, + "node_modules/playwright": { + "version": "1.56.1", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.56.1.tgz", + "integrity": "sha512-aFi5B0WovBHTEvpM3DzXTUaeN6eN0qWnTkKx4NQaH4Wvcmc153PdaY2UBdSYKaGYw+UyWXSVyxDUg5DoPEttjw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "playwright-core": "1.56.1" + }, + "bin": { + "playwright": "cli.js" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "fsevents": "2.3.2" + } + }, + "node_modules/playwright-core": { + "version": "1.56.1", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.56.1.tgz", + "integrity": "sha512-hutraynyn31F+Bifme+Ps9Vq59hKuUCz7H1kDOcBs+2oGguKkWTU50bBWrtz34OUWmIwpBTWDxaRPXrIXkgvmQ==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "playwright-core": "cli.js" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/playwright/node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/pngjs": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-7.0.0.tgz", + "integrity": "sha512-LKWqWJRhstyYo9pGvgor/ivk2w94eSjE3RGVuzLGlr3NmD8bf7RcYGze1mNdEHRP6TRP6rMuDHk5t44hnTRyow==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.19.0" + } + }, "node_modules/postcss": { "version": "8.5.6", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", @@ -2472,6 +4315,70 @@ "node": ">= 0.8.0" } }, + "node_modules/pretty-format": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz", + "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", + "react-is": "^17.0.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/pretty-format/node_modules/react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/prompts": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", + "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" + }, + "engines": { + "node": ">= 6" + } + }, + "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==", + "dev": true, + "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", @@ -2482,6 +4389,27 @@ "node": ">=6" } }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, "node_modules/react": { "version": "19.2.0", "resolved": "https://registry.npmjs.org/react/-/react-19.2.0.tgz", @@ -2491,6 +4419,38 @@ "node": ">=0.10.0" } }, + "node_modules/react-docgen": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/react-docgen/-/react-docgen-8.0.2.tgz", + "integrity": "sha512-+NRMYs2DyTP4/tqWz371Oo50JqmWltR1h2gcdgUMAWZJIAvrd0/SqlCfx7tpzpl/s36rzw6qH2MjoNrxtRNYhA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.28.0", + "@babel/traverse": "^7.28.0", + "@babel/types": "^7.28.2", + "@types/babel__core": "^7.20.5", + "@types/babel__traverse": "^7.20.7", + "@types/doctrine": "^0.0.9", + "@types/resolve": "^1.20.2", + "doctrine": "^3.0.0", + "resolve": "^1.22.1", + "strip-indent": "^4.0.0" + }, + "engines": { + "node": "^20.9.0 || >=22" + } + }, + "node_modules/react-docgen-typescript": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/react-docgen-typescript/-/react-docgen-typescript-2.4.0.tgz", + "integrity": "sha512-ZtAp5XTO5HRzQctjPU0ybY0RRCQO19X/8fxn3w7y2VVTUbGHDKULPTL4ky3vB05euSgG5NpALhEhDPvQ56wvXg==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "typescript": ">= 4.3.x" + } + }, "node_modules/react-dom": { "version": "19.2.0", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.0.tgz", @@ -2503,6 +4463,13 @@ "react": "^19.2.0" } }, + "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==", + "dev": true, + "license": "MIT" + }, "node_modules/react-refresh": { "version": "0.17.0", "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.17.0.tgz", @@ -2535,6 +4502,71 @@ } } }, + "node_modules/recast": { + "version": "0.23.11", + "resolved": "https://registry.npmjs.org/recast/-/recast-0.23.11.tgz", + "integrity": "sha512-YTUo+Flmw4ZXiWfQKGcwwc11KnoRAYgzAE2E7mXKCjSviTKShtxBsN6YUUBB2gtaBzKzeKunxhUwNHQuRryhWA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ast-types": "^0.16.1", + "esprima": "~4.0.0", + "source-map": "~0.6.1", + "tiny-invariant": "^1.3.3", + "tslib": "^2.0.1" + }, + "engines": { + "node": ">= 4" + } + }, + "node_modules/redent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", + "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", + "dev": true, + "license": "MIT", + "dependencies": { + "indent-string": "^4.0.0", + "strip-indent": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/redent/node_modules/strip-indent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", + "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "min-indent": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve": { + "version": "1.22.11", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.11.tgz", + "integrity": "sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-core-module": "^2.16.1", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/resolve-from": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", @@ -2545,6 +4577,17 @@ "node": ">=4" } }, + "node_modules/reusify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", + "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", + "dev": true, + "license": "MIT", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, "node_modules/rollup": { "version": "4.52.4", "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.52.4.tgz", @@ -2587,6 +4630,30 @@ "fsevents": "~2.3.2" } }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, "node_modules/scheduler": { "version": "0.27.0", "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.27.0.tgz", @@ -2632,6 +4699,58 @@ "node": ">=8" } }, + "node_modules/siginfo": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", + "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", + "dev": true, + "license": "ISC" + }, + "node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/sirv": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/sirv/-/sirv-3.0.2.tgz", + "integrity": "sha512-2wcC/oGxHis/BoHkkPwldgiPSYcpZK3JU28WoMVv55yHJgcZ8rlXvuG9iZggz+sU1d4bRgIGASwyWqjxu3FM0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@polka/url": "^1.0.0-next.24", + "mrmime": "^2.0.0", + "totalist": "^3.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "dev": true, + "license": "MIT" + }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/source-map-js": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", @@ -2642,6 +4761,238 @@ "node": ">=0.10.0" } }, + "node_modules/stackback": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", + "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", + "dev": true, + "license": "MIT" + }, + "node_modules/std-env": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.10.0.tgz", + "integrity": "sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==", + "dev": true, + "license": "MIT" + }, + "node_modules/storybook": { + "version": "10.0.8", + "resolved": "https://registry.npmjs.org/storybook/-/storybook-10.0.8.tgz", + "integrity": "sha512-vQMufKKA9TxgoEDHJv3esrqUkjszuuRiDkThiHxENFPdQawHhm2Dei+iwNRwH5W671zTDy9iRT9P1KDjcU5Iyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@storybook/global": "^5.0.0", + "@storybook/icons": "^1.6.0", + "@testing-library/jest-dom": "^6.6.3", + "@testing-library/user-event": "^14.6.1", + "@vitest/expect": "3.2.4", + "@vitest/mocker": "3.2.4", + "@vitest/spy": "3.2.4", + "esbuild": "^0.18.0 || ^0.19.0 || ^0.20.0 || ^0.21.0 || ^0.22.0 || ^0.23.0 || ^0.24.0 || ^0.25.0", + "recast": "^0.23.5", + "semver": "^7.6.2", + "ws": "^8.18.0" + }, + "bin": { + "storybook": "dist/bin/dispatcher.js" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "prettier": "^2 || ^3" + }, + "peerDependenciesMeta": { + "prettier": { + "optional": true + } + } + }, + "node_modules/storybook/node_modules/@vitest/mocker": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-3.2.4.tgz", + "integrity": "sha512-46ryTE9RZO/rfDd7pEqFl7etuyzekzEhUbTW3BvmeO/BcCMEgq59BKhek3dXDWgAj4oMK6OZi+vRr1wPW6qjEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/spy": "3.2.4", + "estree-walker": "^3.0.3", + "magic-string": "^0.30.17" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "msw": "^2.4.9", + "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0" + }, + "peerDependenciesMeta": { + "msw": { + "optional": true + }, + "vite": { + "optional": true + } + } + }, + "node_modules/storybook/node_modules/@vitest/spy": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-3.2.4.tgz", + "integrity": "sha512-vAfasCOe6AIK70iP5UD11Ac4siNUNJ9i/9PZ3NKx07sG6sUxeag1LWdNrMWeKKYBLlzuK+Gn65Yd5nyL6ds+nw==", + "dev": true, + "license": "MIT", + "dependencies": { + "tinyspy": "^4.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/storybook/node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0" + } + }, + "node_modules/storybook/node_modules/semver": { + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/string-width-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", + "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi/node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/strip-indent": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-4.1.1.tgz", + "integrity": "sha512-SlyRoSkdh1dYP0PzclLE7r0M9sgbFKKMFXpFRUMNuKhQSbC6VQIGzq3E0qsfvGJaUFJPGv6Ws1NZ/haTAjfbMA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/strip-json-comments": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", @@ -2668,6 +5019,40 @@ "node": ">=8" } }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/tiny-invariant": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.3.tgz", + "integrity": "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==", + "dev": true, + "license": "MIT" + }, + "node_modules/tinybench": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz", + "integrity": "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==", + "dev": true, + "license": "MIT" + }, + "node_modules/tinyexec": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.2.tgz", + "integrity": "sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==", + "dev": true, + "license": "MIT" + }, "node_modules/tinyglobby": { "version": "0.2.15", "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", @@ -2685,6 +5070,94 @@ "url": "https://github.com/sponsors/SuperchupuDev" } }, + "node_modules/tinyrainbow": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-3.0.3.tgz", + "integrity": "sha512-PSkbLUoxOFRzJYjjxHJt9xro7D+iilgMX/C9lawzVuYiIdcihh9DXmVibBe8lmcFrRi/VzlPjBxbN7rH24q8/Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/tinyspy": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-4.0.4.tgz", + "integrity": "sha512-azl+t0z7pw/z958Gy9svOTuzqIk6xq+NSheJzn5MMWtWTFywIacg2wUlzKFGtt3cthx0r2SxMK0yzJOR0IES7Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/totalist": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz", + "integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/ts-api-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.1.0.tgz", + "integrity": "sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.12" + }, + "peerDependencies": { + "typescript": ">=4.8.4" + } + }, + "node_modules/ts-dedent": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/ts-dedent/-/ts-dedent-2.2.0.tgz", + "integrity": "sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.10" + } + }, + "node_modules/tsconfig-paths": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-4.2.0.tgz", + "integrity": "sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg==", + "dev": true, + "license": "MIT", + "dependencies": { + "json5": "^2.2.2", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "dev": true, + "license": "0BSD" + }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -2698,6 +5171,47 @@ "node": ">= 0.8.0" } }, + "node_modules/typescript": { + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", + "dev": true, + "license": "Apache-2.0", + "peer": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/unplugin": { + "version": "2.3.11", + "resolved": "https://registry.npmjs.org/unplugin/-/unplugin-2.3.11.tgz", + "integrity": "sha512-5uKD0nqiYVzlmCRs01Fhs2BdkEgBS3SAVP6ndrBsuK42iC2+JHyxM05Rm9G8+5mkmRtzMZGY8Ct5+mliZxU/Ww==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/remapping": "^2.3.5", + "acorn": "^8.15.0", + "picomatch": "^4.0.3", + "webpack-virtual-modules": "^0.6.2" + }, + "engines": { + "node": ">=18.12.0" + } + }, "node_modules/update-browserslist-db": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz", @@ -2814,6 +5328,123 @@ } } }, + "node_modules/vitest": { + "version": "4.0.13", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-4.0.13.tgz", + "integrity": "sha512-QSD4I0fN6uZQfftryIXuqvqgBxTvJ3ZNkF6RWECd82YGAYAfhcppBLFXzXJHQAAhVFyYEuFTrq6h0hQqjB7jIQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/expect": "4.0.13", + "@vitest/mocker": "4.0.13", + "@vitest/pretty-format": "4.0.13", + "@vitest/runner": "4.0.13", + "@vitest/snapshot": "4.0.13", + "@vitest/spy": "4.0.13", + "@vitest/utils": "4.0.13", + "debug": "^4.4.3", + "es-module-lexer": "^1.7.0", + "expect-type": "^1.2.2", + "magic-string": "^0.30.21", + "pathe": "^2.0.3", + "picomatch": "^4.0.3", + "std-env": "^3.10.0", + "tinybench": "^2.9.0", + "tinyexec": "^0.3.2", + "tinyglobby": "^0.2.15", + "tinyrainbow": "^3.0.3", + "vite": "^6.0.0 || ^7.0.0", + "why-is-node-running": "^2.3.0" + }, + "bin": { + "vitest": "vitest.mjs" + }, + "engines": { + "node": "^20.0.0 || ^22.0.0 || >=24.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "@edge-runtime/vm": "*", + "@opentelemetry/api": "^1.9.0", + "@types/debug": "^4.1.12", + "@types/node": "^20.0.0 || ^22.0.0 || >=24.0.0", + "@vitest/browser-playwright": "4.0.13", + "@vitest/browser-preview": "4.0.13", + "@vitest/browser-webdriverio": "4.0.13", + "@vitest/ui": "4.0.13", + "happy-dom": "*", + "jsdom": "*" + }, + "peerDependenciesMeta": { + "@edge-runtime/vm": { + "optional": true + }, + "@opentelemetry/api": { + "optional": true + }, + "@types/debug": { + "optional": true + }, + "@types/node": { + "optional": true + }, + "@vitest/browser-playwright": { + "optional": true + }, + "@vitest/browser-preview": { + "optional": true + }, + "@vitest/browser-webdriverio": { + "optional": true + }, + "@vitest/ui": { + "optional": true + }, + "happy-dom": { + "optional": true + }, + "jsdom": { + "optional": true + } + } + }, + "node_modules/vitest/node_modules/@vitest/expect": { + "version": "4.0.13", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-4.0.13.tgz", + "integrity": "sha512-zYtcnNIBm6yS7Gpr7nFTmq8ncowlMdOJkWLqYvhr/zweY6tFbDkDi8BPPOeHxEtK1rSI69H7Fd4+1sqvEGli6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@standard-schema/spec": "^1.0.0", + "@types/chai": "^5.2.2", + "@vitest/spy": "4.0.13", + "@vitest/utils": "4.0.13", + "chai": "^6.2.1", + "tinyrainbow": "^3.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/vitest/node_modules/chai": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/chai/-/chai-6.2.1.tgz", + "integrity": "sha512-p4Z49OGG5W/WBCPSS/dH3jQ73kD6tiMmUM+bckNK6Jr5JHMG3k9bg/BvKR8lKmtVBKmOiuVaV2ws8s9oSbwysg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/webpack-virtual-modules": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/webpack-virtual-modules/-/webpack-virtual-modules-0.6.2.tgz", + "integrity": "sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==", + "dev": true, + "license": "MIT" + }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -2830,6 +5461,23 @@ "node": ">= 8" } }, + "node_modules/why-is-node-running": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz", + "integrity": "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==", + "dev": true, + "license": "MIT", + "dependencies": { + "siginfo": "^2.0.0", + "stackback": "0.0.2" + }, + "bin": { + "why-is-node-running": "cli.js" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/word-wrap": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", @@ -2840,6 +5488,113 @@ "node": ">=0.10.0" } }, + "node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/wrap-ansi-cjs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/ws": { + "version": "8.18.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.3.tgz", + "integrity": "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, "node_modules/yallist": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", diff --git a/src/pages/Stat/StatPage.jsx b/src/pages/Stat/StatPage.jsx new file mode 100644 index 0000000..c0e7794 --- /dev/null +++ b/src/pages/Stat/StatPage.jsx @@ -0,0 +1,115 @@ +import React, { useState } from "react"; +import styles from "./StatPage.module.css"; + +function StatPage() { + const [months, setMonths] = useState(3); + const participationRate = 90; + + // les event incomplets + const incompleteEvents = [ + { title: "Événement A", tasks: "Préparation des flyers" }, + { title: "Événement B", tasks: "Réservation de la salle" }, + { title: "Événement C", tasks: "Communication sur les réseaux" }, + ]; +/* c la liste des membres en attente*/ + const pendingMembers = [ + { name: "Alice Dupont" }, + { name: "Bob Martin" }, + { name: "Charlie Durand" }, + ]; + + const handleValidate = (name) => { + console.log(`Valider ${name}`); + }; + + const handleReject = (name) => { + console.log(`Refuser ${name}`); + }; + + return ( +
+
+
+ + +
+
+ + + + + {participationRate}% + + +
+
+
+ +
+

Événements incomplets

+
+ {incompleteEvents.map((event, index) => ( +
+

{event.title}

+

{event.tasks}

+
+ ))} +
+
+ +
+

Membres en attente de validation

+
+ {pendingMembers.map((member, index) => ( +
+

{member.name}

+
+ + +
+
+ ))} +
+
+
+
+ ); +} + +export default StatPage; diff --git a/src/pages/Stat/StatPage.module.css b/src/pages/Stat/StatPage.module.css new file mode 100644 index 0000000..ed49bbb --- /dev/null +++ b/src/pages/Stat/StatPage.module.css @@ -0,0 +1,119 @@ +.container { + display: flex; + flex-direction: row; + width: 100%; + padding: 20px; + box-sizing: border-box; + gap: 20px; +} +/* style a montrer a giovanni prcq il est + bo */ +/*.glassCard { + background: rgba(255, 255, 255, 0.2); + backdrop-filter: blur(10px); + border-radius: 10px; + padding: 15px; + box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); + border: 1px solid rgba(255, 255, 255, 0.3); +}*/ + +.block { + border-radius: 10px; + padding: 15px; + box-sizing: border-box; +} + +.leftBlock { + width: 40%; + display: flex; + flex-direction: column; + align-items: center; +} + +.participationHeader { + display: flex; + align-items: center; + margin-bottom: 20px; + width: 100%; +} + +.monthsDropdown { + margin-left: 10px; + padding: 5px; + border-radius: 5px; + border: 1px solid #ccc; +} + +.chartContainer { + width: 100%; + display: flex; + justify-content: center; +} + +.donutChart { + width: 150px; + height: 150px; +} + +.rightSection { + width: 60%; + display: flex; + flex-direction: column; + gap: 20px; +} + +.rightBlock { + width: 100%; +} + +.eventsContainer { + display: flex; + flex-direction: row; + gap: 10px; + margin-top: 15px; +} + +.eventCard { + flex: 1; + padding: 10px; + text-align: center; + padding-bottom:200px; +} + +.membersContainer { + display: flex; + flex-direction: column; + gap: 10px; + margin-top: 15px; +} + +.memberCard { + display: flex; + justify-content: space-between; + align-items: center; + padding: 10px; +} + +.buttonGroup { + display: flex; + gap: 10px; +} + +.validateButton { + background-color: #4CAF50; + color: white; + border: none; + padding: 5px 10px; + border-radius: 15px; + cursor: pointer; + width:200px; +} + +.rejectButton { + background-color: #f44336; + color: white; + border: none; + padding: 5px 10px; + border-radius: 15px; + cursor: pointer; + width:200px; +} diff --git a/src/router.js b/src/router.js index c3351c5..be0cf78 100644 --- a/src/router.js +++ b/src/router.js @@ -2,6 +2,7 @@ import { createBrowserRouter } from "react-router"; import Layout from "./layout.jsx"; import HomePage from "./pages/Home/HomePage"; import LoginPage from "./pages/Login/LoginPage"; +import StatPage from "./pages/Stat/StatPage"; const router = createBrowserRouter([ { @@ -15,6 +16,10 @@ const router = createBrowserRouter([ { path: "/login", Component: LoginPage, + }, + { + path: "/stat", + Component:StatPage, } ] } From 96061547a29538686cf61fc8b88fdcb7215ce515 Mon Sep 17 00:00:00 2001 From: p2405951 Date: Sun, 23 Nov 2025 19:14:08 +0100 Subject: [PATCH 02/31] add reponsive --- src/pages/Stat/StatPage.module.css | 49 ++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/src/pages/Stat/StatPage.module.css b/src/pages/Stat/StatPage.module.css index ed49bbb..37a83fc 100644 --- a/src/pages/Stat/StatPage.module.css +++ b/src/pages/Stat/StatPage.module.css @@ -117,3 +117,52 @@ cursor: pointer; width:200px; } + +@media screen and (max-width: 760px) { + .container { + flex-direction: column; + padding: 10px; + } + + .leftBlock { + width: 100%; + margin-bottom: 20px; + } + + .rightSection { + width: 100%; + } + + .eventsContainer { + flex-direction: column; + } + + .eventCard { + width: 100%; + } + + .donutChart { + width: 120px; + height: 120px; + } + + .memberCard { + flex-direction: column; + align-items: flex-start; + gap: 10px; + } + + .buttonGroup { + width: 100%; + justify-content: space-between; + } + + .validateButton, + .rejectButton { + flex: 1; + text-align: center; + padding: 8px; + } +} + + From 87f9df62ba1a460006039fe5386eb97063680f05 Mon Sep 17 00:00:00 2001 From: p2405951 Date: Mon, 24 Nov 2025 14:25:11 +0100 Subject: [PATCH 03/31] --allow-empty --- src/pages/Stat/StatPage.jsx | 4 ++-- src/pages/Stat/StatPage.module.css | 18 +++++++++++++++--- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/src/pages/Stat/StatPage.jsx b/src/pages/Stat/StatPage.jsx index c0e7794..c057769 100644 --- a/src/pages/Stat/StatPage.jsx +++ b/src/pages/Stat/StatPage.jsx @@ -3,7 +3,7 @@ import styles from "./StatPage.module.css"; function StatPage() { const [months, setMonths] = useState(3); - const participationRate = 90; + const participationRate = 77; // les event incomplets const incompleteEvents = [ @@ -58,7 +58,7 @@ function StatPage() { cy="50" r="40" fill="none" - stroke="#4CAF50" + stroke="#07f60fff" strokeWidth="20" strokeDasharray={`${participationRate} 100`} transform="rotate(-90 50 50)" diff --git a/src/pages/Stat/StatPage.module.css b/src/pages/Stat/StatPage.module.css index 37a83fc..2c9fbd9 100644 --- a/src/pages/Stat/StatPage.module.css +++ b/src/pages/Stat/StatPage.module.css @@ -64,6 +64,9 @@ .rightBlock { width: 100%; } +.rightBlock>h2{ + font-size:29px; +} .eventsContainer { display: flex; @@ -72,13 +75,16 @@ margin-top: 15px; } + .eventCard { flex: 1; padding: 10px; text-align: center; padding-bottom:200px; } - +.eventCard>h3{ + font-size: 24px; +} .membersContainer { display: flex; flex-direction: column; @@ -92,6 +98,11 @@ align-items: center; padding: 10px; } +.memberCard p{ + font-weight: bold; + font-size: 20px; +} + .buttonGroup { display: flex; @@ -99,7 +110,7 @@ } .validateButton { - background-color: #4CAF50; + background-color: #15ef1c; color: white; border: none; padding: 5px 10px; @@ -109,7 +120,7 @@ } .rejectButton { - background-color: #f44336; + background-color: #ff1100; color: white; border: none; padding: 5px 10px; @@ -150,6 +161,7 @@ flex-direction: column; align-items: flex-start; gap: 10px; + } .buttonGroup { From f9da3e10beb695edeec79882ff83c50c02d641bf Mon Sep 17 00:00:00 2001 From: p2405951 Date: Fri, 28 Nov 2025 11:50:05 +0100 Subject: [PATCH 04/31] amelioration graphique + responsive --- package-lock.json | 30 ++++++++ package.json | 10 +-- src/pages/Stat/StatPage.jsx | 107 +++++++++++++++++++---------- src/pages/Stat/StatPage.module.css | 68 ++++++++++-------- vite.config.js | 3 + 5 files changed, 150 insertions(+), 68 deletions(-) diff --git a/package-lock.json b/package-lock.json index 0591a36..2e4d992 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,7 +8,9 @@ "name": "sae-front", "version": "0.0.0", "dependencies": { + "chart.js": "^4.5.1", "react": "^19.1.1", + "react-chartjs-2": "^5.3.1", "react-dom": "^19.1.1", "react-router": "^7.9.4" }, @@ -1107,6 +1109,12 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, + "node_modules/@kurkle/color": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/@kurkle/color/-/color-0.3.4.tgz", + "integrity": "sha512-M5UknZPHRu3DEDWoipU6sE8PdkZ6Z/S+v4dD+Ke8IaNlpdSQah50lz1KtcFBa2vsdOnwbbnxJwVM4wty6udA5w==", + "license": "MIT" + }, "node_modules/@mdx-js/react": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/@mdx-js/react/-/react-3.1.1.tgz", @@ -2682,6 +2690,18 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, + "node_modules/chart.js": { + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/chart.js/-/chart.js-4.5.1.tgz", + "integrity": "sha512-GIjfiT9dbmHRiYi6Nl2yFCq7kkwdkp1W/lp2J99rX0yo9tgJGn3lKQATztIjb5tVtevcBtIdICNWqlq5+E8/Pw==", + "license": "MIT", + "dependencies": { + "@kurkle/color": "^0.3.0" + }, + "engines": { + "pnpm": ">=8" + } + }, "node_modules/check-error": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.1.tgz", @@ -4419,6 +4439,16 @@ "node": ">=0.10.0" } }, + "node_modules/react-chartjs-2": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/react-chartjs-2/-/react-chartjs-2-5.3.1.tgz", + "integrity": "sha512-h5IPXKg9EXpjoBzUfyWJvllMjG2mQ4EiuHQFhms/AjUm0XSZHhyRy2xVmLXHKrtcdrPO4mnGqRtYoD0vp95A0A==", + "license": "MIT", + "peerDependencies": { + "chart.js": "^4.1.1", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, "node_modules/react-docgen": { "version": "8.0.2", "resolved": "https://registry.npmjs.org/react-docgen/-/react-docgen-8.0.2.tgz", diff --git a/package.json b/package.json index d2aa97d..902a0fc 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,9 @@ "build-storybook": "storybook build" }, "dependencies": { + "chart.js": "^4.5.1", "react": "^19.1.1", + "react-chartjs-2": "^5.3.1", "react-dom": "^19.1.1", "react-router": "^7.9.4" }, @@ -26,17 +28,17 @@ "@types/react": "^19.1.16", "@types/react-dom": "^19.1.9", "@vitejs/plugin-react": "^5.0.4", + "@vitest/browser-playwright": "^4.0.8", + "@vitest/coverage-v8": "^4.0.8", "eslint": "^9.36.0", "eslint-plugin-react-hooks": "^5.2.0", "eslint-plugin-react-refresh": "^0.4.22", "eslint-plugin-storybook": "^10.0.6", "globals": "^16.4.0", + "playwright": "^1.56.1", "prop-types": "^15.8.1", "storybook": "^10.0.6", "vite": "^7.1.7", - "vitest": "^4.0.8", - "playwright": "^1.56.1", - "@vitest/browser-playwright": "^4.0.8", - "@vitest/coverage-v8": "^4.0.8" + "vitest": "^4.0.8" } } diff --git a/src/pages/Stat/StatPage.jsx b/src/pages/Stat/StatPage.jsx index c057769..cd75918 100644 --- a/src/pages/Stat/StatPage.jsx +++ b/src/pages/Stat/StatPage.jsx @@ -1,21 +1,27 @@ import React, { useState } from "react"; +import { Doughnut } from "react-chartjs-2"; +import { Chart, ArcElement } from "chart.js"; import styles from "./StatPage.module.css"; +import Button from "./../../components/ui/button/button"; + +// Enregistrer les éléments nécessaires +Chart.register(ArcElement); function StatPage() { const [months, setMonths] = useState(3); - const participationRate = 77; + + const [participationRate, setParticipationRate] = useState(89); - // les event incomplets const incompleteEvents = [ { title: "Événement A", tasks: "Préparation des flyers" }, { title: "Événement B", tasks: "Réservation de la salle" }, { title: "Événement C", tasks: "Communication sur les réseaux" }, ]; -/* c la liste des membres en attente*/ + const pendingMembers = [ - { name: "Alice Dupont" }, - { name: "Bob Martin" }, - { name: "Charlie Durand" }, + { name: "Antoine Ordonneau" }, + { name: "Giovanni Josserand" }, + { name: "Quentin T'Jampens" }, ]; const handleValidate = (name) => { @@ -26,11 +32,45 @@ function StatPage() { console.log(`Refuser ${name}`); }; + const chartData = { + labels: ["Progress", "Background"], + datasets: [ + { + data: [participationRate, 100 - participationRate], + backgroundColor: ["#1e60f9ff", "#ffffffff"], + borderWidth: 0, + weight:10, + cutout: "90%", + circumference: 360, + rotation: -90, + }, + ], + }; + + const chartOptions = { + responsive: true, + plugins: { + legend: { + display: false, + }, + tooltip: { + enabled: false, + }, + }, + animation: { + animateScale: true, + animateRotate: true, + }, + }; + return (
- +
+ + + +
+
- - - - +
+ +
{participationRate}% - - +
+
-

Événements incomplets

@@ -82,7 +116,6 @@ function StatPage() { ))}
-

Membres en attente de validation

@@ -90,18 +123,18 @@ function StatPage() {

{member.name}

- - +
))} diff --git a/src/pages/Stat/StatPage.module.css b/src/pages/Stat/StatPage.module.css index 2c9fbd9..666a610 100644 --- a/src/pages/Stat/StatPage.module.css +++ b/src/pages/Stat/StatPage.module.css @@ -27,6 +27,7 @@ display: flex; flex-direction: column; align-items: center; + height:fit-content; } .participationHeader { @@ -35,25 +36,53 @@ margin-bottom: 20px; width: 100%; } +.partiText{ + display: flex; + flex-direction: column; + width: 100%; +} +.participationHeader label{ + font-size:20px; + text-align: center; +} .monthsDropdown { - margin-left: 10px; - padding: 5px; + width:25%; border-radius: 5px; - border: 1px solid #ccc; + opacity: 1; + background-color: transparent; + border:none; } + .chartContainer { - width: 100%; - display: flex; - justify-content: center; + + max-width: 80%; + margin: 0 auto; + position: relative; } -.donutChart { - width: 150px; - height: 150px; + +.circularProgress { + width: 100%; + height: 100%; } +.progressBackground { + opacity: 0.3; +} + +.progressBar { + transition: stroke-dasharray 0.5s ease; + stroke-linecap: round; +} + +.progressText { + font-weight: bold; + font-family: Arial, sans-serif; +} + + .rightSection { width: 60%; display: flex; @@ -107,27 +136,11 @@ .buttonGroup { display: flex; gap: 10px; + justify-content: right; } -.validateButton { - background-color: #15ef1c; - color: white; - border: none; - padding: 5px 10px; - border-radius: 15px; - cursor: pointer; - width:200px; -} -.rejectButton { - background-color: #ff1100; - color: white; - border: none; - padding: 5px 10px; - border-radius: 15px; - cursor: pointer; - width:200px; -} + @media screen and (max-width: 760px) { .container { @@ -138,6 +151,7 @@ .leftBlock { width: 100%; margin-bottom: 20px; + height:fit-content; } .rightSection { diff --git a/vite.config.js b/vite.config.js index fbcb6d3..5a921d3 100644 --- a/vite.config.js +++ b/vite.config.js @@ -34,5 +34,8 @@ export default defineConfig({ setupFiles: ['.storybook/vitest.setup.js'] } }] + }, + server: { + host: true, } }); \ No newline at end of file From 3816d3a296c1529cef76e3dc0a13b70b7a9bf3e6 Mon Sep 17 00:00:00 2001 From: T'JAMPENS QUENTIN p2406187 Date: Sat, 29 Nov 2025 01:17:43 +0100 Subject: [PATCH 05/31] Add .env api url --- .env.exemple | 1 + .gitignore | 2 ++ src/utils/getUser.js | 2 +- src/utils/getXSRF.js | 2 +- src/utils/login.js | 2 +- src/utils/register.js | 2 +- 6 files changed, 7 insertions(+), 4 deletions(-) create mode 100644 .env.exemple diff --git a/.env.exemple b/.env.exemple new file mode 100644 index 0000000..3452b5c --- /dev/null +++ b/.env.exemple @@ -0,0 +1 @@ +VITE_API_URL= \ No newline at end of file diff --git a/.gitignore b/.gitignore index f52343a..bd7187d 100644 --- a/.gitignore +++ b/.gitignore @@ -25,3 +25,5 @@ dist-ssr *storybook.log storybook-static + +.env \ No newline at end of file diff --git a/src/utils/getUser.js b/src/utils/getUser.js index 6826525..24297ca 100644 --- a/src/utils/getUser.js +++ b/src/utils/getUser.js @@ -1,6 +1,6 @@ export default async function getUser() { try { - const res = await fetch('http://localhost:8000/api/me', { + const res = await fetch(`http://${import.meta.env.VITE_API_URL}/api/users/me`, { method: 'GET', credentials: 'include', headers: { diff --git a/src/utils/getXSRF.js b/src/utils/getXSRF.js index 1bed25f..0c78e40 100644 --- a/src/utils/getXSRF.js +++ b/src/utils/getXSRF.js @@ -1,5 +1,5 @@ export default async function getXSRFToken() { - const response = await fetch('http://localhost:8000/sanctum/csrf-cookie', { + const response = await fetch(`http://${import.meta.env.VITE_API_URL}/sanctum/csrf-cookie`, { method: 'GET', credentials: 'include' }); diff --git a/src/utils/login.js b/src/utils/login.js index a08151b..161268c 100644 --- a/src/utils/login.js +++ b/src/utils/login.js @@ -4,7 +4,7 @@ export default async function login(email, password) { const csrfToken = await getXSRFToken(); try { - const response = await fetch('http://localhost:8000/api/users/login', { + const response = await fetch(`http://${import.meta.env.VITE_API_URL}/api/users/login`, { method: 'POST', credentials: 'include', headers: { diff --git a/src/utils/register.js b/src/utils/register.js index 1612bf8..313df77 100644 --- a/src/utils/register.js +++ b/src/utils/register.js @@ -4,7 +4,7 @@ export default async function register(email, password, name, lastname) { const csrfToken = await getXSRFToken(); try { - const response = await fetch('http://localhost:8000/api/users/register', { + const response = await fetch(`http://${import.meta.env.VITE_API_URL}/api/users/register`, { method: 'POST', credentials: 'include', headers: { From 66696251c7c4d560bbcf89eca1af62d75f2bb0dd Mon Sep 17 00:00:00 2001 From: T'JAMPENS QUENTIN p2406187 Date: Sun, 30 Nov 2025 17:31:19 +0100 Subject: [PATCH 06/31] Create modal component --- src/components/ui/modal/modal.jsx | 23 ++++++++++++++++ src/components/ui/modal/modal.module.css | 35 ++++++++++++++++++++++++ 2 files changed, 58 insertions(+) create mode 100644 src/components/ui/modal/modal.jsx create mode 100644 src/components/ui/modal/modal.module.css diff --git a/src/components/ui/modal/modal.jsx b/src/components/ui/modal/modal.jsx new file mode 100644 index 0000000..66ae46b --- /dev/null +++ b/src/components/ui/modal/modal.jsx @@ -0,0 +1,23 @@ +import styles from "./modal.module.css" +import Button from "../button/button.jsx"; + +const Modal = ({ open, onClose, children, title }) => { + + if(!open) return null; + + return
+ +
+ + {title &&

{title}

} + + {children} + +
+ +
+ +
+} + +export default Modal; \ No newline at end of file diff --git a/src/components/ui/modal/modal.module.css b/src/components/ui/modal/modal.module.css new file mode 100644 index 0000000..76b108a --- /dev/null +++ b/src/components/ui/modal/modal.module.css @@ -0,0 +1,35 @@ +.overlay { + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + background-color: rgba(0, 0, 0, 0.25); + display: flex; + justify-content: center; + align-items: center; + z-index: 1000; +} + +.modal { + padding: 20px 20px 20px 20px; + border-radius: 8px; + min-width: 300px; + max-width: 70%; + position: relative; + box-shadow: 0 4px 15px rgba(0,0,0,0.2); + width: fit-content; + border: 1px solid rgba(200, 200, 200, 0.3); + background: rgba(255, 255, 255, 0.5); + backdrop-filter: blur(10px); + -webkit-backdrop-filter: blur(10px); + color: #000; + outline: none; +} + +.modalFooter { + display: flex; + align-items: center; + justify-content: center; + margin-top: 20px; +} From c2d64ed34103ff58dd31e997c84851e68bbfb57f Mon Sep 17 00:00:00 2001 From: T'JAMPENS QUENTIN p2406187 Date: Sun, 30 Nov 2025 17:47:10 +0100 Subject: [PATCH 07/31] Create modal component stories --- src/stories/Modal.stories.jsx | 49 +++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 src/stories/Modal.stories.jsx diff --git a/src/stories/Modal.stories.jsx b/src/stories/Modal.stories.jsx new file mode 100644 index 0000000..1ece2ae --- /dev/null +++ b/src/stories/Modal.stories.jsx @@ -0,0 +1,49 @@ +import Modal from "../components/ui/modal/modal.jsx"; +import Button from "../components/ui/button/button.jsx"; +import { useState } from "react"; + +export default { + title: 'UI/Modal', + component: Modal, + parameters: { + layout: 'centered', + }, + tags: ['autodocs'], + argTypes: { + open: { + control: 'boolean', + description: 'Variable qui gère si la modal est ouverte ou fermée.', + }, + children: { + control: Object, + description: 'Contenu de la modal.', + }, + title: { + control: 'text', + description: 'Titre de la modal', + }, + onClose: { + action: 'changed', + description: 'Fonction appelée pour fermer la modal.', + }, + }, +}; + +const Template = (args) => { + const [isOpen, setIsOpen] = useState(false); + + return ( +
+ + setIsOpen(false)}> + {args.children} + +
+ ); +}; + +export const Default = Template.bind({}); +Default.args = { + title: "Hello", + children:

Lorem Ipsum...

, +}; From 98518be81338e02b8f678c724a7798c3968d52e0 Mon Sep 17 00:00:00 2001 From: T'JAMPENS QUENTIN p2406187 Date: Tue, 2 Dec 2025 17:40:52 +0100 Subject: [PATCH 08/31] Link backend to profile page --- src/components/Header/Header.jsx | 2 +- src/components/Task/Task.jsx | 30 ++++++++ src/components/Task/Task.module.css | 22 ++++++ src/index.css | 1 - src/pages/Profile/ProfilePage.jsx | 98 +++++------------------- src/pages/Profile/ProfilePage.module.css | 9 +-- src/utils/date/formatDate.js | 9 +++ src/utils/event/getEventById.js | 23 ++++++ 8 files changed, 104 insertions(+), 90 deletions(-) create mode 100644 src/components/Task/Task.jsx create mode 100644 src/components/Task/Task.module.css create mode 100644 src/utils/date/formatDate.js create mode 100644 src/utils/event/getEventById.js diff --git a/src/components/Header/Header.jsx b/src/components/Header/Header.jsx index 2a8ea25..177cf3d 100644 --- a/src/components/Header/Header.jsx +++ b/src/components/Header/Header.jsx @@ -70,7 +70,7 @@ function Header() { {unreadNotification && } - + diff --git a/src/components/Task/Task.jsx b/src/components/Task/Task.jsx new file mode 100644 index 0000000..bcade11 --- /dev/null +++ b/src/components/Task/Task.jsx @@ -0,0 +1,30 @@ +import React, {useEffect, useState} from "react"; +import getEventById from "../../utils/event/getEventById.js"; +import styles from "./Task.module.css"; +import formatDate from "../../utils/date/formatDate.js"; + +const Task = ({ task }) => { + const [event, setEvent] = useState(null); + + useEffect(() => { + (async () => { + const e = await getEventById(task.id); + console.log(e); + setEvent(e); + }) () + }, []) + + return ( +
+
+
+

{event && event.name} - {task.name}

+

{task.description}

+

{formatDate(task.start)}

+
+
+
+ ); +} + +export default Task; \ No newline at end of file diff --git a/src/components/Task/Task.module.css b/src/components/Task/Task.module.css new file mode 100644 index 0000000..052d0a3 --- /dev/null +++ b/src/components/Task/Task.module.css @@ -0,0 +1,22 @@ +.task { + width: 100%; + padding: 12px; + margin-bottom: 10px; + border-radius: 8px; +} + +.content { + display: flex; + justify-content: space-between; + flex-direction: column; +} + +.desc { + font-size: 0.8rem; + color: #666; + margin: 0 0 0 0; +} + +.date { + font-size: 0.8rem; +} \ No newline at end of file diff --git a/src/index.css b/src/index.css index f7d7591..8f76726 100644 --- a/src/index.css +++ b/src/index.css @@ -46,7 +46,6 @@ body { .glassCard { width: 100%; - padding: 10px; height: fit-content; background: rgba(255, 255, 255, 0.65); backdrop-filter: blur(3px); diff --git a/src/pages/Profile/ProfilePage.jsx b/src/pages/Profile/ProfilePage.jsx index c38328f..99f953d 100644 --- a/src/pages/Profile/ProfilePage.jsx +++ b/src/pages/Profile/ProfilePage.jsx @@ -1,106 +1,44 @@ -import React, { useState } from "react"; +import React, { useContext } from "react"; import styles from "./ProfilePage.module.css"; - -function Event({ title,date, tasks }) { - const [isExpanded, setIsExpanded] = useState(false); - - const toggleExpand = () => { - setIsExpanded(!isExpanded); - }; - - return ( -
-
-
-

{title}

-

{date}

-
- -
-
    - {tasks.map((task, index) => ( -
  • -- {task}
  • - ))} -
-
- ); -} - +import { AuthContext } from "../../contexts/auth/AuthContext.js"; +import formatDate from "../../utils/date/formatDate.js"; +import Task from "../../components/Task/Task"; function ProfilePage() { + + const { user } = useContext(AuthContext); + return (
Photo de profil
-

LEBLOND Malo

+

{user.name} {user.lastname}

-

Role : Président

-

Membre depuis : 2019

+

Role : {user.role}

+

Membre depuis : {formatDate(user.created_at)}

-

Mail : mailpro@gmail.com

-

Téléphone : 08 67 87 32 21

+

Mail : {user.email}

+

Téléphone : {user.phone}

+

Vos Événements :

- - - - - - - + {user.tasks && user.tasks.map((task, index) => ( + + ))}
+
diff --git a/src/pages/Profile/ProfilePage.module.css b/src/pages/Profile/ProfilePage.module.css index 54569c6..1c7b177 100644 --- a/src/pages/Profile/ProfilePage.module.css +++ b/src/pages/Profile/ProfilePage.module.css @@ -51,13 +51,6 @@ border-radius: 5px; } -.event { - width: 100%; - padding: 12px; - margin-bottom: 10px; - border-radius: 8px; -} - .eventTasks { max-height: 0; overflow: hidden; @@ -78,7 +71,7 @@ .profilePicture{ width:90%; } -/* Tablette (768px et plus) */ + @media screen and (min-width: 768px) { .contentWrapper { flex-direction: row; diff --git a/src/utils/date/formatDate.js b/src/utils/date/formatDate.js new file mode 100644 index 0000000..3fd1371 --- /dev/null +++ b/src/utils/date/formatDate.js @@ -0,0 +1,9 @@ +export default function formatDate(d) { + const date = new Date(d); + + const jj = String(date.getUTCDate()).padStart(2, '0'); + const mm = String(date.getUTCMonth() + 1).padStart(2, '0'); + const aaaa = date.getUTCFullYear(); + + return `${jj}/${mm}/${aaaa}`; +} \ No newline at end of file diff --git a/src/utils/event/getEventById.js b/src/utils/event/getEventById.js new file mode 100644 index 0000000..8d09b78 --- /dev/null +++ b/src/utils/event/getEventById.js @@ -0,0 +1,23 @@ +export default async function GetEventById(id) { + + try { + const res = await fetch(`http://${import.meta.env.VITE_API_URL}/api/events/${id}`, { + method: 'GET', + credentials: 'include', + headers: { + 'Accept': 'application/json' + } + }); + + if (!res.ok) { + throw new Error(`Erreur serveur : ${res.status}`); + } + + const data = await res.json(); + return data; + } catch (err) { + console.error('Erreur :', err); + return null; + } + +} \ No newline at end of file From 6f2465a4524e68124996b69345193c5bb95622d2 Mon Sep 17 00:00:00 2001 From: T'JAMPENS QUENTIN p2406187 Date: Thu, 4 Dec 2025 10:00:37 +0100 Subject: [PATCH 09/31] update profile btn --- pnpm-lock.yaml | 30 ++++++++++++++++++++++++ public/icons/pen.svg | 4 ++++ src/pages/Profile/ProfilePage.jsx | 8 +++++-- src/pages/Profile/ProfilePage.module.css | 5 ++++ 4 files changed, 45 insertions(+), 2 deletions(-) create mode 100644 public/icons/pen.svg diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 2f9b236..c6cc5fd 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -8,9 +8,15 @@ importers: .: dependencies: + chart.js: + specifier: ^4.5.1 + version: 4.5.1 react: specifier: ^19.1.1 version: 19.2.0 + react-chartjs-2: + specifier: ^5.3.1 + version: 5.3.1(chart.js@4.5.1)(react@19.2.0) react-dom: specifier: ^19.1.1 version: 19.2.0(react@19.2.0) @@ -436,6 +442,9 @@ packages: '@jridgewell/trace-mapping@0.3.31': resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} + '@kurkle/color@0.3.4': + resolution: {integrity: sha512-M5UknZPHRu3DEDWoipU6sE8PdkZ6Z/S+v4dD+Ke8IaNlpdSQah50lz1KtcFBa2vsdOnwbbnxJwVM4wty6udA5w==} + '@mdx-js/react@3.1.1': resolution: {integrity: sha512-f++rKLQgUVYDAtECQ6fn/is15GkEH9+nZPM3MS0RcxVqoTfawHvDlSCH7JbMhAM6uJ32v3eXLvLmLvjGu7PTQw==} peerDependencies: @@ -949,6 +958,10 @@ packages: resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} engines: {node: '>=10'} + chart.js@4.5.1: + resolution: {integrity: sha512-GIjfiT9dbmHRiYi6Nl2yFCq7kkwdkp1W/lp2J99rX0yo9tgJGn3lKQATztIjb5tVtevcBtIdICNWqlq5+E8/Pw==} + engines: {pnpm: '>=8'} + check-error@2.1.1: resolution: {integrity: sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==} engines: {node: '>= 16'} @@ -1510,6 +1523,12 @@ packages: queue-microtask@1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + react-chartjs-2@5.3.1: + resolution: {integrity: sha512-h5IPXKg9EXpjoBzUfyWJvllMjG2mQ4EiuHQFhms/AjUm0XSZHhyRy2xVmLXHKrtcdrPO4mnGqRtYoD0vp95A0A==} + peerDependencies: + chart.js: ^4.1.1 + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + react-docgen-typescript@2.4.0: resolution: {integrity: sha512-ZtAp5XTO5HRzQctjPU0ybY0RRCQO19X/8fxn3w7y2VVTUbGHDKULPTL4ky3vB05euSgG5NpALhEhDPvQ56wvXg==} peerDependencies: @@ -2186,6 +2205,8 @@ snapshots: '@jridgewell/resolve-uri': 3.1.2 '@jridgewell/sourcemap-codec': 1.5.5 + '@kurkle/color@0.3.4': {} + '@mdx-js/react@3.1.1(@types/react@19.2.2)(react@19.2.0)': dependencies: '@types/mdx': 2.0.13 @@ -2738,6 +2759,10 @@ snapshots: ansi-styles: 4.3.0 supports-color: 7.2.0 + chart.js@4.5.1: + dependencies: + '@kurkle/color': 0.3.4 + check-error@2.1.1: {} chromatic@12.2.0: {} @@ -3255,6 +3280,11 @@ snapshots: queue-microtask@1.2.3: {} + react-chartjs-2@5.3.1(chart.js@4.5.1)(react@19.2.0): + dependencies: + chart.js: 4.5.1 + react: 19.2.0 + react-docgen-typescript@2.4.0(typescript@5.9.3): dependencies: typescript: 5.9.3 diff --git a/public/icons/pen.svg b/public/icons/pen.svg new file mode 100644 index 0000000..b13361f --- /dev/null +++ b/public/icons/pen.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/src/pages/Profile/ProfilePage.jsx b/src/pages/Profile/ProfilePage.jsx index 99f953d..808df57 100644 --- a/src/pages/Profile/ProfilePage.jsx +++ b/src/pages/Profile/ProfilePage.jsx @@ -3,10 +3,13 @@ import styles from "./ProfilePage.module.css"; import { AuthContext } from "../../contexts/auth/AuthContext.js"; import formatDate from "../../utils/date/formatDate.js"; import Task from "../../components/Task/Task"; +import Button from "../../components/ui/button/button.jsx"; +import { useNavigate } from "react-router"; function ProfilePage() { const { user } = useContext(AuthContext); + const navigate = useNavigate(); return (
@@ -30,7 +33,9 @@ function ProfilePage() {

Mail : {user.email}

Téléphone : {user.phone}

- +

Vos Événements :

@@ -38,7 +43,6 @@ function ProfilePage() { ))}
-
diff --git a/src/pages/Profile/ProfilePage.module.css b/src/pages/Profile/ProfilePage.module.css index 1c7b177..fb51bd6 100644 --- a/src/pages/Profile/ProfilePage.module.css +++ b/src/pages/Profile/ProfilePage.module.css @@ -117,6 +117,11 @@ } +.modifyIcon { + height:50px; + width:50px; +} + /* Desktop (1024px et plus) */ @media screen and (min-width: 1024px) { .container { From ad58a36707246a8bad2ab6dcf2d862f0eb60253d Mon Sep 17 00:00:00 2001 From: T'JAMPENS QUENTIN p2406187 Date: Thu, 4 Dec 2025 11:21:35 +0100 Subject: [PATCH 10/31] Add vitest --- package.json | 3 +- src/utils/date/formatDate.test.js | 9 ++++ vite.config.js | 69 +++++++++++++++++-------------- 3 files changed, 50 insertions(+), 31 deletions(-) create mode 100644 src/utils/date/formatDate.test.js diff --git a/package.json b/package.json index 902a0fc..c86a179 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,8 @@ "lint": "eslint .", "preview": "vite preview", "storybook": "storybook dev -p 6006", - "build-storybook": "storybook build" + "build-storybook": "storybook build", + "test": "vitest" }, "dependencies": { "chart.js": "^4.5.1", diff --git a/src/utils/date/formatDate.test.js b/src/utils/date/formatDate.test.js new file mode 100644 index 0000000..97179dc --- /dev/null +++ b/src/utils/date/formatDate.test.js @@ -0,0 +1,9 @@ +import { expect, test } from 'vitest'; +import formatDate from './formatDate'; + +const date = "2025-11-28T11:26:45.000000Z" +const res = "28/11/2025" + +test("Format Date", () => { + expect(formatDate(date)).toBe(res); +}) \ No newline at end of file diff --git a/vite.config.js b/vite.config.js index 59b0166..3277a15 100644 --- a/vite.config.js +++ b/vite.config.js @@ -1,39 +1,48 @@ +// vite.config.js /// -import { defineConfig } from 'vite'; -import react from '@vitejs/plugin-react'; +import { defineConfig } from 'vite' +import react from '@vitejs/plugin-react' +import path from 'node:path' +import { fileURLToPath } from 'node:url' +import { storybookTest } from '@storybook/addon-vitest/vitest-plugin' +import { playwright } from '@vitest/browser-playwright' -// https://vite.dev/config/ -import path from 'node:path'; -import { fileURLToPath } from 'node:url'; -import { storybookTest } from '@storybook/addon-vitest/vitest-plugin'; -import { playwright } from '@vitest/browser-playwright'; const dirname = typeof __dirname !== 'undefined' ? __dirname : path.dirname(fileURLToPath(import.meta.url)); -// More info at: https://storybook.js.org/docs/next/writing-tests/integrations/vitest-addon export default defineConfig({ plugins: [react()], base: '/', test: { - projects: [{ - extends: true, - plugins: [ - // The plugin will run tests for the stories defined in your Storybook config - // See options at: https://storybook.js.org/docs/next/writing-tests/integrations/vitest-addon#storybooktest - storybookTest({ - configDir: path.join(dirname, '.storybook') - })], - test: { - name: 'storybook', - browser: { - enabled: true, - headless: true, - provider: playwright({}), - instances: [{ - browser: 'chromium' - }] + projects: [ + { + extends: true, + plugins: [ + storybookTest({ + configDir: path.join(dirname, '.storybook'), + }), + ], + test: { + name: 'storybook', + browser: { + enabled: true, + headless: true, + provider: playwright({}), + instances: [{ browser: 'chromium' }], + }, + setupFiles: ['.storybook/vitest.setup.js'], }, - setupFiles: ['.storybook/vitest.setup.js'] - } - }] - } -}); \ No newline at end of file + }, + { + test: { + name: 'unit', + include: [ + 'src/**/*.test.js', + 'src/**/*.test.ts', + 'utils/**/*.test.js', + ], + environment: 'node', + }, + }, + ], + }, +}) From 22065fbd16b7cde0cfc139aacaf81d6aa54c3230 Mon Sep 17 00:00:00 2001 From: T'JAMPENS QUENTIN p2406187 Date: Thu, 4 Dec 2025 18:18:31 +0100 Subject: [PATCH 11/31] Add logout btn --- src/contexts/auth/authProvider.jsx | 3 ++- src/index.css | 1 - src/pages/Profile/ProfilePage.jsx | 11 ++++++++-- src/pages/Profile/ProfilePage.module.css | 12 +++++++--- src/utils/auth/logout.js | 28 ++++++++++++++++++++++++ 5 files changed, 48 insertions(+), 7 deletions(-) create mode 100644 src/utils/auth/logout.js diff --git a/src/contexts/auth/authProvider.jsx b/src/contexts/auth/authProvider.jsx index 7151a96..009ec58 100644 --- a/src/contexts/auth/authProvider.jsx +++ b/src/contexts/auth/authProvider.jsx @@ -2,6 +2,7 @@ import { useState, useEffect } from "react"; import loginFunction from "../../utils/login.js"; import getUser from "../../utils/getUser.js"; import { AuthContext } from "./AuthContext"; +import logoutFunction from "../../utils/auth/logout.js" export function AuthProvider({ children }) { @@ -25,7 +26,7 @@ export function AuthProvider({ children }) { }; const logout = async () => { - // TODO: Appeller fonction logout + await logoutFunction(); setUser(null); }; diff --git a/src/index.css b/src/index.css index 8f76726..71532f3 100644 --- a/src/index.css +++ b/src/index.css @@ -3,7 +3,6 @@ padding: 0; width: 100%; box-sizing: border-box; - overflow-x: hidden; } :root { diff --git a/src/pages/Profile/ProfilePage.jsx b/src/pages/Profile/ProfilePage.jsx index 808df57..033ea4b 100644 --- a/src/pages/Profile/ProfilePage.jsx +++ b/src/pages/Profile/ProfilePage.jsx @@ -8,9 +8,13 @@ import { useNavigate } from "react-router"; function ProfilePage() { - const { user } = useContext(AuthContext); + const { user, logout } = useContext(AuthContext); const navigate = useNavigate(); + const handleLogout = () => { + logout(); + } + return (
@@ -23,7 +27,10 @@ function ProfilePage() { />
-

{user.name} {user.lastname}

+
+

{user.name} {user.lastname}

+ +

Role : {user.role}

diff --git a/src/pages/Profile/ProfilePage.module.css b/src/pages/Profile/ProfilePage.module.css index fb51bd6..438156d 100644 --- a/src/pages/Profile/ProfilePage.module.css +++ b/src/pages/Profile/ProfilePage.module.css @@ -66,7 +66,7 @@ } .description h2{ font-size:30px; - margin-bottom: 2%; + } .profilePicture{ width:90%; @@ -105,7 +105,6 @@ } .description h2{ font-size:30px; - margin-bottom: 2%; } .profilePicture{ width:90%; @@ -122,6 +121,14 @@ width:50px; } +.headerProfile { + display: flex; + flex-direction: row; + justify-content: space-between; + align-items: center; + margin-bottom: 20px; +} + /* Desktop (1024px et plus) */ @media screen and (min-width: 1024px) { .container { @@ -151,6 +158,5 @@ } .description h2{ font-size:30px; - margin-bottom: 2%; } } diff --git a/src/utils/auth/logout.js b/src/utils/auth/logout.js new file mode 100644 index 0000000..fa34b2f --- /dev/null +++ b/src/utils/auth/logout.js @@ -0,0 +1,28 @@ +import getXSRFToken from "../getXSRF.js"; + +export default async function logout() { + + const csrfToken = await getXSRFToken(); + + try { + const response = await fetch(`http://${import.meta.env.VITE_API_URL}/api/users/logout`, { + method: 'POST', + credentials: 'include', + headers: { + 'Content-Type': 'application/json', + 'Accept': 'application/json', + 'X-XSRF-TOKEN': csrfToken + }, + }); + + console.log('Code HTTP :', response.status); + + if (!response.ok) { + throw new Error(`Erreur HTTP ${response.status}`); + } + + return { status: response.status }; + } catch (error) { + return error; + } +} From ea49ee1722de8e290c86929a505a05662eb190d9 Mon Sep 17 00:00:00 2001 From: T'JAMPENS QUENTIN p2406187 Date: Thu, 4 Dec 2025 18:18:47 +0100 Subject: [PATCH 12/31] Remove console.log --- src/components/Task/Task.jsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/components/Task/Task.jsx b/src/components/Task/Task.jsx index bcade11..740aeda 100644 --- a/src/components/Task/Task.jsx +++ b/src/components/Task/Task.jsx @@ -9,7 +9,6 @@ const Task = ({ task }) => { useEffect(() => { (async () => { const e = await getEventById(task.id); - console.log(e); setEvent(e); }) () }, []) From ec2b798839217c7016d8fca242b28470ff19a490 Mon Sep 17 00:00:00 2001 From: T'JAMPENS QUENTIN p2406187 Date: Thu, 4 Dec 2025 18:19:05 +0100 Subject: [PATCH 13/31] Stop calling loadNotification --- src/components/Header/Header.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/Header/Header.jsx b/src/components/Header/Header.jsx index 177cf3d..14043a7 100644 --- a/src/components/Header/Header.jsx +++ b/src/components/Header/Header.jsx @@ -18,7 +18,7 @@ function Header() { setNotifications(notifData || []); } - loadNotifications(); + //loadNotifications(); const handleClickOutside = (event) => { if ( notificationRef.current && From 89d2af34b95e7768358c88e07362ee4618b32880 Mon Sep 17 00:00:00 2001 From: T'JAMPENS QUENTIN p2406187 Date: Thu, 4 Dec 2025 18:30:46 +0100 Subject: [PATCH 14/31] Fix UI --- src/components/loginform/loginForm.jsx | 2 +- src/components/loginform/loginForm.module.css | 4 ++++ src/pages/Login/LoginPage.jsx | 17 ++++++++--------- src/pages/Login/LoginPage.module.css | 19 +++++++++++++------ src/pages/Register/RegisterPage.jsx | 4 ++-- src/pages/Register/RegisterPage.module.css | 14 ++++++++++++++ 6 files changed, 42 insertions(+), 18 deletions(-) diff --git a/src/components/loginform/loginForm.jsx b/src/components/loginform/loginForm.jsx index edc6c55..218201d 100644 --- a/src/components/loginform/loginForm.jsx +++ b/src/components/loginform/loginForm.jsx @@ -24,7 +24,7 @@ function LoginForm({ className }) { }; return ( -
+
- -
- -
- - + return ( + +
+

Connexion

+ +
+
+ ); } export default LoginPage; - - diff --git a/src/pages/Login/LoginPage.module.css b/src/pages/Login/LoginPage.module.css index fd5d61d..69e4f8c 100644 --- a/src/pages/Login/LoginPage.module.css +++ b/src/pages/Login/LoginPage.module.css @@ -1,16 +1,23 @@ .container { - position: relative; + position: absolute; z-index: 2; display: flex; + flex-direction: column; width: 600px; - overflow: hidden; max-height: 80%; justify-content: center; align-items: center; padding: 20px; - border-radius:12px; - margin-left: 33.3%; + border-radius: 12px; + left: 50%; + top: 50%; + transform: translate(-50%, -50%); } - - +.title { + font-size: 36px; + color: white; + text-align: center; + margin-bottom: 20px; + text-shadow: 0 2px 8px rgba(0,0,0,0.3); +} diff --git a/src/pages/Register/RegisterPage.jsx b/src/pages/Register/RegisterPage.jsx index 489858d..c2e47ab 100644 --- a/src/pages/Register/RegisterPage.jsx +++ b/src/pages/Register/RegisterPage.jsx @@ -30,9 +30,9 @@ function RegisterPage() {
-
+

Créer un compte

-

Créer un compte

+
Date: Fri, 5 Dec 2025 14:34:33 +0100 Subject: [PATCH 15/31] get database users --- src/pages/Volunteers/VolunteerCard.jsx | 67 +++++++++++++++ src/pages/Volunteers/VolunteersPage.jsx | 109 +++--------------------- src/utils/users/getAllUsers.js | 21 +++++ src/utils/users/getUserById.js | 20 +++++ 4 files changed, 121 insertions(+), 96 deletions(-) create mode 100644 src/pages/Volunteers/VolunteerCard.jsx create mode 100644 src/utils/users/getAllUsers.js create mode 100644 src/utils/users/getUserById.js diff --git a/src/pages/Volunteers/VolunteerCard.jsx b/src/pages/Volunteers/VolunteerCard.jsx new file mode 100644 index 0000000..c402971 --- /dev/null +++ b/src/pages/Volunteers/VolunteerCard.jsx @@ -0,0 +1,67 @@ +import React, {useEffect, useState} from "react"; +import styles from "./VolunteersPage.module.css"; +import getUserById from "../../utils/users/getUserById.js"; +import formatDate from "../../utils/date/formatDate.js"; + +export default function VolunteerCard({ id }) { + + const [isExpanded, setIsExpanded] = useState(false); + const [user, setUser] = useState({}); + + const toggleExpand = () => { + setIsExpanded(!isExpanded); + }; + + useEffect(() => { + (async () => { + const data = await getUserById(id); + setUser(data); + }) () + }, []); + + return ( +
+
+ {!isExpanded ? ( +
+

{user?.name}

+

Rôle : {user?.role}

+

Membre depuis : {user?.created_at && formatDate(user.created_at)}

+
+ ) : ( +
+
+ {`profile +
+
+
+

{user?.name}

+

Rôle : {user?.role}

+

Membre depuis : {user?.created_at && formatDate(user.created_at)}

+
+
+

Email : {user?.email}

+ + {user?.phone && ( +

Téléphone : {user.phone}

+ )} +
+
+
+ )} + + {isExpanded && ( +
+ VOIR PLUS +
+ )} +
+
+ ); + +} \ No newline at end of file diff --git a/src/pages/Volunteers/VolunteersPage.jsx b/src/pages/Volunteers/VolunteersPage.jsx index 782f2a3..0fa3d2c 100644 --- a/src/pages/Volunteers/VolunteersPage.jsx +++ b/src/pages/Volunteers/VolunteersPage.jsx @@ -1,106 +1,23 @@ - -import React, { useState } from "react"; +import { useState, useEffect } from "react"; import styles from "./VolunteersPage.module.css"; +import VolunteerCard from "./VolunteerCard.jsx"; +import getAllUser from "../../utils/users/getAllUsers.js"; -function Volunteer({ name, role, since, email, phone, photo }) { - const [isExpanded, setIsExpanded] = useState(false); - - const toggleExpand = () => { - setIsExpanded(!isExpanded); - }; - - return ( -
-
- {!isExpanded ? ( -
-

{name}

-

Rôle : {role}

-

Membre depuis : {since}

-
- ) : ( -
-
- {`${name}'s -
-
-
-

{name}

-

Rôle : {role}

-

Membre depuis : {since}

-
-
-

Email : {email}

-

Téléphone : {phone}

-
-
-
- )} - - {isExpanded && ( -
- VOIR PLUS -
- )} -
-
- ); -} function VolunteerPage() { - const volunteers = [ - { - name: "LEBLOND Malo", - role: "Président", - since: "2019", - email: "malo.leblond@example.com", - phone: "08 67 87 32 21", - photo: "../src/assets/react.svg", - }, - { - name: "DUPONT Jean", - role: "Bénévole", - since: "2020", - email: "jean.dupont@example.com", - phone: "06 12 34 56 78", - photo: "../src/assets/react.svg", - }, - { - name: "MARTIN Sophie", - role: "Bénévole", - since: "2021", - email: "sophie.martin@example.com", - phone: "06 87 65 43 21", - photo: "../src/assets/react.svg", - }, - { - name: "MARTIN Sophie", - role: "Bénévole", - since: "2021", - email: "sophie.martin@example.com", - phone: "06 87 65 43 21", - photo: "../src/assets/react.svg", - }, - ]; + + const [users, setUsers] = useState([]); + + useEffect(() => { + (async () => { + const data = await getAllUser(); + setUsers(data); + }) () + }, []) return (
- {volunteers.map((volunteer, index) => ( - - ))} + {users.map((user, index) => )}
); } diff --git a/src/utils/users/getAllUsers.js b/src/utils/users/getAllUsers.js new file mode 100644 index 0000000..c9c383e --- /dev/null +++ b/src/utils/users/getAllUsers.js @@ -0,0 +1,21 @@ +export default async function getAllUser() { + try { + const res = await fetch(`http://${import.meta.env.VITE_API_URL}/api/users`, { + method: 'GET', + credentials: 'include', + headers: { + 'Accept': 'application/json' + } + }); + + if (!res.ok) { + throw new Error(`Erreur serveur : ${res.status}`); + } + + const data = await res.json(); + return data; + } catch (err) { + console.error('Erreur :', err); + return null; + } +} diff --git a/src/utils/users/getUserById.js b/src/utils/users/getUserById.js new file mode 100644 index 0000000..59af94a --- /dev/null +++ b/src/utils/users/getUserById.js @@ -0,0 +1,20 @@ +export default async function getUserById (id) { + try { + const res = await fetch(`http://${import.meta.env.VITE_API_URL}/api/users/${id}`, { + method: 'GET', + credentials: 'include', + headers: { + 'Accept': 'application/json' + } + }); + + if (!res.ok) { + throw new Error(`Erreur serveur : ${res.status}`); + } + + return await res.json(); + } catch (err) { + console.error('Erreur :', err); + return null; + } +} \ No newline at end of file From 80f6408f74066e6270e34dfc7e3e8654a916dd9f Mon Sep 17 00:00:00 2001 From: T'JAMPENS QUENTIN p2406187 Date: Fri, 5 Dec 2025 14:58:25 +0100 Subject: [PATCH 16/31] fix ui --- src/pages/Volunteers/VolunteerCard.jsx | 76 ++++---- .../Volunteers/VolunteersPage.module.css | 170 ++++++++---------- 2 files changed, 125 insertions(+), 121 deletions(-) diff --git a/src/pages/Volunteers/VolunteerCard.jsx b/src/pages/Volunteers/VolunteerCard.jsx index c402971..0f5437c 100644 --- a/src/pages/Volunteers/VolunteerCard.jsx +++ b/src/pages/Volunteers/VolunteerCard.jsx @@ -2,6 +2,8 @@ import React, {useEffect, useState} from "react"; import styles from "./VolunteersPage.module.css"; import getUserById from "../../utils/users/getUserById.js"; import formatDate from "../../utils/date/formatDate.js"; +import { useNavigate } from "react-router"; +import Button from "../../components/ui/button/button.jsx"; export default function VolunteerCard({ id }) { @@ -19,49 +21,63 @@ export default function VolunteerCard({ id }) { }) () }, []); + const navigate = useNavigate(); + return (
-
- {!isExpanded ? ( -
-

{user?.name}

-

Rôle : {user?.role}

-

Membre depuis : {user?.created_at && formatDate(user.created_at)}

-
- ) : ( -
-
- {`profile -
-
-
-

{user?.name}

-

Rôle : {user?.role}

-

Membre depuis : {user?.created_at && formatDate(user.created_at)}

-
-
-

Email : {user?.email}

- {user?.phone && ( -

Téléphone : {user.phone}

- )} -
-
-
- )} + {/* Header : titre + bouton expand */} +
+

{user?.name}

- {isExpanded && ( -
- VOIR PLUS +
+ +
+ {!isExpanded ? ( +
+

Rôle : {user?.role}

+

Membre depuis : {user?.created_at && formatDate(user.created_at)}

+
+ ) : ( +
+
+ profile +
+ +
+
+

Rôle : {user?.role}

+

Membre depuis : {user?.created_at && formatDate(user.created_at)}

+
+ +
+

Email : {user?.email}

+ {user?.phone &&

Téléphone : {user.phone}

} +
+
)}
+ + {isExpanded && ( +
+ +
+ )} +
); + + } \ No newline at end of file diff --git a/src/pages/Volunteers/VolunteersPage.module.css b/src/pages/Volunteers/VolunteersPage.module.css index 01bb808..bf48824 100644 --- a/src/pages/Volunteers/VolunteersPage.module.css +++ b/src/pages/Volunteers/VolunteersPage.module.css @@ -1,125 +1,113 @@ .container { - width: 100%; - padding: 10px; - box-sizing: border-box; - margin-top: 50px; + width: 100%; + padding: 10px; + margin-top: 50px; + box-sizing: border-box; } .profileboard { - width: 100%; - padding: 15px; - border-radius: 10px; - box-sizing: border-box; - margin-top: 3%; - position: relative; + width: 100%; + padding: 15px; + margin-top: 3%; + display: flex; + flex-direction: column; + gap: 10px; + box-sizing: border-box; } +.header { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 10px; +} + +.header h2 { + margin: 0; +} + + .mainContent { - display: flex; - flex-direction: row; - justify-content: space-between; - align-items: flex-start; - width: 100%; + display: flex; + flex-direction: row; + width: 100%; + flex: 1; } .basicInfo { - flex: 1; + flex: 1; } .expandedContent { - display: flex; - flex-direction: row; - align-items: flex-start; - width: 100%; -} - -.profilePictureContainer { - width: 120px; - height: 120px; - margin-right: 20px; -} - -.profilePicture { - width: 100%; - height: 100%; - border-radius: 50%; - object-fit: cover; + display: flex; + flex-direction: row; + width: 100%; } .textInfo { - display: flex; - flex-direction: column; - flex: 1; + display: flex; + flex-direction: column; + flex: 1; } .contactInfo { - margin-top: 10px; + margin-top: 10px; } .contactInfo p { - margin: 5px 0; + margin: 5px 0; +} + +.bottomBar { + display: flex; + justify-content: flex-end; +} + +.profilePictureContainer { + width: 120px; + height: 120px; + margin-right: 20px; +} + +.profilePicture { + width: 100%; + height: 100%; + border-radius: 50%; + object-fit: cover; } .expandButton { - width: 30px; - height: 30px; - display: flex; - align-items: center; - justify-content: center; - cursor: pointer; - background: transparent; - border: none; - font-size: 16px; - margin-left: 10px; - position: absolute; - top: 10px; - right: 10px; -} - -.voirPlus { - position: absolute; - bottom: 10px; - right: 10px; - color: #007bff; - text-decoration: none; - font-weight: bold; - cursor: pointer; -} - -.voirPlus:hover { - text-decoration: underline; + width: 30px; + height: 30px; + display: flex; + align-items: center; + justify-content: center; + cursor: pointer; + background: transparent; + border: none; + font-size: 16px; } @media screen and (min-width: 768px) { - .profilePictureContainer { - width: 150px; - height: 150px; - } - .voirPlus{ - text-align: right; - } + .profilePictureContainer { + width: 150px; + height: 150px; + } } @media screen and (min-width: 1024px) { - .container { - max-width: 1200px; - margin: 0 auto; - padding: 20px; - margin-top:50px; - margin-bottom: 50px; - } + .container { + max-width: 1200px; + margin: 50px auto; + padding: 20px; + } - .profileboard { - padding: 25px; - } + .profileboard { + padding: 25px; + } - .profilePictureContainer { - width: 200px; - height: auto; - } + .profilePictureContainer { + width: 200px; + height: auto; + } } - - - - - From d2e95744b8a4e753eaac8813df6121ff41f39084 Mon Sep 17 00:00:00 2001 From: T'JAMPENS QUENTIN p2406187 Date: Sun, 7 Dec 2025 01:07:27 +0100 Subject: [PATCH 17/31] get db events --- src/components/Event/Event.jsx | 18 ++-- src/pages/Events/EventsPage.jsx | 165 +++++--------------------------- src/utils/event/getAllEvents.js | 23 +++++ 3 files changed, 55 insertions(+), 151 deletions(-) create mode 100644 src/utils/event/getAllEvents.js diff --git a/src/components/Event/Event.jsx b/src/components/Event/Event.jsx index deaec58..ab646c6 100644 --- a/src/components/Event/Event.jsx +++ b/src/components/Event/Event.jsx @@ -41,14 +41,16 @@ function Event({event}){

{event.description}

    - {event.tasks - .slice(0,5) - .map((task, index) => ( -
  • - {task.name}
  • - ))} - {event.tasks.length > 5 ? ( -
  • ...
  • - ) : null} + {event.tasks.length > 0 && ( + <> + {event.tasks.slice(0, 5).map((task, index) => ( +
  • {task.name}
  • + ))} + + {event.tasks.length > 5 &&
  • ...
  • } + + )} +
diff --git a/src/pages/Events/EventsPage.jsx b/src/pages/Events/EventsPage.jsx index f547b45..5e84496 100644 --- a/src/pages/Events/EventsPage.jsx +++ b/src/pages/Events/EventsPage.jsx @@ -1,8 +1,9 @@ -import {useState} from "react"; +import { useEffect, useState } from "react"; import Event from "../../components/Event/Event.jsx"; -import {Link} from "react-router"; +import { Link } from "react-router"; import styles from "./EventsPage.module.css"; import Filter from "../../components/Filter/Filter.jsx"; +import getAllEvents from "../../utils/event/getAllEvents.js"; @@ -17,8 +18,11 @@ function EventsPage(){ yearOrder: "asc", }); - const [events] = useState([ - { + const [events, setEvents] = useState([]); + + /* + + { id: 1, name: "Marathon de la Ville", description: "Participez au marathon annuel et soutenez les associations locales.", @@ -41,144 +45,15 @@ function EventsPage(){ volunteers_count: 3 }, ] - }, - { - id: 2, - name: "Festival de Musique d’Été", - description: "Un week-end de concerts en plein air avec des artistes locaux et internationaux.", - image: null, - tasks: [ - { - name: "Montage de la scène", - start: "2018-09-24 22:21:20", - end: "2018-09-24 22:21:20", - place: "Parc central", - description: "Installer la scène, les éclairages et le son.", - volunteers_count: 6 - }, - { - name: "Accueil du public", - start: "2018-09-24 22:21:20", - end: "2018-09-24 22:21:20", - place: "Entrée principale", - description: "Vérifier les billets et orienter les visiteurs.", - volunteers_count: 4 - }, - ] - }, - { - id: 3, - name: "Conférence Tech Innovante", - description: "Journée de conférences et workshops autour des nouvelles technologies.", - image: null, - tasks: [ - { - name: "Préparation des salles", - start: "2018-09-24 22:21:20", - end: "2018-09-24 22:21:20", - place: "Campus Tech", - description: "Installer les chaises, projecteurs et matériel pour les conférences.", - volunteers_count: 4 - }, - { - name: "Accueil des intervenants", - start: "2018-09-24 22:21:20", - end: "2018-09-24 22:21:20", - place: "Hall principal", - description: "Assister les speakers et orienter vers les salles.", - volunteers_count: 2 - }, - { - name: "Gestion du buffet", - start: "2018-09-24 22:21:20", - end: "2018-09-24 22:21:20", - place: "Salle de restauration", - description: "Distribuer boissons et repas aux participants.", - volunteers_count: 3 - }, - ] - }, - { - id: 4, - name: "Atelier de Jardinage Urbain", - description: "Apprenez à cultiver vos plantes en ville et participez à la création de jardins partagés.", - image: null, - tasks: [ - { - name: "Installation du matériel", - start: "2018-09-24 22:21:20", - end: "2018-09-24 22:21:20", - place: "Jardin partagé", - description: "Préparer outils et terreaux pour les participants.", - volunteers_count: 2 - }, - { - name: "Encadrement des participants", - start: "2018-09-24 22:21:20", - end: "2018-09-24 22:21:20", - place: "Jardin partagé", - description: "Aider et conseiller sur la plantation et l’entretien.", - volunteers_count: 3 - }, - ] - }, - { - id: 5, - name: "Collecte de Sang", - description: "Aidez à sauver des vies en participant à notre collecte de sang annuelle.", - image: null, - tasks: [ - { - name: "Accueil et enregistrement", - start: "2020-09-24 22:21:20", - end: "2020-09-24 22:21:20", - place: "Salle municipale", - description: "Enregistrer les donneurs et expliquer le processus.", - volunteers_count: 4 - }, - { - name: "Préparation des salles", - start: "2018-09-24 22:21:20", - end: "2018-09-24 22:21:20", - place: "Salle municipale", - description: "Installer les lits, tables et matériel médical.", - volunteers_count: 3 - }, - { - name: "Assistance post-don", - start: "2018-09-24 22:21:20", - end: "2018-09-24 22:21:20", - place: "Salle municipale", - description: "Accompagner les donneurs après le don et proposer des rafraîchissements.", - volunteers_count: 2 - }, - { - name: "Accueil et enregistrement", - start: "2020-09-24 22:21:20", - end: "2020-09-24 22:21:20", - place: "Salle municipale", - description: "Enregistrer les donneurs et expliquer le processus.", - volunteers_count: 4 - }, - { - name: "Préparation des salles", - start: "2018-09-24 22:21:20", - end: "2018-09-24 22:21:20", - place: "Salle municipale", - description: "Installer les lits, tables et matériel médical.", - volunteers_count: 3 - }, - { - name: "Assistance post-don", - start: "2018-09-24 22:21:20", - end: "2018-09-24 22:21:20", - place: "Salle municipale", - description: "Accompagner les donneurs après le don et proposer des rafraîchissements.", - volunteers_count: 2 - }, - ] - }, - ]); + } + */ + + useEffect(() => { + (async () => { + const data = await getAllEvents(); + setEvents(data.data); + }) () + }, []); const compareDate = (dateA, dateB) => { const dA = new Date(dateA); @@ -191,6 +66,8 @@ function EventsPage(){ } }; + /* + const sortedEvents = [...events].sort((a, b) => { const sortedATasks = a.tasks.sort((taskA, taskB) => compareDate(taskA.start, taskB.start) @@ -217,6 +94,8 @@ function EventsPage(){ return 0; }); + */ + @@ -240,7 +119,7 @@ function EventsPage(){
- {sortedEvents.map((event, index) => ( + {events.map((event, index) => ( ))}
diff --git a/src/utils/event/getAllEvents.js b/src/utils/event/getAllEvents.js new file mode 100644 index 0000000..f5e37c5 --- /dev/null +++ b/src/utils/event/getAllEvents.js @@ -0,0 +1,23 @@ +export default async function getAllEvents() { + + try { + const res = await fetch(`http://${import.meta.env.VITE_API_URL}/api/events/`, { + method: 'GET', + credentials: 'include', + headers: { + 'Accept': 'application/json' + } + }); + + if (!res.ok) { + throw new Error(`Erreur serveur : ${res.status}`); + } + + const data = await res.json(); + return data; + } catch (err) { + console.error('Erreur :', err); + return null; + } + +} \ No newline at end of file From e1fee3dd82f9fc02b003e0e365ca497eab348116 Mon Sep 17 00:00:00 2001 From: T'JAMPENS QUENTIN p2406187 Date: Sun, 7 Dec 2025 01:17:12 +0100 Subject: [PATCH 18/31] Accept className --- src/components/ui/button/button.jsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/ui/button/button.jsx b/src/components/ui/button/button.jsx index 5ff769c..0fc74ab 100644 --- a/src/components/ui/button/button.jsx +++ b/src/components/ui/button/button.jsx @@ -1,6 +1,6 @@ import styles from "./button.module.css"; -const Button = ({ children, variant = "primary", onClick }) => { +const Button = ({ children, variant = "primary", onClick, className }) => { let btnStyle; if (variant === "primary") btnStyle = styles.primary; @@ -8,7 +8,7 @@ const Button = ({ children, variant = "primary", onClick }) => { else if(variant === "transparent") btnStyle = styles.transparent; else btnStyle = styles.default; - return
+ return
{children}
; }; From 51a32e01f33c2848baff957f436ab7458f6cd7a8 Mon Sep 17 00:00:00 2001 From: T'JAMPENS QUENTIN p2406187 Date: Sun, 7 Dec 2025 01:17:21 +0100 Subject: [PATCH 19/31] Update style --- src/components/Event/Event.module.css | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/src/components/Event/Event.module.css b/src/components/Event/Event.module.css index 142d004..e294c74 100644 --- a/src/components/Event/Event.module.css +++ b/src/components/Event/Event.module.css @@ -3,6 +3,7 @@ flex-direction: column; margin: 1rem 0; width: 80%; + padding: 1rem 0.5rem; } .eventContainerTop { @@ -45,11 +46,6 @@ font-size: 2rem; } - - - - - .eventButtons { display: flex; flex-direction: column; @@ -63,9 +59,6 @@ white-space: nowrap; } - - - .moreButton { background: none; border: none; @@ -94,19 +87,16 @@ rotate: 90deg; } - .eventMenuOpen { display: flex; + flex-direction: column; + margin-left: 1.5em; } .eventMenuClose { display: none; } - - - - @media screen and (max-width: 768px) { .eventImage { width: 100%; From e5917a89cdc05b9fd1b4246ebbec910e4aed047d Mon Sep 17 00:00:00 2001 From: T'JAMPENS QUENTIN p2406187 Date: Sun, 7 Dec 2025 01:17:41 +0100 Subject: [PATCH 20/31] Use ui Button --- src/components/Event/Event.jsx | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/src/components/Event/Event.jsx b/src/components/Event/Event.jsx index ab646c6..68c2625 100644 --- a/src/components/Event/Event.jsx +++ b/src/components/Event/Event.jsx @@ -31,7 +31,7 @@ function Event({event}){
{event.image == null ? ( - Pas de photo de l'événement + Pas de photo de l'événement ) : ( Photo de l'événement )} @@ -39,8 +39,7 @@ function Event({event}){

{event.name}

{event.description}

-
-
    +
      {event.tasks.length > 0 && ( <> {event.tasks.slice(0, 5).map((task, index) => ( @@ -50,18 +49,18 @@ function Event({event}){ {event.tasks.length > 5 &&
    • ...
    • } )} -
    -
{windowSize.width > 768 ? (
- +
) : null}
@@ -70,7 +69,7 @@ function Event({event}){ - + ) : null}
From e41ac77a1fceed8d91f35cba34c1b91c6c5b1e0f Mon Sep 17 00:00:00 2001 From: T'JAMPENS QUENTIN p2406187 Date: Sun, 7 Dec 2025 01:19:49 +0100 Subject: [PATCH 21/31] Use useNavigate hook --- src/components/Event/Event.jsx | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/components/Event/Event.jsx b/src/components/Event/Event.jsx index 68c2625..cc01258 100644 --- a/src/components/Event/Event.jsx +++ b/src/components/Event/Event.jsx @@ -1,9 +1,12 @@ import styles from "./Event.module.css"; -import {useState, useEffect} from "react"; -import {Link} from "react-router"; +import { useState, useEffect } from "react"; +import { useNavigate } from "react-router"; import Button from "/src/components/ui/button/button.jsx" function Event({event}){ + + const navigate = useNavigate(); + const [eventMenu, seteventMenu] = useState(false); const [windowSize, setWindowSize] = useState({ width: null, @@ -66,11 +69,9 @@ function Event({event}){
{(windowSize.width <= 768 || eventMenu) ? ( - - - + + + ) : null}
From fa2c112d7e95dd72a61050219cae61496e53e53a Mon Sep 17 00:00:00 2001 From: T'JAMPENS QUENTIN p2406187 Date: Sun, 7 Dec 2025 01:22:27 +0100 Subject: [PATCH 22/31] Remove useless login route --- src/router.js | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/router.js b/src/router.js index 1576c66..bd0c986 100644 --- a/src/router.js +++ b/src/router.js @@ -25,10 +25,6 @@ const router = createBrowserRouter([ path: "/", Component: HomePage, }, - { - path: "/login", - Component: LoginPage, - }, { path: "/stat", Component:StatPage, From 0188ac43bfcc04870eac398654f293f605079a0c Mon Sep 17 00:00:00 2001 From: T'JAMPENS QUENTIN p2406187 Date: Sun, 7 Dec 2025 01:39:46 +0100 Subject: [PATCH 23/31] Add dark theme --- src/components/background/background.jsx | 11 ++++++++--- src/components/background/background.module.css | 16 +++++++++------- 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/src/components/background/background.jsx b/src/components/background/background.jsx index b77ce82..05ba976 100644 --- a/src/components/background/background.jsx +++ b/src/components/background/background.jsx @@ -1,8 +1,10 @@ import styles from "./background.module.css"; -import { useEffect, useRef } from "react"; +import { useEffect, useRef, useState } from "react"; const Background = ({ children, className }) => { - const circlesRef = useRef([]); + + const circlesRef = useRef([]); + const [theme, setTheme] = useState("light"); const getRandomTranslation = () => { const randomX = Math.floor(Math.random() * 100) - 30; @@ -11,6 +13,9 @@ const Background = ({ children, className }) => { }; useEffect(() => { + + setTheme(localStorage.getItem("theme") ? localStorage.getItem("theme") : "light"); + circlesRef.current.forEach((circle) => { if (circle) { const { x, y } = getRandomTranslation(); @@ -21,7 +26,7 @@ const Background = ({ children, className }) => { }, []); return ( -
+
(circlesRef.current[0] = el)} className={`${styles["circle"]} ${styles["circle-1"]}`} diff --git a/src/components/background/background.module.css b/src/components/background/background.module.css index e5cca18..c0e7211 100644 --- a/src/components/background/background.module.css +++ b/src/components/background/background.module.css @@ -1,10 +1,9 @@ /* BACKGROUND ////////////////////////////////////////////////////////*/ -.background-container { +.backgroundContainer { z-index: 0; margin: 0; padding: 0; min-height: 100vh; - background: #00F0FF; overflow: hidden; position: relative; width: 100vw; @@ -13,6 +12,14 @@ align-items: center; } +.backgroundLight { + background: #00F0FF; +} + +.backgroundDark { + background: #001C83; +} + .circle { position: absolute; border-radius: 50%; @@ -82,7 +89,6 @@ .circle-1 { width: 300px; height: 300px; - background-color: #019AFF; top: -5%; left: -5%; } @@ -90,7 +96,6 @@ .circle-2 { width: 175px; height: 175px; - background-color: #91FCFF; top: 58%; left: 10%; } @@ -98,7 +103,6 @@ .circle-3 { width: 140px; height: 140px; - background-color: #91FCFF; top: 29%; right: 9%; } @@ -106,7 +110,6 @@ .circle-4 { width: 250px; height: 250px; - background-color: #019AFF; bottom: 0; right: 0; } @@ -114,7 +117,6 @@ .circle-5 { width: 240px; height: 240px; - background-color: #015AFF; top: 2%; right: 10%; } From b0de796c457694656bd31d82d67fde4746d487dc Mon Sep 17 00:00:00 2001 From: T'JAMPENS QUENTIN p2406187 Date: Sun, 7 Dec 2025 01:54:32 +0100 Subject: [PATCH 24/31] Switch theme btn --- src/components/background/background.jsx | 20 ++++++++++++++++---- src/pages/Profile/ProfilePage.jsx | 18 +++++++++++++++++- src/pages/Profile/ProfilePage.module.css | 8 +++++++- 3 files changed, 40 insertions(+), 6 deletions(-) diff --git a/src/components/background/background.jsx b/src/components/background/background.jsx index 05ba976..96df4b6 100644 --- a/src/components/background/background.jsx +++ b/src/components/background/background.jsx @@ -13,9 +13,6 @@ const Background = ({ children, className }) => { }; useEffect(() => { - - setTheme(localStorage.getItem("theme") ? localStorage.getItem("theme") : "light"); - circlesRef.current.forEach((circle) => { if (circle) { const { x, y } = getRandomTranslation(); @@ -25,7 +22,22 @@ const Background = ({ children, className }) => { }); }, []); - return ( + useEffect(() => { + const updateTheme = () => { + setTheme(localStorage.getItem("theme") || "light"); + }; + + updateTheme(); // Initial load + + window.addEventListener("theme-changed", updateTheme); + + return () => { + window.removeEventListener("theme-changed", updateTheme); + }; + }, []); + + + return (
(circlesRef.current[0] = el)} diff --git a/src/pages/Profile/ProfilePage.jsx b/src/pages/Profile/ProfilePage.jsx index 033ea4b..5eeb17e 100644 --- a/src/pages/Profile/ProfilePage.jsx +++ b/src/pages/Profile/ProfilePage.jsx @@ -15,6 +15,19 @@ function ProfilePage() { logout(); } + const switchTheme = () => { + + const currentTheme = localStorage.getItem("theme"); + let newTheme = currentTheme === "light" ? "dark" : "light"; + + if(currentTheme === null) newTheme = "dark"; + + localStorage.setItem("theme", newTheme); + + window.dispatchEvent(new Event("theme-changed")); + }; + + return (
@@ -29,7 +42,10 @@ function ProfilePage() {

{user.name} {user.lastname}

- +
+ + +
diff --git a/src/pages/Profile/ProfilePage.module.css b/src/pages/Profile/ProfilePage.module.css index 438156d..6f61f45 100644 --- a/src/pages/Profile/ProfilePage.module.css +++ b/src/pages/Profile/ProfilePage.module.css @@ -70,7 +70,13 @@ } .profilePicture{ width:90%; - } +} + +.settingsBtns { + display: flex; + gap: 5px; + justify-content: right; +} @media screen and (min-width: 768px) { .contentWrapper { From c66076f1ed33c6209f344b65831c8ed2e3a1453c Mon Sep 17 00:00:00 2001 From: T'JAMPENS QUENTIN p2406187 Date: Sun, 7 Dec 2025 14:32:26 +0100 Subject: [PATCH 25/31] Create ThemeSwitcher btn --- .../ui/themeSwitcher/ThemeSwitcher.jsx | 19 +++++++++++++++++++ src/pages/Profile/ProfilePage.jsx | 16 ++-------------- 2 files changed, 21 insertions(+), 14 deletions(-) create mode 100644 src/components/ui/themeSwitcher/ThemeSwitcher.jsx diff --git a/src/components/ui/themeSwitcher/ThemeSwitcher.jsx b/src/components/ui/themeSwitcher/ThemeSwitcher.jsx new file mode 100644 index 0000000..1b9a84f --- /dev/null +++ b/src/components/ui/themeSwitcher/ThemeSwitcher.jsx @@ -0,0 +1,19 @@ +import Button from "../button/button.jsx"; +import React from "react"; + +export default function ThemeSwitcher() { + + const switchTheme = () => { + + const currentTheme = localStorage.getItem("theme"); + let newTheme = currentTheme === "light" ? "dark" : "light"; + + if(currentTheme === null) newTheme = "dark"; + + localStorage.setItem("theme", newTheme); + + window.dispatchEvent(new Event("theme-changed")); + }; + + return +} \ No newline at end of file diff --git a/src/pages/Profile/ProfilePage.jsx b/src/pages/Profile/ProfilePage.jsx index 5eeb17e..871edb5 100644 --- a/src/pages/Profile/ProfilePage.jsx +++ b/src/pages/Profile/ProfilePage.jsx @@ -5,6 +5,7 @@ import formatDate from "../../utils/date/formatDate.js"; import Task from "../../components/Task/Task"; import Button from "../../components/ui/button/button.jsx"; import { useNavigate } from "react-router"; +import ThemeSwitcher from "../../components/ui/themeSwitcher/ThemeSwitcher.jsx"; function ProfilePage() { @@ -15,19 +16,6 @@ function ProfilePage() { logout(); } - const switchTheme = () => { - - const currentTheme = localStorage.getItem("theme"); - let newTheme = currentTheme === "light" ? "dark" : "light"; - - if(currentTheme === null) newTheme = "dark"; - - localStorage.setItem("theme", newTheme); - - window.dispatchEvent(new Event("theme-changed")); - }; - - return (
@@ -43,7 +31,7 @@ function ProfilePage() {

{user.name} {user.lastname}

- +
From a3ccbb9c136a08d30d507fdd885ebfa2bd39045d Mon Sep 17 00:00:00 2001 From: T'JAMPENS QUENTIN p2406187 Date: Sun, 7 Dec 2025 14:34:46 +0100 Subject: [PATCH 26/31] Display message if user don't have tasks --- src/pages/Profile/ProfilePage.jsx | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/pages/Profile/ProfilePage.jsx b/src/pages/Profile/ProfilePage.jsx index 871edb5..0271d42 100644 --- a/src/pages/Profile/ProfilePage.jsx +++ b/src/pages/Profile/ProfilePage.jsx @@ -50,9 +50,14 @@ function ProfilePage() {

Vos Événements :

- {user.tasks && user.tasks.map((task, index) => ( - - ))} + {user.tasks && user.tasks.length > 0 ? ( + user.tasks.map((task, index) => ( + + )) + ) : ( +

Aucune tâche pour le moment.

+ )} +
From 86305699ed94698aed49567e9e76c8ee1c5b333a Mon Sep 17 00:00:00 2001 From: T'JAMPENS QUENTIN p2406187 Date: Sun, 7 Dec 2025 14:43:38 +0100 Subject: [PATCH 27/31] Fix border radius --- src/pages/Profile/ProfilePage.module.css | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pages/Profile/ProfilePage.module.css b/src/pages/Profile/ProfilePage.module.css index 6f61f45..e4e467b 100644 --- a/src/pages/Profile/ProfilePage.module.css +++ b/src/pages/Profile/ProfilePage.module.css @@ -7,7 +7,7 @@ .profileboard { width: 100%; padding: 15px; - border-radius: 10px; + border-radius: 20px; box-sizing: border-box; } @@ -144,7 +144,7 @@ } .profileboard { - padding: 25px; + padding: 25px; } .profilePictureContainer { From efbf234fb98b7c0cae41b7a748b17de2b4f351bb Mon Sep 17 00:00:00 2001 From: T'JAMPENS QUENTIN p2406187 Date: Sun, 7 Dec 2025 14:58:42 +0100 Subject: [PATCH 28/31] Create passwordInput component --- src/components/loginform/loginForm.jsx | 32 +----------------------- src/components/ui/input/input.jsx | 29 +++++++++++++++++++-- src/components/ui/input/input.module.css | 20 +++++++++++++++ 3 files changed, 48 insertions(+), 33 deletions(-) diff --git a/src/components/loginform/loginForm.jsx b/src/components/loginform/loginForm.jsx index 218201d..cc3a47f 100644 --- a/src/components/loginform/loginForm.jsx +++ b/src/components/loginform/loginForm.jsx @@ -9,7 +9,6 @@ import { AuthContext } from "../../contexts/auth/AuthContext.js"; function LoginForm({ className }) { const [email, setEmail] = useState(''); const [password, setPassword] = useState(''); - const [showPassword, setShowPassword] = useState(false); let navigate = useNavigate(); const { login } = useContext(AuthContext); @@ -19,10 +18,6 @@ function LoginForm({ className }) { navigate("/"); } - const toggleShowPassword = () => { - setShowPassword(!showPassword); - }; - return (
@@ -35,32 +30,7 @@ function LoginForm({ className }) { />
-
- setPassword(e.target.value)} - style={{ width: '100%' }} - /> - -
+ setPassword(e.target.value)} value={password} />
diff --git a/src/components/ui/input/input.jsx b/src/components/ui/input/input.jsx index c756a3e..0218b3e 100644 --- a/src/components/ui/input/input.jsx +++ b/src/components/ui/input/input.jsx @@ -1,13 +1,38 @@ import styles from "./input.module.css"; +import { useState } from "react"; -const TextInput = ({ placeholder, onChange, value, borderStyle, ...props }) => { +const TextInput = ({ placeholder, onChange, value, borderStyle, password, className, ...props }) => { + const [showPassword, setShowPassword] = useState(false); let inputBorderStyle = styles.square; if (borderStyle === "square") inputBorderStyle = styles.square; if(borderStyle === "rounded") inputBorderStyle = styles.rounded; - return + const toggleShowPassword = () => { + setShowPassword(!showPassword); + }; + + if(password) return ( +
+ + +
+ ); + + return }; export default TextInput; diff --git a/src/components/ui/input/input.module.css b/src/components/ui/input/input.module.css index eaafa25..e56ef67 100644 --- a/src/components/ui/input/input.module.css +++ b/src/components/ui/input/input.module.css @@ -30,3 +30,23 @@ border-radius: 12px; } +.passwordContainer { + position: relative; + width: 100%; +} + +.passwordInput { + width: 100%; +} + +.passwordBtn { + position: absolute; + width: 30px; + right: 10px; + top: 50%; + transform: translateY(-50%); + background: none; + border: none; + cursor: pointer; + font-size: 16px; +} From 31b2e36140a4f4918df608116bea9afdb038838a Mon Sep 17 00:00:00 2001 From: T'JAMPENS QUENTIN p2406187 Date: Sun, 7 Dec 2025 15:00:55 +0100 Subject: [PATCH 29/31] Add redirection to register page --- src/components/loginform/loginForm.jsx | 1 + src/components/loginform/loginForm.module.css | 9 ++++++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/components/loginform/loginForm.jsx b/src/components/loginform/loginForm.jsx index cc3a47f..cd22971 100644 --- a/src/components/loginform/loginForm.jsx +++ b/src/components/loginform/loginForm.jsx @@ -34,6 +34,7 @@ function LoginForm({ className }) {
+
diff --git a/src/components/loginform/loginForm.module.css b/src/components/loginform/loginForm.module.css index f04cfe7..45caff4 100644 --- a/src/components/loginform/loginForm.module.css +++ b/src/components/loginform/loginForm.module.css @@ -18,15 +18,18 @@ input::placeholder{ font-size: 20px; color: rgba(0,0,0,0.45); } + +.formgroup{ + margin-top:23px; +} + .logButton{ display: flex; justify-content: center; + flex-direction: column; align-items: center; margin-top: 12px; } -.formgroup{ - margin-top:23px; -} .inputContainer { padding: 15px; From c556829bc5b2b759fca8cf41741ff6015e285652 Mon Sep 17 00:00:00 2001 From: T'JAMPENS QUENTIN p2406187 Date: Sun, 7 Dec 2025 15:02:52 +0100 Subject: [PATCH 30/31] use Passwordinput component --- src/pages/Register/RegisterPage.jsx | 27 +-------------------------- 1 file changed, 1 insertion(+), 26 deletions(-) diff --git a/src/pages/Register/RegisterPage.jsx b/src/pages/Register/RegisterPage.jsx index c2e47ab..cac9e4d 100644 --- a/src/pages/Register/RegisterPage.jsx +++ b/src/pages/Register/RegisterPage.jsx @@ -62,32 +62,7 @@ function RegisterPage() { />
-
- setPassword(e.target.value)} - style={{ width: '100%' }} - /> - -
+ setPassword(e.target.value)} value={password} />
From 6f7e5b9258e286050918bf5a0cb73812e0e3f0b5 Mon Sep 17 00:00:00 2001 From: T'JAMPENS QUENTIN p2406187 Date: Sun, 7 Dec 2025 15:38:37 +0100 Subject: [PATCH 31/31] use UI Button --- src/pages/Volunteers/VolunteerCard.jsx | 10 +++++----- src/pages/Volunteers/VolunteersPage.module.css | 4 ++++ 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/pages/Volunteers/VolunteerCard.jsx b/src/pages/Volunteers/VolunteerCard.jsx index 0f5437c..a2a3f84 100644 --- a/src/pages/Volunteers/VolunteerCard.jsx +++ b/src/pages/Volunteers/VolunteerCard.jsx @@ -26,15 +26,15 @@ export default function VolunteerCard({ id }) { return (
- {/* Header : titre + bouton expand */}

{user?.name}

- + {">"} +
diff --git a/src/pages/Volunteers/VolunteersPage.module.css b/src/pages/Volunteers/VolunteersPage.module.css index bf48824..c18433e 100644 --- a/src/pages/Volunteers/VolunteersPage.module.css +++ b/src/pages/Volunteers/VolunteersPage.module.css @@ -88,6 +88,10 @@ font-size: 16px; } +.moreButtonClicked { + rotate: 90deg; +} + @media screen and (min-width: 768px) { .profilePictureContainer { width: 150px;