From cc30cb16441033e64983deff4b30ba9183f59abb Mon Sep 17 00:00:00 2001 From: Sharyu Marwadi Date: Fri, 26 Jul 2024 12:08:19 +0530 Subject: [PATCH 01/23] [feature/boiler-plate] vite setup --- .eslintrc.cjs | 18 + .gitignore | 24 + .vite/deps/_metadata.json | 8 + .vite/deps/package.json | 3 + README.md | 2 +- index.html | 13 + package-lock.json | 3255 +++++++++++++++++++++++++++++++++++++ package.json | 28 + public/vite.svg | 1 + src/App.css | 42 + src/App.tsx | 13 + src/assets/react.svg | 1 + src/index.css | 68 + src/main.tsx | 10 + src/vite-env.d.ts | 1 + tsconfig.app.json | 27 + tsconfig.json | 11 + tsconfig.node.json | 13 + vite.config.ts | 7 + 19 files changed, 3544 insertions(+), 1 deletion(-) create mode 100644 .eslintrc.cjs create mode 100644 .gitignore create mode 100644 .vite/deps/_metadata.json create mode 100644 .vite/deps/package.json create mode 100644 index.html create mode 100644 package-lock.json create mode 100644 package.json create mode 100644 public/vite.svg create mode 100644 src/App.css create mode 100644 src/App.tsx create mode 100644 src/assets/react.svg create mode 100644 src/index.css create mode 100644 src/main.tsx create mode 100644 src/vite-env.d.ts create mode 100644 tsconfig.app.json create mode 100644 tsconfig.json create mode 100644 tsconfig.node.json create mode 100644 vite.config.ts diff --git a/.eslintrc.cjs b/.eslintrc.cjs new file mode 100644 index 0000000..d6c9537 --- /dev/null +++ b/.eslintrc.cjs @@ -0,0 +1,18 @@ +module.exports = { + root: true, + env: { browser: true, es2020: true }, + extends: [ + 'eslint:recommended', + 'plugin:@typescript-eslint/recommended', + 'plugin:react-hooks/recommended', + ], + ignorePatterns: ['dist', '.eslintrc.cjs'], + parser: '@typescript-eslint/parser', + plugins: ['react-refresh'], + rules: { + 'react-refresh/only-export-components': [ + 'warn', + { allowConstantExport: true }, + ], + }, +} 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/.vite/deps/_metadata.json b/.vite/deps/_metadata.json new file mode 100644 index 0000000..556b748 --- /dev/null +++ b/.vite/deps/_metadata.json @@ -0,0 +1,8 @@ +{ + "hash": "53f9bab4", + "configHash": "002b0fa1", + "lockfileHash": "e3b0c442", + "browserHash": "6003c74b", + "optimized": {}, + "chunks": {} +} \ No newline at end of file diff --git a/.vite/deps/package.json b/.vite/deps/package.json new file mode 100644 index 0000000..3dbc1ca --- /dev/null +++ b/.vite/deps/package.json @@ -0,0 +1,3 @@ +{ + "type": "module" +} diff --git a/README.md b/README.md index 59e8419..9c8df27 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,2 @@ # peerly-admin -PeerLy is a peer-reward and recognition system with high-5's. (hi5) +PeerLy is a peer-reward and recognition system diff --git a/index.html b/index.html new file mode 100644 index 0000000..e4b78ea --- /dev/null +++ b/index.html @@ -0,0 +1,13 @@ + + + + + + + Vite + React + TS + + +
+ + + diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..34fca6f --- /dev/null +++ b/package-lock.json @@ -0,0 +1,3255 @@ +{ + "name": "peerly_admin", + "version": "0.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "peerly_admin", + "version": "0.0.0", + "dependencies": { + "react": "^18.3.1", + "react-dom": "^18.3.1" + }, + "devDependencies": { + "@types/react": "^18.3.3", + "@types/react-dom": "^18.3.0", + "@typescript-eslint/eslint-plugin": "^7.15.0", + "@typescript-eslint/parser": "^7.15.0", + "@vitejs/plugin-react": "^4.3.1", + "eslint": "^8.57.0", + "eslint-plugin-react-hooks": "^4.6.2", + "eslint-plugin-react-refresh": "^0.4.7", + "typescript": "^5.2.2", + "vite": "^5.3.4" + } + }, + "node_modules/@ampproject/remapping": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", + "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", + "dev": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz", + "integrity": "sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==", + "dev": true, + "dependencies": { + "@babel/highlight": "^7.24.7", + "picocolors": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.24.9", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.24.9.tgz", + "integrity": "sha512-e701mcfApCJqMMueQI0Fb68Amflj83+dvAvHawoBpAz+GDjCIyGHzNwnefjsWJ3xiYAqqiQFoWbspGYBdb2/ng==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.24.9", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.24.9.tgz", + "integrity": "sha512-5e3FI4Q3M3Pbr21+5xJwCv6ZT6KmGkI0vw3Tozy5ODAQFTIWe37iT8Cr7Ice2Ntb+M3iSKCEWMB1MBgKrW3whg==", + "dev": true, + "dependencies": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.24.7", + "@babel/generator": "^7.24.9", + "@babel/helper-compilation-targets": "^7.24.8", + "@babel/helper-module-transforms": "^7.24.9", + "@babel/helpers": "^7.24.8", + "@babel/parser": "^7.24.8", + "@babel/template": "^7.24.7", + "@babel/traverse": "^7.24.8", + "@babel/types": "^7.24.9", + "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/core/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, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/generator": { + "version": "7.24.10", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.24.10.tgz", + "integrity": "sha512-o9HBZL1G2129luEUlG1hB4N/nlYNWHnpwlND9eOMclRqqu1YDy2sSYVCFUZwl8I1Gxh+QSRrP2vD7EpUmFVXxg==", + "dev": true, + "dependencies": { + "@babel/types": "^7.24.9", + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25", + "jsesc": "^2.5.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.24.8.tgz", + "integrity": "sha512-oU+UoqCHdp+nWVDkpldqIQL/i/bvAv53tRqLG/s+cOXxe66zOYLU7ar/Xs3LdmBihrUMEUhwu6dMZwbNOYDwvw==", + "dev": true, + "dependencies": { + "@babel/compat-data": "^7.24.8", + "@babel/helper-validator-option": "^7.24.8", + "browserslist": "^4.23.1", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets/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, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-environment-visitor": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.24.7.tgz", + "integrity": "sha512-DoiN84+4Gnd0ncbBOM9AZENV4a5ZiL39HYMyZJGZ/AZEykHYdJw0wW3kdcsh9/Kn+BRXHLkkklZ51ecPKmI1CQ==", + "dev": true, + "dependencies": { + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-function-name": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.24.7.tgz", + "integrity": "sha512-FyoJTsj/PEUWu1/TYRiXTIHc8lbw+TDYkZuoE43opPS5TrI7MyONBE1oNvfguEXAD9yhQRrVBnXdXzSLQl9XnA==", + "dev": true, + "dependencies": { + "@babel/template": "^7.24.7", + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-hoist-variables": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.24.7.tgz", + "integrity": "sha512-MJJwhkoGy5c4ehfoRyrJ/owKeMl19U54h27YYftT0o2teQ3FJ3nQUf/I3LlJsX4l3qlw7WRXUmiyajvHXoTubQ==", + "dev": true, + "dependencies": { + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.7.tgz", + "integrity": "sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==", + "dev": true, + "dependencies": { + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.24.9", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.24.9.tgz", + "integrity": "sha512-oYbh+rtFKj/HwBQkFlUzvcybzklmVdVV3UU+mN7n2t/q3yGHbuVdNxyFvSBO1tfvjyArpHNcWMAzsSPdyI46hw==", + "dev": true, + "dependencies": { + "@babel/helper-environment-visitor": "^7.24.7", + "@babel/helper-module-imports": "^7.24.7", + "@babel/helper-simple-access": "^7.24.7", + "@babel/helper-split-export-declaration": "^7.24.7", + "@babel/helper-validator-identifier": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.8.tgz", + "integrity": "sha512-FFWx5142D8h2Mgr/iPVGH5G7w6jDn4jUSpZTyDnQO0Yn7Ks2Kuz6Pci8H6MPCoUJegd/UZQ3tAvfLCxQSnWWwg==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-simple-access": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.24.7.tgz", + "integrity": "sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg==", + "dev": true, + "dependencies": { + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-split-export-declaration": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.7.tgz", + "integrity": "sha512-oy5V7pD+UvfkEATUKvIjvIAH/xCzfsFVw7ygW2SI6NClZzquT+mwdTfgfdbUiceh6iQO0CHtCPsyze/MZ2YbAA==", + "dev": true, + "dependencies": { + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.8.tgz", + "integrity": "sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz", + "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.24.8.tgz", + "integrity": "sha512-xb8t9tD1MHLungh/AIoWYN+gVHaB9kwlu8gffXGSt3FFEIT7RjS+xWbc2vUD1UTZdIpKj/ab3rdqJ7ufngyi2Q==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.24.8.tgz", + "integrity": "sha512-gV2265Nkcz7weJJfvDoAEVzC1e2OTDpkGbEsebse8koXUJUXPsCMi7sRo/+SPMuMZ9MtUPnGwITTnQnU5YjyaQ==", + "dev": true, + "dependencies": { + "@babel/template": "^7.24.7", + "@babel/types": "^7.24.8" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz", + "integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==", + "dev": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.24.7", + "chalk": "^2.4.2", + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.8.tgz", + "integrity": "sha512-WzfbgXOkGzZiXXCqk43kKwZjzwx4oulxZi3nq2TYL9mOjQv6kYwul9mz6ID36njuL7Xkp6nJEfok848Zj10j/w==", + "dev": true, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-self": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.24.7.tgz", + "integrity": "sha512-fOPQYbGSgH0HUp4UJO4sMBFjY6DuWq+2i8rixyUMb3CdGixs/gccURvYOAhajBdKDoGajFr3mUq5rH3phtkGzw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-source": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.24.7.tgz", + "integrity": "sha512-J2z+MWzZHVOemyLweMqngXrgGC42jQ//R0KdxqkIz/OrbVIIlhFI3WigZ5fO+nwFvBlncr4MGapd8vTyc7RPNQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/template": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.7.tgz", + "integrity": "sha512-jYqfPrU9JTF0PmPy1tLYHW4Mp4KlgxJD9l2nP9fD6yT/ICi554DmrWBAEYpIelzjHf1msDP3PxJIRt/nFNfBig==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.24.7", + "@babel/parser": "^7.24.7", + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.8.tgz", + "integrity": "sha512-t0P1xxAPzEDcEPmjprAQq19NWum4K0EQPjMwZQZbHt+GiZqvjCHjj755Weq1YRPVzBI+3zSfvScfpnuIecVFJQ==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.24.7", + "@babel/generator": "^7.24.8", + "@babel/helper-environment-visitor": "^7.24.7", + "@babel/helper-function-name": "^7.24.7", + "@babel/helper-hoist-variables": "^7.24.7", + "@babel/helper-split-export-declaration": "^7.24.7", + "@babel/parser": "^7.24.8", + "@babel/types": "^7.24.8", + "debug": "^4.3.1", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.24.9", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.9.tgz", + "integrity": "sha512-xm8XrMKz0IlUdocVbYJe0Z9xEgidU7msskG8BbhnTPK/HZ2z/7FP7ykqPgrUH+C+r414mNfNWam1f2vqOjqjYQ==", + "dev": true, + "dependencies": { + "@babel/helper-string-parser": "^7.24.8", + "@babel/helper-validator-identifier": "^7.24.7", + "to-fast-properties": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", + "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", + "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", + "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", + "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", + "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", + "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", + "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", + "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", + "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", + "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", + "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", + "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", + "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", + "cpu": [ + "mips64el" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", + "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", + "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", + "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", + "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", + "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", + "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", + "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", + "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", + "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", + "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", + "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.11.0", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.11.0.tgz", + "integrity": "sha512-G/M/tIiMrTAxEWRfLfQJMmGNX28IxBg4PBz8XqQhqUHLFI6TL2htpIB1iQCj144V5ee/JaKyT9/WZ0MGZWfA7A==", + "dev": true, + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", + "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", + "dev": true, + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.6.0", + "globals": "^13.19.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/eslintrc/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@eslint/eslintrc/node_modules/globals": { + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "dev": true, + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@eslint/eslintrc/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@eslint/js": { + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz", + "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/@humanwhocodes/config-array": { + "version": "0.11.14", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", + "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", + "deprecated": "Use @eslint/config-array instead", + "dev": true, + "dependencies": { + "@humanwhocodes/object-schema": "^2.0.2", + "debug": "^4.3.1", + "minimatch": "^3.0.5" + }, + "engines": { + "node": ">=10.10.0" + } + }, + "node_modules/@humanwhocodes/config-array/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@humanwhocodes/config-array/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/object-schema": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", + "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", + "deprecated": "Use @eslint/object-schema instead", + "dev": true + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", + "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", + "dev": true, + "dependencies": { + "@jridgewell/set-array": "^1.2.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "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, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", + "dev": true + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "dev": true, + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.19.0.tgz", + "integrity": "sha512-JlPfZ/C7yn5S5p0yKk7uhHTTnFlvTgLetl2VxqE518QgyM7C9bSfFTYvB/Q/ftkq0RIPY4ySxTz+/wKJ/dXC0w==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.19.0.tgz", + "integrity": "sha512-RDxUSY8D1tWYfn00DDi5myxKgOk6RvWPxhmWexcICt/MEC6yEMr4HNCu1sXXYLw8iAsg0D44NuU+qNq7zVWCrw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.19.0.tgz", + "integrity": "sha512-emvKHL4B15x6nlNTBMtIaC9tLPRpeA5jMvRLXVbl/W9Ie7HhkrE7KQjvgS9uxgatL1HmHWDXk5TTS4IaNJxbAA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.19.0.tgz", + "integrity": "sha512-fO28cWA1dC57qCd+D0rfLC4VPbh6EOJXrreBmFLWPGI9dpMlER2YwSPZzSGfq11XgcEpPukPTfEVFtw2q2nYJg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.19.0.tgz", + "integrity": "sha512-2Rn36Ubxdv32NUcfm0wB1tgKqkQuft00PtM23VqLuCUR4N5jcNWDoV5iBC9jeGdgS38WK66ElncprqgMUOyomw==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.19.0.tgz", + "integrity": "sha512-gJuzIVdq/X1ZA2bHeCGCISe0VWqCoNT8BvkQ+BfsixXwTOndhtLUpOg0A1Fcx/+eA6ei6rMBzlOz4JzmiDw7JQ==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.19.0.tgz", + "integrity": "sha512-0EkX2HYPkSADo9cfeGFoQ7R0/wTKb7q6DdwI4Yn/ULFE1wuRRCHybxpl2goQrx4c/yzK3I8OlgtBu4xvted0ug==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.19.0.tgz", + "integrity": "sha512-GlIQRj9px52ISomIOEUq/IojLZqzkvRpdP3cLgIE1wUWaiU5Takwlzpz002q0Nxxr1y2ZgxC2obWxjr13lvxNQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.19.0.tgz", + "integrity": "sha512-N6cFJzssruDLUOKfEKeovCKiHcdwVYOT1Hs6dovDQ61+Y9n3Ek4zXvtghPPelt6U0AH4aDGnDLb83uiJMkWYzQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.19.0.tgz", + "integrity": "sha512-2DnD3mkS2uuam/alF+I7M84koGwvn3ZVD7uG+LEWpyzo/bq8+kKnus2EVCkcvh6PlNB8QPNFOz6fWd5N8o1CYg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.19.0.tgz", + "integrity": "sha512-D6pkaF7OpE7lzlTOFCB2m3Ngzu2ykw40Nka9WmKGUOTS3xcIieHe82slQlNq69sVB04ch73thKYIWz/Ian8DUA==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.19.0.tgz", + "integrity": "sha512-HBndjQLP8OsdJNSxpNIN0einbDmRFg9+UQeZV1eiYupIRuZsDEoeGU43NQsS34Pp166DtwQOnpcbV/zQxM+rWA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.19.0.tgz", + "integrity": "sha512-HxfbvfCKJe/RMYJJn0a12eiOI9OOtAUF4G6ozrFUK95BNyoJaSiBjIOHjZskTUffUrB84IPKkFG9H9nEvJGW6A==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.19.0.tgz", + "integrity": "sha512-HxDMKIhmcguGTiP5TsLNolwBUK3nGGUEoV/BO9ldUBoMLBssvh4J0X8pf11i1fTV7WShWItB1bKAKjX4RQeYmg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.19.0.tgz", + "integrity": "sha512-xItlIAZZaiG/u0wooGzRsx11rokP4qyc/79LkAOdznGRAbOFc+SfEdfUOszG1odsHNgwippUJavag/+W/Etc6Q==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.19.0.tgz", + "integrity": "sha512-xNo5fV5ycvCCKqiZcpB65VMR11NJB+StnxHz20jdqRAktfdfzhgjTiJ2doTDQE/7dqGaV5I7ZGqKpgph6lCIag==", + "cpu": [ + "x64" + ], + "dev": true, + "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, + "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.6.8", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.8.tgz", + "integrity": "sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==", + "dev": true, + "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, + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__traverse": { + "version": "7.20.6", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.6.tgz", + "integrity": "sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg==", + "dev": true, + "dependencies": { + "@babel/types": "^7.20.7" + } + }, + "node_modules/@types/estree": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", + "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", + "dev": true + }, + "node_modules/@types/prop-types": { + "version": "15.7.12", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.12.tgz", + "integrity": "sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q==", + "dev": true + }, + "node_modules/@types/react": { + "version": "18.3.3", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.3.tgz", + "integrity": "sha512-hti/R0pS0q1/xx+TsI73XIqk26eBsISZ2R0wUijXIngRK9R/e7Xw/cXVxQK7R5JjW+SV4zGcn5hXjudkN/pLIw==", + "dev": true, + "dependencies": { + "@types/prop-types": "*", + "csstype": "^3.0.2" + } + }, + "node_modules/@types/react-dom": { + "version": "18.3.0", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.0.tgz", + "integrity": "sha512-EhwApuTmMBmXuFOikhQLIBUn6uFg81SwLMOAUgodJF14SOBOCMdU04gDoYi0WOJJHD144TL32z4yDqCW3dnkQg==", + "dev": true, + "dependencies": { + "@types/react": "*" + } + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "7.17.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.17.0.tgz", + "integrity": "sha512-pyiDhEuLM3PuANxH7uNYan1AaFs5XE0zw1hq69JBvGvE7gSuEoQl1ydtEe/XQeoC3GQxLXyOVa5kNOATgM638A==", + "dev": true, + "dependencies": { + "@eslint-community/regexpp": "^4.10.0", + "@typescript-eslint/scope-manager": "7.17.0", + "@typescript-eslint/type-utils": "7.17.0", + "@typescript-eslint/utils": "7.17.0", + "@typescript-eslint/visitor-keys": "7.17.0", + "graphemer": "^1.4.0", + "ignore": "^5.3.1", + "natural-compare": "^1.4.0", + "ts-api-utils": "^1.3.0" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^7.0.0", + "eslint": "^8.56.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "7.17.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.17.0.tgz", + "integrity": "sha512-puiYfGeg5Ydop8eusb/Hy1k7QmOU6X3nvsqCgzrB2K4qMavK//21+PzNE8qeECgNOIoertJPUC1SpegHDI515A==", + "dev": true, + "dependencies": { + "@typescript-eslint/scope-manager": "7.17.0", + "@typescript-eslint/types": "7.17.0", + "@typescript-eslint/typescript-estree": "7.17.0", + "@typescript-eslint/visitor-keys": "7.17.0", + "debug": "^4.3.4" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.56.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "7.17.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.17.0.tgz", + "integrity": "sha512-0P2jTTqyxWp9HiKLu/Vemr2Rg1Xb5B7uHItdVZ6iAenXmPo4SZ86yOPCJwMqpCyaMiEHTNqizHfsbmCFT1x9SA==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "7.17.0", + "@typescript-eslint/visitor-keys": "7.17.0" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "7.17.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.17.0.tgz", + "integrity": "sha512-XD3aaBt+orgkM/7Cei0XNEm1vwUxQ958AOLALzPlbPqb8C1G8PZK85tND7Jpe69Wualri81PLU+Zc48GVKIMMA==", + "dev": true, + "dependencies": { + "@typescript-eslint/typescript-estree": "7.17.0", + "@typescript-eslint/utils": "7.17.0", + "debug": "^4.3.4", + "ts-api-utils": "^1.3.0" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.56.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/types": { + "version": "7.17.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.17.0.tgz", + "integrity": "sha512-a29Ir0EbyKTKHnZWbNsrc/gqfIBqYPwj3F2M+jWE/9bqfEHg0AMtXzkbUkOG6QgEScxh2+Pz9OXe11jHDnHR7A==", + "dev": true, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "7.17.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.17.0.tgz", + "integrity": "sha512-72I3TGq93t2GoSBWI093wmKo0n6/b7O4j9o8U+f65TVD0FS6bI2180X5eGEr8MA8PhKMvYe9myZJquUT2JkCZw==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "7.17.0", + "@typescript-eslint/visitor-keys": "7.17.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^1.3.0" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "7.17.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.17.0.tgz", + "integrity": "sha512-r+JFlm5NdB+JXc7aWWZ3fKSm1gn0pkswEwIYsrGPdsT2GjsRATAKXiNtp3vgAAO1xZhX8alIOEQnNMl3kbTgJw==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.4.0", + "@typescript-eslint/scope-manager": "7.17.0", + "@typescript-eslint/types": "7.17.0", + "@typescript-eslint/typescript-estree": "7.17.0" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.56.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "7.17.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.17.0.tgz", + "integrity": "sha512-RVGC9UhPOCsfCdI9pU++K4nD7to+jTcMIbXTSOcrLqUEW6gF2pU1UUbYJKc9cvcRSK1UDeMJ7pdMxf4bhMpV/A==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "7.17.0", + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@ungap/structured-clone": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", + "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", + "dev": true + }, + "node_modules/@vitejs/plugin-react": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.3.1.tgz", + "integrity": "sha512-m/V2syj5CuVnaxcUJOQRel/Wr31FFXRFlnOoq1TVtkCxsY5veGMTEmpWHndrhB2U8ScHtCQB1e+4hWYExQc6Lg==", + "dev": true, + "dependencies": { + "@babel/core": "^7.24.5", + "@babel/plugin-transform-react-jsx-self": "^7.24.5", + "@babel/plugin-transform-react-jsx-source": "^7.24.1", + "@types/babel__core": "^7.20.5", + "react-refresh": "^0.14.2" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "peerDependencies": { + "vite": "^4.2.0 || ^5.0.0" + } + }, + "node_modules/acorn": { + "version": "8.12.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", + "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.23.2", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.2.tgz", + "integrity": "sha512-qkqSyistMYdxAcw+CzbZwlBy8AGmS/eEWs+sEV5TnLRGDOL+C5M2EnH6tlZyg0YoAxGJAFKh61En9BR941GnHA==", + "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" + } + ], + "dependencies": { + "caniuse-lite": "^1.0.30001640", + "electron-to-chromium": "^1.4.820", + "node-releases": "^2.0.14", + "update-browserslist-db": "^1.1.0" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001643", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001643.tgz", + "integrity": "sha512-ERgWGNleEilSrHM6iUz/zJNSQTP8Mr21wDWpdgvRwcTXGAq6jMtOUPP4dqFPTdKqZ2wKTdtB+uucZ3MRpAUSmg==", + "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" + } + ] + }, + "node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, + "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 + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/csstype": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", + "dev": true + }, + "node_modules/debug": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", + "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/electron-to-chromium": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.1.tgz", + "integrity": "sha512-FKbOCOQ5QRB3VlIbl1LZQefWIYwszlBloaXcY2rbfpu9ioJnNh3TK03YtIDKDo3WKBi8u+YV4+Fn2CkEozgf4w==", + "dev": true + }, + "node_modules/esbuild": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", + "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", + "dev": true, + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.21.5", + "@esbuild/android-arm": "0.21.5", + "@esbuild/android-arm64": "0.21.5", + "@esbuild/android-x64": "0.21.5", + "@esbuild/darwin-arm64": "0.21.5", + "@esbuild/darwin-x64": "0.21.5", + "@esbuild/freebsd-arm64": "0.21.5", + "@esbuild/freebsd-x64": "0.21.5", + "@esbuild/linux-arm": "0.21.5", + "@esbuild/linux-arm64": "0.21.5", + "@esbuild/linux-ia32": "0.21.5", + "@esbuild/linux-loong64": "0.21.5", + "@esbuild/linux-mips64el": "0.21.5", + "@esbuild/linux-ppc64": "0.21.5", + "@esbuild/linux-riscv64": "0.21.5", + "@esbuild/linux-s390x": "0.21.5", + "@esbuild/linux-x64": "0.21.5", + "@esbuild/netbsd-x64": "0.21.5", + "@esbuild/openbsd-x64": "0.21.5", + "@esbuild/sunos-x64": "0.21.5", + "@esbuild/win32-arm64": "0.21.5", + "@esbuild/win32-ia32": "0.21.5", + "@esbuild/win32-x64": "0.21.5" + } + }, + "node_modules/escalade": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", + "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/eslint": { + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz", + "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.4", + "@eslint/js": "8.57.0", + "@humanwhocodes/config-array": "^0.11.14", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "@ungap/structured-clone": "^1.2.0", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", + "esquery": "^1.4.2", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "graphemer": "^1.4.0", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3", + "strip-ansi": "^6.0.1", + "text-table": "^0.2.0" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-plugin-react-hooks": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.2.tgz", + "integrity": "sha512-QzliNJq4GinDBcD8gPB5v0wh6g8q3SUi6EFF0x8N/BL9PoVs0atuGc47ozMRyOWAKdwaZ5OnbOEa3WR+dSGKuQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0" + } + }, + "node_modules/eslint-plugin-react-refresh": { + "version": "0.4.9", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-refresh/-/eslint-plugin-react-refresh-0.4.9.tgz", + "integrity": "sha512-QK49YrBAo5CLNLseZ7sZgvgTy21E6NEw22eZqc4teZfH8pxV3yXc9XXOYfUI6JNpw7mfHNkAeWtBxrTyykB6HA==", + "dev": true, + "peerDependencies": { + "eslint": ">=7" + } + }, + "node_modules/eslint-scope": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/eslint/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/eslint/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/eslint/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/eslint/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/eslint/node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/globals": { + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "dev": true, + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/eslint/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/espree": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", + "dev": true, + "dependencies": { + "acorn": "^8.9.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esquery": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", + "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", + "dev": true, + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "node_modules/fast-glob": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", + "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true + }, + "node_modules/fastq": { + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", + "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", + "dev": true, + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, + "dependencies": { + "flat-cache": "^3.0.4" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat-cache": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", + "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", + "dev": true, + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.3", + "rimraf": "^3.0.2" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/flatted": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", + "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", + "dev": true + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": 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, + "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, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/glob/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/glob/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dev": true, + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "dev": true + }, + "node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/ignore": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", + "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", + "dev": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "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==" + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true, + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true + }, + "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, + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, + "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==", + "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, + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.7.tgz", + "integrity": "sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==", + "dev": true, + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/nanoid": { + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true + }, + "node_modules/node-releases": { + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz", + "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==", + "dev": true + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/optionator": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", + "dev": true, + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/picocolors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", + "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==", + "dev": true + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/postcss": { + "version": "8.4.40", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.40.tgz", + "integrity": "sha512-YF2kKIUzAofPMpfH6hOi2cGnv/HrUlfucspc7pDyvv7kGdqXrfj8SCl/t8owkEgKEuu8ZcRjSOxFxVLqwChZ2Q==", + "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" + } + ], + "dependencies": { + "nanoid": "^3.3.7", + "picocolors": "^1.0.1", + "source-map-js": "^1.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "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==", + "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==", + "dependencies": { + "loose-envify": "^1.1.0", + "scheduler": "^0.23.2" + }, + "peerDependencies": { + "react": "^18.3.1" + } + }, + "node_modules/react-refresh": { + "version": "0.14.2", + "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.2.tgz", + "integrity": "sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true, + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rollup": { + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.19.0.tgz", + "integrity": "sha512-5r7EYSQIowHsK4eTZ0Y81qpZuJz+MUuYeqmmYmRMl1nwhdmbiYqt5jwzf6u7wyOzJgYqtCRMtVRKOtHANBz7rA==", + "dev": true, + "dependencies": { + "@types/estree": "1.0.5" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.19.0", + "@rollup/rollup-android-arm64": "4.19.0", + "@rollup/rollup-darwin-arm64": "4.19.0", + "@rollup/rollup-darwin-x64": "4.19.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.19.0", + "@rollup/rollup-linux-arm-musleabihf": "4.19.0", + "@rollup/rollup-linux-arm64-gnu": "4.19.0", + "@rollup/rollup-linux-arm64-musl": "4.19.0", + "@rollup/rollup-linux-powerpc64le-gnu": "4.19.0", + "@rollup/rollup-linux-riscv64-gnu": "4.19.0", + "@rollup/rollup-linux-s390x-gnu": "4.19.0", + "@rollup/rollup-linux-x64-gnu": "4.19.0", + "@rollup/rollup-linux-x64-musl": "4.19.0", + "@rollup/rollup-win32-arm64-msvc": "4.19.0", + "@rollup/rollup-win32-ia32-msvc": "4.19.0", + "@rollup/rollup-win32-x64-msvc": "4.19.0", + "fsevents": "~2.3.2" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.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==", + "dependencies": { + "loose-envify": "^1.1.0" + } + }, + "node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/source-map-js": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", + "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "dev": true + }, + "node_modules/to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/ts-api-utils": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz", + "integrity": "sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==", + "dev": true, + "engines": { + "node": ">=16" + }, + "peerDependencies": { + "typescript": ">=4.2.0" + } + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/typescript": { + "version": "5.5.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.4.tgz", + "integrity": "sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.0.tgz", + "integrity": "sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==", + "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" + } + ], + "dependencies": { + "escalade": "^3.1.2", + "picocolors": "^1.0.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/vite": { + "version": "5.3.5", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.3.5.tgz", + "integrity": "sha512-MdjglKR6AQXQb9JGiS7Rc2wC6uMjcm7Go/NHNO63EwiJXfuk9PgqiP/n5IDJCziMkfw9n4Ubp7lttNwz+8ZVKA==", + "dev": true, + "dependencies": { + "esbuild": "^0.21.3", + "postcss": "^8.4.39", + "rollup": "^4.13.0" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || >=20.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", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.4.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + } + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": 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 + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..e88db0f --- /dev/null +++ b/package.json @@ -0,0 +1,28 @@ +{ + "name": "peerly_admin", + "private": true, + "version": "0.0.0", + "type": "module", + "scripts": { + "dev": "vite", + "build": "tsc -b && vite build", + "lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0", + "preview": "vite preview" + }, + "dependencies": { + "react": "^18.3.1", + "react-dom": "^18.3.1" + }, + "devDependencies": { + "@types/react": "^18.3.3", + "@types/react-dom": "^18.3.0", + "@typescript-eslint/eslint-plugin": "^7.15.0", + "@typescript-eslint/parser": "^7.15.0", + "@vitejs/plugin-react": "^4.3.1", + "eslint": "^8.57.0", + "eslint-plugin-react-hooks": "^4.6.2", + "eslint-plugin-react-refresh": "^0.4.7", + "typescript": "^5.2.2", + "vite": "^5.3.4" + } +} diff --git a/public/vite.svg b/public/vite.svg new file mode 100644 index 0000000..e7b8dfb --- /dev/null +++ b/public/vite.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/App.css b/src/App.css new file mode 100644 index 0000000..b9d355d --- /dev/null +++ b/src/App.css @@ -0,0 +1,42 @@ +#root { + max-width: 1280px; + margin: 0 auto; + padding: 2rem; + text-align: center; +} + +.logo { + height: 6em; + padding: 1.5em; + will-change: filter; + transition: filter 300ms; +} +.logo:hover { + filter: drop-shadow(0 0 2em #646cffaa); +} +.logo.react:hover { + filter: drop-shadow(0 0 2em #61dafbaa); +} + +@keyframes logo-spin { + from { + transform: rotate(0deg); + } + to { + transform: rotate(360deg); + } +} + +@media (prefers-reduced-motion: no-preference) { + a:nth-of-type(2) .logo { + animation: logo-spin infinite 20s linear; + } +} + +.card { + padding: 2em; +} + +.read-the-docs { + color: #888; +} diff --git a/src/App.tsx b/src/App.tsx new file mode 100644 index 0000000..c56c219 --- /dev/null +++ b/src/App.tsx @@ -0,0 +1,13 @@ + +import './App.css' + +function App() { + + return ( + <> + Peerly + + ) +} + +export default App 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/index.css b/src/index.css new file mode 100644 index 0000000..6119ad9 --- /dev/null +++ b/src/index.css @@ -0,0 +1,68 @@ +:root { + font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif; + line-height: 1.5; + font-weight: 400; + + color-scheme: light dark; + color: rgba(255, 255, 255, 0.87); + background-color: #242424; + + font-synthesis: none; + text-rendering: optimizeLegibility; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +a { + font-weight: 500; + color: #646cff; + text-decoration: inherit; +} +a:hover { + color: #535bf2; +} + +body { + margin: 0; + display: flex; + place-items: center; + min-width: 320px; + min-height: 100vh; +} + +h1 { + font-size: 3.2em; + line-height: 1.1; +} + +button { + border-radius: 8px; + border: 1px solid transparent; + padding: 0.6em 1.2em; + font-size: 1em; + font-weight: 500; + font-family: inherit; + background-color: #1a1a1a; + cursor: pointer; + transition: border-color 0.25s; +} +button:hover { + border-color: #646cff; +} +button:focus, +button:focus-visible { + outline: 4px auto -webkit-focus-ring-color; +} + +@media (prefers-color-scheme: light) { + :root { + color: #213547; + background-color: #ffffff; + } + a:hover { + color: #747bff; + } + button { + background-color: #f9f9f9; + } +} diff --git a/src/main.tsx b/src/main.tsx new file mode 100644 index 0000000..3d7150d --- /dev/null +++ b/src/main.tsx @@ -0,0 +1,10 @@ +import React from 'react' +import ReactDOM from 'react-dom/client' +import App from './App.tsx' +import './index.css' + +ReactDOM.createRoot(document.getElementById('root')!).render( + + + , +) diff --git a/src/vite-env.d.ts b/src/vite-env.d.ts new file mode 100644 index 0000000..11f02fe --- /dev/null +++ b/src/vite-env.d.ts @@ -0,0 +1 @@ +/// diff --git a/tsconfig.app.json b/tsconfig.app.json new file mode 100644 index 0000000..d739292 --- /dev/null +++ b/tsconfig.app.json @@ -0,0 +1,27 @@ +{ + "compilerOptions": { + "composite": true, + "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo", + "target": "ES2020", + "useDefineForClassFields": true, + "lib": ["ES2020", "DOM", "DOM.Iterable"], + "module": "ESNext", + "skipLibCheck": true, + + /* Bundler mode */ + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "resolveJsonModule": true, + "isolatedModules": true, + "moduleDetection": "force", + "noEmit": true, + "jsx": "react-jsx", + + /* Linting */ + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noFallthroughCasesInSwitch": true + }, + "include": ["src"] +} diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..ea9d0cd --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,11 @@ +{ + "files": [], + "references": [ + { + "path": "./tsconfig.app.json" + }, + { + "path": "./tsconfig.node.json" + } + ] +} diff --git a/tsconfig.node.json b/tsconfig.node.json new file mode 100644 index 0000000..3afdd6e --- /dev/null +++ b/tsconfig.node.json @@ -0,0 +1,13 @@ +{ + "compilerOptions": { + "composite": true, + "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo", + "skipLibCheck": true, + "module": "ESNext", + "moduleResolution": "bundler", + "allowSyntheticDefaultImports": true, + "strict": true, + "noEmit": true + }, + "include": ["vite.config.ts"] +} diff --git a/vite.config.ts b/vite.config.ts new file mode 100644 index 0000000..5a33944 --- /dev/null +++ b/vite.config.ts @@ -0,0 +1,7 @@ +import { defineConfig } from 'vite' +import react from '@vitejs/plugin-react' + +// https://vitejs.dev/config/ +export default defineConfig({ + plugins: [react()], +}) From a4ed6e0e14ebc808e2a2545ab94cb421a93ecaf8 Mon Sep 17 00:00:00 2001 From: Sharyu Marwadi Date: Tue, 30 Jul 2024 12:10:29 +0530 Subject: [PATCH 02/23] admin login page --- package-lock.json | 912 +++++++++++++++++++++++++++-- package.json | 11 +- src/App.css | 42 -- src/App.tsx | 26 +- src/assets/loginImage.webp | Bin 0 -> 7186 bytes src/home/index.tsx | 7 + src/index.css | 68 --- src/login/apiSlice.tsx | 26 + src/login/components/loginForm.tsx | 86 +++ src/login/index.tsx | 25 + src/login/types.tsx | 31 + src/main.tsx | 4 + src/store.tsx | 18 + 13 files changed, 1093 insertions(+), 163 deletions(-) create mode 100644 src/assets/loginImage.webp create mode 100644 src/home/index.tsx create mode 100644 src/login/apiSlice.tsx create mode 100644 src/login/components/loginForm.tsx create mode 100644 src/login/index.tsx create mode 100644 src/login/types.tsx create mode 100644 src/store.tsx diff --git a/package-lock.json b/package-lock.json index 34fca6f..ef6e9e8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,8 +8,17 @@ "name": "peerly_admin", "version": "0.0.0", "dependencies": { + "@emotion/react": "^11.13.0", + "@emotion/styled": "^11.13.0", + "@mui/material": "^5.16.5", + "@reduxjs/toolkit": "^2.2.7", + "formik": "^2.4.6", "react": "^18.3.1", - "react-dom": "^18.3.1" + "react-dom": "^18.3.1", + "react-redux": "^9.1.2", + "react-router-dom": "^6.25.1", + "react-toastify": "^10.0.5", + "yup": "^1.4.0" }, "devDependencies": { "@types/react": "^18.3.3", @@ -41,7 +50,6 @@ "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz", "integrity": "sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==", - "dev": true, "dependencies": { "@babel/highlight": "^7.24.7", "picocolors": "^1.0.0" @@ -102,7 +110,6 @@ "version": "7.24.10", "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.24.10.tgz", "integrity": "sha512-o9HBZL1G2129luEUlG1hB4N/nlYNWHnpwlND9eOMclRqqu1YDy2sSYVCFUZwl8I1Gxh+QSRrP2vD7EpUmFVXxg==", - "dev": true, "dependencies": { "@babel/types": "^7.24.9", "@jridgewell/gen-mapping": "^0.3.5", @@ -142,7 +149,6 @@ "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.24.7.tgz", "integrity": "sha512-DoiN84+4Gnd0ncbBOM9AZENV4a5ZiL39HYMyZJGZ/AZEykHYdJw0wW3kdcsh9/Kn+BRXHLkkklZ51ecPKmI1CQ==", - "dev": true, "dependencies": { "@babel/types": "^7.24.7" }, @@ -154,7 +160,6 @@ "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.24.7.tgz", "integrity": "sha512-FyoJTsj/PEUWu1/TYRiXTIHc8lbw+TDYkZuoE43opPS5TrI7MyONBE1oNvfguEXAD9yhQRrVBnXdXzSLQl9XnA==", - "dev": true, "dependencies": { "@babel/template": "^7.24.7", "@babel/types": "^7.24.7" @@ -167,7 +172,6 @@ "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.24.7.tgz", "integrity": "sha512-MJJwhkoGy5c4ehfoRyrJ/owKeMl19U54h27YYftT0o2teQ3FJ3nQUf/I3LlJsX4l3qlw7WRXUmiyajvHXoTubQ==", - "dev": true, "dependencies": { "@babel/types": "^7.24.7" }, @@ -179,7 +183,6 @@ "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.7.tgz", "integrity": "sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==", - "dev": true, "dependencies": { "@babel/traverse": "^7.24.7", "@babel/types": "^7.24.7" @@ -233,7 +236,6 @@ "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.7.tgz", "integrity": "sha512-oy5V7pD+UvfkEATUKvIjvIAH/xCzfsFVw7ygW2SI6NClZzquT+mwdTfgfdbUiceh6iQO0CHtCPsyze/MZ2YbAA==", - "dev": true, "dependencies": { "@babel/types": "^7.24.7" }, @@ -245,7 +247,6 @@ "version": "7.24.8", "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.8.tgz", "integrity": "sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ==", - "dev": true, "engines": { "node": ">=6.9.0" } @@ -254,7 +255,6 @@ "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz", "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==", - "dev": true, "engines": { "node": ">=6.9.0" } @@ -285,7 +285,6 @@ "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz", "integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==", - "dev": true, "dependencies": { "@babel/helper-validator-identifier": "^7.24.7", "chalk": "^2.4.2", @@ -300,7 +299,6 @@ "version": "7.24.8", "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.8.tgz", "integrity": "sha512-WzfbgXOkGzZiXXCqk43kKwZjzwx4oulxZi3nq2TYL9mOjQv6kYwul9mz6ID36njuL7Xkp6nJEfok848Zj10j/w==", - "dev": true, "bin": { "parser": "bin/babel-parser.js" }, @@ -338,11 +336,21 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/@babel/runtime": { + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.0.tgz", + "integrity": "sha512-7dRy4DwXwtzBrPbZflqxnvfxLF8kdZXPkhymtDeFoFqE6ldzjQFgYTtYIFARcLEYDrqfBfYcZt1WqFxRoyC9Rw==", + "dependencies": { + "regenerator-runtime": "^0.14.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@babel/template": { "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.7.tgz", "integrity": "sha512-jYqfPrU9JTF0PmPy1tLYHW4Mp4KlgxJD9l2nP9fD6yT/ICi554DmrWBAEYpIelzjHf1msDP3PxJIRt/nFNfBig==", - "dev": true, "dependencies": { "@babel/code-frame": "^7.24.7", "@babel/parser": "^7.24.7", @@ -356,7 +364,6 @@ "version": "7.24.8", "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.8.tgz", "integrity": "sha512-t0P1xxAPzEDcEPmjprAQq19NWum4K0EQPjMwZQZbHt+GiZqvjCHjj755Weq1YRPVzBI+3zSfvScfpnuIecVFJQ==", - "dev": true, "dependencies": { "@babel/code-frame": "^7.24.7", "@babel/generator": "^7.24.8", @@ -377,7 +384,6 @@ "version": "7.24.9", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.9.tgz", "integrity": "sha512-xm8XrMKz0IlUdocVbYJe0Z9xEgidU7msskG8BbhnTPK/HZ2z/7FP7ykqPgrUH+C+r414mNfNWam1f2vqOjqjYQ==", - "dev": true, "dependencies": { "@babel/helper-string-parser": "^7.24.8", "@babel/helper-validator-identifier": "^7.24.7", @@ -387,6 +393,155 @@ "node": ">=6.9.0" } }, + "node_modules/@emotion/babel-plugin": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.12.0.tgz", + "integrity": "sha512-y2WQb+oP8Jqvvclh8Q55gLUyb7UFvgv7eJfsj7td5TToBrIUtPay2kMrZi4xjq9qw2vD0ZR5fSho0yqoFgX7Rw==", + "dependencies": { + "@babel/helper-module-imports": "^7.16.7", + "@babel/runtime": "^7.18.3", + "@emotion/hash": "^0.9.2", + "@emotion/memoize": "^0.9.0", + "@emotion/serialize": "^1.2.0", + "babel-plugin-macros": "^3.1.0", + "convert-source-map": "^1.5.0", + "escape-string-regexp": "^4.0.0", + "find-root": "^1.1.0", + "source-map": "^0.5.7", + "stylis": "4.2.0" + } + }, + "node_modules/@emotion/babel-plugin/node_modules/convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==" + }, + "node_modules/@emotion/babel-plugin/node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@emotion/cache": { + "version": "11.13.1", + "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.13.1.tgz", + "integrity": "sha512-iqouYkuEblRcXmylXIwwOodiEK5Ifl7JcX7o6V4jI3iW4mLXX3dmt5xwBtIkJiQEXFAI+pC8X0i67yiPkH9Ucw==", + "dependencies": { + "@emotion/memoize": "^0.9.0", + "@emotion/sheet": "^1.4.0", + "@emotion/utils": "^1.4.0", + "@emotion/weak-memoize": "^0.4.0", + "stylis": "4.2.0" + } + }, + "node_modules/@emotion/hash": { + "version": "0.9.2", + "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.2.tgz", + "integrity": "sha512-MyqliTZGuOm3+5ZRSaaBGP3USLw6+EGykkwZns2EPC5g8jJ4z9OrdZY9apkl3+UP9+sdz76YYkwCKP5gh8iY3g==" + }, + "node_modules/@emotion/is-prop-valid": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.3.0.tgz", + "integrity": "sha512-SHetuSLvJDzuNbOdtPVbq6yMMMlLoW5Q94uDqJZqy50gcmAjxFkVqmzqSGEFq9gT2iMuIeKV1PXVWmvUhuZLlQ==", + "dependencies": { + "@emotion/memoize": "^0.9.0" + } + }, + "node_modules/@emotion/memoize": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.9.0.tgz", + "integrity": "sha512-30FAj7/EoJ5mwVPOWhAyCX+FPfMDrVecJAM+Iw9NRoSl4BBAQeqj4cApHHUXOVvIPgLVDsCFoz/hGD+5QQD1GQ==" + }, + "node_modules/@emotion/react": { + "version": "11.13.0", + "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.13.0.tgz", + "integrity": "sha512-WkL+bw1REC2VNV1goQyfxjx1GYJkcc23CRQkXX+vZNLINyfI7o+uUn/rTGPt/xJ3bJHd5GcljgnxHf4wRw5VWQ==", + "dependencies": { + "@babel/runtime": "^7.18.3", + "@emotion/babel-plugin": "^11.12.0", + "@emotion/cache": "^11.13.0", + "@emotion/serialize": "^1.3.0", + "@emotion/use-insertion-effect-with-fallbacks": "^1.1.0", + "@emotion/utils": "^1.4.0", + "@emotion/weak-memoize": "^0.4.0", + "hoist-non-react-statics": "^3.3.1" + }, + "peerDependencies": { + "react": ">=16.8.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@emotion/serialize": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.3.0.tgz", + "integrity": "sha512-jACuBa9SlYajnpIVXB+XOXnfJHyckDfe6fOpORIM6yhBDlqGuExvDdZYHDQGoDf3bZXGv7tNr+LpLjJqiEQ6EA==", + "dependencies": { + "@emotion/hash": "^0.9.2", + "@emotion/memoize": "^0.9.0", + "@emotion/unitless": "^0.9.0", + "@emotion/utils": "^1.4.0", + "csstype": "^3.0.2" + } + }, + "node_modules/@emotion/sheet": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.4.0.tgz", + "integrity": "sha512-fTBW9/8r2w3dXWYM4HCB1Rdp8NLibOw2+XELH5m5+AkWiL/KqYX6dc0kKYlaYyKjrQ6ds33MCdMPEwgs2z1rqg==" + }, + "node_modules/@emotion/styled": { + "version": "11.13.0", + "resolved": "https://registry.npmjs.org/@emotion/styled/-/styled-11.13.0.tgz", + "integrity": "sha512-tkzkY7nQhW/zC4hztlwucpT8QEZ6eUzpXDRhww/Eej4tFfO0FxQYWRyg/c5CCXa4d/f174kqeXYjuQRnhzf6dA==", + "dependencies": { + "@babel/runtime": "^7.18.3", + "@emotion/babel-plugin": "^11.12.0", + "@emotion/is-prop-valid": "^1.3.0", + "@emotion/serialize": "^1.3.0", + "@emotion/use-insertion-effect-with-fallbacks": "^1.1.0", + "@emotion/utils": "^1.4.0" + }, + "peerDependencies": { + "@emotion/react": "^11.0.0-rc.0", + "react": ">=16.8.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@emotion/unitless": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.9.0.tgz", + "integrity": "sha512-TP6GgNZtmtFaFcsOgExdnfxLLpRDla4Q66tnenA9CktvVSdNKDvMVuUah4QvWPIpNjrWsGg3qeGo9a43QooGZQ==" + }, + "node_modules/@emotion/use-insertion-effect-with-fallbacks": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.1.0.tgz", + "integrity": "sha512-+wBOcIV5snwGgI2ya3u99D7/FJquOIniQT1IKyDsBmEgwvpxMNeS65Oib7OnE2d2aY+3BU4OiH+0Wchf8yk3Hw==", + "peerDependencies": { + "react": ">=16.8.0" + } + }, + "node_modules/@emotion/utils": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.4.0.tgz", + "integrity": "sha512-spEnrA1b6hDR/C68lC2M7m6ALPUHZC0lIY7jAS/B/9DuuO1ZP04eov8SMv/6fwRd8pzmsn2AuJEznRREWlQrlQ==" + }, + "node_modules/@emotion/weak-memoize": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.4.0.tgz", + "integrity": "sha512-snKqtPW01tN0ui7yu9rGv69aJXr/a/Ywvl11sUjNtEcRc+ng/mQriFL0wLXMef74iHa/EkftbDzU9F8iFbH+zg==" + }, "node_modules/@esbuild/aix-ppc64": { "version": "0.21.5", "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", @@ -909,7 +1064,6 @@ "version": "0.3.5", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", - "dev": true, "dependencies": { "@jridgewell/set-array": "^1.2.1", "@jridgewell/sourcemap-codec": "^1.4.10", @@ -923,7 +1077,6 @@ "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, "engines": { "node": ">=6.0.0" } @@ -932,7 +1085,6 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", - "dev": true, "engines": { "node": ">=6.0.0" } @@ -940,19 +1092,208 @@ "node_modules/@jridgewell/sourcemap-codec": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", - "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", - "dev": true + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==" }, "node_modules/@jridgewell/trace-mapping": { "version": "0.3.25", "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", - "dev": true, "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, + "node_modules/@mui/core-downloads-tracker": { + "version": "5.16.5", + "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.16.5.tgz", + "integrity": "sha512-ziFn1oPm6VjvHQcdGcAO+fXvOQEgieIj0BuSqcltFU+JXIxjPdVYNTdn2HU7/Ak5Gabk6k2u7+9PV7oZ6JT5sA==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + } + }, + "node_modules/@mui/material": { + "version": "5.16.5", + "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.16.5.tgz", + "integrity": "sha512-eQrjjg4JeczXvh/+8yvJkxWIiKNHVptB/AqpsKfZBWp5mUD5U3VsjODMuUl1K2BSq0omV3CiO/mQmWSSMKSmaA==", + "dependencies": { + "@babel/runtime": "^7.23.9", + "@mui/core-downloads-tracker": "^5.16.5", + "@mui/system": "^5.16.5", + "@mui/types": "^7.2.15", + "@mui/utils": "^5.16.5", + "@popperjs/core": "^2.11.8", + "@types/react-transition-group": "^4.4.10", + "clsx": "^2.1.0", + "csstype": "^3.1.3", + "prop-types": "^15.8.1", + "react-is": "^18.3.1", + "react-transition-group": "^4.4.5" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@emotion/react": "^11.5.0", + "@emotion/styled": "^11.3.0", + "@types/react": "^17.0.0 || ^18.0.0", + "react": "^17.0.0 || ^18.0.0", + "react-dom": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@emotion/react": { + "optional": true + }, + "@emotion/styled": { + "optional": true + }, + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/private-theming": { + "version": "5.16.5", + "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.16.5.tgz", + "integrity": "sha512-CSLg0YkpDqg0aXOxtjo3oTMd3XWMxvNb5d0v4AYVqwOltU8q6GvnZjhWyCLjGSCrcgfwm6/VDjaKLPlR14wxIA==", + "dependencies": { + "@babel/runtime": "^7.23.9", + "@mui/utils": "^5.16.5", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@types/react": "^17.0.0 || ^18.0.0", + "react": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/styled-engine": { + "version": "5.16.4", + "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.16.4.tgz", + "integrity": "sha512-0+mnkf+UiAmTVB8PZFqOhqf729Yh0Cxq29/5cA3VAyDVTRIUUQ8FXQhiAhUIbijFmM72rY80ahFPXIm4WDbzcA==", + "dependencies": { + "@babel/runtime": "^7.23.9", + "@emotion/cache": "^11.11.0", + "csstype": "^3.1.3", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@emotion/react": "^11.4.1", + "@emotion/styled": "^11.3.0", + "react": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@emotion/react": { + "optional": true + }, + "@emotion/styled": { + "optional": true + } + } + }, + "node_modules/@mui/system": { + "version": "5.16.5", + "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.16.5.tgz", + "integrity": "sha512-uzIUGdrWddUx1HPxW4+B2o4vpgKyRxGe/8BxbfXVDPNPHX75c782TseoCnR/VyfnZJfqX87GcxDmnZEE1c031g==", + "dependencies": { + "@babel/runtime": "^7.23.9", + "@mui/private-theming": "^5.16.5", + "@mui/styled-engine": "^5.16.4", + "@mui/types": "^7.2.15", + "@mui/utils": "^5.16.5", + "clsx": "^2.1.0", + "csstype": "^3.1.3", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@emotion/react": "^11.5.0", + "@emotion/styled": "^11.3.0", + "@types/react": "^17.0.0 || ^18.0.0", + "react": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@emotion/react": { + "optional": true + }, + "@emotion/styled": { + "optional": true + }, + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/types": { + "version": "7.2.15", + "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.2.15.tgz", + "integrity": "sha512-nbo7yPhtKJkdf9kcVOF8JZHPZTmqXjJ/tI0bdWgHg5tp9AnIN4Y7f7wm9T+0SyGYJk76+GYZ8Q5XaTYAsUHN0Q==", + "peerDependencies": { + "@types/react": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/utils": { + "version": "5.16.5", + "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.16.5.tgz", + "integrity": "sha512-CwhcA9y44XwK7k2joL3Y29mRUnoBt+gOZZdGyw7YihbEwEErJYBtDwbZwVgH68zAljGe/b+Kd5bzfl63Gi3R2A==", + "dependencies": { + "@babel/runtime": "^7.23.9", + "@mui/types": "^7.2.15", + "@types/prop-types": "^15.7.12", + "clsx": "^2.1.1", + "prop-types": "^15.8.1", + "react-is": "^18.3.1" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@types/react": "^17.0.0 || ^18.0.0", + "react": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -988,6 +1329,46 @@ "node": ">= 8" } }, + "node_modules/@popperjs/core": { + "version": "2.11.8", + "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", + "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/popperjs" + } + }, + "node_modules/@reduxjs/toolkit": { + "version": "2.2.7", + "resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-2.2.7.tgz", + "integrity": "sha512-faI3cZbSdFb8yv9dhDTmGwclW0vk0z5o1cia+kf7gCbaCwHI5e+7tP57mJUv22pNcNbeA62GSrPpfrUfdXcQ6g==", + "dependencies": { + "immer": "^10.0.3", + "redux": "^5.0.1", + "redux-thunk": "^3.1.0", + "reselect": "^5.1.0" + }, + "peerDependencies": { + "react": "^16.9.0 || ^17.0.0 || ^18", + "react-redux": "^7.2.1 || ^8.1.3 || ^9.0.0" + }, + "peerDependenciesMeta": { + "react": { + "optional": true + }, + "react-redux": { + "optional": true + } + } + }, + "node_modules/@remix-run/router": { + "version": "1.18.0", + "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.18.0.tgz", + "integrity": "sha512-L3jkqmqoSVBVKHfpGZmLrex0lxR5SucGA0sUfFzGctehw+S/ggL9L/0NnC5mw6P8HUWpFZ3nQw3cRApjjWx9Sw==", + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/@rollup/rollup-android-arm-eabi": { "version": "4.19.0", "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.19.0.tgz", @@ -1243,17 +1624,29 @@ "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", "dev": true }, + "node_modules/@types/hoist-non-react-statics": { + "version": "3.3.5", + "resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.5.tgz", + "integrity": "sha512-SbcrWzkKBw2cdwRTwQAswfpB9g9LJWfjtUeW/jvNwbhC8cpmmNYVePa+ncbUe0rGTQ7G3Ff6mYUN2VMfLVr+Sg==", + "dependencies": { + "@types/react": "*", + "hoist-non-react-statics": "^3.3.0" + } + }, + "node_modules/@types/parse-json": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz", + "integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==" + }, "node_modules/@types/prop-types": { "version": "15.7.12", "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.12.tgz", - "integrity": "sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q==", - "dev": true + "integrity": "sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q==" }, "node_modules/@types/react": { "version": "18.3.3", "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.3.tgz", "integrity": "sha512-hti/R0pS0q1/xx+TsI73XIqk26eBsISZ2R0wUijXIngRK9R/e7Xw/cXVxQK7R5JjW+SV4zGcn5hXjudkN/pLIw==", - "dev": true, "dependencies": { "@types/prop-types": "*", "csstype": "^3.0.2" @@ -1268,6 +1661,19 @@ "@types/react": "*" } }, + "node_modules/@types/react-transition-group": { + "version": "4.4.10", + "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.10.tgz", + "integrity": "sha512-hT/+s0VQs2ojCX823m60m5f0sL5idt9SO6Tj6Dg+rdphGPIeJbJ6CxvBYkgkGKrYeDjvIpKTR38UzmtHJOGW3Q==", + "dependencies": { + "@types/react": "*" + } + }, + "node_modules/@types/use-sync-external-store": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/@types/use-sync-external-store/-/use-sync-external-store-0.0.3.tgz", + "integrity": "sha512-EwmlvuaxPNej9+T4v5AuBPJa2x2UOJVdjCtDHgcDqitUeOtjnJKJ+apYjVcAoBEMjKW1VVFGZLUb5+qqa09XFA==" + }, "node_modules/@typescript-eslint/eslint-plugin": { "version": "7.17.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.17.0.tgz", @@ -1528,7 +1934,6 @@ "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, "dependencies": { "color-convert": "^1.9.0" }, @@ -1551,6 +1956,20 @@ "node": ">=8" } }, + "node_modules/babel-plugin-macros": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz", + "integrity": "sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==", + "dependencies": { + "@babel/runtime": "^7.12.5", + "cosmiconfig": "^7.0.0", + "resolve": "^1.19.0" + }, + "engines": { + "node": ">=10", + "npm": ">=6" + } + }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", @@ -1614,7 +2033,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true, "engines": { "node": ">=6" } @@ -1643,7 +2061,6 @@ "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, "dependencies": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", @@ -1653,11 +2070,18 @@ "node": ">=4" } }, + "node_modules/clsx": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", + "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", + "engines": { + "node": ">=6" + } + }, "node_modules/color-convert": { "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, "dependencies": { "color-name": "1.1.3" } @@ -1665,8 +2089,7 @@ "node_modules/color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" }, "node_modules/concat-map": { "version": "0.0.1", @@ -1680,6 +2103,21 @@ "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", "dev": true }, + "node_modules/cosmiconfig": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", + "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", + "dependencies": { + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.2.1", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.10.0" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", @@ -1697,14 +2135,12 @@ "node_modules/csstype": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", - "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", - "dev": true + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==" }, "node_modules/debug": { "version": "4.3.5", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", - "dev": true, "dependencies": { "ms": "2.1.2" }, @@ -1723,6 +2159,14 @@ "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", "dev": true }, + "node_modules/deepmerge": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-2.2.1.tgz", + "integrity": "sha512-R9hc1Xa/NOBi9WRVUWg19rl1UB7Tt4kuPd+thNJgFZoxXsTz7ncaPaeIm+40oSGuP33DfMb4sZt1QIGiJzC4EA==", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/dir-glob": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", @@ -1747,12 +2191,29 @@ "node": ">=6.0.0" } }, + "node_modules/dom-helpers": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz", + "integrity": "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==", + "dependencies": { + "@babel/runtime": "^7.8.7", + "csstype": "^3.0.2" + } + }, "node_modules/electron-to-chromium": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.1.tgz", "integrity": "sha512-FKbOCOQ5QRB3VlIbl1LZQefWIYwszlBloaXcY2rbfpu9ioJnNh3TK03YtIDKDo3WKBi8u+YV4+Fn2CkEozgf4w==", "dev": true }, + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, "node_modules/esbuild": { "version": "0.21.5", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", @@ -1804,7 +2265,6 @@ "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, "engines": { "node": ">=0.8.0" } @@ -2170,6 +2630,11 @@ "node": ">=8" } }, + "node_modules/find-root": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", + "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==" + }, "node_modules/find-up": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", @@ -2206,6 +2671,30 @@ "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", "dev": true }, + "node_modules/formik": { + "version": "2.4.6", + "resolved": "https://registry.npmjs.org/formik/-/formik-2.4.6.tgz", + "integrity": "sha512-A+2EI7U7aG296q2TLGvNapDNTZp1khVt5Vk0Q/fyfSROss0V/V6+txt2aJnwEos44IxTCW/LYAi/zgWzlevj+g==", + "funding": [ + { + "type": "individual", + "url": "https://opencollective.com/formik" + } + ], + "dependencies": { + "@types/hoist-non-react-statics": "^3.3.1", + "deepmerge": "^2.1.1", + "hoist-non-react-statics": "^3.3.0", + "lodash": "^4.17.21", + "lodash-es": "^4.17.21", + "react-fast-compare": "^2.0.1", + "tiny-warning": "^1.0.2", + "tslib": "^2.0.0" + }, + "peerDependencies": { + "react": ">=16.8.0" + } + }, "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -2226,6 +2715,14 @@ "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/gensync": { "version": "1.0.0-beta.2", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", @@ -2294,7 +2791,6 @@ "version": "11.12.0", "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true, "engines": { "node": ">=4" } @@ -2329,11 +2825,34 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, "engines": { "node": ">=4" } }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/hoist-non-react-statics": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", + "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", + "dependencies": { + "react-is": "^16.7.0" + } + }, + "node_modules/hoist-non-react-statics/node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + }, "node_modules/ignore": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", @@ -2343,11 +2862,19 @@ "node": ">= 4" } }, + "node_modules/immer": { + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/immer/-/immer-10.1.1.tgz", + "integrity": "sha512-s2MPrmjovJcoMaHtx6K11Ra7oD05NT97w1IC5zpMkT6Atjr7H8LjaDd81iIxUYpMKSRRNMJE703M1Fhr/TctHw==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/immer" + } + }, "node_modules/import-fresh": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dev": true, "dependencies": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" @@ -2385,6 +2912,25 @@ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==" + }, + "node_modules/is-core-module": { + "version": "2.15.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.0.tgz", + "integrity": "sha512-Dd+Lb2/zvk9SKy1TGCt1wFJFo/MWBPMX5x7KcvLajWTGuomczdQX61PvY5yK6SVACwpoexWo81IfFyoKY2QnTA==", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", @@ -2451,7 +2997,6 @@ "version": "2.5.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", - "dev": true, "bin": { "jsesc": "bin/jsesc" }, @@ -2465,6 +3010,11 @@ "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", "dev": true }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==" + }, "node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", @@ -2511,6 +3061,11 @@ "node": ">= 0.8.0" } }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==" + }, "node_modules/locate-path": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", @@ -2526,6 +3081,16 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, + "node_modules/lodash-es": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz", + "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==" + }, "node_modules/lodash.merge": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", @@ -2592,8 +3157,7 @@ "node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, "node_modules/nanoid": { "version": "3.3.7", @@ -2625,6 +3189,14 @@ "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==", "dev": true }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -2685,7 +3257,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, "dependencies": { "callsites": "^3.0.0" }, @@ -2693,6 +3264,23 @@ "node": ">=6" } }, + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -2720,11 +3308,15 @@ "node": ">=8" } }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" + }, "node_modules/path-type": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true, "engines": { "node": ">=8" } @@ -2732,8 +3324,7 @@ "node_modules/picocolors": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", - "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==", - "dev": true + "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==" }, "node_modules/picomatch": { "version": "2.3.1", @@ -2784,6 +3375,26 @@ "node": ">= 0.8.0" } }, + "node_modules/prop-types": { + "version": "15.8.1", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", + "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "dependencies": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.1" + } + }, + "node_modules/prop-types/node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + }, + "node_modules/property-expr": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/property-expr/-/property-expr-2.0.6.tgz", + "integrity": "sha512-SVtmxhRE/CGkn3eZY1T6pC8Nln6Fr/lu1mKSgRud0eC73whjGfoAogbn78LkD8aFL0zz3bAFerKSnOl7NlErBA==" + }, "node_modules/punycode": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", @@ -2836,6 +3447,38 @@ "react": "^18.3.1" } }, + "node_modules/react-fast-compare": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-2.0.4.tgz", + "integrity": "sha512-suNP+J1VU1MWFKcyt7RtjiSWUjvidmQSlqu+eHslq+342xCbGTYmC0mEhPCOHxlW0CywylOC1u2DFAT+bv4dBw==" + }, + "node_modules/react-is": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==" + }, + "node_modules/react-redux": { + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-9.1.2.tgz", + "integrity": "sha512-0OA4dhM1W48l3uzmv6B7TXPCGmokUU4p1M44DGN2/D9a1FjVPukVjER1PcPX97jIg6aUeLq1XJo1IpfbgULn0w==", + "dependencies": { + "@types/use-sync-external-store": "^0.0.3", + "use-sync-external-store": "^1.0.0" + }, + "peerDependencies": { + "@types/react": "^18.2.25", + "react": "^18.0", + "redux": "^5.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "redux": { + "optional": true + } + } + }, "node_modules/react-refresh": { "version": "0.14.2", "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.2.tgz", @@ -2845,11 +3488,106 @@ "node": ">=0.10.0" } }, + "node_modules/react-router": { + "version": "6.25.1", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.25.1.tgz", + "integrity": "sha512-u8ELFr5Z6g02nUtpPAggP73Jigj1mRePSwhS/2nkTrlPU5yEkH1vYzWNyvSnSzeeE2DNqWdH+P8OhIh9wuXhTw==", + "dependencies": { + "@remix-run/router": "1.18.0" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "react": ">=16.8" + } + }, + "node_modules/react-router-dom": { + "version": "6.25.1", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.25.1.tgz", + "integrity": "sha512-0tUDpbFvk35iv+N89dWNrJp+afLgd+y4VtorJZuOCXK0kkCWjEvb3vTJM++SYvMEpbVwXKf3FjeVveVEb6JpDQ==", + "dependencies": { + "@remix-run/router": "1.18.0", + "react-router": "6.25.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "react": ">=16.8", + "react-dom": ">=16.8" + } + }, + "node_modules/react-toastify": { + "version": "10.0.5", + "resolved": "https://registry.npmjs.org/react-toastify/-/react-toastify-10.0.5.tgz", + "integrity": "sha512-mNKt2jBXJg4O7pSdbNUfDdTsK9FIdikfsIE/yUCxbAEXl4HMyJaivrVFcn3Elvt5xvCQYhUZm+hqTIu1UXM3Pw==", + "dependencies": { + "clsx": "^2.1.0" + }, + "peerDependencies": { + "react": ">=18", + "react-dom": ">=18" + } + }, + "node_modules/react-transition-group": { + "version": "4.4.5", + "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz", + "integrity": "sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==", + "dependencies": { + "@babel/runtime": "^7.5.5", + "dom-helpers": "^5.0.1", + "loose-envify": "^1.4.0", + "prop-types": "^15.6.2" + }, + "peerDependencies": { + "react": ">=16.6.0", + "react-dom": ">=16.6.0" + } + }, + "node_modules/redux": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/redux/-/redux-5.0.1.tgz", + "integrity": "sha512-M9/ELqF6fy8FwmkpnF0S3YKOqMyoWJ4+CS5Efg2ct3oY9daQvd/Pc71FpGZsVsbl3Cpb+IIcjBDUnnyBdQbq4w==" + }, + "node_modules/redux-thunk": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-3.1.0.tgz", + "integrity": "sha512-NW2r5T6ksUKXCabzhL9z+h206HQw/NJkcLm1GPImRQ8IzfXwRGqjVhKJGauHirT0DAuyy6hjdnMZaRoAcy0Klw==", + "peerDependencies": { + "redux": "^5.0.0" + } + }, + "node_modules/regenerator-runtime": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==" + }, + "node_modules/reselect": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/reselect/-/reselect-5.1.1.tgz", + "integrity": "sha512-K/BG6eIky/SBpzfHZv/dd+9JBFiS4SWV7FIujVyJRux6e45+73RaUHXLmIR1f7WOMaQ0U1km6qwklRQxpJJY0w==" + }, + "node_modules/resolve": { + "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "dependencies": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/resolve-from": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true, "engines": { "node": ">=4" } @@ -2988,6 +3726,14 @@ "node": ">=8" } }, + "node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/source-map-js": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", @@ -3021,11 +3767,15 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/stylis": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.2.0.tgz", + "integrity": "sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==" + }, "node_modules/supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, "dependencies": { "has-flag": "^3.0.0" }, @@ -3033,17 +3783,37 @@ "node": ">=4" } }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", "dev": true }, + "node_modules/tiny-case": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tiny-case/-/tiny-case-1.0.3.tgz", + "integrity": "sha512-Eet/eeMhkO6TX8mnUteS9zgPbUMQa4I6Kkp5ORiBD5476/m+PIRiumP5tmh5ioJpH7k51Kehawy2UDfsnxxY8Q==" + }, + "node_modules/tiny-warning": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz", + "integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==" + }, "node_modules/to-fast-properties": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", - "dev": true, "engines": { "node": ">=4" } @@ -3060,6 +3830,11 @@ "node": ">=8.0" } }, + "node_modules/toposort": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/toposort/-/toposort-2.0.2.tgz", + "integrity": "sha512-0a5EOkAUp8D4moMi2W8ZF8jcga7BgZd91O/yabJCFY8az+XSzeGyTKs0Aoo897iV1Nj6guFq8orWDS96z91oGg==" + }, "node_modules/ts-api-utils": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz", @@ -3072,6 +3847,11 @@ "typescript": ">=4.2.0" } }, + "node_modules/tslib": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" + }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -3148,6 +3928,14 @@ "punycode": "^2.1.0" } }, + "node_modules/use-sync-external-store": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.2.tgz", + "integrity": "sha512-PElTlVMwpblvbNqQ82d2n6RjStvdSoNe9FG28kNfz3WiXilJm4DdNkEzRhCZuIDwY8U08WVihhGR5iRqAwfDiw==", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, "node_modules/vite": { "version": "5.3.5", "resolved": "https://registry.npmjs.org/vite/-/vite-5.3.5.tgz", @@ -3239,6 +4027,14 @@ "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", "dev": true }, + "node_modules/yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "engines": { + "node": ">= 6" + } + }, "node_modules/yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", @@ -3250,6 +4046,28 @@ "funding": { "url": "https://github.com/sponsors/sindresorhus" } + }, + "node_modules/yup": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/yup/-/yup-1.4.0.tgz", + "integrity": "sha512-wPbgkJRCqIf+OHyiTBQoJiP5PFuAXaWiJK6AmYkzQAh5/c2K9hzSApBZG5wV9KoKSePF7sAxmNSvh/13YHkFDg==", + "dependencies": { + "property-expr": "^2.0.5", + "tiny-case": "^1.0.3", + "toposort": "^2.0.2", + "type-fest": "^2.19.0" + } + }, + "node_modules/yup/node_modules/type-fest": { + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz", + "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==", + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } } } } diff --git a/package.json b/package.json index e88db0f..8cc4e65 100644 --- a/package.json +++ b/package.json @@ -10,8 +10,17 @@ "preview": "vite preview" }, "dependencies": { + "@emotion/react": "^11.13.0", + "@emotion/styled": "^11.13.0", + "@mui/material": "^5.16.5", + "@reduxjs/toolkit": "^2.2.7", + "formik": "^2.4.6", "react": "^18.3.1", - "react-dom": "^18.3.1" + "react-dom": "^18.3.1", + "react-redux": "^9.1.2", + "react-router-dom": "^6.25.1", + "react-toastify": "^10.0.5", + "yup": "^1.4.0" }, "devDependencies": { "@types/react": "^18.3.3", diff --git a/src/App.css b/src/App.css index b9d355d..e69de29 100644 --- a/src/App.css +++ b/src/App.css @@ -1,42 +0,0 @@ -#root { - max-width: 1280px; - margin: 0 auto; - padding: 2rem; - text-align: center; -} - -.logo { - height: 6em; - padding: 1.5em; - will-change: filter; - transition: filter 300ms; -} -.logo:hover { - filter: drop-shadow(0 0 2em #646cffaa); -} -.logo.react:hover { - filter: drop-shadow(0 0 2em #61dafbaa); -} - -@keyframes logo-spin { - from { - transform: rotate(0deg); - } - to { - transform: rotate(360deg); - } -} - -@media (prefers-reduced-motion: no-preference) { - a:nth-of-type(2) .logo { - animation: logo-spin infinite 20s linear; - } -} - -.card { - padding: 2em; -} - -.read-the-docs { - color: #888; -} diff --git a/src/App.tsx b/src/App.tsx index c56c219..b1d18b7 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,13 +1,29 @@ - -import './App.css' +import "./App.css"; +import Login from "./login"; +import { ToastContainer } from "react-toastify"; +import { createBrowserRouter, RouterProvider } from "react-router-dom"; +import Home from "./home"; function App() { + const router = createBrowserRouter([ + { + path: "/", + element: , + }, + { + path: "/login", + element: , + }, + ]); return ( <> - Peerly +
+ +
+ - ) + ); } -export default App +export default App; diff --git a/src/assets/loginImage.webp b/src/assets/loginImage.webp new file mode 100644 index 0000000000000000000000000000000000000000..2c3228c981826e4c78a91671ae21ba8edd55f494 GIT binary patch literal 7186 zcmV+t9PQ&$Nk&Er8~^}UMM6+kP&gp|8vp?CdjOpQDr^A;0X``bh(jTvArZM{P#6M) zvA2F6ucu+QfO!ERuJ9$RrvJtEpmEPP`BUvRVt(28|MzeG56hqQeZ6)Em-i=sp8o0k zpZ-t(|J5JwU-ADf{!xCN|DWy``iK5^`tSA+_y6QOm3fN(PyNIGNBSS%UzZQ|f3E)Y ze`o!GzmxxB|GVv7|8v>9&>Q*(`=9>ayPvc_3m?`$+5Xpj3jV%-yX@QPC+s)+j@v)S z^ptw<*`9RqKKY;AU&j7r{$_pg{;R$o0e;Q@4f%8Vd&dR<|49DL{%`XK{0GC=)Bm{i zKkTpi&$e%{FXunnKh6GWb4>Z~uov>5>_6>)%YHrltN+3N%lu!fKdry#dx?Itf3E!H z|0m$5(HHgba$DzCzvt#EM25dI;xqJ|=y3}$D}nqvk6CE?l1;<2%oqo^J?ey3v5Oc=*;bU4IG z=E_mvjT|^A7HvCMD0~I}qA%*Uu`(o$I4Rj-#+HyuL%g*u0T-Y+8rz|&h*?iH@`v%A zw0h-?BilS=S+<+bF{ZyR)^56X;hL?h-}R93teM#wAblH*V97S*D_bLw_aK`hS+2{c zt3=bkUwi1bOksYSLN@-zakrp|ZgR|hBH*hA+5wy@6dvRhw-1OlyzN|Q?nHqVxlF%M zxuJZutbhK9PO^0BwX!rluRG;lf}Y`{JuCKy%W#1?KhGmfF1tJT|01p6^1sklCx*b7 z|33$E?9sBTWCbJRn&JVQQLwNBq@{DB^DOh1h{M!-TRY&?6pVI z6Wqd~cdKJ%NS){RY4DjZ&!mtfa!kSbrBo7w>N{Liwkty!fh4HU=Ms|%I6B%7b4Pcv zz?9E{jVRvv|atsipW-*8npr0UO%pZ{Zp(v$Be|vY)||TdoUs8yOpi zQP>=o$5bB%YQpfhj{0sJ$ES<_j5JUEWbWH+pyH$h%!l;_w8vvAf5AN!?yu1`xRy|B1b(^Aq1Jmv;8#T?)LrftO0dzu2vSjKB8a#*fo1%>v7 z*~+Dt0440XB_!WR=nU`QcPlFOV+z=xKiMG`Ryop%zOE{N)=~Ai6xd@!bb#}ci)}7s zEREpJQj5a@N1|R;^XilA}`aKeu``{m&BPu!3i(bvxD7>c-UU$fa6O; z)V~I~)X>MN+KHmuJMJ&1FnxvZgaxQyHwOjMh}fYajps{{PbF000LRA+g!4 z#PrM*J#tpd-UC6qL0QTC8qIBK!qxOG_2%RxtLOB%0EjX#GX2bqz(|XXZcsdDZSB$v znfi4+e6jHDaK|}2?9-2mJDZ@l9|4n;4P`XuFDd3t8&iX=$bP|*w z8eU8JXCE9F_1RqTywqm_@V7qd>P93dY_5jIH9!4V%X&4BeTDV27ce=8Bvt|%dcPI_ ztV!3$O8`tN)lw>moknih?mYXel2)_I(#h01xdk6$)}(m)jH!8P>?it)f3ytUo$CkG zHm0EP7n}tW1*>^3zJ&wW2FjNiNRqisy+rsT(`sO{%MuW4B>ELGB-LW#7TAV#SN&f~ z&#`P%l<3llr$J8rC`{bNR104t4_=Tu;<@_oc)nXX3^FIuo(`7I&)nGZ@m%Ouy8ZUZ zWp1@yOjB&46thUSkAa6d_dW=R=F*qRL^H}+9o=3ATBH;r+SNbSVdI(AbOERtan;sK z^2mva9YDVKe{tg2U1gPnmzLH;s!f5p2T6_;u6Ug|7Ul>5BFe83Y&wVnE@}Xz!k*(D zg1itU6hBq6-j!kCd1H2Afl)x~6SwVe*-x&0pInNF^+CqqSa-^4Q;p%DGp{kNRo?_A zmP3+1yYOhhy3?tgmnBR0zp!f$>IMmp;e2Ss&S{0y+&dr?o;c+A-vKo{@ z8$mbnD=$p`Iq>bI{KCYE*sP&_EcgX@DbT|}zeOh`K-Qi^m8}^qFD2J&uT}r%f7VzX z9ii%Dl;r0UnAptYcmOVlN|DTV$HHB8Nu(F=Y-MBAs3qu|9oL9S2i{n*e7k^EDeY5U zK~tLzzH(9v-qaGh14@~OC&8SMJM-oS<>h((Ba{~ZKd@aq>Cu2-@)BBJ)kH)TZnUPn ziop${ebfx!36Ara1rW{Ho?~PDBO4#{iP3#5RfGPix)F^hQgh^Q-*54^8EN0g${{}o zk2-Vy#9!)uEndIMUBnxS-gwB)e{m*4b|0{@-InwpNSxgCpEnXQlArL_5C8ZalmHp} zz!NY#?{5+bk2tJ^>W5mmv5goXU>~e^lNRU6ETUR@UN^@7SJ6DW3A;Ui1bF zf@XqJbF|9}=Y`bm`eI#h0_yz(3%2mI`~M~OYQDhh-2(i~N(8b?7!V^EcTuJ;AllBR zDWBi}3|j;uapF?N&cUX%k*kX_mX%FSTAO0@3dF6d$eW5 z^ko^dAQNXy_clLB&Nt5_Cqj{Oe)N$Fptn)&14&xZjVd#oJpqj<_6C;l$7|a9aSUXE z$7o$0doqalUy=e|gaTcYFOvT#Ipmw9V>cS9!azg!FGze(M9Aq29fQ3i+^GH(jNnl9I5LTZ-Bp+WdL`{~zTYh|gyu`56;&%8W9^A&IU4ifwt~`;O%0fO) zw!7u{OEAW+Ib>(&%c)UHl=!jfbP0?1VZmj4!PR|> z-FWidAW}qLeh1a3r}7h3u(6~JZf-K7LprWnZc=}~1MFXLrqn&LjK+Xp8-EU9-`@e` zSv$o%=(j1)Vs>sMdKJP-V@Aao9;Z_q-Ft60(jAzym?mNeNKu&g@aZG%EeAasqIzo# zMH4tY2U|3%kCiqE{7z946A>AKxB@~i^7lBZp|=SFnf5DpezLtrkYHr zko_UYe=mav(=Dnd_yJ0m2$Hc0AW@+^L{cMZJ7oep+{=+TkOdpVXp+v+7#;F7Oo{L4 z%sOrJMycJ4$mqhi!@2xwK-H=JU6`77WyysuHPF%pzNlE0)N2+6cQ8?YIX2LZGdTW-azAj!%FUf++CFT z+J`oPxy#rYdJVu}eIDpq7OGDh%AgXoCq>CEsaA)^<6!R{ibZw?@}WPv9*>=Z+{^t3 z;}awl#j-_}y~ZA_^>F527&a2kWt`dDvtxfCTbbIuno5{ht??i)km z9eMvZ-{s=d+sJc%%?NtmyAXT2Yyfk*RO%pk zwwXGAaN+Jdnz`*2!pSowtL79cYuizlt?5+NR%wJ_>x%r-v5fTxpY%QZ{tMP&y=B$T z=5jO)yI-NXrXJ9pLzJ)y^}W$F+X<4Wkz%p7IlaE`M;{lfzknpCkEMJFF8K!u5@35C zdDOLWw#BB*)6q`=_(zquESWOa7nvu6Fkk4&w>W^KDo-iOja_@`)xw<_BoYiFySRv2 zFf)gPf9yma*+pLOj1Eu$j~zG4IJ68QI3p!_>RSb;ZNFACAG^aTs$EHk;rXBXG`ME@ z@ymikAw3_Gw~O<=V^!(+De?0$Ix_y7x$J}fHdAhJ<{^8MO4wvDsBAUh#A2-U* zKPO3pCKx4Y{jsrwFaWLxAub`Pq+0=sOAQ+V$}>Kbo@&bl$!GOcv3S4BwAOWR0vX=V z>bd{3e>V5#&|Brl)A0lJ`uQ4}(36dID!uT2T~F}u$bstHlF|A#VuI{<1a%`{ z+X2s;nQ37+3}l!TUDua?Y=RXj4-C2vH(uAcnf9#E{iOa&&SftaeV)5CEZ?Pf>Av@1 zS8H3pCPid4*Hh(8$o$fKJ2{rW>|;Fp>cJ&Cir>mf??PjA%|>ZX2h07B)*F#=BCrfF zHqaqLci3*}5ZEN#k80L3vH5DWoK<|Au;T>8d9lu`St52i!3AL}`G>C7O z+&gHeh^?A0hNfo42uw)9q=QH>NBYU-GVG1Vvm!X9%Wu)pTR5|u5Pn5Xa*081rEm%3 z#0*1oCzQOsIOe1=@gwa(a1a~6{WK|hnRU>YxJS_c!_{Z_V!!X@&b;gRya9CfiYxD6 z(U#)0J!bz5PAk3cskW|463!B6L-7T^y<(Iz1!RSDk?*;((Y4yO z<`s6838)Oh5O4tZy0!LA<0UpTFwA&}NbK+?JKbLbq91b0mT*@wD*!O7J99SdP&$ zL1OD1BisViCNT;o%APPw9${|#sI{Hqb#D$Uku)GG?d9|MeC3r# z(j{p@cseaD6J|P+gW1n3j?+gJF>|H=p9jiQGq5dQ%dforX-qkqATb8U@Ia@_D|KnR8!FWbQXSW0lKgv@~WkX$)o75-++w4#+2OlIbPk;OdY-0R%}oQ!X_vF8{u%@DmHm0UvnleZrP{SR~#jE;6<{ z0yZ?Q{No4c(V+`}a z#-gc`Lkcp9pq~UNP|5t<3Lu;ktmNz0v*h5eP3c7#szlTuw{ZGv|7Jx^TX)K$M$SXqY41ebY|w~l1F<>V zZa#heOxZNL^z;Ho0jKiL0WRO$wmP zg$Gk`si>@_G|9X=h~R8?>&A`uo15!-N4^E0;@v(iZVTCUk3Z2{ek;;$RuB(lAIM$x zCivZ5Vx%km!q+u!W&rXaGePV7PAE!=q_Er{r0q6eH$0;m-E6L8ttzN~g>oVpDKyxDW>v`yAgS!t25My-0PX*agx1R^D z3zA^#LS8X;auv^he@r-<96C!2^}B1U_OpIlYYO^sGb|C5Q*Gcw`tc@?;8rAWPG0Mo z_oR}tI$dsj7zmZB#t(R!ayjk%|mY$U*KAy$7Q@$-Gj6r?vN z#mtJ301p4qL$aD5DaXYw@f3}ttA4>q&bNT9>gW)?s^sP8KI}gg)h*e-#W?#2(|nGW zryJZ$VL$(Yjv4nd3T1F`|Ex~Ioy->%IHTyM1Gx?!Cov5nxu-VO=I1h1bn91Rcn&fl z#B^5B*Q7bYU!7i?H0JqaT~e_=)G=W-!24Z%{1o{)j@LA@zP33Wx>RfKPa+%2*Ma*} zXfWyzo{;J>Sk^E9dfDsAy{<_EN5QP*AXNjEMS?t3MS8r{8kA>ep&_#zqk%F|$pn(R z&ZxSqm%0}Cs8tdJL=yziImlD(R}Rau0^$z=HZQ<3dVfA6Uh;?bWCb<5i6YVyU~-L> z7t$qf5|d#(Th2J%&TEgHudVGn_;^YkrK}e-59D8&NAUPGUAX*tmbB^|wQe|9_J?%{ z_!3q602O4@20~G1y#8Wl@|VJS7$@sQ1pV;w^LJI@xQ7Ox&ZoG76`1~!l4W7HybW)?A^;`G$YakpI@0?dV zB=u=ZoYcNye8%e&a+8`?H7}NxHgm$5RHQ!S*WG3J;&&^ULCPnDEflvzS{Vpd;~QE& ze3@x)`ME8xe9RuZh;iEMB#gUIKNLaIDr*fHrbFfHozcEvI}J@~Ap8LTqSZUNBmAl$ z1)Xk+1WtFwOD~y&3^6$$y>j*Yl!J8Poycf#GY8YvRGQ#IxJA<&on@yO~$NNo9B1q z>5X<&JwJ+>T?3#T@wfrbwZ-Ui8qm;?h4Tg0*cZpBNMaV!dDdPx*|e539#@ID+OZqu z=Kfvn47Uy9A!G63R!I=2F4Fwwn$;BhQGGvFt?gB#7NpUKx=QdhrmCJp+`$n%VApa* zVD!gK;So^UswRAqI^pOzIS9xo`=geZg!AiD%Cs6gq^+I0MTduGBDHR7ODatg*>$2h zq6&mXgM70zV|3t_@;?2N0TO97@m2kz@|fm`LG^>P$W{I}HUHSZ$${nNSKV={7jx4n z%}ui?g|m{@W6q@tTSvxo|7!aUe`1ll)fWb>n!Au#Jt>)2I4Il<1(eOIK5=`(m=u%5;4~rFm2x5jg zcZf9EvKyn(Xk}NceOWlB1#ZxCTuc`hw2N$j{8|=&_0iEb8io_0-WPt9i$5+F4iAW< zVCuV%+{_~e>EJR{JrINR+Y7Anh%Y6(m6?ulKjuMO1^xaVW!h}LuFVe@J4a1M<|?B* za^GyC<5=I`F(Kf9a_pY{P-O818(19;saj6mpAg8_DWfA&!}LP#k|XS=&B-k38QKNt zWik@h9M%~nU(#-`LZCOkD<3*0zXVEh%0a5JuqT9tmRUTN%m#BO`)u|N<{9?uy};x< zoO-Mm&e~KN5+^oqbPOQ69rm_eaQvteF*T)7o*!kk16whoJ_Vi6N>zkx*8%Je%uIOk zmoy_u<+Od0=X-)|vBngGzzKsF~?55AVHg6e09e7_nr*U)(F}b>bhhedqNgSZ&eEVg?NdGKqc0Udnf0u zq`y^h0bGcn;k|yoa2n=Eb<+XrYnD(t-qjLM3;M`0T7h7~Wq1^3Y4@bCJ1UE;%0$H6 zR+g)%J||G*D9a3|nryfv6Cl<7u40$M?b~gK){zeEtshYD7%<6=pS__T9w8k{^$Ysq zmz!+JME`}1m>-|$kr z3AA;iEr^9#3En*-fogOfoJLH_C_A*a^#%h!8Js(!1pcb@gZufONVv7UB*}qCu!=c~ z8BtHkM9wvg3~RQ~nw}fi(I_eBSKK^lhr;HsPG^+usg6Sw;oZbjy#n!VGx-R6z=x1BKE zxh=G47a-C<;>|sZR$IV8jOg{LAoy?DmMz$kq@+LIFlG4mh-g;-pQh8YDR!G{pgtP` zm~-$8W=){qZvK`ZTcL0_&~Vzz0E3dDjp@Y6ju*sI;jt>xeYJ_;^M5@5_`?y6>6+>t zeNuwcDcJu-;O}Sgqw>wl{w2MG1EQ@8S6@Eg{ezsAa%@&>i%*QcBwSh3v6z{%-?2@P UJp|PY2yE { + return( + <>home + ) +} + +export default Home \ No newline at end of file diff --git a/src/index.css b/src/index.css index 6119ad9..e69de29 100644 --- a/src/index.css +++ b/src/index.css @@ -1,68 +0,0 @@ -:root { - font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif; - line-height: 1.5; - font-weight: 400; - - color-scheme: light dark; - color: rgba(255, 255, 255, 0.87); - background-color: #242424; - - font-synthesis: none; - text-rendering: optimizeLegibility; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; -} - -a { - font-weight: 500; - color: #646cff; - text-decoration: inherit; -} -a:hover { - color: #535bf2; -} - -body { - margin: 0; - display: flex; - place-items: center; - min-width: 320px; - min-height: 100vh; -} - -h1 { - font-size: 3.2em; - line-height: 1.1; -} - -button { - border-radius: 8px; - border: 1px solid transparent; - padding: 0.6em 1.2em; - font-size: 1em; - font-weight: 500; - font-family: inherit; - background-color: #1a1a1a; - cursor: pointer; - transition: border-color 0.25s; -} -button:hover { - border-color: #646cff; -} -button:focus, -button:focus-visible { - outline: 4px auto -webkit-focus-ring-color; -} - -@media (prefers-color-scheme: light) { - :root { - color: #213547; - background-color: #ffffff; - } - a:hover { - color: #747bff; - } - button { - background-color: #f9f9f9; - } -} diff --git a/src/login/apiSlice.tsx b/src/login/apiSlice.tsx new file mode 100644 index 0000000..2819430 --- /dev/null +++ b/src/login/apiSlice.tsx @@ -0,0 +1,26 @@ +import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react' +import { userLoginBody, userLoginResp } from './types' + +export const loginSlice = createApi({ + reducerPath: 'loginSlice', + baseQuery: fetchBaseQuery({ + baseUrl: 'http://localhost:33001', + }), + tagTypes: ['Login'], + endpoints: (builder) => ({ + adminLogin: builder.mutation>({ + query: (payload) => ({ + url: '/admin/login', + method: 'POST', + body: payload, + headers: { + 'Content-type': 'application/json; charset=UTF-8', + 'Accept-Version': 'application/vnd.peerly.v1' + }, + }), + invalidatesTags: ['Login'], + }), + }), +}) + +export const { useAdminLoginMutation } = loginSlice \ No newline at end of file diff --git a/src/login/components/loginForm.tsx b/src/login/components/loginForm.tsx new file mode 100644 index 0000000..d3a7fa1 --- /dev/null +++ b/src/login/components/loginForm.tsx @@ -0,0 +1,86 @@ +import { Button, TextField } from "@mui/material"; +import { userLoginBody } from "../types"; +import * as Yup from "yup"; +import { useFormik } from "formik"; +import { useAdminLoginMutation } from "../apiSlice"; +import { useNavigate } from "react-router-dom"; +import { toast } from "react-toastify"; +import "react-toastify/dist/ReactToastify.css"; + +const LoginForm = () => { + const navigate = useNavigate(); + const initialValues: userLoginBody = { + email: "", + password: "", + }; + const loginSchema = Yup.object().shape({ + email: Yup.string().email("Invalid Email!").required("Required!"), + password: Yup.string().required("Required!"), + }); + const [loginAdmin] = useAdminLoginMutation(); + const formik = useFormik({ + initialValues: initialValues, + validationSchema: loginSchema, + onSubmit: (values) => { + loginAdmin(values) + .unwrap() + .then((resp) => { + console.log("response -> ", resp); + toast.success(resp.message); + localStorage.setItem("token", resp.data.AuthToken); + navigate("/") + }) + .catch((resp) => { + console.log("response -> ", resp); + toast.error(resp.data.message); + }); + }, + }); + return ( +
+ + + + + ); +}; + +export default LoginForm; diff --git a/src/login/index.tsx b/src/login/index.tsx new file mode 100644 index 0000000..e40e6ab --- /dev/null +++ b/src/login/index.tsx @@ -0,0 +1,25 @@ +import { Box, Divider } from "@mui/material"; +import loginImage from "../assets/loginImage.webp"; +import LoginForm from "./components/loginForm"; + +const Login = () => { + return ( + + login image + + + + ); +}; + +export default Login; diff --git a/src/login/types.tsx b/src/login/types.tsx new file mode 100644 index 0000000..67e5edd --- /dev/null +++ b/src/login/types.tsx @@ -0,0 +1,31 @@ +interface data { + User: user; + AuthToken: string; + NewUserCreated: boolean; +} + +interface user { + created_at: Int16Array; + designation: string; + email: string; + employee_id: string; + first_name: string; + grade_id: Int16Array; + id: Int16Array; + last_name: string; + profile_image_url: string; + reward_quota_balance: Int16Array; + role_id: Int16Array; +} + +export interface userLoginBody { + email: string; + password: string; +} + +export interface userLoginResp { + message: string; + status_code: Int16Array; + success: boolean; + data: data; +} diff --git a/src/main.tsx b/src/main.tsx index 3d7150d..9dcb351 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -2,9 +2,13 @@ import React from 'react' import ReactDOM from 'react-dom/client' import App from './App.tsx' import './index.css' +import { Provider } from 'react-redux' +import { store } from './store.tsx' ReactDOM.createRoot(document.getElementById('root')!).render( + + , ) diff --git a/src/store.tsx b/src/store.tsx new file mode 100644 index 0000000..fddeb23 --- /dev/null +++ b/src/store.tsx @@ -0,0 +1,18 @@ +import { configureStore } from '@reduxjs/toolkit'; + +import { loginSlice } from './login/apiSlice.tsx'; + + +export const store = configureStore({ + + reducer: { + + [loginSlice.reducerPath]: loginSlice.reducer, + + }, + + middleware: (getDefaultMiddleware) => + + getDefaultMiddleware().concat(loginSlice.middleware), + +}); \ No newline at end of file From 7fbdf575e73372a6ea282e6a0fdd7daac9d08b0a Mon Sep 17 00:00:00 2001 From: Sharyu Marwadi Date: Thu, 1 Aug 2024 16:35:15 +0530 Subject: [PATCH 03/23] [feature/PEER-50-Appreciations] table set --- package-lock.json | 26 + package.json | 1 + src/App.tsx | 4 +- src/appreciations/apiSlice.tsx | 34 ++ src/appreciations/components/badgeAvatars.tsx | 30 + src/appreciations/components/card.css | 1 + src/appreciations/components/card.tsx | 60 ++ src/appreciations/components/table.tsx | 541 ++++++++++++++++++ src/appreciations/components/toggleButton.tsx | 29 + src/appreciations/index.tsx | 34 ++ src/appreciations/types.tsx | 58 ++ src/store.tsx | 4 +- 12 files changed, 819 insertions(+), 3 deletions(-) create mode 100644 src/appreciations/apiSlice.tsx create mode 100644 src/appreciations/components/badgeAvatars.tsx create mode 100644 src/appreciations/components/card.css create mode 100644 src/appreciations/components/card.tsx create mode 100644 src/appreciations/components/table.tsx create mode 100644 src/appreciations/components/toggleButton.tsx create mode 100644 src/appreciations/index.tsx create mode 100644 src/appreciations/types.tsx diff --git a/package-lock.json b/package-lock.json index ef6e9e8..7df1054 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,6 +10,7 @@ "dependencies": { "@emotion/react": "^11.13.0", "@emotion/styled": "^11.13.0", + "@mui/icons-material": "^5.16.6", "@mui/material": "^5.16.5", "@reduxjs/toolkit": "^2.2.7", "formik": "^2.4.6", @@ -1112,6 +1113,31 @@ "url": "https://opencollective.com/mui-org" } }, + "node_modules/@mui/icons-material": { + "version": "5.16.6", + "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-5.16.6.tgz", + "integrity": "sha512-ceNGjoXheH9wbIFa1JHmSc9QVjJUvh18KvHrR4/FkJCSi9HXJ+9ee1kUhCOEFfuxNF8UB6WWVrIUOUgRd70t0A==", + "dependencies": { + "@babel/runtime": "^7.23.9" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@mui/material": "^5.0.0", + "@types/react": "^17.0.0 || ^18.0.0", + "react": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, "node_modules/@mui/material": { "version": "5.16.5", "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.16.5.tgz", diff --git a/package.json b/package.json index 8cc4e65..457decb 100644 --- a/package.json +++ b/package.json @@ -12,6 +12,7 @@ "dependencies": { "@emotion/react": "^11.13.0", "@emotion/styled": "^11.13.0", + "@mui/icons-material": "^5.16.6", "@mui/material": "^5.16.5", "@reduxjs/toolkit": "^2.2.7", "formik": "^2.4.6", diff --git a/src/App.tsx b/src/App.tsx index b1d18b7..92b3bdf 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -2,13 +2,13 @@ import "./App.css"; import Login from "./login"; import { ToastContainer } from "react-toastify"; import { createBrowserRouter, RouterProvider } from "react-router-dom"; -import Home from "./home"; +import Appreciations from "./appreciations"; function App() { const router = createBrowserRouter([ { path: "/", - element: , + element: , }, { path: "/login", diff --git a/src/appreciations/apiSlice.tsx b/src/appreciations/apiSlice.tsx new file mode 100644 index 0000000..f8a3f5d --- /dev/null +++ b/src/appreciations/apiSlice.tsx @@ -0,0 +1,34 @@ +import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react' +import { response } from './types'; + +export const appreciationSlice = createApi({ + reducerPath: 'appreciationSlice', + baseQuery: fetchBaseQuery({ + baseUrl: 'http://localhost:33001', + }), + tagTypes: ['appreciation'], + endpoints: (builder) => ({ + getAppreciations: builder.query({ + query: ({ page, page_size }) => ({ + url: `/appreciations?page=${page}&page_size=${page_size}`, + method: 'GET', + headers: { + 'Accept-Version': 'application/vnd.peerly.v1', + 'Authorization': 'Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJJZCI6NTQsIlJvbGUiOiJ1c2VyIiwiZXhwIjoxNzI0MjI1MzEyfQ.dPvo969X1KfLS_PxXMfULBJHSpQyhFZbCXBeGNWTtVg' + }, + }), + }), + getReportedAppreciations: builder.query({ + query: () => ({ + url: `/report_appreciations`, + method: 'GET', + headers: { + 'Accept-Version': 'application/vnd.peerly.v1', + 'Authorization': 'Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJJZCI6NTQsIlJvbGUiOiJ1c2VyIiwiZXhwIjoxNzI0MjI1MzEyfQ.dPvo969X1KfLS_PxXMfULBJHSpQyhFZbCXBeGNWTtVg' + }, + }), + }), + }), +}) + +export const { useGetAppreciationsQuery, useGetReportedAppreciationsQuery } = appreciationSlice \ No newline at end of file diff --git a/src/appreciations/components/badgeAvatars.tsx b/src/appreciations/components/badgeAvatars.tsx new file mode 100644 index 0000000..ef511ea --- /dev/null +++ b/src/appreciations/components/badgeAvatars.tsx @@ -0,0 +1,30 @@ +import { styled } from "@mui/material/styles"; +import Badge from "@mui/material/Badge"; +import Avatar from "@mui/material/Avatar"; + + +const SmallAvatar = styled(Avatar)(({ theme }) => ({ + width: 50, + height: 50, + border: `2px solid ${theme.palette.background.paper}`, + left:"25px", + bottom:"15px" +})); + +export default function BadgeAvatars() { + return ( + + } + > + + + ); +} diff --git a/src/appreciations/components/card.css b/src/appreciations/components/card.css new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/src/appreciations/components/card.css @@ -0,0 +1 @@ + diff --git a/src/appreciations/components/card.tsx b/src/appreciations/components/card.tsx new file mode 100644 index 0000000..b763249 --- /dev/null +++ b/src/appreciations/components/card.tsx @@ -0,0 +1,60 @@ +import Box from "@mui/material/Box"; +import Card from "@mui/material/Card"; +import CardContent from "@mui/material/CardContent"; +import Typography from "@mui/material/Typography"; +import "./card.css"; +import BadgeAvatars from "./badgeAvatars"; + +const bull = ( + + • + +); + +export default function AppreciationCard() { + return ( + + + + + + + + + + + Mangesh Pawar + + Technical Lead + + Appriciated by + + Manas Joshi + + 10 days ago + + + + + Core Value + + + Technical Excellence + + + + + + ); +} diff --git a/src/appreciations/components/table.tsx b/src/appreciations/components/table.tsx new file mode 100644 index 0000000..8a1401b --- /dev/null +++ b/src/appreciations/components/table.tsx @@ -0,0 +1,541 @@ +import { useEffect, useState, useMemo } from "react"; +import Box from "@mui/material/Box"; +import Table from "@mui/material/Table"; +import TableBody from "@mui/material/TableBody"; +import TableCell from "@mui/material/TableCell"; +import TableContainer from "@mui/material/TableContainer"; +import TableHead from "@mui/material/TableHead"; +import TablePagination from "@mui/material/TablePagination"; +import TableRow from "@mui/material/TableRow"; +import TableSortLabel from "@mui/material/TableSortLabel"; +import Toolbar from "@mui/material/Toolbar"; +import Typography from "@mui/material/Typography"; +import Paper from "@mui/material/Paper"; +import IconButton from "@mui/material/IconButton"; +import Tooltip from "@mui/material/Tooltip"; +import DeleteIcon from "@mui/icons-material/Delete"; +import { visuallyHidden } from "@mui/utils"; +import { IPropsTable } from "../types"; +import AppreciationToggleButton from "./toggleButton"; + +interface Data { + id: number; + description: string; + sender: string; + senderDesignation: string; + receiver: string; + receiverDesignation: string; + coreValue: string; + rewardPoints: number; + date: number; + reportedBy: string; + reportingComment: string; + reportedAt: number; + moderatedBy: string; + moderatorComment: string; + isValid: boolean; +} + +function createData( + id: number, + description: string, + sender: string, + senderDesignation: string, + receiver: string, + receiverDesignation: string, + coreValue: string, + rewardPoints: number, + date: number, + reportedBy: string, + reportingComment: string, + reportedAt: number, + moderatedBy: string, + moderatorComment: string, + isValid: boolean +): Data { + return { + id, + description, + sender, + senderDesignation, + receiver, + receiverDesignation, + coreValue, + rewardPoints, + date, + reportedBy, + reportingComment, + reportedAt, + moderatedBy, + moderatorComment, + isValid, + }; +} + +function descendingComparator(a: T, b: T, orderBy: keyof T) { + if (b[orderBy] < a[orderBy]) { + return -1; + } + if (b[orderBy] > a[orderBy]) { + return 1; + } + return 0; +} + +type Order = "asc" | "desc"; + +function getComparator( + order: Order, + orderBy: Key +): ( + a: { [key in Key]: number | string | boolean }, + b: { [key in Key]: number | string | boolean } +) => number { + return order === "desc" + ? (a, b) => descendingComparator(a, b, orderBy) + : (a, b) => -descendingComparator(a, b, orderBy); +} + +function stableSort( + array: readonly T[], + comparator: (a: T, b: T) => number +) { + const stabilizedThis = array.map((el, index) => [el, index] as [T, number]); + stabilizedThis.sort((a, b) => { + const order = comparator(a[0], b[0]); + if (order !== 0) { + return order; + } + return a[1] - b[1]; + }); + return stabilizedThis.map((el) => el[0]); +} + +interface HeadCell { + disablePadding: boolean; + id: keyof Data; + label: string; + numeric: boolean; +} + +interface EnhancedTableProps { + numSelected: number; + filter: string; + onRequestSort: ( + event: React.MouseEvent, + property: keyof Data + ) => void; + onSelectAllClick: (event: React.ChangeEvent) => void; + order: Order; + orderBy: string; + rowCount: number; +} + +const reportedColumns: HeadCell[] = [ + { + id: "reportedBy", + numeric: false, + disablePadding: false, + label: "Reported By", + }, + { + id: "reportingComment", + numeric: false, + disablePadding: false, + label: "Reporting Comment", + }, + { + id: "reportedAt", + numeric: true, + disablePadding: false, + label: "Reported At", + }, + { + id: "moderatedBy", + numeric: false, + disablePadding: false, + label: "Moderated By", + }, + { + id: "moderatorComment", + numeric: false, + disablePadding: false, + label: "Moderator Comment", + }, +]; + +const DefaultCells: HeadCell[] = [ + { + id: "description", + numeric: false, + disablePadding: false, + label: "Description", + }, + { + id: "sender", + numeric: false, + disablePadding: true, + label: "Appreciated By", + }, + { + id: "senderDesignation", + numeric: false, + disablePadding: true, + label: "Sender Designation", + }, + { + id: "receiver", + numeric: false, + disablePadding: false, + label: "Appreciation To", + }, + { + id: "receiverDesignation", + numeric: false, + disablePadding: false, + label: "Receiver Designation", + }, + { + id: "coreValue", + numeric: false, + disablePadding: false, + label: "Core Value", + }, + { + id: "rewardPoints", + numeric: true, + disablePadding: false, + label: "Reward Points", + }, + { + id: "date", + numeric: true, + disablePadding: false, + label: "Date", + }, +]; + +function EnhancedTableHead(props: EnhancedTableProps) { + const [headCells, setHeadCells] = useState(DefaultCells); + + useEffect(() => { + setHeadCells(DefaultCells); + if (props.filter === "reported") { + reportedColumns?.forEach((item) => { + console.log("In reported columns map"); + return setHeadCells((prevData) => [...prevData, item]); + }); + } + }, [props.filter]); + const { order, orderBy, onRequestSort } = props; + const createSortHandler = + (property: keyof Data) => (event: React.MouseEvent) => { + onRequestSort(event, property); + }; + + return ( + + + {headCells.map((headCell) => ( + + + {headCell.label} + {orderBy === headCell.id ? ( + + {order === "desc" ? "sorted descending" : "sorted ascending"} + + ) : null} + + + ))} + + {props.filter === "reported" ? ( + Delete + ) : ( + + )} + + + ); +} + +interface EnhancedTableToolbarProps { + numSelected: number; + setFilter: (value: string | ((prevVar: string) => string)) => void; +} + +function EnhancedTableToolbar(props: EnhancedTableToolbarProps) { + return ( + + + Appreciations + + + + + + + ); +} +export default function AppreciationTable(props: IPropsTable) { + const [order, setOrder] = useState("asc"); + const [orderBy, setOrderBy] = useState("date"); + const [selected, setSelected] = useState([]); + const [page, setPage] = useState(0); + const [rowsPerPage, setRowsPerPage] = useState(5); + const [rows, setRows] = useState([]); + + useEffect(() => { + const data = props.response; + setRows([]); + + data?.map((item) => { + const updatedItem = { + ...item, + reported_by_first_name: item.reported_by_first_name || "", + reported_by_last_name: item.reported_by_last_name || "", + moderated_by_first_name: item.moderated_by_first_name || "", + moderated_by_last_name: item.moderated_by_last_name || "", + is_valid: item.is_valid === undefined ? true : item.is_valid, + }; + + console.log("is_valid -> ", item.is_valid); + + return setRows((prevData) => [ + ...prevData, + createData( + updatedItem.id, + updatedItem.description, + updatedItem.sender_first_name + " " + updatedItem.sender_last_name, + updatedItem.sender_designation, + updatedItem.receiver_first_name + + " " + + updatedItem.receiver_last_name, + updatedItem.receiver_designation, + updatedItem.core_value_name, + updatedItem.total_reward_points, + updatedItem.created_at, + updatedItem.reported_by_first_name + + " " + + updatedItem.reported_by_last_name, + updatedItem.reporting_comment, + updatedItem.reported_at, + updatedItem.moderated_by_first_name + + " " + + updatedItem.moderated_by_last_name, + updatedItem.moderator_comment, + updatedItem.is_valid + ), + ]); + }); + }, [props.response]); + + const handleRequestSort = ( + event: React.MouseEvent, + property: keyof Data + ) => { + const isAsc = orderBy === property && order === "asc"; + setOrder(isAsc ? "desc" : "asc"); + setOrderBy(property); + }; + + const handleSelectAllClick = (event: React.ChangeEvent) => { + if (event.target.checked) { + const newSelected = rows.map((n) => n.id); + setSelected(newSelected); + return; + } + setSelected([]); + }; + + // const handleClick = (event: React.MouseEvent, id: number) => { + // const selectedIndex = selected.indexOf(id); + // let newSelected: readonly number[] = []; + + // if (selectedIndex === -1) { + // newSelected = newSelected.concat(selected, id); + // } else if (selectedIndex === 0) { + // newSelected = newSelected.concat(selected.slice(1)); + // } else if (selectedIndex === selected.length - 1) { + // newSelected = newSelected.concat(selected.slice(0, -1)); + // } else if (selectedIndex > 0) { + // newSelected = newSelected.concat( + // selected.slice(0, selectedIndex), + // selected.slice(selectedIndex + 1) + // ); + // } + // setSelected(newSelected); + // }; + + const handleChangePage = (event: unknown, newPage: number) => { + setPage(newPage); + }; + + const handleChangeRowsPerPage = ( + event: React.ChangeEvent + ) => { + setRowsPerPage(parseInt(event.target.value, 10)); + setPage(0); + }; + + // Avoid a layout jump when reaching the last page with empty rows. + const emptyRows = + page > 0 ? Math.max(0, (1 + page) * rowsPerPage - rows.length) : 0; + + const visibleRows = useMemo( + () => + stableSort(rows, getComparator(order, orderBy)).slice( + page * rowsPerPage, + page * rowsPerPage + rowsPerPage + ), + [order, orderBy, page, rowsPerPage, rows] + ); + + return ( + + + + + + + + {visibleRows.map((row, index) => { + const labelId = `enhanced-table-checkbox-${index}`; + + return ( + handleClick(event, row.id)} + tabIndex={-1} + key={row.id} + sx={{ cursor: "pointer" }} + > + + {row.description} + + {row.sender} + {row.senderDesignation} + {row.receiver} + + {row.receiverDesignation} + + {row.coreValue} + {row.rewardPoints} + + {row.date == undefined + ? row.date + : new Date(row.date).toLocaleString()} + + {props.filter === "reported" ? ( + <> + {row.reportedBy} + + {row.reportingComment} + + + {row.reportedAt == undefined + ? row.reportedAt + : new Date(row.reportedAt).toLocaleString()} + + {row.moderatedBy} + + {row.moderatorComment} + + {row.isValid ? ( + + + + + + ) : ( + + )} + + ) : ( + <> + )} + {/* {row.reportedBy} + {row.reportingComment} + + {row.reportedAt == undefined + ? row.reportedAt + : new Date(row.reportedAt).toLocaleString()} + + {row.moderatedBy} + {row.moderatorComment} */} + {/* {row.isValid ? ( + + + + + + ) : ( + <> + )} */} + + ); + })} + {emptyRows > 0 && ( + + + + )} + +
+
+ +
+
+ ); +} diff --git a/src/appreciations/components/toggleButton.tsx b/src/appreciations/components/toggleButton.tsx new file mode 100644 index 0000000..5ba407e --- /dev/null +++ b/src/appreciations/components/toggleButton.tsx @@ -0,0 +1,29 @@ +import * as React from 'react'; +import ToggleButton from '@mui/material/ToggleButton'; +import ToggleButtonGroup from '@mui/material/ToggleButtonGroup'; +import { IPropsButtons } from '../types'; + +export default function AppreciationToggleButton(props: IPropsButtons) { + const [alignment, setAlignment] = React.useState('appreciations'); + + const handleChange = ( + event: React.MouseEvent, + newAlignment: string, + ) => { + setAlignment(newAlignment); + props.setFilter(newAlignment) + }; + + return ( + + Appreciations + Reported + + ); +} diff --git a/src/appreciations/index.tsx b/src/appreciations/index.tsx new file mode 100644 index 0000000..4033a8e --- /dev/null +++ b/src/appreciations/index.tsx @@ -0,0 +1,34 @@ +import AppreciationTable from "./components/table"; +import { useGetAppreciationsQuery, useGetReportedAppreciationsQuery } from "./apiSlice"; +import { useMemo, useState } from "react"; + +const Appreciations = () => { + const { data: appreciations, isError: listAppreciationsError } = useGetAppreciationsQuery({ + page: 1, + page_size: 10, + }); + const { data: reportedAppreciations, isError: listReportedAppreciationsError} = useGetReportedAppreciationsQuery() + const [filter, setFilter] = useState("appreciations") + + const response = useMemo(() => { + if(filter == "appreciations"){ + return appreciations?.data.appreciations + } + else if(filter == "reported"){ + return reportedAppreciations?.data.appreciations + } + + },[filter, appreciations?.data.appreciations, reportedAppreciations?.data.appreciations]) + + return ( + <> + {listAppreciationsError || listReportedAppreciationsError ? ( +

Error

+ ) : ( + + )} + + ); +}; + +export default Appreciations; diff --git a/src/appreciations/types.tsx b/src/appreciations/types.tsx new file mode 100644 index 0000000..37a42bc --- /dev/null +++ b/src/appreciations/types.tsx @@ -0,0 +1,58 @@ +export interface appreciation { + id: number; + core_value_name: string; + core_value_description: string; + description: string; + total_reward_points: number; + quarter: number; + sender_first_name: string; + sender_last_name: string; + sender_image_url: string; + sender_designation: string; + receiver_first_name:string; + receiver_last_name: string; + receiver_image_url: string; + receiver_designation: string; + total_rewards: number; + given_reward_point: number; + created_at: number; + updated_at: number; + is_valid: boolean; + reported_by_first_name: string | undefined ; + reported_by_last_name: string | undefined; + reporting_comment: string; + reported_at: number; + moderated_by_first_name: string; + moderated_by_last_name: string; + moderator_comment: string; + moderated_at: number; +} + +interface metadata{ + page: number; + total_page: number; + page_size: number; + total_records: number; +} + +interface data{ + appreciations: appreciation[] + metadata: metadata +} + +export interface response { + success: boolean; + message: string; + status_code: number; + data: data; +} + +export interface IPropsTable { + response: appreciation[] | undefined + filter: string + setFilter: (value: string | ((prevVar: string) => string)) => void; +} + +export interface IPropsButtons{ + setFilter: (value: string | ((prevVar: string) => string)) => void; +} \ No newline at end of file diff --git a/src/store.tsx b/src/store.tsx index fddeb23..c99ecb6 100644 --- a/src/store.tsx +++ b/src/store.tsx @@ -1,6 +1,7 @@ import { configureStore } from '@reduxjs/toolkit'; import { loginSlice } from './login/apiSlice.tsx'; +import { appreciationSlice } from './appreciations/apiSlice.tsx'; export const store = configureStore({ @@ -8,11 +9,12 @@ export const store = configureStore({ reducer: { [loginSlice.reducerPath]: loginSlice.reducer, + [appreciationSlice.reducerPath]: appreciationSlice.reducer, }, middleware: (getDefaultMiddleware) => - getDefaultMiddleware().concat(loginSlice.middleware), + getDefaultMiddleware().concat(loginSlice.middleware).concat(appreciationSlice.middleware), }); \ No newline at end of file From 0205a377e1d3382d4d670d5295f73af939590313 Mon Sep 17 00:00:00 2001 From: Sharyu Marwadi Date: Mon, 5 Aug 2024 12:07:12 +0530 Subject: [PATCH 04/23] [feature/PEER-50-Appreciations] appreciations page done --- src/App.tsx | 25 +++- src/appreciations/apiSlice.tsx | 69 ++++++---- src/appreciations/components/dialogeBox.tsx | 80 ++++++++++++ src/appreciations/components/table.tsx | 133 +++++++------------- src/appreciations/index.tsx | 21 +++- src/appreciations/types.tsx | 14 +++ src/home/index.tsx | 6 +- src/login/apiSlice.tsx | 6 +- src/login/components/loginForm.tsx | 6 +- src/login/slice.tsx | 24 ++++ src/sideBar/index.tsx | 66 ++++++++++ src/sideBar/slice.tsx | 23 ++++ src/store.tsx | 17 ++- 13 files changed, 367 insertions(+), 123 deletions(-) create mode 100644 src/appreciations/components/dialogeBox.tsx create mode 100644 src/login/slice.tsx create mode 100644 src/sideBar/index.tsx create mode 100644 src/sideBar/slice.tsx diff --git a/src/App.tsx b/src/App.tsx index 92b3bdf..3c59814 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,21 +1,42 @@ import "./App.css"; import Login from "./login"; import { ToastContainer } from "react-toastify"; -import { createBrowserRouter, RouterProvider } from "react-router-dom"; +import { createBrowserRouter, RouterProvider, useNavigate } from "react-router-dom"; import Appreciations from "./appreciations"; +import { useDispatch } from "react-redux"; +import { getAuthToken } from "./login/slice"; +import { useEffect } from "react"; +import Home from "./home"; function App() { const router = createBrowserRouter([ { path: "/", - element: , + element: , }, { path: "/login", element: , }, + { + path: "/appreciations", + element: , + }, ]); + const dispatch = useDispatch(); + + const sendData = () => { + const authToken: string | null = localStorage.getItem("token"); + if (authToken) { + dispatch(getAuthToken(authToken)); + } + }; + + useEffect(() => { + sendData(); + }, []); + return ( <>
diff --git a/src/appreciations/apiSlice.tsx b/src/appreciations/apiSlice.tsx index f8a3f5d..0ae662c 100644 --- a/src/appreciations/apiSlice.tsx +++ b/src/appreciations/apiSlice.tsx @@ -1,34 +1,53 @@ -import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react' -import { response } from './types'; +import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react"; +import { moderationReq, moderationResponse, response } from "./types"; export const appreciationSlice = createApi({ - reducerPath: 'appreciationSlice', + reducerPath: "appreciationSlice", baseQuery: fetchBaseQuery({ - baseUrl: 'http://localhost:33001', + baseUrl: "http://localhost:33001", }), - tagTypes: ['appreciation'], + tagTypes: ["appreciation", "reported", "moderation"], endpoints: (builder) => ({ - getAppreciations: builder.query({ - query: ({ page, page_size }) => ({ - url: `/appreciations?page=${page}&page_size=${page_size}`, - method: 'GET', - headers: { - 'Accept-Version': 'application/vnd.peerly.v1', - 'Authorization': 'Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJJZCI6NTQsIlJvbGUiOiJ1c2VyIiwiZXhwIjoxNzI0MjI1MzEyfQ.dPvo969X1KfLS_PxXMfULBJHSpQyhFZbCXBeGNWTtVg' - }, - }), + getAppreciations: builder.query({ + query: ({ page, page_size, authToken }) => ({ + url: `/appreciations?page=${page}&page_size=${page_size}`, + method: "GET", + headers: { + "Accept-Version": "application/vnd.peerly.v1", + Authorization: `Bearer ${authToken}`, + }, }), - getReportedAppreciations: builder.query({ - query: () => ({ - url: `/report_appreciations`, - method: 'GET', - headers: { - 'Accept-Version': 'application/vnd.peerly.v1', - 'Authorization': 'Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJJZCI6NTQsIlJvbGUiOiJ1c2VyIiwiZXhwIjoxNzI0MjI1MzEyfQ.dPvo969X1KfLS_PxXMfULBJHSpQyhFZbCXBeGNWTtVg' - }, - }), + providesTags: ["appreciation"], + }), + getReportedAppreciations: builder.query({ + query: ({ authToken }) => ({ + url: `/report_appreciations`, + method: "GET", + headers: { + "Accept-Version": "application/vnd.peerly.v1", + Authorization: `Bearer ${authToken}`, + }, }), + providesTags: ["reported"], + }), + deleteAppreciation: builder.mutation>({ + query: (payload) => ({ + url: `/moderate_appreciation/${payload.id}`, + method: "PUT", + body: { moderator_comment: payload.moderator_comment }, + headers: { + "Content-type": "application/json; charset=UTF-8", + "Accept-Version": "application/vnd.peerly.v1", + Authorization: `Bearer ${payload.authToken}`, + }, + }), + invalidatesTags: () => [{ type: "reported" }], + }), }), -}) +}); -export const { useGetAppreciationsQuery, useGetReportedAppreciationsQuery } = appreciationSlice \ No newline at end of file +export const { + useGetAppreciationsQuery, + useGetReportedAppreciationsQuery, + useDeleteAppreciationMutation, +} = appreciationSlice; diff --git a/src/appreciations/components/dialogeBox.tsx b/src/appreciations/components/dialogeBox.tsx new file mode 100644 index 0000000..a3342ed --- /dev/null +++ b/src/appreciations/components/dialogeBox.tsx @@ -0,0 +1,80 @@ +import * as React from 'react'; +import Button from '@mui/material/Button'; +import Dialog from '@mui/material/Dialog'; +import DialogActions from '@mui/material/DialogActions'; +import DialogContent from '@mui/material/DialogContent'; +import DialogContentText from '@mui/material/DialogContentText'; +import DialogTitle from '@mui/material/DialogTitle'; +import TextField from '@mui/material/TextField'; +import { useDeleteAppreciationMutation } from '../apiSlice'; +import { moderationReq } from '../types'; +import { toast } from 'react-toastify'; +import { RootState } from '../../store'; +import { useSelector } from 'react-redux'; + +interface IProps { + open: boolean; + setOpen: (value: boolean | ((prevVar: boolean) => boolean)) => void; + id: number; +} +export default function DeleteDialog(props: IProps) { + + const authToken = useSelector((state: RootState) => state.loginStore.authToken); + + const handleClose = () => { + props.setOpen(false); + }; + + const [deleteAppreciation] = useDeleteAppreciationMutation(); + + return ( + + ) => { + event.preventDefault(); + const formData = new FormData(event.currentTarget); + const formJson = Object.fromEntries((formData as any).entries()); + const moderationComment = formJson.moderator_comment; + const req: moderationReq = { + moderator_comment: moderationComment, + id: props.id, + authToken: authToken + } + deleteAppreciation(req).unwrap().then(resp=>{ + toast.success(resp.message) + }).catch(err=>{ + toast.error(err.data.message) + }) + handleClose(); + }, + }} + > + Delete Appreciation + + + Are you sure you want to delete the appreciation? + + + + + + + + + + ); +} diff --git a/src/appreciations/components/table.tsx b/src/appreciations/components/table.tsx index 8a1401b..0b3118d 100644 --- a/src/appreciations/components/table.tsx +++ b/src/appreciations/components/table.tsx @@ -17,14 +17,13 @@ import DeleteIcon from "@mui/icons-material/Delete"; import { visuallyHidden } from "@mui/utils"; import { IPropsTable } from "../types"; import AppreciationToggleButton from "./toggleButton"; +import DeleteDialog from "./dialogeBox"; interface Data { id: number; description: string; sender: string; - senderDesignation: string; receiver: string; - receiverDesignation: string; coreValue: string; rewardPoints: number; date: number; @@ -40,9 +39,7 @@ function createData( id: number, description: string, sender: string, - senderDesignation: string, receiver: string, - receiverDesignation: string, coreValue: string, rewardPoints: number, date: number, @@ -57,9 +54,7 @@ function createData( id, description, sender, - senderDesignation, receiver, - receiverDesignation, coreValue, rewardPoints, date, @@ -162,6 +157,21 @@ const reportedColumns: HeadCell[] = [ disablePadding: false, label: "Moderator Comment", }, + { + id: "isValid", + numeric: false, + disablePadding: false, + label: "Delete", + }, +]; + +const appreciationColumns: HeadCell[] = [ + { + id: "date", + numeric: true, + disablePadding: false, + label: "Date", + }, ]; const DefaultCells: HeadCell[] = [ @@ -177,24 +187,12 @@ const DefaultCells: HeadCell[] = [ disablePadding: true, label: "Appreciated By", }, - { - id: "senderDesignation", - numeric: false, - disablePadding: true, - label: "Sender Designation", - }, { id: "receiver", numeric: false, disablePadding: false, label: "Appreciation To", }, - { - id: "receiverDesignation", - numeric: false, - disablePadding: false, - label: "Receiver Designation", - }, { id: "coreValue", numeric: false, @@ -207,12 +205,6 @@ const DefaultCells: HeadCell[] = [ disablePadding: false, label: "Reward Points", }, - { - id: "date", - numeric: true, - disablePadding: false, - label: "Date", - }, ]; function EnhancedTableHead(props: EnhancedTableProps) { @@ -222,7 +214,10 @@ function EnhancedTableHead(props: EnhancedTableProps) { setHeadCells(DefaultCells); if (props.filter === "reported") { reportedColumns?.forEach((item) => { - console.log("In reported columns map"); + return setHeadCells((prevData) => [...prevData, item]); + }); + } else { + appreciationColumns?.forEach((item) => { return setHeadCells((prevData) => [...prevData, item]); }); } @@ -239,7 +234,7 @@ function EnhancedTableHead(props: EnhancedTableProps) { {headCells.map((headCell) => ( @@ -257,12 +252,6 @@ function EnhancedTableHead(props: EnhancedTableProps) { ))} - - {props.filter === "reported" ? ( - Delete - ) : ( - - )} ); @@ -297,7 +286,7 @@ function EnhancedTableToolbar(props: EnhancedTableToolbarProps) { ); } export default function AppreciationTable(props: IPropsTable) { - const [order, setOrder] = useState("asc"); + const [order, setOrder] = useState("desc"); const [orderBy, setOrderBy] = useState("date"); const [selected, setSelected] = useState([]); const [page, setPage] = useState(0); @@ -306,6 +295,12 @@ export default function AppreciationTable(props: IPropsTable) { useEffect(() => { const data = props.response; + if(props.filter == "reported"){ + setOrderBy("isValid") + } + else{ + setOrderBy("date") + } setRows([]); data?.map((item) => { @@ -318,19 +313,15 @@ export default function AppreciationTable(props: IPropsTable) { is_valid: item.is_valid === undefined ? true : item.is_valid, }; - console.log("is_valid -> ", item.is_valid); - return setRows((prevData) => [ ...prevData, createData( updatedItem.id, updatedItem.description, updatedItem.sender_first_name + " " + updatedItem.sender_last_name, - updatedItem.sender_designation, updatedItem.receiver_first_name + " " + updatedItem.receiver_last_name, - updatedItem.receiver_designation, updatedItem.core_value_name, updatedItem.total_reward_points, updatedItem.created_at, @@ -367,24 +358,12 @@ export default function AppreciationTable(props: IPropsTable) { setSelected([]); }; - // const handleClick = (event: React.MouseEvent, id: number) => { - // const selectedIndex = selected.indexOf(id); - // let newSelected: readonly number[] = []; - - // if (selectedIndex === -1) { - // newSelected = newSelected.concat(selected, id); - // } else if (selectedIndex === 0) { - // newSelected = newSelected.concat(selected.slice(1)); - // } else if (selectedIndex === selected.length - 1) { - // newSelected = newSelected.concat(selected.slice(0, -1)); - // } else if (selectedIndex > 0) { - // newSelected = newSelected.concat( - // selected.slice(0, selectedIndex), - // selected.slice(selectedIndex + 1) - // ); - // } - // setSelected(newSelected); - // }; + const [open, setOpen] = useState(false); + + const handleClickOpen = (id: number) => { + setId(id); + setOpen(true); + }; const handleChangePage = (event: unknown, newPage: number) => { setPage(newPage); @@ -397,7 +376,6 @@ export default function AppreciationTable(props: IPropsTable) { setPage(0); }; - // Avoid a layout jump when reaching the last page with empty rows. const emptyRows = page > 0 ? Math.max(0, (1 + page) * rowsPerPage - rows.length) : 0; @@ -410,6 +388,8 @@ export default function AppreciationTable(props: IPropsTable) { [order, orderBy, page, rowsPerPage, rows] ); + const [id, setId] = useState(0); + return ( @@ -439,7 +419,6 @@ export default function AppreciationTable(props: IPropsTable) { return ( handleClick(event, row.id)} tabIndex={-1} key={row.id} sx={{ cursor: "pointer" }} @@ -453,18 +432,19 @@ export default function AppreciationTable(props: IPropsTable) { {row.description} {row.sender} - {row.senderDesignation} {row.receiver} - - {row.receiverDesignation} - {row.coreValue} {row.rewardPoints} - - {row.date == undefined - ? row.date - : new Date(row.date).toLocaleString()} - + + {props.filter === "appreciations" ? ( + + {row.date == undefined + ? row.date + : new Date(row.date).toLocaleString()} + + ) : ( + <> + )} {props.filter === "reported" ? ( <> {row.reportedBy} @@ -482,7 +462,7 @@ export default function AppreciationTable(props: IPropsTable) { {row.isValid ? ( - + handleClickOpen(row.id)}> @@ -493,24 +473,6 @@ export default function AppreciationTable(props: IPropsTable) { ) : ( <> )} - {/* {row.reportedBy} - {row.reportingComment} - - {row.reportedAt == undefined - ? row.reportedAt - : new Date(row.reportedAt).toLocaleString()} - - {row.moderatedBy} - {row.moderatorComment} */} - {/* {row.isValid ? ( - - - - - - ) : ( - <> - )} */} ); })} @@ -536,6 +498,7 @@ export default function AppreciationTable(props: IPropsTable) { onRowsPerPageChange={handleChangeRowsPerPage} /> + ); } diff --git a/src/appreciations/index.tsx b/src/appreciations/index.tsx index 4033a8e..e301294 100644 --- a/src/appreciations/index.tsx +++ b/src/appreciations/index.tsx @@ -1,15 +1,31 @@ import AppreciationTable from "./components/table"; import { useGetAppreciationsQuery, useGetReportedAppreciationsQuery } from "./apiSlice"; -import { useMemo, useState } from "react"; +import { useEffect, useMemo, useState } from "react"; +import { useSelector } from "react-redux"; +import { RootState } from "../store"; +import { useNavigate } from "react-router-dom"; +import TemporaryDrawer from "../sideBar"; const Appreciations = () => { + const navigate = useNavigate() + const authToken = useSelector((state: RootState) => state.loginStore.authToken); const { data: appreciations, isError: listAppreciationsError } = useGetAppreciationsQuery({ page: 1, page_size: 10, + authToken: authToken }); - const { data: reportedAppreciations, isError: listReportedAppreciationsError} = useGetReportedAppreciationsQuery() + const { data: reportedAppreciations, isError: listReportedAppreciationsError} = useGetReportedAppreciationsQuery({authToken: authToken}) const [filter, setFilter] = useState("appreciations") + useEffect(()=>{ + console.log("authtoken -> ",authToken) + if(authToken === ""){ + navigate("/login") + }else{ + navigate("/appreciations") + } + },[authToken]) + const response = useMemo(() => { if(filter == "appreciations"){ return appreciations?.data.appreciations @@ -22,6 +38,7 @@ const Appreciations = () => { return ( <> + {listAppreciationsError || listReportedAppreciationsError ? (

Error

) : ( diff --git a/src/appreciations/types.tsx b/src/appreciations/types.tsx index 37a42bc..80f350a 100644 --- a/src/appreciations/types.tsx +++ b/src/appreciations/types.tsx @@ -1,3 +1,4 @@ + export interface appreciation { id: number; core_value_name: string; @@ -55,4 +56,17 @@ export interface IPropsTable { export interface IPropsButtons{ setFilter: (value: string | ((prevVar: string) => string)) => void; +} + +export interface moderationReq{ + moderator_comment: string + id: number + authToken: string +} + +export interface moderationResponse { + success: boolean; + message: string; + status_code: number; + data: object; } \ No newline at end of file diff --git a/src/home/index.tsx b/src/home/index.tsx index 57f12e1..b7f35b1 100644 --- a/src/home/index.tsx +++ b/src/home/index.tsx @@ -1,6 +1,10 @@ +import TemporaryDrawer from "../sideBar" + const Home = () => { return( - <>home + <> + + home ) } diff --git a/src/login/apiSlice.tsx b/src/login/apiSlice.tsx index 2819430..ffd90c8 100644 --- a/src/login/apiSlice.tsx +++ b/src/login/apiSlice.tsx @@ -1,7 +1,9 @@ import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react' import { userLoginBody, userLoginResp } from './types' +import { useSelector } from 'react-redux'; +import { RootState } from '../store'; -export const loginSlice = createApi({ +export const loginApiSlice = createApi({ reducerPath: 'loginSlice', baseQuery: fetchBaseQuery({ baseUrl: 'http://localhost:33001', @@ -23,4 +25,4 @@ export const loginSlice = createApi({ }), }) -export const { useAdminLoginMutation } = loginSlice \ No newline at end of file +export const { useAdminLoginMutation } = loginApiSlice \ No newline at end of file diff --git a/src/login/components/loginForm.tsx b/src/login/components/loginForm.tsx index d3a7fa1..b918fed 100644 --- a/src/login/components/loginForm.tsx +++ b/src/login/components/loginForm.tsx @@ -6,6 +6,8 @@ import { useAdminLoginMutation } from "../apiSlice"; import { useNavigate } from "react-router-dom"; import { toast } from "react-toastify"; import "react-toastify/dist/ReactToastify.css"; +import { useDispatch } from "react-redux"; +import { getAuthToken } from "../slice"; const LoginForm = () => { const navigate = useNavigate(); @@ -18,6 +20,7 @@ const LoginForm = () => { password: Yup.string().required("Required!"), }); const [loginAdmin] = useAdminLoginMutation(); + const dispatch = useDispatch(); const formik = useFormik({ initialValues: initialValues, validationSchema: loginSchema, @@ -28,7 +31,8 @@ const LoginForm = () => { console.log("response -> ", resp); toast.success(resp.message); localStorage.setItem("token", resp.data.AuthToken); - navigate("/") + dispatch(getAuthToken(resp.data.AuthToken)); + navigate("/"); }) .catch((resp) => { console.log("response -> ", resp); diff --git a/src/login/slice.tsx b/src/login/slice.tsx new file mode 100644 index 0000000..54ccffe --- /dev/null +++ b/src/login/slice.tsx @@ -0,0 +1,24 @@ +import { createSlice, PayloadAction } from "@reduxjs/toolkit"; + +export interface TheStoreState { + authToken: string; +} + +const initialStateValue: TheStoreState = { + authToken: "", +}; + +export const loginSlice = createSlice({ + name: "loginStore", + initialState: initialStateValue, + reducers: { + getAuthToken: (state, action: PayloadAction) => { + state.authToken = action.payload; + }, + }, +}); + +export const { getAuthToken } = loginSlice.actions; + +export default loginSlice.reducer; + diff --git a/src/sideBar/index.tsx b/src/sideBar/index.tsx new file mode 100644 index 0000000..1486d22 --- /dev/null +++ b/src/sideBar/index.tsx @@ -0,0 +1,66 @@ +import * as React from 'react'; +import Box from '@mui/material/Box'; +import Drawer from '@mui/material/Drawer'; +import Button from '@mui/material/Button'; +import List from '@mui/material/List'; +import ListItem from '@mui/material/ListItem'; +import ListItemButton from '@mui/material/ListItemButton'; +import ListItemIcon from '@mui/material/ListItemIcon'; +import ListItemText from '@mui/material/ListItemText'; +import MoreVertIcon from '@mui/icons-material/MoreVert'; +import DashboardIcon from '@mui/icons-material/Dashboard'; +import PostAddIcon from '@mui/icons-material/PostAdd'; +import LocalPoliceIcon from '@mui/icons-material/LocalPolice'; +import DiamondIcon from '@mui/icons-material/Diamond'; +import AssuredWorkloadIcon from '@mui/icons-material/AssuredWorkload'; +import { useNavigate } from 'react-router-dom'; +import { getRoute } from './slice'; +import { useDispatch } from 'react-redux'; + +export default function TemporaryDrawer() { + const [open, setOpen] = React.useState(false); + const navigate = useNavigate(); + + const toggleDrawer = (newOpen: boolean) => () => { + setOpen(newOpen); + }; + + const iconList = [, , , , ] + const routeList = ['/', '/appreciations', '/', '/', '/'] + const dispatch = useDispatch(); + const setRoute = (index: number) => () => { + dispatch(getRoute(routeList[index])); + navigate(routeList[index]) + toggleDrawer(false) + } + + + const DrawerList = ( + + + {['Dashboard', 'Appreciations', 'Badges', 'Corevalues', 'Config'].map((text, index) => ( + + + + {iconList[index]} + + + + + ))} + + {/* */} + + ); + + return ( +
+ + + {DrawerList} + +
+ ); +} diff --git a/src/sideBar/slice.tsx b/src/sideBar/slice.tsx new file mode 100644 index 0000000..6862ff5 --- /dev/null +++ b/src/sideBar/slice.tsx @@ -0,0 +1,23 @@ +import { createSlice, PayloadAction } from "@reduxjs/toolkit"; + +export interface SidebarStoreState { + route: string; +} + +const initialStateValue: SidebarStoreState = { + route: "/", +}; + +export const sidebarSlice = createSlice({ + name: "sidebarStore", + initialState: initialStateValue, + reducers: { + getRoute: (state, action: PayloadAction) => { + state.route = action.payload; + }, + }, +}); + +export const { getRoute } = sidebarSlice.actions; + +export default sidebarSlice.reducer; diff --git a/src/store.tsx b/src/store.tsx index c99ecb6..0afba39 100644 --- a/src/store.tsx +++ b/src/store.tsx @@ -1,20 +1,27 @@ import { configureStore } from '@reduxjs/toolkit'; -import { loginSlice } from './login/apiSlice.tsx'; -import { appreciationSlice } from './appreciations/apiSlice.tsx'; +import { loginApiSlice } from './login/apiSlice.tsx'; +import { appreciationSlice } from './appreciations/apiSlice'; +import loginReducer from './login/slice'; +import sidebarReducer from './sideBar/slice.tsx'; export const store = configureStore({ reducer: { - [loginSlice.reducerPath]: loginSlice.reducer, + loginStore: loginReducer, + sidebarStore: sidebarReducer, + [loginApiSlice.reducerPath]: loginApiSlice.reducer, [appreciationSlice.reducerPath]: appreciationSlice.reducer, }, middleware: (getDefaultMiddleware) => - getDefaultMiddleware().concat(loginSlice.middleware).concat(appreciationSlice.middleware), + getDefaultMiddleware().concat(loginApiSlice.middleware).concat(appreciationSlice.middleware) -}); \ No newline at end of file +}); + +export type RootState = ReturnType; +export type AppDispatch = typeof store.dispatch; \ No newline at end of file From 1029bb901bee83578bef30444ae98402268529f1 Mon Sep 17 00:00:00 2001 From: Sharyu Marwadi Date: Tue, 6 Aug 2024 19:34:18 +0530 Subject: [PATCH 05/23] [feature/PEER-57-Config] edit renewal frequency done --- src/App.tsx | 7 +- src/appreciations/apiSlice.tsx | 2 +- src/config/apiSlice.tsx | 53 ++++++++++++ .../components/editRenewalFreqDialog.tsx | 80 +++++++++++++++++++ src/config/components/grades.tsx | 60 ++++++++++++++ src/config/components/orgConfig.tsx | 57 +++++++++++++ src/config/components/quater.tsx | 52 ++++++++++++ src/config/index.tsx | 35 ++++++++ src/config/types.tsx | 36 +++++++++ src/login/apiSlice.tsx | 4 +- src/sideBar/index.tsx | 5 +- src/store.tsx | 4 +- 12 files changed, 387 insertions(+), 8 deletions(-) create mode 100644 src/config/apiSlice.tsx create mode 100644 src/config/components/editRenewalFreqDialog.tsx create mode 100644 src/config/components/grades.tsx create mode 100644 src/config/components/orgConfig.tsx create mode 100644 src/config/components/quater.tsx create mode 100644 src/config/index.tsx create mode 100644 src/config/types.tsx diff --git a/src/App.tsx b/src/App.tsx index 3c59814..3a7eb73 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,12 +1,13 @@ import "./App.css"; import Login from "./login"; import { ToastContainer } from "react-toastify"; -import { createBrowserRouter, RouterProvider, useNavigate } from "react-router-dom"; +import { createBrowserRouter, RouterProvider } from "react-router-dom"; import Appreciations from "./appreciations"; import { useDispatch } from "react-redux"; import { getAuthToken } from "./login/slice"; import { useEffect } from "react"; import Home from "./home"; +import Config from "./config"; function App() { const router = createBrowserRouter([ @@ -22,6 +23,10 @@ function App() { path: "/appreciations", element: , }, + { + path: "/config", + element: , + }, ]); const dispatch = useDispatch(); diff --git a/src/appreciations/apiSlice.tsx b/src/appreciations/apiSlice.tsx index 0ae662c..339634c 100644 --- a/src/appreciations/apiSlice.tsx +++ b/src/appreciations/apiSlice.tsx @@ -4,7 +4,7 @@ import { moderationReq, moderationResponse, response } from "./types"; export const appreciationSlice = createApi({ reducerPath: "appreciationSlice", baseQuery: fetchBaseQuery({ - baseUrl: "http://localhost:33001", + baseUrl: "http://localhost:33001/peerly", }), tagTypes: ["appreciation", "reported", "moderation"], endpoints: (builder) => ({ diff --git a/src/config/apiSlice.tsx b/src/config/apiSlice.tsx new file mode 100644 index 0000000..0ad593b --- /dev/null +++ b/src/config/apiSlice.tsx @@ -0,0 +1,53 @@ +import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react"; +import { editRenewalFrequencyReq, editRenewalFrequencyResp, gradesResponse, orgConfigResponse } from "./types"; + +export const configSlice = createApi({ + reducerPath: "configSlice", + baseQuery: fetchBaseQuery({ + baseUrl: "http://localhost:33001/peerly", + }), + tagTypes: ["gradesConfig","orgConfig","editGrades"], + endpoints: (builder) => ({ + getGrades: builder.query({ + query: ({ authToken }) => ({ + url: "/grades", + method: "GET", + headers: { + "Accept-Version": "application/vnd.peerly.v1", + Authorization: `Bearer ${authToken}`, + }, + }), + providesTags: ["gradesConfig"], + }), + getOrgConfig: builder.query({ + query: ({ authToken }) => ({ + url: "/organizationconfig", + method: "GET", + headers: { + "Accept-Version": "application/vnd.peerly.v1", + Authorization: `Bearer ${authToken}`, + }, + }), + providesTags: ["orgConfig"], + }), + editRenewalFrequency: builder.mutation>({ + query: (payload) => ({ + url: "/organizationconfig", + method: "PUT", + body: { reward_quota_renewal_frequency: payload.reward_quota_renewal_frequency}, + headers: { + "Content-type": "application/json; charset=UTF-8", + "Accept-Version": "application/vnd.peerly.v1", + Authorization: `Bearer ${payload.authToken}`, + }, + }), + invalidatesTags: () => [{ type: "orgConfig" }], + }), + }), +}); + +export const { + useGetGradesQuery, + useGetOrgConfigQuery, + useEditRenewalFrequencyMutation +} = configSlice; diff --git a/src/config/components/editRenewalFreqDialog.tsx b/src/config/components/editRenewalFreqDialog.tsx new file mode 100644 index 0000000..0cc82d3 --- /dev/null +++ b/src/config/components/editRenewalFreqDialog.tsx @@ -0,0 +1,80 @@ +import * as React from 'react'; +import Button from '@mui/material/Button'; +import Dialog from '@mui/material/Dialog'; +import DialogActions from '@mui/material/DialogActions'; +import DialogContent from '@mui/material/DialogContent'; +import DialogTitle from '@mui/material/DialogTitle'; +import TextField from '@mui/material/TextField'; +import { toast } from 'react-toastify'; +import { RootState } from '../../store'; +import { useSelector } from 'react-redux'; +import { useEditRenewalFrequencyMutation } from '../apiSlice'; +import { editRenewalFrequencyReq } from '../types'; +import { number } from 'yup'; + +interface IProps { + open: boolean; + setOpen: (value: boolean | ((prevVar: boolean) => boolean)) => void; +} +export default function EditRenewalFreqDialog(props: IProps) { + + const authToken = useSelector((state: RootState) => state.loginStore.authToken); + + const handleClose = () => { + props.setOpen(false); + }; + + const [editRenewalFrequency] = useEditRenewalFrequencyMutation(); + + + return ( + + ) => { + event.preventDefault(); + const formData = new FormData(event.currentTarget); + console.log(formData) + const formJson = Object.fromEntries((formData as any).entries()); + const renewalFrequency = Number(formJson.renewal_frequency); + const req: editRenewalFrequencyReq = { + reward_quota_renewal_frequency: renewalFrequency, + authToken: authToken + } + editRenewalFrequency(req).unwrap().then(resp=>{ + toast.success(resp.message) + }).catch(err=>{ + toast.error(err.data.message) + }) + handleClose(); + }, + }} + > + Edit renewal frequency + + {/* + Enter new renewal frequency + */} + + + + + + + + + ); +} diff --git a/src/config/components/grades.tsx b/src/config/components/grades.tsx new file mode 100644 index 0000000..6502060 --- /dev/null +++ b/src/config/components/grades.tsx @@ -0,0 +1,60 @@ +import Table from "@mui/material/Table"; +import TableBody from "@mui/material/TableBody"; +import TableCell from "@mui/material/TableCell"; +import TableContainer from "@mui/material/TableContainer"; +import TableHead from "@mui/material/TableHead"; +import TableRow from "@mui/material/TableRow"; +import Paper from "@mui/material/Paper"; +import { grade } from "../types"; +import { useEffect, useState } from "react"; +import BorderColorIcon from '@mui/icons-material/BorderColor'; + +function createData(id: number, name: string, points: number) { + return { id, name, points }; +} + +interface IProps { + gradesList: grade[]|undefined; +} + +export default function GradesTable(props: IProps) { + const [rows, setRows] = useState([]); + useEffect(() => { + props.gradesList?.map((grade) => { + setRows((prevData) => [ + ...prevData, + createData(grade.id, grade.name, grade.points), + ]); + }); + }, [props.gradesList]); + return ( + + + + + Sr No + Grade + Points + + + + {rows.map((row) => ( + + + {row.id} + + {row.name} + {row.points} + + + + + ))} + +
+
+ ); +} diff --git a/src/config/components/orgConfig.tsx b/src/config/components/orgConfig.tsx new file mode 100644 index 0000000..2db0bde --- /dev/null +++ b/src/config/components/orgConfig.tsx @@ -0,0 +1,57 @@ +import Table from "@mui/material/Table"; +import TableBody from "@mui/material/TableBody"; +import TableCell from "@mui/material/TableCell"; +import TableContainer from "@mui/material/TableContainer"; +import TableRow from "@mui/material/TableRow"; +import Paper from "@mui/material/Paper"; +import { orgConfig } from "../types"; +import { useEffect, useState } from "react"; +import BorderColorIcon from '@mui/icons-material/BorderColor'; + +function createData( + id: number | undefined , + reward_quota_renewal_frequency: number | undefined, +) { + return { id, reward_quota_renewal_frequency }; +} + +interface IProps { + orgConfig: orgConfig | undefined; + setOpen: (value: boolean | ((prevVar: boolean) => boolean)) => void; +} + + +export default function OrgConfigTable(props: IProps) { + const handleClickOpen = () => { + props.setOpen(true); + }; + const [row, setRow] = useState(); + useEffect(() => { + setRow( + createData( + props.orgConfig?.id, + props.orgConfig?.reward_quota_renewal_frequency + ) + ); + }, [props.orgConfig]); + return ( + + + + + + + Reward quota renewal frequency + + + {row!=undefined && row.reward_quota_renewal_frequency!=undefined && row?.reward_quota_renewal_frequency <= 1 ? `${row?.reward_quota_renewal_frequency} month` : `${row?.reward_quota_renewal_frequency} months`} + + + + + + +
+
+ ); +} diff --git a/src/config/components/quater.tsx b/src/config/components/quater.tsx new file mode 100644 index 0000000..59ca183 --- /dev/null +++ b/src/config/components/quater.tsx @@ -0,0 +1,52 @@ +import Table from '@mui/material/Table'; +import TableBody from '@mui/material/TableBody'; +import TableCell from '@mui/material/TableCell'; +import TableContainer from '@mui/material/TableContainer'; +import TableHead from '@mui/material/TableHead'; +import TableRow from '@mui/material/TableRow'; +import Paper from '@mui/material/Paper'; + +function createData( + quaterNo: number, + startDate: Date, + endDate: Date, +) { + return { quaterNo, startDate, endDate}; +} + +const rows = [ + createData(1,new Date(new Date().getFullYear(), 0, 1),new Date(new Date().getFullYear(), 2, 31)), + createData(2,new Date(new Date().getFullYear(), 3, 1),new Date(new Date().getFullYear(), 5, 30)), + createData(3,new Date(new Date().getFullYear(), 6, 1),new Date(new Date().getFullYear(), 8, 31)), + createData(4,new Date(new Date().getFullYear(), 9, 1),new Date(new Date().getFullYear(), 11, 31)) +]; + +export default function QuaterTable() { + return ( + + + + + Quater No + Start Date + End Date + + + + {rows.map((row) => ( + + + {row.quaterNo} + + {row.startDate.toLocaleDateString()} + {row.endDate.toLocaleDateString()} + + ))} + +
+
+ ); +} diff --git a/src/config/index.tsx b/src/config/index.tsx new file mode 100644 index 0000000..a4480d4 --- /dev/null +++ b/src/config/index.tsx @@ -0,0 +1,35 @@ +import { Typography } from "@mui/material"; +import QuaterTable from "./components/quater"; +import TemporaryDrawer from "../sideBar"; +import { useGetGradesQuery, useGetOrgConfigQuery } from "./apiSlice"; +import { useSelector } from "react-redux"; +import { RootState } from "../store"; +import GradesTable from "./components/grades"; +import OrgConfigTable from "./components/orgConfig"; +import EditRenewalFreqDialog from "./components/editRenewalFreqDialog"; +import { useState } from "react"; + +const Config = () => { + const authToken = useSelector((state: RootState) => state.loginStore.authToken); + const {data: gradesResp, isError: listGradesError} = useGetGradesQuery({ + authToken: authToken + }); + const {data: orgConfigResp, isError: getOrgConfigError} = useGetOrgConfigQuery({ + authToken: authToken + }); + const [open, setOpen] = useState(false); + return ( + <> + + Quaters + + Grades + {!listGradesError ? : <>} + Organisation Config + {!getOrgConfigError ? : <>} + + + ); +}; + +export default Config; diff --git a/src/config/types.tsx b/src/config/types.tsx new file mode 100644 index 0000000..8e9c2b0 --- /dev/null +++ b/src/config/types.tsx @@ -0,0 +1,36 @@ +export interface grade { + id: number; + name: string; + points: number; +} + +export interface gradesResponse { + success: boolean; + message: string; + status_code: number; + data: grade[]; +} + +export interface orgConfig { + id: number | undefined; + reward_quota_renewal_frequency: number | undefined; +} + +export interface orgConfigResponse { + success: boolean; + message: string; + status_code: number; + data: orgConfig; +} + +export interface editRenewalFrequencyReq { + reward_quota_renewal_frequency: number; + authToken: string; +} + +export interface editRenewalFrequencyResp { + success: string; + message: string; + status_code: number; + data: orgConfig; +} diff --git a/src/login/apiSlice.tsx b/src/login/apiSlice.tsx index ffd90c8..7314802 100644 --- a/src/login/apiSlice.tsx +++ b/src/login/apiSlice.tsx @@ -1,12 +1,10 @@ import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react' import { userLoginBody, userLoginResp } from './types' -import { useSelector } from 'react-redux'; -import { RootState } from '../store'; export const loginApiSlice = createApi({ reducerPath: 'loginSlice', baseQuery: fetchBaseQuery({ - baseUrl: 'http://localhost:33001', + baseUrl: 'http://localhost:33001/peerly', }), tagTypes: ['Login'], endpoints: (builder) => ({ diff --git a/src/sideBar/index.tsx b/src/sideBar/index.tsx index 1486d22..9a572f4 100644 --- a/src/sideBar/index.tsx +++ b/src/sideBar/index.tsx @@ -16,6 +16,7 @@ import AssuredWorkloadIcon from '@mui/icons-material/AssuredWorkload'; import { useNavigate } from 'react-router-dom'; import { getRoute } from './slice'; import { useDispatch } from 'react-redux'; +import ViewSidebarIcon from '@mui/icons-material/ViewSidebar'; export default function TemporaryDrawer() { const [open, setOpen] = React.useState(false); @@ -26,7 +27,7 @@ export default function TemporaryDrawer() { }; const iconList = [, , , , ] - const routeList = ['/', '/appreciations', '/', '/', '/'] + const routeList = ['/', '/appreciations', '/', '/', '/config'] const dispatch = useDispatch(); const setRoute = (index: number) => () => { dispatch(getRoute(routeList[index])); @@ -56,7 +57,7 @@ export default function TemporaryDrawer() { return (
{DrawerList} diff --git a/src/store.tsx b/src/store.tsx index 0afba39..115779e 100644 --- a/src/store.tsx +++ b/src/store.tsx @@ -4,6 +4,7 @@ import { loginApiSlice } from './login/apiSlice.tsx'; import { appreciationSlice } from './appreciations/apiSlice'; import loginReducer from './login/slice'; import sidebarReducer from './sideBar/slice.tsx'; +import { configSlice } from './config/apiSlice.tsx'; export const store = configureStore({ @@ -14,12 +15,13 @@ export const store = configureStore({ sidebarStore: sidebarReducer, [loginApiSlice.reducerPath]: loginApiSlice.reducer, [appreciationSlice.reducerPath]: appreciationSlice.reducer, + [configSlice.reducerPath]: configSlice.reducer, }, middleware: (getDefaultMiddleware) => - getDefaultMiddleware().concat(loginApiSlice.middleware).concat(appreciationSlice.middleware) + getDefaultMiddleware().concat(loginApiSlice.middleware).concat(appreciationSlice.middleware).concat(configSlice.middleware) }); From 6965b7251df97a004ad9e70231a403d5fb316860 Mon Sep 17 00:00:00 2001 From: Sharyu Marwadi Date: Tue, 6 Aug 2024 23:48:53 +0530 Subject: [PATCH 06/23] [feature/PEER-57-Config] config page functional --- src/config/apiSlice.tsx | 20 ++++- src/config/components/editGradeDialogue.tsx | 79 +++++++++++++++++++ .../components/editRenewalFreqDialog.tsx | 4 - src/config/components/grades.tsx | 26 ++++-- src/config/components/orgConfig.tsx | 18 +++-- src/config/index.tsx | 12 ++- src/config/types.tsx | 12 +++ 7 files changed, 146 insertions(+), 25 deletions(-) create mode 100644 src/config/components/editGradeDialogue.tsx diff --git a/src/config/apiSlice.tsx b/src/config/apiSlice.tsx index 0ad593b..7b612d5 100644 --- a/src/config/apiSlice.tsx +++ b/src/config/apiSlice.tsx @@ -1,12 +1,12 @@ import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react"; -import { editRenewalFrequencyReq, editRenewalFrequencyResp, gradesResponse, orgConfigResponse } from "./types"; +import { editGradeReq, editGradeResp, editRenewalFrequencyReq, editRenewalFrequencyResp, gradesResponse, orgConfigResponse } from "./types"; export const configSlice = createApi({ reducerPath: "configSlice", baseQuery: fetchBaseQuery({ baseUrl: "http://localhost:33001/peerly", }), - tagTypes: ["gradesConfig","orgConfig","editGrades"], + tagTypes: ["gradesConfig","orgConfig"], endpoints: (builder) => ({ getGrades: builder.query({ query: ({ authToken }) => ({ @@ -43,11 +43,25 @@ export const configSlice = createApi({ }), invalidatesTags: () => [{ type: "orgConfig" }], }), + editGrade: builder.mutation>({ + query: (payload) => ({ + url: `/grades/${payload.id}`, + method: "PATCH", + body: { points: payload.points}, + headers: { + "Content-type": "application/json; charset=UTF-8", + "Accept-Version": "application/vnd.peerly.v1", + Authorization: `Bearer ${payload.authToken}`, + }, + }), + invalidatesTags: () => [{ type: "gradesConfig" }], + }), }), }); export const { useGetGradesQuery, useGetOrgConfigQuery, - useEditRenewalFrequencyMutation + useEditRenewalFrequencyMutation, + useEditGradeMutation } = configSlice; diff --git a/src/config/components/editGradeDialogue.tsx b/src/config/components/editGradeDialogue.tsx new file mode 100644 index 0000000..be299dd --- /dev/null +++ b/src/config/components/editGradeDialogue.tsx @@ -0,0 +1,79 @@ +import * as React from 'react'; +import Button from '@mui/material/Button'; +import Dialog from '@mui/material/Dialog'; +import DialogActions from '@mui/material/DialogActions'; +import DialogContent from '@mui/material/DialogContent'; +import DialogTitle from '@mui/material/DialogTitle'; +import TextField from '@mui/material/TextField'; +import { toast } from 'react-toastify'; +import { RootState } from '../../store'; +import { useSelector } from 'react-redux'; +import { useEditGradeMutation } from '../apiSlice'; +import { editGradeReq } from '../types'; + +interface IProps { + open: boolean; + setOpen: (value: boolean | ((prevVar: boolean) => boolean)) => void; + id: number; +} +export default function EditGradeDialog(props: IProps) { + + const authToken = useSelector((state: RootState) => state.loginStore.authToken); + + const handleClose = () => { + props.setOpen(false); + }; + + const [editGrade] = useEditGradeMutation(); + + return ( + + ) => { + event.preventDefault(); + const formData = new FormData(event.currentTarget); + const formJson = Object.fromEntries((formData as any).entries()); + const points = Number(formJson.points); + const req: editGradeReq = { + points: points, + id: props.id, + authToken: authToken + } + editGrade(req).unwrap().then(resp=>{ + toast.success(resp.message) + }).catch(err=>{ + console.log(err) + }) + handleClose(); + }, + }} + > + Edit grade points + + {/* + Are you sure you want to delete the appreciation? + */} + + + + + + + + + ); +} diff --git a/src/config/components/editRenewalFreqDialog.tsx b/src/config/components/editRenewalFreqDialog.tsx index 0cc82d3..23bcdcb 100644 --- a/src/config/components/editRenewalFreqDialog.tsx +++ b/src/config/components/editRenewalFreqDialog.tsx @@ -10,7 +10,6 @@ import { RootState } from '../../store'; import { useSelector } from 'react-redux'; import { useEditRenewalFrequencyMutation } from '../apiSlice'; import { editRenewalFrequencyReq } from '../types'; -import { number } from 'yup'; interface IProps { open: boolean; @@ -55,9 +54,6 @@ export default function EditRenewalFreqDialog(props: IProps) { > Edit renewal frequency - {/* - Enter new renewal frequency - */} boolean)) => void; + id: number; + setId: (value: number | ((prevVar: number) => number)) => void; } export default function GradesTable(props: IProps) { + const handleClickOpen = (id: number) => { + props.setId(id); + props.setOpen(true); + }; const [rows, setRows] = useState([]); useEffect(() => { + setRows([]); props.gradesList?.map((grade) => { setRows((prevData) => [ ...prevData, @@ -32,7 +40,7 @@ export default function GradesTable(props: IProps) { - Sr No + Sr No Grade Points @@ -48,9 +56,15 @@ export default function GradesTable(props: IProps) { {row.name} {row.points} - - - + { + handleClickOpen(row.id); + }} + sx={{cursor:"pointer"}} + > + + ))} diff --git a/src/config/components/orgConfig.tsx b/src/config/components/orgConfig.tsx index 2db0bde..f07a5a7 100644 --- a/src/config/components/orgConfig.tsx +++ b/src/config/components/orgConfig.tsx @@ -6,11 +6,11 @@ import TableRow from "@mui/material/TableRow"; import Paper from "@mui/material/Paper"; import { orgConfig } from "../types"; import { useEffect, useState } from "react"; -import BorderColorIcon from '@mui/icons-material/BorderColor'; +import BorderColorIcon from "@mui/icons-material/BorderColor"; function createData( - id: number | undefined , - reward_quota_renewal_frequency: number | undefined, + id: number | undefined, + reward_quota_renewal_frequency: number | undefined ) { return { id, reward_quota_renewal_frequency }; } @@ -20,7 +20,6 @@ interface IProps { setOpen: (value: boolean | ((prevVar: boolean) => boolean)) => void; } - export default function OrgConfigTable(props: IProps) { const handleClickOpen = () => { props.setOpen(true); @@ -37,17 +36,20 @@ export default function OrgConfigTable(props: IProps) { return (
- Reward quota renewal frequency - {row!=undefined && row.reward_quota_renewal_frequency!=undefined && row?.reward_quota_renewal_frequency <= 1 ? `${row?.reward_quota_renewal_frequency} month` : `${row?.reward_quota_renewal_frequency} months`} + {row != undefined && + row.reward_quota_renewal_frequency != undefined && + row?.reward_quota_renewal_frequency <= 1 + ? `${row?.reward_quota_renewal_frequency} month` + : `${row?.reward_quota_renewal_frequency} months`} - - + + diff --git a/src/config/index.tsx b/src/config/index.tsx index a4480d4..edc1222 100644 --- a/src/config/index.tsx +++ b/src/config/index.tsx @@ -8,6 +8,7 @@ import GradesTable from "./components/grades"; import OrgConfigTable from "./components/orgConfig"; import EditRenewalFreqDialog from "./components/editRenewalFreqDialog"; import { useState } from "react"; +import EditGradeDialog from "./components/editGradeDialogue"; const Config = () => { const authToken = useSelector((state: RootState) => state.loginStore.authToken); @@ -17,17 +18,20 @@ const Config = () => { const {data: orgConfigResp, isError: getOrgConfigError} = useGetOrgConfigQuery({ authToken: authToken }); - const [open, setOpen] = useState(false); + const [openEditFrequency, setOpenEditFrequency] = useState(false); + const [openEditGrade, setOpenEditGrade] = useState(false); + const [id,setId] = useState(0); return ( <> Quaters Grades - {!listGradesError ? : <>} + {!listGradesError ? : <>} Organisation Config - {!getOrgConfigError ? : <>} - + {!getOrgConfigError ? : <>} + + ); }; diff --git a/src/config/types.tsx b/src/config/types.tsx index 8e9c2b0..5f009d7 100644 --- a/src/config/types.tsx +++ b/src/config/types.tsx @@ -34,3 +34,15 @@ export interface editRenewalFrequencyResp { status_code: number; data: orgConfig; } + +export interface editGradeReq { + id: number; + points: number; + authToken: string; +} + +export interface editGradeResp { + success: string; + message: string; + status_code: number; +} From e45bc7ef2f1aaa0d8739b5c9451729e168fc8f13 Mon Sep 17 00:00:00 2001 From: Sharyu Marwadi Date: Wed, 7 Aug 2024 13:07:23 +0530 Subject: [PATCH 07/23] [feature/PEER-57-Config] useEffect fixes --- src/config/index.tsx | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/config/index.tsx b/src/config/index.tsx index edc1222..e3821fc 100644 --- a/src/config/index.tsx +++ b/src/config/index.tsx @@ -7,10 +7,12 @@ import { RootState } from "../store"; import GradesTable from "./components/grades"; import OrgConfigTable from "./components/orgConfig"; import EditRenewalFreqDialog from "./components/editRenewalFreqDialog"; -import { useState } from "react"; +import { useEffect, useState } from "react"; import EditGradeDialog from "./components/editGradeDialogue"; +import { useNavigate } from "react-router-dom"; const Config = () => { + const navigate = useNavigate() const authToken = useSelector((state: RootState) => state.loginStore.authToken); const {data: gradesResp, isError: listGradesError} = useGetGradesQuery({ authToken: authToken @@ -21,6 +23,14 @@ const Config = () => { const [openEditFrequency, setOpenEditFrequency] = useState(false); const [openEditGrade, setOpenEditGrade] = useState(false); const [id,setId] = useState(0); + useEffect(()=>{ + console.log("authtoken -> ",authToken) + if(authToken === ""){ + navigate("/login") + }else{ + navigate("/config") + } + },[authToken]) return ( <> From 5ec6c89d4fca170aaa0cf4305952bfba61952a75 Mon Sep 17 00:00:00 2001 From: Sharyu Marwadi Date: Wed, 7 Aug 2024 13:08:34 +0530 Subject: [PATCH 08/23] [feature/PEER-53-Badges] badges table don --- src/App.tsx | 5 ++ src/badges/apiSlice.tsx | 41 ++++++++++++++ src/badges/components/dialogueBox.tsx | 79 +++++++++++++++++++++++++++ src/badges/components/table.tsx | 75 +++++++++++++++++++++++++ src/badges/index.tsx | 38 +++++++++++++ src/badges/types.tsx | 25 +++++++++ src/sideBar/index.tsx | 2 +- src/store.tsx | 4 +- 8 files changed, 267 insertions(+), 2 deletions(-) create mode 100644 src/badges/apiSlice.tsx create mode 100644 src/badges/components/dialogueBox.tsx create mode 100644 src/badges/components/table.tsx create mode 100644 src/badges/index.tsx create mode 100644 src/badges/types.tsx diff --git a/src/App.tsx b/src/App.tsx index 3a7eb73..bec6769 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -8,6 +8,7 @@ import { getAuthToken } from "./login/slice"; import { useEffect } from "react"; import Home from "./home"; import Config from "./config"; +import Badges from "./badges"; function App() { const router = createBrowserRouter([ @@ -27,6 +28,10 @@ function App() { path: "/config", element: , }, + { + path: "/badges", + element: , + }, ]); const dispatch = useDispatch(); diff --git a/src/badges/apiSlice.tsx b/src/badges/apiSlice.tsx new file mode 100644 index 0000000..e3b2424 --- /dev/null +++ b/src/badges/apiSlice.tsx @@ -0,0 +1,41 @@ +import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react"; +import { badgesResponse, editBadgeReq, editBadgeResp } from "./types"; + +export const badgesSlice = createApi({ + reducerPath: "badgesSlice", + baseQuery: fetchBaseQuery({ + baseUrl: "http://localhost:33001/peerly", + }), + tagTypes: ["badges"], + endpoints: (builder) => ({ + getBadges: builder.query({ + query: ({ authToken }) => ({ + url: "/badges", + method: "GET", + headers: { + "Accept-Version": "application/vnd.peerly.v1", + Authorization: `Bearer ${authToken}`, + }, + }), + providesTags: ["badges"], + }), + editBadge: builder.mutation>({ + query: (payload) => ({ + url: `/badges/${payload.id}`, + method: "PATCH", + body: { reward_points: payload.reward_points}, + headers: { + "Content-type": "application/json; charset=UTF-8", + "Accept-Version": "application/vnd.peerly.v1", + Authorization: `Bearer ${payload.authToken}`, + }, + }), + invalidatesTags: () => [{ type: "badges" }], + }), + }), +}); + +export const { + useGetBadgesQuery, + useEditBadgeMutation +} = badgesSlice; diff --git a/src/badges/components/dialogueBox.tsx b/src/badges/components/dialogueBox.tsx new file mode 100644 index 0000000..f444fd5 --- /dev/null +++ b/src/badges/components/dialogueBox.tsx @@ -0,0 +1,79 @@ +import * as React from 'react'; +import Button from '@mui/material/Button'; +import Dialog from '@mui/material/Dialog'; +import DialogActions from '@mui/material/DialogActions'; +import DialogContent from '@mui/material/DialogContent'; +import DialogTitle from '@mui/material/DialogTitle'; +import TextField from '@mui/material/TextField'; +import { toast } from 'react-toastify'; +import { RootState } from '../../store'; +import { useSelector } from 'react-redux'; +import { useEditBadgeMutation } from '../apiSlice'; +import { editBadgeReq } from '../types'; + +interface IProps { + open: boolean; + setOpen: (value: boolean | ((prevVar: boolean) => boolean)) => void; + id: number; +} +export default function EditBadgeDialog(props: IProps) { + + const authToken = useSelector((state: RootState) => state.loginStore.authToken); + + const handleClose = () => { + props.setOpen(false); + }; + + const [editBadge] = useEditBadgeMutation(); + + return ( + + ) => { + event.preventDefault(); + const formData = new FormData(event.currentTarget); + const formJson = Object.fromEntries((formData as any).entries()); + const reward_points = Number(formJson.reward_points); + const req: editBadgeReq = { + reward_points: reward_points, + id: props.id, + authToken: authToken + } + editBadge(req).unwrap().then(resp=>{ + toast.success(resp.message) + }).catch(err=>{ + console.log(err) + }) + handleClose(); + }, + }} + > + Edit grade points + + {/* + Are you sure you want to delete the appreciation? + */} + + + + + + + + + ); +} diff --git a/src/badges/components/table.tsx b/src/badges/components/table.tsx new file mode 100644 index 0000000..7fc3566 --- /dev/null +++ b/src/badges/components/table.tsx @@ -0,0 +1,75 @@ +import Table from "@mui/material/Table"; +import TableBody from "@mui/material/TableBody"; +import TableCell from "@mui/material/TableCell"; +import TableContainer from "@mui/material/TableContainer"; +import TableHead from "@mui/material/TableHead"; +import TableRow from "@mui/material/TableRow"; +import Paper from "@mui/material/Paper"; +import { useEffect, useState } from "react"; +import BorderColorIcon from "@mui/icons-material/BorderColor"; +import { badge } from "../types"; + +function createData(id: number, name: string, reward_points: number) { + return { id, name, reward_points }; +} + +interface IProps { + badgeList: badge[] | undefined; + setOpen: (value: boolean | ((prevVar: boolean) => boolean)) => void; + id: number; + setId: (value: number | ((prevVar: number) => number)) => void; +} + +export default function BadgesTable(props: IProps) { + const handleClickOpen = (id: number) => { + props.setId(id); + props.setOpen(true); + }; + const [rows, setRows] = useState([]); + useEffect(() => { + setRows([]); + props.badgeList?.map((badge) => { + setRows((prevData) => [ + ...prevData, + createData(badge.id, badge.name, badge.reward_points), + ]); + }); + }, [props.badgeList]); + return ( + +
+ + + Sr No + Badge + Reward Points + + + + + {rows.map((row) => ( + + + {row.id} + + {row.name} + {row.reward_points} + { + handleClickOpen(row.id); + }} + sx={{cursor:"pointer"}} + > + + + + ))} + +
+ + ); +} diff --git a/src/badges/index.tsx b/src/badges/index.tsx new file mode 100644 index 0000000..7ef2a8d --- /dev/null +++ b/src/badges/index.tsx @@ -0,0 +1,38 @@ +import { Typography } from "@mui/material"; +import TemporaryDrawer from "../sideBar"; +import { useSelector } from "react-redux"; +import { RootState } from "../store"; +import { useEffect, useState } from "react"; +import { useNavigate } from "react-router-dom"; +import { useGetBadgesQuery } from "./apiSlice"; +import BadgesTable from "./components/table"; +import EditBadgeDialog from "./components/dialogueBox"; + +const Badges = () => { + const navigate = useNavigate() + const authToken = useSelector((state: RootState) => state.loginStore.authToken); + const {data: badgesResp, isError: listBadgesError} = useGetBadgesQuery({ + authToken: authToken + }); + const [open, setOpen] = useState(false); + const [id,setId] = useState(0); + useEffect(()=>{ + console.log("authtoken -> ",authToken) + if(authToken === ""){ + navigate("/login") + }else{ + navigate("/badges") + } + },[authToken]) + return ( + <> + + Badges + {!listBadgesError ? : <>} + + + + ); +}; + +export default Badges; diff --git a/src/badges/types.tsx b/src/badges/types.tsx new file mode 100644 index 0000000..2fb108a --- /dev/null +++ b/src/badges/types.tsx @@ -0,0 +1,25 @@ +export interface badge { + id: number; + name: string; + reward_points: number; + } + + export interface badgesResponse { + success: boolean; + message: string; + status_code: number; + data: badge[]; + } + + export interface editBadgeReq { + id: number; + reward_points: number; + authToken: string; + } + + export interface editBadgeResp { + success: string; + message: string; + status_code: number; + } + \ No newline at end of file diff --git a/src/sideBar/index.tsx b/src/sideBar/index.tsx index 9a572f4..af1ab1c 100644 --- a/src/sideBar/index.tsx +++ b/src/sideBar/index.tsx @@ -27,7 +27,7 @@ export default function TemporaryDrawer() { }; const iconList = [, , , , ] - const routeList = ['/', '/appreciations', '/', '/', '/config'] + const routeList = ['/', '/appreciations', '/badges', '/', '/config'] const dispatch = useDispatch(); const setRoute = (index: number) => () => { dispatch(getRoute(routeList[index])); diff --git a/src/store.tsx b/src/store.tsx index 115779e..49e89dd 100644 --- a/src/store.tsx +++ b/src/store.tsx @@ -5,6 +5,7 @@ import { appreciationSlice } from './appreciations/apiSlice'; import loginReducer from './login/slice'; import sidebarReducer from './sideBar/slice.tsx'; import { configSlice } from './config/apiSlice.tsx'; +import { badgesSlice } from './badges/apiSlice.tsx'; export const store = configureStore({ @@ -16,12 +17,13 @@ export const store = configureStore({ [loginApiSlice.reducerPath]: loginApiSlice.reducer, [appreciationSlice.reducerPath]: appreciationSlice.reducer, [configSlice.reducerPath]: configSlice.reducer, + [badgesSlice.reducerPath]: badgesSlice.reducer, }, middleware: (getDefaultMiddleware) => - getDefaultMiddleware().concat(loginApiSlice.middleware).concat(appreciationSlice.middleware).concat(configSlice.middleware) + getDefaultMiddleware().concat(loginApiSlice.middleware).concat(appreciationSlice.middleware).concat(configSlice.middleware).concat(badgesSlice.middleware) }); From 818f8d51c88aa7db126aa1e3dbae044cb1efd569 Mon Sep 17 00:00:00 2001 From: Sharyu Marwadi Date: Thu, 8 Aug 2024 17:58:20 +0530 Subject: [PATCH 09/23] [feature/PEER-53-Badges] css fixed --- src/App.tsx | 1 + src/appreciations/components/table.tsx | 12 +- src/appreciations/components/toggleButton.tsx | 3 +- src/appreciations/index.tsx | 6 +- src/appreciations/types.tsx | 1 + src/badges/index.tsx | 10 +- src/config/index.tsx | 199 ++++++++++++++++-- src/home/index.tsx | 6 +- src/permanentSidebar/index.tsx | 74 +++++++ src/sideBar/index.tsx | 1 - 10 files changed, 276 insertions(+), 37 deletions(-) create mode 100644 src/permanentSidebar/index.tsx diff --git a/src/App.tsx b/src/App.tsx index bec6769..801da49 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -46,6 +46,7 @@ function App() { useEffect(() => { sendData(); }, []); + return ( <> diff --git a/src/appreciations/components/table.tsx b/src/appreciations/components/table.tsx index 0b3118d..fa9ecf8 100644 --- a/src/appreciations/components/table.tsx +++ b/src/appreciations/components/table.tsx @@ -242,6 +242,7 @@ function EnhancedTableHead(props: EnhancedTableProps) { active={orderBy === headCell.id} direction={orderBy === headCell.id ? order : "asc"} onClick={createSortHandler(headCell.id)} + sx={props.filter =="reported" ? (headCell.id == "isValid"|| headCell.id == "rewardPoints" ? {width: "120px"} : {width: "160px"}) : {}} > {headCell.label} {orderBy === headCell.id ? ( @@ -260,11 +261,13 @@ function EnhancedTableHead(props: EnhancedTableProps) { interface EnhancedTableToolbarProps { numSelected: number; setFilter: (value: string | ((prevVar: string) => string)) => void; + setPage: (value: number | ((prevVar: number) => number)) => void; } function EnhancedTableToolbar(props: EnhancedTableToolbarProps) { return ( - + ); @@ -290,7 +293,7 @@ export default function AppreciationTable(props: IPropsTable) { const [orderBy, setOrderBy] = useState("date"); const [selected, setSelected] = useState([]); const [page, setPage] = useState(0); - const [rowsPerPage, setRowsPerPage] = useState(5); + const [rowsPerPage, setRowsPerPage] = useState(8); const [rows, setRows] = useState([]); useEffect(() => { @@ -391,11 +394,12 @@ export default function AppreciationTable(props: IPropsTable) { const [id, setId] = useState(0); return ( - + { setAlignment(newAlignment); - props.setFilter(newAlignment) + props.setFilter(newAlignment); + props.setPage(0) }; return ( diff --git a/src/appreciations/index.tsx b/src/appreciations/index.tsx index e301294..1bf6873 100644 --- a/src/appreciations/index.tsx +++ b/src/appreciations/index.tsx @@ -5,6 +5,7 @@ import { useSelector } from "react-redux"; import { RootState } from "../store"; import { useNavigate } from "react-router-dom"; import TemporaryDrawer from "../sideBar"; +import PermanentDrawerLeft from "../permanentSidebar"; const Appreciations = () => { const navigate = useNavigate() @@ -38,11 +39,12 @@ const Appreciations = () => { return ( <> - + {/* */} {listAppreciationsError || listReportedAppreciationsError ? (

Error

) : ( - + } /> + )} ); diff --git a/src/appreciations/types.tsx b/src/appreciations/types.tsx index 80f350a..81f12a6 100644 --- a/src/appreciations/types.tsx +++ b/src/appreciations/types.tsx @@ -56,6 +56,7 @@ export interface IPropsTable { export interface IPropsButtons{ setFilter: (value: string | ((prevVar: string) => string)) => void; + setPage: (value: number | ((prevVar: number) => number)) => void; } export interface moderationReq{ diff --git a/src/badges/index.tsx b/src/badges/index.tsx index 7ef2a8d..c0fea47 100644 --- a/src/badges/index.tsx +++ b/src/badges/index.tsx @@ -7,8 +7,9 @@ import { useNavigate } from "react-router-dom"; import { useGetBadgesQuery } from "./apiSlice"; import BadgesTable from "./components/table"; import EditBadgeDialog from "./components/dialogueBox"; +import PermanentDrawerLeft from "../permanentSidebar"; -const Badges = () => { +const BadgesComponent = () => { const navigate = useNavigate() const authToken = useSelector((state: RootState) => state.loginStore.authToken); const {data: badgesResp, isError: listBadgesError} = useGetBadgesQuery({ @@ -26,7 +27,6 @@ const Badges = () => { },[authToken]) return ( <> - Badges {!listBadgesError ? : <>} @@ -35,4 +35,10 @@ const Badges = () => { ); }; +const Badges = () => { + return( + } /> + ) +} + export default Badges; diff --git a/src/config/index.tsx b/src/config/index.tsx index e3821fc..7fe3406 100644 --- a/src/config/index.tsx +++ b/src/config/index.tsx @@ -10,40 +10,193 @@ import EditRenewalFreqDialog from "./components/editRenewalFreqDialog"; import { useEffect, useState } from "react"; import EditGradeDialog from "./components/editGradeDialogue"; import { useNavigate } from "react-router-dom"; +import PermanentDrawerLeft from "../permanentSidebar"; -const Config = () => { - const navigate = useNavigate() - const authToken = useSelector((state: RootState) => state.loginStore.authToken); - const {data: gradesResp, isError: listGradesError} = useGetGradesQuery({ - authToken: authToken - }); - const {data: orgConfigResp, isError: getOrgConfigError} = useGetOrgConfigQuery({ - authToken: authToken +const ConfigComponent = () => { + const navigate = useNavigate(); + const authToken = useSelector( + (state: RootState) => state.loginStore.authToken + ); + const { data: gradesResp, isError: listGradesError } = useGetGradesQuery({ + authToken: authToken, }); + const { data: orgConfigResp, isError: getOrgConfigError } = + useGetOrgConfigQuery({ + authToken: authToken, + }); const [openEditFrequency, setOpenEditFrequency] = useState(false); const [openEditGrade, setOpenEditGrade] = useState(false); - const [id,setId] = useState(0); - useEffect(()=>{ - console.log("authtoken -> ",authToken) - if(authToken === ""){ - navigate("/login") - }else{ - navigate("/config") + const [id, setId] = useState(0); + useEffect(() => { + console.log("authtoken -> ", authToken); + if (authToken === "") { + navigate("/login"); + } else { + navigate("/config"); } - },[authToken]) + }, [authToken]); return ( <> - Quaters - Grades - {!listGradesError ? : <>} - Organisation Config - {!getOrgConfigError ? : <>} - - + + Grades + + {!listGradesError ? ( + + ) : ( + <> + )} + + Organisation Config + + {!getOrgConfigError ? ( + + ) : ( + <> + )} + + ); }; + + + + +import * as React from "react"; +import Tabs from "@mui/material/Tabs"; +import Tab from "@mui/material/Tab"; +import Box from "@mui/material/Box"; + +interface TabPanelProps { + children?: React.ReactNode; + index: number; + value: number; +} + +function CustomTabPanel(props: TabPanelProps) { + const { children, value, index, ...other } = props; + + return ( + + ); +} + +function a11yProps(index: number) { + return { + id: `simple-tab-${index}`, + "aria-controls": `simple-tabpanel-${index}`, + }; +} + +export function ConfigTabs() { + const [value, setValue] = useState(0); + + const handleChange = (event: React.SyntheticEvent, newValue: number) => { + setValue(newValue); + }; + + const navigate = useNavigate(); + const authToken = useSelector( + (state: RootState) => state.loginStore.authToken + ); + const { data: gradesResp, isError: listGradesError } = useGetGradesQuery({ + authToken: authToken, + }); + const { data: orgConfigResp, isError: getOrgConfigError } = + useGetOrgConfigQuery({ + authToken: authToken, + }); + const [openEditFrequency, setOpenEditFrequency] = useState(false); + const [openEditGrade, setOpenEditGrade] = useState(false); + const [id, setId] = useState(0); + useEffect(() => { + console.log("authtoken -> ", authToken); + if (authToken === "") { + navigate("/login"); + } else { + navigate("/config"); + } + }, [authToken]); + + return ( + + + + + + + + + + + + + {!listGradesError ? ( + + ) : ( + <> + )} + + + {!getOrgConfigError ? ( + + ) : ( + <> + )} + + + + + ); +} + +const Config = () => { + return } />; +}; + export default Config; diff --git a/src/home/index.tsx b/src/home/index.tsx index b7f35b1..5fb1a56 100644 --- a/src/home/index.tsx +++ b/src/home/index.tsx @@ -1,10 +1,8 @@ -import TemporaryDrawer from "../sideBar" +import PermanentDrawerLeft from "../permanentSidebar" const Home = () => { return( - <> - - home + Home}/> ) } diff --git a/src/permanentSidebar/index.tsx b/src/permanentSidebar/index.tsx new file mode 100644 index 0000000..db5dbfd --- /dev/null +++ b/src/permanentSidebar/index.tsx @@ -0,0 +1,74 @@ +import Box from "@mui/material/Box"; +import Drawer from "@mui/material/Drawer"; +import List from "@mui/material/List"; +import ListItem from "@mui/material/ListItem"; +import ListItemButton from "@mui/material/ListItemButton"; +import ListItemIcon from "@mui/material/ListItemIcon"; +import ListItemText from "@mui/material/ListItemText"; +import DashboardIcon from '@mui/icons-material/Dashboard'; +import PostAddIcon from '@mui/icons-material/PostAdd'; +import LocalPoliceIcon from '@mui/icons-material/LocalPolice'; +import DiamondIcon from '@mui/icons-material/Diamond'; +import AssuredWorkloadIcon from '@mui/icons-material/AssuredWorkload'; +import { useDispatch } from "react-redux"; +import { getRoute } from "../sideBar/slice"; +import { useNavigate } from "react-router-dom"; + +const drawerWidth = 200; + +interface IProps { + component: any +} + +export default function PermanentDrawerLeft(props: IProps) { + const iconList = [ + , + , + , + , + , + ]; + const routeList = ["/", "/appreciations", "/badges", "/", "/config"]; + const dispatch = useDispatch(); + const navigate = useNavigate(); + const setRoute = (index: number) => () => { + dispatch(getRoute(routeList[index])); + navigate(routeList[index]); + }; + return ( + + + + {["Dashboard", "Appreciations", "Badges", "Corevalues", "Config"].map( + (text, index) => ( + + + {iconList[index]} + + + + ) + )} + + + + + {props.component} + + + ); +} diff --git a/src/sideBar/index.tsx b/src/sideBar/index.tsx index af1ab1c..03c986f 100644 --- a/src/sideBar/index.tsx +++ b/src/sideBar/index.tsx @@ -7,7 +7,6 @@ import ListItem from '@mui/material/ListItem'; import ListItemButton from '@mui/material/ListItemButton'; import ListItemIcon from '@mui/material/ListItemIcon'; import ListItemText from '@mui/material/ListItemText'; -import MoreVertIcon from '@mui/icons-material/MoreVert'; import DashboardIcon from '@mui/icons-material/Dashboard'; import PostAddIcon from '@mui/icons-material/PostAdd'; import LocalPoliceIcon from '@mui/icons-material/LocalPolice'; From 91ff4decd60eb7193d3f3de46cdc493526257d05 Mon Sep 17 00:00:00 2001 From: Sharyu Marwadi Date: Sun, 11 Aug 2024 12:50:45 +0530 Subject: [PATCH 10/23] [feature/PEER-53-Badges] core values completed --- src/App.tsx | 5 +++ src/coreValues/apiSlice.tsx | 27 ++++++++++++++ src/coreValues/components/table.tsx | 58 +++++++++++++++++++++++++++++ src/coreValues/index.tsx | 38 +++++++++++++++++++ src/coreValues/types.tsx | 13 +++++++ src/permanentSidebar/index.tsx | 2 +- src/sideBar/index.tsx | 3 +- src/store.tsx | 4 +- 8 files changed, 146 insertions(+), 4 deletions(-) create mode 100644 src/coreValues/apiSlice.tsx create mode 100644 src/coreValues/components/table.tsx create mode 100644 src/coreValues/index.tsx create mode 100644 src/coreValues/types.tsx diff --git a/src/App.tsx b/src/App.tsx index 801da49..e8d53cd 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -9,6 +9,7 @@ import { useEffect } from "react"; import Home from "./home"; import Config from "./config"; import Badges from "./badges"; +import CoreValues from "./coreValues"; function App() { const router = createBrowserRouter([ @@ -32,6 +33,10 @@ function App() { path: "/badges", element: , }, + { + path: "/core_values", + element: , + }, ]); const dispatch = useDispatch(); diff --git a/src/coreValues/apiSlice.tsx b/src/coreValues/apiSlice.tsx new file mode 100644 index 0000000..df36fff --- /dev/null +++ b/src/coreValues/apiSlice.tsx @@ -0,0 +1,27 @@ +import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react"; +import { coreValuesResp } from "./types"; + +export const coreValueSlice = createApi({ + reducerPath: "coreValueSlice", + baseQuery: fetchBaseQuery({ + baseUrl: "http://localhost:33001/peerly", + }), + tagTypes: ["coreValues"], + endpoints: (builder) => ({ + getCoreValues: builder.query({ + query: ({ authToken }) => ({ + url: "/core_values", + method: "GET", + headers: { + "Accept-Version": "application/vnd.peerly.v1", + Authorization: `Bearer ${authToken}`, + }, + }), + providesTags: ["coreValues"], + }), + }), +}); + +export const { + useGetCoreValuesQuery +} = coreValueSlice; diff --git a/src/coreValues/components/table.tsx b/src/coreValues/components/table.tsx new file mode 100644 index 0000000..0348e87 --- /dev/null +++ b/src/coreValues/components/table.tsx @@ -0,0 +1,58 @@ +import Table from "@mui/material/Table"; +import TableBody from "@mui/material/TableBody"; +import TableCell from "@mui/material/TableCell"; +import TableContainer from "@mui/material/TableContainer"; +import TableHead from "@mui/material/TableHead"; +import TableRow from "@mui/material/TableRow"; +import Paper from "@mui/material/Paper"; +import { useEffect, useState } from "react"; +import { coreValue } from "../types"; + +function createData(id: number, name: string, description: string, parent_id: number) { + return { id, name, description, parent_id }; +} + +interface IProps { + coreValueList: coreValue[] | undefined; +} + +export default function CoreValuesTable(props: IProps) { + const [rows, setRows] = useState([]); + useEffect(() => { + console.log("corevaluelist -> ",props.coreValueList) + setRows([]); + props.coreValueList?.map((coreValue) => { + setRows((prevData) => [ + ...prevData, + createData(coreValue.id, coreValue.name, coreValue.description, coreValue.parent_id), + ]); + }); + }, [props.coreValueList]); + return ( + +
+ + + Sr No + CoreValue + Description + + + + {rows.map((row) => ( + + + {row.id} + + {row.name} + {row.description} + + ))} + +
+
+ ); +} diff --git a/src/coreValues/index.tsx b/src/coreValues/index.tsx new file mode 100644 index 0000000..425dd36 --- /dev/null +++ b/src/coreValues/index.tsx @@ -0,0 +1,38 @@ +import { Typography } from "@mui/material"; +import { useSelector } from "react-redux"; +import { RootState } from "../store"; +import { useEffect } from "react"; +import { useNavigate } from "react-router-dom"; +import PermanentDrawerLeft from "../permanentSidebar"; +import CoreValuesTable from "./components/table"; +import { useGetCoreValuesQuery } from "./apiSlice"; + +const CoreValuesComponent = () => { + const navigate = useNavigate() + const authToken = useSelector((state: RootState) => state.loginStore.authToken); + const {data: coreValueResp, isError: listCoreValuesError} = useGetCoreValuesQuery({ + authToken: authToken + }); + useEffect(()=>{ + console.log("authtoken -> ",authToken) + if(authToken === ""){ + navigate("/login") + }else{ + navigate("/core_values") + } + },[authToken]) + return ( + <> + Core Values + {!listCoreValuesError ? : <>} + + ); +}; + +const CoreValues = () => { + return( + } /> + ) +} + +export default CoreValues; diff --git a/src/coreValues/types.tsx b/src/coreValues/types.tsx new file mode 100644 index 0000000..c32ba7f --- /dev/null +++ b/src/coreValues/types.tsx @@ -0,0 +1,13 @@ +export interface coreValue { + id: number; + name: string; + description: string; + parent_id: number; +} + +export interface coreValuesResp { + success: boolean; + message: string; + status_code: number; + data: coreValue[]; +} diff --git a/src/permanentSidebar/index.tsx b/src/permanentSidebar/index.tsx index db5dbfd..1d13ff0 100644 --- a/src/permanentSidebar/index.tsx +++ b/src/permanentSidebar/index.tsx @@ -28,7 +28,7 @@ export default function PermanentDrawerLeft(props: IProps) { , , ]; - const routeList = ["/", "/appreciations", "/badges", "/", "/config"]; + const routeList = ["/", "/appreciations", "/badges", "/core_values", "/config"]; const dispatch = useDispatch(); const navigate = useNavigate(); const setRoute = (index: number) => () => { diff --git a/src/sideBar/index.tsx b/src/sideBar/index.tsx index 03c986f..8e0d906 100644 --- a/src/sideBar/index.tsx +++ b/src/sideBar/index.tsx @@ -26,7 +26,7 @@ export default function TemporaryDrawer() { }; const iconList = [, , , , ] - const routeList = ['/', '/appreciations', '/badges', '/', '/config'] + const routeList = ['/', '/appreciations', '/badges', '/core_values', '/config'] const dispatch = useDispatch(); const setRoute = (index: number) => () => { dispatch(getRoute(routeList[index])); @@ -49,7 +49,6 @@ export default function TemporaryDrawer() { ))} - {/* */}
); diff --git a/src/store.tsx b/src/store.tsx index 49e89dd..5d3d921 100644 --- a/src/store.tsx +++ b/src/store.tsx @@ -6,6 +6,7 @@ import loginReducer from './login/slice'; import sidebarReducer from './sideBar/slice.tsx'; import { configSlice } from './config/apiSlice.tsx'; import { badgesSlice } from './badges/apiSlice.tsx'; +import { coreValueSlice } from './coreValues/apiSlice.tsx'; export const store = configureStore({ @@ -18,12 +19,13 @@ export const store = configureStore({ [appreciationSlice.reducerPath]: appreciationSlice.reducer, [configSlice.reducerPath]: configSlice.reducer, [badgesSlice.reducerPath]: badgesSlice.reducer, + [coreValueSlice.reducerPath]: coreValueSlice.reducer, }, middleware: (getDefaultMiddleware) => - getDefaultMiddleware().concat(loginApiSlice.middleware).concat(appreciationSlice.middleware).concat(configSlice.middleware).concat(badgesSlice.middleware) + getDefaultMiddleware().concat(loginApiSlice.middleware).concat(appreciationSlice.middleware).concat(configSlice.middleware).concat(badgesSlice.middleware).concat(coreValueSlice.middleware) }); From e306a3c2aa47b8df12e70fb44856191ac4eafc78 Mon Sep 17 00:00:00 2001 From: Sharyu Marwadi Date: Mon, 12 Aug 2024 11:30:15 +0530 Subject: [PATCH 11/23] [feature/Dashboard] report download done --- package-lock.json | 6 ++ package.json | 1 + src/appreciations/index.tsx | 1 - src/home/apiSlice.tsx | 28 +++++++++ src/home/components/appreciationCountCard.tsx | 25 ++++++++ src/home/components/downloadExcel.tsx | 59 +++++++++++++++++++ src/home/components/sendNotificationCard.tsx | 37 ++++++++++++ src/home/index.tsx | 41 +++++++++++-- src/home/types.tsx | 10 ++++ src/store.tsx | 5 +- 10 files changed, 204 insertions(+), 9 deletions(-) create mode 100644 src/home/apiSlice.tsx create mode 100644 src/home/components/appreciationCountCard.tsx create mode 100644 src/home/components/downloadExcel.tsx create mode 100644 src/home/components/sendNotificationCard.tsx create mode 100644 src/home/types.tsx diff --git a/package-lock.json b/package-lock.json index 7df1054..6710e7d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,6 +14,7 @@ "@mui/material": "^5.16.5", "@reduxjs/toolkit": "^2.2.7", "formik": "^2.4.6", + "js-file-download": "^0.4.12", "react": "^18.3.1", "react-dom": "^18.3.1", "react-redux": "^9.1.2", @@ -3002,6 +3003,11 @@ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", "dev": true }, + "node_modules/js-file-download": { + "version": "0.4.12", + "resolved": "https://registry.npmjs.org/js-file-download/-/js-file-download-0.4.12.tgz", + "integrity": "sha512-rML+NkoD08p5Dllpjo0ffy4jRHeY6Zsapvr/W86N7E0yuzAO6qa5X9+xog6zQNlH102J7IXljNY2FtS6Lj3ucg==" + }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", diff --git a/package.json b/package.json index 457decb..c0cec98 100644 --- a/package.json +++ b/package.json @@ -16,6 +16,7 @@ "@mui/material": "^5.16.5", "@reduxjs/toolkit": "^2.2.7", "formik": "^2.4.6", + "js-file-download": "^0.4.12", "react": "^18.3.1", "react-dom": "^18.3.1", "react-redux": "^9.1.2", diff --git a/src/appreciations/index.tsx b/src/appreciations/index.tsx index 1bf6873..edaf287 100644 --- a/src/appreciations/index.tsx +++ b/src/appreciations/index.tsx @@ -4,7 +4,6 @@ import { useEffect, useMemo, useState } from "react"; import { useSelector } from "react-redux"; import { RootState } from "../store"; import { useNavigate } from "react-router-dom"; -import TemporaryDrawer from "../sideBar"; import PermanentDrawerLeft from "../permanentSidebar"; const Appreciations = () => { diff --git a/src/home/apiSlice.tsx b/src/home/apiSlice.tsx new file mode 100644 index 0000000..8fd168f --- /dev/null +++ b/src/home/apiSlice.tsx @@ -0,0 +1,28 @@ +import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react"; + +export const homeSlice = createApi({ + reducerPath: "homeSlice", + baseQuery: fetchBaseQuery({ + baseUrl: "http://localhost:33001/peerly", + }), + tagTypes: ["downloadReport"], + endpoints: (builder) => ({ + downloadReport: builder.query({ + query: ({authToken}) => ({ + url: "/admin/report", + method: "GET", + headers: { + // "Accept-Version": "application/vnd.peerly.v1", + Authorization: `Bearer ${authToken}`, + }, + responseHandler: (response) => response.arrayBuffer(), + }), + // transformResponse: (response: Blob) => response, + + }), + }), +}); + +export const { + useDownloadReportQuery +} = homeSlice; diff --git a/src/home/components/appreciationCountCard.tsx b/src/home/components/appreciationCountCard.tsx new file mode 100644 index 0000000..cae3959 --- /dev/null +++ b/src/home/components/appreciationCountCard.tsx @@ -0,0 +1,25 @@ +import Card from "@mui/material/Card"; +import CardContent from "@mui/material/CardContent"; +import Typography from "@mui/material/Typography"; +import { CardActionArea } from "@mui/material"; + +interface IProps{ + count : number | undefined +} + +export default function AppreciationCountCard(props: IProps) { + return ( + + + + + {props.count} + + + Appreciation count for the quater + + + + + ); +} diff --git a/src/home/components/downloadExcel.tsx b/src/home/components/downloadExcel.tsx new file mode 100644 index 0000000..c9cbbf6 --- /dev/null +++ b/src/home/components/downloadExcel.tsx @@ -0,0 +1,59 @@ +import Box from "@mui/material/Box"; +import Card from "@mui/material/Card"; +import CardActions from "@mui/material/CardActions"; +import CardContent from "@mui/material/CardContent"; +import Button from "@mui/material/Button"; +import Typography from "@mui/material/Typography"; +import { useSelector } from "react-redux"; +import { RootState } from "../../store"; +import { useState } from "react"; +import { useDownloadReportQuery } from "../apiSlice"; + +const bull = ( + + • + +); + +export default function DownloadExcelCard() { + const authToken = useSelector((state: RootState) => state.loginStore.authToken); + const { data, error, isLoading } = useDownloadReportQuery({authToken}); + const handleClick = () => { + console.log("data -> ",data) + if (data) { + // Create a URL for the Blob + const blob = new Blob([data], { type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" }); + + // Create a link element and trigger a download + const url = window.URL.createObjectURL(blob); + const a = document.createElement("a"); + a.href = url; + a.download = "report.xlsx"; // Set the desired filename + document.body.appendChild(a); + a.click(); + document.body.removeChild(a); + window.URL.revokeObjectURL(url); + } else if (error) { + console.error("Error downloading the report:", error); + } + }; + return ( + + + + + Download report for the quarter in excel format + + + + + + + + ); +} diff --git a/src/home/components/sendNotificationCard.tsx b/src/home/components/sendNotificationCard.tsx new file mode 100644 index 0000000..6f53ed8 --- /dev/null +++ b/src/home/components/sendNotificationCard.tsx @@ -0,0 +1,37 @@ +import * as React from 'react'; +import Box from '@mui/material/Box'; +import Card from '@mui/material/Card'; +import CardActions from '@mui/material/CardActions'; +import CardContent from '@mui/material/CardContent'; +import Button from '@mui/material/Button'; +import Typography from '@mui/material/Typography'; + +const bull = ( + + • + +); + +const card = ( + + + + Send a notification + + + + + + +); + +export default function NotificationCard() { + return ( + + {card} + + ); +} diff --git a/src/home/index.tsx b/src/home/index.tsx index 5fb1a56..a67c396 100644 --- a/src/home/index.tsx +++ b/src/home/index.tsx @@ -1,9 +1,38 @@ -import PermanentDrawerLeft from "../permanentSidebar" +import { useSelector } from "react-redux"; +import { useGetAppreciationsQuery } from "../appreciations/apiSlice"; +import PermanentDrawerLeft from "../permanentSidebar"; +import AppreciationCountCard from "./components/appreciationCountCard"; +import { RootState } from "../store"; +import NotificationCard from "./components/sendNotificationCard"; +import DownloadExcelCard from "./components/downloadExcel"; + +const HomeComponent = () => { + const authToken = useSelector( + (state: RootState) => state.loginStore.authToken + ); + const { data: appreciations, isError: listAppreciationsError } = + useGetAppreciationsQuery({ + page: 1, + page_size: 10, + authToken: authToken, + }); + return ( + <> + {!listAppreciationsError ? ( + + ) : ( + + )} + + + + ); +}; const Home = () => { - return( - Home}/> - ) -} + return } />; +}; -export default Home \ No newline at end of file +export default Home; diff --git a/src/home/types.tsx b/src/home/types.tsx new file mode 100644 index 0000000..cb16583 --- /dev/null +++ b/src/home/types.tsx @@ -0,0 +1,10 @@ +export interface downloadReportResponse { + success: boolean; + message: string; + status_code: number; + data: object; +} + +export interface downloadReportReq{ + authToken: string +} \ No newline at end of file diff --git a/src/store.tsx b/src/store.tsx index 5d3d921..4c6994d 100644 --- a/src/store.tsx +++ b/src/store.tsx @@ -7,6 +7,7 @@ import sidebarReducer from './sideBar/slice.tsx'; import { configSlice } from './config/apiSlice.tsx'; import { badgesSlice } from './badges/apiSlice.tsx'; import { coreValueSlice } from './coreValues/apiSlice.tsx'; +import { homeSlice } from './home/apiSlice.tsx'; export const store = configureStore({ @@ -20,12 +21,12 @@ export const store = configureStore({ [configSlice.reducerPath]: configSlice.reducer, [badgesSlice.reducerPath]: badgesSlice.reducer, [coreValueSlice.reducerPath]: coreValueSlice.reducer, - + [homeSlice.reducerPath]: homeSlice.reducer }, middleware: (getDefaultMiddleware) => - getDefaultMiddleware().concat(loginApiSlice.middleware).concat(appreciationSlice.middleware).concat(configSlice.middleware).concat(badgesSlice.middleware).concat(coreValueSlice.middleware) + getDefaultMiddleware().concat(loginApiSlice.middleware).concat(appreciationSlice.middleware).concat(configSlice.middleware).concat(badgesSlice.middleware).concat(coreValueSlice.middleware).concat(homeSlice.middleware) }); From 14b92b47f29b2eced9c723de30484650e1c603b4 Mon Sep 17 00:00:00 2001 From: Sharyu Marwadi Date: Tue, 13 Aug 2024 12:48:26 +0530 Subject: [PATCH 12/23] [feature/Dashboard] notifications done --- src/config/components/quater.tsx | 8 +- src/home/apiSlice.tsx | 53 +++++-- src/home/components/notifyAllDilogBox.tsx | 98 +++++++++++++ src/home/components/notifyUserDialogBox.tsx | 139 +++++++++++++++++++ src/home/components/sendNotificationCard.tsx | 60 +++++--- src/home/index.tsx | 35 +++-- src/home/types.tsx | 64 ++++++++- 7 files changed, 407 insertions(+), 50 deletions(-) create mode 100644 src/home/components/notifyAllDilogBox.tsx create mode 100644 src/home/components/notifyUserDialogBox.tsx diff --git a/src/config/components/quater.tsx b/src/config/components/quater.tsx index 59ca183..e9856c9 100644 --- a/src/config/components/quater.tsx +++ b/src/config/components/quater.tsx @@ -15,10 +15,10 @@ function createData( } const rows = [ - createData(1,new Date(new Date().getFullYear(), 0, 1),new Date(new Date().getFullYear(), 2, 31)), - createData(2,new Date(new Date().getFullYear(), 3, 1),new Date(new Date().getFullYear(), 5, 30)), - createData(3,new Date(new Date().getFullYear(), 6, 1),new Date(new Date().getFullYear(), 8, 31)), - createData(4,new Date(new Date().getFullYear(), 9, 1),new Date(new Date().getFullYear(), 11, 31)) + createData(1,new Date(new Date().getFullYear(), 3, 1),new Date(new Date().getFullYear(), 5, 30)), + createData(2,new Date(new Date().getFullYear(), 6, 1),new Date(new Date().getFullYear(), 8, 31)), + createData(3,new Date(new Date().getFullYear(), 9, 1),new Date(new Date().getFullYear(), 11, 31)), + createData(4,new Date(new Date().getFullYear(), 0, 1),new Date(new Date().getFullYear(), 2, 31)), ]; export default function QuaterTable() { diff --git a/src/home/apiSlice.tsx b/src/home/apiSlice.tsx index 8fd168f..e28806e 100644 --- a/src/home/apiSlice.tsx +++ b/src/home/apiSlice.tsx @@ -1,28 +1,63 @@ import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react"; +import { listUsersResp, sendNotificationReq, sendNotificationResponse } from "./types"; export const homeSlice = createApi({ reducerPath: "homeSlice", baseQuery: fetchBaseQuery({ baseUrl: "http://localhost:33001/peerly", }), - tagTypes: ["downloadReport"], + tagTypes: ["downloadReport", "users"], endpoints: (builder) => ({ - downloadReport: builder.query({ - query: ({authToken}) => ({ + downloadReport: builder.query({ + query: ({ authToken }) => ({ url: "/admin/report", method: "GET", headers: { - // "Accept-Version": "application/vnd.peerly.v1", Authorization: `Bearer ${authToken}`, }, responseHandler: (response) => response.arrayBuffer(), }), - // transformResponse: (response: Blob) => response, - + }), + + getUsers: builder.query({ + query: ({ page, page_size, authToken }) => ({ + url: `/users?page=${page}&page_size=${page_size}`, + method: "GET", + headers: { + "Accept-Version": "application/vnd.peerly.v1", + Authorization: `Bearer ${authToken}`, + }, + }), + providesTags: ["users"], + }), + + sendNotification: builder.mutation< + sendNotificationResponse, + Partial + >({ + query: (payload) => ({ + url: "/admin/notification", + method: "POST", + body: { + message: { + title: payload.message?.title, + body: payload.message?.body, + }, + all: payload.all, + id: payload.id, + }, + headers: { + "Content-type": "application/json; charset=UTF-8", + "Accept-Version": "application/vnd.peerly.v1", + Authorization: `Bearer ${payload.authToken}`, + }, + }), }), }), }); -export const { - useDownloadReportQuery -} = homeSlice; +export const { + useDownloadReportQuery, + useSendNotificationMutation, + useGetUsersQuery + } = homeSlice; diff --git a/src/home/components/notifyAllDilogBox.tsx b/src/home/components/notifyAllDilogBox.tsx new file mode 100644 index 0000000..70ea853 --- /dev/null +++ b/src/home/components/notifyAllDilogBox.tsx @@ -0,0 +1,98 @@ +import * as React from 'react'; +import Button from '@mui/material/Button'; +import TextField from '@mui/material/TextField'; +import Dialog from '@mui/material/Dialog'; +import DialogActions from '@mui/material/DialogActions'; +import DialogContent from '@mui/material/DialogContent'; +import DialogContentText from '@mui/material/DialogContentText'; +import DialogTitle from '@mui/material/DialogTitle'; +import { useGetUsersQuery, useSendNotificationMutation } from '../apiSlice'; +import { sendNotificationReq } from '../types'; +import { useSelector } from 'react-redux'; +import { RootState } from '../../store'; +import { toast } from 'react-toastify'; + +interface IProps{ + open: boolean + setOpen: (value: boolean | ((prevVar: boolean) => boolean)) => void; + } + +export default function NotifiyAllDialog(props: IProps) { + + const authToken = useSelector((state: RootState) => state.loginStore.authToken); + + const handleClose = () => { + props.setOpen(false); + }; + + const [sendNotification] = useSendNotificationMutation() + + return ( + + ) => { + event.preventDefault(); + const formData = new FormData(event.currentTarget); + const formJson = Object.fromEntries((formData as any).entries()); + const title = formJson.title; + const body = formJson.message; + const req : sendNotificationReq = { + message: { + title: title, + body: body, + }, + all: true, + id: 0, + authToken: authToken + } + sendNotification(req).then(resp => { + console.log(resp) + toast.success(resp.data?.message) + }).catch(resp => { + console.log(resp) + toast.error(resp.data.message); + }) + handleClose(); + }, + }} + > + Notification + + + Enter the notification title and message + + + + + + + + + + + ); +} diff --git a/src/home/components/notifyUserDialogBox.tsx b/src/home/components/notifyUserDialogBox.tsx new file mode 100644 index 0000000..765e14f --- /dev/null +++ b/src/home/components/notifyUserDialogBox.tsx @@ -0,0 +1,139 @@ +import * as React from "react"; +import Button from "@mui/material/Button"; +import TextField from "@mui/material/TextField"; +import Dialog from "@mui/material/Dialog"; +import DialogActions from "@mui/material/DialogActions"; +import DialogContent from "@mui/material/DialogContent"; +import DialogContentText from "@mui/material/DialogContentText"; +import DialogTitle from "@mui/material/DialogTitle"; +import { useGetUsersQuery, useSendNotificationMutation } from "../apiSlice"; +import { sendNotificationReq, user, userDropdown } from "../types"; +import { useSelector } from "react-redux"; +import { RootState } from "../../store"; +import { toast } from "react-toastify"; +import { Autocomplete } from "@mui/material"; + +interface IProps { + open: boolean; + setOpen: (value: boolean | ((prevVar: boolean) => boolean)) => void; +} + +export default function NotifiyUserDialog(props: IProps) { + const handleClose = () => { + props.setOpen(false); + }; + + const [sendNotification] = useSendNotificationMutation(); + const authToken = useSelector( + (state: RootState) => state.loginStore.authToken + ); + + const [selectedUser, setSelectedUser] = React.useState(); + + + const { data, isError, isFetching } = useGetUsersQuery({ + page: 1, + page_size: 400, + authToken: authToken + }); + + const [users, setUsers] = React.useState([]) + + + React.useEffect(()=>{ + setUsers([]) + if (data != undefined){ + data.data.user_list.map((user)=>{ + return setUsers((prevData)=>[...prevData,{ + label: user.first_name + " "+ user.last_name, + id: user.id, + }]) + }) + } + console.log(users) + },[data]) + + return ( + + ) => { + event.preventDefault(); + const formData = new FormData(event.currentTarget); + const formJson = Object.fromEntries((formData as any).entries()); + console.log("formJson -> ", formJson) + console.log("user -> ",selectedUser) + const title = formJson.title; + const body = formJson.message; + const id = selectedUser?.id + const req: sendNotificationReq = { + message: { + title: title, + body: body, + }, + all: false, + id: id, + authToken: authToken, + }; + sendNotification(req) + .then((resp) => { + console.log(resp); + toast.success(resp.data?.message); + }) + .catch((resp) => { + console.log(resp); + toast.error(resp.data.message); + }); + handleClose(); + }, + }} + > + Notification + + + Enter the notification title and message + + setSelectedUser(newValue)} + renderInput={(params) => ( + + )} + /> + + + + + + + + + + ); +} diff --git a/src/home/components/sendNotificationCard.tsx b/src/home/components/sendNotificationCard.tsx index 6f53ed8..c01fd20 100644 --- a/src/home/components/sendNotificationCard.tsx +++ b/src/home/components/sendNotificationCard.tsx @@ -1,37 +1,53 @@ -import * as React from 'react'; -import Box from '@mui/material/Box'; -import Card from '@mui/material/Card'; -import CardActions from '@mui/material/CardActions'; -import CardContent from '@mui/material/CardContent'; -import Button from '@mui/material/Button'; -import Typography from '@mui/material/Typography'; +import Box from "@mui/material/Box"; +import Card from "@mui/material/Card"; +import CardActions from "@mui/material/CardActions"; +import CardContent from "@mui/material/CardContent"; +import Button from "@mui/material/Button"; +import Typography from "@mui/material/Typography"; const bull = ( ); -const card = ( - - - - Send a notification - - - - - - -); +interface IProps { + setOpenNotifyUser: (value: boolean | ((prevVar: boolean) => boolean)) => void; + setOpenNotifyAll: (value: boolean | ((prevVar: boolean) => boolean)) => void; +} + +export default function NotificationCard(props: IProps) { + const handleClickOpenNotifyAll = () => { + props.setOpenNotifyAll(true); + }; + + const handleClickOpenNotifyUser = () => { + props.setOpenNotifyUser(true); + }; -export default function NotificationCard() { return ( - {card} + + + Send a notification + + + + + + + + + + + ); } diff --git a/src/home/index.tsx b/src/home/index.tsx index a67c396..85a4088 100644 --- a/src/home/index.tsx +++ b/src/home/index.tsx @@ -5,8 +5,15 @@ import AppreciationCountCard from "./components/appreciationCountCard"; import { RootState } from "../store"; import NotificationCard from "./components/sendNotificationCard"; import DownloadExcelCard from "./components/downloadExcel"; +import { useState } from "react"; +import NotifiyAllDialog from "./components/notifyAllDilogBox"; +import NotifiyUserDialog from "./components/notifyUserDialogBox"; +import { Box } from "@mui/material"; const HomeComponent = () => { + const [openNotifyAll, setOpenNotifyAll] = useState(false); + const [openNotifyUser, setOpenNotifyUser] = useState(false); + const authToken = useSelector( (state: RootState) => state.loginStore.authToken ); @@ -18,15 +25,27 @@ const HomeComponent = () => { }); return ( <> - {!listAppreciationsError ? ( - + {!listAppreciationsError ? ( + + ) : ( + + )} + - ) : ( - - )} - - + +
+ + ); }; diff --git a/src/home/types.tsx b/src/home/types.tsx index cb16583..aab89e5 100644 --- a/src/home/types.tsx +++ b/src/home/types.tsx @@ -1,10 +1,60 @@ export interface downloadReportResponse { - success: boolean; - message: string; - status_code: number; - data: object; + success: boolean; + message: string; + status_code: number; + data: object; } -export interface downloadReportReq{ - authToken: string -} \ No newline at end of file +export interface downloadReportReq { + authToken: string; +} + +export interface sendNotificationResponse { + success: boolean; + message: string; + status_code: number; + data: object; +} + +export interface message { + title: string; + body: string; +} + +export interface sendNotificationReq { + message: message; + all: boolean; + id: number | undefined; + authToken: string; +} + +export interface user { + id: number; + email: string; + first_name: string; + last_name: string; +} + +export interface metadata { + page: number; + total_page: number; + page_size: number; + total_records: number; +} + +export interface data{ + user_list: user[]; + metadata: metadata +} + +export interface listUsersResp { + success: boolean; + message: string; + status_code: number; + data: data; +} + +export interface userDropdown { + label: string; + id: number; +} From 9b1150463548ed26c1ccd511a30f88ad68e621ab Mon Sep 17 00:00:00 2001 From: Sharyu Marwadi Date: Tue, 13 Aug 2024 14:32:01 +0530 Subject: [PATCH 13/23] [feature/Dashboard] base url constant added --- src/appreciations/apiSlice.tsx | 3 ++- src/badges/apiSlice.tsx | 3 ++- src/config/apiSlice.tsx | 3 ++- src/constants.tsx | 1 + src/coreValues/apiSlice.tsx | 3 ++- src/home/apiSlice.tsx | 3 ++- src/login/apiSlice.tsx | 3 ++- 7 files changed, 13 insertions(+), 6 deletions(-) create mode 100644 src/constants.tsx diff --git a/src/appreciations/apiSlice.tsx b/src/appreciations/apiSlice.tsx index 339634c..cd304bc 100644 --- a/src/appreciations/apiSlice.tsx +++ b/src/appreciations/apiSlice.tsx @@ -1,10 +1,11 @@ import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react"; import { moderationReq, moderationResponse, response } from "./types"; +import { baseUrl } from "../constants"; export const appreciationSlice = createApi({ reducerPath: "appreciationSlice", baseQuery: fetchBaseQuery({ - baseUrl: "http://localhost:33001/peerly", + baseUrl: baseUrl, }), tagTypes: ["appreciation", "reported", "moderation"], endpoints: (builder) => ({ diff --git a/src/badges/apiSlice.tsx b/src/badges/apiSlice.tsx index e3b2424..d14b284 100644 --- a/src/badges/apiSlice.tsx +++ b/src/badges/apiSlice.tsx @@ -1,10 +1,11 @@ import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react"; import { badgesResponse, editBadgeReq, editBadgeResp } from "./types"; +import { baseUrl } from "../constants"; export const badgesSlice = createApi({ reducerPath: "badgesSlice", baseQuery: fetchBaseQuery({ - baseUrl: "http://localhost:33001/peerly", + baseUrl: baseUrl, }), tagTypes: ["badges"], endpoints: (builder) => ({ diff --git a/src/config/apiSlice.tsx b/src/config/apiSlice.tsx index 7b612d5..f1cc956 100644 --- a/src/config/apiSlice.tsx +++ b/src/config/apiSlice.tsx @@ -1,10 +1,11 @@ import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react"; import { editGradeReq, editGradeResp, editRenewalFrequencyReq, editRenewalFrequencyResp, gradesResponse, orgConfigResponse } from "./types"; +import { baseUrl } from "../constants"; export const configSlice = createApi({ reducerPath: "configSlice", baseQuery: fetchBaseQuery({ - baseUrl: "http://localhost:33001/peerly", + baseUrl: baseUrl, }), tagTypes: ["gradesConfig","orgConfig"], endpoints: (builder) => ({ diff --git a/src/constants.tsx b/src/constants.tsx new file mode 100644 index 0000000..4d91f3c --- /dev/null +++ b/src/constants.tsx @@ -0,0 +1 @@ +export const baseUrl = "https://pg-stage-intranet.joshsoftware.com/peerly" \ No newline at end of file diff --git a/src/coreValues/apiSlice.tsx b/src/coreValues/apiSlice.tsx index df36fff..72f2d76 100644 --- a/src/coreValues/apiSlice.tsx +++ b/src/coreValues/apiSlice.tsx @@ -1,10 +1,11 @@ import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react"; import { coreValuesResp } from "./types"; +import { baseUrl } from "../constants"; export const coreValueSlice = createApi({ reducerPath: "coreValueSlice", baseQuery: fetchBaseQuery({ - baseUrl: "http://localhost:33001/peerly", + baseUrl: baseUrl, }), tagTypes: ["coreValues"], endpoints: (builder) => ({ diff --git a/src/home/apiSlice.tsx b/src/home/apiSlice.tsx index e28806e..9cce23f 100644 --- a/src/home/apiSlice.tsx +++ b/src/home/apiSlice.tsx @@ -1,10 +1,11 @@ import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react"; import { listUsersResp, sendNotificationReq, sendNotificationResponse } from "./types"; +import { baseUrl } from "../constants"; export const homeSlice = createApi({ reducerPath: "homeSlice", baseQuery: fetchBaseQuery({ - baseUrl: "http://localhost:33001/peerly", + baseUrl: baseUrl, }), tagTypes: ["downloadReport", "users"], endpoints: (builder) => ({ diff --git a/src/login/apiSlice.tsx b/src/login/apiSlice.tsx index 7314802..b76b20d 100644 --- a/src/login/apiSlice.tsx +++ b/src/login/apiSlice.tsx @@ -1,10 +1,11 @@ import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react' import { userLoginBody, userLoginResp } from './types' +import { baseUrl } from '../constants' export const loginApiSlice = createApi({ reducerPath: 'loginSlice', baseQuery: fetchBaseQuery({ - baseUrl: 'http://localhost:33001/peerly', + baseUrl: baseUrl, }), tagTypes: ['Login'], endpoints: (builder) => ({ From 14e187c78cf0d6894c3eeada2b7bf3a3f0112660 Mon Sep 17 00:00:00 2001 From: Sharyu Marwadi Date: Sat, 17 Aug 2024 13:01:33 +0530 Subject: [PATCH 14/23] [feature/Dashboard] download two different reports --- src/appreciations/apiSlice.tsx | 24 ++++++ src/appreciations/components/table.tsx | 97 ++++++++++++++++++--- src/constants.tsx | 5 +- src/home/apiSlice.tsx | 22 ++--- src/home/components/downloadExcel.tsx | 112 ++++++++++++------------- src/home/index.tsx | 4 +- 6 files changed, 183 insertions(+), 81 deletions(-) diff --git a/src/appreciations/apiSlice.tsx b/src/appreciations/apiSlice.tsx index cd304bc..d895a79 100644 --- a/src/appreciations/apiSlice.tsx +++ b/src/appreciations/apiSlice.tsx @@ -44,6 +44,28 @@ export const appreciationSlice = createApi({ }), invalidatesTags: () => [{ type: "reported" }], }), + + appreciationReport: builder.query({ + query: ({ authToken }) => ({ + url: "/admin/appreciation_report", + method: "GET", + headers: { + Authorization: `Bearer ${authToken}`, + }, + responseHandler: (response) => response.arrayBuffer(), + }), + }), + + reportedAppreciationReport: builder.query({ + query: ({ authToken }) => ({ + url: "/admin/reported_appreciation_report", + method: "GET", + headers: { + Authorization: `Bearer ${authToken}`, + }, + responseHandler: (response) => response.arrayBuffer(), + }), + }), }), }); @@ -51,4 +73,6 @@ export const { useGetAppreciationsQuery, useGetReportedAppreciationsQuery, useDeleteAppreciationMutation, + useAppreciationReportQuery, + useReportedAppreciationReportQuery, } = appreciationSlice; diff --git a/src/appreciations/components/table.tsx b/src/appreciations/components/table.tsx index fa9ecf8..11e6829 100644 --- a/src/appreciations/components/table.tsx +++ b/src/appreciations/components/table.tsx @@ -18,6 +18,13 @@ import { visuallyHidden } from "@mui/utils"; import { IPropsTable } from "../types"; import AppreciationToggleButton from "./toggleButton"; import DeleteDialog from "./dialogeBox"; +import { Button } from "@mui/material"; +import { useSelector } from "react-redux"; +import { + useAppreciationReportQuery, + useReportedAppreciationReportQuery, +} from "../apiSlice"; +import { RootState } from "../../store"; interface Data { id: number; @@ -242,7 +249,13 @@ function EnhancedTableHead(props: EnhancedTableProps) { active={orderBy === headCell.id} direction={orderBy === headCell.id ? order : "asc"} onClick={createSortHandler(headCell.id)} - sx={props.filter =="reported" ? (headCell.id == "isValid"|| headCell.id == "rewardPoints" ? {width: "120px"} : {width: "160px"}) : {}} + sx={ + props.filter == "reported" + ? headCell.id == "isValid" || headCell.id == "rewardPoints" + ? { width: "120px" } + : { width: "160px" } + : {} + } > {headCell.label} {orderBy === headCell.id ? ( @@ -260,14 +273,65 @@ function EnhancedTableHead(props: EnhancedTableProps) { interface EnhancedTableToolbarProps { numSelected: number; + filter: string; setFilter: (value: string | ((prevVar: string) => string)) => void; setPage: (value: number | ((prevVar: number) => number)) => void; } function EnhancedTableToolbar(props: EnhancedTableToolbarProps) { + const authToken = useSelector( + (state: RootState) => state.loginStore.authToken + ); + const { data: appreciations, error: appreciationError } = + useAppreciationReportQuery({ authToken }); + const { data: reportedAppreciations, error: reportedAppreciationError } = + useReportedAppreciationReportQuery({ authToken }); + const handleClick = () => { + if (props.filter === "reported") { + if (reportedAppreciations) { + // Create a URL for the Blob + const blob = new Blob([reportedAppreciations], { + type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", + }); + + // Create a link element and trigger a download + const url = window.URL.createObjectURL(blob); + const a = document.createElement("a"); + a.href = url; + a.download = "ReportedAppreciaitionsReport.xlsx"; // Set the desired filename + document.body.appendChild(a); + a.click(); + document.body.removeChild(a); + window.URL.revokeObjectURL(url); + } else if (reportedAppreciations) { + console.error( + "Error downloading the report:", + reportedAppreciationError + ); + } + } else { + if (appreciations) { + // Create a URL for the Blob + const blob = new Blob([appreciations], { + type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", + }); + + // Create a link element and trigger a download + const url = window.URL.createObjectURL(blob); + const a = document.createElement("a"); + a.href = url; + a.download = "AppreciationsReport.xlsx"; // Set the desired filename + document.body.appendChild(a); + a.click(); + document.body.removeChild(a); + window.URL.revokeObjectURL(url); + } else if (appreciationError) { + console.error("Error downloading the report:", appreciationError); + } + } + }; return ( - - - + + + ); } @@ -298,11 +367,10 @@ export default function AppreciationTable(props: IPropsTable) { useEffect(() => { const data = props.response; - if(props.filter == "reported"){ - setOrderBy("isValid") - } - else{ - setOrderBy("date") + if (props.filter == "reported") { + setOrderBy("isValid"); + } else { + setOrderBy("date"); } setRows([]); @@ -394,12 +462,19 @@ export default function AppreciationTable(props: IPropsTable) { const [id, setId] = useState(0); return ( - + ({ - downloadReport: builder.query({ - query: ({ authToken }) => ({ - url: "/admin/report", - method: "GET", - headers: { - Authorization: `Bearer ${authToken}`, - }, - responseHandler: (response) => response.arrayBuffer(), - }), - }), + // downloadReport: builder.query({ + // query: ({ authToken }) => ({ + // url: "/admin/appreciation_report", + // method: "GET", + // headers: { + // Authorization: `Bearer ${authToken}`, + // }, + // responseHandler: (response) => response.arrayBuffer(), + // }), + // }), getUsers: builder.query({ query: ({ page, page_size, authToken }) => ({ @@ -58,7 +58,7 @@ export const homeSlice = createApi({ }); export const { - useDownloadReportQuery, + // useDownloadReportQuery, useSendNotificationMutation, useGetUsersQuery } = homeSlice; diff --git a/src/home/components/downloadExcel.tsx b/src/home/components/downloadExcel.tsx index c9cbbf6..0593714 100644 --- a/src/home/components/downloadExcel.tsx +++ b/src/home/components/downloadExcel.tsx @@ -1,59 +1,59 @@ -import Box from "@mui/material/Box"; -import Card from "@mui/material/Card"; -import CardActions from "@mui/material/CardActions"; -import CardContent from "@mui/material/CardContent"; -import Button from "@mui/material/Button"; -import Typography from "@mui/material/Typography"; -import { useSelector } from "react-redux"; -import { RootState } from "../../store"; -import { useState } from "react"; -import { useDownloadReportQuery } from "../apiSlice"; +// import Box from "@mui/material/Box"; +// import Card from "@mui/material/Card"; +// import CardActions from "@mui/material/CardActions"; +// import CardContent from "@mui/material/CardContent"; +// import Button from "@mui/material/Button"; +// import Typography from "@mui/material/Typography"; +// import { useSelector } from "react-redux"; +// import { RootState } from "../../store"; +// import { useState } from "react"; +// // import { useDownloadReportQuery } from "../apiSlice"; -const bull = ( - - • - -); +// const bull = ( +// +// • +// +// ); -export default function DownloadExcelCard() { - const authToken = useSelector((state: RootState) => state.loginStore.authToken); - const { data, error, isLoading } = useDownloadReportQuery({authToken}); - const handleClick = () => { - console.log("data -> ",data) - if (data) { - // Create a URL for the Blob - const blob = new Blob([data], { type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" }); +// export default function DownloadExcelCard() { +// const authToken = useSelector((state: RootState) => state.loginStore.authToken); +// const { data, error, isLoading } = useDownloadReportQuery({authToken}); +// const handleClick = () => { +// console.log("data -> ",data) +// if (data) { +// // Create a URL for the Blob +// const blob = new Blob([data], { type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" }); - // Create a link element and trigger a download - const url = window.URL.createObjectURL(blob); - const a = document.createElement("a"); - a.href = url; - a.download = "report.xlsx"; // Set the desired filename - document.body.appendChild(a); - a.click(); - document.body.removeChild(a); - window.URL.revokeObjectURL(url); - } else if (error) { - console.error("Error downloading the report:", error); - } - }; - return ( - - - - - Download report for the quarter in excel format - - - - - - - - ); -} +// // Create a link element and trigger a download +// const url = window.URL.createObjectURL(blob); +// const a = document.createElement("a"); +// a.href = url; +// a.download = "report.xlsx"; // Set the desired filename +// document.body.appendChild(a); +// a.click(); +// document.body.removeChild(a); +// window.URL.revokeObjectURL(url); +// } else if (error) { +// console.error("Error downloading the report:", error); +// } +// }; +// return ( +// +// +// +// +// Download report for the quarter in excel format +// +// +// +// +// +// +// +// ); +// } diff --git a/src/home/index.tsx b/src/home/index.tsx index 85a4088..6efcb2c 100644 --- a/src/home/index.tsx +++ b/src/home/index.tsx @@ -4,7 +4,7 @@ import PermanentDrawerLeft from "../permanentSidebar"; import AppreciationCountCard from "./components/appreciationCountCard"; import { RootState } from "../store"; import NotificationCard from "./components/sendNotificationCard"; -import DownloadExcelCard from "./components/downloadExcel"; +// import DownloadExcelCard from "./components/downloadExcel"; import { useState } from "react"; import NotifiyAllDialog from "./components/notifyAllDilogBox"; import NotifiyUserDialog from "./components/notifyUserDialogBox"; @@ -42,7 +42,7 @@ const HomeComponent = () => { setOpenNotifyAll={setOpenNotifyAll} setOpenNotifyUser={setOpenNotifyUser} /> - + {/* */} From 80dafdcebad724742c8c36b8d73435d9c305a9b3 Mon Sep 17 00:00:00 2001 From: Sharyu Marwadi Date: Thu, 22 Aug 2024 21:36:10 +0530 Subject: [PATCH 15/23] [feature/PEER-58-AdminLogin] login page done --- .env | 1 + src/constants.tsx | 1 + src/login/apiSlice.tsx | 7 ++++--- src/login/components/loginForm.tsx | 8 ++++++-- src/login/index.tsx | 2 +- src/login/slice.tsx | 23 +++++++++++++++++++++++ src/login/types.tsx | 2 +- src/store.tsx | 9 +++++---- 8 files changed, 42 insertions(+), 11 deletions(-) create mode 100644 .env create mode 100644 src/constants.tsx create mode 100644 src/login/slice.tsx diff --git a/.env b/.env new file mode 100644 index 0000000..d2eb028 --- /dev/null +++ b/.env @@ -0,0 +1 @@ +BASE_URL = https://pg-stage-intranet.joshsoftware.com/peerly \ No newline at end of file diff --git a/src/constants.tsx b/src/constants.tsx new file mode 100644 index 0000000..4d91f3c --- /dev/null +++ b/src/constants.tsx @@ -0,0 +1 @@ +export const baseUrl = "https://pg-stage-intranet.joshsoftware.com/peerly" \ No newline at end of file diff --git a/src/login/apiSlice.tsx b/src/login/apiSlice.tsx index 2819430..b76b20d 100644 --- a/src/login/apiSlice.tsx +++ b/src/login/apiSlice.tsx @@ -1,10 +1,11 @@ import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react' import { userLoginBody, userLoginResp } from './types' +import { baseUrl } from '../constants' -export const loginSlice = createApi({ +export const loginApiSlice = createApi({ reducerPath: 'loginSlice', baseQuery: fetchBaseQuery({ - baseUrl: 'http://localhost:33001', + baseUrl: baseUrl, }), tagTypes: ['Login'], endpoints: (builder) => ({ @@ -23,4 +24,4 @@ export const loginSlice = createApi({ }), }) -export const { useAdminLoginMutation } = loginSlice \ No newline at end of file +export const { useAdminLoginMutation } = loginApiSlice \ No newline at end of file diff --git a/src/login/components/loginForm.tsx b/src/login/components/loginForm.tsx index d3a7fa1..08fa8cc 100644 --- a/src/login/components/loginForm.tsx +++ b/src/login/components/loginForm.tsx @@ -6,6 +6,8 @@ import { useAdminLoginMutation } from "../apiSlice"; import { useNavigate } from "react-router-dom"; import { toast } from "react-toastify"; import "react-toastify/dist/ReactToastify.css"; +import { useDispatch } from "react-redux"; +import { getAuthToken } from "../slice"; const LoginForm = () => { const navigate = useNavigate(); @@ -18,6 +20,7 @@ const LoginForm = () => { password: Yup.string().required("Required!"), }); const [loginAdmin] = useAdminLoginMutation(); + const dispatch = useDispatch(); const formik = useFormik({ initialValues: initialValues, validationSchema: loginSchema, @@ -28,7 +31,8 @@ const LoginForm = () => { console.log("response -> ", resp); toast.success(resp.message); localStorage.setItem("token", resp.data.AuthToken); - navigate("/") + dispatch(getAuthToken(resp.data.AuthToken)); + navigate("/"); }) .catch((resp) => { console.log("response -> ", resp); @@ -83,4 +87,4 @@ const LoginForm = () => { ); }; -export default LoginForm; +export default LoginForm; \ No newline at end of file diff --git a/src/login/index.tsx b/src/login/index.tsx index e40e6ab..3d667df 100644 --- a/src/login/index.tsx +++ b/src/login/index.tsx @@ -22,4 +22,4 @@ const Login = () => { ); }; -export default Login; +export default Login; \ No newline at end of file diff --git a/src/login/slice.tsx b/src/login/slice.tsx new file mode 100644 index 0000000..33ce7da --- /dev/null +++ b/src/login/slice.tsx @@ -0,0 +1,23 @@ +import { createSlice, PayloadAction } from "@reduxjs/toolkit"; + +export interface TheStoreState { + authToken: string; +} + +const initialStateValue: TheStoreState = { + authToken: "", +}; + +export const loginSlice = createSlice({ + name: "loginStore", + initialState: initialStateValue, + reducers: { + getAuthToken: (state, action: PayloadAction) => { + state.authToken = action.payload; + }, + }, +}); + +export const { getAuthToken } = loginSlice.actions; + +export default loginSlice.reducer; \ No newline at end of file diff --git a/src/login/types.tsx b/src/login/types.tsx index 67e5edd..2399d90 100644 --- a/src/login/types.tsx +++ b/src/login/types.tsx @@ -28,4 +28,4 @@ export interface userLoginResp { status_code: Int16Array; success: boolean; data: data; -} +} \ No newline at end of file diff --git a/src/store.tsx b/src/store.tsx index fddeb23..6c6eafa 100644 --- a/src/store.tsx +++ b/src/store.tsx @@ -1,18 +1,19 @@ import { configureStore } from '@reduxjs/toolkit'; - -import { loginSlice } from './login/apiSlice.tsx'; +import { loginApiSlice } from './login/apiSlice.tsx'; +import loginReducer from './login/slice'; export const store = configureStore({ reducer: { - [loginSlice.reducerPath]: loginSlice.reducer, + loginStore: loginReducer, + [loginApiSlice.reducerPath]: loginApiSlice.reducer, }, middleware: (getDefaultMiddleware) => - getDefaultMiddleware().concat(loginSlice.middleware), + getDefaultMiddleware().concat(loginApiSlice.middleware), }); \ No newline at end of file From b4a5e149e8fbc1cfd9a1802bfbd9a82681d629ae Mon Sep 17 00:00:00 2001 From: Sharyu Marwadi Date: Thu, 22 Aug 2024 21:55:31 +0530 Subject: [PATCH 16/23] [feature/Header] header done --- src/assets/logo.png | Bin 0 -> 3143 bytes src/header/index.tsx | 42 ++++++++++++++++++++++++++++++++++++++++++ src/home/index.tsx | 6 +++++- 3 files changed, 47 insertions(+), 1 deletion(-) create mode 100644 src/assets/logo.png create mode 100644 src/header/index.tsx diff --git a/src/assets/logo.png b/src/assets/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..51e3923596338fa6bb6893bb4d8a99ef532d3818 GIT binary patch literal 3143 zcmV-N47l@&P)1^@s60=OdL00009a7bBm000XU z000XU0RWnu7ytkO0drDELIAGL9O(c600d`2O+f$vv5yPYvij4n=6oV;XvE6g?zP~+cc~EjZe-0KL zaGG??m|Tzm3u(V)0DUQ0UkJa?8T8f3d+_e?eE+D`hcSaeO)PGI*Z?M7knBgvV1Y~N zO2!sAK48{E=1c}3UV0K3J*bC-x|Tv*1>f?QNV!!cO0(>^MUZqaDf{ZaLw~dE0-I<+ z4J^L>Wfvd1qe#K@>M*AMN+=ISD8`zjRmQQnll;xtf%kL6dBdFZ9{*p1im1$?BzA1x z`B%oExZ3i6`p5$-NEaXJPkG!&Gqaz&R3R0$jw)L$H*Nm{tz zFG-UgdnLR#s)wy#-?fgQ0xA=9Y3CY=$y{|H%DpNPbm{GN8#p`EhnF||%d1cmi*I}Q zK>U5QNCaG{FGJCp6cLm7Vf*?>F!n|tcJaB^p(IKZG!S)u9zM9_{`1?Pt1EHh$|nte z#5nuOIPIYrZ{Gg=;sT}!7w7VI-s#atI+ns;yM5QXfD+(P77gABiOImZ9Z-X&q1=amgB%VVBD6X7y&d{)~ zMkl4bLOs0spM%yF%oxvhKAfR}dQG1Nz|pV!%UibBT63rpbw&mwz`f+9^@|z@b*17; zO-yCEh1|M1SZO^5ViM*D{-*XQh(K+cv+cFk1Vz31CK7c9C!Y@fQu^W1GdM)Q@;q{l zkShiETQ~1kD!C|=LLmBbFFZy@I<&pkO5_thCmIY?)+KbO3O&(bPKfw1a%CGHF_yM} zImak)l|I}0rdAvpSoHu>LMcP^!*;Jp*Bitn3%>T)iAj*o{Ydngvs;vtP`@ks0fm>Q zsNWtepMWKZn36f?hHrTpaQE~rcoh)i2$09>fFi58$RKATm!L}2ImPOM@es`4151!g zB$(4P^yM)H0Cn7~S>VY)keGYw0HusPoxI=YbEvT*q@-<$K?~7vM%R+RT2;i!!qVcv zjPSrW1?Mo&H_bFkb$m`U&L?7i+;4Skuho&*YXR&f=9yNbghfezaNID%(!9B(60}Zu zX)Xlm+>d`>-YmQZ?98*iRYJjWfx^-OdOG0(XU!#DT_5NpIu7>*!b|Pi6xp`rsFar4Ipo%!DQ>Lf`@=du2ycaZ3yWeg1x}S`Y zImV%Nd`<(w;OMt4zP;X!kKbEW2Fu{eD3;$}*~rR!QjCvT`n_;m8-H+8AgMFM(gs?6 z^ZUps)eSGBam>uO0v6pQmO&V}DLS%?vHX_JeIDd0B^J{TS|>0gWQC;>ht>%%P29eF zalt?us)D%`b|#2t7D@M$m%meRe_P8OX;<*1AlKSZ99q7X5`qD#frET(gXj;2xav#s*CIZ1f}1n z^Sn1Hd%(CDCEgSHj#xf4#-%kHre=ji&y@l`@Cght1v#cZR4#+yBy2g&o)j6LQlDM{iIm&&2vnpLW-4xa5?cOYdj_t*dXk5(5R0Z5k$=A1#Syi!gL=+KpZ`|{zp(kt5mV@J@P55%GE@FtUt z^Mg$cn3uiBy1u0dYbhdK?}q14*Iks^6_>^J(Rc&oPK&XM+Zh8ZXt)T>eL6q6GH$RV z#5u=OaW7eh&Vr7RV)48x45I%3GctosT8~7TO4&iArN;5h@6~)P#wpgJ<_53eChGH~ ztp3vWbr-4eYILTO2*f@;7Cq_ROR;WyKibqABZeNMEMWsrho7VIQstqdASYMkspu4a=Keobs?2DZ zYA}8_?kstV=xH#w!BFhBKfJdRVe}P~Y9QzlaNd*D*^U!5iHRu8G-;BCT!MyW5rPno z;!0|m8Z|QD1n2l!nT7+h%=9qd@8m~1al(%3`$2?bryKJYCme_7@*U18ZyYHa5gi!M z-&&r}p@K)^<;YQDfD#X*h6C1oIv1&hLP*AGH^_#As>Fs%0-`Lh>c$Drn0VVZbj&k2 zG#AbJIb(_Fya1M~a*But!BnxNYu|mf2)Wvb%~-4MLQYgPzGHN#Cn;0C(VU3IFvST ziJ&gQf=y~xj(vVKq4%^KyW`}r_@Q!$;vrGiY>1K>f|gCqVF=0|%wq)gd|1h_+3{yZ z(CEeiVVl8)a#y($l+}0qR-B8cOO&hyw;eb2KEJaWg zkpr%?P{f{J=Ne~b28VRx?YosdoAI*LfDq!?Hh@SULlai|r&<1^&IzavX-SR778@2HrU8RK{@e4f$&~2QSvl-cZatcF5-|a*+t+H>%Va>M1aq7dUqg1HaM2n(Hx= z9)WU^Fr3Y@Tr>{A zDMps2v93x&N2 zc1svufX1{4i(J}^;&62AGg5TaqTU(Drrz2F4WSjg%cbxAe+a6<77dq&3hc+g6JYC1 zNJ{&;=5^z+=2?V|Z^U3%H~TMCmxs!^K4~8$r{61U&++PeY5JV~HSQG85d=A#JSkWDPPb_4>qQ?Pk-VBC1_41 z=lrFZH9-%Z zZ7NoHFSMYSFX@0<(4t%e*RjV*_t*U4M7QE@ { + localStorage.removeItem("token"); + navigate("/login"); + }; + return ( + + + + + + + + + ); +} \ No newline at end of file diff --git a/src/home/index.tsx b/src/home/index.tsx index 57f12e1..d4368f0 100644 --- a/src/home/index.tsx +++ b/src/home/index.tsx @@ -1,6 +1,10 @@ +import Header from "../header" + const Home = () => { return( - <>home + <> +
+ ) } From a01fc8f928e7dc409b345cf6b05e7f8b0c09e507 Mon Sep 17 00:00:00 2001 From: Sharyu Marwadi Date: Thu, 22 Aug 2024 22:11:30 +0530 Subject: [PATCH 17/23] [feature/Sidebar] permanent sidebar done --- package-lock.json | 26 +++++++++++ package.json | 1 + src/home/index.tsx | 8 +++- src/permanentSidebar/index.tsx | 79 ++++++++++++++++++++++++++++++++++ src/permanentSidebar/slice.tsx | 23 ++++++++++ src/store.tsx | 2 + 6 files changed, 138 insertions(+), 1 deletion(-) create mode 100644 src/permanentSidebar/index.tsx create mode 100644 src/permanentSidebar/slice.tsx diff --git a/package-lock.json b/package-lock.json index ef6e9e8..475c543 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,6 +10,7 @@ "dependencies": { "@emotion/react": "^11.13.0", "@emotion/styled": "^11.13.0", + "@mui/icons-material": "^5.16.7", "@mui/material": "^5.16.5", "@reduxjs/toolkit": "^2.2.7", "formik": "^2.4.6", @@ -1112,6 +1113,31 @@ "url": "https://opencollective.com/mui-org" } }, + "node_modules/@mui/icons-material": { + "version": "5.16.7", + "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-5.16.7.tgz", + "integrity": "sha512-UrGwDJCXEszbDI7yV047BYU5A28eGJ79keTCP4cc74WyncuVrnurlmIRxaHL8YK+LI1Kzq+/JM52IAkNnv4u+Q==", + "dependencies": { + "@babel/runtime": "^7.23.9" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@mui/material": "^5.0.0", + "@types/react": "^17.0.0 || ^18.0.0", + "react": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, "node_modules/@mui/material": { "version": "5.16.5", "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.16.5.tgz", diff --git a/package.json b/package.json index 8cc4e65..8700477 100644 --- a/package.json +++ b/package.json @@ -12,6 +12,7 @@ "dependencies": { "@emotion/react": "^11.13.0", "@emotion/styled": "^11.13.0", + "@mui/icons-material": "^5.16.7", "@mui/material": "^5.16.5", "@reduxjs/toolkit": "^2.2.7", "formik": "^2.4.6", diff --git a/src/home/index.tsx b/src/home/index.tsx index d4368f0..5caa525 100644 --- a/src/home/index.tsx +++ b/src/home/index.tsx @@ -1,6 +1,7 @@ import Header from "../header" +import PermanentDrawerLeft from "../permanentSidebar" -const Home = () => { +export function HomeTab() { return( <>
@@ -8,4 +9,9 @@ const Home = () => { ) } + +const Home = () => { + return } />; + }; + export default Home \ No newline at end of file diff --git a/src/permanentSidebar/index.tsx b/src/permanentSidebar/index.tsx new file mode 100644 index 0000000..b2d36ce --- /dev/null +++ b/src/permanentSidebar/index.tsx @@ -0,0 +1,79 @@ +import Box from "@mui/material/Box"; +import Drawer from "@mui/material/Drawer"; +import List from "@mui/material/List"; +import ListItem from "@mui/material/ListItem"; +import ListItemButton from "@mui/material/ListItemButton"; +import ListItemIcon from "@mui/material/ListItemIcon"; +import ListItemText from "@mui/material/ListItemText"; +import DashboardIcon from '@mui/icons-material/Dashboard'; +import PostAddIcon from '@mui/icons-material/PostAdd'; +import LocalPoliceIcon from '@mui/icons-material/LocalPolice'; +import DiamondIcon from '@mui/icons-material/Diamond'; +import AssuredWorkloadIcon from '@mui/icons-material/AssuredWorkload'; +import { useDispatch } from "react-redux"; +import { getRoute } from "./slice"; +import { useNavigate } from "react-router-dom"; +import Header from "../header"; + +const drawerWidth = 200; + +interface IProps { + component: any +} + +export default function PermanentDrawerLeft(props: IProps) { + const iconList = [ + , + , + , + , + , + ]; + const routeList = ["/", "/appreciations", "/badges", "/core_values", "/config"]; + const dispatch = useDispatch(); + const navigate = useNavigate(); + const setRoute = (index: number) => () => { + dispatch(getRoute(routeList[index])); + navigate(routeList[index]); + }; + return ( + <> +
+ + + + {["Dashboard", "Appreciations", "Badges", "Corevalues", "Config"].map( + (text, index) => ( + + + {iconList[index]} + + + + ) + )} + + + + + {props.component} + + + + ); +} \ No newline at end of file diff --git a/src/permanentSidebar/slice.tsx b/src/permanentSidebar/slice.tsx new file mode 100644 index 0000000..2a91647 --- /dev/null +++ b/src/permanentSidebar/slice.tsx @@ -0,0 +1,23 @@ +import { createSlice, PayloadAction } from "@reduxjs/toolkit"; + +export interface SidebarStoreState { + route: string; +} + +const initialStateValue: SidebarStoreState = { + route: "/", +}; + +export const sidebarSlice = createSlice({ + name: "sidebarStore", + initialState: initialStateValue, + reducers: { + getRoute: (state, action: PayloadAction) => { + state.route = action.payload; + }, + }, +}); + +export const { getRoute } = sidebarSlice.actions; + +export default sidebarSlice.reducer; \ No newline at end of file diff --git a/src/store.tsx b/src/store.tsx index 6c6eafa..6b98c67 100644 --- a/src/store.tsx +++ b/src/store.tsx @@ -1,6 +1,7 @@ import { configureStore } from '@reduxjs/toolkit'; import { loginApiSlice } from './login/apiSlice.tsx'; import loginReducer from './login/slice'; +import sidebarReducer from './permanentSidebar/slice.tsx'; export const store = configureStore({ @@ -8,6 +9,7 @@ export const store = configureStore({ reducer: { loginStore: loginReducer, + sidebarStore: sidebarReducer, [loginApiSlice.reducerPath]: loginApiSlice.reducer, }, From adc474e84a076e3728978bc2fab8f37a0ce5e03f Mon Sep 17 00:00:00 2001 From: Sharyu Marwadi Date: Thu, 22 Aug 2024 22:52:10 +0530 Subject: [PATCH 18/23] [feature/PEER-50-Appreciations] page done --- .gitignore | 2 +- .vite/deps/package.json | 2 +- package-lock.json | 10 - src/App.tsx | 2 +- src/appreciations/apiSlice.tsx | 45 +- src/appreciations/appreciations.css | 3 + .../{table.tsx => appreciationTable.tsx} | 366 +++++----- src/appreciations/components/badgeAvatars.tsx | 30 - src/appreciations/components/card.css | 1 - src/appreciations/components/card.tsx | 60 -- .../{dialogeBox.tsx => deleteDialogueBox.tsx} | 2 +- .../components/reportedAppreciationTable.tsx | 690 ++++++++++++++++++ .../components/resolveDialogueBox.tsx | 80 ++ src/appreciations/components/toggleButton.tsx | 29 - src/appreciations/index.tsx | 145 +++- src/appreciations/types.tsx | 140 ++-- src/store.tsx | 4 +- 17 files changed, 1174 insertions(+), 437 deletions(-) create mode 100644 src/appreciations/appreciations.css rename src/appreciations/components/{table.tsx => appreciationTable.tsx} (55%) delete mode 100644 src/appreciations/components/badgeAvatars.tsx delete mode 100644 src/appreciations/components/card.css delete mode 100644 src/appreciations/components/card.tsx rename src/appreciations/components/{dialogeBox.tsx => deleteDialogueBox.tsx} (99%) create mode 100644 src/appreciations/components/reportedAppreciationTable.tsx create mode 100644 src/appreciations/components/resolveDialogueBox.tsx delete mode 100644 src/appreciations/components/toggleButton.tsx diff --git a/.gitignore b/.gitignore index a547bf3..54f07af 100644 --- a/.gitignore +++ b/.gitignore @@ -21,4 +21,4 @@ dist-ssr *.ntvs* *.njsproj *.sln -*.sw? +*.sw? \ No newline at end of file diff --git a/.vite/deps/package.json b/.vite/deps/package.json index 3dbc1ca..aead43d 100644 --- a/.vite/deps/package.json +++ b/.vite/deps/package.json @@ -1,3 +1,3 @@ { "type": "module" -} +} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index c6d1bee..475c543 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,11 +10,7 @@ "dependencies": { "@emotion/react": "^11.13.0", "@emotion/styled": "^11.13.0", -<<<<<<< HEAD - "@mui/icons-material": "^5.16.6", -======= "@mui/icons-material": "^5.16.7", ->>>>>>> a01fc8f928e7dc409b345cf6b05e7f8b0c09e507 "@mui/material": "^5.16.5", "@reduxjs/toolkit": "^2.2.7", "formik": "^2.4.6", @@ -1118,15 +1114,9 @@ } }, "node_modules/@mui/icons-material": { -<<<<<<< HEAD - "version": "5.16.6", - "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-5.16.6.tgz", - "integrity": "sha512-ceNGjoXheH9wbIFa1JHmSc9QVjJUvh18KvHrR4/FkJCSi9HXJ+9ee1kUhCOEFfuxNF8UB6WWVrIUOUgRd70t0A==", -======= "version": "5.16.7", "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-5.16.7.tgz", "integrity": "sha512-UrGwDJCXEszbDI7yV047BYU5A28eGJ79keTCP4cc74WyncuVrnurlmIRxaHL8YK+LI1Kzq+/JM52IAkNnv4u+Q==", ->>>>>>> a01fc8f928e7dc409b345cf6b05e7f8b0c09e507 "dependencies": { "@babel/runtime": "^7.23.9" }, diff --git a/src/App.tsx b/src/App.tsx index 3c59814..e45efdb 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,7 +1,7 @@ import "./App.css"; import Login from "./login"; import { ToastContainer } from "react-toastify"; -import { createBrowserRouter, RouterProvider, useNavigate } from "react-router-dom"; +import { createBrowserRouter, RouterProvider } from "react-router-dom"; import Appreciations from "./appreciations"; import { useDispatch } from "react-redux"; import { getAuthToken } from "./login/slice"; diff --git a/src/appreciations/apiSlice.tsx b/src/appreciations/apiSlice.tsx index 0ae662c..d602d42 100644 --- a/src/appreciations/apiSlice.tsx +++ b/src/appreciations/apiSlice.tsx @@ -1,10 +1,11 @@ import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react"; import { moderationReq, moderationResponse, response } from "./types"; +import { baseUrl } from "../constants"; export const appreciationSlice = createApi({ reducerPath: "appreciationSlice", baseQuery: fetchBaseQuery({ - baseUrl: "http://localhost:33001", + baseUrl: baseUrl, }), tagTypes: ["appreciation", "reported", "moderation"], endpoints: (builder) => ({ @@ -30,6 +31,7 @@ export const appreciationSlice = createApi({ }), providesTags: ["reported"], }), + deleteAppreciation: builder.mutation>({ query: (payload) => ({ url: `/moderate_appreciation/${payload.id}`, @@ -43,6 +45,42 @@ export const appreciationSlice = createApi({ }), invalidatesTags: () => [{ type: "reported" }], }), + + resolveAppreciation: builder.mutation>({ + query: (payload) => ({ + url: `/resolve_appreciation/${payload.id}`, + method: "PUT", + body: { moderator_comment: payload.moderator_comment }, + headers: { + "Content-type": "application/json; charset=UTF-8", + "Accept-Version": "application/vnd.peerly.v1", + Authorization: `Bearer ${payload.authToken}`, + }, + }), + invalidatesTags: () => [{ type: "reported" }], + }), + + appreciationReport: builder.query({ + query: ({ authToken }) => ({ + url: "/admin/appreciation_report", + method: "GET", + headers: { + Authorization: `Bearer ${authToken}`, + }, + responseHandler: (response) => response.arrayBuffer(), + }), + }), + + reportedAppreciationReport: builder.query({ + query: ({ authToken }) => ({ + url: "/admin/reported_appreciation_report", + method: "GET", + headers: { + Authorization: `Bearer ${authToken}`, + }, + responseHandler: (response) => response.arrayBuffer(), + }), + }), }), }); @@ -50,4 +88,7 @@ export const { useGetAppreciationsQuery, useGetReportedAppreciationsQuery, useDeleteAppreciationMutation, -} = appreciationSlice; + useAppreciationReportQuery, + useReportedAppreciationReportQuery, + useResolveAppreciationMutation, +} = appreciationSlice; \ No newline at end of file diff --git a/src/appreciations/appreciations.css b/src/appreciations/appreciations.css new file mode 100644 index 0000000..2810a90 --- /dev/null +++ b/src/appreciations/appreciations.css @@ -0,0 +1,3 @@ +.MuiBox-root{ + padding: 0px !important ; +} \ No newline at end of file diff --git a/src/appreciations/components/table.tsx b/src/appreciations/components/appreciationTable.tsx similarity index 55% rename from src/appreciations/components/table.tsx rename to src/appreciations/components/appreciationTable.tsx index 0b3118d..ddb31f3 100644 --- a/src/appreciations/components/table.tsx +++ b/src/appreciations/components/appreciationTable.tsx @@ -9,15 +9,13 @@ import TablePagination from "@mui/material/TablePagination"; import TableRow from "@mui/material/TableRow"; import TableSortLabel from "@mui/material/TableSortLabel"; import Toolbar from "@mui/material/Toolbar"; -import Typography from "@mui/material/Typography"; import Paper from "@mui/material/Paper"; -import IconButton from "@mui/material/IconButton"; -import Tooltip from "@mui/material/Tooltip"; -import DeleteIcon from "@mui/icons-material/Delete"; import { visuallyHidden } from "@mui/utils"; import { IPropsTable } from "../types"; -import AppreciationToggleButton from "./toggleButton"; -import DeleteDialog from "./dialogeBox"; +import { Button, Tooltip } from "@mui/material"; +import { useSelector } from "react-redux"; +import { useAppreciationReportQuery } from "../apiSlice"; +import { RootState } from "../../store"; interface Data { id: number; @@ -27,12 +25,6 @@ interface Data { coreValue: string; rewardPoints: number; date: number; - reportedBy: string; - reportingComment: string; - reportedAt: number; - moderatedBy: string; - moderatorComment: string; - isValid: boolean; } function createData( @@ -42,13 +34,7 @@ function createData( receiver: string, coreValue: string, rewardPoints: number, - date: number, - reportedBy: string, - reportingComment: string, - reportedAt: number, - moderatedBy: string, - moderatorComment: string, - isValid: boolean + date: number ): Data { return { id, @@ -58,12 +44,6 @@ function createData( coreValue, rewardPoints, date, - reportedBy, - reportingComment, - reportedAt, - moderatedBy, - moderatorComment, - isValid, }; } @@ -115,7 +95,6 @@ interface HeadCell { interface EnhancedTableProps { numSelected: number; - filter: string; onRequestSort: ( event: React.MouseEvent, property: keyof Data @@ -126,55 +105,7 @@ interface EnhancedTableProps { rowCount: number; } -const reportedColumns: HeadCell[] = [ - { - id: "reportedBy", - numeric: false, - disablePadding: false, - label: "Reported By", - }, - { - id: "reportingComment", - numeric: false, - disablePadding: false, - label: "Reporting Comment", - }, - { - id: "reportedAt", - numeric: true, - disablePadding: false, - label: "Reported At", - }, - { - id: "moderatedBy", - numeric: false, - disablePadding: false, - label: "Moderated By", - }, - { - id: "moderatorComment", - numeric: false, - disablePadding: false, - label: "Moderator Comment", - }, - { - id: "isValid", - numeric: false, - disablePadding: false, - label: "Delete", - }, -]; - -const appreciationColumns: HeadCell[] = [ - { - id: "date", - numeric: true, - disablePadding: false, - label: "Date", - }, -]; - -const DefaultCells: HeadCell[] = [ +const headCells: HeadCell[] = [ { id: "description", numeric: false, @@ -205,23 +136,15 @@ const DefaultCells: HeadCell[] = [ disablePadding: false, label: "Reward Points", }, + { + id: "date", + numeric: true, + disablePadding: false, + label: "Date", + }, ]; function EnhancedTableHead(props: EnhancedTableProps) { - const [headCells, setHeadCells] = useState(DefaultCells); - - useEffect(() => { - setHeadCells(DefaultCells); - if (props.filter === "reported") { - reportedColumns?.forEach((item) => { - return setHeadCells((prevData) => [...prevData, item]); - }); - } else { - appreciationColumns?.forEach((item) => { - return setHeadCells((prevData) => [...prevData, item]); - }); - } - }, [props.filter]); const { order, orderBy, onRequestSort } = props; const createSortHandler = (property: keyof Data) => (event: React.MouseEvent) => { @@ -259,29 +182,56 @@ function EnhancedTableHead(props: EnhancedTableProps) { interface EnhancedTableToolbarProps { numSelected: number; - setFilter: (value: string | ((prevVar: string) => string)) => void; + setPage: (value: number | ((prevVar: number) => number)) => void; } function EnhancedTableToolbar(props: EnhancedTableToolbarProps) { + const authToken = useSelector( + (state: RootState) => state.loginStore.authToken + ); + const { data: appreciations, error: appreciationError } = + useAppreciationReportQuery({ authToken }); + const handleClick = () => { + if (appreciations) { + // Create a URL for the Blob + const blob = new Blob([appreciations], { + type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", + }); + + // Create a link element and trigger a download + const url = window.URL.createObjectURL(blob); + const a = document.createElement("a"); + a.href = url; + a.download = "AppreciationsReport.xlsx"; // Set the desired filename + document.body.appendChild(a); + a.click(); + document.body.removeChild(a); + window.URL.revokeObjectURL(url); + } else if (appreciationError) { + console.error("Error downloading the report:", appreciationError); + } + }; return ( - Appreciations - + */} - - - + ); } @@ -290,51 +240,24 @@ export default function AppreciationTable(props: IPropsTable) { const [orderBy, setOrderBy] = useState("date"); const [selected, setSelected] = useState([]); const [page, setPage] = useState(0); - const [rowsPerPage, setRowsPerPage] = useState(5); + const [rowsPerPage, setRowsPerPage] = useState(7); const [rows, setRows] = useState([]); useEffect(() => { const data = props.response; - if(props.filter == "reported"){ - setOrderBy("isValid") - } - else{ - setOrderBy("date") - } setRows([]); data?.map((item) => { - const updatedItem = { - ...item, - reported_by_first_name: item.reported_by_first_name || "", - reported_by_last_name: item.reported_by_last_name || "", - moderated_by_first_name: item.moderated_by_first_name || "", - moderated_by_last_name: item.moderated_by_last_name || "", - is_valid: item.is_valid === undefined ? true : item.is_valid, - }; - return setRows((prevData) => [ ...prevData, createData( - updatedItem.id, - updatedItem.description, - updatedItem.sender_first_name + " " + updatedItem.sender_last_name, - updatedItem.receiver_first_name + - " " + - updatedItem.receiver_last_name, - updatedItem.core_value_name, - updatedItem.total_reward_points, - updatedItem.created_at, - updatedItem.reported_by_first_name + - " " + - updatedItem.reported_by_last_name, - updatedItem.reporting_comment, - updatedItem.reported_at, - updatedItem.moderated_by_first_name + - " " + - updatedItem.moderated_by_last_name, - updatedItem.moderator_comment, - updatedItem.is_valid + item.id, + item.description, + item.sender_first_name + " " + item.sender_last_name, + item.receiver_first_name + " " + item.receiver_last_name, + item.core_value_name, + item.total_reward_points, + item.created_at ), ]); }); @@ -358,13 +281,6 @@ export default function AppreciationTable(props: IPropsTable) { setSelected([]); }; - const [open, setOpen] = useState(false); - - const handleClickOpen = (id: number) => { - setId(id); - setOpen(true); - }; - const handleChangePage = (event: unknown, newPage: number) => { setPage(newPage); }; @@ -388,15 +304,10 @@ export default function AppreciationTable(props: IPropsTable) { [order, orderBy, page, rowsPerPage, rows] ); - const [id, setId] = useState(0); - return ( - +
- {row.description} + {row.description}

+ } + sx={{ fontSize: "20px" }} + placement="bottom-start" + > + {row.description} +
+ + + {row.sender}

+ } + sx={{ fontSize: "20px" }} + placement="bottom-start" + > + {row.sender} +
+ +
+ + {row.receiver}

+ } + sx={{ fontSize: "20px" }} + placement="bottom-start" + > + {row.receiver} +
+ +
+ + {row.coreValue}

+ } + sx={{ fontSize: "20px" }} + placement="bottom-start" + > + {row.coreValue} +
+
+ + {row.rewardPoints}

+ } + sx={{ fontSize: "20px" }} + placement="bottom-start" + > + {row.rewardPoints} +
+
+ + + {row.date == undefined + ? row.date + : new Date(row.date).toLocaleString()} +

+ } + sx={{ fontSize: "20px" }} + placement="bottom-start" + > + + {row.date == undefined + ? row.date + : new Date(row.date).toLocaleString()} + +
- {row.sender} - {row.receiver} - {row.coreValue} - {row.rewardPoints} - - {props.filter === "appreciations" ? ( - - {row.date == undefined - ? row.date - : new Date(row.date).toLocaleString()} - - ) : ( - <> - )} - {props.filter === "reported" ? ( - <> - {row.reportedBy} - - {row.reportingComment} - - - {row.reportedAt == undefined - ? row.reportedAt - : new Date(row.reportedAt).toLocaleString()} - - {row.moderatedBy} - - {row.moderatorComment} - - {row.isValid ? ( - - handleClickOpen(row.id)}> - - - - ) : ( - - )} - - ) : ( - <> - )} ); })} @@ -489,7 +476,7 @@ export default function AppreciationTable(props: IPropsTable) {
-
); -} +} \ No newline at end of file diff --git a/src/appreciations/components/badgeAvatars.tsx b/src/appreciations/components/badgeAvatars.tsx deleted file mode 100644 index ef511ea..0000000 --- a/src/appreciations/components/badgeAvatars.tsx +++ /dev/null @@ -1,30 +0,0 @@ -import { styled } from "@mui/material/styles"; -import Badge from "@mui/material/Badge"; -import Avatar from "@mui/material/Avatar"; - - -const SmallAvatar = styled(Avatar)(({ theme }) => ({ - width: 50, - height: 50, - border: `2px solid ${theme.palette.background.paper}`, - left:"25px", - bottom:"15px" -})); - -export default function BadgeAvatars() { - return ( - - } - > - - - ); -} diff --git a/src/appreciations/components/card.css b/src/appreciations/components/card.css deleted file mode 100644 index 8b13789..0000000 --- a/src/appreciations/components/card.css +++ /dev/null @@ -1 +0,0 @@ - diff --git a/src/appreciations/components/card.tsx b/src/appreciations/components/card.tsx deleted file mode 100644 index b763249..0000000 --- a/src/appreciations/components/card.tsx +++ /dev/null @@ -1,60 +0,0 @@ -import Box from "@mui/material/Box"; -import Card from "@mui/material/Card"; -import CardContent from "@mui/material/CardContent"; -import Typography from "@mui/material/Typography"; -import "./card.css"; -import BadgeAvatars from "./badgeAvatars"; - -const bull = ( - - • - -); - -export default function AppreciationCard() { - return ( - - - - - - - - - - - Mangesh Pawar - - Technical Lead - - Appriciated by - - Manas Joshi - - 10 days ago - - - - - Core Value - - - Technical Excellence - - - - - - ); -} diff --git a/src/appreciations/components/dialogeBox.tsx b/src/appreciations/components/deleteDialogueBox.tsx similarity index 99% rename from src/appreciations/components/dialogeBox.tsx rename to src/appreciations/components/deleteDialogueBox.tsx index a3342ed..9d65ace 100644 --- a/src/appreciations/components/dialogeBox.tsx +++ b/src/appreciations/components/deleteDialogueBox.tsx @@ -77,4 +77,4 @@ export default function DeleteDialog(props: IProps) { ); -} +} \ No newline at end of file diff --git a/src/appreciations/components/reportedAppreciationTable.tsx b/src/appreciations/components/reportedAppreciationTable.tsx new file mode 100644 index 0000000..3bfd915 --- /dev/null +++ b/src/appreciations/components/reportedAppreciationTable.tsx @@ -0,0 +1,690 @@ +import { useEffect, useState, useMemo } from "react"; +import Box from "@mui/material/Box"; +import Table from "@mui/material/Table"; +import TableBody from "@mui/material/TableBody"; +import TableCell from "@mui/material/TableCell"; +import TableContainer from "@mui/material/TableContainer"; +import TableHead from "@mui/material/TableHead"; +import TablePagination from "@mui/material/TablePagination"; +import TableRow from "@mui/material/TableRow"; +import TableSortLabel from "@mui/material/TableSortLabel"; +import Toolbar from "@mui/material/Toolbar"; +import Paper from "@mui/material/Paper"; +import IconButton from "@mui/material/IconButton"; +import DeleteIcon from "@mui/icons-material/Delete"; +import { visuallyHidden } from "@mui/utils"; +import { IPropsTable } from "../types"; +import DeleteDialog from "./deleteDialogueBox"; +import { Button, Tooltip } from "@mui/material"; +import { useSelector } from "react-redux"; +import CheckIcon from "@mui/icons-material/Check"; +import { useReportedAppreciationReportQuery } from "../apiSlice"; +import { RootState } from "../../store"; +import ResolveDialog from "./resolveDialogueBox"; + +interface Data { + id: number; + description: string; + sender: string; + receiver: string; + coreValue: string; + rewardPoints: number; + date: number; + reportedBy: string; + reportingComment: string; + reportedAt: number; + moderatedBy: string; + moderatorComment: string; + status: string; +} + +function createData( + id: number, + description: string, + sender: string, + receiver: string, + coreValue: string, + rewardPoints: number, + date: number, + reportedBy: string, + reportingComment: string, + reportedAt: number, + moderatedBy: string, + moderatorComment: string, + status: string +): Data { + return { + id, + description, + sender, + receiver, + coreValue, + rewardPoints, + date, + reportedBy, + reportingComment, + reportedAt, + moderatedBy, + moderatorComment, + status, + }; +} + +function descendingComparator(a: T, b: T, orderBy: keyof T) { + if (b[orderBy] < a[orderBy]) { + return -1; + } + if (b[orderBy] > a[orderBy]) { + return 1; + } + return 0; +} + +type Order = "asc" | "desc"; + +function getComparator( + order: Order, + orderBy: Key +): ( + a: { [key in Key]: number | string | boolean }, + b: { [key in Key]: number | string | boolean } +) => number { + return order === "desc" + ? (a, b) => descendingComparator(a, b, orderBy) + : (a, b) => -descendingComparator(a, b, orderBy); +} + +function stableSort( + array: readonly T[], + comparator: (a: T, b: T) => number +) { + const stabilizedThis = array.map((el, index) => [el, index] as [T, number]); + stabilizedThis.sort((a, b) => { + const order = comparator(a[0], b[0]); + if (order !== 0) { + return order; + } + return a[1] - b[1]; + }); + return stabilizedThis.map((el) => el[0]); +} + +interface HeadCell { + disablePadding: boolean; + id: keyof Data; + label: string; + numeric: boolean; +} + +interface EnhancedTableProps { + numSelected: number; + onRequestSort: ( + event: React.MouseEvent, + property: keyof Data + ) => void; + onSelectAllClick: (event: React.ChangeEvent) => void; + order: Order; + orderBy: string; + rowCount: number; +} + +const headCells: HeadCell[] = [ + { + id: "description", + numeric: false, + disablePadding: false, + label: "Description", + }, + { + id: "sender", + numeric: false, + disablePadding: true, + label: "Appreciated By", + }, + { + id: "receiver", + numeric: false, + disablePadding: false, + label: "Appreciation To", + }, + { + id: "coreValue", + numeric: false, + disablePadding: false, + label: "Core Value", + }, + { + id: "rewardPoints", + numeric: true, + disablePadding: false, + label: "Reward Points", + }, + { + id: "reportedBy", + numeric: false, + disablePadding: false, + label: "Reported By", + }, + { + id: "reportingComment", + numeric: false, + disablePadding: false, + label: "Report", + }, + { + id: "reportedAt", + numeric: true, + disablePadding: false, + label: "Reported At", + }, + { + id: "moderatedBy", + numeric: false, + disablePadding: false, + label: "Moderated By", + }, + { + id: "moderatorComment", + numeric: false, + disablePadding: false, + label: "Moderator Comment", + }, + { + id: "status", + numeric: false, + disablePadding: false, + label: "Status", + }, +]; + +function EnhancedTableHead(props: EnhancedTableProps) { + const { order, orderBy, onRequestSort } = props; + const createSortHandler = + (property: keyof Data) => (event: React.MouseEvent) => { + onRequestSort(event, property); + }; + + return ( + + + {headCells.map((headCell) => ( + + + {headCell.label} + {orderBy === headCell.id ? ( + + {order === "desc" ? "sorted descending" : "sorted ascending"} + + ) : null} + + + ))} + + Delete + Resolve + + + ); +} + +interface EnhancedTableToolbarProps { + numSelected: number; + setPage: (value: number | ((prevVar: number) => number)) => void; +} + +function EnhancedTableToolbar(props: EnhancedTableToolbarProps) { + const authToken = useSelector( + (state: RootState) => state.loginStore.authToken + ); + const { data: reportedAppreciations, error: reportedAppreciationError } = + useReportedAppreciationReportQuery({ authToken }); + const handleClick = () => { + if (reportedAppreciations) { + // Create a URL for the Blob + const blob = new Blob([reportedAppreciations], { + type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", + }); + + // Create a link element and trigger a download + const url = window.URL.createObjectURL(blob); + const a = document.createElement("a"); + a.href = url; + a.download = "ReportedAppreciaitionsReport.xlsx"; // Set the desired filename + document.body.appendChild(a); + a.click(); + document.body.removeChild(a); + window.URL.revokeObjectURL(url); + } else if (reportedAppreciationError) { + console.error("Error downloading the report:", reportedAppreciationError); + } + }; + return ( + + {/* + Appreciations + */} + + + + ); +} +export default function ReportedAppreciationTable(props: IPropsTable) { + const [order, setOrder] = useState("desc"); + const [orderBy, setOrderBy] = useState("date"); + const [selected, setSelected] = useState([]); + const [page, setPage] = useState(0); + const [rowsPerPage, setRowsPerPage] = useState(7); + const [rows, setRows] = useState([]); + + useEffect(() => { + const data = props.response; + setRows([]); + + data?.map((item) => { + const updatedItem = { + ...item, + reported_by_first_name: item.reported_by_first_name || "", + reported_by_last_name: item.reported_by_last_name || "", + moderated_by_first_name: item.moderated_by_first_name || "", + moderated_by_last_name: item.moderated_by_last_name || "", + is_valid: item.is_valid === undefined ? true : item.is_valid, + }; + + return setRows((prevData) => [ + ...prevData, + createData( + updatedItem.id, + updatedItem.description, + updatedItem.sender_first_name + " " + updatedItem.sender_last_name, + updatedItem.receiver_first_name + + " " + + updatedItem.receiver_last_name, + updatedItem.core_value_name, + updatedItem.total_reward_points, + updatedItem.created_at, + updatedItem.reported_by_first_name + + " " + + updatedItem.reported_by_last_name, + updatedItem.reporting_comment, + updatedItem.reported_at, + updatedItem.moderated_by_first_name + + " " + + updatedItem.moderated_by_last_name, + updatedItem.moderator_comment, + updatedItem.status + ), + ]); + }); + }, [props.response]); + + const handleRequestSort = ( + event: React.MouseEvent, + property: keyof Data + ) => { + const isAsc = orderBy === property && order === "asc"; + setOrder(isAsc ? "desc" : "asc"); + setOrderBy(property); + }; + + const handleSelectAllClick = (event: React.ChangeEvent) => { + if (event.target.checked) { + const newSelected = rows.map((n) => n.id); + setSelected(newSelected); + return; + } + setSelected([]); + }; + + const [openDelete, setOpenDelete] = useState(false); + const [openResolve, setOpenResolve] = useState(false); + + const handleClickOpenDelete = (id: number) => { + setId(id); + setOpenDelete(true); + }; + + const handleClickOpenResolve = (id: number) => { + setId(id); + setOpenResolve(true); + }; + + const handleChangePage = (event: unknown, newPage: number) => { + setPage(newPage); + }; + + const handleChangeRowsPerPage = ( + event: React.ChangeEvent + ) => { + setRowsPerPage(parseInt(event.target.value, 10)); + setPage(0); + }; + + const emptyRows = + page > 0 ? Math.max(0, (1 + page) * rowsPerPage - rows.length) : 0; + + const visibleRows = useMemo( + () => + stableSort(rows, getComparator(order, orderBy)).slice( + page * rowsPerPage, + page * rowsPerPage + rowsPerPage + ), + [order, orderBy, page, rowsPerPage, rows] + ); + + const [id, setId] = useState(0); + + return ( + + + + + + + + {visibleRows.map((row, index) => { + const labelId = `enhanced-table-checkbox-${index}`; + + return ( + + + {row.description}

+ } + sx={{ fontSize: "20px" }} + placement="bottom-start" + > + {row.description} +
+
+ + {row.sender}

+ } + sx={{ fontSize: "20px" }} + placement="bottom-start" + > + {row.sender} +
+
+ + {row.receiver}

+ } + sx={{ fontSize: "20px" }} + placement="bottom-start" + > + {row.receiver} +
+ +
+ + {row.coreValue}

+ } + sx={{ fontSize: "20px" }} + placement="bottom-start" + > + {row.coreValue} +
+ +
+ + {row.rewardPoints}

+ } + sx={{ fontSize: "20px" }} + placement="bottom-start" + > + {row.rewardPoints} +
+ +
+ + {row.reportedBy}

+ } + sx={{ fontSize: "20px" }} + placement="bottom-start" + > + {row.reportedBy} +
+ +
+ + {row.reportingComment}

+ } + sx={{ fontSize: "20px" }} + placement="bottom-start" + > + {row.reportingComment} +
+ +
+ + {row.reportedAt == undefined + ? row.reportedAt + : new Date(row.reportedAt).toLocaleString()}

+ } + sx={{ fontSize: "20px" }} + placement="bottom-start" + > + {row.reportedAt == undefined + ? row.reportedAt + : new Date(row.reportedAt).toLocaleString()} +
+ +
+ + {" "} + {row.moderatedBy}

+ } + sx={{ fontSize: "20px" }} + placement="bottom-start" + > + {row.moderatedBy} +
+ +
+ + {row.moderatorComment}

+ } + sx={{ fontSize: "20px" }} + placement="bottom-start" + > + {row.moderatorComment} +
+ +
+ {row.status} + {row.status === "reported" ? ( + + handleClickOpenDelete(row.id)} + > + + + + ) : ( + <> + + + )} + {row.status === "reported" ? ( + + handleClickOpenResolve(row.id)} + > + + + + ) : ( + <> + + + )} +
+ ); + })} + {emptyRows > 0 && ( + + + + )} +
+
+
+ +
+ + +
+ ); +} \ No newline at end of file diff --git a/src/appreciations/components/resolveDialogueBox.tsx b/src/appreciations/components/resolveDialogueBox.tsx new file mode 100644 index 0000000..3b35001 --- /dev/null +++ b/src/appreciations/components/resolveDialogueBox.tsx @@ -0,0 +1,80 @@ +import * as React from 'react'; +import Button from '@mui/material/Button'; +import Dialog from '@mui/material/Dialog'; +import DialogActions from '@mui/material/DialogActions'; +import DialogContent from '@mui/material/DialogContent'; +import DialogContentText from '@mui/material/DialogContentText'; +import DialogTitle from '@mui/material/DialogTitle'; +import TextField from '@mui/material/TextField'; +import { useResolveAppreciationMutation } from '../apiSlice'; +import { moderationReq } from '../types'; +import { toast } from 'react-toastify'; +import { RootState } from '../../store'; +import { useSelector } from 'react-redux'; + +interface IProps { + open: boolean; + setOpen: (value: boolean | ((prevVar: boolean) => boolean)) => void; + id: number; +} +export default function ResolveDialog(props: IProps) { + + const authToken = useSelector((state: RootState) => state.loginStore.authToken); + + const handleClose = () => { + props.setOpen(false); + }; + + const [resolveAppreciation] = useResolveAppreciationMutation(); + + return ( + + ) => { + event.preventDefault(); + const formData = new FormData(event.currentTarget); + const formJson = Object.fromEntries((formData as any).entries()); + const moderationComment = formJson.moderator_comment; + const req: moderationReq = { + moderator_comment: moderationComment, + id: props.id, + authToken: authToken + } + resolveAppreciation(req).unwrap().then(resp=>{ + toast.success(resp.message) + }).catch(err=>{ + toast.error(err.data.message) + }) + handleClose(); + }, + }} + > + Resolve Appreciation + + + Are you sure you want to resolve the appreciation? + + + + + + + + + + ); +} \ No newline at end of file diff --git a/src/appreciations/components/toggleButton.tsx b/src/appreciations/components/toggleButton.tsx deleted file mode 100644 index 5ba407e..0000000 --- a/src/appreciations/components/toggleButton.tsx +++ /dev/null @@ -1,29 +0,0 @@ -import * as React from 'react'; -import ToggleButton from '@mui/material/ToggleButton'; -import ToggleButtonGroup from '@mui/material/ToggleButtonGroup'; -import { IPropsButtons } from '../types'; - -export default function AppreciationToggleButton(props: IPropsButtons) { - const [alignment, setAlignment] = React.useState('appreciations'); - - const handleChange = ( - event: React.MouseEvent, - newAlignment: string, - ) => { - setAlignment(newAlignment); - props.setFilter(newAlignment) - }; - - return ( - - Appreciations - Reported - - ); -} diff --git a/src/appreciations/index.tsx b/src/appreciations/index.tsx index e301294..38288ec 100644 --- a/src/appreciations/index.tsx +++ b/src/appreciations/index.tsx @@ -1,51 +1,116 @@ -import AppreciationTable from "./components/table"; -import { useGetAppreciationsQuery, useGetReportedAppreciationsQuery } from "./apiSlice"; -import { useEffect, useMemo, useState } from "react"; +import { + useGetAppreciationsQuery, + useGetReportedAppreciationsQuery, +} from "./apiSlice"; +import { useEffect, useState } from "react"; import { useSelector } from "react-redux"; import { RootState } from "../store"; import { useNavigate } from "react-router-dom"; -import TemporaryDrawer from "../sideBar"; +import PermanentDrawerLeft from "../permanentSidebar"; +import * as React from "react"; +import Tabs from "@mui/material/Tabs"; +import Tab from "@mui/material/Tab"; +import Box from "@mui/material/Box"; +import "./appreciations.css" +import AppreciationTable from "./components/appreciationTable"; +import ReportedAppreciationTable from "./components/reportedAppreciationTable"; -const Appreciations = () => { - const navigate = useNavigate() - const authToken = useSelector((state: RootState) => state.loginStore.authToken); - const { data: appreciations, isError: listAppreciationsError } = useGetAppreciationsQuery({ - page: 1, - page_size: 10, - authToken: authToken - }); - const { data: reportedAppreciations, isError: listReportedAppreciationsError} = useGetReportedAppreciationsQuery({authToken: authToken}) - const [filter, setFilter] = useState("appreciations") - - useEffect(()=>{ - console.log("authtoken -> ",authToken) - if(authToken === ""){ - navigate("/login") - }else{ - navigate("/appreciations") - } - },[authToken]) +interface TabPanelProps { + children?: React.ReactNode; + index: number; + value: number; +} - const response = useMemo(() => { - if(filter == "appreciations"){ - return appreciations?.data.appreciations - } - else if(filter == "reported"){ - return reportedAppreciations?.data.appreciations - } +function CustomTabPanel(props: TabPanelProps) { + const { children, value, index, ...other } = props; + + return ( + + ); +} + +function a11yProps(index: number) { + return { + id: `simple-tab-${index}`, + "aria-controls": `simple-tabpanel-${index}`, + }; +} - },[filter, appreciations?.data.appreciations, reportedAppreciations?.data.appreciations]) +export function AppTabs() { + const [value, setValue] = useState(0); + + const handleChange = (event: React.SyntheticEvent, newValue: number) => { + setValue(newValue); + }; + + const navigate = useNavigate(); + const authToken = useSelector( + (state: RootState) => state.loginStore.authToken + ); + const { data: appreciations, isError: listAppreciationsError } = + useGetAppreciationsQuery({ + page: 1, + page_size: 1000, + authToken: authToken, + }); + const { + data: reportedAppreciations, + isError: listReportedAppreciationsError, + } = useGetReportedAppreciationsQuery({ authToken: authToken }); + + useEffect(() => { + console.log("authtoken -> ", authToken); + if (authToken === "") { + navigate("/login"); + } else { + navigate("/appreciations"); + } + }, [authToken]); return ( - <> - - {listAppreciationsError || listReportedAppreciationsError ? ( -

Error

- ) : ( - - )} - + + + + + + + + + {listAppreciationsError || listReportedAppreciationsError ? ( +

Error

+ ) : ( + + )} +
+ + {!listReportedAppreciationsError ? ( + + ) : ( + <> + )} + +
); +} + +const Appreciations = () => { + return } />; }; -export default Appreciations; +export default Appreciations; \ No newline at end of file diff --git a/src/appreciations/types.tsx b/src/appreciations/types.tsx index 80f350a..702461e 100644 --- a/src/appreciations/types.tsx +++ b/src/appreciations/types.tsx @@ -1,72 +1,72 @@ export interface appreciation { - id: number; - core_value_name: string; - core_value_description: string; - description: string; - total_reward_points: number; - quarter: number; - sender_first_name: string; - sender_last_name: string; - sender_image_url: string; - sender_designation: string; - receiver_first_name:string; - receiver_last_name: string; - receiver_image_url: string; - receiver_designation: string; - total_rewards: number; - given_reward_point: number; - created_at: number; - updated_at: number; - is_valid: boolean; - reported_by_first_name: string | undefined ; - reported_by_last_name: string | undefined; - reporting_comment: string; - reported_at: number; - moderated_by_first_name: string; - moderated_by_last_name: string; - moderator_comment: string; - moderated_at: number; -} - -interface metadata{ - page: number; - total_page: number; - page_size: number; - total_records: number; -} - -interface data{ - appreciations: appreciation[] - metadata: metadata -} - -export interface response { - success: boolean; - message: string; - status_code: number; - data: data; -} - -export interface IPropsTable { - response: appreciation[] | undefined - filter: string - setFilter: (value: string | ((prevVar: string) => string)) => void; -} - -export interface IPropsButtons{ - setFilter: (value: string | ((prevVar: string) => string)) => void; -} - -export interface moderationReq{ - moderator_comment: string - id: number - authToken: string -} - -export interface moderationResponse { - success: boolean; - message: string; - status_code: number; - data: object; -} \ No newline at end of file + id: number; + core_value_name: string; + core_value_description: string; + description: string; + total_reward_points: number; + quarter: number; + sender_first_name: string; + sender_last_name: string; + sender_image_url: string; + sender_designation: string; + receiver_first_name:string; + receiver_last_name: string; + receiver_image_url: string; + receiver_designation: string; + total_rewards: number; + given_reward_point: number; + created_at: number; + updated_at: number; + is_valid: boolean; + reported_by_first_name: string | undefined ; + reported_by_last_name: string | undefined; + reporting_comment: string; + reported_at: number; + moderated_by_first_name: string; + moderated_by_last_name: string; + moderator_comment: string; + moderated_at: number; + status: string; + } + + interface metadata{ + page: number; + total_page: number; + page_size: number; + total_records: number; + } + + interface data{ + appreciations: appreciation[] + metadata: metadata + } + + export interface response { + success: boolean; + message: string; + status_code: number; + data: data; + } + + export interface IPropsTable { + response: appreciation[] | undefined + } + + export interface IPropsButtons{ + setFilter: (value: string | ((prevVar: string) => string)) => void; + setPage: (value: number | ((prevVar: number) => number)) => void; + } + + export interface moderationReq{ + moderator_comment: string + id: number + authToken: string + } + + export interface moderationResponse { + success: boolean; + message: string; + status_code: number; + data: object; + } \ No newline at end of file diff --git a/src/store.tsx b/src/store.tsx index 012e916..e1fc2b8 100644 --- a/src/store.tsx +++ b/src/store.tsx @@ -2,6 +2,7 @@ import { configureStore } from '@reduxjs/toolkit'; import { loginApiSlice } from './login/apiSlice.tsx'; import loginReducer from './login/slice'; import sidebarReducer from './permanentSidebar/slice.tsx'; +import { appreciationSlice } from './appreciations/apiSlice'; export const store = configureStore({ @@ -11,12 +12,13 @@ export const store = configureStore({ loginStore: loginReducer, sidebarStore: sidebarReducer, [loginApiSlice.reducerPath]: loginApiSlice.reducer, + [appreciationSlice.reducerPath]: appreciationSlice.reducer, }, middleware: (getDefaultMiddleware) => - getDefaultMiddleware().concat(loginApiSlice.middleware), + getDefaultMiddleware().concat(loginApiSlice.middleware).concat(appreciationSlice.middleware), }); From 5ba4b8d5cc57380a23adcad2a41bcf1403f5743f Mon Sep 17 00:00:00 2001 From: Sharyu Marwadi Date: Thu, 22 Aug 2024 23:11:38 +0530 Subject: [PATCH 19/23] [feature/PEER-57-Config] config page done --- src/config/apiSlice.tsx | 5 +- src/config/components/editGradeDialogue.tsx | 2 +- .../components/editRenewalFreqDialog.tsx | 2 +- src/config/components/grades.tsx | 11 +- src/config/components/orgConfig.tsx | 15 +- src/config/components/quater.tsx | 10 +- src/config/index.tsx | 142 ++++++++++++++---- src/config/types.tsx | 4 +- src/sideBar/slice.tsx | 23 --- src/store.tsx | 4 +- 10 files changed, 143 insertions(+), 75 deletions(-) delete mode 100644 src/sideBar/slice.tsx diff --git a/src/config/apiSlice.tsx b/src/config/apiSlice.tsx index 7b612d5..0efaea2 100644 --- a/src/config/apiSlice.tsx +++ b/src/config/apiSlice.tsx @@ -1,10 +1,11 @@ import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react"; import { editGradeReq, editGradeResp, editRenewalFrequencyReq, editRenewalFrequencyResp, gradesResponse, orgConfigResponse } from "./types"; +import { baseUrl } from "../constants"; export const configSlice = createApi({ reducerPath: "configSlice", baseQuery: fetchBaseQuery({ - baseUrl: "http://localhost:33001/peerly", + baseUrl: baseUrl, }), tagTypes: ["gradesConfig","orgConfig"], endpoints: (builder) => ({ @@ -64,4 +65,4 @@ export const { useGetOrgConfigQuery, useEditRenewalFrequencyMutation, useEditGradeMutation -} = configSlice; +} = configSlice; \ No newline at end of file diff --git a/src/config/components/editGradeDialogue.tsx b/src/config/components/editGradeDialogue.tsx index be299dd..366d2bb 100644 --- a/src/config/components/editGradeDialogue.tsx +++ b/src/config/components/editGradeDialogue.tsx @@ -76,4 +76,4 @@ export default function EditGradeDialog(props: IProps) { ); -} +} \ No newline at end of file diff --git a/src/config/components/editRenewalFreqDialog.tsx b/src/config/components/editRenewalFreqDialog.tsx index 23bcdcb..23696b0 100644 --- a/src/config/components/editRenewalFreqDialog.tsx +++ b/src/config/components/editRenewalFreqDialog.tsx @@ -73,4 +73,4 @@ export default function EditRenewalFreqDialog(props: IProps) { ); -} +} \ No newline at end of file diff --git a/src/config/components/grades.tsx b/src/config/components/grades.tsx index e0d7aa7..c00d6b4 100644 --- a/src/config/components/grades.tsx +++ b/src/config/components/grades.tsx @@ -9,8 +9,8 @@ import { grade } from "../types"; import { useEffect, useState } from "react"; import BorderColorIcon from "@mui/icons-material/BorderColor"; -function createData(id: number, name: string, points: number) { - return { id, name, points }; +function createData(id: number, name: string, points: number, updated_by: string) { + return { id, name, points, updated_by }; } interface IProps { @@ -31,7 +31,7 @@ export default function GradesTable(props: IProps) { props.gradesList?.map((grade) => { setRows((prevData) => [ ...prevData, - createData(grade.id, grade.name, grade.points), + createData(grade.id, grade.name, grade.points, grade.updated_by), ]); }); }, [props.gradesList]); @@ -43,6 +43,8 @@ export default function GradesTable(props: IProps) { Sr No Grade Points + Updated By + @@ -56,6 +58,7 @@ export default function GradesTable(props: IProps) { {row.name} {row.points} + {row.updated_by} { @@ -71,4 +74,4 @@ export default function GradesTable(props: IProps) { ); -} +} \ No newline at end of file diff --git a/src/config/components/orgConfig.tsx b/src/config/components/orgConfig.tsx index f07a5a7..abb4ab2 100644 --- a/src/config/components/orgConfig.tsx +++ b/src/config/components/orgConfig.tsx @@ -6,13 +6,13 @@ import TableRow from "@mui/material/TableRow"; import Paper from "@mui/material/Paper"; import { orgConfig } from "../types"; import { useEffect, useState } from "react"; -import BorderColorIcon from "@mui/icons-material/BorderColor"; function createData( id: number | undefined, - reward_quota_renewal_frequency: number | undefined + reward_quota_renewal_frequency: number | undefined, + updated_by: string | undefined ) { - return { id, reward_quota_renewal_frequency }; + return { id, reward_quota_renewal_frequency, updated_by }; } interface IProps { @@ -29,7 +29,8 @@ export default function OrgConfigTable(props: IProps) { setRow( createData( props.orgConfig?.id, - props.orgConfig?.reward_quota_renewal_frequency + props.orgConfig?.reward_quota_renewal_frequency, + props.orgConfig?.updated_by, ) ); }, [props.orgConfig]); @@ -48,12 +49,12 @@ export default function OrgConfigTable(props: IProps) { ? `${row?.reward_quota_renewal_frequency} month` : `${row?.reward_quota_renewal_frequency} months`} - + {/* - + */} ); -} +} \ No newline at end of file diff --git a/src/config/components/quater.tsx b/src/config/components/quater.tsx index 59ca183..b037978 100644 --- a/src/config/components/quater.tsx +++ b/src/config/components/quater.tsx @@ -15,10 +15,10 @@ function createData( } const rows = [ - createData(1,new Date(new Date().getFullYear(), 0, 1),new Date(new Date().getFullYear(), 2, 31)), - createData(2,new Date(new Date().getFullYear(), 3, 1),new Date(new Date().getFullYear(), 5, 30)), - createData(3,new Date(new Date().getFullYear(), 6, 1),new Date(new Date().getFullYear(), 8, 31)), - createData(4,new Date(new Date().getFullYear(), 9, 1),new Date(new Date().getFullYear(), 11, 31)) + createData(1,new Date(new Date().getFullYear(), 3, 1),new Date(new Date().getFullYear(), 5, 30)), + createData(2,new Date(new Date().getFullYear(), 6, 1),new Date(new Date().getFullYear(), 8, 31)), + createData(3,new Date(new Date().getFullYear(), 9, 1),new Date(new Date().getFullYear(), 11, 31)), + createData(4,new Date(new Date().getFullYear(), 0, 1),new Date(new Date().getFullYear(), 2, 31)), ]; export default function QuaterTable() { @@ -49,4 +49,4 @@ export default function QuaterTable() { ); -} +} \ No newline at end of file diff --git a/src/config/index.tsx b/src/config/index.tsx index e3821fc..6424f7d 100644 --- a/src/config/index.tsx +++ b/src/config/index.tsx @@ -1,6 +1,4 @@ -import { Typography } from "@mui/material"; import QuaterTable from "./components/quater"; -import TemporaryDrawer from "../sideBar"; import { useGetGradesQuery, useGetOrgConfigQuery } from "./apiSlice"; import { useSelector } from "react-redux"; import { RootState } from "../store"; @@ -10,40 +8,124 @@ import EditRenewalFreqDialog from "./components/editRenewalFreqDialog"; import { useEffect, useState } from "react"; import EditGradeDialog from "./components/editGradeDialogue"; import { useNavigate } from "react-router-dom"; +import PermanentDrawerLeft from "../permanentSidebar"; +import * as React from "react"; +import Tabs from "@mui/material/Tabs"; +import Tab from "@mui/material/Tab"; +import Box from "@mui/material/Box"; -const Config = () => { - const navigate = useNavigate() - const authToken = useSelector((state: RootState) => state.loginStore.authToken); - const {data: gradesResp, isError: listGradesError} = useGetGradesQuery({ - authToken: authToken - }); - const {data: orgConfigResp, isError: getOrgConfigError} = useGetOrgConfigQuery({ - authToken: authToken +interface TabPanelProps { + children?: React.ReactNode; + index: number; + value: number; +} + +function CustomTabPanel(props: TabPanelProps) { + const { children, value, index, ...other } = props; + + return ( + + ); +} + +function a11yProps(index: number) { + return { + id: `simple-tab-${index}`, + "aria-controls": `simple-tabpanel-${index}`, + }; +} + +export function ConfigTabs() { + const [value, setValue] = useState(0); + + const handleChange = (event: React.SyntheticEvent, newValue: number) => { + setValue(newValue); + }; + + const navigate = useNavigate(); + const authToken = useSelector( + (state: RootState) => state.loginStore.authToken + ); + const { data: gradesResp, isError: listGradesError } = useGetGradesQuery({ + authToken: authToken, }); + const { data: orgConfigResp, isError: getOrgConfigError } = + useGetOrgConfigQuery({ + authToken: authToken, + }); const [openEditFrequency, setOpenEditFrequency] = useState(false); const [openEditGrade, setOpenEditGrade] = useState(false); - const [id,setId] = useState(0); - useEffect(()=>{ - console.log("authtoken -> ",authToken) - if(authToken === ""){ - navigate("/login") - }else{ - navigate("/config") + const [id, setId] = useState(0); + useEffect(() => { + console.log("authtoken -> ", authToken); + if (authToken === "") { + navigate("/login"); + } else { + navigate("/config"); } - },[authToken]) + }, [authToken]); + return ( - <> - - Quaters - - Grades - {!listGradesError ? : <>} - Organisation Config - {!getOrgConfigError ? : <>} - - - + + + + + + + + + + + + + {!listGradesError ? ( + + ) : ( + <> + )} + + + {!getOrgConfigError ? ( + + ) : ( + <> + )} + + + + ); +} + +const Config = () => { + return } />; }; -export default Config; +export default Config; \ No newline at end of file diff --git a/src/config/types.tsx b/src/config/types.tsx index 5f009d7..5734606 100644 --- a/src/config/types.tsx +++ b/src/config/types.tsx @@ -2,6 +2,7 @@ export interface grade { id: number; name: string; points: number; + updated_by: string; } export interface gradesResponse { @@ -14,6 +15,7 @@ export interface gradesResponse { export interface orgConfig { id: number | undefined; reward_quota_renewal_frequency: number | undefined; + updated_by : string |undefined; } export interface orgConfigResponse { @@ -45,4 +47,4 @@ export interface editGradeResp { success: string; message: string; status_code: number; -} +} \ No newline at end of file diff --git a/src/sideBar/slice.tsx b/src/sideBar/slice.tsx deleted file mode 100644 index 6862ff5..0000000 --- a/src/sideBar/slice.tsx +++ /dev/null @@ -1,23 +0,0 @@ -import { createSlice, PayloadAction } from "@reduxjs/toolkit"; - -export interface SidebarStoreState { - route: string; -} - -const initialStateValue: SidebarStoreState = { - route: "/", -}; - -export const sidebarSlice = createSlice({ - name: "sidebarStore", - initialState: initialStateValue, - reducers: { - getRoute: (state, action: PayloadAction) => { - state.route = action.payload; - }, - }, -}); - -export const { getRoute } = sidebarSlice.actions; - -export default sidebarSlice.reducer; diff --git a/src/store.tsx b/src/store.tsx index e1fc2b8..0cfaf82 100644 --- a/src/store.tsx +++ b/src/store.tsx @@ -3,6 +3,7 @@ import { loginApiSlice } from './login/apiSlice.tsx'; import loginReducer from './login/slice'; import sidebarReducer from './permanentSidebar/slice.tsx'; import { appreciationSlice } from './appreciations/apiSlice'; +import { configSlice } from './config/apiSlice.tsx'; export const store = configureStore({ @@ -13,12 +14,13 @@ export const store = configureStore({ sidebarStore: sidebarReducer, [loginApiSlice.reducerPath]: loginApiSlice.reducer, [appreciationSlice.reducerPath]: appreciationSlice.reducer, + [configSlice.reducerPath]: configSlice.reducer, }, middleware: (getDefaultMiddleware) => - getDefaultMiddleware().concat(loginApiSlice.middleware).concat(appreciationSlice.middleware), + getDefaultMiddleware().concat(loginApiSlice.middleware).concat(appreciationSlice.middleware).concat(configSlice.middleware), }); From c08c171229c72cfe757771079451018d72d348c0 Mon Sep 17 00:00:00 2001 From: Sharyu Marwadi Date: Thu, 22 Aug 2024 23:28:14 +0530 Subject: [PATCH 20/23] [feature/PEER-53-Badges] badges page done --- src/App.tsx | 5 - .../components/appreciationTable.tsx | 30 +--- src/appreciations/index.tsx | 17 -- src/appreciations/types.tsx | 74 -------- src/badges/apiSlice.tsx | 5 +- src/badges/components/dialogueBox.tsx | 2 +- src/badges/components/table.tsx | 10 +- src/badges/index.tsx | 9 +- src/badges/types.tsx | 48 ++--- src/config/index.tsx | 167 ------------------ src/store.tsx | 4 +- 11 files changed, 42 insertions(+), 329 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index e8d53cd..801da49 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -9,7 +9,6 @@ import { useEffect } from "react"; import Home from "./home"; import Config from "./config"; import Badges from "./badges"; -import CoreValues from "./coreValues"; function App() { const router = createBrowserRouter([ @@ -33,10 +32,6 @@ function App() { path: "/badges", element: , }, - { - path: "/core_values", - element: , - }, ]); const dispatch = useDispatch(); diff --git a/src/appreciations/components/appreciationTable.tsx b/src/appreciations/components/appreciationTable.tsx index 39ec69e..ddb31f3 100644 --- a/src/appreciations/components/appreciationTable.tsx +++ b/src/appreciations/components/appreciationTable.tsx @@ -165,7 +165,6 @@ function EnhancedTableHead(props: EnhancedTableProps) { active={orderBy === headCell.id} direction={orderBy === headCell.id ? order : "asc"} onClick={createSortHandler(headCell.id)} - sx={props.filter =="reported" ? (headCell.id == "isValid"|| headCell.id == "rewardPoints" ? {width: "120px"} : {width: "160px"}) : {}} > {headCell.label} {orderBy === headCell.id ? ( @@ -183,10 +182,6 @@ function EnhancedTableHead(props: EnhancedTableProps) { interface EnhancedTableToolbarProps { numSelected: number; -<<<<<<< HEAD:src/appreciations/components/table.tsx - setFilter: (value: string | ((prevVar: string) => string)) => void; -======= ->>>>>>> 5ba4b8d5cc57380a23adcad2a41bcf1403f5743f:src/appreciations/components/appreciationTable.tsx setPage: (value: number | ((prevVar: number) => number)) => void; } @@ -218,7 +213,6 @@ function EnhancedTableToolbar(props: EnhancedTableToolbarProps) { }; return ( */} -<<<<<<< HEAD:src/appreciations/components/table.tsx - - - -======= ->>>>>>> 5ba4b8d5cc57380a23adcad2a41bcf1403f5743f:src/appreciations/components/appreciationTable.tsx ); } @@ -252,11 +240,7 @@ export default function AppreciationTable(props: IPropsTable) { const [orderBy, setOrderBy] = useState("date"); const [selected, setSelected] = useState([]); const [page, setPage] = useState(0); -<<<<<<< HEAD:src/appreciations/components/table.tsx - const [rowsPerPage, setRowsPerPage] = useState(8); -======= const [rowsPerPage, setRowsPerPage] = useState(7); ->>>>>>> 5ba4b8d5cc57380a23adcad2a41bcf1403f5743f:src/appreciations/components/appreciationTable.tsx const [rows, setRows] = useState([]); useEffect(() => { @@ -321,17 +305,9 @@ export default function AppreciationTable(props: IPropsTable) { ); return ( - + -<<<<<<< HEAD:src/appreciations/components/table.tsx - -======= ->>>>>>> 5ba4b8d5cc57380a23adcad2a41bcf1403f5743f:src/appreciations/components/appreciationTable.tsx >>>>>> 5ba4b8d5cc57380a23adcad2a41bcf1403f5743f:src/appreciations/components/appreciationTable.tsx component="div" count={rows.length} rowsPerPage={rowsPerPage} diff --git a/src/appreciations/index.tsx b/src/appreciations/index.tsx index 965a0ba..38288ec 100644 --- a/src/appreciations/index.tsx +++ b/src/appreciations/index.tsx @@ -6,10 +6,6 @@ import { useEffect, useState } from "react"; import { useSelector } from "react-redux"; import { RootState } from "../store"; import { useNavigate } from "react-router-dom"; -<<<<<<< HEAD -import TemporaryDrawer from "../sideBar"; -import PermanentDrawerLeft from "../permanentSidebar"; -======= import PermanentDrawerLeft from "../permanentSidebar"; import * as React from "react"; import Tabs from "@mui/material/Tabs"; @@ -18,7 +14,6 @@ import Box from "@mui/material/Box"; import "./appreciations.css" import AppreciationTable from "./components/appreciationTable"; import ReportedAppreciationTable from "./components/reportedAppreciationTable"; ->>>>>>> 5ba4b8d5cc57380a23adcad2a41bcf1403f5743f interface TabPanelProps { children?: React.ReactNode; @@ -81,17 +76,6 @@ export function AppTabs() { }, [authToken]); return ( -<<<<<<< HEAD - <> - {/* */} - {listAppreciationsError || listReportedAppreciationsError ? ( -

Error

- ) : ( - } /> - - )} - -======= ->>>>>>> 5ba4b8d5cc57380a23adcad2a41bcf1403f5743f ); } diff --git a/src/appreciations/types.tsx b/src/appreciations/types.tsx index 60e3e32..82873ef 100644 --- a/src/appreciations/types.tsx +++ b/src/appreciations/types.tsx @@ -1,78 +1,5 @@ export interface appreciation { -<<<<<<< HEAD - id: number; - core_value_name: string; - core_value_description: string; - description: string; - total_reward_points: number; - quarter: number; - sender_first_name: string; - sender_last_name: string; - sender_image_url: string; - sender_designation: string; - receiver_first_name:string; - receiver_last_name: string; - receiver_image_url: string; - receiver_designation: string; - total_rewards: number; - given_reward_point: number; - created_at: number; - updated_at: number; - is_valid: boolean; - reported_by_first_name: string | undefined ; - reported_by_last_name: string | undefined; - reporting_comment: string; - reported_at: number; - moderated_by_first_name: string; - moderated_by_last_name: string; - moderator_comment: string; - moderated_at: number; -} - -interface metadata{ - page: number; - total_page: number; - page_size: number; - total_records: number; -} - -interface data{ - appreciations: appreciation[] - metadata: metadata -} - -export interface response { - success: boolean; - message: string; - status_code: number; - data: data; -} - -export interface IPropsTable { - response: appreciation[] | undefined - filter: string - setFilter: (value: string | ((prevVar: string) => string)) => void; -} - -export interface IPropsButtons{ - setFilter: (value: string | ((prevVar: string) => string)) => void; - setPage: (value: number | ((prevVar: number) => number)) => void; -} - -export interface moderationReq{ - moderator_comment: string - id: number - authToken: string -} - -export interface moderationResponse { - success: boolean; - message: string; - status_code: number; - data: object; -} -======= id: number; core_value_name: string; core_value_description: string; @@ -143,4 +70,3 @@ export interface moderationResponse { status_code: number; data: object; } ->>>>>>> 5ba4b8d5cc57380a23adcad2a41bcf1403f5743f diff --git a/src/badges/apiSlice.tsx b/src/badges/apiSlice.tsx index e3b2424..ba4d49a 100644 --- a/src/badges/apiSlice.tsx +++ b/src/badges/apiSlice.tsx @@ -1,10 +1,11 @@ import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react"; import { badgesResponse, editBadgeReq, editBadgeResp } from "./types"; +import { baseUrl } from "../constants"; export const badgesSlice = createApi({ reducerPath: "badgesSlice", baseQuery: fetchBaseQuery({ - baseUrl: "http://localhost:33001/peerly", + baseUrl: baseUrl, }), tagTypes: ["badges"], endpoints: (builder) => ({ @@ -38,4 +39,4 @@ export const badgesSlice = createApi({ export const { useGetBadgesQuery, useEditBadgeMutation -} = badgesSlice; +} = badgesSlice; \ No newline at end of file diff --git a/src/badges/components/dialogueBox.tsx b/src/badges/components/dialogueBox.tsx index f444fd5..c7379bb 100644 --- a/src/badges/components/dialogueBox.tsx +++ b/src/badges/components/dialogueBox.tsx @@ -76,4 +76,4 @@ export default function EditBadgeDialog(props: IProps) { ); -} +} \ No newline at end of file diff --git a/src/badges/components/table.tsx b/src/badges/components/table.tsx index 7fc3566..6ae9f45 100644 --- a/src/badges/components/table.tsx +++ b/src/badges/components/table.tsx @@ -9,8 +9,8 @@ import { useEffect, useState } from "react"; import BorderColorIcon from "@mui/icons-material/BorderColor"; import { badge } from "../types"; -function createData(id: number, name: string, reward_points: number) { - return { id, name, reward_points }; +function createData(id: number, name: string, reward_points: number, updated_by: string) { + return { id, name, reward_points, updated_by }; } interface IProps { @@ -31,7 +31,7 @@ export default function BadgesTable(props: IProps) { props.badgeList?.map((badge) => { setRows((prevData) => [ ...prevData, - createData(badge.id, badge.name, badge.reward_points), + createData(badge.id, badge.name, badge.reward_points, badge.updated_by), ]); }); }, [props.badgeList]); @@ -43,6 +43,7 @@ export default function BadgesTable(props: IProps) { Sr No Badge Reward Points + Updated By @@ -57,6 +58,7 @@ export default function BadgesTable(props: IProps) { {row.name} {row.reward_points} + {row.updated_by} { @@ -72,4 +74,4 @@ export default function BadgesTable(props: IProps) {
); -} +} \ No newline at end of file diff --git a/src/badges/index.tsx b/src/badges/index.tsx index c0fea47..0d91515 100644 --- a/src/badges/index.tsx +++ b/src/badges/index.tsx @@ -1,5 +1,4 @@ -import { Typography } from "@mui/material"; -import TemporaryDrawer from "../sideBar"; +import { Box, Typography } from "@mui/material"; import { useSelector } from "react-redux"; import { RootState } from "../store"; import { useEffect, useState } from "react"; @@ -26,12 +25,12 @@ const BadgesComponent = () => { } },[authToken]) return ( - <> + Badges {!listBadgesError ? : <>} - + ); }; @@ -41,4 +40,4 @@ const Badges = () => { ) } -export default Badges; +export default Badges; \ No newline at end of file diff --git a/src/badges/types.tsx b/src/badges/types.tsx index 2fb108a..1803bd1 100644 --- a/src/badges/types.tsx +++ b/src/badges/types.tsx @@ -1,25 +1,25 @@ export interface badge { - id: number; - name: string; - reward_points: number; - } - - export interface badgesResponse { - success: boolean; - message: string; - status_code: number; - data: badge[]; - } - - export interface editBadgeReq { - id: number; - reward_points: number; - authToken: string; - } - - export interface editBadgeResp { - success: string; - message: string; - status_code: number; - } - \ No newline at end of file + id: number; + name: string; + reward_points: number; + updated_by: string; +} + +export interface badgesResponse { + success: boolean; + message: string; + status_code: number; + data: badge[]; +} + +export interface editBadgeReq { + id: number; + reward_points: number; + authToken: string; +} + +export interface editBadgeResp { + success: string; + message: string; + status_code: number; +} diff --git a/src/config/index.tsx b/src/config/index.tsx index d7f94f4..1b8638b 100644 --- a/src/config/index.tsx +++ b/src/config/index.tsx @@ -9,170 +9,6 @@ import { useEffect, useState } from "react"; import EditGradeDialog from "./components/editGradeDialogue"; import { useNavigate } from "react-router-dom"; import PermanentDrawerLeft from "../permanentSidebar"; -<<<<<<< HEAD - -const ConfigComponent = () => { -======= -import * as React from "react"; -import Tabs from "@mui/material/Tabs"; -import Tab from "@mui/material/Tab"; -import Box from "@mui/material/Box"; - -interface TabPanelProps { - children?: React.ReactNode; - index: number; - value: number; -} - -function CustomTabPanel(props: TabPanelProps) { - const { children, value, index, ...other } = props; - - return ( - - ); -} - -function a11yProps(index: number) { - return { - id: `simple-tab-${index}`, - "aria-controls": `simple-tabpanel-${index}`, - }; -} - -export function ConfigTabs() { - const [value, setValue] = useState(0); - - const handleChange = (event: React.SyntheticEvent, newValue: number) => { - setValue(newValue); - }; - ->>>>>>> 5ba4b8d5cc57380a23adcad2a41bcf1403f5743f - const navigate = useNavigate(); - const authToken = useSelector( - (state: RootState) => state.loginStore.authToken - ); - const { data: gradesResp, isError: listGradesError } = useGetGradesQuery({ - authToken: authToken, - }); - const { data: orgConfigResp, isError: getOrgConfigError } = - useGetOrgConfigQuery({ - authToken: authToken, - }); - const [openEditFrequency, setOpenEditFrequency] = useState(false); - const [openEditGrade, setOpenEditGrade] = useState(false); - const [id, setId] = useState(0); - useEffect(() => { - console.log("authtoken -> ", authToken); - if (authToken === "") { - navigate("/login"); - } else { - navigate("/config"); - } - }, [authToken]); -<<<<<<< HEAD - return ( - <> - Quaters - - - Grades - - {!listGradesError ? ( - - ) : ( - <> - )} - - Organisation Config - - {!getOrgConfigError ? ( - - ) : ( - <> - )} -======= - - return ( - - - - - - - - - - - - - {!listGradesError ? ( - - ) : ( - <> - )} - - - {!getOrgConfigError ? ( - - ) : ( - <> - )} - ->>>>>>> 5ba4b8d5cc57380a23adcad2a41bcf1403f5743f - - -<<<<<<< HEAD - -======= - ->>>>>>> 5ba4b8d5cc57380a23adcad2a41bcf1403f5743f - ); -} - -const Config = () => { - return } />; -}; - -<<<<<<< HEAD - - - - import * as React from "react"; import Tabs from "@mui/material/Tabs"; import Tab from "@mui/material/Tab"; @@ -293,6 +129,3 @@ const Config = () => { }; export default Config; -======= -export default Config; ->>>>>>> 5ba4b8d5cc57380a23adcad2a41bcf1403f5743f diff --git a/src/store.tsx b/src/store.tsx index 0cfaf82..986a84f 100644 --- a/src/store.tsx +++ b/src/store.tsx @@ -4,6 +4,7 @@ import loginReducer from './login/slice'; import sidebarReducer from './permanentSidebar/slice.tsx'; import { appreciationSlice } from './appreciations/apiSlice'; import { configSlice } from './config/apiSlice.tsx'; +import { badgesSlice } from './badges/apiSlice.tsx'; export const store = configureStore({ @@ -15,12 +16,13 @@ export const store = configureStore({ [loginApiSlice.reducerPath]: loginApiSlice.reducer, [appreciationSlice.reducerPath]: appreciationSlice.reducer, [configSlice.reducerPath]: configSlice.reducer, + [badgesSlice.reducerPath]: badgesSlice.reducer, }, middleware: (getDefaultMiddleware) => - getDefaultMiddleware().concat(loginApiSlice.middleware).concat(appreciationSlice.middleware).concat(configSlice.middleware), + getDefaultMiddleware().concat(loginApiSlice.middleware).concat(appreciationSlice.middleware).concat(configSlice.middleware).concat(badgesSlice.middleware), }); From c48674c6e9c142cbd635ea1d97b2cc2676c2e34b Mon Sep 17 00:00:00 2001 From: Sharyu Marwadi Date: Thu, 22 Aug 2024 23:36:20 +0530 Subject: [PATCH 21/23] [feature/CoreValues] core values page added --- src/App.tsx | 5 +++ src/coreValues/apiSlice.tsx | 28 ++++++++++++++ src/coreValues/components/table.tsx | 58 +++++++++++++++++++++++++++++ src/coreValues/index.tsx | 38 +++++++++++++++++++ src/coreValues/types.tsx | 13 +++++++ src/store.tsx | 4 +- 6 files changed, 145 insertions(+), 1 deletion(-) create mode 100644 src/coreValues/apiSlice.tsx create mode 100644 src/coreValues/components/table.tsx create mode 100644 src/coreValues/index.tsx create mode 100644 src/coreValues/types.tsx diff --git a/src/App.tsx b/src/App.tsx index 801da49..e8d53cd 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -9,6 +9,7 @@ import { useEffect } from "react"; import Home from "./home"; import Config from "./config"; import Badges from "./badges"; +import CoreValues from "./coreValues"; function App() { const router = createBrowserRouter([ @@ -32,6 +33,10 @@ function App() { path: "/badges", element: , }, + { + path: "/core_values", + element: , + }, ]); const dispatch = useDispatch(); diff --git a/src/coreValues/apiSlice.tsx b/src/coreValues/apiSlice.tsx new file mode 100644 index 0000000..b00e7a7 --- /dev/null +++ b/src/coreValues/apiSlice.tsx @@ -0,0 +1,28 @@ +import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react"; +import { coreValuesResp } from "./types"; +import { baseUrl } from "../constants"; + +export const coreValueSlice = createApi({ + reducerPath: "coreValueSlice", + baseQuery: fetchBaseQuery({ + baseUrl: baseUrl, + }), + tagTypes: ["coreValues"], + endpoints: (builder) => ({ + getCoreValues: builder.query({ + query: ({ authToken }) => ({ + url: "/core_values", + method: "GET", + headers: { + "Accept-Version": "application/vnd.peerly.v1", + Authorization: `Bearer ${authToken}`, + }, + }), + providesTags: ["coreValues"], + }), + }), +}); + +export const { + useGetCoreValuesQuery +} = coreValueSlice; \ No newline at end of file diff --git a/src/coreValues/components/table.tsx b/src/coreValues/components/table.tsx new file mode 100644 index 0000000..42a0754 --- /dev/null +++ b/src/coreValues/components/table.tsx @@ -0,0 +1,58 @@ +import Table from "@mui/material/Table"; +import TableBody from "@mui/material/TableBody"; +import TableCell from "@mui/material/TableCell"; +import TableContainer from "@mui/material/TableContainer"; +import TableHead from "@mui/material/TableHead"; +import TableRow from "@mui/material/TableRow"; +import Paper from "@mui/material/Paper"; +import { useEffect, useState } from "react"; +import { coreValue } from "../types"; + +function createData(id: number, name: string, description: string, parent_id: number) { + return { id, name, description, parent_id }; +} + +interface IProps { + coreValueList: coreValue[] | undefined; +} + +export default function CoreValuesTable(props: IProps) { + const [rows, setRows] = useState([]); + useEffect(() => { + console.log("corevaluelist -> ",props.coreValueList) + setRows([]); + props.coreValueList?.map((coreValue) => { + setRows((prevData) => [ + ...prevData, + createData(coreValue.id, coreValue.name, coreValue.description, coreValue.parent_id), + ]); + }); + }, [props.coreValueList]); + return ( + + + + + Sr No + CoreValue + Description + + + + {rows.map((row) => ( + + + {row.id} + + {row.name} + {row.description} + + ))} + +
+
+ ); +} \ No newline at end of file diff --git a/src/coreValues/index.tsx b/src/coreValues/index.tsx new file mode 100644 index 0000000..c3dfe33 --- /dev/null +++ b/src/coreValues/index.tsx @@ -0,0 +1,38 @@ +import { Box, Typography } from "@mui/material"; +import { useSelector } from "react-redux"; +import { RootState } from "../store"; +import { useEffect } from "react"; +import { useNavigate } from "react-router-dom"; +import PermanentDrawerLeft from "../permanentSidebar"; +import CoreValuesTable from "./components/table"; +import { useGetCoreValuesQuery } from "./apiSlice"; + +const CoreValuesComponent = () => { + const navigate = useNavigate() + const authToken = useSelector((state: RootState) => state.loginStore.authToken); + const {data: coreValueResp, isError: listCoreValuesError} = useGetCoreValuesQuery({ + authToken: authToken + }); + useEffect(()=>{ + console.log("authtoken -> ",authToken) + if(authToken === ""){ + navigate("/login") + }else{ + navigate("/core_values") + } + },[authToken]) + return ( + + Core Values + {!listCoreValuesError ? : <>} + + ); +}; + +const CoreValues = () => { + return( + } /> + ) +} + +export default CoreValues; \ No newline at end of file diff --git a/src/coreValues/types.tsx b/src/coreValues/types.tsx new file mode 100644 index 0000000..78954f5 --- /dev/null +++ b/src/coreValues/types.tsx @@ -0,0 +1,13 @@ +export interface coreValue { + id: number; + name: string; + description: string; + parent_id: number; + } + + export interface coreValuesResp { + success: boolean; + message: string; + status_code: number; + data: coreValue[]; + } \ No newline at end of file diff --git a/src/store.tsx b/src/store.tsx index 986a84f..7104ed4 100644 --- a/src/store.tsx +++ b/src/store.tsx @@ -5,6 +5,7 @@ import sidebarReducer from './permanentSidebar/slice.tsx'; import { appreciationSlice } from './appreciations/apiSlice'; import { configSlice } from './config/apiSlice.tsx'; import { badgesSlice } from './badges/apiSlice.tsx'; +import { coreValueSlice } from './coreValues/apiSlice.tsx'; export const store = configureStore({ @@ -17,12 +18,13 @@ export const store = configureStore({ [appreciationSlice.reducerPath]: appreciationSlice.reducer, [configSlice.reducerPath]: configSlice.reducer, [badgesSlice.reducerPath]: badgesSlice.reducer, + [coreValueSlice.reducerPath]: coreValueSlice.reducer, }, middleware: (getDefaultMiddleware) => - getDefaultMiddleware().concat(loginApiSlice.middleware).concat(appreciationSlice.middleware).concat(configSlice.middleware).concat(badgesSlice.middleware), + getDefaultMiddleware().concat(loginApiSlice.middleware).concat(appreciationSlice.middleware).concat(configSlice.middleware).concat(badgesSlice.middleware).concat(coreValueSlice.middleware), }); From acdf9c7f2c71617d602c4f0031ecb66615c69cca Mon Sep 17 00:00:00 2001 From: Sharyu Marwadi Date: Thu, 22 Aug 2024 23:48:13 +0530 Subject: [PATCH 22/23] [feature/Dashboard] dashboard done --- src/home/apiSlice.tsx | 2 +- src/home/components/appreciationCountCard.tsx | 21 ++++-- src/home/components/downloadExcel.tsx | 59 --------------- src/home/components/notifyAllDilogBox.tsx | 2 +- src/home/components/notifyUserDialogBox.tsx | 2 +- src/home/components/sendNotificationCard.tsx | 18 +++-- src/home/index.tsx | 74 ++++++++++++++++--- src/home/types.tsx | 2 +- src/store.tsx | 2 +- 9 files changed, 95 insertions(+), 87 deletions(-) delete mode 100644 src/home/components/downloadExcel.tsx diff --git a/src/home/apiSlice.tsx b/src/home/apiSlice.tsx index 05b918a..a21a9fc 100644 --- a/src/home/apiSlice.tsx +++ b/src/home/apiSlice.tsx @@ -61,4 +61,4 @@ export const { // useDownloadReportQuery, useSendNotificationMutation, useGetUsersQuery - } = homeSlice; + } = homeSlice; \ No newline at end of file diff --git a/src/home/components/appreciationCountCard.tsx b/src/home/components/appreciationCountCard.tsx index cae3959..de2bcf5 100644 --- a/src/home/components/appreciationCountCard.tsx +++ b/src/home/components/appreciationCountCard.tsx @@ -3,23 +3,32 @@ import CardContent from "@mui/material/CardContent"; import Typography from "@mui/material/Typography"; import { CardActionArea } from "@mui/material"; -interface IProps{ - count : number | undefined +interface IProps { + count: number | undefined; } export default function AppreciationCountCard(props: IProps) { return ( - + - + {props.count} - + Appreciation count for the quater ); -} +} \ No newline at end of file diff --git a/src/home/components/downloadExcel.tsx b/src/home/components/downloadExcel.tsx deleted file mode 100644 index 0593714..0000000 --- a/src/home/components/downloadExcel.tsx +++ /dev/null @@ -1,59 +0,0 @@ -// import Box from "@mui/material/Box"; -// import Card from "@mui/material/Card"; -// import CardActions from "@mui/material/CardActions"; -// import CardContent from "@mui/material/CardContent"; -// import Button from "@mui/material/Button"; -// import Typography from "@mui/material/Typography"; -// import { useSelector } from "react-redux"; -// import { RootState } from "../../store"; -// import { useState } from "react"; -// // import { useDownloadReportQuery } from "../apiSlice"; - -// const bull = ( -// -// • -// -// ); - -// export default function DownloadExcelCard() { -// const authToken = useSelector((state: RootState) => state.loginStore.authToken); -// const { data, error, isLoading } = useDownloadReportQuery({authToken}); -// const handleClick = () => { -// console.log("data -> ",data) -// if (data) { -// // Create a URL for the Blob -// const blob = new Blob([data], { type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" }); - -// // Create a link element and trigger a download -// const url = window.URL.createObjectURL(blob); -// const a = document.createElement("a"); -// a.href = url; -// a.download = "report.xlsx"; // Set the desired filename -// document.body.appendChild(a); -// a.click(); -// document.body.removeChild(a); -// window.URL.revokeObjectURL(url); -// } else if (error) { -// console.error("Error downloading the report:", error); -// } -// }; -// return ( -// -// -// -// -// Download report for the quarter in excel format -// -// -// -// -// -// -// -// ); -// } diff --git a/src/home/components/notifyAllDilogBox.tsx b/src/home/components/notifyAllDilogBox.tsx index 70ea853..ec8270d 100644 --- a/src/home/components/notifyAllDilogBox.tsx +++ b/src/home/components/notifyAllDilogBox.tsx @@ -95,4 +95,4 @@ export default function NotifiyAllDialog(props: IProps) { ); -} +} \ No newline at end of file diff --git a/src/home/components/notifyUserDialogBox.tsx b/src/home/components/notifyUserDialogBox.tsx index 765e14f..b3696bc 100644 --- a/src/home/components/notifyUserDialogBox.tsx +++ b/src/home/components/notifyUserDialogBox.tsx @@ -136,4 +136,4 @@ export default function NotifiyUserDialog(props: IProps) { ); -} +} \ No newline at end of file diff --git a/src/home/components/sendNotificationCard.tsx b/src/home/components/sendNotificationCard.tsx index c01fd20..cdb7974 100644 --- a/src/home/components/sendNotificationCard.tsx +++ b/src/home/components/sendNotificationCard.tsx @@ -29,20 +29,28 @@ export default function NotificationCard(props: IProps) { }; return ( - - + + Send a notification - + - @@ -50,4 +58,4 @@ export default function NotificationCard(props: IProps) { ); -} +} \ No newline at end of file diff --git a/src/home/index.tsx b/src/home/index.tsx index fcc074b..302e05b 100644 --- a/src/home/index.tsx +++ b/src/home/index.tsx @@ -1,17 +1,67 @@ -import Header from "../header" -import PermanentDrawerLeft from "../permanentSidebar" +import { useSelector } from "react-redux"; +import { useGetAppreciationsQuery } from "../appreciations/apiSlice"; +import PermanentDrawerLeft from "../permanentSidebar"; +import AppreciationCountCard from "./components/appreciationCountCard"; +import { RootState } from "../store"; +import NotificationCard from "./components/sendNotificationCard"; +// import DownloadExcelCard from "./components/downloadExcel"; +import { useEffect, useState } from "react"; +import NotifiyAllDialog from "./components/notifyAllDilogBox"; +import NotifiyUserDialog from "./components/notifyUserDialogBox"; +import { Box } from "@mui/material"; +import { useNavigate } from "react-router-dom"; -export function HomeTab() { - return( - <> -
- - ) -} +const HomeComponent = () => { + const [openNotifyAll, setOpenNotifyAll] = useState(false); + const [openNotifyUser, setOpenNotifyUser] = useState(false); + const authToken = useSelector( + (state: RootState) => state.loginStore.authToken + ); + const { data: appreciations, isError: listAppreciationsError } = + useGetAppreciationsQuery({ + page: 1, + page_size: 10, + authToken: authToken, + }); + const navigate = useNavigate(); + useEffect(() => { + console.log("authtoken -> ", authToken); + if (authToken === "") { + navigate("/login"); + } else { + navigate("/"); + } + }, [authToken]); + return ( + <> + + {!listAppreciationsError ? ( + + ) : ( + + )} + + {/* */} + + + + + ); +}; const Home = () => { - return } />; - }; + return } />; +}; -export default Home +export default Home; \ No newline at end of file diff --git a/src/home/types.tsx b/src/home/types.tsx index aab89e5..0c57c11 100644 --- a/src/home/types.tsx +++ b/src/home/types.tsx @@ -57,4 +57,4 @@ export interface listUsersResp { export interface userDropdown { label: string; id: number; -} +} \ No newline at end of file diff --git a/src/store.tsx b/src/store.tsx index 03062f2..6a5ca1e 100644 --- a/src/store.tsx +++ b/src/store.tsx @@ -25,7 +25,7 @@ export const store = configureStore({ middleware: (getDefaultMiddleware) => - getDefaultMiddleware().concat(loginApiSlice.middleware).concat(appreciationSlice.middleware).concat(configSlice.middleware).concat(badgesSlice.middleware).concat(coreValueSlice.middleware), + getDefaultMiddleware().concat(loginApiSlice.middleware).concat(appreciationSlice.middleware).concat(configSlice.middleware).concat(badgesSlice.middleware).concat(coreValueSlice.middleware).concat(homeSlice.middleware), }); From 50e2c549e8c04796f4dd4a10c1a506f9c54331b4 Mon Sep 17 00:00:00 2001 From: Sharyu Marwadi Date: Thu, 22 Aug 2024 23:52:25 +0530 Subject: [PATCH 23/23] [fix/Quarter] quarter spelling fixed --- src/config/components/quater.tsx | 2 +- src/config/index.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/config/components/quater.tsx b/src/config/components/quater.tsx index b037978..68ed4cc 100644 --- a/src/config/components/quater.tsx +++ b/src/config/components/quater.tsx @@ -27,7 +27,7 @@ export default function QuaterTable() { - Quater No + Quarter No Start Date End Date diff --git a/src/config/index.tsx b/src/config/index.tsx index 1b8638b..7155c8c 100644 --- a/src/config/index.tsx +++ b/src/config/index.tsx @@ -81,7 +81,7 @@ export function ConfigTabs() { onChange={handleChange} aria-label="basic tabs example" > - +