diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..6b892d6 --- /dev/null +++ b/.gitignore @@ -0,0 +1,32 @@ +# Node modules +node_modules/ + +# Logs +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +# Environment files +.env +.env.local +.env.*.local + +# Build output +dist/ +build/ +.next/ +out/ + +# IDE files +.vscode/ +.idea/ +*.swp + +# Mac / Linux / Windows system files +.DS_Store +Thumbs.db + +# Temporary +*.tmp diff --git a/index.html b/index.html new file mode 100644 index 0000000..9354468 --- /dev/null +++ b/index.html @@ -0,0 +1,15 @@ + + + + + + + Access Hub Homepage Design + + + +
+ + + + \ No newline at end of file diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..a4d4024 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,4248 @@ +{ + "name": "Access Hub Homepage Design", + "version": "0.1.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "Access Hub Homepage Design", + "version": "0.1.0", + "dependencies": { + "@radix-ui/react-accordion": "^1.2.3", + "@radix-ui/react-alert-dialog": "^1.1.6", + "@radix-ui/react-aspect-ratio": "^1.1.2", + "@radix-ui/react-avatar": "^1.1.3", + "@radix-ui/react-checkbox": "^1.1.4", + "@radix-ui/react-collapsible": "^1.1.3", + "@radix-ui/react-context-menu": "^2.2.6", + "@radix-ui/react-dialog": "^1.1.6", + "@radix-ui/react-dropdown-menu": "^2.1.6", + "@radix-ui/react-hover-card": "^1.1.6", + "@radix-ui/react-label": "^2.1.2", + "@radix-ui/react-menubar": "^1.1.6", + "@radix-ui/react-navigation-menu": "^1.2.5", + "@radix-ui/react-popover": "^1.1.6", + "@radix-ui/react-progress": "^1.1.2", + "@radix-ui/react-radio-group": "^1.2.3", + "@radix-ui/react-scroll-area": "^1.2.3", + "@radix-ui/react-select": "^2.1.6", + "@radix-ui/react-separator": "^1.1.2", + "@radix-ui/react-slider": "^1.2.3", + "@radix-ui/react-slot": "^1.1.2", + "@radix-ui/react-switch": "^1.1.3", + "@radix-ui/react-tabs": "^1.1.3", + "@radix-ui/react-toggle": "^1.1.2", + "@radix-ui/react-toggle-group": "^1.1.2", + "@radix-ui/react-tooltip": "^1.1.8", + "@radix-ui/react-visually-hidden": "^1.1.1", + "@tailwindcss/postcss": "^4.1.14", + "class-variance-authority": "^0.7.1", + "clsx": "*", + "cmdk": "^1.1.1", + "embla-carousel-react": "^8.6.0", + "input-otp": "^1.4.2", + "lucide-react": "^0.487.0", + "motion": "*", + "next-themes": "^0.4.6", + "postcss": "^8.5.6", + "react": "^18.3.1", + "react-day-picker": "^8.10.1", + "react-dom": "^18.3.1", + "react-hook-form": "^7.55.0", + "react-resizable-panels": "^2.1.7", + "recharts": "^2.15.2", + "sonner": "^2.0.3", + "tailwind-merge": "*", + "tailwindcss": "^4.1.14", + "vaul": "^1.1.2" + }, + "devDependencies": { + "@types/node": "^20.10.0", + "@types/react": "^19.2.2", + "@types/react-dom": "^19.2.2", + "@vitejs/plugin-react-swc": "^3.10.2", + "vite": "6.3.5" + } + }, + "node_modules/@alloc/quick-lru": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz", + "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.10.tgz", + "integrity": "sha512-0NFWnA+7l41irNuaSVlLfgNT12caWJVLzp5eAVhZ0z1qpxbockccEt3s+149rE64VUI3Ml2zt8Nv5JVc4QXTsw==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.10.tgz", + "integrity": "sha512-dQAxF1dW1C3zpeCDc5KqIYuZ1tgAdRXNoZP7vkBIRtKZPYe2xVr/d3SkirklCHudW1B45tGiUlz2pUWDfbDD4w==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.10.tgz", + "integrity": "sha512-LSQa7eDahypv/VO6WKohZGPSJDq5OVOo3UoFR1E4t4Gj1W7zEQMUhI+lo81H+DtB+kP+tDgBp+M4oNCwp6kffg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.10.tgz", + "integrity": "sha512-MiC9CWdPrfhibcXwr39p9ha1x0lZJ9KaVfvzA0Wxwz9ETX4v5CHfF09bx935nHlhi+MxhA63dKRRQLiVgSUtEg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.10.tgz", + "integrity": "sha512-JC74bdXcQEpW9KkV326WpZZjLguSZ3DfS8wrrvPMHgQOIEIG/sPXEN/V8IssoJhbefLRcRqw6RQH2NnpdprtMA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.10.tgz", + "integrity": "sha512-tguWg1olF6DGqzws97pKZ8G2L7Ig1vjDmGTwcTuYHbuU6TTjJe5FXbgs5C1BBzHbJ2bo1m3WkQDbWO2PvamRcg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.10.tgz", + "integrity": "sha512-3ZioSQSg1HT2N05YxeJWYR+Libe3bREVSdWhEEgExWaDtyFbbXWb49QgPvFH8u03vUPX10JhJPcz7s9t9+boWg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.10.tgz", + "integrity": "sha512-LLgJfHJk014Aa4anGDbh8bmI5Lk+QidDmGzuC2D+vP7mv/GeSN+H39zOf7pN5N8p059FcOfs2bVlrRr4SK9WxA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.10.tgz", + "integrity": "sha512-oR31GtBTFYCqEBALI9r6WxoU/ZofZl962pouZRTEYECvNF/dtXKku8YXcJkhgK/beU+zedXfIzHijSRapJY3vg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.10.tgz", + "integrity": "sha512-5luJWN6YKBsawd5f9i4+c+geYiVEw20FVW5x0v1kEMWNq8UctFjDiMATBxLvmmHA4bf7F6hTRaJgtghFr9iziQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.10.tgz", + "integrity": "sha512-NrSCx2Kim3EnnWgS4Txn0QGt0Xipoumb6z6sUtl5bOEZIVKhzfyp/Lyw4C1DIYvzeW/5mWYPBFJU3a/8Yr75DQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.10.tgz", + "integrity": "sha512-xoSphrd4AZda8+rUDDfD9J6FUMjrkTz8itpTITM4/xgerAZZcFW7Dv+sun7333IfKxGG8gAq+3NbfEMJfiY+Eg==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.10.tgz", + "integrity": "sha512-ab6eiuCwoMmYDyTnyptoKkVS3k8fy/1Uvq7Dj5czXI6DF2GqD2ToInBI0SHOp5/X1BdZ26RKc5+qjQNGRBelRA==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.10.tgz", + "integrity": "sha512-NLinzzOgZQsGpsTkEbdJTCanwA5/wozN9dSgEl12haXJBzMTpssebuXR42bthOF3z7zXFWH1AmvWunUCkBE4EA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.10.tgz", + "integrity": "sha512-FE557XdZDrtX8NMIeA8LBJX3dC2M8VGXwfrQWU7LB5SLOajfJIxmSdyL/gU1m64Zs9CBKvm4UAuBp5aJ8OgnrA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.10.tgz", + "integrity": "sha512-3BBSbgzuB9ajLoVZk0mGu+EHlBwkusRmeNYdqmznmMc9zGASFjSsxgkNsqmXugpPk00gJ0JNKh/97nxmjctdew==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.10.tgz", + "integrity": "sha512-QSX81KhFoZGwenVyPoberggdW1nrQZSvfVDAIUXr3WqLRZGZqWk/P4T8p2SP+de2Sr5HPcvjhcJzEiulKgnxtA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.10.tgz", + "integrity": "sha512-AKQM3gfYfSW8XRk8DdMCzaLUFB15dTrZfnX8WXQoOUpUBQ+NaAFCP1kPS/ykbbGYz7rxn0WS48/81l9hFl3u4A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.10.tgz", + "integrity": "sha512-7RTytDPGU6fek/hWuN9qQpeGPBZFfB4zZgcz2VK2Z5VpdUxEI8JKYsg3JfO0n/Z1E/6l05n0unDCNc4HnhQGig==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.10.tgz", + "integrity": "sha512-5Se0VM9Wtq797YFn+dLimf2Zx6McttsH2olUBsDml+lm0GOCRVebRWUvDtkY4BWYv/3NgzS8b/UM3jQNh5hYyw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.10.tgz", + "integrity": "sha512-XkA4frq1TLj4bEMB+2HnI0+4RnjbuGZfet2gs/LNs5Hc7D89ZQBHQ0gL2ND6Lzu1+QVkjp3x1gIcPKzRNP8bXw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.10.tgz", + "integrity": "sha512-AVTSBhTX8Y/Fz6OmIVBip9tJzZEUcY8WLh7I59+upa5/GPhh2/aM6bvOMQySspnCCHvFi79kMtdJS1w0DXAeag==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.10.tgz", + "integrity": "sha512-fswk3XT0Uf2pGJmOpDB7yknqhVkJQkAQOcW/ccVOtfx05LkbWOaRAtn5SaqXypeKQra1QaEa841PgrSL9ubSPQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.10.tgz", + "integrity": "sha512-ah+9b59KDTSfpaCg6VdJoOQvKjI33nTaQr4UluQwW7aEwZQsbMCfTmfEO4VyewOxx4RaDT/xCy9ra2GPWmO7Kw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.10.tgz", + "integrity": "sha512-QHPDbKkrGO8/cz9LKVnJU22HOi4pxZnZhhA2HYHez5Pz4JeffhDjf85E57Oyco163GnzNCVkZK0b/n4Y0UHcSw==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.10.tgz", + "integrity": "sha512-9KpxSVFCu0iK1owoez6aC/s/EdUQLDN3adTxGCqxMVhrPDj6bt5dbrHDXUuq+Bs2vATFBBrQS5vdQ/Ed2P+nbw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@floating-ui/core": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.7.3.tgz", + "integrity": "sha512-sGnvb5dmrJaKEZ+LDIpguvdX3bDlEllmv4/ClQ9awcmCZrlx5jQyyMWFM5kBI+EyNOCDDiKk8il0zeuX3Zlg/w==", + "license": "MIT", + "dependencies": { + "@floating-ui/utils": "^0.2.10" + } + }, + "node_modules/@floating-ui/dom": { + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.7.4.tgz", + "integrity": "sha512-OOchDgh4F2CchOX94cRVqhvy7b3AFb+/rQXyswmzmGakRfkMgoWVjfnLWkRirfLEfuD4ysVW16eXzwt3jHIzKA==", + "license": "MIT", + "dependencies": { + "@floating-ui/core": "^1.7.3", + "@floating-ui/utils": "^0.2.10" + } + }, + "node_modules/@floating-ui/react-dom": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.6.tgz", + "integrity": "sha512-4JX6rEatQEvlmgU80wZyq9RT96HZJa88q8hp0pBd+LrczeDI4o6uA2M+uvxngVHo4Ihr8uibXxH6+70zhAFrVw==", + "license": "MIT", + "dependencies": { + "@floating-ui/dom": "^1.7.4" + }, + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, + "node_modules/@floating-ui/utils": { + "version": "0.2.10", + "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.10.tgz", + "integrity": "sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ==", + "license": "MIT" + }, + "node_modules/@isaacs/fs-minipass": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz", + "integrity": "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==", + "license": "ISC", + "dependencies": { + "minipass": "^7.0.4" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/remapping": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", + "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@radix-ui/number": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/number/-/number-1.1.1.tgz", + "integrity": "sha512-MkKCwxlXTgz6CFoJx3pCwn07GKp36+aZyu/u2Ln2VrA5DcdyCZkASEDBTd8x5whTQQL5CiYf4prXKLcgQdv29g==", + "license": "MIT" + }, + "node_modules/@radix-ui/primitive": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.3.tgz", + "integrity": "sha512-JTF99U/6XIjCBo0wqkU5sK10glYe27MRRsfwoiq5zzOEZLHU3A3KCMa5X/azekYRCJ0HlwI0crAXS/5dEHTzDg==", + "license": "MIT" + }, + "node_modules/@radix-ui/react-accordion": { + "version": "1.2.12", + "resolved": "https://registry.npmjs.org/@radix-ui/react-accordion/-/react-accordion-1.2.12.tgz", + "integrity": "sha512-T4nygeh9YE9dLRPhAHSeOZi7HBXo+0kYIPJXayZfvWOWA0+n3dESrZbjfDPUABkUNym6Hd+f2IR113To8D2GPA==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-collapsible": "1.1.12", + "@radix-ui/react-collection": "1.1.7", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-direction": "1.1.1", + "@radix-ui/react-id": "1.1.1", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-controllable-state": "1.2.2" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-alert-dialog": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/@radix-ui/react-alert-dialog/-/react-alert-dialog-1.1.15.tgz", + "integrity": "sha512-oTVLkEw5GpdRe29BqJ0LSDFWI3qu0vR1M0mUkOQWDIUnY/QIkLpgDMWuKxP94c2NAC2LGcgVhG1ImF3jkZ5wXw==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-dialog": "1.1.15", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-slot": "1.2.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-arrow": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/@radix-ui/react-arrow/-/react-arrow-1.1.7.tgz", + "integrity": "sha512-F+M1tLhO+mlQaOWspE8Wstg+z6PwxwRd8oQ8IXceWz92kfAmalTRf0EjrouQeo7QssEPfCn05B4Ihs1K9WQ/7w==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-primitive": "2.1.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-aspect-ratio": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/@radix-ui/react-aspect-ratio/-/react-aspect-ratio-1.1.7.tgz", + "integrity": "sha512-Yq6lvO9HQyPwev1onK1daHCHqXVLzPhSVjmsNjCa2Zcxy2f7uJD2itDtxknv6FzAKCwD1qQkeVDmX/cev13n/g==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-primitive": "2.1.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-avatar": { + "version": "1.1.10", + "resolved": "https://registry.npmjs.org/@radix-ui/react-avatar/-/react-avatar-1.1.10.tgz", + "integrity": "sha512-V8piFfWapM5OmNCXTzVQY+E1rDa53zY+MQ4Y7356v4fFz6vqCyUtIz2rUD44ZEdwg78/jKmMJHj07+C/Z/rcog==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-callback-ref": "1.1.1", + "@radix-ui/react-use-is-hydrated": "0.1.0", + "@radix-ui/react-use-layout-effect": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-checkbox": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-checkbox/-/react-checkbox-1.3.3.tgz", + "integrity": "sha512-wBbpv+NQftHDdG86Qc0pIyXk5IR3tM8Vd0nWLKDcX8nNn4nXFOFwsKuqw2okA/1D/mpaAkmuyndrPJTYDNZtFw==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-presence": "1.1.5", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-controllable-state": "1.2.2", + "@radix-ui/react-use-previous": "1.1.1", + "@radix-ui/react-use-size": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-collapsible": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/@radix-ui/react-collapsible/-/react-collapsible-1.1.12.tgz", + "integrity": "sha512-Uu+mSh4agx2ib1uIGPP4/CKNULyajb3p92LsVXmH2EHVMTfZWpll88XJ0j4W0z3f8NK1eYl1+Mf/szHPmcHzyA==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-id": "1.1.1", + "@radix-ui/react-presence": "1.1.5", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-controllable-state": "1.2.2", + "@radix-ui/react-use-layout-effect": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-collection": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-1.1.7.tgz", + "integrity": "sha512-Fh9rGN0MoI4ZFUNyfFVNU4y9LUz93u9/0K+yLgA2bwRojxM8JU1DyvvMBabnZPBgMWREAJvU2jjVzq+LrFUglw==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-slot": "1.2.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-compose-refs": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.2.tgz", + "integrity": "sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-context": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.2.tgz", + "integrity": "sha512-jCi/QKUM2r1Ju5a3J64TH2A5SpKAgh0LpknyqdQ4m6DCV0xJ2HG1xARRwNGPQfi1SLdLWZ1OJz6F4OMBBNiGJA==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-context-menu": { + "version": "2.2.16", + "resolved": "https://registry.npmjs.org/@radix-ui/react-context-menu/-/react-context-menu-2.2.16.tgz", + "integrity": "sha512-O8morBEW+HsVG28gYDZPTrT9UUovQUlJue5YO836tiTJhuIWBm/zQHc7j388sHWtdH/xUZurK9olD2+pcqx5ww==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-menu": "2.1.16", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-callback-ref": "1.1.1", + "@radix-ui/react-use-controllable-state": "1.2.2" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-dialog": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dialog/-/react-dialog-1.1.15.tgz", + "integrity": "sha512-TCglVRtzlffRNxRMEyR36DGBLJpeusFcgMVD9PZEzAKnUs1lKCgX5u9BmC2Yg+LL9MgZDugFFs1Vl+Jp4t/PGw==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-dismissable-layer": "1.1.11", + "@radix-ui/react-focus-guards": "1.1.3", + "@radix-ui/react-focus-scope": "1.1.7", + "@radix-ui/react-id": "1.1.1", + "@radix-ui/react-portal": "1.1.9", + "@radix-ui/react-presence": "1.1.5", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-slot": "1.2.3", + "@radix-ui/react-use-controllable-state": "1.2.2", + "aria-hidden": "^1.2.4", + "react-remove-scroll": "^2.6.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-direction": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-direction/-/react-direction-1.1.1.tgz", + "integrity": "sha512-1UEWRX6jnOA2y4H5WczZ44gOOjTEmlqv1uNW4GAJEO5+bauCBhv8snY65Iw5/VOS/ghKN9gr2KjnLKxrsvoMVw==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-dismissable-layer": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.11.tgz", + "integrity": "sha512-Nqcp+t5cTB8BinFkZgXiMJniQH0PsUt2k51FUhbdfeKvc4ACcG2uQniY/8+h1Yv6Kza4Q7lD7PQV0z0oicE0Mg==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-callback-ref": "1.1.1", + "@radix-ui/react-use-escape-keydown": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-dropdown-menu": { + "version": "2.1.16", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dropdown-menu/-/react-dropdown-menu-2.1.16.tgz", + "integrity": "sha512-1PLGQEynI/3OX/ftV54COn+3Sud/Mn8vALg2rWnBLnRaGtJDduNW/22XjlGgPdpcIbiQxjKtb7BkcjP00nqfJw==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-id": "1.1.1", + "@radix-ui/react-menu": "2.1.16", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-controllable-state": "1.2.2" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-focus-guards": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-guards/-/react-focus-guards-1.1.3.tgz", + "integrity": "sha512-0rFg/Rj2Q62NCm62jZw0QX7a3sz6QCQU0LpZdNrJX8byRGaGVTqbrW9jAoIAHyMQqsNpeZ81YgSizOt5WXq0Pw==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-focus-scope": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-scope/-/react-focus-scope-1.1.7.tgz", + "integrity": "sha512-t2ODlkXBQyn7jkl6TNaw/MtVEVvIGelJDCG41Okq/KwUsJBwQ4XVZsHAVUkK4mBv3ewiAS3PGuUWuY2BoK4ZUw==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-callback-ref": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-hover-card": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/@radix-ui/react-hover-card/-/react-hover-card-1.1.15.tgz", + "integrity": "sha512-qgTkjNT1CfKMoP0rcasmlH2r1DAiYicWsDsufxl940sT2wHNEWWv6FMWIQXWhVdmC1d/HYfbhQx60KYyAtKxjg==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-dismissable-layer": "1.1.11", + "@radix-ui/react-popper": "1.2.8", + "@radix-ui/react-portal": "1.1.9", + "@radix-ui/react-presence": "1.1.5", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-controllable-state": "1.2.2" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-id": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.1.1.tgz", + "integrity": "sha512-kGkGegYIdQsOb4XjsfM97rXsiHaBwco+hFI66oO4s9LU+PLAC5oJ7khdOVFxkhsmlbpUqDAvXw11CluXP+jkHg==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-use-layout-effect": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-label": { + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/@radix-ui/react-label/-/react-label-2.1.7.tgz", + "integrity": "sha512-YT1GqPSL8kJn20djelMX7/cTRp/Y9w5IZHvfxQTVHrOqa2yMl7i/UfMqKRU5V7mEyKTrUVgJXhNQPVCG8PBLoQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-primitive": "2.1.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-menu": { + "version": "2.1.16", + "resolved": "https://registry.npmjs.org/@radix-ui/react-menu/-/react-menu-2.1.16.tgz", + "integrity": "sha512-72F2T+PLlphrqLcAotYPp0uJMr5SjP5SL01wfEspJbru5Zs5vQaSHb4VB3ZMJPimgHHCHG7gMOeOB9H3Hdmtxg==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-collection": "1.1.7", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-direction": "1.1.1", + "@radix-ui/react-dismissable-layer": "1.1.11", + "@radix-ui/react-focus-guards": "1.1.3", + "@radix-ui/react-focus-scope": "1.1.7", + "@radix-ui/react-id": "1.1.1", + "@radix-ui/react-popper": "1.2.8", + "@radix-ui/react-portal": "1.1.9", + "@radix-ui/react-presence": "1.1.5", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-roving-focus": "1.1.11", + "@radix-ui/react-slot": "1.2.3", + "@radix-ui/react-use-callback-ref": "1.1.1", + "aria-hidden": "^1.2.4", + "react-remove-scroll": "^2.6.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-menubar": { + "version": "1.1.16", + "resolved": "https://registry.npmjs.org/@radix-ui/react-menubar/-/react-menubar-1.1.16.tgz", + "integrity": "sha512-EB1FktTz5xRRi2Er974AUQZWg2yVBb1yjip38/lgwtCVRd3a+maUoGHN/xs9Yv8SY8QwbSEb+YrxGadVWbEutA==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-collection": "1.1.7", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-direction": "1.1.1", + "@radix-ui/react-id": "1.1.1", + "@radix-ui/react-menu": "2.1.16", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-roving-focus": "1.1.11", + "@radix-ui/react-use-controllable-state": "1.2.2" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-navigation-menu": { + "version": "1.2.14", + "resolved": "https://registry.npmjs.org/@radix-ui/react-navigation-menu/-/react-navigation-menu-1.2.14.tgz", + "integrity": "sha512-YB9mTFQvCOAQMHU+C/jVl96WmuWeltyUEpRJJky51huhds5W2FQr1J8D/16sQlf0ozxkPK8uF3niQMdUwZPv5w==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-collection": "1.1.7", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-direction": "1.1.1", + "@radix-ui/react-dismissable-layer": "1.1.11", + "@radix-ui/react-id": "1.1.1", + "@radix-ui/react-presence": "1.1.5", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-callback-ref": "1.1.1", + "@radix-ui/react-use-controllable-state": "1.2.2", + "@radix-ui/react-use-layout-effect": "1.1.1", + "@radix-ui/react-use-previous": "1.1.1", + "@radix-ui/react-visually-hidden": "1.2.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-popover": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/@radix-ui/react-popover/-/react-popover-1.1.15.tgz", + "integrity": "sha512-kr0X2+6Yy/vJzLYJUPCZEc8SfQcf+1COFoAqauJm74umQhta9M7lNJHP7QQS3vkvcGLQUbWpMzwrXYwrYztHKA==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-dismissable-layer": "1.1.11", + "@radix-ui/react-focus-guards": "1.1.3", + "@radix-ui/react-focus-scope": "1.1.7", + "@radix-ui/react-id": "1.1.1", + "@radix-ui/react-popper": "1.2.8", + "@radix-ui/react-portal": "1.1.9", + "@radix-ui/react-presence": "1.1.5", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-slot": "1.2.3", + "@radix-ui/react-use-controllable-state": "1.2.2", + "aria-hidden": "^1.2.4", + "react-remove-scroll": "^2.6.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-popper": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.2.8.tgz", + "integrity": "sha512-0NJQ4LFFUuWkE7Oxf0htBKS6zLkkjBH+hM1uk7Ng705ReR8m/uelduy1DBo0PyBXPKVnBA6YBlU94MBGXrSBCw==", + "license": "MIT", + "dependencies": { + "@floating-ui/react-dom": "^2.0.0", + "@radix-ui/react-arrow": "1.1.7", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-callback-ref": "1.1.1", + "@radix-ui/react-use-layout-effect": "1.1.1", + "@radix-ui/react-use-rect": "1.1.1", + "@radix-ui/react-use-size": "1.1.1", + "@radix-ui/rect": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-portal": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.1.9.tgz", + "integrity": "sha512-bpIxvq03if6UNwXZ+HTK71JLh4APvnXntDc6XOX8UVq4XQOVl7lwok0AvIl+b8zgCw3fSaVTZMpAPPagXbKmHQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-layout-effect": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-presence": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.5.tgz", + "integrity": "sha512-/jfEwNDdQVBCNvjkGit4h6pMOzq8bHkopq458dPt2lMjx+eBQUohZNG9A7DtO/O5ukSbxuaNGXMjHicgwy6rQQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-use-layout-effect": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-primitive": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz", + "integrity": "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-slot": "1.2.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-progress": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/@radix-ui/react-progress/-/react-progress-1.1.7.tgz", + "integrity": "sha512-vPdg/tF6YC/ynuBIJlk1mm7Le0VgW6ub6J2UWnTQ7/D23KXcPI1qy+0vBkgKgd38RCMJavBXpB83HPNFMTb0Fg==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-primitive": "2.1.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-radio-group": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/@radix-ui/react-radio-group/-/react-radio-group-1.3.8.tgz", + "integrity": "sha512-VBKYIYImA5zsxACdisNQ3BjCBfmbGH3kQlnFVqlWU4tXwjy7cGX8ta80BcrO+WJXIn5iBylEH3K6ZTlee//lgQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-direction": "1.1.1", + "@radix-ui/react-presence": "1.1.5", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-roving-focus": "1.1.11", + "@radix-ui/react-use-controllable-state": "1.2.2", + "@radix-ui/react-use-previous": "1.1.1", + "@radix-ui/react-use-size": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-roving-focus": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/@radix-ui/react-roving-focus/-/react-roving-focus-1.1.11.tgz", + "integrity": "sha512-7A6S9jSgm/S+7MdtNDSb+IU859vQqJ/QAtcYQcfFC6W8RS4IxIZDldLR0xqCFZ6DCyrQLjLPsxtTNch5jVA4lA==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-collection": "1.1.7", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-direction": "1.1.1", + "@radix-ui/react-id": "1.1.1", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-callback-ref": "1.1.1", + "@radix-ui/react-use-controllable-state": "1.2.2" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-scroll-area": { + "version": "1.2.10", + "resolved": "https://registry.npmjs.org/@radix-ui/react-scroll-area/-/react-scroll-area-1.2.10.tgz", + "integrity": "sha512-tAXIa1g3sM5CGpVT0uIbUx/U3Gs5N8T52IICuCtObaos1S8fzsrPXG5WObkQN3S6NVl6wKgPhAIiBGbWnvc97A==", + "license": "MIT", + "dependencies": { + "@radix-ui/number": "1.1.1", + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-direction": "1.1.1", + "@radix-ui/react-presence": "1.1.5", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-callback-ref": "1.1.1", + "@radix-ui/react-use-layout-effect": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-select": { + "version": "2.2.6", + "resolved": "https://registry.npmjs.org/@radix-ui/react-select/-/react-select-2.2.6.tgz", + "integrity": "sha512-I30RydO+bnn2PQztvo25tswPH+wFBjehVGtmagkU78yMdwTwVf12wnAOF+AeP8S2N8xD+5UPbGhkUfPyvT+mwQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/number": "1.1.1", + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-collection": "1.1.7", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-direction": "1.1.1", + "@radix-ui/react-dismissable-layer": "1.1.11", + "@radix-ui/react-focus-guards": "1.1.3", + "@radix-ui/react-focus-scope": "1.1.7", + "@radix-ui/react-id": "1.1.1", + "@radix-ui/react-popper": "1.2.8", + "@radix-ui/react-portal": "1.1.9", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-slot": "1.2.3", + "@radix-ui/react-use-callback-ref": "1.1.1", + "@radix-ui/react-use-controllable-state": "1.2.2", + "@radix-ui/react-use-layout-effect": "1.1.1", + "@radix-ui/react-use-previous": "1.1.1", + "@radix-ui/react-visually-hidden": "1.2.3", + "aria-hidden": "^1.2.4", + "react-remove-scroll": "^2.6.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-separator": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/@radix-ui/react-separator/-/react-separator-1.1.7.tgz", + "integrity": "sha512-0HEb8R9E8A+jZjvmFCy/J4xhbXy3TV+9XSnGJ3KvTtjlIUy/YQ/p6UYZvi7YbeoeXdyU9+Y3scizK6hkY37baA==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-primitive": "2.1.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-slider": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slider/-/react-slider-1.3.6.tgz", + "integrity": "sha512-JPYb1GuM1bxfjMRlNLE+BcmBC8onfCi60Blk7OBqi2MLTFdS+8401U4uFjnwkOr49BLmXxLC6JHkvAsx5OJvHw==", + "license": "MIT", + "dependencies": { + "@radix-ui/number": "1.1.1", + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-collection": "1.1.7", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-direction": "1.1.1", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-controllable-state": "1.2.2", + "@radix-ui/react-use-layout-effect": "1.1.1", + "@radix-ui/react-use-previous": "1.1.1", + "@radix-ui/react-use-size": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-slot": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", + "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-switch": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@radix-ui/react-switch/-/react-switch-1.2.6.tgz", + "integrity": "sha512-bByzr1+ep1zk4VubeEVViV592vu2lHE2BZY5OnzehZqOOgogN80+mNtCqPkhn2gklJqOpxWgPoYTSnhBCqpOXQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-controllable-state": "1.2.2", + "@radix-ui/react-use-previous": "1.1.1", + "@radix-ui/react-use-size": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-tabs": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/@radix-ui/react-tabs/-/react-tabs-1.1.13.tgz", + "integrity": "sha512-7xdcatg7/U+7+Udyoj2zodtI9H/IIopqo+YOIcZOq1nJwXWBZ9p8xiu5llXlekDbZkca79a/fozEYQXIA4sW6A==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-direction": "1.1.1", + "@radix-ui/react-id": "1.1.1", + "@radix-ui/react-presence": "1.1.5", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-roving-focus": "1.1.11", + "@radix-ui/react-use-controllable-state": "1.2.2" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-toggle": { + "version": "1.1.10", + "resolved": "https://registry.npmjs.org/@radix-ui/react-toggle/-/react-toggle-1.1.10.tgz", + "integrity": "sha512-lS1odchhFTeZv3xwHH31YPObmJn8gOg7Lq12inrr0+BH/l3Tsq32VfjqH1oh80ARM3mlkfMic15n0kg4sD1poQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-controllable-state": "1.2.2" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-toggle-group": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/@radix-ui/react-toggle-group/-/react-toggle-group-1.1.11.tgz", + "integrity": "sha512-5umnS0T8JQzQT6HbPyO7Hh9dgd82NmS36DQr+X/YJ9ctFNCiiQd6IJAYYZ33LUwm8M+taCz5t2ui29fHZc4Y6Q==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-direction": "1.1.1", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-roving-focus": "1.1.11", + "@radix-ui/react-toggle": "1.1.10", + "@radix-ui/react-use-controllable-state": "1.2.2" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-tooltip": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@radix-ui/react-tooltip/-/react-tooltip-1.2.8.tgz", + "integrity": "sha512-tY7sVt1yL9ozIxvmbtN5qtmH2krXcBCfjEiCgKGLqunJHvgvZG2Pcl2oQ3kbcZARb1BGEHdkLzcYGO8ynVlieg==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-dismissable-layer": "1.1.11", + "@radix-ui/react-id": "1.1.1", + "@radix-ui/react-popper": "1.2.8", + "@radix-ui/react-portal": "1.1.9", + "@radix-ui/react-presence": "1.1.5", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-slot": "1.2.3", + "@radix-ui/react-use-controllable-state": "1.2.2", + "@radix-ui/react-visually-hidden": "1.2.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-callback-ref": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.1.tgz", + "integrity": "sha512-FkBMwD+qbGQeMu1cOHnuGB6x4yzPjho8ap5WtbEJ26umhgqVXbhekKUQO+hZEL1vU92a3wHwdp0HAcqAUF5iDg==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-controllable-state": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.2.2.tgz", + "integrity": "sha512-BjasUjixPFdS+NKkypcyyN5Pmg83Olst0+c6vGov0diwTEo6mgdqVR6hxcEgFuh4QrAs7Rc+9KuGJ9TVCj0Zzg==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-use-effect-event": "0.0.2", + "@radix-ui/react-use-layout-effect": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-effect-event": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-effect-event/-/react-use-effect-event-0.0.2.tgz", + "integrity": "sha512-Qp8WbZOBe+blgpuUT+lw2xheLP8q0oatc9UpmiemEICxGvFLYmHm9QowVZGHtJlGbS6A6yJ3iViad/2cVjnOiA==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-use-layout-effect": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-escape-keydown": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.1.1.tgz", + "integrity": "sha512-Il0+boE7w/XebUHyBjroE+DbByORGR9KKmITzbR7MyQ4akpORYP/ZmbhAr0DG7RmmBqoOnZdy2QlvajJ2QA59g==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-use-callback-ref": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-is-hydrated": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-is-hydrated/-/react-use-is-hydrated-0.1.0.tgz", + "integrity": "sha512-U+UORVEq+cTnRIaostJv9AGdV3G6Y+zbVd+12e18jQ5A3c0xL03IhnHuiU4UV69wolOQp5GfR58NW/EgdQhwOA==", + "license": "MIT", + "dependencies": { + "use-sync-external-store": "^1.5.0" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-layout-effect": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.1.1.tgz", + "integrity": "sha512-RbJRS4UWQFkzHTTwVymMTUv8EqYhOp8dOOviLj2ugtTiXRaRQS7GLGxZTLL1jWhMeoSCf5zmcZkqTl9IiYfXcQ==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-previous": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-previous/-/react-use-previous-1.1.1.tgz", + "integrity": "sha512-2dHfToCj/pzca2Ck724OZ5L0EVrr3eHRNsG/b3xQJLA2hZpVCS99bLAX+hm1IHXDEnzU6by5z/5MIY794/a8NQ==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-rect": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-rect/-/react-use-rect-1.1.1.tgz", + "integrity": "sha512-QTYuDesS0VtuHNNvMh+CjlKJ4LJickCMUAqjlE3+j8w+RlRpwyX3apEQKGFzbZGdo7XNG1tXa+bQqIE7HIXT2w==", + "license": "MIT", + "dependencies": { + "@radix-ui/rect": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-size": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-size/-/react-use-size-1.1.1.tgz", + "integrity": "sha512-ewrXRDTAqAXlkl6t/fkXWNAhFX9I+CkKlw6zjEwk86RSPKwZr3xpBRso655aqYafwtnbpHLj6toFzmd6xdVptQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-use-layout-effect": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-visually-hidden": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-visually-hidden/-/react-visually-hidden-1.2.3.tgz", + "integrity": "sha512-pzJq12tEaaIhqjbzpCuv/OypJY/BPavOofm+dbab+MHLajy277+1lLm6JFcGgF5eskJ6mquGirhXY2GD/8u8Ug==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-primitive": "2.1.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/rect": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/rect/-/rect-1.1.1.tgz", + "integrity": "sha512-HPwpGIzkl28mWyZqG52jiqDJ12waP11Pa1lGoiyUkIEuMLBP0oeK/C89esbXrxsky5we7dfd8U58nm0SgAWpVw==", + "license": "MIT" + }, + "node_modules/@rolldown/pluginutils": { + "version": "1.0.0-beta.27", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.27.tgz", + "integrity": "sha512-+d0F4MKMCbeVUJwG96uQ4SgAznZNSq93I3V+9NHA4OpvqG8mRCpGdKmK8l/dl02h2CCDHwW2FqilnTyDcAnqjA==", + "dev": true, + "license": "MIT" + }, + "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", + "integrity": "sha512-BTm2qKNnWIQ5auf4deoetINJm2JzvihvGb9R6K/ETwKLql/Bb3Eg2H1FBp1gUb4YGbydMA3jcmQTR73q7J+GAA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.52.4.tgz", + "integrity": "sha512-P9LDQiC5vpgGFgz7GSM6dKPCiqR3XYN1WwJKA4/BUVDjHpYsf3iBEmVz62uyq20NGYbiGPR5cNHI7T1HqxNs2w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.52.4.tgz", + "integrity": "sha512-QRWSW+bVccAvZF6cbNZBJwAehmvG9NwfWHwMy4GbWi/BQIA/laTIktebT2ipVjNncqE6GLPxOok5hsECgAxGZg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.52.4.tgz", + "integrity": "sha512-hZgP05pResAkRJxL1b+7yxCnXPGsXU0fG9Yfd6dUaoGk+FhdPKCJ5L1Sumyxn8kvw8Qi5PvQ8ulenUbRjzeCTw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.52.4.tgz", + "integrity": "sha512-xmc30VshuBNUd58Xk4TKAEcRZHaXlV+tCxIXELiE9sQuK3kG8ZFgSPi57UBJt8/ogfhAF5Oz4ZSUBN77weM+mQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.52.4.tgz", + "integrity": "sha512-WdSLpZFjOEqNZGmHflxyifolwAiZmDQzuOzIq9L27ButpCVpD7KzTRtEG1I0wMPFyiyUdOO+4t8GvrnBLQSwpw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.52.4.tgz", + "integrity": "sha512-xRiOu9Of1FZ4SxVbB0iEDXc4ddIcjCv2aj03dmW8UrZIW7aIQ9jVJdLBIhxBI+MaTnGAKyvMwPwQnoOEvP7FgQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.52.4.tgz", + "integrity": "sha512-FbhM2p9TJAmEIEhIgzR4soUcsW49e9veAQCziwbR+XWB2zqJ12b4i/+hel9yLiD8pLncDH4fKIPIbt5238341Q==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.52.4.tgz", + "integrity": "sha512-4n4gVwhPHR9q/g8lKCyz0yuaD0MvDf7dV4f9tHt0C73Mp8h38UCtSCSE6R9iBlTbXlmA8CjpsZoujhszefqueg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.52.4.tgz", + "integrity": "sha512-u0n17nGA0nvi/11gcZKsjkLj1QIpAuPFQbR48Subo7SmZJnGxDpspyw2kbpuoQnyK+9pwf3pAoEXerJs/8Mi9g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-gnu": { + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.52.4.tgz", + "integrity": "sha512-0G2c2lpYtbTuXo8KEJkDkClE/+/2AFPdPAbmaHoE870foRFs4pBrDehilMcrSScrN/fB/1HTaWO4bqw+ewBzMQ==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-gnu": { + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.52.4.tgz", + "integrity": "sha512-teSACug1GyZHmPDv14VNbvZFX779UqWTsd7KtTM9JIZRDI5NUwYSIS30kzI8m06gOPB//jtpqlhmraQ68b5X2g==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.52.4.tgz", + "integrity": "sha512-/MOEW3aHjjs1p4Pw1Xk4+3egRevx8Ji9N6HUIA1Ifh8Q+cg9dremvFCUbOX2Zebz80BwJIgCBUemjqhU5XI5Eg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.52.4.tgz", + "integrity": "sha512-1HHmsRyh845QDpEWzOFtMCph5Ts+9+yllCrREuBR/vg2RogAQGGBRC8lDPrPOMnrdOJ+mt1WLMOC2Kao/UwcvA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.52.4.tgz", + "integrity": "sha512-seoeZp4L/6D1MUyjWkOMRU6/iLmCU2EjbMTyAG4oIOs1/I82Y5lTeaxW0KBfkUdHAWN7j25bpkt0rjnOgAcQcA==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.52.4.tgz", + "integrity": "sha512-Wi6AXf0k0L7E2gteNsNHUs7UMwCIhsCTs6+tqQ5GPwVRWMaflqGec4Sd8n6+FNFDw9vGcReqk2KzBDhCa1DLYg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.52.4.tgz", + "integrity": "sha512-dtBZYjDmCQ9hW+WgEkaffvRRCKm767wWhxsFW3Lw86VXz/uJRuD438/XvbZT//B96Vs8oTA8Q4A0AfHbrxP9zw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-openharmony-arm64": { + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.52.4.tgz", + "integrity": "sha512-1ox+GqgRWqaB1RnyZXL8PD6E5f7YyRUJYnCqKpNzxzP0TkaUh112NDrR9Tt+C8rJ4x5G9Mk8PQR3o7Ku2RKqKA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.52.4.tgz", + "integrity": "sha512-8GKr640PdFNXwzIE0IrkMWUNUomILLkfeHjXBi/nUvFlpZP+FA8BKGKpacjW6OUUHaNI6sUURxR2U2g78FOHWQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.52.4.tgz", + "integrity": "sha512-AIy/jdJ7WtJ/F6EcfOb2GjR9UweO0n43jNObQMb6oGxkYTfLcnN7vYYpG+CN3lLxrQkzWnMOoNSHTW54pgbVxw==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-gnu": { + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.52.4.tgz", + "integrity": "sha512-UF9KfsH9yEam0UjTwAgdK0anlQ7c8/pWPU2yVjyWcF1I1thABt6WXE47cI71pGiZ8wGvxohBoLnxM04L/wj8mQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.52.4.tgz", + "integrity": "sha512-bf9PtUa0u8IXDVxzRToFQKsNCRz9qLYfR/MpECxl4mRoWYjAeFjgxj1XdZr2M/GNVpT05p+LgQOHopYDlUu6/w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@swc/core": { + "version": "1.13.5", + "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.13.5.tgz", + "integrity": "sha512-WezcBo8a0Dg2rnR82zhwoR6aRNxeTGfK5QCD6TQ+kg3xx/zNT02s/0o+81h/3zhvFSB24NtqEr8FTw88O5W/JQ==", + "dev": true, + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "@swc/counter": "^0.1.3", + "@swc/types": "^0.1.24" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/swc" + }, + "optionalDependencies": { + "@swc/core-darwin-arm64": "1.13.5", + "@swc/core-darwin-x64": "1.13.5", + "@swc/core-linux-arm-gnueabihf": "1.13.5", + "@swc/core-linux-arm64-gnu": "1.13.5", + "@swc/core-linux-arm64-musl": "1.13.5", + "@swc/core-linux-x64-gnu": "1.13.5", + "@swc/core-linux-x64-musl": "1.13.5", + "@swc/core-win32-arm64-msvc": "1.13.5", + "@swc/core-win32-ia32-msvc": "1.13.5", + "@swc/core-win32-x64-msvc": "1.13.5" + }, + "peerDependencies": { + "@swc/helpers": ">=0.5.17" + }, + "peerDependenciesMeta": { + "@swc/helpers": { + "optional": true + } + } + }, + "node_modules/@swc/core-darwin-arm64": { + "version": "1.13.5", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.13.5.tgz", + "integrity": "sha512-lKNv7SujeXvKn16gvQqUQI5DdyY8v7xcoO3k06/FJbHJS90zEwZdQiMNRiqpYw/orU543tPaWgz7cIYWhbopiQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-darwin-x64": { + "version": "1.13.5", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.13.5.tgz", + "integrity": "sha512-ILd38Fg/w23vHb0yVjlWvQBoE37ZJTdlLHa8LRCFDdX4WKfnVBiblsCU9ar4QTMNdeTBEX9iUF4IrbNWhaF1Ng==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-arm-gnueabihf": { + "version": "1.13.5", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.13.5.tgz", + "integrity": "sha512-Q6eS3Pt8GLkXxqz9TAw+AUk9HpVJt8Uzm54MvPsqp2yuGmY0/sNaPPNVqctCX9fu/Nu8eaWUen0si6iEiCsazQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-arm64-gnu": { + "version": "1.13.5", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.13.5.tgz", + "integrity": "sha512-aNDfeN+9af+y+M2MYfxCzCy/VDq7Z5YIbMqRI739o8Ganz6ST+27kjQFd8Y/57JN/hcnUEa9xqdS3XY7WaVtSw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-arm64-musl": { + "version": "1.13.5", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.13.5.tgz", + "integrity": "sha512-9+ZxFN5GJag4CnYnq6apKTnnezpfJhCumyz0504/JbHLo+Ue+ZtJnf3RhyA9W9TINtLE0bC4hKpWi8ZKoETyOQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-x64-gnu": { + "version": "1.13.5", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.13.5.tgz", + "integrity": "sha512-WD530qvHrki8Ywt/PloKUjaRKgstQqNGvmZl54g06kA+hqtSE2FTG9gngXr3UJxYu/cNAjJYiBifm7+w4nbHbA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-x64-musl": { + "version": "1.13.5", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.13.5.tgz", + "integrity": "sha512-Luj8y4OFYx4DHNQTWjdIuKTq2f5k6uSXICqx+FSabnXptaOBAbJHNbHT/06JZh6NRUouaf0mYXN0mcsqvkhd7Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-win32-arm64-msvc": { + "version": "1.13.5", + "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.13.5.tgz", + "integrity": "sha512-cZ6UpumhF9SDJvv4DA2fo9WIzlNFuKSkZpZmPG1c+4PFSEMy5DFOjBSllCvnqihCabzXzpn6ykCwBmHpy31vQw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-win32-ia32-msvc": { + "version": "1.13.5", + "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.13.5.tgz", + "integrity": "sha512-C5Yi/xIikrFUzZcyGj9L3RpKljFvKiDMtyDzPKzlsDrKIw2EYY+bF88gB6oGY5RGmv4DAX8dbnpRAqgFD0FMEw==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-win32-x64-msvc": { + "version": "1.13.5", + "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.13.5.tgz", + "integrity": "sha512-YrKdMVxbYmlfybCSbRtrilc6UA8GF5aPmGKBdPvjrarvsmf4i7ZHGCEnLtfOMd3Lwbs2WUZq3WdMbozYeLU93Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/counter": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@swc/counter/-/counter-0.1.3.tgz", + "integrity": "sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/@swc/types": { + "version": "0.1.25", + "resolved": "https://registry.npmjs.org/@swc/types/-/types-0.1.25.tgz", + "integrity": "sha512-iAoY/qRhNH8a/hBvm3zKj9qQ4oc2+3w1unPJa2XvTK3XjeLXtzcCingVPw/9e5mn1+0yPqxcBGp9Jf0pkfMb1g==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@swc/counter": "^0.1.3" + } + }, + "node_modules/@tailwindcss/node": { + "version": "4.1.14", + "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.1.14.tgz", + "integrity": "sha512-hpz+8vFk3Ic2xssIA3e01R6jkmsAhvkQdXlEbRTk6S10xDAtiQiM3FyvZVGsucefq764euO/b8WUW9ysLdThHw==", + "license": "MIT", + "dependencies": { + "@jridgewell/remapping": "^2.3.4", + "enhanced-resolve": "^5.18.3", + "jiti": "^2.6.0", + "lightningcss": "1.30.1", + "magic-string": "^0.30.19", + "source-map-js": "^1.2.1", + "tailwindcss": "4.1.14" + } + }, + "node_modules/@tailwindcss/oxide": { + "version": "4.1.14", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.1.14.tgz", + "integrity": "sha512-23yx+VUbBwCg2x5XWdB8+1lkPajzLmALEfMb51zZUBYaYVPDQvBSD/WYDqiVyBIo2BZFa3yw1Rpy3G2Jp+K0dw==", + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "detect-libc": "^2.0.4", + "tar": "^7.5.1" + }, + "engines": { + "node": ">= 10" + }, + "optionalDependencies": { + "@tailwindcss/oxide-android-arm64": "4.1.14", + "@tailwindcss/oxide-darwin-arm64": "4.1.14", + "@tailwindcss/oxide-darwin-x64": "4.1.14", + "@tailwindcss/oxide-freebsd-x64": "4.1.14", + "@tailwindcss/oxide-linux-arm-gnueabihf": "4.1.14", + "@tailwindcss/oxide-linux-arm64-gnu": "4.1.14", + "@tailwindcss/oxide-linux-arm64-musl": "4.1.14", + "@tailwindcss/oxide-linux-x64-gnu": "4.1.14", + "@tailwindcss/oxide-linux-x64-musl": "4.1.14", + "@tailwindcss/oxide-wasm32-wasi": "4.1.14", + "@tailwindcss/oxide-win32-arm64-msvc": "4.1.14", + "@tailwindcss/oxide-win32-x64-msvc": "4.1.14" + } + }, + "node_modules/@tailwindcss/oxide-android-arm64": { + "version": "4.1.14", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.1.14.tgz", + "integrity": "sha512-a94ifZrGwMvbdeAxWoSuGcIl6/DOP5cdxagid7xJv6bwFp3oebp7y2ImYsnZBMTwjn5Ev5xESvS3FFYUGgPODQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-darwin-arm64": { + "version": "4.1.14", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.1.14.tgz", + "integrity": "sha512-HkFP/CqfSh09xCnrPJA7jud7hij5ahKyWomrC3oiO2U9i0UjP17o9pJbxUN0IJ471GTQQmzwhp0DEcpbp4MZTA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-darwin-x64": { + "version": "4.1.14", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.1.14.tgz", + "integrity": "sha512-eVNaWmCgdLf5iv6Qd3s7JI5SEFBFRtfm6W0mphJYXgvnDEAZ5sZzqmI06bK6xo0IErDHdTA5/t7d4eTfWbWOFw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-freebsd-x64": { + "version": "4.1.14", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.1.14.tgz", + "integrity": "sha512-QWLoRXNikEuqtNb0dhQN6wsSVVjX6dmUFzuuiL09ZeXju25dsei2uIPl71y2Ic6QbNBsB4scwBoFnlBfabHkEw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-linux-arm-gnueabihf": { + "version": "4.1.14", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.1.14.tgz", + "integrity": "sha512-VB4gjQni9+F0VCASU+L8zSIyjrLLsy03sjcR3bM0V2g4SNamo0FakZFKyUQ96ZVwGK4CaJsc9zd/obQy74o0Fw==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-linux-arm64-gnu": { + "version": "4.1.14", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.1.14.tgz", + "integrity": "sha512-qaEy0dIZ6d9vyLnmeg24yzA8XuEAD9WjpM5nIM1sUgQ/Zv7cVkharPDQcmm/t/TvXoKo/0knI3me3AGfdx6w1w==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-linux-arm64-musl": { + "version": "4.1.14", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.1.14.tgz", + "integrity": "sha512-ISZjT44s59O8xKsPEIesiIydMG/sCXoMBCqsphDm/WcbnuWLxxb+GcvSIIA5NjUw6F8Tex7s5/LM2yDy8RqYBQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-linux-x64-gnu": { + "version": "4.1.14", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.1.14.tgz", + "integrity": "sha512-02c6JhLPJj10L2caH4U0zF8Hji4dOeahmuMl23stk0MU1wfd1OraE7rOloidSF8W5JTHkFdVo/O7uRUJJnUAJg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-linux-x64-musl": { + "version": "4.1.14", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.1.14.tgz", + "integrity": "sha512-TNGeLiN1XS66kQhxHG/7wMeQDOoL0S33x9BgmydbrWAb9Qw0KYdd8o1ifx4HOGDWhVmJ+Ul+JQ7lyknQFilO3Q==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-wasm32-wasi": { + "version": "4.1.14", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.1.14.tgz", + "integrity": "sha512-uZYAsaW/jS/IYkd6EWPJKW/NlPNSkWkBlaeVBi/WsFQNP05/bzkebUL8FH1pdsqx4f2fH/bWFcUABOM9nfiJkQ==", + "bundleDependencies": [ + "@napi-rs/wasm-runtime", + "@emnapi/core", + "@emnapi/runtime", + "@tybys/wasm-util", + "@emnapi/wasi-threads", + "tslib" + ], + "cpu": [ + "wasm32" + ], + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/core": "^1.5.0", + "@emnapi/runtime": "^1.5.0", + "@emnapi/wasi-threads": "^1.1.0", + "@napi-rs/wasm-runtime": "^1.0.5", + "@tybys/wasm-util": "^0.10.1", + "tslib": "^2.4.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@tailwindcss/oxide-win32-arm64-msvc": { + "version": "4.1.14", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.1.14.tgz", + "integrity": "sha512-Az0RnnkcvRqsuoLH2Z4n3JfAef0wElgzHD5Aky/e+0tBUxUhIeIqFBTMNQvmMRSP15fWwmvjBxZ3Q8RhsDnxAA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-win32-x64-msvc": { + "version": "4.1.14", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.1.14.tgz", + "integrity": "sha512-ttblVGHgf68kEE4om1n/n44I0yGPkCPbLsqzjvybhpwa6mKKtgFfAzy6btc3HRmuW7nHe0OOrSeNP9sQmmH9XA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/postcss": { + "version": "4.1.14", + "resolved": "https://registry.npmjs.org/@tailwindcss/postcss/-/postcss-4.1.14.tgz", + "integrity": "sha512-BdMjIxy7HUNThK87C7BC8I1rE8BVUsfNQSI5siQ4JK3iIa3w0XyVvVL9SXLWO//CtYTcp1v7zci0fYwJOjB+Zg==", + "license": "MIT", + "dependencies": { + "@alloc/quick-lru": "^5.2.0", + "@tailwindcss/node": "4.1.14", + "@tailwindcss/oxide": "4.1.14", + "postcss": "^8.4.41", + "tailwindcss": "4.1.14" + } + }, + "node_modules/@types/d3-array": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/@types/d3-array/-/d3-array-3.2.2.tgz", + "integrity": "sha512-hOLWVbm7uRza0BYXpIIW5pxfrKe0W+D5lrFiAEYR+pb6w3N2SwSMaJbXdUfSEv+dT4MfHBLtn5js0LAWaO6otw==", + "license": "MIT" + }, + "node_modules/@types/d3-color": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/@types/d3-color/-/d3-color-3.1.3.tgz", + "integrity": "sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A==", + "license": "MIT" + }, + "node_modules/@types/d3-ease": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/d3-ease/-/d3-ease-3.0.2.tgz", + "integrity": "sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA==", + "license": "MIT" + }, + "node_modules/@types/d3-interpolate": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-3.0.4.tgz", + "integrity": "sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA==", + "license": "MIT", + "dependencies": { + "@types/d3-color": "*" + } + }, + "node_modules/@types/d3-path": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@types/d3-path/-/d3-path-3.1.1.tgz", + "integrity": "sha512-VMZBYyQvbGmWyWVea0EHs/BwLgxc+MKi1zLDCONksozI4YJMcTt8ZEuIR4Sb1MMTE8MMW49v0IwI5+b7RmfWlg==", + "license": "MIT" + }, + "node_modules/@types/d3-scale": { + "version": "4.0.9", + "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-4.0.9.tgz", + "integrity": "sha512-dLmtwB8zkAeO/juAMfnV+sItKjlsw2lKdZVVy6LRr0cBmegxSABiLEpGVmSJJ8O08i4+sGR6qQtb6WtuwJdvVw==", + "license": "MIT", + "dependencies": { + "@types/d3-time": "*" + } + }, + "node_modules/@types/d3-shape": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-3.1.7.tgz", + "integrity": "sha512-VLvUQ33C+3J+8p+Daf+nYSOsjB4GXp19/S/aGo60m9h1v6XaxjiT82lKVWJCfzhtuZ3yD7i/TPeC/fuKLLOSmg==", + "license": "MIT", + "dependencies": { + "@types/d3-path": "*" + } + }, + "node_modules/@types/d3-time": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-3.0.4.tgz", + "integrity": "sha512-yuzZug1nkAAaBlBBikKZTgzCeA+k1uy4ZFwWANOfKw5z5LRhV0gNA7gNkKm7HoK+HRN0wX3EkxGk0fpbWhmB7g==", + "license": "MIT" + }, + "node_modules/@types/d3-timer": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/d3-timer/-/d3-timer-3.0.2.tgz", + "integrity": "sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw==", + "license": "MIT" + }, + "node_modules/@types/estree": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "20.19.21", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.21.tgz", + "integrity": "sha512-CsGG2P3I5y48RPMfprQGfy4JPRZ6csfC3ltBZSRItG3ngggmNY/qs2uZKp4p9VbrpqNNSMzUZNFZKzgOGnd/VA==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.21.0" + } + }, + "node_modules/@types/react": { + "version": "19.2.2", + "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.2.tgz", + "integrity": "sha512-6mDvHUFSjyT2B2yeNx2nUgMxh9LtOWvkhIU3uePn2I2oyNymUAX1NIsdgviM4CH+JSrp2D2hsMvJOkxY+0wNRA==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "csstype": "^3.0.2" + } + }, + "node_modules/@types/react-dom": { + "version": "19.2.2", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.2.2.tgz", + "integrity": "sha512-9KQPoO6mZCi7jcIStSnlOWn2nEF3mNmyr3rIAsGnAbQKYbRLyqmeSc39EVgtxXVia+LMT8j3knZLAZAh+xLmrw==", + "devOptional": true, + "license": "MIT", + "peerDependencies": { + "@types/react": "^19.2.0" + } + }, + "node_modules/@vitejs/plugin-react-swc": { + "version": "3.11.0", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-react-swc/-/plugin-react-swc-3.11.0.tgz", + "integrity": "sha512-YTJCGFdNMHCMfjODYtxRNVAYmTWQ1Lb8PulP/2/f/oEEtglw8oKxKIZmmRkyXrVrHfsKOaVkAc3NT9/dMutO5w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@rolldown/pluginutils": "1.0.0-beta.27", + "@swc/core": "^1.12.11" + }, + "peerDependencies": { + "vite": "^4 || ^5 || ^6 || ^7" + } + }, + "node_modules/aria-hidden": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/aria-hidden/-/aria-hidden-1.2.6.tgz", + "integrity": "sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA==", + "license": "MIT", + "dependencies": { + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/chownr": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-3.0.0.tgz", + "integrity": "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==", + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=18" + } + }, + "node_modules/class-variance-authority": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/class-variance-authority/-/class-variance-authority-0.7.1.tgz", + "integrity": "sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg==", + "license": "Apache-2.0", + "dependencies": { + "clsx": "^2.1.1" + }, + "funding": { + "url": "https://polar.sh/cva" + } + }, + "node_modules/clsx": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", + "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/cmdk": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/cmdk/-/cmdk-1.1.1.tgz", + "integrity": "sha512-Vsv7kFaXm+ptHDMZ7izaRsP70GgrW9NBNGswt9OZaVBLlE0SNpDq8eu/VGXyF9r7M0azK3Wy7OlYXsuyYLFzHg==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "^1.1.1", + "@radix-ui/react-dialog": "^1.1.6", + "@radix-ui/react-id": "^1.1.0", + "@radix-ui/react-primitive": "^2.0.2" + }, + "peerDependencies": { + "react": "^18 || ^19 || ^19.0.0-rc", + "react-dom": "^18 || ^19 || ^19.0.0-rc" + } + }, + "node_modules/csstype": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", + "license": "MIT" + }, + "node_modules/d3-array": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-3.2.4.tgz", + "integrity": "sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==", + "license": "ISC", + "dependencies": { + "internmap": "1 - 2" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-color": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz", + "integrity": "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-ease": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.1.tgz", + "integrity": "sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-format": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-3.1.0.tgz", + "integrity": "sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-interpolate": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz", + "integrity": "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==", + "license": "ISC", + "dependencies": { + "d3-color": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-path": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-3.1.0.tgz", + "integrity": "sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-scale": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-4.0.2.tgz", + "integrity": "sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==", + "license": "ISC", + "dependencies": { + "d3-array": "2.10.0 - 3", + "d3-format": "1 - 3", + "d3-interpolate": "1.2.0 - 3", + "d3-time": "2.1.1 - 3", + "d3-time-format": "2 - 4" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-shape": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-3.2.0.tgz", + "integrity": "sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==", + "license": "ISC", + "dependencies": { + "d3-path": "^3.1.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-time": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-3.1.0.tgz", + "integrity": "sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==", + "license": "ISC", + "dependencies": { + "d3-array": "2 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-time-format": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-4.1.0.tgz", + "integrity": "sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==", + "license": "ISC", + "dependencies": { + "d3-time": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-timer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-3.0.1.tgz", + "integrity": "sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/date-fns": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-3.6.0.tgz", + "integrity": "sha512-fRHTG8g/Gif+kSh50gaGEdToemgfj74aRX3swtiouboip5JDLAyDE9F11nHMIcvOaXeOC6D7SpNhi7uFyB7Uww==", + "license": "MIT", + "peer": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/kossnocorp" + } + }, + "node_modules/decimal.js-light": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/decimal.js-light/-/decimal.js-light-2.5.1.tgz", + "integrity": "sha512-qIMFpTMZmny+MMIitAB6D7iVPEorVw6YQRWkvarTkT4tBeSLLiHzcwj6q0MmYSFCiVpiqPJTJEYIrpcPzVEIvg==", + "license": "MIT" + }, + "node_modules/detect-libc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", + "license": "Apache-2.0", + "engines": { + "node": ">=8" + } + }, + "node_modules/detect-node-es": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/detect-node-es/-/detect-node-es-1.1.0.tgz", + "integrity": "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==", + "license": "MIT" + }, + "node_modules/dom-helpers": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz", + "integrity": "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.8.7", + "csstype": "^3.0.2" + } + }, + "node_modules/embla-carousel": { + "version": "8.6.0", + "resolved": "https://registry.npmjs.org/embla-carousel/-/embla-carousel-8.6.0.tgz", + "integrity": "sha512-SjWyZBHJPbqxHOzckOfo8lHisEaJWmwd23XppYFYVh10bU66/Pn5tkVkbkCMZVdbUE5eTCI2nD8OyIP4Z+uwkA==", + "license": "MIT" + }, + "node_modules/embla-carousel-react": { + "version": "8.6.0", + "resolved": "https://registry.npmjs.org/embla-carousel-react/-/embla-carousel-react-8.6.0.tgz", + "integrity": "sha512-0/PjqU7geVmo6F734pmPqpyHqiM99olvyecY7zdweCw+6tKEXnrE90pBiBbMMU8s5tICemzpQ3hi5EpxzGW+JA==", + "license": "MIT", + "dependencies": { + "embla-carousel": "8.6.0", + "embla-carousel-reactive-utils": "8.6.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.1 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" + } + }, + "node_modules/embla-carousel-reactive-utils": { + "version": "8.6.0", + "resolved": "https://registry.npmjs.org/embla-carousel-reactive-utils/-/embla-carousel-reactive-utils-8.6.0.tgz", + "integrity": "sha512-fMVUDUEx0/uIEDM0Mz3dHznDhfX+znCCDCeIophYb1QGVM7YThSWX+wz11zlYwWFOr74b4QLGg0hrGPJeG2s4A==", + "license": "MIT", + "peerDependencies": { + "embla-carousel": "8.6.0" + } + }, + "node_modules/enhanced-resolve": { + "version": "5.18.3", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.3.tgz", + "integrity": "sha512-d4lC8xfavMeBjzGr2vECC3fsGXziXZQyJxD868h2M/mBI3PwAuODxAkLkq5HYuvrPYcUtiLzsTo8U3PgX3Ocww==", + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/esbuild": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.10.tgz", + "integrity": "sha512-9RiGKvCwaqxO2owP61uQ4BgNborAQskMR6QusfWzQqv7AZOg5oGehdY2pRJMTKuwxd1IDBP4rSbI5lHzU7SMsQ==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.25.10", + "@esbuild/android-arm": "0.25.10", + "@esbuild/android-arm64": "0.25.10", + "@esbuild/android-x64": "0.25.10", + "@esbuild/darwin-arm64": "0.25.10", + "@esbuild/darwin-x64": "0.25.10", + "@esbuild/freebsd-arm64": "0.25.10", + "@esbuild/freebsd-x64": "0.25.10", + "@esbuild/linux-arm": "0.25.10", + "@esbuild/linux-arm64": "0.25.10", + "@esbuild/linux-ia32": "0.25.10", + "@esbuild/linux-loong64": "0.25.10", + "@esbuild/linux-mips64el": "0.25.10", + "@esbuild/linux-ppc64": "0.25.10", + "@esbuild/linux-riscv64": "0.25.10", + "@esbuild/linux-s390x": "0.25.10", + "@esbuild/linux-x64": "0.25.10", + "@esbuild/netbsd-arm64": "0.25.10", + "@esbuild/netbsd-x64": "0.25.10", + "@esbuild/openbsd-arm64": "0.25.10", + "@esbuild/openbsd-x64": "0.25.10", + "@esbuild/openharmony-arm64": "0.25.10", + "@esbuild/sunos-x64": "0.25.10", + "@esbuild/win32-arm64": "0.25.10", + "@esbuild/win32-ia32": "0.25.10", + "@esbuild/win32-x64": "0.25.10" + } + }, + "node_modules/eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", + "license": "MIT" + }, + "node_modules/fast-equals": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/fast-equals/-/fast-equals-5.3.2.tgz", + "integrity": "sha512-6rxyATwPCkaFIL3JLqw8qXqMpIZ942pTX/tbQFkRsDGblS8tNGtlUauA/+mt6RUfqn/4MoEr+WDkYoIQbibWuQ==", + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/framer-motion": { + "version": "12.23.24", + "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-12.23.24.tgz", + "integrity": "sha512-HMi5HRoRCTou+3fb3h9oTLyJGBxHfW+HnNE25tAXOvVx/IvwMHK0cx7IR4a2ZU6sh3IX1Z+4ts32PcYBOqka8w==", + "license": "MIT", + "dependencies": { + "motion-dom": "^12.23.23", + "motion-utils": "^12.23.6", + "tslib": "^2.4.0" + }, + "peerDependencies": { + "@emotion/is-prop-valid": "*", + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@emotion/is-prop-valid": { + "optional": true + }, + "react": { + "optional": true + }, + "react-dom": { + "optional": true + } + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/get-nonce": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-nonce/-/get-nonce-1.0.1.tgz", + "integrity": "sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "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==", + "license": "ISC" + }, + "node_modules/input-otp": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/input-otp/-/input-otp-1.4.2.tgz", + "integrity": "sha512-l3jWwYNvrEa6NTCt7BECfCm48GvwuZzkoeG3gBL2w4CHeOXW3eKFmf9UNYkNfYc3mxMrthMnxjIE07MT0zLBQA==", + "license": "MIT", + "peerDependencies": { + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0.0 || ^19.0.0-rc" + } + }, + "node_modules/internmap": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/internmap/-/internmap-2.0.3.tgz", + "integrity": "sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/jiti": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.6.1.tgz", + "integrity": "sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==", + "license": "MIT", + "bin": { + "jiti": "lib/jiti-cli.mjs" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "license": "MIT" + }, + "node_modules/lightningcss": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.30.1.tgz", + "integrity": "sha512-xi6IyHML+c9+Q3W0S4fCQJOym42pyurFiJUHEcEyHS0CeKzia4yZDEsLlqOFykxOdHpNy0NmvVO31vcSqAxJCg==", + "license": "MPL-2.0", + "dependencies": { + "detect-libc": "^2.0.3" + }, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "lightningcss-darwin-arm64": "1.30.1", + "lightningcss-darwin-x64": "1.30.1", + "lightningcss-freebsd-x64": "1.30.1", + "lightningcss-linux-arm-gnueabihf": "1.30.1", + "lightningcss-linux-arm64-gnu": "1.30.1", + "lightningcss-linux-arm64-musl": "1.30.1", + "lightningcss-linux-x64-gnu": "1.30.1", + "lightningcss-linux-x64-musl": "1.30.1", + "lightningcss-win32-arm64-msvc": "1.30.1", + "lightningcss-win32-x64-msvc": "1.30.1" + } + }, + "node_modules/lightningcss-darwin-arm64": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.30.1.tgz", + "integrity": "sha512-c8JK7hyE65X1MHMN+Viq9n11RRC7hgin3HhYKhrMyaXflk5GVplZ60IxyoVtzILeKr+xAJwg6zK6sjTBJ0FKYQ==", + "cpu": [ + "arm64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-x64": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.30.1.tgz", + "integrity": "sha512-k1EvjakfumAQoTfcXUcHQZhSpLlkAuEkdMBsI/ivWw9hL+7FtilQc0Cy3hrx0AAQrVtQAbMI7YjCgYgvn37PzA==", + "cpu": [ + "x64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-freebsd-x64": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.30.1.tgz", + "integrity": "sha512-kmW6UGCGg2PcyUE59K5r0kWfKPAVy4SltVeut+umLCFoJ53RdCUWxcRDzO1eTaxf/7Q2H7LTquFHPL5R+Gjyig==", + "cpu": [ + "x64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm-gnueabihf": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.30.1.tgz", + "integrity": "sha512-MjxUShl1v8pit+6D/zSPq9S9dQ2NPFSQwGvxBCYaBYLPlCWuPh9/t1MRS8iUaR8i+a6w7aps+B4N0S1TYP/R+Q==", + "cpu": [ + "arm" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-gnu": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.30.1.tgz", + "integrity": "sha512-gB72maP8rmrKsnKYy8XUuXi/4OctJiuQjcuqWNlJQ6jZiWqtPvqFziskH3hnajfvKB27ynbVCucKSm2rkQp4Bw==", + "cpu": [ + "arm64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-musl": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.30.1.tgz", + "integrity": "sha512-jmUQVx4331m6LIX+0wUhBbmMX7TCfjF5FoOH6SD1CttzuYlGNVpA7QnrmLxrsub43ClTINfGSYyHe2HWeLl5CQ==", + "cpu": [ + "arm64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-gnu": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.30.1.tgz", + "integrity": "sha512-piWx3z4wN8J8z3+O5kO74+yr6ze/dKmPnI7vLqfSqI8bccaTGY5xiSGVIJBDd5K5BHlvVLpUB3S2YCfelyJ1bw==", + "cpu": [ + "x64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-musl": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.30.1.tgz", + "integrity": "sha512-rRomAK7eIkL+tHY0YPxbc5Dra2gXlI63HL+v1Pdi1a3sC+tJTcFrHX+E86sulgAXeI7rSzDYhPSeHHjqFhqfeQ==", + "cpu": [ + "x64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-arm64-msvc": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.30.1.tgz", + "integrity": "sha512-mSL4rqPi4iXq5YVqzSsJgMVFENoa4nGTT/GjO2c0Yl9OuQfPsIfncvLrEW6RbbB24WtZ3xP/2CCmI3tNkNV4oA==", + "cpu": [ + "arm64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-x64-msvc": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.30.1.tgz", + "integrity": "sha512-PVqXh48wh4T53F/1CCu8PIPCxLzWyCnn/9T5W1Jpmdy5h9Cwd+0YQS6/LwhHXSafuc61/xg9Lv5OrCby6a++jg==", + "cpu": [ + "x64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "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==", + "license": "MIT", + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, + "node_modules/lucide-react": { + "version": "0.487.0", + "resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-0.487.0.tgz", + "integrity": "sha512-aKqhOQ+YmFnwq8dWgGjOuLc8V1R9/c/yOd+zDY4+ohsR2Jo05lSGc3WsstYPIzcTpeosN7LoCkLReUUITvaIvw==", + "license": "ISC", + "peerDependencies": { + "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/magic-string": { + "version": "0.30.19", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.19.tgz", + "integrity": "sha512-2N21sPY9Ws53PZvsEpVtNuSW+ScYbQdp4b9qUaL+9QkHUrGFKo56Lg9Emg5s9V/qrtNBmiR01sYhUOwu3H+VOw==", + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.5" + } + }, + "node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/minizlib": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-3.1.0.tgz", + "integrity": "sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw==", + "license": "MIT", + "dependencies": { + "minipass": "^7.1.2" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/motion": { + "version": "12.23.24", + "resolved": "https://registry.npmjs.org/motion/-/motion-12.23.24.tgz", + "integrity": "sha512-Rc5E7oe2YZ72N//S3QXGzbnXgqNrTESv8KKxABR20q2FLch9gHLo0JLyYo2hZ238bZ9Gx6cWhj9VO0IgwbMjCw==", + "license": "MIT", + "dependencies": { + "framer-motion": "^12.23.24", + "tslib": "^2.4.0" + }, + "peerDependencies": { + "@emotion/is-prop-valid": "*", + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@emotion/is-prop-valid": { + "optional": true + }, + "react": { + "optional": true + }, + "react-dom": { + "optional": true + } + } + }, + "node_modules/motion-dom": { + "version": "12.23.23", + "resolved": "https://registry.npmjs.org/motion-dom/-/motion-dom-12.23.23.tgz", + "integrity": "sha512-n5yolOs0TQQBRUFImrRfs/+6X4p3Q4n1dUEqt/H58Vx7OW6RF+foWEgmTVDhIWJIMXOuNNL0apKH2S16en9eiA==", + "license": "MIT", + "dependencies": { + "motion-utils": "^12.23.6" + } + }, + "node_modules/motion-utils": { + "version": "12.23.6", + "resolved": "https://registry.npmjs.org/motion-utils/-/motion-utils-12.23.6.tgz", + "integrity": "sha512-eAWoPgr4eFEOFfg2WjIsMoqJTW6Z8MTUCgn/GZ3VRpClWBdnbjryiA3ZSNLyxCTmCQx4RmYX6jX1iWHbenUPNQ==", + "license": "MIT" + }, + "node_modules/nanoid": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/next-themes": { + "version": "0.4.6", + "resolved": "https://registry.npmjs.org/next-themes/-/next-themes-0.4.6.tgz", + "integrity": "sha512-pZvgD5L0IEvX5/9GWyHMf3m8BKiVQwsCMHfoFosXtXBMnaS0ZnIJ9ST4b4NqLVKDEm8QBxoNNGNaBv2JNF6XNA==", + "license": "MIT", + "peerDependencies": { + "react": "^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/postcss": { + "version": "8.5.6", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", + "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.11", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/prop-types": { + "version": "15.8.1", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", + "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.1" + } + }, + "node_modules/prop-types/node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "license": "MIT" + }, + "node_modules/react": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", + "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-day-picker": { + "version": "8.10.1", + "resolved": "https://registry.npmjs.org/react-day-picker/-/react-day-picker-8.10.1.tgz", + "integrity": "sha512-TMx7fNbhLk15eqcMt+7Z7S2KF7mfTId/XJDjKE8f+IUcFn0l08/kI4FiYTL/0yuOLmEcbR4Fwe3GJf/NiiMnPA==", + "license": "MIT", + "funding": { + "type": "individual", + "url": "https://github.com/sponsors/gpbl" + }, + "peerDependencies": { + "date-fns": "^2.28.0 || ^3.0.0", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/react-dom": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", + "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.1.0", + "scheduler": "^0.23.2" + }, + "peerDependencies": { + "react": "^18.3.1" + } + }, + "node_modules/react-hook-form": { + "version": "7.65.0", + "resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.65.0.tgz", + "integrity": "sha512-xtOzDz063WcXvGWaHgLNrNzlsdFgtUWcb32E6WFaGTd7kPZG3EeDusjdZfUsPwKCKVXy1ZlntifaHZ4l8pAsmw==", + "license": "MIT", + "engines": { + "node": ">=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/react-hook-form" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17 || ^18 || ^19" + } + }, + "node_modules/react-is": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", + "license": "MIT" + }, + "node_modules/react-remove-scroll": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.7.1.tgz", + "integrity": "sha512-HpMh8+oahmIdOuS5aFKKY6Pyog+FNaZV/XyJOq7b4YFwsFHe5yYfdbIalI4k3vU2nSDql7YskmUseHsRrJqIPA==", + "license": "MIT", + "dependencies": { + "react-remove-scroll-bar": "^2.3.7", + "react-style-singleton": "^2.2.3", + "tslib": "^2.1.0", + "use-callback-ref": "^1.3.3", + "use-sidecar": "^1.1.3" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/react-remove-scroll-bar": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/react-remove-scroll-bar/-/react-remove-scroll-bar-2.3.8.tgz", + "integrity": "sha512-9r+yi9+mgU33AKcj6IbT9oRCO78WriSj6t/cF8DWBZJ9aOGPOTEDvdUDz1FwKim7QXWwmHqtdHnRJfhAxEG46Q==", + "license": "MIT", + "dependencies": { + "react-style-singleton": "^2.2.2", + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/react-resizable-panels": { + "version": "2.1.9", + "resolved": "https://registry.npmjs.org/react-resizable-panels/-/react-resizable-panels-2.1.9.tgz", + "integrity": "sha512-z77+X08YDIrgAes4jl8xhnUu1LNIRp4+E7cv4xHmLOxxUPO/ML7PSrE813b90vj7xvQ1lcf7g2uA9GeMZonjhQ==", + "license": "MIT", + "peerDependencies": { + "react": "^16.14.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc", + "react-dom": "^16.14.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" + } + }, + "node_modules/react-smooth": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/react-smooth/-/react-smooth-4.0.4.tgz", + "integrity": "sha512-gnGKTpYwqL0Iii09gHobNolvX4Kiq4PKx6eWBCYYix+8cdw+cGo3do906l1NBPKkSWx1DghC1dlWG9L2uGd61Q==", + "license": "MIT", + "dependencies": { + "fast-equals": "^5.0.1", + "prop-types": "^15.8.1", + "react-transition-group": "^4.4.5" + }, + "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" + } + }, + "node_modules/react-style-singleton": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/react-style-singleton/-/react-style-singleton-2.2.3.tgz", + "integrity": "sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ==", + "license": "MIT", + "dependencies": { + "get-nonce": "^1.0.0", + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/react-transition-group": { + "version": "4.4.5", + "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz", + "integrity": "sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==", + "license": "BSD-3-Clause", + "dependencies": { + "@babel/runtime": "^7.5.5", + "dom-helpers": "^5.0.1", + "loose-envify": "^1.4.0", + "prop-types": "^15.6.2" + }, + "peerDependencies": { + "react": ">=16.6.0", + "react-dom": ">=16.6.0" + } + }, + "node_modules/recharts": { + "version": "2.15.4", + "resolved": "https://registry.npmjs.org/recharts/-/recharts-2.15.4.tgz", + "integrity": "sha512-UT/q6fwS3c1dHbXv2uFgYJ9BMFHu3fwnd7AYZaEQhXuYQ4hgsxLvsUXzGdKeZrW5xopzDCvuA2N41WJ88I7zIw==", + "license": "MIT", + "dependencies": { + "clsx": "^2.0.0", + "eventemitter3": "^4.0.1", + "lodash": "^4.17.21", + "react-is": "^18.3.1", + "react-smooth": "^4.0.4", + "recharts-scale": "^0.4.4", + "tiny-invariant": "^1.3.1", + "victory-vendor": "^36.6.8" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "react": "^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/recharts-scale": { + "version": "0.4.5", + "resolved": "https://registry.npmjs.org/recharts-scale/-/recharts-scale-0.4.5.tgz", + "integrity": "sha512-kivNFO+0OcUNu7jQquLXAxz1FIwZj8nrj+YkOKc5694NbjCvcT6aSZiIzNzd2Kul4o4rTto8QVR9lMNtxD4G1w==", + "license": "MIT", + "dependencies": { + "decimal.js-light": "^2.4.1" + } + }, + "node_modules/rollup": { + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.52.4.tgz", + "integrity": "sha512-CLEVl+MnPAiKh5pl4dEWSyMTpuflgNQiLGhMv8ezD5W/qP8AKvmYpCOKRRNOh7oRKnauBZ4SyeYkMS+1VSyKwQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "1.0.8" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.52.4", + "@rollup/rollup-android-arm64": "4.52.4", + "@rollup/rollup-darwin-arm64": "4.52.4", + "@rollup/rollup-darwin-x64": "4.52.4", + "@rollup/rollup-freebsd-arm64": "4.52.4", + "@rollup/rollup-freebsd-x64": "4.52.4", + "@rollup/rollup-linux-arm-gnueabihf": "4.52.4", + "@rollup/rollup-linux-arm-musleabihf": "4.52.4", + "@rollup/rollup-linux-arm64-gnu": "4.52.4", + "@rollup/rollup-linux-arm64-musl": "4.52.4", + "@rollup/rollup-linux-loong64-gnu": "4.52.4", + "@rollup/rollup-linux-ppc64-gnu": "4.52.4", + "@rollup/rollup-linux-riscv64-gnu": "4.52.4", + "@rollup/rollup-linux-riscv64-musl": "4.52.4", + "@rollup/rollup-linux-s390x-gnu": "4.52.4", + "@rollup/rollup-linux-x64-gnu": "4.52.4", + "@rollup/rollup-linux-x64-musl": "4.52.4", + "@rollup/rollup-openharmony-arm64": "4.52.4", + "@rollup/rollup-win32-arm64-msvc": "4.52.4", + "@rollup/rollup-win32-ia32-msvc": "4.52.4", + "@rollup/rollup-win32-x64-gnu": "4.52.4", + "@rollup/rollup-win32-x64-msvc": "4.52.4", + "fsevents": "~2.3.2" + } + }, + "node_modules/scheduler": { + "version": "0.23.2", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz", + "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.1.0" + } + }, + "node_modules/sonner": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/sonner/-/sonner-2.0.7.tgz", + "integrity": "sha512-W6ZN4p58k8aDKA4XPcx2hpIQXBRAgyiWVkYhT7CvK6D3iAu7xjvVyhQHg2/iaKJZ1XVJ4r7XuwGL+WGEK37i9w==", + "license": "MIT", + "peerDependencies": { + "react": "^18.0.0 || ^19.0.0 || ^19.0.0-rc", + "react-dom": "^18.0.0 || ^19.0.0 || ^19.0.0-rc" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/tailwind-merge": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-3.3.1.tgz", + "integrity": "sha512-gBXpgUm/3rp1lMZZrM/w7D8GKqshif0zAymAhbCyIt8KMe+0v9DQ7cdYLR4FHH/cKpdTXb+A/tKKU3eolfsI+g==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/dcastil" + } + }, + "node_modules/tailwindcss": { + "version": "4.1.14", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.1.14.tgz", + "integrity": "sha512-b7pCxjGO98LnxVkKjaZSDeNuljC4ueKUddjENJOADtubtdo8llTaJy7HwBMeLNSSo2N5QIAgklslK1+Ir8r6CA==", + "license": "MIT" + }, + "node_modules/tapable": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.3.0.tgz", + "integrity": "sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==", + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/tar": { + "version": "7.5.1", + "resolved": "https://registry.npmjs.org/tar/-/tar-7.5.1.tgz", + "integrity": "sha512-nlGpxf+hv0v7GkWBK2V9spgactGOp0qvfWRxUMjqHyzrt3SgwE48DIv/FhqPHJYLHpgW1opq3nERbz5Anq7n1g==", + "license": "ISC", + "dependencies": { + "@isaacs/fs-minipass": "^4.0.0", + "chownr": "^3.0.0", + "minipass": "^7.1.2", + "minizlib": "^3.1.0", + "yallist": "^5.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "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==", + "license": "MIT" + }, + "node_modules/tinyglobby": { + "version": "0.2.15", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", + "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.3" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "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==", + "license": "0BSD" + }, + "node_modules/undici-types": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", + "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/use-callback-ref": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/use-callback-ref/-/use-callback-ref-1.3.3.tgz", + "integrity": "sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg==", + "license": "MIT", + "dependencies": { + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/use-sidecar": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/use-sidecar/-/use-sidecar-1.1.3.tgz", + "integrity": "sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ==", + "license": "MIT", + "dependencies": { + "detect-node-es": "^1.1.0", + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/use-sync-external-store": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.6.0.tgz", + "integrity": "sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w==", + "license": "MIT", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/vaul": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vaul/-/vaul-1.1.2.tgz", + "integrity": "sha512-ZFkClGpWyI2WUQjdLJ/BaGuV6AVQiJ3uELGk3OYtP+B6yCO7Cmn9vPFXVJkRaGkOJu3m8bQMgtyzNHixULceQA==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-dialog": "^1.1.1" + }, + "peerDependencies": { + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0.0 || ^19.0.0-rc" + } + }, + "node_modules/victory-vendor": { + "version": "36.9.2", + "resolved": "https://registry.npmjs.org/victory-vendor/-/victory-vendor-36.9.2.tgz", + "integrity": "sha512-PnpQQMuxlwYdocC8fIJqVXvkeViHYzotI+NJrCuav0ZYFoq912ZHBk3mCeuj+5/VpodOjPe1z0Fk2ihgzlXqjQ==", + "license": "MIT AND ISC", + "dependencies": { + "@types/d3-array": "^3.0.3", + "@types/d3-ease": "^3.0.0", + "@types/d3-interpolate": "^3.0.1", + "@types/d3-scale": "^4.0.2", + "@types/d3-shape": "^3.1.0", + "@types/d3-time": "^3.0.0", + "@types/d3-timer": "^3.0.0", + "d3-array": "^3.1.6", + "d3-ease": "^3.0.1", + "d3-interpolate": "^3.0.1", + "d3-scale": "^4.0.2", + "d3-shape": "^3.1.0", + "d3-time": "^3.0.0", + "d3-timer": "^3.0.1" + } + }, + "node_modules/vite": { + "version": "6.3.5", + "resolved": "https://registry.npmjs.org/vite/-/vite-6.3.5.tgz", + "integrity": "sha512-cZn6NDFE7wdTpINgs++ZJ4N49W2vRp8LCKrn3Ob1kYNtOo21vfDoaV5GzBfLU4MovSAB8uNRm4jgzVQZ+mBzPQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "^0.25.0", + "fdir": "^6.4.4", + "picomatch": "^4.0.2", + "postcss": "^8.5.3", + "rollup": "^4.34.9", + "tinyglobby": "^0.2.13" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || ^20.0.0 || >=22.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", + "jiti": ">=1.21.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "sass-embedded": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "jiti": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + }, + "node_modules/yallist": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-5.0.0.tgz", + "integrity": "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==", + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=18" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..4be01ca --- /dev/null +++ b/package.json @@ -0,0 +1,65 @@ +{ + "name": "Access Hub Homepage Design", + "version": "0.1.0", + "private": true, + "dependencies": { + "@radix-ui/react-accordion": "^1.2.3", + "@radix-ui/react-alert-dialog": "^1.1.6", + "@radix-ui/react-aspect-ratio": "^1.1.2", + "@radix-ui/react-avatar": "^1.1.3", + "@radix-ui/react-checkbox": "^1.1.4", + "@radix-ui/react-collapsible": "^1.1.3", + "@radix-ui/react-context-menu": "^2.2.6", + "@radix-ui/react-dialog": "^1.1.6", + "@radix-ui/react-dropdown-menu": "^2.1.6", + "@radix-ui/react-hover-card": "^1.1.6", + "@radix-ui/react-label": "^2.1.2", + "@radix-ui/react-menubar": "^1.1.6", + "@radix-ui/react-navigation-menu": "^1.2.5", + "@radix-ui/react-popover": "^1.1.6", + "@radix-ui/react-progress": "^1.1.2", + "@radix-ui/react-radio-group": "^1.2.3", + "@radix-ui/react-scroll-area": "^1.2.3", + "@radix-ui/react-select": "^2.1.6", + "@radix-ui/react-separator": "^1.1.2", + "@radix-ui/react-slider": "^1.2.3", + "@radix-ui/react-slot": "^1.1.2", + "@radix-ui/react-switch": "^1.1.3", + "@radix-ui/react-tabs": "^1.1.3", + "@radix-ui/react-toggle": "^1.1.2", + "@radix-ui/react-toggle-group": "^1.1.2", + "@radix-ui/react-tooltip": "^1.1.8", + "@radix-ui/react-visually-hidden": "^1.1.1", + "@tailwindcss/postcss": "^4.1.14", + "class-variance-authority": "^0.7.1", + "clsx": "*", + "cmdk": "^1.1.1", + "embla-carousel-react": "^8.6.0", + "input-otp": "^1.4.2", + "lucide-react": "^0.487.0", + "motion": "*", + "next-themes": "^0.4.6", + "postcss": "^8.5.6", + "react": "^18.3.1", + "react-day-picker": "^8.10.1", + "react-dom": "^18.3.1", + "react-hook-form": "^7.55.0", + "react-resizable-panels": "^2.1.7", + "recharts": "^2.15.2", + "sonner": "^2.0.3", + "tailwind-merge": "*", + "tailwindcss": "^4.1.14", + "vaul": "^1.1.2" + }, + "devDependencies": { + "@types/node": "^20.10.0", + "@types/react": "^19.2.2", + "@types/react-dom": "^19.2.2", + "@vitejs/plugin-react-swc": "^3.10.2", + "vite": "6.3.5" + }, + "scripts": { + "dev": "vite", + "build": "vite build" + } +} diff --git a/postcss.config.mjs b/postcss.config.mjs new file mode 100644 index 0000000..b776c62 --- /dev/null +++ b/postcss.config.mjs @@ -0,0 +1,5 @@ +export default { + plugins: { + "@tailwindcss/postcss": {}, + } +} \ No newline at end of file diff --git a/src/AdminApp.tsx b/src/AdminApp.tsx new file mode 100644 index 0000000..1c20b56 --- /dev/null +++ b/src/AdminApp.tsx @@ -0,0 +1,54 @@ +import { useState, useEffect } from "react"; +import { AdminShell } from "./components/admin/AdminShell"; +import { OverviewPage } from "./components/admin/pages/OverviewPage"; +import { UsersRetailersPage } from "./components/admin/pages/UsersRetailersPage"; +import { UsersManufacturersPage } from "./components/admin/pages/UsersManufacturersPage"; +import { UsersPage } from "./components/admin/pages/UsersPage"; +import { ContentPage } from "./components/admin/pages/ContentPage"; +import { AnalyticsPage } from "./components/admin/pages/AnalyticsPage"; +import { SettingsPage } from "./components/admin/pages/SettingsPage"; +import { Toaster } from "./components/ui/sonner"; + +export default function AdminApp() { + const [currentPage, setCurrentPage] = useState("overview"); + const [theme, setTheme] = useState<"light" | "dark">("light"); + + useEffect(() => { + const root = document.documentElement; + if (theme === "dark") { + root.classList.add("dark"); + } else { + root.classList.remove("dark"); + } + }, [theme]); + + const renderPage = () => { + switch (currentPage) { + case "overview": + return ; + case "users-retailers": + return ; + case "users-manufacturers": + return ; + case "users-customers": + return ; + case "content": + return ; + case "analytics": + return ; + case "settings": + return ; + default: + return ; + } + }; + + return ( + <> + + + {renderPage()} + + + ); +} diff --git a/src/App.tsx b/src/App.tsx new file mode 100644 index 0000000..b957933 --- /dev/null +++ b/src/App.tsx @@ -0,0 +1,439 @@ +import { useState, useEffect, Suspense, lazy } from "react"; +import { + Shield, + ShoppingBag, + Store, + Factory, + HelpCircle, + ArrowRight, + Moon, + Sun, + Globe, + Sparkles, + Users, + Award, + Gem, +} from "lucide-react"; +import { PortalTile } from "./components/PortalTile"; +import { PortalOverlay } from "./components/PortalOverlay"; +import { HelpOverlay } from "./components/HelpOverlay"; +import { Footer } from "./components/Footer"; +import { Button } from "./components/ui/button"; +import { Card } from "./components/ui/card"; +import { Toaster } from "./components/ui/sonner"; +import { + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue, +} from "./components/ui/select"; + +const AdminApp = lazy(() => import("./AdminApp")); +const CustomerApp = lazy(() => import("./CustomerApp")); +const RetailerApp = lazy(() => import("./RetailerApp")); +const ManufacturerApp = lazy(() => import("./ManufacturerApp")); + +const PORTAL_DATA = { + admin: { + icon: Shield, + title: "Admin Console", + description: "Control tenants, roles, compliance, analytics.", + features: [ + "Manage user roles and permissions", + "Monitor platform analytics", + "Configure compliance settings", + ], + keyActions: [ + "Create and manage tenant organizations", + "Assign and revoke user permissions", + "View system-wide analytics and reports", + "Configure DPDP compliance settings", + ], + requiresLogin: false, + tenantScope: "Super Admin or Tenant Admin", + }, + customer: { + icon: ShoppingBag, + title: "Customer App", + description: "Browse collections, wishlist, chat, book appointments.", + features: [ + "Explore jewellery collections", + "Create wishlists and favorites", + "Book in-store appointments", + ], + keyActions: [ + "Browse curated jewellery catalogs", + "Save items to personal wishlist", + "Chat with retailers and designers", + "Schedule showroom visits", + ], + requiresLogin: false, + tenantScope: "Individual Customer", + }, + retailer: { + icon: Store, + title: "Retailers' Shop", + description: "Curate catalogues, publish virtual stores, manage CRM.", + features: [ + "Build and customize virtual store", + "Manage customer relationships", + "Track inventory and orders", + ], + keyActions: [ + "Create and publish product catalogs", + "Manage customer data and preferences", + "Process orders and track fulfillment", + "Generate sales reports", + ], + requiresLogin: false, + tenantScope: "Retailer Tenant", + }, + manufacturer: { + icon: Factory, + title: "Manufacturers' Shop", + description: "Sync inventory, share with retailers, handle custom orders.", + features: [ + "Synchronize production inventory", + "Share catalogs with retailers", + "Manage custom order requests", + ], + keyActions: [ + "Upload and sync inventory data", + "Share product listings with retail partners", + "Accept and process custom orders", + "Track production schedules", + ], + requiresLogin: false, + tenantScope: "Manufacturer Tenant", + }, +}; + +const TRANSLATIONS = { + en: { + hero_title: "Your Jewellery Ecosystem, One Hub", + hero_description: "A unified platform connecting admins, customers, retailers, and manufacturers in the jewellery industry. Streamline operations, enhance collaboration, and grow your business.", + get_started: "Get Started", + learn_more: "Learn More", + portals_title: "Specialized Portals for Every Role", + portals_description: "Each portal is designed specifically for its users, providing the exact tools and features needed for success", + cta_title: "Ready to Transform Your Jewellery Business?", + cta_description: "Join hundreds of businesses already using Hello Jewellers to streamline their operations and grow their sales", + get_started_today: "Get Started Today", + view_docs: "View Documentation", + }, + hi: { + hero_title: "आपका आभूषण इकोसिस्टम, एक हब", + hero_description: "आभूषण उद्योग में एडमिन, ग्राहकों, रिटेलर्स और निर्माताओं को जोड़ने वाला एक एकीकृत मंच। संचालन को सुव्यवस्थित करें, सहयोग बढ़ाएं और अपने व्यवसाय को बढ़ाएं।", + get_started: "शुरू करें", + learn_more: "और जानें", + portals_title: "हर भूमिका के लिए विशेष पोर्टल", + portals_description: "प्रत्येक पोर्टल विशेष रूप से अपने उपयोगकर्ताओं के लिए डिज़ाइन किया गया है", + cta_title: "अपने आभूषण व्यवसाय को बदलने के लिए तैयार हैं?", + cta_description: "सैकड़ों व्यवसाय पहले से ही हैलो ज्वेलर्स का उपयोग कर रहे हैं", + get_started_today: "आज ही शुरू करें", + view_docs: "दस्तावेज़ देखें", + }, + mr: { + hero_title: "तुमचा दागिना परिसंस्था, एक केंद्र", + hero_description: "दागिना उद्योगात प्रशासक, ग्राहक, किरकोळ विक्रेते आणि उत्पादकांना जोडणारे एकीकृत व्यासपीठ. ऑपरेशन सुव्यवस्थित करा, सहयोग वाढवा आणि आपला व्यवसाय वाढवा।", + get_started: "सुरू करा", + learn_more: "अधिक जाणून घ्या", + portals_title: "प्रत्येक भूमिकेसाठी विशेष पोर्टल", + portals_description: "प्रत्येक पोर्टल विशेषतः त्याच्या वापरकर्त्यांसाठी डिझाइन केलेले आहे", + cta_title: "आपला दागिना व्यवसाय बदलण्यास तयार आहात?", + cta_description: "शेकडो व्यवसाय आधीच हॅलो ज्वेलर्स वापरत आहेत", + get_started_today: "आज सुरू करा", + view_docs: "कागदपत्रे पहा", + }, + gu: { + hero_title: "તમારું દાગીના ઇકોસિસ્ટમ, એક હબ", + hero_description: "દાગીના ઉદ્યોગમાં એડમિન, ગ્રાહકો, રિટેલર્સ અને ઉત્પાદકોને જોડતું એકીકૃત પ્લેટફોર્મ. કામગીરીને સુવ્યવસ્થિત કરો, સહયોગ વધારો અને તમારા વ્યવસાયને વધારો.", + get_started: "પ્રારંભ કરો", + learn_more: "વધુ જાણો", + portals_title: "દરેક ભૂમિકા માટે વિશિષ્ટ પોર્ટલ", + portals_description: "દરેક પોર્ટલ ખાસ કરીને તેના વપરાશકર્તાઓ માટે ડિઝાઇન કરવામાં આવ્યું છે", + cta_title: "તમારા દાગીના વ્યવસાયને પરિવર્તિત કરવા તૈયાર છો?", + cta_description: "સેંકડો વ્યવસાયો પહેલેથી જ હેલો જ્વેલર્સનો ઉપયોગ કરી રહ્યા છે", + get_started_today: "આજે શરૂ કરો", + view_docs: "દસ્તાવેજો જુઓ", + }, +}; + +export default function App() { + const [theme, setTheme] = useState<"light" | "dark">("light"); + const [language, setLanguage] = useState("en"); + const [helpOpen, setHelpOpen] = useState(false); + const [activePortalOverlay, setActivePortalOverlay] = useState(null); + const [currentView, setCurrentView] = useState<"home" | "admin" | "customer" | "retailer" | "manufacturer">("home"); + + const t = TRANSLATIONS[language as keyof typeof TRANSLATIONS] || TRANSLATIONS.en; + + useEffect(() => { + const root = document.documentElement; + if (theme === "dark") { + root.classList.add("dark"); + } else { + root.classList.remove("dark"); + } + }, [theme]); + + // If in admin view, show admin console + if (currentView === "admin") { + return ( + +
+
+

Loading Admin Console...

+
+
+ }> + +
+ ); + } + + // If in customer view, show customer app + if (currentView === "customer") { + return ( + +
+
+

