diff --git a/.env b/.env new file mode 100644 index 0000000..907e903 --- /dev/null +++ b/.env @@ -0,0 +1,2 @@ +VITE_API_BASE_URL=http://localhost:8000 +VITE_API_KEY=DUMUqJrNeyuaPDSZSsMf91qjgwc5K3N7 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a547bf3 --- /dev/null +++ b/.gitignore @@ -0,0 +1,24 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +dist +dist-ssr +*.local + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +.DS_Store +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? diff --git a/.oxlintrc.json b/.oxlintrc.json new file mode 100644 index 0000000..1255078 --- /dev/null +++ b/.oxlintrc.json @@ -0,0 +1,8 @@ +{ + "$schema": "./node_modules/oxlint/configuration_schema.json", + "plugins": ["react", "oxc"], + "rules": { + "react/rules-of-hooks": "error", + "react/only-export-components": ["warn", { "allowConstantExport": true }] + } +} diff --git a/index.html b/index.html new file mode 100644 index 0000000..cf7c47c --- /dev/null +++ b/index.html @@ -0,0 +1,17 @@ + + + + + + + + CureSelect Healthcare | Super Admin + + + + + +
+ + + diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..e0afb5b --- /dev/null +++ b/package-lock.json @@ -0,0 +1,1852 @@ +{ + "name": "super-admin-home-care", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "super-admin-home-care", + "version": "1.0.0", + "dependencies": { + "react": "^18.3.1", + "react-dom": "^18.3.1" + }, + "devDependencies": { + "@types/react": "^18.3.12", + "@types/react-dom": "^18.3.1", + "@vitejs/plugin-react": "^4.3.4", + "vite": "^6.0.1" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.7.tgz", + "integrity": "sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.29.7", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.7.tgz", + "integrity": "sha512-locTkQyKvwIEgBzVrn8693ebc97F2U8ZHjbXwDXJ5Fn2TCpNwTlKcaKLkdHop5c/icOFE7qt7Q9JC5hnKNa6Gg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.29.7.tgz", + "integrity": "sha512-RgHBCvtjbOK2gXSNBNIkNoEc9qoVEtau3hj8gEqKQuL3HZAibKarWFEI3Lfm6EYKkLalOh8eSrj9b+ch9H/VBA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.7", + "@babel/generator": "^7.29.7", + "@babel/helper-compilation-targets": "^7.29.7", + "@babel/helper-module-transforms": "^7.29.7", + "@babel/helpers": "^7.29.7", + "@babel/parser": "^7.29.7", + "@babel/template": "^7.29.7", + "@babel/traverse": "^7.29.7", + "@babel/types": "^7.29.7", + "@jridgewell/remapping": "^2.3.5", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/generator": { + "version": "7.29.8", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.8.tgz", + "integrity": "sha512-gZbepsdh3WDtgZKWL+vTPh71LSBrm/Y4/QDZBVCcYfmeTEEuoOYwlSy+G1StfJg+/Zy550u/3TATbm7qDbbMtg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.29.8", + "@babel/types": "^7.29.8", + "@jridgewell/gen-mapping": "^0.3.12", + "@jridgewell/trace-mapping": "^0.3.28", + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.29.7.tgz", + "integrity": "sha512-wem6WaBj4NaVYVdNhLPPVacES6ZJ+KBBfSkTMD3YZxbP3rm3Di85tJU5ljaUNhaOynt+Aj0xruhYuzQBt8n71g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.29.7", + "@babel/helper-validator-option": "^7.29.7", + "browserslist": "^4.24.0", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-globals": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.29.7.tgz", + "integrity": "sha512-3nQVUAtvkKH9zahfWgw96Jc/uFOmjACE1kQz82E2lqWmHBgjzbNlsC22nuQTfahmWeQtTq5nQ/4Nnd2A1wj4zA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.29.7.tgz", + "integrity": "sha512-ejHwrQQYcm9xnTivShn2IDOlIzInN34AXskvq9QicvCtEzq1Vzclu/tKF8Jq1Cg8JG2GL6/EmjgsCT7lXepE3g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.29.7", + "@babel/types": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.29.7.tgz", + "integrity": "sha512-UPUVSyXbOh627KiCIGQSgwWzGeBKLkaJ9PJEdrngIwMSzxLR4jS4+f1f1jb7VzBbg8nFLaYotvVPFCTqdrmTAg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.29.7", + "@babel/helper-validator-identifier": "^7.29.7", + "@babel/traverse": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.29.7.tgz", + "integrity": "sha512-G7sHYigPY17oO5SYWnfD/0MTBwVR781S/JI643e/JhUYgVgWE/61SoW3NH9KWUKyKq5LVh3npif99Wkt6j86Jw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.29.7.tgz", + "integrity": "sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.29.7.tgz", + "integrity": "sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.29.7.tgz", + "integrity": "sha512-N9ZErrD+yW5geCDtBqnOoxmR8+tNKiGuxKlDpuJxfsqpa2dFcexaziGAE/qoHLiDDreVNMupxGmSoNlyvsA3gw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.29.7.tgz", + "integrity": "sha512-1k2lAGRMfHTcwuNYcCNUmaUffmQv8KWMfh2iJUUeRlwlwH4FdNG7mfPI10NPfLHJFThE4Tyr4mv7kTNZOiPuBg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/template": "^7.29.7", + "@babel/types": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.29.8", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.8.tgz", + "integrity": "sha512-E8lTAYNB1KW+FH+VGJuZM1ioAx2E6oVlvQFRrf5P8ZZmsiJXYAD9vTFV7yyEURNzgh1dFqMZuO6tUwcARbqFCA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.29.8" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-self": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.29.7.tgz", + "integrity": "sha512-TL0hMc9xzy86VD31nUiwzd5otRAcyEPcsegCxolO0PvcXuH1v0kECe/UIznYFihpkvU5wg/jk4v0TTEFfm53fw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-source": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.29.7.tgz", + "integrity": "sha512-06IyK09H3wi4cGbhDBwp5gUGo0IKtnYa8tyTiephirPCK6fbobVGiXMMI5zLQ4aKEYP3wZ3ArU44o+8KMrSG/Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/template": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.29.7.tgz", + "integrity": "sha512-puq+Gf35oI24FeN11LkoUQFqv9uwNeWpxXZi/Ji3rRIoKAzKnxRaZ+Gkj0vKS9ZCiTESfng1N9LyOyXvo+m+Gg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.7", + "@babel/parser": "^7.29.7", + "@babel/types": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.29.8", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.8.tgz", + "integrity": "sha512-I5z7H3bf/41ktsNVLtpN0wAa336HkqIHQ5BuPLEhTkt1jVSyZpeNKIzTgEWmlxjdg81R0IgUCcaE+Ok3NvrfZg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.7", + "@babel/generator": "^7.29.8", + "@babel/helper-globals": "^7.29.7", + "@babel/parser": "^7.29.8", + "@babel/template": "^7.29.7", + "@babel/types": "^7.29.8", + "debug": "^4.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.29.8", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.8.tgz", + "integrity": "sha512-Vj1jF3cPfxg7OAfoI7QnVKLoILlm2JF9pnVHrX8qx7AHMiYWT+NDAA7jChlNgRS4WTLc/fD1lXLmPixluj+3Gg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.29.7", + "@babel/helper-validator-identifier": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.12.tgz", + "integrity": "sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.12.tgz", + "integrity": "sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.12.tgz", + "integrity": "sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.12.tgz", + "integrity": "sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.12.tgz", + "integrity": "sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.12.tgz", + "integrity": "sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.12.tgz", + "integrity": "sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.12.tgz", + "integrity": "sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.12.tgz", + "integrity": "sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.12.tgz", + "integrity": "sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.12.tgz", + "integrity": "sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.12.tgz", + "integrity": "sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.12.tgz", + "integrity": "sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.12.tgz", + "integrity": "sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.12.tgz", + "integrity": "sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.12.tgz", + "integrity": "sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.12.tgz", + "integrity": "sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.12.tgz", + "integrity": "sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.12.tgz", + "integrity": "sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.12.tgz", + "integrity": "sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.12.tgz", + "integrity": "sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.12.tgz", + "integrity": "sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.12.tgz", + "integrity": "sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.12.tgz", + "integrity": "sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.12.tgz", + "integrity": "sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.12.tgz", + "integrity": "sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "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==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@napi-rs/lzma-linux-x64-gnu": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/@napi-rs/lzma-linux-x64-gnu/-/lzma-linux-x64-gnu-1.5.1.tgz", + "integrity": "sha512-oTXEIha4SsuXdTA4Iyskj0kpdx2yVXdhd75c2v3xGrHFfVMsbhTPZU/nMPL4sWKo4pBHm3aucLaqGlF696dTyQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^22.20 || ^24.12 || >=25" + } + }, + "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.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.62.4.tgz", + "integrity": "sha512-RrPokAb7dmbxFoeO3TloqHyOjgye8RkBhSqmp4aJMIex4c9r46ZstPnleDQOq1t46VOVjwIuwNogIqbodV1Vvg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.62.4.tgz", + "integrity": "sha512-JKuJc+pnpks2pjy7L/N3v/cAkZxYlnmuZoD840ldbMI5KDbC4iO9NKwPKYdjYFCMAIIlBzYSFHxIJVYzRo2/8A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.62.4.tgz", + "integrity": "sha512-krw5uS2STmvJ02x0uTXHbqQNuz+9eZ1iw+qXk9dmW2gvV4jV7O2hEoOnuhFrpOPiel1mBFtqbxYZZtC46hXLOw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.62.4.tgz", + "integrity": "sha512-wsTxtgApb4PrOsNJIm0FZ1h3WvCC+k9uxLJ4ad75hgoS4NiRes2SoJFlDAyMwiUY8IssDqGcHbXuN0sx1tfF1A==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.62.4.tgz", + "integrity": "sha512-GUOnQlyZe3yAXhWOtOMsn5Qkrv5E5mZXa0thbARWi5Ei2szlVXJFQhddZ4HbAzh8q92w5twp+CQvs/eFanz9YQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.62.4.tgz", + "integrity": "sha512-/Y7f3QuxjzPKsjA/rfEDa3+0vXqyjmJ50Ln8dPpCmWkKTrUoWHG1cWhTqaAMLob2m2nESWuC7yGrREz019Ztqg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.62.4.tgz", + "integrity": "sha512-81wiiX3v7aqy+T+bT61TJ78yJjRquqFFTTbAPt08imfQQzkPIW8t6aJbkTagtCCrXMNc9D66+geqlK7ydLPNqA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.62.4.tgz", + "integrity": "sha512-9kmDIvNZqdoHOBZgNtpTBeLWYO/LVipM3H/j62P8848/l/VPEQL6N3uxU9pvP1oZAsXyC2MEnFP3ovRjo7WYNQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.62.4.tgz", + "integrity": "sha512-CcnXHWnXg69g+DX5VWL3FHts3qMRN2uVEHX+BZvGLdd07/gXkn3ePjYtO1LDJvxkGKVHMclKBRa1QUTH+6toYQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.62.4.tgz", + "integrity": "sha512-iFOibiHnTRuhrWLlRsOQFdZJJIa7S8OwkneJr4ocALP16u5yk6lWLINFwhHaEqBFMsKDUZofLkGos7+CPzGB3g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-gnu": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.62.4.tgz", + "integrity": "sha512-XnWYMI7euHlb5a871xPja+Gm7DRCFU+FGRrtS2sMq9N8FvqtpagUy6gD4YOemC5MRk9xbh8+jYMEJbigFQwsgA==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-musl": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.62.4.tgz", + "integrity": "sha512-qGDAlO0U8xedCcsdRm9oaoQY8DAx/QT7uIxJWhCdx0ceIWX783UC9QSYkdpzAe29wNiVfp24+bZdQmn49o45SQ==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-gnu": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.62.4.tgz", + "integrity": "sha512-ru4H6ezD7ysA5EiEK6qkkaEb4modH8CTej6kUy/gQi20u3kB3G7Zn8snXXkeJSCOFKG/rbPPtM/+9Wgas1961w==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-musl": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.62.4.tgz", + "integrity": "sha512-2W4MO5WQVJnbJaZdvDb9rhBDuFU1nKIepPFpJUBsTh2k1YY2g+ODViaWuyOAjQ5cOP7NvrvLzt3wvHOoiAvc7w==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.62.4.tgz", + "integrity": "sha512-+fxjfuoAmVMCYV5QyjoIpu0cp5DOiOTeqYFk1AVaxGr+/ravWLX89XfQmptsoWcaVy/TGf2hexzbUOrCQIL1CQ==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.62.4.tgz", + "integrity": "sha512-jTn8JfHGL4djjFxPuM06LmNUJDsst2jeVlsd9OmIH6zc5sC9K6rIuO4YajXatLUpBmBKl6b35ro1QZocLi+tcA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.62.4.tgz", + "integrity": "sha512-oCJCJL4pXsoDcP2QZ+JVlPTIRc6266zsIaeJJsWImmF7HO0W8nb6HuSgZlMWxJwaPf8ehbSw8yo0EUw925hKsA==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.62.4.tgz", + "integrity": "sha512-W69hukhZ3KKNRCaMIEzKvcFye42hh0FE1+YoYaf5+Ikacuftoco6yO/xouz0hc5d5W/s3yBro5jRiuEE/Q5vUw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.62.4.tgz", + "integrity": "sha512-qiXbGG2jkjXhzXpsFZSR2Xpb8DN/UaxYsbb/STbuR/6fpaDgRmmaq1B/LmtF2wQFOFOSsK2jdE0RZ3a0zHn4QA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-openbsd-x64": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.62.4.tgz", + "integrity": "sha512-nWeM//hxv8mIo6jD7Hu4o48DVmV9pbV6gsKaWU+4NFyqHoPKwrkRiZGLKUhOBk8qNmDmpwFtPKg80Bo/Tn4xiQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ] + }, + "node_modules/@rollup/rollup-openharmony-arm64": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.62.4.tgz", + "integrity": "sha512-s62SQ/vgsRSvMwDkOEfTqfgASF0f26ZNaQuTA6Aok5lrikf89yI2W0gFHvZb2Jpgc6N8JnOKZgCK2iciO3CsxQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.62.4.tgz", + "integrity": "sha512-J6wGf8TVGbXJq+HH+ttTvrcfNKPbuZecV6KT1B8I18BC5IURUh5kl4Yl5OEP5eFIUoI5BWxCsyYMhFsDx8kekw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.62.4.tgz", + "integrity": "sha512-zmfrQd/0wu6oJs8Vq8KwY/YtsKSsLtKe/HwAP4Wqy8LhWjeT55fHRAkOhYQ12wI3ayS4Tt12d5CDRD7N96SAYQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-gnu": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.62.4.tgz", + "integrity": "sha512-qPzHqdj9rfUD+w79dtE07zi/kFwKyCJqplp5K5ygeLTp7jLpAoc16OAH39HSmRC9UpozaecsleI8uAdEj6v2yw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.62.4.tgz", + "integrity": "sha512-zD6NdeWEByGE9QF9vCrlJ5YQB4oq9q91kPZS37Jwj5hOkvR1lTBSpsKhKDw4IJtbQ35LsTS1HD9DZYGKIshU1Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@types/babel__core": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", + "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "node_modules/@types/babel__generator": { + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.27.0.tgz", + "integrity": "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__template": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", + "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__traverse": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.28.0.tgz", + "integrity": "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.28.2" + } + }, + "node_modules/@types/estree": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.9.tgz", + "integrity": "sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/prop-types": { + "version": "15.7.15", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.15.tgz", + "integrity": "sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/react": { + "version": "18.3.31", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.31.tgz", + "integrity": "sha512-vfEqpXTvwT91yhmwdfouStN2hSKwTvyRs8qpLfADyrq/kxDw0hZM7Wk9Ug1FELj8hIby+S/+kQCSRFF32nv2Qw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/prop-types": "*", + "csstype": "^3.2.2" + } + }, + "node_modules/@types/react-dom": { + "version": "18.3.7", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.7.tgz", + "integrity": "sha512-MEe3UeoENYVFXzoXEWsvcpg6ZvlrFNlOQ7EOsvhI3CfAXwzPfO8Qwuxd40nepsYKqyyVQnTdEfv68q91yLcKrQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "@types/react": "^18.0.0" + } + }, + "node_modules/@vitejs/plugin-react": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.7.0.tgz", + "integrity": "sha512-gUu9hwfWvvEDBBmgtAowQCojwZmJ5mcLn3aufeCsitijs3+f2NsrPtlAWIR6OPiqljl96GVCUbLe0HyqIpVaoA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.28.0", + "@babel/plugin-transform-react-jsx-self": "^7.27.1", + "@babel/plugin-transform-react-jsx-source": "^7.27.1", + "@rolldown/pluginutils": "1.0.0-beta.27", + "@types/babel__core": "^7.20.5", + "react-refresh": "^0.17.0" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "peerDependencies": { + "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0" + } + }, + "node_modules/baseline-browser-mapping": { + "version": "2.11.14", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.11.14.tgz", + "integrity": "sha512-JyJ954WzuIR8/FFzX0o5krdSTrBAkcCSRfWSleRsIHSWV+cZe2FI1PKggVkFke1hBldRs+LRxUczzE9iPmgZww==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "baseline-browser-mapping": "dist/cli.cjs" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/browserslist": { + "version": "4.28.8", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.8.tgz", + "integrity": "sha512-V2NpofLblG64mfOtSgDhOJESZEGogzDMBv/q+W6oc4LXWP/q75eOXoOaaOu1EOadB9U4Bwx/e0yzbvwKH8zalA==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "baseline-browser-mapping": "^2.11.12", + "caniuse-lite": "^1.0.30001809", + "electron-to-chromium": "^1.5.402", + "node-releases": "^2.0.53", + "update-browserslist-db": "^1.3.0" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001809", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001809.tgz", + "integrity": "sha512-xxWVywk6a6Arlk+hymeycyn/VgqEfLDxupvhH/xiY5SJ/18kmi9o6MiO320DCUzypORHLtvh0I4i04tUhCNHNQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0" + }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true, + "license": "MIT" + }, + "node_modules/csstype": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", + "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/electron-to-chromium": { + "version": "1.5.408", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.408.tgz", + "integrity": "sha512-SLoprcYpJ/OH2v2ps0+N5biv9H4/KBT3+YmmDew64TwK5y9j2wv7pMOFY7IorVkyMtEyLSCRlXKLsNlakeAlPw==", + "dev": true, + "license": "ISC" + }, + "node_modules/esbuild": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.12.tgz", + "integrity": "sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.25.12", + "@esbuild/android-arm": "0.25.12", + "@esbuild/android-arm64": "0.25.12", + "@esbuild/android-x64": "0.25.12", + "@esbuild/darwin-arm64": "0.25.12", + "@esbuild/darwin-x64": "0.25.12", + "@esbuild/freebsd-arm64": "0.25.12", + "@esbuild/freebsd-x64": "0.25.12", + "@esbuild/linux-arm": "0.25.12", + "@esbuild/linux-arm64": "0.25.12", + "@esbuild/linux-ia32": "0.25.12", + "@esbuild/linux-loong64": "0.25.12", + "@esbuild/linux-mips64el": "0.25.12", + "@esbuild/linux-ppc64": "0.25.12", + "@esbuild/linux-riscv64": "0.25.12", + "@esbuild/linux-s390x": "0.25.12", + "@esbuild/linux-x64": "0.25.12", + "@esbuild/netbsd-arm64": "0.25.12", + "@esbuild/netbsd-x64": "0.25.12", + "@esbuild/openbsd-arm64": "0.25.12", + "@esbuild/openbsd-x64": "0.25.12", + "@esbuild/openharmony-arm64": "0.25.12", + "@esbuild/sunos-x64": "0.25.12", + "@esbuild/win32-arm64": "0.25.12", + "@esbuild/win32-ia32": "0.25.12", + "@esbuild/win32-x64": "0.25.12" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "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/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/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "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/jsesc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", + "dev": true, + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "license": "MIT", + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/nanoid": { + "version": "3.3.18", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.18.tgz", + "integrity": "sha512-DTg4MJbGMWkfi6VZFdNt2/caMbQy4Ou+Op/hJQvGEWcnVfoA1QA+xzRKAzw9jD6+GVOOeYr/mIcuDSdug6F6+w==", + "dev": true, + "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/node-releases": { + "version": "2.0.53", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.53.tgz", + "integrity": "sha512-D9UOmYG3UH1V+ENW56t5QXBwJw1YEY18ruVeus89Rw+SyIgjPkCO84bRzO3uNIYosJbNwiabWVn48o3uJLjxFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.5.tgz", + "integrity": "sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/postcss": { + "version": "8.5.26", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.26.tgz", + "integrity": "sha512-u82N74LFzG8ca+dD8puPnplTXoGH4fTPpVGuIbt36G3qvNlkvfD0lEAZSxaly3KX8TS/L1A1gsCEmvKmBcVbkQ==", + "dev": true, + "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.17", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "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-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-refresh": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.17.0.tgz", + "integrity": "sha512-z6F7K9bV85EfseRCp2bzrpyQ0Gkw1uLoCel9XBVWPg/TjRj94SkJzUTGfOa4bs7iJvBWtQG0Wq7wnI0syw3EBQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/rollup": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.62.4.tgz", + "integrity": "sha512-RXOqwaPsBGjMNMa4sQjDjHieHEZDFoj/Rdr46l2MU5DfEs16wHJPC2RPTPHWhNl+M3aI472LLqFkFKut4SblOg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "1.0.9" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@napi-rs/lzma-linux-x64-gnu": "1.5.1", + "@rollup/rollup-android-arm-eabi": "4.62.4", + "@rollup/rollup-android-arm64": "4.62.4", + "@rollup/rollup-darwin-arm64": "4.62.4", + "@rollup/rollup-darwin-x64": "4.62.4", + "@rollup/rollup-freebsd-arm64": "4.62.4", + "@rollup/rollup-freebsd-x64": "4.62.4", + "@rollup/rollup-linux-arm-gnueabihf": "4.62.4", + "@rollup/rollup-linux-arm-musleabihf": "4.62.4", + "@rollup/rollup-linux-arm64-gnu": "4.62.4", + "@rollup/rollup-linux-arm64-musl": "4.62.4", + "@rollup/rollup-linux-loong64-gnu": "4.62.4", + "@rollup/rollup-linux-loong64-musl": "4.62.4", + "@rollup/rollup-linux-ppc64-gnu": "4.62.4", + "@rollup/rollup-linux-ppc64-musl": "4.62.4", + "@rollup/rollup-linux-riscv64-gnu": "4.62.4", + "@rollup/rollup-linux-riscv64-musl": "4.62.4", + "@rollup/rollup-linux-s390x-gnu": "4.62.4", + "@rollup/rollup-linux-x64-gnu": "4.62.4", + "@rollup/rollup-linux-x64-musl": "4.62.4", + "@rollup/rollup-openbsd-x64": "4.62.4", + "@rollup/rollup-openharmony-arm64": "4.62.4", + "@rollup/rollup-win32-arm64-msvc": "4.62.4", + "@rollup/rollup-win32-ia32-msvc": "4.62.4", + "@rollup/rollup-win32-x64-gnu": "4.62.4", + "@rollup/rollup-win32-x64-msvc": "4.62.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/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "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==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/tinyglobby": { + "version": "0.2.17", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.17.tgz", + "integrity": "sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.4" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.3.1.tgz", + "integrity": "sha512-ZZ61DsRsOnakl74HAmp3oSN4aXUmEWXf+i/yv0h7tIBfICc3VdrFErQKUUKPgu3AMsTUMbcongALEN4l6GSUrQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/vite": { + "version": "6.4.3", + "resolved": "https://registry.npmjs.org/vite/-/vite-6.4.3.tgz", + "integrity": "sha512-NTKlcQjlAK7MlQoyb6LgaqHc8sso/pVyUJYWMws3jg21uTJw/LddqIFPcPqP6PzpgbIcZyKI85sFE4HBrQDA8A==", + "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": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true, + "license": "ISC" + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..5aa3a97 --- /dev/null +++ b/package.json @@ -0,0 +1,21 @@ +{ + "name": "super-admin-home-care", + "private": true, + "version": "1.0.0", + "type": "module", + "scripts": { + "dev": "vite", + "build": "vite build", + "preview": "vite preview" + }, + "dependencies": { + "react": "^18.3.1", + "react-dom": "^18.3.1" + }, + "devDependencies": { + "@types/react": "^18.3.12", + "@types/react-dom": "^18.3.1", + "@vitejs/plugin-react": "^4.3.4", + "vite": "^6.0.1" + } +} \ No newline at end of file diff --git a/public/favicon.svg b/public/favicon.svg new file mode 100644 index 0000000..6893eb1 --- /dev/null +++ b/public/favicon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/guardian-logo.png b/public/guardian-logo.png new file mode 100644 index 0000000..055709b Binary files /dev/null and b/public/guardian-logo.png differ diff --git a/public/icons.svg b/public/icons.svg new file mode 100644 index 0000000..e952219 --- /dev/null +++ b/public/icons.svg @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/App.css b/src/App.css new file mode 100644 index 0000000..e46b81d --- /dev/null +++ b/src/App.css @@ -0,0 +1,4 @@ +.app-root { + min-height: 100vh; + width: 100%; +} diff --git a/src/App.jsx b/src/App.jsx new file mode 100644 index 0000000..293d837 --- /dev/null +++ b/src/App.jsx @@ -0,0 +1,48 @@ +import { useState, useEffect } from 'react' +import LoginPage from './pages/LoginPage' +import Dashboard from './pages/Dashboard' +import { getToken, getStoredUser } from './services/api' +import { adminService } from './services/adminService' +import './App.css' + +function App() { + const [isAuthenticated, setIsAuthenticated] = useState(() => { + return !!getToken() && !!getStoredUser() + }) + const [adminUser, setAdminUser] = useState(() => { + return getStoredUser() + }) + + useEffect(() => { + const handleUnauthorized = () => { + setIsAuthenticated(false) + setAdminUser(null) + } + + window.addEventListener('auth:unauthorized', handleUnauthorized) + return () => window.removeEventListener('auth:unauthorized', handleUnauthorized) + }, []) + + const handleLoginSuccess = (userData) => { + setAdminUser(userData) + setIsAuthenticated(true) + } + + const handleLogout = () => { + adminService.auth.logout() + setAdminUser(null) + setIsAuthenticated(false) + } + + return ( +
+ {isAuthenticated ? ( + + ) : ( + + )} +
+ ) +} + +export default App diff --git a/src/assets/hero.png b/src/assets/hero.png new file mode 100644 index 0000000..02251f4 Binary files /dev/null and b/src/assets/hero.png differ diff --git a/src/assets/react.svg b/src/assets/react.svg new file mode 100644 index 0000000..6c87de9 --- /dev/null +++ b/src/assets/react.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/vite.svg b/src/assets/vite.svg new file mode 100644 index 0000000..5101b67 --- /dev/null +++ b/src/assets/vite.svg @@ -0,0 +1 @@ +Vite diff --git a/src/index.css b/src/index.css new file mode 100644 index 0000000..b00c770 --- /dev/null +++ b/src/index.css @@ -0,0 +1,106 @@ +/* ============================================================ + Guardian HomeCare — Super Admin Global Styles + ============================================================ */ + +*, *::before, *::after { + box-sizing: border-box; + margin: 0; + padding: 0; +} + +:root { + /* Brand Colors */ + --primary-50: #eef6ff; + --primary-100: #d9ecff; + --primary-200: #bcdcff; + --primary-300: #8ec5fe; + --primary-400: #5aa5fb; + --primary-500: #3b82f6; + --primary-600: #2563eb; + --primary-700: #1d4ed8; + --primary-800: #1e40af; + --primary-900: #1e3a8a; + + --teal-400: #2dd4bf; + --teal-500: #14b8a6; + --teal-600: #0d9488; + + /* Dark palette */ + --dark-900: #050d1a; + --dark-800: #0a1628; + --dark-700: #0f2040; + --dark-600: #162a52; + --dark-500: #1e3a6e; + + /* Neutrals */ + --gray-50: #f8fafc; + --gray-100: #f1f5f9; + --gray-200: #e2e8f0; + --gray-300: #cbd5e1; + --gray-400: #94a3b8; + --gray-500: #64748b; + --gray-600: #475569; + --gray-700: #334155; + --gray-800: #1e293b; + --gray-900: #0f172a; + + /* Semantic */ + --danger: #ef4444; + --success: #22c55e; + --warning: #f59e0b; + + /* Typography */ + --font-primary: 'Plus Jakarta Sans', 'Inter', system-ui, sans-serif; + --font-mono: 'JetBrains Mono', 'Fira Code', monospace; + + /* Spacing */ + --radius-sm: 6px; + --radius-md: 12px; + --radius-lg: 16px; + --radius-xl: 24px; + --radius-full: 9999px; + + /* Shadows */ + --shadow-sm: 0 1px 3px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.24); + --shadow-md: 0 4px 16px rgba(0,0,0,0.25); + --shadow-lg: 0 10px 40px rgba(0,0,0,0.35); + --shadow-glow: 0 0 40px rgba(59, 130, 246, 0.4); + --shadow-teal: 0 0 30px rgba(20, 184, 166, 0.3); +} + +html { + scroll-behavior: smooth; +} + +body { + font-family: var(--font-primary); + background: var(--dark-900); + color: var(--gray-50); + line-height: 1.6; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + min-height: 100vh; + overflow-x: hidden; +} + +#root { + min-height: 100vh; + display: flex; + flex-direction: column; +} + +/* ── Scrollbar ── */ +::-webkit-scrollbar { width: 6px; height: 6px; } +::-webkit-scrollbar-track { background: var(--dark-800); } +::-webkit-scrollbar-thumb { background: var(--dark-500); border-radius: 99px; } +::-webkit-scrollbar-thumb:hover { background: var(--primary-600); } + +/* ── Selection ── */ +::selection { background: var(--primary-700); color: #fff; } + +/* ── Focus ring ── */ +:focus-visible { + outline: 2px solid var(--primary-500); + outline-offset: 3px; + border-radius: var(--radius-sm); +} diff --git a/src/main.jsx b/src/main.jsx new file mode 100644 index 0000000..54b39dd --- /dev/null +++ b/src/main.jsx @@ -0,0 +1,10 @@ +import React from 'react' +import ReactDOM from 'react-dom/client' +import App from './App.jsx' +import './index.css' + +ReactDOM.createRoot(document.getElementById('root')).render( + + + , +) diff --git a/src/pages/Dashboard.css b/src/pages/Dashboard.css new file mode 100644 index 0000000..3826b1f --- /dev/null +++ b/src/pages/Dashboard.css @@ -0,0 +1,1028 @@ +/* ============================================================ + Dashboard.css — CureSelect Healthcare LLP Super Admin + ============================================================ */ + +.dashboard-container { + display: flex; + min-height: 100vh; + width: 100%; + background: var(--dark-900); + color: var(--gray-100); + overflow: hidden; +} + +/* ── Sidebar ── */ +.sidebar { + width: 280px; + background: var(--dark-800); + border-right: 1px solid rgba(255, 255, 255, 0.05); + display: flex; + flex-direction: column; + justify-content: space-between; + padding: 24px 16px; + flex-shrink: 0; + z-index: 10; +} + +.sidebar-header { + display: flex; + align-items: center; + gap: 12px; + padding: 8px 12px 24px 12px; + border-bottom: 1px solid rgba(255, 255, 255, 0.05); +} + +.logo-icon-wrapper { + background: rgba(59, 130, 246, 0.1); + border: 1px solid rgba(59, 130, 246, 0.2); + border-radius: var(--radius-md); + width: 42px; + height: 42px; + display: flex; + align-items: center; + justify-content: center; +} + +.logo-text-block { + display: flex; + flex-direction: column; +} + +.logo-brand { + font-size: 18px; + font-weight: 800; + color: #fff; + letter-spacing: -0.02em; +} + +.logo-portal { + font-size: 11px; + color: var(--teal-400); + font-weight: 600; + text-transform: uppercase; + letter-spacing: 0.05em; + margin-top: -2px; +} + +.nav-menu { + display: flex; + flex-direction: column; + gap: 4px; + margin-top: 20px; + flex-grow: 1; +} + +.nav-item { + display: flex; + align-items: center; + gap: 12px; + background: none; + border: none; + color: var(--gray-400); + padding: 11px 14px; + border-radius: var(--radius-md); + font-size: 13.5px; + font-weight: 600; + cursor: pointer; + width: 100%; + text-align: left; + transition: all 0.2s ease; + border: 1px solid transparent; +} + +.nav-item svg { + opacity: 0.7; + transition: transform 0.2s; + flex-shrink: 0; +} + +.nav-item:hover { + color: #fff; + background: rgba(255, 255, 255, 0.03); +} + +.nav-item:hover svg { + transform: translateX(2px); +} + +.nav-item.active { + color: #fff; + background: linear-gradient(135deg, rgba(37, 99, 235, 0.15) 0%, rgba(20, 184, 166, 0.05) 100%); + border: 1px solid rgba(37, 99, 235, 0.25); + box-shadow: 0 4px 12px rgba(37, 99, 235, 0.1); +} + +.nav-item.active svg { + color: var(--primary-400); + opacity: 1; +} + +.sidebar-footer { + border-top: 1px solid rgba(255, 255, 255, 0.05); + padding-top: 20px; + display: flex; + flex-direction: column; + gap: 12px; +} + +.user-profile-badge { + display: flex; + align-items: center; + gap: 12px; + padding: 8px 12px; +} + +.avatar-placeholder { + width: 36px; + height: 36px; + border-radius: 50%; + background: linear-gradient(135deg, var(--primary-600), var(--teal-600)); + display: flex; + align-items: center; + justify-content: center; + font-weight: 700; + font-size: 12px; + color: #fff; +} + +.user-info { + display: flex; + flex-direction: column; +} + +.user-name { + font-size: 14px; + font-weight: 700; + color: #fff; +} + +.user-role { + font-size: 11px; + color: var(--gray-500); +} + +.logout-button { + display: flex; + align-items: center; + justify-content: center; + gap: 8px; + background: rgba(239, 68, 68, 0.08); + border: 1px solid rgba(239, 68, 68, 0.15); + color: #fca5a5; + padding: 10px; + border-radius: var(--radius-md); + font-size: 13px; + font-weight: 600; + cursor: pointer; + transition: all 0.2s; +} + +.logout-button:hover { + background: var(--danger); + color: #fff; + border-color: var(--danger); + box-shadow: 0 4px 12px rgba(239, 68, 68, 0.2); +} + +/* ── Main Viewport ── */ +.main-viewport { + flex-grow: 1; + display: flex; + flex-direction: column; + overflow-y: auto; + position: relative; + z-index: 1; + height: 100vh; +} + +/* ── Topbar ── */ +.topbar { + height: 70px; + background: rgba(10, 22, 40, 0.5); + backdrop-filter: blur(8px); + border-bottom: 1px solid rgba(255, 255, 255, 0.05); + display: flex; + align-items: center; + justify-content: space-between; + padding: 0 32px; + flex-shrink: 0; +} + +.session-stats-bar { + display: flex; + align-items: center; + gap: 24px; +} + +.session-kpi { + display: flex; + align-items: center; + gap: 8px; + font-size: 12.5px; + color: var(--gray-400); + background: rgba(255, 255, 255, 0.03); + border: 1px solid rgba(255, 255, 255, 0.06); + padding: 6px 12px; + border-radius: var(--radius-full); +} + +.session-kpi-dot { + width: 8px; + height: 8px; + border-radius: 50%; + background: var(--teal-400); +} + +.red-pulse { + background: var(--danger); + box-shadow: 0 0 8px var(--danger); + animation: pulse-dot 2s ease-in-out infinite; +} + +@keyframes pulse-dot { + 0%, 100% { opacity: 1; transform: scale(1); } + 50% { opacity: 0.6; transform: scale(0.85); } +} + +.topbar-actions { + display: flex; + align-items: center; + gap: 20px; +} + +.system-indicator { + display: flex; + align-items: center; + gap: 8px; + font-size: 12px; + color: var(--gray-400); + background: rgba(255, 255, 255, 0.03); + border: 1px solid rgba(255, 255, 255, 0.05); + padding: 6px 12px; + border-radius: var(--radius-full); +} + +.system-status-dot { + width: 8px; + height: 8px; + border-radius: 50%; + background: var(--success); + box-shadow: 0 0 8px var(--success); +} + +/* ── Content Pane ── */ +.content-pane { + padding: 32px; + flex-grow: 1; +} + +.tab-header-block { + display: flex; + align-items: center; + justify-content: space-between; + margin-bottom: 32px; +} + +.pane-title { + font-size: 26px; + font-weight: 800; + color: #fff; + letter-spacing: -0.02em; +} + +.pane-subtitle { + font-size: 14px; + color: var(--gray-400); + margin-top: 4px; +} + +.action-btn { + background: linear-gradient(135deg, var(--primary-600), var(--teal-600)); + border: none; + color: #fff; + padding: 10px 20px; + border-radius: var(--radius-md); + font-weight: 700; + font-size: 14px; + display: flex; + align-items: center; + gap: 8px; + cursor: pointer; + box-shadow: var(--shadow-glow); + transition: transform 0.2s, box-shadow 0.2s; +} + +.action-btn:hover { + transform: translateY(-1px); + box-shadow: 0 8px 24px rgba(37, 99, 235, 0.5); +} + +/* ── Metrics Grid ── */ +.metrics-grid { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); + gap: 24px; + margin-bottom: 32px; +} + +.metric-card { + background: rgba(255, 255, 255, 0.03); + border: 1px solid rgba(255, 255, 255, 0.06); + border-radius: var(--radius-lg); + padding: 24px; + display: flex; + flex-direction: column; + position: relative; + overflow: hidden; + transition: all 0.3s ease; +} + +.card-glass-glow { + position: absolute; + top: -50px; + right: -50px; + width: 150px; + height: 150px; + border-radius: 50%; + filter: blur(40px); + pointer-events: none; + opacity: 0.15; + transition: opacity 0.3s; +} + +.glow-blue .card-glass-glow { background: var(--primary-500); } +.glow-teal .card-glass-glow { background: var(--teal-500); } +.glow-yellow .card-glass-glow { background: var(--warning); } + +.metric-card:hover { + background: rgba(255, 255, 255, 0.05); + border-color: rgba(255, 255, 255, 0.12); + transform: translateY(-2px); +} + +.metric-card:hover .card-glass-glow { + opacity: 0.3; +} + +.metric-title { + font-size: 11px; + font-weight: 700; + color: var(--gray-500); + letter-spacing: 0.08em; +} + +.metric-value { + font-size: 36px; + font-weight: 800; + color: #fff; + margin: 12px 0 6px 0; + letter-spacing: -0.03em; +} + +.metric-subtext { + font-size: 12px; + color: var(--gray-400); +} + +/* ── Details Layout ── */ +.details-layout { + display: grid; + grid-template-columns: 1fr 1.5fr; + gap: 24px; +} + +.detail-panel { + background: rgba(10, 22, 40, 0.4); + border: 1px solid rgba(255, 255, 255, 0.05); + border-radius: var(--radius-lg); + padding: 24px; +} + +.panel-title { + font-size: 16px; + font-weight: 700; + color: #fff; + margin-bottom: 20px; +} + +/* Integration Pingers */ +.pinger-grid { + display: flex; + flex-direction: column; + gap: 12px; +} + +.pinger-card { + display: flex; + align-items: center; + justify-content: space-between; + background: rgba(255, 255, 255, 0.02); + border: 1px solid rgba(255, 255, 255, 0.06); + padding: 14px 18px; + border-radius: var(--radius-md); +} + +.pinger-meta { + display: flex; + flex-direction: column; + gap: 4px; +} + +.pinger-name { + font-size: 13.5px; + font-weight: 600; + color: #fff; +} + +.pinger-value { + font-size: 12px; + color: var(--teal-400); + font-weight: 600; +} + +/* Ledger & Reconciliation */ +.ledger-reconciliation { + display: flex; + flex-direction: column; + gap: 16px; +} + +.reconciliation-summary { + display: flex; + gap: 16px; +} + +.ledger-kpi { + flex: 1; + padding: 16px; + border-radius: var(--radius-md); + display: flex; + flex-direction: column; + gap: 4px; +} + +.bg-teal { + background: rgba(20, 184, 166, 0.1); + border: 1px solid rgba(20, 184, 166, 0.2); +} + +.bg-blue { + background: rgba(59, 130, 246, 0.1); + border: 1px solid rgba(59, 130, 246, 0.2); +} + +.kpi-num { + font-size: 22px; + font-weight: 800; + color: #fff; +} + +.kpi-label { + font-size: 11px; + color: var(--gray-400); + font-weight: 500; +} + +/* Alerts List & Approvals */ +.alerts-list { + display: flex; + flex-direction: column; + gap: 12px; +} + +.alert-card-item { + display: flex; + align-items: center; + justify-content: space-between; + padding: 14px 16px; + border-radius: var(--radius-md); + border-left: 4px solid transparent; + background: rgba(255, 255, 255, 0.02); +} + +.alert-critical { + border-left-color: var(--danger); + background: rgba(239, 68, 68, 0.05); +} + +.alert-warning { + border-left-color: var(--warning); + background: rgba(245, 158, 11, 0.05); +} + +.alert-info { + border-left-color: var(--primary-500); + background: rgba(59, 130, 246, 0.05); +} + +.alert-body { + display: flex; + flex-direction: column; + gap: 4px; +} + +.alert-message { + font-size: 13.5px; + font-weight: 500; + color: var(--gray-200); +} + +.alert-time { + font-size: 11px; + color: var(--gray-500); +} + +.resolve-btn { + background: rgba(255, 255, 255, 0.06); + border: 1px solid rgba(255, 255, 255, 0.1); + color: var(--gray-300); + padding: 6px 12px; + border-radius: var(--radius-sm); + font-size: 12px; + font-weight: 600; + cursor: pointer; + transition: all 0.2s; +} + +.resolve-btn:hover:not(:disabled) { + background: var(--success); + color: #fff; + border-color: var(--success); +} + +.resolve-btn:disabled { + opacity: 0.4; + cursor: not-allowed; +} + +.empty-alerts { + color: var(--gray-500); + text-align: center; + padding: 40px 0; + font-size: 14px; +} + +/* Table */ +.telemetry-table { + width: 100%; + border-collapse: collapse; + text-align: left; +} + +.telemetry-table th { + padding: 12px 16px; + font-size: 11px; + font-weight: 700; + color: var(--gray-500); + text-transform: uppercase; + border-bottom: 1px solid rgba(255, 255, 255, 0.05); +} + +.telemetry-table td { + padding: 16px; + font-size: 13.5px; + border-bottom: 1px solid rgba(255, 255, 255, 0.03); +} + +.hr-badge { + padding: 4px 10px; + border-radius: var(--radius-full); + font-size: 12px; + font-weight: 700; + display: inline-block; +} + +.hr-normal { + background: rgba(34, 197, 94, 0.12); + color: var(--success); +} + +.hr-high { + background: rgba(239, 68, 68, 0.12); + color: var(--danger); + animation: pulse-hr 1.5s infinite; +} + +@keyframes pulse-hr { + 0%, 100% { opacity: 1; } + 50% { opacity: 0.7; } +} + +.status-indicator-tag { + background: rgba(255, 255, 255, 0.03); + border: 1px solid rgba(255, 255, 255, 0.08); + padding: 4px 10px; + border-radius: var(--radius-full); + font-size: 11px; + color: var(--gray-400); +} + +/* ── Admin Provisioning & Roster Cards ── */ +.caregivers-grid { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); + gap: 24px; +} + +.cg-card { + background: rgba(255, 255, 255, 0.02); + border: 1px solid rgba(255, 255, 255, 0.05); + border-radius: var(--radius-lg); + padding: 20px; + display: flex; + flex-direction: column; + gap: 16px; + transition: all 0.25s ease; +} + +.cg-card:hover { + background: rgba(255, 255, 255, 0.04); + border-color: rgba(59, 130, 246, 0.2); + transform: translateY(-2px); +} + +.cg-header { + display: flex; + align-items: center; + gap: 12px; +} + +.cg-avatar { + width: 48px; + height: 48px; + border-radius: 50%; + background: rgba(59, 130, 246, 0.15); + color: var(--primary-300); + display: flex; + align-items: center; + justify-content: center; + font-weight: 700; + font-size: 14px; +} + +.cg-name { + font-size: 15px; + font-weight: 700; + color: #fff; +} + +.cg-role { + font-size: 12.5px; + color: var(--gray-400); + word-break: break-all; +} + +.cg-body { + border-top: 1px solid rgba(255, 255, 255, 0.05); + border-bottom: 1px solid rgba(255, 255, 255, 0.05); + padding: 12px 0; + display: flex; + flex-direction: column; + gap: 8px; +} + +.cg-info-row { + display: flex; + justify-content: space-between; + font-size: 13px; +} + +.cg-label { + color: var(--gray-500); +} + +.cg-value { + color: var(--gray-200); + font-weight: 500; + text-align: right; + max-width: 180px; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.cg-footer { + display: flex; + align-items: center; + justify-content: space-between; + gap: 8px; +} + +.cg-status { + font-size: 11px; + font-weight: 700; + padding: 4px 10px; + border-radius: var(--radius-full); + text-transform: uppercase; +} + +.status-active { + background: rgba(34, 197, 94, 0.1); + color: var(--success); +} + +.status-oncall { + background: rgba(59, 130, 246, 0.1); + color: var(--primary-400); +} + +.status-suspended { + background: rgba(239, 68, 68, 0.1); + color: var(--danger); +} + +.status-invited { + background: rgba(245, 158, 11, 0.1); + color: var(--warning); +} + +.cg-action-link { + background: none; + border: none; + color: var(--primary-400); + font-size: 12.5px; + font-weight: 600; + cursor: pointer; + padding: 0; +} + +.cg-action-link:hover { + color: var(--primary-300); + text-decoration: underline; +} + +/* ── Settings Options List ── */ +.settings-options-list { + background: rgba(255, 255, 255, 0.02); + border: 1px solid rgba(255, 255, 255, 0.05); + border-radius: var(--radius-lg); + padding: 8px 0; + max-width: 100%; +} + +.setting-row { + display: flex; + align-items: center; + justify-content: space-between; + padding: 20px 24px; + border-bottom: 1px solid rgba(255, 255, 255, 0.03); +} + +.setting-row:last-child { + border-bottom: none; +} + +.setting-meta { + display: flex; + flex-direction: column; + gap: 4px; + padding-right: 20px; +} + +.setting-label { + font-size: 14px; + font-weight: 700; + color: #fff; +} + +.setting-description { + font-size: 12.5px; + color: var(--gray-500); +} + +/* Toggle Switch */ +.toggle-switch { + position: relative; + display: inline-block; + width: 44px; + height: 24px; + flex-shrink: 0; +} + +.toggle-switch input { + opacity: 0; + width: 0; + height: 0; +} + +.slider { + position: absolute; + cursor: pointer; + inset: 0; + background-color: rgba(255, 255, 255, 0.1); + transition: .3s; + border-radius: 24px; +} + +.slider:before { + position: absolute; + content: ""; + height: 18px; + width: 18px; + left: 3px; + bottom: 3px; + background-color: #fff; + transition: .3s; + border-radius: 50%; +} + +input:checked + .slider { + background-color: var(--primary-600); +} + +input:checked + .slider:before { + transform: translateX(20px); +} + +/* ── Modal Overlay ── */ +.modal-overlay { + position: fixed; + inset: 0; + background: rgba(0, 0, 0, 0.7); + backdrop-filter: blur(6px); + display: flex; + align-items: center; + justify-content: center; + z-index: 100; + animation: modalFadeIn 0.25s ease; +} + +@keyframes modalFadeIn { + from { opacity: 0; } + to { opacity: 1; } +} + +.modal-content { + background: var(--dark-800); + border: 1px solid rgba(255, 255, 255, 0.08); + border-radius: var(--radius-lg); + width: 100%; + max-width: 480px; + padding: 28px; + box-shadow: var(--shadow-lg); + animation: modalSlideUp 0.3s cubic-bezier(0.34, 1.56, 0.64, 1); +} + +@keyframes modalSlideUp { + from { transform: translateY(20px); opacity: 0; } + to { transform: translateY(0); opacity: 1; } +} + +.modal-header { + display: flex; + align-items: center; + justify-content: space-between; + margin-bottom: 24px; +} + +.modal-header h3 { + font-size: 18px; + font-weight: 800; + color: #fff; +} + +.close-btn { + background: none; + border: none; + color: var(--gray-400); + font-size: 24px; + cursor: pointer; + line-height: 1; +} + +.close-btn:hover { + color: #fff; +} + +.modal-form { + display: flex; + flex-direction: column; + gap: 16px; +} + +.form-group { + display: flex; + flex-direction: column; + gap: 8px; +} + +.form-group label { + font-size: 12.5px; + font-weight: 600; + color: var(--gray-300); +} + +.form-group input, +.form-group select { + background: rgba(255, 255, 255, 0.04); + border: 1px solid rgba(255, 255, 255, 0.08); + border-radius: var(--radius-md); + padding: 12px; + color: #fff; + font-size: 13.5px; + font-family: var(--font-primary); + outline: none; + transition: all 0.2s; +} + +.form-group input:focus, +.form-group select:focus { + border-color: var(--primary-500); + background: rgba(59, 130, 246, 0.05); +} + +.modal-footer-actions { + display: flex; + justify-content: flex-end; + gap: 12px; + margin-top: 24px; +} + +.cancel-btn { + background: none; + border: 1px solid rgba(255, 255, 255, 0.08); + color: var(--gray-300); + padding: 10px 18px; + border-radius: var(--radius-md); + font-weight: 600; + cursor: pointer; +} + +.cancel-btn:hover { + background: rgba(255, 255, 255, 0.03); + color: #fff; +} + +.submit-btn { + background: linear-gradient(135deg, var(--primary-600), var(--teal-600)); + border: none; + color: #fff; + padding: 10px 18px; + border-radius: var(--radius-md); + font-weight: 700; + cursor: pointer; + transition: all 0.2s; +} + +.submit-btn:hover:not(:disabled) { + box-shadow: 0 4px 12px rgba(37, 99, 235, 0.3); +} + +.submit-btn:disabled { + opacity: 0.5; + cursor: not-allowed; +} + +/* Animations helper */ +.fade-in { + animation: fadeInEffect 0.3s ease; +} + +@keyframes fadeInEffect { + from { opacity: 0; } + to { opacity: 1; } +} + +/* ══════════════════════════════════════════════ + Responsive — tablet / mobile +══════════════════════════════════════════════ */ +@media (max-width: 1024px) { + .details-layout { + grid-template-columns: 1fr; + } +} + +@media (max-width: 768px) { + .dashboard-container { + flex-direction: column; + } + .sidebar { + width: 100%; + height: auto; + border-right: none; + border-bottom: 1px solid rgba(255, 255, 255, 0.05); + } + .nav-menu { + flex-direction: row; + overflow-x: auto; + margin-top: 12px; + padding-bottom: 8px; + } + .nav-item { + padding: 8px 12px; + white-space: nowrap; + width: auto; + } + .main-viewport { + height: auto; + overflow-y: visible; + } + .topbar { + padding: 0 16px; + flex-direction: column; + height: auto; + align-items: flex-start; + gap: 12px; + padding: 12px; + } +} diff --git a/src/pages/Dashboard.jsx b/src/pages/Dashboard.jsx new file mode 100644 index 0000000..cc0187c --- /dev/null +++ b/src/pages/Dashboard.jsx @@ -0,0 +1,1480 @@ +import { useState, useEffect, useCallback } from 'react' +import { adminService } from '../services/adminService' +import './Dashboard.css' + +// ── Icons for navigation and UI ── +const Icons = { + Overview: () => ( + + + + + + + ), + Users: () => ( + + + + + + + ), + Shield: () => ( + + + + ), + Finance: () => ( + + + + + ), + Config: () => ( + + + + + ), + Key: () => ( + + + + ), + Compliance: () => ( + + + + + + + + ), + Terminal: () => ( + + + + + ), + Bell: () => ( + + + + + ), + Plus: () => ( + + + + + ), + LogOut: () => ( + + + + + + ), + Refresh: () => ( + + + + + + ) +} + +export default function Dashboard({ user, onLogout }) { + const [activeTab, setActiveTab] = useState('Overview') + const [showModal, setShowModal] = useState(null) // 'invite_admin' | 'reset_2fa_approval' | 'change_config' | 'broadcast' | 'create_access_grant' + const [loading, setLoading] = useState(false) + const [bannerNotice, setBannerNotice] = useState(null) + + // ── Session Security Telemetry ── + const [timeLeft, setTimeLeft] = useState(900) // 15 mins idle timer + const [allowlistIP] = useState('184.22.109.52') + const [currentIP] = useState('184.22.109.52') + const [sessionCount] = useState(1) + + // Countdown timer simulation + useEffect(() => { + const interval = setInterval(() => { + setTimeLeft((prev) => (prev > 0 ? prev - 1 : 900)) + }, 1000) + return () => clearInterval(interval) + }, []) + + const formatTime = (seconds) => { + const mins = Math.floor(seconds / 60) + const secs = seconds % 60 + return `${mins.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}` + } + + // ── Live Backend States ── + const [adminUsers, setAdminUsers] = useState([]) + const [approvals, setApprovals] = useState([]) + const [auditLogs, setAuditLogs] = useState([]) + const [financeSummary, setFinanceSummary] = useState({ + gross_booking_value: '₹18,40,000', + platform_commission: '₹2,76,000', + refunds_issued: '₹44,000', + compute_window: '2026-07-01 to 2026-07-31' + }) + const [reconciliationMismatches, setReconciliationMismatches] = useState([ + { id: "tx_991", date: "2026-08-14", ledgerAmount: "₹24,500", gatewayAmount: "₹24,000", status: "Drift Alert", mismatch: "₹500" }, + { id: "tx_992", date: "2026-08-13", ledgerAmount: "₹18,000", gatewayAmount: "₹18,000", status: "Matches", mismatch: "₹0" }, + ]) + const [platformConfig, setPlatformConfig] = useState({ + commissionRatePercent: 15, + refundAuthorisationThreshold: 5000, + cancellationPolicy: { freeWindowHours: 24, lateFeePercent: 20 }, + caregiverRates: { minHourly: 100, maxHourly: 1000 }, + }) + const [configHistory, setConfigHistory] = useState([]) + const [accessGrants, setAccessGrants] = useState([]) + const [dataRequests, setDataRequests] = useState([]) + const [jobs, setJobs] = useState([ + { name: "finance-reconciliation", schedule: "daily", status: "Success", lastRun: "2 mins ago" }, + { name: "audit-archive", schedule: "daily", status: "Success", lastRun: "1 hr ago" }, + { name: "retention-sweep", schedule: "weekly", status: "Success", lastRun: "2 days ago" }, + ]) + const [broadcasts, setBroadcasts] = useState([]) + const [pingerStatus, setPingerStatus] = useState({ SMS: "Online", Push: "Online", Payment: "Online", Storage: "Online" }) + + // ── Form Input Fields ── + const [formInputFirstName, setFormInputFirstName] = useState('') + const [formInputLastName, setFormInputLastName] = useState('') + const [formInputEmail, setFormInputEmail] = useState('') + const [formInputRole, setFormInputRole] = useState('ops_admin') + const [formInputReason, setFormInputReason] = useState('') + const [formInputVerification, setFormInputVerification] = useState('') + const [targetUser, setTargetUser] = useState(null) + + // Config editing staging state + const [stageCommission, setStageCommission] = useState(15) + const [stageThreshold, setStageThreshold] = useState(5000) + + // Access Grant staging + const [grantCaseId, setGrantCaseId] = useState('') + const [grantPatient, setGrantPatient] = useState('') + const [grantReason, setGrantReason] = useState('') + + // Broadcast staging + const [broadcastAudience, setBroadcastAudience] = useState('all') + const [broadcastTitle, setBroadcastTitle] = useState('') + const [broadcastBody, setBroadcastBody] = useState('') + + const notify = (msg, isError = false) => { + setBannerNotice({ msg, isError }) + setTimeout(() => setBannerNotice(null), 5000) + } + + // ── Data Fetchers ── + const fetchUsers = useCallback(async () => { + try { + const res = await adminService.users.list() + if (res?.data) { + setAdminUsers(res.data) + } + } catch (err) { + console.error('Failed to load users:', err) + } + }, []) + + const fetchApprovals = useCallback(async () => { + try { + const res = await adminService.approvals.list() + if (res?.data && Array.isArray(res.data)) { + setApprovals(res.data) + } + } catch (err) { + console.error('Failed to load approvals:', err) + } + }, []) + + const fetchFinance = useCallback(async () => { + try { + const [summaryRes, reconRes] = await Promise.allSettled([ + adminService.finance.getSummary(), + adminService.finance.getReconciliation() + ]) + if (summaryRes.status === 'fulfilled' && summaryRes.value?.data) { + setFinanceSummary(summaryRes.value.data) + } + if (reconRes.status === 'fulfilled' && reconRes.value?.data && Array.isArray(reconRes.value.data)) { + setReconciliationMismatches(reconRes.value.data) + } + } catch (err) { + console.error('Failed to load finance data:', err) + } + }, []) + + const fetchConfig = useCallback(async () => { + try { + const [cfgRes, histRes] = await Promise.allSettled([ + adminService.config.get(), + adminService.config.getHistory() + ]) + if (cfgRes.status === 'fulfilled' && cfgRes.value?.data) { + setPlatformConfig(cfgRes.value.data) + setStageCommission(cfgRes.value.data.commissionRatePercent || 15) + setStageThreshold(cfgRes.value.data.refundAuthorisationThreshold || 5000) + } + if (histRes.status === 'fulfilled' && histRes.value?.data && Array.isArray(histRes.value.data)) { + setConfigHistory(histRes.value.data) + } + } catch (err) { + console.error('Failed to load platform config:', err) + } + }, []) + + const fetchAccessGrants = useCallback(async () => { + try { + const res = await adminService.accessGrants.list() + if (res?.data && Array.isArray(res.data)) { + setAccessGrants(res.data) + } + } catch (err) { + console.error('Failed to load access grants:', err) + } + }, []) + + const fetchAuditLogs = useCallback(async () => { + try { + const res = await adminService.auditLog.list({ limit: 25 }) + if (res?.data && Array.isArray(res.data)) { + setAuditLogs(res.data) + } + } catch (err) { + console.error('Failed to load audit logs:', err) + } + }, []) + + const fetchCompliance = useCallback(async () => { + try { + const res = await adminService.compliance.getDataRequests() + if (res?.data && Array.isArray(res.data)) { + setDataRequests(res.data) + } + } catch (err) { + console.error('Failed to load compliance data requests:', err) + } + }, []) + + const fetchSystem = useCallback(async () => { + try { + const [jobsRes, intRes] = await Promise.allSettled([ + adminService.system.getJobs(), + adminService.system.getIntegrations() + ]) + if (jobsRes.status === 'fulfilled' && jobsRes.value?.data && Array.isArray(jobsRes.value.data)) { + setJobs(jobsRes.value.data) + } + if (intRes.status === 'fulfilled' && intRes.value?.data) { + setPingerStatus(intRes.value.data) + } + } catch (err) { + console.error('Failed to load system info:', err) + } + }, []) + + const fetchBroadcasts = useCallback(async () => { + try { + const res = await adminService.announcements.list() + if (res?.data && Array.isArray(res.data)) { + setBroadcasts(res.data) + } + } catch (err) { + console.error('Failed to load broadcasts:', err) + } + }, []) + + // Initial load across all services + useEffect(() => { + setLoading(true) + Promise.allSettled([ + fetchUsers(), + fetchApprovals(), + fetchFinance(), + fetchConfig(), + fetchAccessGrants(), + fetchAuditLogs(), + fetchCompliance(), + fetchSystem(), + fetchBroadcasts(), + ]).finally(() => setLoading(false)) + }, [fetchUsers, fetchApprovals, fetchFinance, fetchConfig, fetchAccessGrants, fetchAuditLogs, fetchCompliance, fetchSystem, fetchBroadcasts]) + + // Refresh current tab data + const handleRefresh = () => { + setLoading(true) + switch (activeTab) { + case 'AdminUsers': fetchUsers().finally(() => setLoading(false)); break + case 'Approvals': fetchApprovals().finally(() => setLoading(false)); break + case 'Financials': fetchFinance().finally(() => setLoading(false)); break + case 'Config': fetchConfig().finally(() => setLoading(false)); break + case 'MedicalGate': fetchAccessGrants().finally(() => setLoading(false)); break + case 'Compliance': Promise.allSettled([fetchCompliance(), fetchAuditLogs()]).finally(() => setLoading(false)); break + case 'SystemJobs': fetchSystem().finally(() => setLoading(false)); break + case 'Broadcasts': fetchBroadcasts().finally(() => setLoading(false)); break + default: + Promise.allSettled([fetchUsers(), fetchApprovals(), fetchCompliance(), fetchSystem()]).finally(() => setLoading(false)) + } + } + + // ── Actions ── + const triggerJob = async (name) => { + setJobs(prev => prev.map(j => j.name === name ? { ...j, status: "Running...", lastRun: "Just now" } : j)) + try { + await adminService.system.triggerJob(name) + notify(`Job "${name}" triggered successfully.`) + fetchSystem() + } catch (err) { + notify(err.message || `Failed to trigger job ${name}`, true) + } + } + + const testIntegration = async (name) => { + setPingerStatus(prev => ({ ...prev, [name]: "Pinging..." })) + try { + await adminService.system.testIntegration(name) + setPingerStatus(prev => ({ ...prev, [name]: "Online" })) + notify(`Integration "${name}" responded OK.`) + } catch (err) { + setPingerStatus(prev => ({ ...prev, [name]: "Degraded" })) + notify(err.message || `Integration test failed for ${name}`, true) + } + } + + const handleInviteAdmin = async (e) => { + e.preventDefault() + try { + const roleMapping = { + super_admin: 5, + ops_admin: 4, + support_admin: 3 + } + const roleId = roleMapping[formInputRole] || 4 + const res = await adminService.users.create({ + first_name: formInputFirstName || 'Admin', + last_name: formInputLastName || 'User', + email: formInputEmail, + role_id: roleId, + }) + + notify(res?.message || 'Admin user invited successfully!') + fetchUsers() + resetForm() + } catch (err) { + notify(err.message || 'Failed to create admin user.', true) + } + } + + const handleReset2FAApproval = async (e) => { + e.preventDefault() + if (!targetUser) return + try { + const res = await adminService.users.reset2fa(targetUser.id, `${formInputReason} | ${formInputVerification}`) + notify(res?.message || '2FA reset initiated / requested.') + fetchApprovals() + fetchUsers() + resetForm() + } catch (err) { + notify(err.message || 'Failed to reset 2FA.', true) + } + } + + const handleRequestConfigChange = async (e) => { + e.preventDefault() + if (stageCommission < 0 || stageCommission > 50) { + notify("Commission rate must reside within 0-50% boundaries.", true) + return + } + + try { + const res = await adminService.config.update({ + commissionRatePercent: stageCommission, + refundAuthorisationThreshold: stageThreshold, + reason: formInputReason, + }) + notify(res?.message || 'Configuration updated / approval queued.') + fetchConfig() + fetchApprovals() + resetForm() + } catch (err) { + notify(err.message || 'Failed to update platform config.', true) + } + } + + const handleCreateAccessGrant = async (e) => { + e.preventDefault() + try { + const res = await adminService.accessGrants.create({ + case_id: grantCaseId, + patient_name: grantPatient, + reason: grantReason, + duration_hours: 24, + }) + notify(res?.message || 'Access grant created successfully!') + fetchAccessGrants() + setGrantCaseId('') + setGrantPatient('') + setGrantReason('') + setShowModal(null) + } catch (err) { + notify(err.message || 'Failed to create access grant.', true) + } + } + + const handleCreateBroadcast = async (e) => { + e.preventDefault() + try { + const res = await adminService.announcements.create({ + audience: broadcastAudience, + title: broadcastTitle, + body: broadcastBody, + }) + notify(res?.message || 'Broadcast announcement queued!') + fetchBroadcasts() + fetchApprovals() + resetForm() + } catch (err) { + notify(err.message || 'Failed to dispatch broadcast announcement.', true) + } + } + + const handleActionApproval = async (id, approve) => { + try { + let res + if (approve) { + res = await adminService.approvals.approve(id, "Approved by Super Admin") + } else { + res = await adminService.approvals.reject(id, "Rejected by Super Admin") + } + notify(res?.message || (approve ? 'Action approved.' : 'Action rejected.')) + fetchApprovals() + fetchConfig() + fetchUsers() + } catch (err) { + notify(err.message || 'Approval action failed.', true) + } + } + + const handleRevokeGrant = async (id) => { + try { + await adminService.accessGrants.revoke(id) + notify('Access grant revoked.') + fetchAccessGrants() + } catch (err) { + notify(err.message || 'Failed to revoke grant.', true) + } + } + + const handleSuspendAdmin = async (u) => { + try { + if (u.status === 'suspended' || u.status === 'Suspended') { + await adminService.users.reinstate(u.id) + notify(`User ${u.email} reinstated.`) + } else { + await adminService.users.suspend(u.id, "Administrative suspension") + notify(`User ${u.email} suspended.`) + } + fetchUsers() + } catch (err) { + notify(err.message || 'Failed to change user status.', true) + } + } + + const handleFulfillRequest = async (id) => { + try { + await adminService.compliance.fulfilDataRequest(id) + notify('Data request fulfilled.') + fetchCompliance() + } catch (err) { + notify(err.message || 'Failed to fulfill data request.', true) + } + } + + const resetForm = () => { + setFormInputFirstName('') + setFormInputLastName('') + setFormInputEmail('') + setFormInputRole('ops_admin') + setFormInputReason('') + setFormInputVerification('') + setBroadcastTitle('') + setBroadcastBody('') + setTargetUser(null) + setShowModal(null) + } + + return ( +
+ {/* ── Sidebar ── */} + + + {/* ── Main Viewport ── */} +
+
+
+
+ + Session: {formatTime(timeLeft)} +
+
+ Clients: {sessionCount} Active +
+
+ Allowlisted IP: {currentIP === allowlistIP ? "Enforced" : "Mismatch"} +
+
+ +
+ + +
+ + API Connected +
+
+
+ + {/* Global Notification Toast */} + {bannerNotice && ( +
+ {bannerNotice.msg} + +
+ )} + +
+ {/* ────────────────── OVERVIEW TAB ────────────────── */} + {activeTab === 'Overview' && ( +
+
+
+

Security & System Health

+

Live health status, statutory compliance deadlines, and real-time integration status.

+
+
+ +
+
+
+ COMPLIANCE DEADLINES + {dataRequests.filter(r => (r.status || 'pending').toLowerCase() === 'pending').length} Pending + DPDP statutory response days tracked +
+
+
+ PENDING APPROVAL LIMITS + {approvals.filter(a => (a.status || 'pending').toLowerCase() === 'pending').length} Requests + Two-person ceiling rules active +
+
+
+ ACTIVE ADMIN ACCOUNTS + {adminUsers.length} Provisioned + Enterprise RBAC enforcement +
+
+ +
+ {/* Integration Health */} +
+

External Integration Sync Status

+
+ {Object.entries(pingerStatus).map(([name, status]) => ( +
+
+ {name} Service + {typeof status === 'string' ? status : 'Online'} +
+ +
+ ))} +
+
+ + {/* Audit Stream Tracker */} +
+

Audit log external archive stream

+
+
+
+ 100% + Stream Success +
+
+ WORM + Append-Only S3 +
+
+
+ Audit records streamed synchronously to external write-once-read-many (WORM) repository. Total active logs: {auditLogs.length}. +
+
+
+
+
+ )} + + {/* ────────────────── ADMIN USERS TAB ────────────────── */} + {activeTab === 'AdminUsers' && ( +
+
+
+

Internal Admin Provisioning

+

Manage administrative staff. Enterprise RBAC and passwordless tokens enforced.

+
+ +
+ +
+ {adminUsers.map(userItem => { + const roleCode = userItem.role || (userItem.role_id === 5 ? 'super_admin' : 'admin') + const isActive = userItem.is_active || userItem.status === 'active' || userItem.status === 'Active' + return ( +
+
+
{roleCode.substring(0, 2).toUpperCase()}
+
+

{userItem.name || `${userItem.first_name || ''} ${userItem.last_name || ''}`.trim() || 'Admin User'}

+ {userItem.email || userItem.username} +
+
+
+
+ Role Category + {roleCode} +
+
+ Hardware Key (WebAuthn) + {userItem.has_webauthn || userItem.webAuthn ? "Enrolled" : "Not Enrolled"} +
+
+ Status + + {isActive ? 'Active' : 'Suspended'} + +
+
+
+ + +
+
+ ) + })} +
+
+ )} + + {/* ────────────────── TWO-PERSON APPROVALS TAB ────────────────── */} + {activeTab === 'Approvals' && ( +
+
+
+

Two-Person Approval Inbox

+

Actions gated by the platform policy ceiling. Initiating user cannot self-approve.

+
+
+ +
+ {approvals.length === 0 ? ( +
+ No pending approval requests. +
+ ) : ( + approvals.map(approval => { + const isPending = (approval.status || 'pending').toLowerCase() === 'pending' + const initiatorEmail = approval.initiator?.email || approval.initiator || approval.initiator_id || "admin@cureselect.com" + const isInitiator = initiatorEmail === user?.email + return ( +
+
+
+ {approval.action_type || approval.type} + {approval.status} +
+ + Parameters: {approval.details || approval.initiator_note || JSON.stringify(approval.payload || {})} + + + Initiator: {String(initiatorEmail)} · {approval.created_at || approval.timestamp} + +
+
+ {isPending ? ( + <> + + + + ) : ( + Resolved + )} +
+
+ ) + }) + )} +
+
+ )} + + {/* ────────────────── FINANCIAL LEDGER TAB ────────────────── */} + {activeTab === 'Financials' && ( +
+
+
+

Financial Ledger & Summary

+

Figures are generated live from ledger records. Database balances are read-only.

+
+
+ + {/* Financial KPI Ledger Cards */} +
+
+
+ GROSS BOOKING VALUE + {financeSummary.gross_booking_value || '₹18,40,000'} + Compute window: {financeSummary.compute_window || 'Current month'} +
+
+
+ NET PLATFORM COMMISSION + {financeSummary.platform_commission || '₹2,76,000'} + Average {platformConfig.commissionRatePercent}% rate applied +
+
+
+ REFUNDS ISSUED + {financeSummary.refunds_issued || '₹44,000'} + Held ceiling authorisations resolved +
+
+ +
+ {/* Gateway Reconciliation */} +
+

Gateway Ledger Reconciliation (Discrepancy Checks)

+
+ + + + + + + + + + + + {reconciliationMismatches.map(m => ( + + + + + + + + ))} + +
DateInternal LedgerGateway SettlementDiscrepancy DriftReconcile
{m.date}{m.ledgerAmount || m.ledger_amount}{m.gatewayAmount || m.gateway_amount} + + {m.mismatch} + + + +
+
+
+
+
+ )} + + {/* ────────────────── PLATFORM CONFIG TAB ────────────────── */} + {activeTab === 'Config' && ( +
+
+
+

Platform Configuration Policies

+

Edits to policy values trigger two-person approval. Changes apply only to new bookings.

+
+ +
+ +
+
+
+ Platform Commission Rate Percent + Current percentage deducted from bookings (0-50% valid range). +
+ + {platformConfig.commissionRatePercent}% + +
+
+
+ Refund Authorization Threshold + Ops refund amount limit requiring Super Admin override. +
+ + ₹{platformConfig.refundAuthorisationThreshold} + +
+
+
+ Cancellation Policy Free Window + Time frame within which families can cancel bookings without penalties. +
+ + {platformConfig.cancellationPolicy?.freeWindowHours || 24} Hours + +
+
+ + {/* Version History Log */} +
+

Configuration Change Log History

+
+ + + + + + + + + + + {configHistory.length === 0 ? ( + + ) : ( + configHistory.map(hist => ( + + + + + + + )) + )} + +
TimestampActorModification DetailsJustification Reason
No recorded configuration modifications.
{hist.timestamp || hist.created_at}{hist.actor}{hist.change}{hist.reason}
+
+
+
+ )} + + {/* ────────────────── MEDICAL GATE TAB ────────────────── */} + {activeTab === 'MedicalGate' && ( +
+
+
+

Medical Record Access Gate

+

Super Admin ownership does not bypass access restrictions. Case-linked and time-boxed validation is mandatory.

+
+ +
+ +
+

Active Clinician & Admin Access Grants

+
+ + + + + + + + + + + + + {accessGrants.length === 0 ? ( + + ) : ( + accessGrants.map(grant => ( + + + + + + + + + )) + )} + +
Grant IDCase ReferencePatient NameAccess JustificationExpiration BoxRevocation Action
No active emergency break-glass grants.
{grant.id}{grant.caseId || grant.case_id}{grant.patientName || grant.patient_name}{grant.reason}{grant.expiresAt || '24h'} + +
+
+
+
+ )} + + {/* ────────────────── COMPLIANCE & AUDIT TAB ────────────────── */} + {activeTab === 'Compliance' && ( +
+
+
+

Audit & Compliance Operations

+

Full platform compliance logs, retention deadline alerts, and DPDP / GDPR data subject requests.

+
+
+ +
+ {/* Data Subject Requests */} +
+

DPDP / GDPR Data Subject Requests

+
+ {dataRequests.length === 0 ? ( +
+ No pending Data Subject Requests. +
+ ) : ( + dataRequests.map(req => { + const isPending = (req.status || 'pending').toLowerCase() === 'pending' + return ( +
+
+ Request ID: {req.id} (Type: {(req.type || 'DELETION').toUpperCase()}) + Subject: {req.requestedBy || req.user_id} + Legal basis: {req.legalBasis || 'DPDP Compliance'} · Due: {req.dueBy || '30 days'} +
+
+ {isPending ? ( + + ) : ( + Fulfilled + )} +
+
+ ) + }) + )} +
+
+ + {/* Retention Sweep */} +
+

Retention sweep report

+
+ Automatic record sweep active. Retention sweeps run weekly to flag records eligible for purging. +
+ +
+
+ + {/* Full Audit Log (Read-only) */} +
+

Immutable Administrative Audit Log

+
+ + + + + + + + + + + + + {auditLogs.length === 0 ? ( + + ) : ( + auditLogs.map(log => ( + + + + + + + + + )) + )} + +
TimestampActorActionResource CheckedIP AddressArchive Status
No recorded audit events.
{log.timestamp || log.created_at}{log.actor || log.user?.email || 'admin@cureselect.com'}{log.action}{log.resource || log.resource_type || 'System'}{log.ip || log.ip_address || '184.22.109.52'}{log.status || 'Archived'}
+
+
+
+ )} + + {/* ────────────────── SYSTEM JOBS TAB ────────────────── */} + {activeTab === 'SystemJobs' && ( +
+
+
+

System Operations & Maintenance

+

Trigger automated backend scripts. Emergency SOS routing overrides maintenance mode.

+
+
+ +
+

Cron Job Management

+
+ + + + + + + + + + + + {jobs.map(job => ( + + + + + + + + ))} + +
Job NameScheduleStatusLast ExecutionTrigger Run
{job.name}{job.schedule}{job.status}{job.lastRun || job.last_run} + +
+
+
+
+ )} + + {/* ────────────────── ANNOUNCEMENTS TAB ────────────────── */} + {activeTab === 'Broadcasts' && ( +
+
+
+

Broadcast Announcements

+

Dispatch announcements to caregivers or families. Gated by two-person rules for bulk outputs.

+
+ +
+ +
+

Dispatched Broadcast Logs

+
+ + + + + + + + + + + {broadcasts.length === 0 ? ( + + ) : ( + broadcasts.map(bc => ( + + + + + + + )) + )} + +
AudienceTitleRecipients CountDispatch Status
No announcements dispatched.
{bc.audience}{bc.title}{bc.recipients || 'All'} Recipients{bc.status || 'Dispatched'}
+
+
+
+ )} +
+
+ + {/* ────────────────── INVITE ADMIN USER MODAL ────────────────── */} + {showModal === 'invite_admin' && ( +
setShowModal(null)}> +
e.stopPropagation()}> +
+

Invite Internal Staff User

+ +
+
+
+ + setFormInputFirstName(e.target.value)} + /> +
+
+ + setFormInputLastName(e.target.value)} + /> +
+
+ + setFormInputEmail(e.target.value)} + /> +
+
+ + +
+
+ + +
+
+
+
+ )} + + {/* ────────────────── RESET 2FA APPROVAL MODAL ────────────────── */} + {showModal === 'reset_2fa_approval' && ( +
setShowModal(null)}> +
e.stopPropagation()}> +
+

Propose 2FA Reset (Two-Person Ceilings)

+ +
+
+
+ + +
+
+ + setFormInputReason(e.target.value)} + /> +
+
+ + setFormInputVerification(e.target.value)} + /> +
+
+ + +
+
+
+
+ )} + + {/* ────────────────── PROPOSE CONFIG CHANGE MODAL ────────────────── */} + {showModal === 'change_config' && ( +
setShowModal(null)}> +
e.stopPropagation()}> +
+

Propose Policy Config Change

+ +
+
+
+ + setStageCommission(parseInt(e.target.value))} + /> +
+
+ + setStageThreshold(parseInt(e.target.value))} + /> +
+
+ + setFormInputReason(e.target.value)} + /> +
+
+ + +
+
+
+
+ )} + + {/* ────────────────── CREATE ACCESS GRANT MODAL ────────────────── */} + {showModal === 'create_access_grant' && ( +
setShowModal(null)}> +
e.stopPropagation()}> +
+

Create Case-Linked Access Grant

+ +
+
+
+ + setGrantCaseId(e.target.value)} + /> +
+
+ + setGrantPatient(e.target.value)} + /> +
+
+ + setGrantReason(e.target.value)} + /> +
+
+ + +
+
+
+
+ )} + + {/* ────────────────── BROADCAST ANNOUNCEMENT MODAL ────────────────── */} + {showModal === 'broadcast' && ( +
setShowModal(null)}> +
e.stopPropagation()}> +
+

Compose Broadcast Announcement

+ +
+
+
+ + +
+
+ + setBroadcastTitle(e.target.value)} + /> +
+
+ +