Loading Customer App...

+
+
+ }> + +
+ ); + } + + // If in retailer view, show retailer portal + if (currentView === "retailer") { + return ( + +
+
+

Loading Retailer Portal...

+
+
+ }> + +
+ ); + } + + // If in manufacturer view, show manufacturer portal + if (currentView === "manufacturer") { + return ( + +
+
+

Loading Manufacturer Portal...

+
+
+ }> + +
+ ); + } + + // Marketing page view + const handlePortalContinue = (portalKey: string) => { + if (portalKey === "admin") { + setCurrentView("admin"); + } else if (portalKey === "customer") { + setCurrentView("customer"); + } else if (portalKey === "retailer") { + setCurrentView("retailer"); + } else if (portalKey === "manufacturer") { + setCurrentView("manufacturer"); + } + setActivePortalOverlay(null); + }; + + return ( +
+ + + {/* Enhanced Header with Theme & Language */} +
+
+
+
+
+ H +
+ Hello Jewellers +
+ +
+ {/* Language Selector */} +
+ + +
+ + {/* Theme Toggle */} + + + {/* Help Button */} + +
+
+
+
+ +
+ {/* Hero Section with Indian-themed vectors */} +
+
+
+
+

+ {t.hero_title} +

+

+ {t.hero_description} +

+
+ +
+ + +
+
+ + {/* Indian-themed vector illustration */} +
+
+
+
+
+
+ +
+
+ +
+
+ +
+
+ +
+
+
+
+
+
+
+ + {/* Portal Tiles */} +
+
+

{t.portals_title}

+

+ {t.portals_description} +

+
+
+ {Object.entries(PORTAL_DATA).map(([key, portal]) => ( + setActivePortalOverlay(key)} + onLearnMore={() => setActivePortalOverlay(key)} + /> + ))} +
+
+ + {/* CTA Section */} +
+ +
+

{t.cta_title}

+

+ {t.cta_description} +

+
+
+ + +
+
+
+
+ + {/* Footer */} +
setTheme(theme === "light" ? "dark" : "light")} + language={language} + onLanguageChange={setLanguage} + /> + + {/* Modals */} + setHelpOpen(false)} /> + + {/* Portal Overlays */} + {activePortalOverlay && ( + setActivePortalOverlay(null)} + icon={PORTAL_DATA[activePortalOverlay as keyof typeof PORTAL_DATA].icon} + title={PORTAL_DATA[activePortalOverlay as keyof typeof PORTAL_DATA].title} + description={PORTAL_DATA[activePortalOverlay as keyof typeof PORTAL_DATA].description} + keyActions={PORTAL_DATA[activePortalOverlay as keyof typeof PORTAL_DATA].keyActions} + requiresLogin={false} + tenantScope={PORTAL_DATA[activePortalOverlay as keyof typeof PORTAL_DATA].tenantScope} + onContinue={() => handlePortalContinue(activePortalOverlay)} + /> + )} +
+ ); +} diff --git a/src/Attributions.md b/src/Attributions.md new file mode 100644 index 0000000..9b7cd4e --- /dev/null +++ b/src/Attributions.md @@ -0,0 +1,3 @@ +This Figma Make file includes components from [shadcn/ui](https://ui.shadcn.com/) used under [MIT license](https://github.com/shadcn-ui/ui/blob/main/LICENSE.md). + +This Figma Make file includes photos from [Unsplash](https://unsplash.com) used under [license](https://unsplash.com/license). \ No newline at end of file diff --git a/src/CustomerApp.tsx b/src/CustomerApp.tsx new file mode 100644 index 0000000..1dfd28c --- /dev/null +++ b/src/CustomerApp.tsx @@ -0,0 +1,341 @@ +import { useState, useEffect } from "react"; +import { MobileShell } from "./components/customer/MobileShell"; +import { SplashScreen } from "./components/customer/screens/SplashScreen"; +import { OnboardingScreen } from "./components/customer/screens/OnboardingScreen"; +import { LoginScreen } from "./components/customer/screens/LoginScreen"; +import { InviteScreen } from "./components/customer/screens/InviteScreen"; +import { ConfirmRetailerScreen } from "./components/customer/screens/ConfirmRetailerScreen"; +import { ProfileSetupScreen } from "./components/customer/screens/ProfileSetupScreen"; +import { HomeScreen } from "./components/customer/screens/HomeScreen"; +import { CollectionsScreen } from "./components/customer/screens/CollectionsScreen"; +import { ProductGridScreen } from "./components/customer/screens/ProductGridScreen"; +import { ProductDetailScreen } from "./components/customer/screens/ProductDetailScreen"; +import { WishlistScreen } from "./components/customer/screens/WishlistScreen"; +import { ChatScreen } from "./components/customer/screens/ChatScreen"; +import { AppointmentsScreen } from "./components/customer/screens/AppointmentsScreen"; +import { BookAppointmentScreen } from "./components/customer/screens/BookAppointmentScreen"; +import { InterestConfirmScreen } from "./components/customer/screens/InterestConfirmScreen"; +import { NotificationsScreen } from "./components/customer/screens/NotificationsScreen"; +import { AccountScreen } from "./components/customer/screens/AccountScreen"; +import { QuotesScreen } from "./components/customer/screens/QuotesScreen"; +import { OrdersScreen } from "./components/customer/screens/OrdersScreen"; +import { MyRetailersScreen } from "./components/customer/screens/MyRetailersScreen"; +import { RetailerStorefrontScreen } from "./components/customer/screens/RetailerStorefrontScreen"; +import { Toaster } from "./components/ui/sonner"; +import { toast } from "sonner@2.0.3"; + +export type CustomerScreen = + | "splash" + | "onboarding" + | "login" + | "invite" + | "confirm-retailer" + | "profile-setup" + | "home" + | "collections" + | "product-grid" + | "product-detail" + | "wishlist" + | "chat" + | "appointments" + | "book-appointment" + | "interest-confirm" + | "notifications" + | "account" + | "quotes" + | "orders" + | "my-retailers" + | "retailer-storefront"; + +interface CustomerState { + isAuthenticated: boolean; + hasRetailer: boolean; + retailer: { + name: string; + location: string; + associate: string; + } | null; + wishlist: string[]; + preferences: { + occasions: string[]; + categories: string[]; + budgetRange: string; + } | null; +} + +export default function CustomerApp() { + const [currentScreen, setCurrentScreen] = useState("splash"); + const [theme, setTheme] = useState<"light" | "dark">("light"); + const [customerState, setCustomerState] = useState({ + isAuthenticated: false, + hasRetailer: false, + retailer: null, + wishlist: ["1", "2", "3", "5", "7"], // Pre-populated wishlist for demo + preferences: null, + }); + + // Context data for navigation + const [selectedCollection, setSelectedCollection] = useState(null); + const [selectedProduct, setSelectedProduct] = useState(null); + + useEffect(() => { + const root = document.documentElement; + if (theme === "dark") { + root.classList.add("dark"); + } else { + root.classList.remove("dark"); + } + }, [theme]); + + // Simulate splash screen + useEffect(() => { + if (currentScreen === "splash") { + const timer = setTimeout(() => { + setCurrentScreen("onboarding"); + }, 2000); + return () => clearTimeout(timer); + } + }, [currentScreen]); + + const handleLogin = () => { + setCustomerState({ ...customerState, isAuthenticated: true }); + setCurrentScreen("invite"); + }; + + const handleSkipRetailer = () => { + // Skip retailer connection and go to profile setup with generic retailer + setCustomerState({ + ...customerState, + hasRetailer: false, + retailer: { + name: "Hello Jewellers", + location: "Browse All", + associate: "Platform", + }, + }); + setCurrentScreen("profile-setup"); + }; + + const handleRetailerConfirm = (retailerData: { name: string; location: string; associate: string }) => { + setCustomerState({ + ...customerState, + hasRetailer: true, + retailer: retailerData, + }); + setCurrentScreen("profile-setup"); + }; + + const handleProfileComplete = (preferences: any) => { + setCustomerState({ + ...customerState, + preferences, + }); + setCurrentScreen("home"); + }; + + const handleNavigate = (screen: CustomerScreen) => { + setCurrentScreen(screen); + }; + + const handleAddToWishlist = (productId: string) => { + setCustomerState({ + ...customerState, + wishlist: [...customerState.wishlist, productId], + }); + }; + + const handleRemoveFromWishlist = (productId: string) => { + setCustomerState({ + ...customerState, + wishlist: customerState.wishlist.filter((id) => id !== productId), + }); + }; + + // Screens that don't use the mobile shell + const splashScreens: CustomerScreen[] = ["splash", "onboarding", "login", "invite", "confirm-retailer", "profile-setup"]; + + const renderScreen = () => { + switch (currentScreen) { + case "splash": + return ; + case "onboarding": + return setCurrentScreen("login")} />; + case "login": + return ; + case "invite": + return ( + setCurrentScreen("confirm-retailer")} + onSkip={handleSkipRetailer} + /> + ); + case "confirm-retailer": + return ( + + handleRetailerConfirm({ + name: "Nova Jewels", + location: "Mumbai", + associate: "Aditi Rao", + }) + } + onSkip={handleSkipRetailer} + /> + ); + case "profile-setup": + return ; + case "home": + return ( + { + setSelectedCollection(id); + setCurrentScreen("product-grid"); + }} + /> + ); + case "collections": + return ( + { + setSelectedCollection(id); + setCurrentScreen("product-grid"); + }} + onBack={() => setCurrentScreen("home")} + /> + ); + case "product-grid": + return ( + { + setSelectedProduct(id); + setCurrentScreen("product-detail"); + }} + onBack={() => setCurrentScreen("home")} + /> + ); + case "product-detail": + return ( + { + handleAddToWishlist(selectedProduct!); + toast.success("Added to wishlist"); + }} + onRemoveFromWishlist={() => { + handleRemoveFromWishlist(selectedProduct!); + toast.success("Removed from wishlist"); + }} + onInquire={() => setCurrentScreen("chat")} + onBookAppointment={() => setCurrentScreen("book-appointment")} + onBack={() => setCurrentScreen("product-grid")} + /> + ); + case "wishlist": + return ( + { + setSelectedProduct(id); + setCurrentScreen("product-detail"); + }} + onRemoveFromWishlist={handleRemoveFromWishlist} + /> + ); + case "chat": + return ( + + ); + case "interest-confirm": + return ( + setCurrentScreen("home")} + onContinueChat={() => setCurrentScreen("chat")} + onBookAppointment={() => setCurrentScreen("book-appointment")} + /> + ); + case "notifications": + return ( + setCurrentScreen("home")} + onNavigate={handleNavigate} + /> + ); + case "appointments": + return ( + setCurrentScreen("book-appointment")} + /> + ); + case "book-appointment": + return ( + setCurrentScreen("appointments")} + onSuccess={() => setCurrentScreen("appointments")} + /> + ); + case "account": + return ( + + ); + case "my-retailers": + return ( + setCurrentScreen("account")} + onViewStore={(retailerId) => { + setSelectedProduct(retailerId); // Reuse for retailer ID + setCurrentScreen("retailer-storefront"); + }} + /> + ); + case "retailer-storefront": + return ( + setCurrentScreen("my-retailers")} + retailerId={selectedProduct || "1"} + /> + ); + case "quotes": + return setCurrentScreen("account")} />; + case "orders": + return setCurrentScreen("account")} />; + default: + return {}} />; + } + }; + + // Screens without bottom nav (add book-appointment, interest-confirm, and notifications) + const screensWithoutNav = [...splashScreens, "book-appointment", "interest-confirm", "notifications"]; + + if (screensWithoutNav.includes(currentScreen)) { + return ( + <> + + {renderScreen()} + + ); + } + + // Screens with mobile shell + return ( + <> + + + {renderScreen()} + + + ); +} diff --git a/src/ManufacturerApp.tsx b/src/ManufacturerApp.tsx new file mode 100644 index 0000000..2b6094c --- /dev/null +++ b/src/ManufacturerApp.tsx @@ -0,0 +1,107 @@ +import { useState } from "react"; +import { ManufacturerShell } from "./components/manufacturer/ManufacturerShell"; +import { DashboardPage } from "./components/manufacturer/pages/DashboardPage"; +import { SharingPage } from "./components/manufacturer/pages/SharingPage"; +import { InquiriesPage } from "./components/manufacturer/pages/InquiriesPage"; +import { CustomOrdersPage } from "./components/manufacturer/pages/CustomOrdersPage"; +import { AnalyticsPage } from "./components/manufacturer/pages/AnalyticsPage"; +import { CompliancePage } from "./components/manufacturer/pages/CompliancePage"; +import { SettingsPage } from "./components/manufacturer/pages/SettingsPage"; +import { KYCPage } from "./components/manufacturer/pages/KYCPage"; +import { Toaster } from "./components/ui/sonner"; + +export type ManufacturerPage = + | "dashboard" + | "sharing" + | "inquiries" + | "custom-orders" + | "analytics" + | "compliance" + | "settings" + | "kyc"; + +interface ManufacturerState { + company: { + name: string; + legalName: string; + logo: string | null; + } | null; + kycStatus: "pending" | "verified" | "rejected"; + isSetupComplete: boolean; +} + +export default function ManufacturerApp() { + const [currentPage, setCurrentPage] = useState("dashboard"); + const [manufacturerState, setManufacturerState] = useState({ + company: { + name: "Auric Foundry", + legalName: "Auric Foundry Pvt Ltd", + logo: null, + }, + kycStatus: "verified", + isSetupComplete: true, + }); + + const handleNavigate = (page: ManufacturerPage) => { + setCurrentPage(page); + }; + + const handleKYCComplete = (status: "verified" | "pending") => { + setManufacturerState({ + ...manufacturerState, + kycStatus: status, + isSetupComplete: true, + }); + setCurrentPage("dashboard"); + }; + + // If KYC not complete, show KYC wizard + if (!manufacturerState.isSetupComplete || manufacturerState.kycStatus === "pending") { + return ( + <> + + + + ); + } + + const renderPage = () => { + switch (currentPage) { + case "dashboard": + return ; + case "sharing": + return ; + case "inquiries": + return ; + case "custom-orders": + return ; + case "analytics": + return ; + case "compliance": + return ; + case "settings": + return ; + case "kyc": + return ; + default: + return ; + } + }; + + return ( + <> + + + {renderPage()} + + + ); +} diff --git a/src/RetailerApp.tsx b/src/RetailerApp.tsx new file mode 100644 index 0000000..fa35c17 --- /dev/null +++ b/src/RetailerApp.tsx @@ -0,0 +1,155 @@ +import { useState, useEffect } from "react"; +import { RetailerShell } from "./components/retailer/RetailerShell"; +import { DashboardPage } from "./components/retailer/pages/DashboardPage"; +import { InventoryPage } from "./components/retailer/pages/InventoryPage"; +import { CurationPage } from "./components/retailer/pages/CurationPage"; +import { CustomersPage } from "./components/retailer/pages/CustomersPage"; +import { ChatPage } from "./components/retailer/pages/ChatPage"; +import { AppointmentsPage } from "./components/retailer/pages/AppointmentsPage"; +import { QuotesOrdersPage } from "./components/retailer/pages/QuotesOrdersPage"; +import { StorefrontPage } from "./components/retailer/pages/StorefrontPage"; +import { AnalyticsPage } from "./components/retailer/pages/AnalyticsPage"; +import { TeamPage } from "./components/retailer/pages/TeamPage"; +import { SetupPage } from "./components/retailer/pages/SetupPage"; +import { GoldRateModal, GoldRates } from "./components/retailer/GoldRateModal"; +import { Toaster } from "./components/ui/sonner"; +import { toast } from "sonner@2.0.3"; + +export type RetailerPage = + | "dashboard" + | "inventory" + | "curation" + | "customers" + | "chat" + | "appointments" + | "quotes-orders" + | "storefront" + | "analytics" + | "team" + | "setup"; + +interface RetailerState { + brand: { + name: string; + logo: string | null; + subdomain: string; + } | null; + stores: Array<{ + id: string; + name: string; + location: string; + }>; + isSetupComplete: boolean; +} + +export default function RetailerApp() { + const [currentPage, setCurrentPage] = useState("dashboard"); + const [goldRateModalOpen, setGoldRateModalOpen] = useState(false); + const [goldRatesSet, setGoldRatesSet] = useState(false); + const [retailerState, setRetailerState] = useState({ + brand: { + name: "Nova Jewels", + logo: null, + subdomain: "nova-jewels", + }, + stores: [ + { id: "1", name: "Mumbai Showroom", location: "Mumbai, Maharashtra" }, + ], + isSetupComplete: true, + }); + + // Check if gold rates need to be set today + useEffect(() => { + const lastRateDate = localStorage.getItem('lastGoldRateDate'); + const today = new Date().toISOString().split('T')[0]; + + if (lastRateDate !== today && retailerState.isSetupComplete) { + // Show modal after a short delay + setTimeout(() => { + setGoldRateModalOpen(true); + }, 1000); + } else if (lastRateDate === today) { + setGoldRatesSet(true); + } + }, [retailerState.isSetupComplete]); + + const handleNavigate = (page: RetailerPage) => { + setCurrentPage(page); + }; + + const handleSetupComplete = (brandData: any) => { + setRetailerState({ + ...retailerState, + brand: brandData, + isSetupComplete: true, + }); + setCurrentPage("dashboard"); + }; + + const handleGoldRatesSubmit = (rates: GoldRates) => { + // Save rates to localStorage + localStorage.setItem('lastGoldRateDate', rates.date); + localStorage.setItem('goldRates', JSON.stringify(rates)); + setGoldRatesSet(true); + toast.success(`Gold rates updated successfully! Shop is now open.`, { + description: `22K: ₹${rates.gold22k}/g | 24K: ₹${rates.gold24k}/g | Silver: ₹${rates.silver}/g`, + }); + }; + + // If setup not complete, show setup wizard + if (!retailerState.isSetupComplete) { + return ( + <> + + + + ); + } + + const renderPage = () => { + switch (currentPage) { + case "dashboard": + return ; + case "inventory": + return ; + case "curation": + return ; + case "customers": + return ; + case "chat": + return ; + case "appointments": + return ; + case "quotes-orders": + return ; + case "storefront": + return ; + case "analytics": + return ; + case "team": + return ; + case "setup": + return ; + default: + return ; + } + }; + + return ( + <> + + setGoldRateModalOpen(false)} + onSubmit={handleGoldRatesSubmit} + /> + + {renderPage()} + + + ); +} diff --git a/src/components/AIAssistant.tsx b/src/components/AIAssistant.tsx new file mode 100644 index 0000000..bd80f55 --- /dev/null +++ b/src/components/AIAssistant.tsx @@ -0,0 +1,363 @@ +import { useState, useRef, useEffect } from "react"; +import { Sparkles, Send, X, Minimize2, Maximize2, TrendingUp, Package, Users, DollarSign, FileText } from "lucide-react"; +import { Button } from "./ui/button"; +import { Input } from "./ui/input"; +import { ScrollArea } from "./ui/scroll-area"; +import { Badge } from "./ui/badge"; +import { Card } from "./ui/card"; +import { motion, AnimatePresence } from "motion/react"; + +interface AIAssistantProps { + portalType: "admin" | "retailer" | "manufacturer"; +} + +interface Message { + id: string; + type: "user" | "assistant"; + content: string; + timestamp: Date; + suggestions?: string[]; + data?: any; +} + +const QUICK_ACTIONS = { + admin: [ + { icon: Users, label: "Show total users", query: "How many total users do we have?" }, + { icon: TrendingUp, label: "Platform analytics", query: "Show me platform analytics summary" }, + { icon: Package, label: "Active tenants", query: "How many active tenants?" }, + { icon: FileText, label: "Recent activity", query: "Show recent platform activity" }, + ], + retailer: [ + { icon: DollarSign, label: "Gold rate today", query: "What is the gold rate today?" }, + { icon: Package, label: "Top products", query: "Which products are generating most interest?" }, + { icon: FileText, label: "Pending quotes", query: "Show my pending quotations" }, + { icon: TrendingUp, label: "Sales summary", query: "Show me this month's sales summary" }, + ], + manufacturer: [ + { icon: Package, label: "Inventory status", query: "What's my current inventory status?" }, + { icon: Users, label: "Connected retailers", query: "How many retailers am I connected to?" }, + { icon: FileText, label: "Custom orders", query: "Show pending custom orders" }, + { icon: TrendingUp, label: "Production analytics", query: "Show production analytics" }, + ], +}; + +const AI_RESPONSES = { + admin: { + "users": { + content: "📊 **Platform User Statistics**\n\n• Total Users: **2,847**\n• Active This Month: **2,156** (76%)\n• New This Week: **142**\n\nBreakdown by role:\n• Customers: 2,245\n• Retailers: 458\n• Manufacturers: 124\n• Admins: 20", + data: { total: 2847, active: 2156, new: 142 }, + }, + "analytics": { + content: "📈 **Platform Analytics Summary**\n\n**This Month:**\n• Total Revenue: ₹24.5 Cr\n• Growth: +18.3% MoM\n• Active Transactions: 1,847\n• Platform Uptime: 99.97%\n\n**Top Performing Regions:**\n1. Mumbai - ₹8.2 Cr\n2. Delhi - ₹6.4 Cr\n3. Bangalore - ₹4.8 Cr", + }, + "tenants": { + content: "🏢 **Active Tenants Overview**\n\n• Total Tenants: **124**\n• Active: **118** (95%)\n• Trial Period: **6**\n\n**By Plan:**\n• Enterprise: 42\n• Professional: 58\n• Starter: 18\n• Trial: 6", + }, + }, + retailer: { + "gold rate": { + content: "💰 **Today's Gold Rates** (Updated 2 mins ago)\n\n**22K Gold:**\n• Rate: ₹6,245/gram\n• Change: +₹25 (+0.4%)\n\n**18K Gold:**\n• Rate: ₹5,120/gram\n• Change: +₹20 (+0.4%)\n\n**24K Gold:**\n• Rate: ₹6,820/gram\n• Change: +₹28 (+0.4%)\n\n📊 7-day avg: ₹6,218/gram", + suggestions: ["Show gold rate trend", "Update my pricing"], + }, + "products": { + content: "🔥 **Top Performing Products** (Last 30 days)\n\n1. **Heritage Bridal Ring**\n • Views: 842\n • Wishlist adds: 142\n • Inquiries: 28\n • Interest Score: 94/100\n\n2. **Classic Gold Necklace**\n • Views: 624\n • Wishlist adds: 98\n • Inquiries: 18\n • Interest Score: 87/100\n\n3. **Diamond Stud Earrings**\n • Views: 512\n • Wishlist adds: 89\n • Inquiries: 15\n • Interest Score: 82/100", + suggestions: ["Show full inventory analytics", "Update featured products"], + }, + "quotes": { + content: "📋 **Pending Quotations**\n\n**High Priority (3):**\n• Quote #Q-2847 - Aditi Sharma\n Bridal Set | ₹4.2L | Expires in 2 days\n\n• Quote #Q-2845 - Rohan Mehta \n Diamond Ring | ₹2.8L | Expires in 3 days\n\n• Quote #Q-2842 - Priya Patel\n Gold Bangles | ₹1.5L | Expires today\n\n**Total Pending:** 8 quotes worth ₹18.6L", + suggestions: ["Send follow-up reminders", "View all quotes"], + }, + "sales": { + content: "💼 **Sales Summary - January 2025**\n\n**Revenue:** ₹86 Lakhs\n• Growth: +22.1% vs Dec\n• Orders: 34 completed\n• Avg Order Value: ₹2.53L\n\n**Top Categories:**\n1. Bridal: ₹42L (49%)\n2. Daily Wear: ₹24L (28%)\n3. Diamond: ₹20L (23%)\n\n**Conversion Rate:** 38.2%", + suggestions: ["View detailed analytics", "Export report"], + }, + }, + manufacturer: { + "inventory": { + content: "📦 **Inventory Status Overview**\n\n**Total SKUs:** 842\n• Available: 687 (82%)\n• Custom Order: 124 (15%)\n• Out of Stock: 31 (3%)\n\n**By Category:**\n• Rings: 245 SKUs\n• Necklaces: 198 SKUs\n• Bangles: 167 SKUs\n• Earrings: 142 SKUs\n• Others: 90 SKUs\n\n⚠️ Low stock alert: 12 items", + suggestions: ["View low stock items", "Sync with retailers"], + }, + "retailers": { + content: "🤝 **Connected Retailers**\n\n**Total Connections:** 48 retailers\n• Active Orders: 12\n• Pending Approvals: 3\n\n**Top Partners:**\n1. Nova Jewels (Mumbai)\n • Orders: 124 | Revenue: ₹42L\n2. Sparkle Gems (Delhi)\n • Orders: 89 | Revenue: ₹28L\n3. Golden Heritage (Jaipur)\n • Orders: 67 | Revenue: ₹24L\n\n**This Month:** 18 new inquiries", + suggestions: ["View all retailers", "Pending approvals"], + }, + "orders": { + content: "🔧 **Pending Custom Orders**\n\n**Urgent (2):**\n• Order #CO-2847\n Nova Jewels | Custom Ring Design\n Due: 3 days | Value: ₹2.8L\n\n• Order #CO-2842\n Sparkle Gems | Bangle Set\n Due: 5 days | Value: ₹1.5L\n\n**Total Pending:** 8 orders\n**Total Value:** ₹14.2L\n\n📅 Next week deliveries: 5 orders", + suggestions: ["View production schedule", "Update order status"], + }, + "analytics": { + content: "📊 **Production Analytics**\n\n**This Month:**\n• Units Produced: 1,247\n• Quality Rate: 98.2%\n• On-time Delivery: 94%\n• Revenue: ₹68L\n\n**Efficiency Metrics:**\n• Avg Production Time: 6.2 days\n• Capacity Utilization: 84%\n• Active Workforce: 42\n\n📈 Growth vs last month: +12%", + suggestions: ["View detailed breakdown", "Export report"], + }, + }, +}; + +export function AIAssistant({ portalType }: AIAssistantProps) { + const [isOpen, setIsOpen] = useState(false); + const [isMinimized, setIsMinimized] = useState(false); + const [messages, setMessages] = useState([ + { + id: "welcome", + type: "assistant", + content: `👋 Hello! I'm your AI assistant. I can help you with:\n\n${ + portalType === "admin" + ? "• User and tenant analytics\n• Platform metrics\n• Activity monitoring\n• Compliance reports" + : portalType === "retailer" + ? "• Gold rate updates\n• Inventory insights\n• Sales analytics\n• Customer quotes" + : "• Inventory management\n• Retailer connections\n• Custom orders\n• Production analytics" + }\n\nHow can I assist you today?`, + timestamp: new Date(), + }, + ]); + const [inputValue, setInputValue] = useState(""); + const [isTyping, setIsTyping] = useState(false); + const scrollRef = useRef(null); + const inputRef = useRef(null); + + const quickActions = QUICK_ACTIONS[portalType]; + + useEffect(() => { + if (scrollRef.current) { + scrollRef.current.scrollTop = scrollRef.current.scrollHeight; + } + }, [messages]); + + const handleSendMessage = (query: string = inputValue) => { + if (!query.trim()) return; + + const userMessage: Message = { + id: Date.now().toString(), + type: "user", + content: query, + timestamp: new Date(), + }; + + setMessages((prev) => [...prev, userMessage]); + setInputValue(""); + setIsTyping(true); + + // Simulate AI response + setTimeout(() => { + const response = getAIResponse(query.toLowerCase(), portalType); + const assistantMessage: Message = { + id: (Date.now() + 1).toString(), + type: "assistant", + content: response.content, + timestamp: new Date(), + suggestions: response.suggestions, + }; + + setMessages((prev) => [...prev, assistantMessage]); + setIsTyping(false); + }, 1500); + }; + + const getAIResponse = (query: string, portal: string) => { + const responses = AI_RESPONSES[portal as keyof typeof AI_RESPONSES]; + + // Match query to response category + if (query.includes("user") || query.includes("total")) { + return responses["users" as keyof typeof responses] || getDefaultResponse(portal); + } else if (query.includes("analytic") || query.includes("summary") || query.includes("sales")) { + return responses["analytics" as keyof typeof responses] || getDefaultResponse(portal); + } else if (query.includes("tenant") || query.includes("active")) { + return responses["tenants" as keyof typeof responses] || getDefaultResponse(portal); + } else if (query.includes("gold") || query.includes("rate") || query.includes("price")) { + return responses["gold rate" as keyof typeof responses] || getDefaultResponse(portal); + } else if (query.includes("product") || query.includes("interest") || query.includes("performing")) { + return responses["products" as keyof typeof responses] || getDefaultResponse(portal); + } else if (query.includes("quote") || query.includes("quotation") || query.includes("pending")) { + return responses["quotes" as keyof typeof responses] || getDefaultResponse(portal); + } else if (query.includes("inventory") || query.includes("stock")) { + return responses["inventory" as keyof typeof responses] || getDefaultResponse(portal); + } else if (query.includes("retailer") || query.includes("connection")) { + return responses["retailers" as keyof typeof responses] || getDefaultResponse(portal); + } else if (query.includes("order") || query.includes("custom")) { + return responses["orders" as keyof typeof responses] || getDefaultResponse(portal); + } + + return getDefaultResponse(portal); + }; + + const getDefaultResponse = (portal: string) => { + return { + content: `I understand you're asking about that. Let me help you find the information you need.\n\nTry asking me about:\n${ + portal === "admin" + ? "• User statistics\n• Platform analytics\n• Tenant information" + : portal === "retailer" + ? "• Gold rates\n• Inventory performance\n• Sales data\n• Customer quotes" + : "• Inventory status\n• Retailer connections\n• Custom orders\n• Production metrics" + }`, + suggestions: quickActions.map((a) => a.query).slice(0, 2), + }; + }; + + return ( + <> + {/* Floating Button */} + {!isOpen && ( + + +
+ + )} + + {/* Chat Window */} + + {isOpen && ( + + {/* Header */} +
+
+
+ +
+
+

AI Assistant

+ {!isMinimized &&

Always here to help

} +
+
+
+ + +
+
+ + {!isMinimized && ( + <> + {/* Messages */} + +
+ {messages.map((message) => ( +
+
+

{message.content}

+ {message.suggestions && ( +
+ {message.suggestions.map((suggestion, i) => ( + + ))} +
+ )} +

+ {message.timestamp.toLocaleTimeString([], { + hour: "2-digit", + minute: "2-digit", + })} +

+
+
+ ))} + + {isTyping && ( +
+
+
+
+
+
+
+
+
+ )} +
+ + + {/* Quick Actions */} + {messages.length === 1 && ( +
+

Quick actions:

+
+ {quickActions.map((action, i) => { + const Icon = action.icon; + return ( + + ); + })} +
+
+ )} + + {/* Input */} +
+
+ setInputValue(e.target.value)} + onKeyPress={(e) => e.key === "Enter" && handleSendMessage()} + placeholder="Ask me anything..." + className="flex-1" + /> + +
+
+ + )} + + )} + + + ); +} diff --git a/src/components/AuthModal.tsx b/src/components/AuthModal.tsx new file mode 100644 index 0000000..52eabd8 --- /dev/null +++ b/src/components/AuthModal.tsx @@ -0,0 +1,212 @@ +import { useState } from "react"; +import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription } from "./ui/dialog"; +import { Tabs, TabsContent, TabsList, TabsTrigger } from "./ui/tabs"; +import { Input } from "./ui/input"; +import { Button } from "./ui/button"; +import { Label } from "./ui/label"; +import { Checkbox } from "./ui/checkbox"; +import { InputOTP, InputOTPGroup, InputOTPSlot } from "./ui/input-otp"; +import { Mail } from "lucide-react"; + +interface AuthModalProps { + open: boolean; + onClose: () => void; + onAuthenticated: (email: string) => void; +} + +export function AuthModal({ open, onClose, onAuthenticated }: AuthModalProps) { + const [email, setEmail] = useState(""); + const [showOTP, setShowOTP] = useState(false); + const [otp, setOtp] = useState(""); + const [consent, setConsent] = useState(false); + const [resendTimer, setResendTimer] = useState(0); + + const handleSendOTP = () => { + if (email && consent) { + setShowOTP(true); + setResendTimer(30); + const interval = setInterval(() => { + setResendTimer((prev) => { + if (prev <= 1) { + clearInterval(interval); + return 0; + } + return prev - 1; + }); + }, 1000); + } + }; + + const handleVerifyOTP = () => { + if (otp.length === 6) { + onAuthenticated(email); + onClose(); + } + }; + + const handleGoogleSignIn = () => { + onAuthenticated("user@example.com"); + onClose(); + }; + + return ( + + + + Sign In + + Sign in with your email using OTP or use Google authentication + + + + + + Email / OTP + Google + + + + {!showOTP ? ( + <> +
+ + setEmail(e.target.value)} + /> +
+ +
+ setConsent(checked as boolean)} + /> + +
+ + + + ) : ( + <> +
+
+
+ +
+

+ We sent a code to {email} +

+
+ +
+ +
+ + + + + + + + + + +
+
+ + + +
+ + {resendTimer > 0 ? ( +

+ Resend OTP in {resendTimer}s +

+ ) : ( + + )} +
+
+ + )} +
+ + +
+

+ Sign in with your Google account for quick access +

+ +
+
+
+
+
+ ); +} diff --git a/src/components/BulkUploadDialog.tsx b/src/components/BulkUploadDialog.tsx new file mode 100644 index 0000000..7993148 --- /dev/null +++ b/src/components/BulkUploadDialog.tsx @@ -0,0 +1,297 @@ +import { useState } from "react"; +import { Upload, Download, FileSpreadsheet, CheckCircle, AlertCircle, X, File } from "lucide-react"; +import { + Dialog, + DialogContent, + DialogDescription, + DialogHeader, + DialogTitle, +} from "./ui/dialog"; +import { Button } from "./ui/button"; +import { Progress } from "./ui/progress"; +import { Alert, AlertDescription } from "./ui/alert"; +import { Separator } from "./ui/separator"; +import { toast } from "sonner@2.0.3"; + +interface BulkUploadDialogProps { + open: boolean; + onClose: () => void; + onUpload: (file: File) => void; + title: string; + description: string; + templateType: "inventory" | "customers" | "catalogue"; +} + +const templates = { + inventory: { + name: "Inventory_Template.xlsx", + fields: ["SKU", "Title", "Category", "Metal", "Purity", "Weight", "Making Charges", "Margin", "Status", "Visibility"], + }, + customers: { + name: "Customers_Template.xlsx", + fields: ["Name", "Email", "Phone", "City", "State", "Tags", "Notes"], + }, + catalogue: { + name: "Catalogue_Template.xlsx", + fields: ["SKU", "Title", "Category", "Metal", "Purity", "Weight", "Wholesale Price", "Min Order Qty", "Lead Time", "Status"], + }, +}; + +export function BulkUploadDialog({ open, onClose, onUpload, title, description, templateType }: BulkUploadDialogProps) { + const [uploadStep, setUploadStep] = useState<"select" | "uploading" | "processing" | "complete">("select"); + const [selectedFile, setSelectedFile] = useState(null); + const [uploadProgress, setUploadProgress] = useState(0); + const [results, setResults] = useState<{ + total: number; + success: number; + failed: number; + errors: string[]; + } | null>(null); + + const template = templates[templateType]; + + const handleFileSelect = (e: React.ChangeEvent) => { + const file = e.target.files?.[0]; + if (file) { + if (file.name.endsWith('.xlsx') || file.name.endsWith('.xls') || file.name.endsWith('.csv')) { + setSelectedFile(file); + } else { + toast.error("Please select a valid Excel or CSV file"); + } + } + }; + + const handleUpload = () => { + if (!selectedFile) return; + + setUploadStep("uploading"); + setUploadProgress(0); + + // Simulate upload progress + const uploadInterval = setInterval(() => { + setUploadProgress((prev) => { + if (prev >= 100) { + clearInterval(uploadInterval); + setUploadStep("processing"); + setTimeout(() => { + // Simulate processing + setUploadStep("complete"); + setResults({ + total: 150, + success: 142, + failed: 8, + errors: [ + "Row 23: Invalid metal type 'Copper'", + "Row 45: Missing required field 'Weight'", + "Row 67: Duplicate SKU 'AU-22K-BR-0192'", + "Row 89: Invalid purity value", + "Row 102: Missing category", + ], + }); + onUpload(selectedFile); + }, 2000); + return 100; + } + return prev + 10; + }); + }, 200); + }; + + const handleDownloadTemplate = () => { + toast.success(`Downloading ${template.name}...`); + // In a real implementation, this would trigger an actual file download + }; + + const handleReset = () => { + setUploadStep("select"); + setSelectedFile(null); + setUploadProgress(0); + setResults(null); + }; + + const handleClose = () => { + handleReset(); + onClose(); + }; + + return ( + + + + {title} + {description} + + +
+ {/* Step 1: Template Download */} +
+
+
+ 1 +
+

Download Template

+
+
+

+ Download our Excel template with pre-defined columns and formatting rules. +

+
+
+
+ +
+

{template.name}

+

+ Includes: {template.fields.slice(0, 3).join(", ")} + {template.fields.length > 3 && ` +${template.fields.length - 3} more`} +

+
+
+ +
+
+
+
+ + + + {/* Step 2: Fill & Upload */} +
+
+
+ 2 +
+

Fill Data & Upload

+
+
+

+ Fill in your data following the template format and upload the file. +

+ + {uploadStep === "select" && ( +
+ + +
+ )} + + {uploadStep === "uploading" && ( +
+
+ +
+

{selectedFile?.name}

+

Uploading...

+
+
+ +

{uploadProgress}% complete

+
+ )} + + {uploadStep === "processing" && ( +
+
+

Processing file...

+

Validating and importing data

+
+ )} + + {uploadStep === "complete" && results && ( +
+ + + + Successfully imported {results.success} out of {results.total} records + + + + {results.failed > 0 && ( + + + +
+

{results.failed} records failed

+
+ {results.errors.map((error, i) => ( +

• {error}

+ ))} +
+
+
+
+ )} + +
+
+

{results.total}

+

Total Rows

+
+
+

{results.success}

+

Imported

+
+
+

{results.failed}

+

Failed

+
+
+
+ )} +
+
+
+ + + +
+ {uploadStep === "select" ? ( + <> + + + + ) : uploadStep === "complete" ? ( + <> + + + + ) : ( + + )} +
+ +
+ ); +} diff --git a/src/components/Footer.tsx b/src/components/Footer.tsx new file mode 100644 index 0000000..e1f1514 --- /dev/null +++ b/src/components/Footer.tsx @@ -0,0 +1,38 @@ +interface FooterProps { + theme?: "light" | "dark"; + onThemeToggle?: () => void; + language?: string; + onLanguageChange?: (lang: string) => void; +} + +export function Footer({ + theme = "light", + onThemeToggle, + language = "en", + onLanguageChange, +}: FooterProps) { + return ( +
+
+
+ {/* Brand & Copyright */} +
+
+
+ H +
+ Hello Jewellers +
+

+ Your Jewellery Ecosystem, One Hub +

+

+ © 2025 Hello Jewellers. v0.1 Prototype +

+
+ +
+
+
+ ); +} diff --git a/src/components/HelpOverlay.tsx b/src/components/HelpOverlay.tsx new file mode 100644 index 0000000..ff1fd27 --- /dev/null +++ b/src/components/HelpOverlay.tsx @@ -0,0 +1,246 @@ +import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription } from "./ui/dialog"; +import { Tabs, TabsContent, TabsList, TabsTrigger } from "./ui/tabs"; +import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from "./ui/accordion"; +import { Card } from "./ui/card"; +import { Shield, ShoppingBag, Store, Factory, CheckCircle } from "lucide-react"; + +interface HelpOverlayProps { + open: boolean; + onClose: () => void; +} + +export function HelpOverlay({ open, onClose }: HelpOverlayProps) { + return ( + + + + Help & Documentation + + Learn about the platform, portals, and how to get started + + + + + + Platform Overview + Portal Guide + FAQs + + + +
+
+

Welcome to Hello Jewellers

+

+ A unified platform connecting the entire jewellery ecosystem - from manufacturers to customers, all in one place. +

+
+ +
+ +
+ +
+

For Customers

+

+ Browse curated jewellery collections, create wishlists, chat with retailers, and book appointments - all from your mobile device. +

+
+
+
+ + +
+ +
+

For Retailers

+

+ Build your virtual store, manage customer relationships, set daily gold rates, and customize your storefront with AI-powered tools. +

+
+
+
+ + +
+ +
+

For Manufacturers

+

+ Sync your inventory, share catalogues with retail partners, handle custom orders, and track production schedules. +

+
+
+
+ + +
+ +
+

For Admins

+

+ Manage users, monitor platform analytics, moderate content, and ensure DPDP compliance across the ecosystem. +

+
+
+
+
+ +
+

Getting Started

+
    +
  1. Choose the portal that matches your role
  2. +
  3. Sign in or create your account
  4. +
  5. Complete your profile setup
  6. +
  7. Start exploring the platform features
  8. +
+
+
+
+ + +
+ +
+
+ +
+
+

Customer App

+

+ Mobile-first experience for browsing and purchasing jewellery +

+
    +
  • • Browse retailer collections
  • +
  • • Create and manage wishlists
  • +
  • • Chat with retailers via text, voice, or video
  • +
  • • Book showroom appointments
  • +
  • • Track orders and quotes
  • +
+
+
+
+ + +
+
+ +
+
+

Retailers' Shop

+

+ Complete toolkit for managing your jewellery retail business +

+
    +
  • • Set daily gold and silver rates
  • +
  • • Customize virtual store with AI themes
  • +
  • • Manage customer relationships and chat
  • +
  • • Handle appointments and bookings
  • +
  • • Track inventory and process orders
  • +
  • • Mobile app view preview
  • +
+
+
+
+ + +
+
+ +
+
+

Manufacturers' Shop

+

+ Production and distribution management for manufacturers +

+
    +
  • • Sync and manage inventory
  • +
  • • Share catalogues with retailers
  • +
  • • Accept custom order requests
  • +
  • • Track production schedules
  • +
  • • API integrations for automation
  • +
+
+
+
+ + +
+
+ +
+
+

Admin Console

+

+ Super admin control panel for platform management +

+
    +
  • • User and role management
  • +
  • • Platform-wide analytics
  • +
  • • Content moderation
  • +
  • • DPDP compliance monitoring
  • +
  • • System configuration
  • +
+
+
+
+
+
+ + + + + How do I connect with a retailer as a customer? + + In the Customer App, you can either enter an invite code provided by your retailer or skip this step to browse available jewellery. You can always connect with a retailer later from your account settings. + + + + + What are daily gold rates and why are they required? + + Retailers must set daily gold and silver rates before opening their shop. These rates are displayed on the storefront and used for accurate pricing calculations. You can update rates anytime from the settings. + + + + + Can retailers customize their storefront? + + Yes! Retailers have access to AI-powered customization tools including theme selection, banner management, content generation for product descriptions, and a live mobile preview to see how their store appears to customers. + + + + + How do voice and video calls work? + + Retailers can initiate voice calls with customers. Video calls can only be initiated by customers, and retailers can accept or decline incoming video calls. All communication is logged for quality and compliance purposes. + + + + + What languages are supported? + + The platform currently supports English, Hindi (हिन्दी), Marathi (मराठी), and Gujarati (ગુજરાતી). You can change the language from the top navigation bar, and your preference will be saved automatically. + + + + + Is my data secure and DPDP compliant? + + Yes, the platform is built with DPDP (Digital Personal Data Protection) compliance at its core. All personal data is encrypted, access is logged, and users have full rights to view, modify, and delete their data. The Admin Console provides compliance monitoring tools. + + + + + Can I use the platform on mobile devices? + + The Customer App is specifically designed for mobile devices with a native app-like experience. All other portals (Retailer, Manufacturer, Admin) are responsive and work on mobile, tablet, and desktop devices. + + + + +
+
+
+ ); +} diff --git a/src/components/InviteCodeModal.tsx b/src/components/InviteCodeModal.tsx new file mode 100644 index 0000000..428224c --- /dev/null +++ b/src/components/InviteCodeModal.tsx @@ -0,0 +1,107 @@ +import { useState } from "react"; +import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription } from "./ui/dialog"; +import { Input } from "./ui/input"; +import { Button } from "./ui/button"; +import { Label } from "./ui/label"; +import { CheckCircle2, AlertCircle } from "lucide-react"; + +interface InviteCodeModalProps { + open: boolean; + onClose: () => void; + onValidateCode: (code: string) => { valid: boolean; portal?: string }; +} + +export function InviteCodeModal({ open, onClose, onValidateCode }: InviteCodeModalProps) { + const [code, setCode] = useState(""); + const [validated, setValidated] = useState<{ valid: boolean; portal?: string } | null>(null); + const [error, setError] = useState(""); + + const handleValidate = () => { + if (code.length < 6) { + setError("Invite code must be at least 6 characters"); + return; + } + + const result = onValidateCode(code); + setValidated(result); + + if (!result.valid) { + setError("Invalid invite code. Please check and try again."); + } else { + setError(""); + } + }; + + const handleClose = () => { + setCode(""); + setValidated(null); + setError(""); + onClose(); + }; + + return ( + + + + Enter Invite Code + + Enter your invitation code to join a tenant organization + + + +
+ {!validated ? ( + <> +
+ + setCode(e.target.value.toUpperCase())} + maxLength={8} + className="uppercase tracking-wider text-center" + /> +

+ Enter the 6-8 character code you received +

+
+ + {error && ( +
+ +

{error}

+
+ )} + + + + ) : validated.valid ? ( +
+
+
+ +
+
+

Code Validated!

+

+ This invite is for {validated.portal} +

+
+
+ +
+ ) : null} +
+
+
+ ); +} diff --git a/src/components/PortalOverlay.tsx b/src/components/PortalOverlay.tsx new file mode 100644 index 0000000..bca617a --- /dev/null +++ b/src/components/PortalOverlay.tsx @@ -0,0 +1,108 @@ +import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription } from "./ui/dialog"; +import { Button } from "./ui/button"; +import { X, LucideIcon } from "lucide-react"; +import { VisuallyHidden } from "@radix-ui/react-visually-hidden@1.1.1"; + +interface PortalOverlayProps { + open: boolean; + onClose: () => void; + icon: LucideIcon; + title: string; + description: string; + keyActions: string[]; + requiresLogin: boolean; + tenantScope: string; + onContinue: () => void; +} + +export function PortalOverlay({ + open, + onClose, + icon: Icon, + title, + description, + keyActions, + requiresLogin, + tenantScope, + onContinue, +}: PortalOverlayProps) { + return ( + + + + + {title} + {description} + + + + + +
+
+
+ +
+ +
+

{title}

+

{description}

+
+ +
+

Key Actions

+
    + {keyActions.map((action, index) => ( +
  • + + {action} +
  • + ))} +
+
+
+ +
+
+
+

User Type

+
+
+ Best For: + {tenantScope} +
+
+
+ +
+ + +
+
+ + +
+
+
+
+ ); +} diff --git a/src/components/PortalTile.tsx b/src/components/PortalTile.tsx new file mode 100644 index 0000000..29cb708 --- /dev/null +++ b/src/components/PortalTile.tsx @@ -0,0 +1,67 @@ +import { ArrowRight, LucideIcon } from "lucide-react"; +import { Button } from "./ui/button"; +import { Badge } from "./ui/badge"; + +interface PortalTileProps { + icon: LucideIcon; + title: string; + description: string; + features: string[]; + requiresLogin: boolean; + ctaText: string; + onCtaClick: () => void; + onLearnMore: () => void; + disabled?: boolean; +} + +export function PortalTile({ + icon: Icon, + title, + description, + features, + requiresLogin, + ctaText, + onCtaClick, + onLearnMore, + disabled = false, +}: PortalTileProps) { + return ( +
+
+
+
+ +
+
+ +
+

{title}

+

{description}

+
+ +
    + {features.map((feature, index) => ( +
  • + + {feature} +
  • + ))} +
+ +
+ +
+
+
+ ); +} diff --git a/src/components/QRScanModal.tsx b/src/components/QRScanModal.tsx new file mode 100644 index 0000000..de7638f --- /dev/null +++ b/src/components/QRScanModal.tsx @@ -0,0 +1,99 @@ +import { useState } from "react"; +import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription } from "./ui/dialog"; +import { Button } from "./ui/button"; +import { QrCode, Upload, Camera } from "lucide-react"; +import { Sheet, SheetContent, SheetHeader, SheetTitle } from "./ui/sheet"; + +interface QRScanModalProps { + open: boolean; + onClose: () => void; + isMobile?: boolean; +} + +export function QRScanModal({ open, onClose, isMobile = false }: QRScanModalProps) { + const [permissionGranted, setPermissionGranted] = useState(false); + + const handleRequestPermission = () => { + // Simulate camera permission + setPermissionGranted(true); + }; + + const content = ( +
+ {!permissionGranted ? ( +
+
+ +
+
+

Camera Access Required

+

+ We need access to your camera to scan QR codes +

+
+ +
+ ) : ( + <> +
+
+
+
+
+
+
+
+
+
+ Position QR code within frame +
+
+
+ +
+
+
+
+
+ Or +
+
+ + + + )} +
+ ); + + if (isMobile) { + return ( + + + + Scan QR Code + +
{content}
+
+
+ ); + } + + return ( + + + + Scan QR Code + + Scan or upload a QR code to quickly access products and stores + + + {content} + + + ); +} diff --git a/src/components/SmartSearch.tsx b/src/components/SmartSearch.tsx new file mode 100644 index 0000000..37140a9 --- /dev/null +++ b/src/components/SmartSearch.tsx @@ -0,0 +1,396 @@ +import { useState, useEffect, useRef } from "react"; +import { Search, Sparkles, TrendingUp, Clock, ArrowRight, Package, Users, FileText, Store } from "lucide-react"; +import { Input } from "./ui/input"; +import { Badge } from "./ui/badge"; +import { ScrollArea } from "./ui/scroll-area"; +import { Separator } from "./ui/separator"; +import { motion, AnimatePresence } from "motion/react"; + +interface SmartSearchProps { + portalType: "admin" | "retailer" | "manufacturer"; + placeholder?: string; + onNavigate?: (page: string, data?: any) => void; +} + +interface SearchResult { + id: string; + type: "product" | "customer" | "order" | "quote" | "page" | "user" | "tenant"; + title: string; + subtitle?: string; + badge?: string; + icon: any; + action?: string; + data?: any; +} + +const SEARCH_DATA = { + admin: [ + { + id: "1", + type: "user", + title: "Priya Sharma", + subtitle: "priya.sharma@novajewels.com", + badge: "Retailer Admin", + icon: Users, + }, + { + id: "2", + type: "tenant", + title: "Nova Jewels", + subtitle: "Mumbai • Active • 42 users", + badge: "Enterprise", + icon: Store, + }, + { + id: "3", + type: "user", + title: "Amit Kumar", + subtitle: "amit@sparklegems.com", + badge: "Retailer Admin", + icon: Users, + }, + { + id: "4", + type: "page", + title: "Analytics Dashboard", + subtitle: "View platform metrics and reports", + icon: TrendingUp, + action: "analytics", + }, + { + id: "5", + type: "page", + title: "User Management", + subtitle: "Manage users and permissions", + icon: Users, + action: "users", + }, + ], + retailer: [ + { + id: "1", + type: "product", + title: "Heritage Bridal Ring", + subtitle: "SKU: AU-22K-BR-0192 • 22K Gold", + badge: "₹2.8L", + icon: Package, + }, + { + id: "2", + type: "product", + title: "Classic Gold Necklace", + subtitle: "SKU: AU-22K-NK-0551 • 22K Gold", + badge: "₹1.8L", + icon: Package, + }, + { + id: "3", + type: "customer", + title: "Aditi Sharma", + subtitle: "aditi@email.com • Mumbai", + badge: "VIP", + icon: Users, + }, + { + id: "4", + type: "quote", + title: "Quote #Q-2847", + subtitle: "Aditi Sharma • Bridal Set • ₹4.2L", + badge: "Pending", + icon: FileText, + }, + { + id: "5", + type: "order", + title: "Order #ORD-2847", + subtitle: "Rohan Mehta • Completed", + badge: "₹2.8L", + icon: FileText, + }, + { + id: "6", + type: "page", + title: "Inventory Management", + subtitle: "Manage your product catalog", + icon: Package, + action: "inventory", + }, + { + id: "7", + type: "page", + title: "Customer Management", + subtitle: "View and manage customers", + icon: Users, + action: "customers", + }, + ], + manufacturer: [ + { + id: "1", + type: "product", + title: "Temple Design Necklace", + subtitle: "SKU: MFG-22K-NK-0551 • 22K Gold", + badge: "Available", + icon: Package, + }, + { + id: "2", + type: "product", + title: "Classic Bangle Set", + subtitle: "SKU: MFG-22K-BG-1023 • 22K Gold", + badge: "In Stock", + icon: Package, + }, + { + id: "3", + type: "user", + title: "Nova Jewels", + subtitle: "Connected Retailer • Mumbai", + badge: "124 Orders", + icon: Store, + }, + { + id: "4", + type: "order", + title: "Custom Order #CO-2847", + subtitle: "Nova Jewels • Ring Design", + badge: "Urgent", + icon: FileText, + }, + { + id: "5", + type: "page", + title: "Sharing & Connections", + subtitle: "Manage retailer partnerships", + icon: Users, + action: "sharing", + }, + ], +}; + +const RECENT_SEARCHES = { + admin: ["User analytics", "Active tenants", "Platform metrics"], + retailer: ["Gold rate today", "Bridal collection", "Pending quotes"], + manufacturer: ["Inventory status", "Connected retailers", "Custom orders"], +}; + +const TRENDING_SEARCHES = { + admin: ["Compliance reports", "New registrations", "Revenue analytics"], + retailer: ["Diamond rings", "Customer preferences", "Sales report"], + manufacturer: ["Production schedule", "Quality metrics", "Order fulfillment"], +}; + +export function SmartSearch({ portalType, placeholder, onNavigate }: SmartSearchProps) { + const [isOpen, setIsOpen] = useState(false); + const [searchQuery, setSearchQuery] = useState(""); + const [results, setResults] = useState([]); + const [isSearching, setIsSearching] = useState(false); + const inputRef = useRef(null); + const containerRef = useRef(null); + + const searchData = SEARCH_DATA[portalType]; + const recentSearches = RECENT_SEARCHES[portalType]; + const trendingSearches = TRENDING_SEARCHES[portalType]; + + useEffect(() => { + const handleClickOutside = (event: MouseEvent) => { + if (containerRef.current && !containerRef.current.contains(event.target as Node)) { + setIsOpen(false); + } + }; + + document.addEventListener("mousedown", handleClickOutside); + return () => document.removeEventListener("mousedown", handleClickOutside); + }, []); + + useEffect(() => { + if (searchQuery.trim()) { + setIsSearching(true); + const timer = setTimeout(() => { + const filtered = searchData.filter( + (item) => + item.title.toLowerCase().includes(searchQuery.toLowerCase()) || + item.subtitle?.toLowerCase().includes(searchQuery.toLowerCase()) + ); + setResults(filtered); + setIsSearching(false); + }, 300); + + return () => clearTimeout(timer); + } else { + setResults([]); + } + }, [searchQuery, portalType]); + + const handleResultClick = (result: SearchResult) => { + if (result.action && onNavigate) { + onNavigate(result.action, result.data); + } + setIsOpen(false); + setSearchQuery(""); + }; + + const handleQuickSearch = (query: string) => { + setSearchQuery(query); + inputRef.current?.focus(); + }; + + return ( +
+ {/* Search Input */} +
+ + setSearchQuery(e.target.value)} + onFocus={() => setIsOpen(true)} + placeholder={placeholder || "Search anything... (⌘K)"} + className="pl-10 pr-12" + /> + {searchQuery && ( + + + AI + + )} +
+ + {/* Search Results Dropdown */} + + {isOpen && ( + + + {/* Search Results */} + {searchQuery && ( +
+ {isSearching ? ( +
+
+
+

AI is searching...

+
+
+ ) : results.length > 0 ? ( +
+
+ +

AI-powered results

+
+ {results.map((result) => { + const Icon = result.icon; + return ( + + ); + })} +
+ ) : ( +
+ +

No results found

+

+ Try a different search term +

+
+ )} +
+ )} + + {/* Default State */} + {!searchQuery && ( +
+ {/* Recent Searches */} +
+
+ +

Recent

+
+
+ {recentSearches.map((search, i) => ( + + ))} +
+
+ + + + {/* Trending Searches */} +
+
+ +

Trending

+
+
+ {trendingSearches.map((search, i) => ( + + ))} +
+
+ + + + {/* AI Tips */} +
+
+ +
+

AI Search Tips

+

+ Try natural language like "Show me pending orders" or "Find customers in + Mumbai" +

+
+
+
+
+ )} + + + )} + +
+ ); +} diff --git a/src/components/TenantSelectModal.tsx b/src/components/TenantSelectModal.tsx new file mode 100644 index 0000000..155a79e --- /dev/null +++ b/src/components/TenantSelectModal.tsx @@ -0,0 +1,91 @@ +import { useState } from "react"; +import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription } from "./ui/dialog"; +import { Input } from "./ui/input"; +import { Button } from "./ui/button"; +import { Badge } from "./ui/badge"; +import { Search, Building2 } from "lucide-react"; + +interface Tenant { + id: string; + name: string; + logo?: string; + role: string; +} + +interface TenantSelectModalProps { + open: boolean; + onClose: () => void; + tenants: Tenant[]; + onSelectTenant: (tenant: Tenant) => void; +} + +export function TenantSelectModal({ + open, + onClose, + tenants, + onSelectTenant, +}: TenantSelectModalProps) { + const [search, setSearch] = useState(""); + + const filteredTenants = tenants.filter((tenant) => + tenant.name.toLowerCase().includes(search.toLowerCase()) + ); + + return ( + + + + Select Tenant + + Choose which organization you want to access + + + +
+
+ + setSearch(e.target.value)} + className="pl-10" + /> +
+ +
+ {filteredTenants.map((tenant) => ( + + ))} +
+ + {filteredTenants.length === 0 && ( +
+

No tenants found matching "{search}"

+
+ )} +
+
+
+ ); +} diff --git a/src/components/TopNavBar.tsx b/src/components/TopNavBar.tsx new file mode 100644 index 0000000..edc7a25 --- /dev/null +++ b/src/components/TopNavBar.tsx @@ -0,0 +1,155 @@ +import { useState } from "react"; +import { Search, Bell, ChevronDown, Moon, Sun } from "lucide-react"; +import { Input } from "./ui/input"; +import { Avatar, AvatarFallback } from "./ui/avatar"; +import { Button } from "./ui/button"; +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuLabel, + DropdownMenuSeparator, + DropdownMenuTrigger, +} from "./ui/dropdown-menu"; +import { Badge } from "./ui/badge"; + +interface TopNavBarProps { + userName: string; + userEmail: string; + currentTenant: string; + tenants: { id: string; name: string; role: string }[]; + onTenantSwitch: (tenantId: string) => void; + notificationCount?: number; + theme: "light" | "dark"; + onThemeToggle: () => void; +} + +export function TopNavBar({ + userName, + userEmail, + currentTenant, + tenants, + onTenantSwitch, + notificationCount = 0, + theme, + onThemeToggle, +}: TopNavBarProps) { + const [searchOpen, setSearchOpen] = useState(false); + + const initials = userName + .split(" ") + .map((n) => n[0]) + .join("") + .toUpperCase(); + + return ( +
+
+
+ {/* Logo */} +
+
+ H +
+ Hello Jewellers +
+ + {/* Search */} +
+
+ + setSearchOpen(true)} + /> +
+
+ + {/* Right side */} +
+ {/* Tenant Switcher */} + + + + + + Switch Tenant + + {tenants.map((tenant) => ( + onTenantSwitch(tenant.id)} + className="flex items-center justify-between" + > +
+ {tenant.name} + {tenant.role} +
+ {tenant.name === currentTenant && ( + + Active + + )} +
+ ))} +
+
+ + {/* Theme Toggle */} + + + {/* Notifications */} + + + {/* User Menu */} + + + + + + +
+ {userName} + {userEmail} +
+
+ + Profile Settings + Preferences + + Sign Out +
+
+
+
+
+
+ ); +} diff --git a/src/components/admin/AdminShell.tsx b/src/components/admin/AdminShell.tsx new file mode 100644 index 0000000..e482170 --- /dev/null +++ b/src/components/admin/AdminShell.tsx @@ -0,0 +1,476 @@ +import { useState } from "react"; +import { + LayoutDashboard, + Users, + FileText, + BarChart3, + Settings, + Search, + ChevronDown, + Menu, + X, + Bell, + User, +} from "lucide-react"; +import { Button } from "../ui/button"; +import { Input } from "../ui/input"; +import { AIAssistant } from "../AIAssistant"; +import { SmartSearch } from "../SmartSearch"; +import { Avatar, AvatarFallback } from "../ui/avatar"; +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuLabel, + DropdownMenuSeparator, + DropdownMenuTrigger, +} from "../ui/dropdown-menu"; +import { ScrollArea } from "../ui/scroll-area"; +import { Separator } from "../ui/separator"; +import { Sheet, SheetContent, SheetHeader, SheetTitle, SheetDescription } from "../ui/sheet"; +import { Card } from "../ui/card"; + +interface AdminShellProps { + children: React.ReactNode; + currentPage: string; + onNavigate: (page: string) => void; +} + +const navigationItems = [ + { id: "overview", label: "Overview", icon: LayoutDashboard, section: null }, + { + id: "users", + label: "Users", + icon: Users, + section: "Management", + children: [ + { id: "users-retailers", label: "Retailers" }, + { id: "users-manufacturers", label: "Manufacturers" }, + { id: "users-customers", label: "Customers" }, + ] + }, + { id: "content", label: "Content Management", icon: FileText, section: "Operations" }, + { id: "analytics", label: "Analytics", icon: BarChart3, section: "Analytics" }, + { id: "settings", label: "Settings", icon: Settings, section: null }, +]; + +export function AdminShell({ children, currentPage, onNavigate }: AdminShellProps) { + const [mobileMenuOpen, setMobileMenuOpen] = useState(false); + const [notificationsOpen, setNotificationsOpen] = useState(false); + const [profileOpen, setProfileOpen] = useState(false); + const [usersExpanded, setUsersExpanded] = useState( + currentPage.startsWith("users-") + ); + + const groupedNav = navigationItems.reduce((acc, item) => { + const section = item.section || "main"; + if (!acc[section]) acc[section] = []; + acc[section].push(item); + return acc; + }, {} as Record); + + const notifications = [ + { id: 1, title: "New Retailer Signup", message: "Nova Jewels has joined the platform", time: "5 min ago", unread: true }, + { id: 2, title: "System Update", message: "Platform maintenance scheduled for tonight", time: "1 hour ago", unread: true }, + { id: 3, title: "Analytics Report", message: "Weekly report is ready to view", time: "2 hours ago", unread: true }, + { id: 4, title: "Content Published", message: "New policy page has been published", time: "1 day ago", unread: false }, + ]; + + const handleNotificationClick = () => { + setNotificationsOpen(true); + }; + + const handleProfileClick = () => { + setProfileOpen(true); + }; + + const renderNavItem = (item: typeof navigationItems[0]) => { + const Icon = item.icon; + const isActive = currentPage === item.id || currentPage.startsWith(item.id + "-"); + const hasChildren = item.children && item.children.length > 0; + + if (hasChildren) { + return ( +
+ + {usersExpanded && item.children && ( +
+ {item.children.map((child) => ( + + ))} +
+ )} +
+ ); + } + + return ( + + ); + }; + + return ( +
+ {/* Top Bar */} +
+
+
+ {/* Mobile Menu Toggle */} + + + {/* Logo */} +
+
+ H +
+
+
Hello Jewellers
+
Super Admin
+
+
+ + {/* Smart AI Search - centered with max width */} +
+ +
+ + {/* Right Actions */} +
+ {/* Notifications */} + + + {/* User Menu */} + + + + + + +
+ Super Admin + admin@hellojewellers.com +
+
+ + + + Profile Settings + + onNavigate("settings")}> + + Preferences + + + Sign Out +
+
+
+
+
+
+ +
+ {/* Side Navigation */} + + + {/* Main Content */} +
+
+ {children} +
+
+
+ + {/* AI Assistant */} + + + {/* Notifications Sheet */} + + +
+ + Notifications + View and manage your notifications + +
+ +
+ {notifications.map((notification) => ( +
+
+

{notification.title}

+ {notification.unread && ( +
+ )} +
+

+ {notification.message} +

+

{notification.time}

+
+ ))} +
+ +
+ +
+ + + + {/* Profile Dialog - Full Screen */} + {profileOpen && ( +
+ {/* Header */} +
+
+
+

Admin Profile

+

Manage your profile settings and security

+
+ +
+
+ + {/* Content */} + +
+ {/* Profile Picture Section */} + +

Profile Picture

+
+ + SA + +
+
+ + +
+

+ JPG, PNG or GIF. Max size 2MB. +

+
+
+
+ + {/* Personal Information */} + +

Personal Information

+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+
+ + {/* Security Settings */} + +

Security

+
+
+
+
Password
+
Last changed 45 days ago
+
+ +
+
+
+
Two-Factor Authentication
+
Add an extra layer of security
+
+ +
+
+
+
Active Sessions
+
3 devices currently logged in
+
+ +
+
+
+
Login History
+
View recent login activity
+
+ +
+
+
+ + {/* Preferences */} + +

Preferences

+
+
+
+
Language
+
Choose your preferred language
+
+ +
+ +
+
+
Time Zone
+
Set your local time zone
+
+ +
+ +
+
+
Email Notifications
+
Receive email updates
+
+ +
+
+
+ + {/* Action Buttons */} +
+ + +
+
+
+
+ )} +
+ ); +} diff --git a/src/components/admin/RoleBadge.tsx b/src/components/admin/RoleBadge.tsx new file mode 100644 index 0000000..1c2526a --- /dev/null +++ b/src/components/admin/RoleBadge.tsx @@ -0,0 +1,25 @@ +import { Badge } from "../ui/badge"; + +type RoleType = "admin" | "retailer-admin" | "retail-associate" | "manufacturer-admin" | "customer" | "auditor"; + +interface RoleBadgeProps { + role: RoleType; + children: React.ReactNode; +} + +const roleStyles: Record = { + admin: "bg-role-admin/10 text-role-admin border-role-admin/20", + "retailer-admin": "bg-role-retailer-admin/10 text-role-retailer-admin border-role-retailer-admin/20", + "retail-associate": "bg-role-retail-associate/10 text-role-retail-associate border-role-retail-associate/20", + "manufacturer-admin": "bg-role-manufacturer-admin/10 text-role-manufacturer-admin border-role-manufacturer-admin/20", + customer: "bg-role-customer/10 text-role-customer border-role-customer/20", + auditor: "bg-role-auditor/10 text-role-auditor border-role-auditor/20", +}; + +export function RoleBadge({ role, children }: RoleBadgeProps) { + return ( + + {children} + + ); +} diff --git a/src/components/admin/StatCard.tsx b/src/components/admin/StatCard.tsx new file mode 100644 index 0000000..53f10ff --- /dev/null +++ b/src/components/admin/StatCard.tsx @@ -0,0 +1,37 @@ +import { Card } from "../ui/card"; +import { LucideIcon, TrendingUp, TrendingDown } from "lucide-react"; + +interface StatCardProps { + title: string; + value: string | number; + icon: LucideIcon; + trend?: { + value: string; + positive: boolean; + }; + iconColor?: string; +} + +export function StatCard({ title, value, icon: Icon, trend, iconColor = "text-primary" }: StatCardProps) { + return ( + +
+

{title}

+ +
+

{value}

+ {trend && ( +
+ {trend.positive ? ( + + ) : ( + + )} + + {trend.value} + +
+ )} +
+ ); +} diff --git a/src/components/admin/StatusBadge.tsx b/src/components/admin/StatusBadge.tsx new file mode 100644 index 0000000..ee42890 --- /dev/null +++ b/src/components/admin/StatusBadge.tsx @@ -0,0 +1,27 @@ +import { Badge } from "../ui/badge"; + +type StatusType = "active" | "suspended" | "trial" | "over-limit" | "flagged" | "pending" | "compliant" | "action-needed"; + +interface StatusBadgeProps { + status: StatusType; + children: React.ReactNode; +} + +const statusStyles: Record = { + active: "bg-status-active/10 text-status-active border-status-active/20", + suspended: "bg-status-suspended/10 text-status-suspended border-status-suspended/20", + trial: "bg-status-trial/10 text-status-trial border-status-trial/20", + "over-limit": "bg-status-over-limit/10 text-status-over-limit border-status-over-limit/20", + flagged: "bg-status-flagged/10 text-status-flagged border-status-flagged/20", + pending: "bg-status-pending/10 text-status-pending border-status-pending/20", + compliant: "bg-status-compliant/10 text-status-compliant border-status-compliant/20", + "action-needed": "bg-status-action-needed/10 text-status-action-needed border-status-action-needed/20", +}; + +export function StatusBadge({ status, children }: StatusBadgeProps) { + return ( + + {children} + + ); +} diff --git a/src/components/admin/pages/AnalyticsPage.tsx b/src/components/admin/pages/AnalyticsPage.tsx new file mode 100644 index 0000000..f8ab040 --- /dev/null +++ b/src/components/admin/pages/AnalyticsPage.tsx @@ -0,0 +1,241 @@ +import { TrendingUp, Users, Package, ShoppingBag, BarChart3 } from "lucide-react"; +import { Card } from "../../ui/card"; +import { StatCard } from "../StatCard"; +import { Tabs, TabsContent, TabsList, TabsTrigger } from "../../ui/tabs"; +import { + Table, + TableBody, + TableCell, + TableHead, + TableHeader, + TableRow, +} from "../../ui/table"; + +const topRetailers = [ + { name: "Sparkle Jewels Pvt Ltd", views: 24850, inquiries: 342, conversion: "14.2%", responseTime: "2.4h" }, + { name: "Auric Gold Co.", views: 18420, inquiries: 256, conversion: "12.8%", responseTime: "3.1h" }, + { name: "Nova Jewels", views: 15680, inquiries: 198, conversion: "11.4%", responseTime: "2.8h" }, + { name: "Zephyr Gems LLP", views: 12340, inquiries: 165, conversion: "10.2%", responseTime: "4.2h" }, +]; + +const categoryDemand = [ + { category: "Bridal", inquiries: 842, orders: 124, avgValue: "₹2.8L" }, + { category: "Daily Wear", inquiries: 1240, orders: 340, avgValue: "₹45K" }, + { category: "Temple Jewellery", inquiries: 580, orders: 86, avgValue: "₹1.2L" }, + { category: "Contemporary", inquiries: 420, orders: 92, avgValue: "₹68K" }, +]; + +export function AnalyticsPage() { + return ( +
+
+

Platform Analytics

+

+ Track usage, growth, and performance across the platform +

+
+ + + + Platform Overview + Tenant Growth + Retailer Performance + Demand Insights + + + + {/* Platform KPIs */} +
+ + + + +
+ + {/* Usage Trends Chart */} + +

Usage Trends (30 Days)

+
+

Chart: Daily Active Users & Engagement

+
+
+ + {/* Engagement Metrics */} +
+ +

Customer Funnel

+
+
+
+ Wishlist Adds + 8,420 +
+
+
+
+
+
+
+ Inquiries + 2,840 +
+
+
+
+
+
+
+ Appointments + 840 +
+
+
+
+
+
+
+ Orders + 420 +
+
+
+
+
+
+ + + +

Notification Impact

+
+
+
+

OTP Messages

+

Delivery: 99.8%

+
+ 8,240 +
+
+
+

Quote Ready

+

Open Rate: 84%

+
+ 2,180 +
+
+
+

Order Updates

+

Reply Rate: 42%

+
+ 1,840 +
+
+
+
+ + + + +

Tenant Activation Funnel

+
+

Chart: Invite → Setup → First Publish → First Order

+
+
+
+ + + +
+

Top Performing Retailers

+

Last 30 days

+
+ + + + Retailer + Views + Inquiries + Conversion + Avg Response Time + + + + {topRetailers.map((retailer, index) => ( + + {retailer.name} + {retailer.views.toLocaleString()} + {retailer.inquiries} + {retailer.conversion} + {retailer.responseTime} + + ))} + +
+
+
+ + + +
+

Category Demand Insights

+

Last 30 days

+
+ + + + Category + Inquiries + Orders + Avg Order Value + + + + {categoryDemand.map((category, index) => ( + + {category.category} + {category.inquiries} + {category.orders} + {category.avgValue} + + ))} + +
+
+ + +

Demand Heatmap (Next 4 Weeks - Forecast)

+
+

Visual: Category × Occasion demand prediction

+
+

+ * Forecasting based on historical trends and upcoming occasions +

+
+
+ +
+ ); +} diff --git a/src/components/admin/pages/CompliancePage.tsx b/src/components/admin/pages/CompliancePage.tsx new file mode 100644 index 0000000..bbf6d59 --- /dev/null +++ b/src/components/admin/pages/CompliancePage.tsx @@ -0,0 +1,314 @@ +import { Shield, CheckCircle, AlertTriangle, FileText, Clock } from "lucide-react"; +import { Card } from "../../ui/card"; +import { StatCard } from "../StatCard"; +import { StatusBadge } from "../StatusBadge"; +import { Button } from "../../ui/button"; +import { Tabs, TabsContent, TabsList, TabsTrigger } from "../../ui/tabs"; +import { + Table, + TableBody, + TableCell, + TableHead, + TableHeader, + TableRow, +} from "../../ui/table"; + +const dsrQueue = [ + { + id: "DSR-2025-0091", + type: "Access", + subject: "Priya Sharma", + email: "priya@example.com", + submitted: "2 days ago", + sla: "5 days remaining", + status: "pending" as const, + }, + { + id: "DSR-2025-0104", + type: "Deletion", + subject: "Amit Patel", + email: "amit@example.com", + submitted: "1 day ago", + sla: "6 days remaining", + status: "pending" as const, + }, + { + id: "DSR-2025-0088", + type: "Correction", + subject: "Sarah Johnson", + email: "sarah@example.com", + submitted: "4 days ago", + sla: "3 days remaining", + status: "pending" as const, + }, +]; + +const consentRecords = [ + { + subject: "Rajesh Kumar", + channel: "WhatsApp", + purpose: "Order Updates", + timestamp: "2025-01-08 14:23", + status: "granted" as const, + }, + { + subject: "Priya Sharma", + channel: "Email", + purpose: "Marketing", + timestamp: "2025-01-10 09:15", + status: "granted" as const, + }, + { + subject: "Dev Mehta", + channel: "SMS", + purpose: "OTP", + timestamp: "2025-01-11 16:40", + status: "granted" as const, + }, +]; + +export function CompliancePage() { + return ( +
+
+

DPDP Compliance

+

+ Manage data privacy, consent, and subject rights compliance +

+
+ + {/* Compliance Scorecard */} +
+ + + + +
+ + {/* Compliance Posture */} + +

Compliance Posture

+
+
+
+
+ Data Minimization + Compliant +
+
+
+
+
+ +
+
+ Consent Management + Compliant +
+
+
+
+
+ +
+
+ Retention Hygiene + Needs Review +
+
+
+
+
+ +
+
+ Breach Readiness + Compliant +
+
+
+
+
+
+ +
+
+ +
+

Action Required

+

+ 2 retention policies need configuration for new data types +

+
+
+ +
+
+ + + + + Data Subject Requests + Consent Registry + Retention Policies + Security Settings + + + + +
+
+
+

DSR Queue

+

+ {dsrQueue.length} pending requests +

+
+ +
+
+ + + + Request ID + Type + Subject + Submitted + SLA + Status + Actions + + + + {dsrQueue.map((dsr) => ( + + {dsr.id} + + {dsr.type} + + +
+

{dsr.subject}

+

{dsr.email}

+
+
+ {dsr.submitted} + {dsr.sla} + + Pending + + + + +
+ ))} +
+
+
+
+ + + +
+

Consent Records

+

+ Recent consent grants and revocations +

+
+ + + + Subject + Channel + Purpose + Timestamp + Status + + + + {consentRecords.map((record, index) => ( + + {record.subject} + {record.channel} + {record.purpose} + {record.timestamp} + + Granted + + + ))} + +
+
+
+ + + + +

Retention Policy Configuration

+

+ Configure auto-delete schedules for different data types +

+ +
+
+ + + +

Security Controls

+
+
+
+

MFA Enforcement

+

Required for all admin users

+
+ Enabled +
+
+
+

Session Timeout

+

Auto logout after 30 minutes idle

+
+ Active +
+
+
+

Webhook Signing

+

HMAC-SHA256 verification

+
+ Enabled +
+
+
+

IP Allow List

+

Restrict admin access by IP

+
+ +
+
+
+
+
+
+ ); +} diff --git a/src/components/admin/pages/ConnectionsPage.tsx b/src/components/admin/pages/ConnectionsPage.tsx new file mode 100644 index 0000000..93d6cdd --- /dev/null +++ b/src/components/admin/pages/ConnectionsPage.tsx @@ -0,0 +1,61 @@ +import { Link2, AlertCircle } from "lucide-react"; +import { Card } from "../../ui/card"; +import { Button } from "../../ui/button"; + +export function ConnectionsPage() { + return ( +
+
+

Connections Governance

+

+ Manage retailer-manufacturer sharing policies and compliance +

+
+ + + +

Connections Management

+

+ View and manage catalogue sharing connections between manufacturers and retailers +

+
+ + +
+
+ +
+ +
+ +
+

2 Policy Violations

+

+ Retailers publishing hidden SKUs or pricing below MRP band +

+ +
+
+
+ + +

Active Connections

+
+
+ Total Connections + 124 +
+
+ Active Shares + 8,420 SKUs +
+
+ Pending Approvals + 12 +
+
+
+
+
+ ); +} diff --git a/src/components/admin/pages/ContentPage.tsx b/src/components/admin/pages/ContentPage.tsx new file mode 100644 index 0000000..9abbe5e --- /dev/null +++ b/src/components/admin/pages/ContentPage.tsx @@ -0,0 +1,398 @@ +import { FileText, Globe, Users, ShoppingBag, Factory } from "lucide-react"; +import { Card } from "../../ui/card"; +import { Button } from "../../ui/button"; +import { + Table, + TableBody, + TableCell, + TableHead, + TableHeader, + TableRow, +} from "../../ui/table"; +import { StatusBadge } from "../StatusBadge"; +import { Tabs, TabsContent, TabsList, TabsTrigger } from "../../ui/tabs"; + +const platformPages = [ + { name: "Terms of Service", platform: "All Platforms", status: "active" as const, lastUpdated: "2024-12-15", version: "v2.1" }, + { name: "Privacy Policy", platform: "All Platforms", status: "active" as const, lastUpdated: "2024-12-15", version: "v2.1" }, + { name: "DPDP Compliance Notice", platform: "All Platforms", status: "active" as const, lastUpdated: "2025-01-05", version: "v1.3" }, + { name: "Refund & Return Policy", platform: "Customer App", status: "active" as const, lastUpdated: "2024-11-20", version: "v1.8" }, + { name: "Shipping Policy", platform: "Customer App", status: "active" as const, lastUpdated: "2024-10-12", version: "v1.5" }, +]; + +const helpContent = [ + { category: "Getting Started", platform: "Customer App", articles: 12, status: "active" as const }, + { category: "Account Management", platform: "All Platforms", articles: 8, status: "active" as const }, + { category: "Inventory Setup", platform: "Retailer Portal", articles: 15, status: "active" as const }, + { category: "Catalogue Management", platform: "Manufacturer Portal", articles: 18, status: "active" as const }, + { category: "Order Processing", platform: "Retailer Portal", articles: 10, status: "active" as const }, + { category: "Custom Orders", platform: "Manufacturer Portal", articles: 7, status: "active" as const }, + { category: "Analytics & Reports", platform: "All Platforms", articles: 9, status: "active" as const }, +]; + +const emailTemplates = [ + { name: "Welcome Email", platform: "All Platforms", status: "active" as const, lastUpdated: "2024-12-01" }, + { name: "Order Confirmation", platform: "Customer App", status: "active" as const, lastUpdated: "2024-11-15" }, + { name: "Appointment Reminder", platform: "Customer App", status: "active" as const, lastUpdated: "2024-11-28" }, + { name: "Quote Request Received", platform: "Retailer Portal", status: "active" as const, lastUpdated: "2024-10-20" }, + { name: "Inventory Alert", platform: "Retailer Portal", status: "active" as const, lastUpdated: "2024-12-10" }, + { name: "PO Notification", platform: "Manufacturer Portal", status: "active" as const, lastUpdated: "2024-11-05" }, +]; + +const bannerContent = [ + { name: "Holiday Season Sale", platform: "Customer App", status: "active" as const, startDate: "2025-01-10", endDate: "2025-01-20" }, + { name: "New Collection Launch", platform: "Retailer Portal", status: "active" as const, startDate: "2025-01-08", endDate: "2025-01-15" }, + { name: "System Maintenance Notice", platform: "All Platforms", status: "pending" as const, startDate: "2025-01-14", endDate: "2025-01-14" }, +]; + +export function ContentPage() { + return ( +
+
+

Content Management

+

+ Manage platform content, policies, help documentation, and communications across all portals +

+
+ + + + + + Legal & Policy Pages + + + + Help & Documentation + + + + Email Templates + + + + Announcements + + + + {/* Legal & Policy Pages */} + + + + + + Page Title + Platform + Status + Last Updated + Version + Actions + + + + {platformPages.map((page, index) => ( + + +
+ + {page.name} +
+
+ +
+ {page.platform === "All Platforms" && } + {page.platform === "Customer App" && } + {page.platform === "Retailer Portal" && } + {page.platform === "Manufacturer Portal" && } + {page.platform} +
+
+ + Published + + {page.lastUpdated} + {page.version} + +
+ + +
+
+
+ ))} +
+
+
+ +
+ +

Localization Coverage

+
+
+ English (Primary) + 100% +
+
+ हिन्दी (Hindi) + 85% +
+
+ मराठी (Marathi) + 72% +
+
+ ગુજરાતી (Gujarati) + 45% +
+
+
+ + +

Content Compliance

+
+
+ DPDP Compliant + Yes +
+
+ Last Audit + 2025-01-05 +
+
+ Next Review + 2025-04-05 +
+
+
+
+
+ + {/* Help & Documentation */} + + + + + + Category + Platform + Articles + Status + Actions + + + + {helpContent.map((item, index) => ( + + +
+ + {item.category} +
+
+ +
+ {item.platform === "All Platforms" && } + {item.platform === "Customer App" && } + {item.platform === "Retailer Portal" && } + {item.platform === "Manufacturer Portal" && } + {item.platform} +
+
+ {item.articles} articles + + Active + + + + +
+ ))} +
+
+
+ + +
+

Documentation Stats

+
+
+
+
79
+
Total Articles
+
+
+
95%
+
Completion
+
+
+
3.2k
+
Monthly Views
+
+
+
12
+
Updates This Month
+
+
+
+
+ + {/* Email Templates */} + + + + + + Template Name + Platform + Status + Last Updated + Actions + + + + {emailTemplates.map((template, index) => ( + + +
+ + {template.name} +
+
+ +
+ {template.platform === "All Platforms" && } + {template.platform === "Customer App" && } + {template.platform === "Retailer Portal" && } + {template.platform === "Manufacturer Portal" && } + {template.platform} +
+
+ + Active + + {template.lastUpdated} + +
+ + +
+
+
+ ))} +
+
+
+ + +

Email Delivery Stats

+
+
+
12.4k
+
Sent This Month
+
+
+
98.2%
+
Delivery Rate
+
+
+
42%
+
Open Rate
+
+
+
8%
+
Click Rate
+
+
+
+
+ + {/* Announcements & Banners */} + + + + + + Announcement + Platform + Status + Start Date + End Date + Actions + + + + {bannerContent.map((banner, index) => ( + + +
+ + {banner.name} +
+
+ +
+ {banner.platform === "All Platforms" && } + {banner.platform === "Customer App" && } + {banner.platform === "Retailer Portal" && } + {banner.platform} +
+
+ + + {banner.status === "active" ? "Active" : "Scheduled"} + + + {banner.startDate} + {banner.endDate} + +
+ + {banner.status === "active" && ( + + )} +
+
+
+ ))} +
+
+
+ + +

Active Announcements by Platform

+
+
+
+ + Customer App +
+ 1 active +
+
+
+ + Retailer Portal +
+ 1 active +
+
+
+ + Manufacturer Portal +
+ 0 active +
+
+
+ + All Platforms +
+ 0 active, 1 scheduled +
+
+
+
+
+
+ ); +} diff --git a/src/components/admin/pages/ModerationPage.tsx b/src/components/admin/pages/ModerationPage.tsx new file mode 100644 index 0000000..b2dd46b --- /dev/null +++ b/src/components/admin/pages/ModerationPage.tsx @@ -0,0 +1,250 @@ +import { useState } from "react"; +import { ShieldCheck, CheckCircle, XCircle, Clock, AlertTriangle } from "lucide-react"; +import { Card } from "../../ui/card"; +import { Button } from "../../ui/button"; +import { + Table, + TableBody, + TableCell, + TableHead, + TableHeader, + TableRow, +} from "../../ui/table"; +import { StatusBadge } from "../StatusBadge"; +import { StatCard } from "../StatCard"; +import { Badge } from "../../ui/badge"; + +const moderationQueue = [ + { + id: "SKU-2025-0847", + title: "22K Gold Temple Necklace Set", + tenant: "Sparkle Jewels Pvt Ltd", + type: "Manufacturer", + flags: ["Missing Hallmark", "Price Anomaly"], + submitted: "18 hours ago", + sla: "30h remaining", + slaStatus: "ok" as const, + }, + { + id: "SKU-2025-0912", + title: "Diamond Stud Earrings 0.5ct", + tenant: "Auric Gold Co.", + type: "Retailer", + flags: ["Bad Image Quality"], + submitted: "52 hours ago", + sla: "Overdue 4h", + slaStatus: "overdue" as const, + }, + { + id: "SKU-2025-0723", + title: "Silver Oxidized Bangles Set", + tenant: "Zephyr Gems LLP", + type: "Manufacturer", + flags: ["Duplicate SKU"], + submitted: "6 hours ago", + sla: "42h remaining", + slaStatus: "ok" as const, + }, + { + id: "SKU-2025-0834", + title: "Bridal Polki Choker", + tenant: "Nova Jewels", + type: "Retailer", + flags: ["Missing Fields", "Price Anomaly"], + submitted: "48 hours ago", + sla: "Critical", + slaStatus: "critical" as const, + }, +]; + +export function ModerationPage() { + const [selectedItem, setSelectedItem] = useState(null); + + const pendingCount = moderationQueue.length; + const overdueCount = moderationQueue.filter((item) => item.slaStatus !== "ok").length; + + return ( +
+
+

Catalogue Oversight

+

+ Review and moderate catalogue submissions from retailers and manufacturers +

+
+ + {/* Stats */} +
+ + + + +
+ + {/* Quick Actions */} + +
+ + + + +
+
+ + {/* Moderation Queue */} + + + + + + + + SKU / Title + Tenant + Flags + Submitted + SLA + Actions + + + + {moderationQueue.map((item) => ( + + + + + +
+

{item.id}

+

{item.title}

+
+
+ +
+

{item.tenant}

+ {item.type} +
+
+ +
+ {item.flags.map((flag, index) => ( + + {flag} + + ))} +
+
+ + {item.submitted} + + + + {item.sla} + + + +
+ + + +
+
+
+ ))} +
+
+
+ + {selectedItem && ( + +
+

Item Details: {selectedItem}

+ +
+
+
+
+

Product Image Preview

+
+
+ + +
+
+
+
+

Specifications

+
+
+ Metal: + Gold 22K +
+
+ Weight: + 45.2g +
+
+ MRP: + ₹3,42,000 +
+
+ Making Charges: + 18% +
+
+
+
+ + + +
+
+
+
+ )} +
+ ); +} diff --git a/src/components/admin/pages/NotificationsPage.tsx b/src/components/admin/pages/NotificationsPage.tsx new file mode 100644 index 0000000..221603a --- /dev/null +++ b/src/components/admin/pages/NotificationsPage.tsx @@ -0,0 +1,157 @@ +import { Bell, Plus, Mail, MessageSquare, Smartphone } from "lucide-react"; +import { Card } from "../../ui/card"; +import { Button } from "../../ui/button"; +import { + Table, + TableBody, + TableCell, + TableHead, + TableHeader, + TableRow, +} from "../../ui/table"; +import { StatusBadge } from "../StatusBadge"; +import { StatCard } from "../StatCard"; + +const templates = [ + { name: "OTP", channel: "SMS", linkedEvents: 1, lastEdited: "2024-12-10", status: "active" as const }, + { name: "Quote Ready", channel: "WhatsApp", linkedEvents: 1, lastEdited: "2024-12-28", status: "active" as const }, + { name: "Order: Under Making", channel: "Email", linkedEvents: 1, lastEdited: "2025-01-05", status: "active" as const }, + { name: "Appointment Confirmed", channel: "Email", linkedEvents: 1, lastEdited: "2024-11-15", status: "active" as const }, + { name: "Moderation Result", channel: "Email", linkedEvents: 2, lastEdited: "2024-12-20", status: "active" as const }, + { name: "Plan Limit 80%", channel: "Email", linkedEvents: 1, lastEdited: "2024-12-01", status: "active" as const }, +]; + +const deliveryLogs = [ + { template: "OTP", channel: "SMS", tenant: "Sparkle Jewels", status: "delivered", timestamp: "2 mins ago" }, + { template: "Quote Ready", channel: "WhatsApp", tenant: "Auric Gold", status: "delivered", timestamp: "15 mins ago" }, + { template: "Order Update", channel: "Email", tenant: "Nova Jewels", status: "delivered", timestamp: "1 hour ago" }, +]; + +export function NotificationsPage() { + return ( +
+
+
+

Notifications Orchestrator

+

+ Manage templates, routing rules, and delivery monitoring +

+
+ +
+ +
+ + + + +
+ + +
+

Templates

+

+ Email, SMS, WhatsApp, and Push notification templates +

+
+ + + + Template Name + Channel + Linked Events + Last Edited + Status + Actions + + + + {templates.map((template, index) => ( + + {template.name} + +
+ {template.channel === "SMS" && } + {template.channel === "WhatsApp" && } + {template.channel === "Email" && } + {template.channel} +
+
+ {template.linkedEvents} event{template.linkedEvents > 1 ? "s" : ""} + {template.lastEdited} + + Active + + +
+ + +
+
+
+ ))} +
+
+
+ + +
+
+
+

Recent Delivery Logs

+

Last 100 notifications

+
+ +
+
+ + + + Template + Channel + Tenant + Status + Timestamp + + + + {deliveryLogs.map((log, index) => ( + + {log.template} + {log.channel} + {log.tenant} + + Delivered + + {log.timestamp} + + ))} + +
+
+
+ ); +} diff --git a/src/components/admin/pages/OverviewPage.tsx b/src/components/admin/pages/OverviewPage.tsx new file mode 100644 index 0000000..e375482 --- /dev/null +++ b/src/components/admin/pages/OverviewPage.tsx @@ -0,0 +1,154 @@ +import { Building2, Users, Package, TrendingUp, ShieldAlert, Clock } from "lucide-react"; +import { StatCard } from "../StatCard"; +import { Card } from "../../ui/card"; +import { Button } from "../../ui/button"; +import { StatusBadge } from "../StatusBadge"; + +interface OverviewPageProps { + onNavigate: (page: string) => void; +} + +const quickActions = [ + { id: "users-retailers", label: "Manage Retailers", description: "View and manage retailer accounts" }, + { id: "users-manufacturers", label: "Manage Manufacturers", description: "View and manage manufacturer accounts" }, + { id: "users-customers", label: "Manage Customers", description: "View and manage customer accounts" }, + { id: "content", label: "Content Management", description: "Manage static pages and policies" }, + { id: "analytics", label: "Platform Analytics", description: "View usage and growth metrics" }, + { id: "settings", label: "System Settings", description: "Configure platform settings" }, +]; + +const recentActivity = [ + { event: "New retailer registered", tenant: "Zephyr Gems LLP", time: "2 hours ago", status: "active" as const }, + { event: "Manufacturer verified", tenant: "Auric Foundry", time: "5 hours ago", status: "active" as const }, + { event: "Customer account created", tenant: "John Doe", time: "1 day ago", status: "active" as const }, + { event: "Content page updated", tenant: "Privacy Policy", time: "2 days ago", status: "compliant" as const }, +]; + +const systemAlerts = [ + { message: "5 new retailer registrations pending review", severity: "warning", action: "Review Users" }, + { message: "Platform content updates available", severity: "warning", action: "View Content" }, + { message: "Weekly analytics report ready", severity: "info", action: "View Report" }, +]; + +export function OverviewPage({ onNavigate }: OverviewPageProps) { + return ( +
+
+

Admin Console

+

+ Welcome back! Here's what's happening across your platform. +

+
+ + {/* Stats Grid */} +
+ + + + +
+ + {/* System Alerts */} + {systemAlerts.length > 0 && ( + +
+

System Alerts

+ {systemAlerts.length} Active +
+
+ {systemAlerts.map((alert, index) => ( +
+
+ + {alert.message} +
+ +
+ ))} +
+
+ )} + + {/* Quick Actions Grid */} +
+

Quick Actions

+
+ {quickActions.map((action) => ( + onNavigate(action.id)} + > +

{action.label}

+

{action.description}

+
+ ))} +
+
+ + {/* Recent Activity */} + +
+

Recent Activity

+ +
+
+ {recentActivity.map((activity, index) => ( +
+
+ +
+

{activity.event}

+

{activity.tenant}

+
+
+
+ + {activity.status.charAt(0).toUpperCase() + activity.status.slice(1)} + + {activity.time} +
+
+ ))} +
+
+
+ ); +} diff --git a/src/components/admin/pages/SettingsPage.tsx b/src/components/admin/pages/SettingsPage.tsx new file mode 100644 index 0000000..5c9ad4b --- /dev/null +++ b/src/components/admin/pages/SettingsPage.tsx @@ -0,0 +1,676 @@ +import { + Settings, + Globe, + Shield, + Bell, + Palette, + Database, + Mail, + Server, + Key, + Clock, + AlertCircle, + CheckCircle2, + Moon, + Sun +} from "lucide-react"; +import { Card } from "../../ui/card"; +import { Button } from "../../ui/button"; +import { Input } from "../../ui/input"; +import { Separator } from "../../ui/separator"; +import { Switch } from "../../ui/switch"; +import { Tabs, TabsContent, TabsList, TabsTrigger } from "../../ui/tabs"; +import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "../../ui/select"; +import { Label } from "../../ui/label"; +import { Textarea } from "../../ui/textarea"; + +export function SettingsPage() { + return ( +
+
+

Settings

+

+ Configure platform settings, security, and system preferences +

+
+ + + + + + General + + + + Appearance + + + + Security + + + + Notifications + + + + Integrations + + + + Advanced + + + + {/* General Settings */} + + +

Platform Information

+
+
+
+ + +
+
+ + +
+
+
+ +