diff --git a/.eslintrc.cjs b/.eslintrc.cjs new file mode 100644 index 0000000..18dadd7 --- /dev/null +++ b/.eslintrc.cjs @@ -0,0 +1,23 @@ +module.exports = { + env: { browser: true, es2020: true }, + extends: [ + 'plugin:react/jsx-runtime', + 'airbnb', + 'airbnb/hooks', + ], + parserOptions: { ecmaVersion: 'latest', sourceType: 'module' }, + settings: { react: { version: '18.2' } }, + plugins: ['react-refresh'], + rules: { + 'react-refresh/only-export-components': 'warn', + 'import/extensions': 'off', + 'react/jsx-filename-extension': [1, { extensions: ['.jsx'] }], + 'react/react-in-jsx-scope': 'off', + 'react/function-component-definition': [2, { namedComponents: 'arrow-function' }], + 'react/prop-types': 'off', + 'linebreak-style': 'off', + 'react-hooks/exhaustive-deps': 0, + 'import/no-extraneous-dependencies': 0, + + }, +}; diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..97308d7 --- /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/extensions.json +.idea +.DS_Store +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..3a10c2b --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,13 @@ +{ + "editor.codeActionsOnSave": { + "source.fixAll.eslint": true + }, + "cSpell.words": [ + "adipisicing", + "Edituser", + "goalweight", + "Hamdy", + "linebreak", + "Redwan" + ] +} \ No newline at end of file diff --git a/index.html b/index.html new file mode 100644 index 0000000..79c4701 --- /dev/null +++ b/index.html @@ -0,0 +1,13 @@ + + + + + + + Vite + React + + +
+ + + diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..f129f74 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,5162 @@ +{ + "name": "gym-react", + "version": "0.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "gym-react", + "version": "0.0.0", + "dependencies": { + "@emotion/react": "^11.11.1", + "@emotion/styled": "^11.11.0", + "@mui/icons-material": "^5.11.16", + "@mui/material": "^5.13.5", + "@mui/system": "^5.13.5", + "@mui/x-charts": "^6.0.0-alpha.0", + "@mui/x-data-grid": "^6.8.0", + "axios": "^1.4.0", + "chart.js": "^4.3.0", + "date-fns": "^2.30.0", + "js-cookie": "^3.0.5", + "jwt-decode": "^3.1.2", + "moment": "^2.29.4", + "react": "^18.2.0", + "react-big-calendar": "^1.8.1", + "react-chartjs-2": "^5.2.0", + "react-datepicker": "^4.16.0", + "react-dom": "^18.2.0", + "react-icons": "^4.10.1", + "react-player": "^2.12.0", + "react-router-dom": "^6.14.0", + "react-scrollable-feed": "^1.3.2", + "react-slick": "^0.29.0", + "react-toastify": "^9.1.3", + "slick-carousel": "^1.8.1", + "socket.io-client": "^4.7.1", + "styled-components": "^5.3.11", + "swiper": "^9.4.1", + "vite-plugin-svgr": "^3.2.0", + "yup": "^1.2.0" + }, + "devDependencies": { + "@types/react": "^18.0.37", + "@types/react-dom": "^18.0.11", + "@vitejs/plugin-react": "^4.0.0", + "eslint": "^8.43.0", + "eslint-config-airbnb": "^19.0.4", + "eslint-plugin-import": "^2.27.5", + "eslint-plugin-jsx-a11y": "^6.7.1", + "eslint-plugin-react": "^7.32.2", + "eslint-plugin-react-hooks": "^4.6.0", + "eslint-plugin-react-refresh": "^0.3.4", + "vite": "^4.3.9" + } + }, + "node_modules/@aashutoshrathi/word-wrap": { + "version": "1.2.6", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@ampproject/remapping": { + "version": "2.2.1", + "license": "Apache-2.0", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.0", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.22.5", + "license": "MIT", + "dependencies": { + "@babel/highlight": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.22.9", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.22.9", + "license": "MIT", + "dependencies": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.22.5", + "@babel/generator": "^7.22.9", + "@babel/helper-compilation-targets": "^7.22.9", + "@babel/helper-module-transforms": "^7.22.9", + "@babel/helpers": "^7.22.6", + "@babel/parser": "^7.22.7", + "@babel/template": "^7.22.5", + "@babel/traverse": "^7.22.8", + "@babel/types": "^7.22.5", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.2", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/generator": { + "version": "7.22.9", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.22.5", + "@jridgewell/gen-mapping": "^0.3.2", + "@jridgewell/trace-mapping": "^0.3.17", + "jsesc": "^2.5.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-annotate-as-pure": { + "version": "7.22.5", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.22.9", + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.22.9", + "@babel/helper-validator-option": "^7.22.5", + "browserslist": "^4.21.9", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-environment-visitor": { + "version": "7.22.5", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-function-name": { + "version": "7.22.5", + "license": "MIT", + "dependencies": { + "@babel/template": "^7.22.5", + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-hoist-variables": { + "version": "7.22.5", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.22.5", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.22.9", + "license": "MIT", + "dependencies": { + "@babel/helper-environment-visitor": "^7.22.5", + "@babel/helper-module-imports": "^7.22.5", + "@babel/helper-simple-access": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/helper-validator-identifier": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.22.5", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-simple-access": { + "version": "7.22.5", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-split-export-declaration": { + "version": "7.22.6", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.22.5", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.22.5", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.22.5", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.22.6", + "license": "MIT", + "dependencies": { + "@babel/template": "^7.22.5", + "@babel/traverse": "^7.22.6", + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight": { + "version": "7.22.5", + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.22.5", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.22.7", + "license": "MIT", + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-syntax-jsx": { + "version": "7.22.5", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-self": { + "version": "7.22.5", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-source": { + "version": "7.22.5", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/runtime": { + "version": "7.22.6", + "license": "MIT", + "dependencies": { + "regenerator-runtime": "^0.13.11" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/template": { + "version": "7.22.5", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.22.5", + "@babel/parser": "^7.22.5", + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.22.8", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.22.5", + "@babel/generator": "^7.22.7", + "@babel/helper-environment-visitor": "^7.22.5", + "@babel/helper-function-name": "^7.22.5", + "@babel/helper-hoist-variables": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/parser": "^7.22.7", + "@babel/types": "^7.22.5", + "debug": "^4.1.0", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.22.5", + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.22.5", + "@babel/helper-validator-identifier": "^7.22.5", + "to-fast-properties": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@emotion/babel-plugin": { + "version": "11.11.0", + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.16.7", + "@babel/runtime": "^7.18.3", + "@emotion/hash": "^0.9.1", + "@emotion/memoize": "^0.8.1", + "@emotion/serialize": "^1.1.2", + "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/cache": { + "version": "11.11.0", + "license": "MIT", + "dependencies": { + "@emotion/memoize": "^0.8.1", + "@emotion/sheet": "^1.2.2", + "@emotion/utils": "^1.2.1", + "@emotion/weak-memoize": "^0.3.1", + "stylis": "4.2.0" + } + }, + "node_modules/@emotion/hash": { + "version": "0.9.1", + "license": "MIT" + }, + "node_modules/@emotion/is-prop-valid": { + "version": "1.2.1", + "license": "MIT", + "dependencies": { + "@emotion/memoize": "^0.8.1" + } + }, + "node_modules/@emotion/memoize": { + "version": "0.8.1", + "license": "MIT" + }, + "node_modules/@emotion/react": { + "version": "11.11.1", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.18.3", + "@emotion/babel-plugin": "^11.11.0", + "@emotion/cache": "^11.11.0", + "@emotion/serialize": "^1.1.2", + "@emotion/use-insertion-effect-with-fallbacks": "^1.0.1", + "@emotion/utils": "^1.2.1", + "@emotion/weak-memoize": "^0.3.1", + "hoist-non-react-statics": "^3.3.1" + }, + "peerDependencies": { + "react": ">=16.8.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@emotion/serialize": { + "version": "1.1.2", + "license": "MIT", + "dependencies": { + "@emotion/hash": "^0.9.1", + "@emotion/memoize": "^0.8.1", + "@emotion/unitless": "^0.8.1", + "@emotion/utils": "^1.2.1", + "csstype": "^3.0.2" + } + }, + "node_modules/@emotion/sheet": { + "version": "1.2.2", + "license": "MIT" + }, + "node_modules/@emotion/styled": { + "version": "11.11.0", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.18.3", + "@emotion/babel-plugin": "^11.11.0", + "@emotion/is-prop-valid": "^1.2.1", + "@emotion/serialize": "^1.1.2", + "@emotion/use-insertion-effect-with-fallbacks": "^1.0.1", + "@emotion/utils": "^1.2.1" + }, + "peerDependencies": { + "@emotion/react": "^11.0.0-rc.0", + "react": ">=16.8.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@emotion/stylis": { + "version": "0.8.5", + "license": "MIT" + }, + "node_modules/@emotion/unitless": { + "version": "0.8.1", + "license": "MIT" + }, + "node_modules/@emotion/use-insertion-effect-with-fallbacks": { + "version": "1.0.1", + "license": "MIT", + "peerDependencies": { + "react": ">=16.8.0" + } + }, + "node_modules/@emotion/utils": { + "version": "1.2.1", + "license": "MIT" + }, + "node_modules/@emotion/weak-memoize": { + "version": "0.3.1", + "license": "MIT" + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.18.16", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.4.0", + "dev": true, + "license": "MIT", + "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.6.1", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "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/globals": { + "version": "13.20.0", + "dev": true, + "license": "MIT", + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@eslint/eslintrc/node_modules/type-fest": { + "version": "0.20.2", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@eslint/js": { + "version": "8.44.0", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/@humanwhocodes/config-array": { + "version": "0.11.10", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanwhocodes/object-schema": "^1.2.1", + "debug": "^4.1.1", + "minimatch": "^3.0.5" + }, + "engines": { + "node": ">=10.10.0" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/object-schema": { + "version": "1.2.1", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.3", + "license": "MIT", + "dependencies": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.0", + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.1.2", + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.18", + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "3.1.0", + "@jridgewell/sourcemap-codec": "1.4.14" + } + }, + "node_modules/@jridgewell/trace-mapping/node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.14", + "license": "MIT" + }, + "node_modules/@kurkle/color": { + "version": "0.3.2", + "license": "MIT" + }, + "node_modules/@mui/base": { + "version": "5.0.0-beta.8", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.22.6", + "@emotion/is-prop-valid": "^1.2.1", + "@mui/types": "^7.2.4", + "@mui/utils": "^5.14.1", + "@popperjs/core": "^2.11.8", + "clsx": "^1.2.1", + "prop-types": "^15.8.1", + "react-is": "^18.2.0" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui" + }, + "peerDependencies": { + "@types/react": "^17.0.0 || ^18.0.0", + "react": "^17.0.0 || ^18.0.0", + "react-dom": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/core-downloads-tracker": { + "version": "5.14.2", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui" + } + }, + "node_modules/@mui/icons-material": { + "version": "5.14.1", + "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-5.14.1.tgz", + "integrity": "sha512-xV/f26muQqtWzerzOIdGPrXoxp/OKaE2G2Wp9gnmG47mHua5Slup/tMc3fA4ZYUreGGrK6+tT81TEvt1Wsng8Q==", + "dependencies": { + "@babel/runtime": "^7.22.6" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui" + }, + "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.14.2", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.22.6", + "@mui/base": "5.0.0-beta.8", + "@mui/core-downloads-tracker": "^5.14.2", + "@mui/system": "^5.14.1", + "@mui/types": "^7.2.4", + "@mui/utils": "^5.14.1", + "@types/react-transition-group": "^4.4.6", + "clsx": "^1.2.1", + "csstype": "^3.1.2", + "prop-types": "^15.8.1", + "react-is": "^18.2.0", + "react-transition-group": "^4.4.5" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui" + }, + "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.13.7", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.22.5", + "@mui/utils": "^5.13.7", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui" + }, + "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.13.2", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.21.0", + "@emotion/cache": "^11.11.0", + "csstype": "^3.1.2", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui" + }, + "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.14.1", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.22.6", + "@mui/private-theming": "^5.13.7", + "@mui/styled-engine": "^5.13.2", + "@mui/types": "^7.2.4", + "@mui/utils": "^5.14.1", + "clsx": "^1.2.1", + "csstype": "^3.1.2", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui" + }, + "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.4", + "license": "MIT", + "peerDependencies": { + "@types/react": "*" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/utils": { + "version": "5.14.1", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.22.6", + "@types/prop-types": "^15.7.5", + "@types/react-is": "^18.2.1", + "prop-types": "^15.8.1", + "react-is": "^18.2.0" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui" + }, + "peerDependencies": { + "react": "^17.0.0 || ^18.0.0" + } + }, + "node_modules/@mui/x-charts": { + "version": "6.0.0-alpha.4", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.22.6", + "clsx": "^1.2.1", + "d3-color": "^3.1.0", + "d3-scale": "^4.0.2", + "d3-shape": "^3.2.0", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "@emotion/react": "^11.9.0", + "@emotion/styled": "^11.8.1", + "@mui/material": "^5.4.1", + "@mui/system": "^5.4.1", + "react": "^17.0.0 || ^18.0.0", + "react-dom": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@emotion/react": { + "optional": true + }, + "@emotion/styled": { + "optional": true + } + } + }, + "node_modules/@mui/x-data-grid": { + "version": "6.10.1", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.22.6", + "@mui/utils": "^5.13.7", + "clsx": "^1.2.1", + "prop-types": "^15.8.1", + "reselect": "^4.1.8" + }, + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui" + }, + "peerDependencies": { + "@mui/material": "^5.4.1", + "@mui/system": "^5.4.1", + "react": "^17.0.0 || ^18.0.0", + "react-dom": "^17.0.0 || ^18.0.0" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@popperjs/core": { + "version": "2.11.8", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/popperjs" + } + }, + "node_modules/@remix-run/router": { + "version": "1.7.2", + "license": "MIT", + "engines": { + "node": ">=14" + } + }, + "node_modules/@restart/hooks": { + "version": "0.4.11", + "license": "MIT", + "dependencies": { + "dequal": "^2.0.3" + }, + "peerDependencies": { + "react": ">=16.8.0" + } + }, + "node_modules/@rollup/pluginutils": { + "version": "5.0.2", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "estree-walker": "^2.0.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0||^3.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@socket.io/component-emitter": { + "version": "3.1.0", + "license": "MIT" + }, + "node_modules/@svgr/babel-plugin-add-jsx-attribute": { + "version": "7.0.0", + "license": "MIT", + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-remove-jsx-attribute": { + "version": "7.0.0", + "license": "MIT", + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-remove-jsx-empty-expression": { + "version": "7.0.0", + "license": "MIT", + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-replace-jsx-attribute-value": { + "version": "7.0.0", + "license": "MIT", + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-svg-dynamic-title": { + "version": "7.0.0", + "license": "MIT", + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-svg-em-dimensions": { + "version": "7.0.0", + "license": "MIT", + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-transform-react-native-svg": { + "version": "7.0.0", + "license": "MIT", + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-transform-svg-component": { + "version": "7.0.0", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-preset": { + "version": "7.0.0", + "license": "MIT", + "dependencies": { + "@svgr/babel-plugin-add-jsx-attribute": "^7.0.0", + "@svgr/babel-plugin-remove-jsx-attribute": "^7.0.0", + "@svgr/babel-plugin-remove-jsx-empty-expression": "^7.0.0", + "@svgr/babel-plugin-replace-jsx-attribute-value": "^7.0.0", + "@svgr/babel-plugin-svg-dynamic-title": "^7.0.0", + "@svgr/babel-plugin-svg-em-dimensions": "^7.0.0", + "@svgr/babel-plugin-transform-react-native-svg": "^7.0.0", + "@svgr/babel-plugin-transform-svg-component": "^7.0.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/core": { + "version": "7.0.0", + "license": "MIT", + "dependencies": { + "@babel/core": "^7.21.3", + "@svgr/babel-preset": "^7.0.0", + "camelcase": "^6.2.0", + "cosmiconfig": "^8.1.3" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/@svgr/core/node_modules/cosmiconfig": { + "version": "8.2.0", + "license": "MIT", + "dependencies": { + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "parse-json": "^5.0.0", + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/d-fischer" + } + }, + "node_modules/@svgr/hast-util-to-babel-ast": { + "version": "7.0.0", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.21.3", + "entities": "^4.4.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/@svgr/plugin-jsx": { + "version": "7.0.0", + "license": "MIT", + "dependencies": { + "@babel/core": "^7.21.3", + "@svgr/babel-preset": "^7.0.0", + "@svgr/hast-util-to-babel-ast": "^7.0.0", + "svg-parser": "^2.0.4" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/@types/estree": { + "version": "1.0.1", + "license": "MIT" + }, + "node_modules/@types/json5": { + "version": "0.0.29", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/parse-json": { + "version": "4.0.0", + "license": "MIT" + }, + "node_modules/@types/prop-types": { + "version": "15.7.5", + "license": "MIT" + }, + "node_modules/@types/react": { + "version": "18.2.16", + "license": "MIT", + "dependencies": { + "@types/prop-types": "*", + "@types/scheduler": "*", + "csstype": "^3.0.2" + } + }, + "node_modules/@types/react-dom": { + "version": "18.2.7", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/react": "*" + } + }, + "node_modules/@types/react-is": { + "version": "18.2.1", + "license": "MIT", + "dependencies": { + "@types/react": "*" + } + }, + "node_modules/@types/react-transition-group": { + "version": "4.4.6", + "license": "MIT", + "dependencies": { + "@types/react": "*" + } + }, + "node_modules/@types/scheduler": { + "version": "0.16.3", + "license": "MIT" + }, + "node_modules/@types/warning": { + "version": "3.0.0", + "license": "MIT" + }, + "node_modules/@vitejs/plugin-react": { + "version": "4.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.22.5", + "@babel/plugin-transform-react-jsx-self": "^7.22.5", + "@babel/plugin-transform-react-jsx-source": "^7.22.5", + "react-refresh": "^0.14.0" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "peerDependencies": { + "vite": "^4.2.0" + } + }, + "node_modules/acorn": { + "version": "8.10.0", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "dev": true, + "license": "MIT", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "dev": true, + "license": "MIT", + "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", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "3.2.1", + "license": "MIT", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "license": "Python-2.0" + }, + "node_modules/aria-query": { + "version": "5.3.0", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "dequal": "^2.0.3" + } + }, + "node_modules/array-buffer-byte-length": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "is-array-buffer": "^3.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array-includes": { + "version": "3.1.6", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4", + "get-intrinsic": "^1.1.3", + "is-string": "^1.0.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flat": { + "version": "1.3.1", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4", + "es-shim-unscopables": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flatmap": { + "version": "1.3.1", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4", + "es-shim-unscopables": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.tosorted": { + "version": "1.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4", + "es-shim-unscopables": "^1.0.0", + "get-intrinsic": "^1.1.3" + } + }, + "node_modules/arraybuffer.prototype.slice": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "array-buffer-byte-length": "^1.0.0", + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "get-intrinsic": "^1.2.1", + "is-array-buffer": "^3.0.2", + "is-shared-array-buffer": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ast-types-flow": { + "version": "0.0.7", + "dev": true, + "license": "ISC" + }, + "node_modules/asynckit": { + "version": "0.4.0", + "license": "MIT" + }, + "node_modules/available-typed-arrays": { + "version": "1.0.5", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/axe-core": { + "version": "4.7.2", + "dev": true, + "license": "MPL-2.0", + "engines": { + "node": ">=4" + } + }, + "node_modules/axios": { + "version": "1.4.0", + "license": "MIT", + "dependencies": { + "follow-redirects": "^1.15.0", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + }, + "node_modules/axobject-query": { + "version": "3.2.1", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "dequal": "^2.0.3" + } + }, + "node_modules/babel-plugin-macros": { + "version": "3.1.0", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.12.5", + "cosmiconfig": "^7.0.0", + "resolve": "^1.19.0" + }, + "engines": { + "node": ">=10", + "npm": ">=6" + } + }, + "node_modules/babel-plugin-styled-components": { + "version": "2.1.4", + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-module-imports": "^7.22.5", + "@babel/plugin-syntax-jsx": "^7.22.5", + "lodash": "^4.17.21", + "picomatch": "^2.3.1" + }, + "peerDependencies": { + "styled-components": ">= 2" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "dev": true, + "license": "MIT" + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/browserslist": { + "version": "4.21.9", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "caniuse-lite": "^1.0.30001503", + "electron-to-chromium": "^1.4.431", + "node-releases": "^2.0.12", + "update-browserslist-db": "^1.0.11" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/call-bind": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/camelcase": { + "version": "6.3.0", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/camelize": { + "version": "1.0.1", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001517", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0" + }, + "node_modules/chalk": { + "version": "2.4.2", + "license": "MIT", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/chalk/node_modules/escape-string-regexp": { + "version": "1.0.5", + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/chart.js": { + "version": "4.3.1", + "license": "MIT", + "dependencies": { + "@kurkle/color": "^0.3.0" + }, + "engines": { + "pnpm": ">=7" + } + }, + "node_modules/classnames": { + "version": "2.3.2", + "license": "MIT" + }, + "node_modules/clsx": { + "version": "1.2.1", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/color-convert": { + "version": "1.9.3", + "license": "MIT", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/color-name": { + "version": "1.1.3", + "license": "MIT" + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "license": "MIT", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/confusing-browser-globals": { + "version": "1.0.11", + "dev": true, + "license": "MIT" + }, + "node_modules/convert-source-map": { + "version": "1.9.0", + "license": "MIT" + }, + "node_modules/cosmiconfig": { + "version": "7.1.0", + "license": "MIT", + "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", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/css-color-keywords": { + "version": "1.0.0", + "license": "ISC", + "engines": { + "node": ">=4" + } + }, + "node_modules/css-to-react-native": { + "version": "3.2.0", + "license": "MIT", + "dependencies": { + "camelize": "^1.0.0", + "css-color-keywords": "^1.0.0", + "postcss-value-parser": "^4.0.2" + } + }, + "node_modules/csstype": { + "version": "3.1.2", + "license": "MIT" + }, + "node_modules/d3-array": { + "version": "3.2.4", + "license": "ISC", + "dependencies": { + "internmap": "1 - 2" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-color": { + "version": "3.1.0", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-format": { + "version": "3.1.0", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-interpolate": { + "version": "3.0.1", + "license": "ISC", + "dependencies": { + "d3-color": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-path": { + "version": "3.1.0", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-scale": { + "version": "4.0.2", + "license": "ISC", + "dependencies": { + "d3-array": "2.10.0 - 3", + "d3-format": "1 - 3", + "d3-interpolate": "1.2.0 - 3", + "d3-time": "2.1.1 - 3", + "d3-time-format": "2 - 4" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-shape": { + "version": "3.2.0", + "license": "ISC", + "dependencies": { + "d3-path": "^3.1.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-time": { + "version": "3.1.0", + "license": "ISC", + "dependencies": { + "d3-array": "2 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-time-format": { + "version": "4.1.0", + "license": "ISC", + "dependencies": { + "d3-time": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/damerau-levenshtein": { + "version": "1.0.8", + "dev": true, + "license": "BSD-2-Clause" + }, + "node_modules/date-arithmetic": { + "version": "4.1.0", + "license": "MIT" + }, + "node_modules/date-fns": { + "version": "2.30.0", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.30.0.tgz", + "integrity": "sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==", + "dependencies": { + "@babel/runtime": "^7.21.0" + }, + "engines": { + "node": ">=0.11" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/date-fns" + } + }, + "node_modules/dayjs": { + "version": "1.11.9", + "license": "MIT" + }, + "node_modules/debug": { + "version": "4.3.4", + "license": "MIT", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "dev": true, + "license": "MIT" + }, + "node_modules/deepmerge": { + "version": "4.3.1", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/define-properties": { + "version": "1.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/dequal": { + "version": "2.0.3", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/doctrine": { + "version": "3.0.0", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/dom-helpers": { + "version": "5.2.1", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.8.7", + "csstype": "^3.0.2" + } + }, + "node_modules/electron-to-chromium": { + "version": "1.4.470", + "license": "ISC" + }, + "node_modules/emoji-regex": { + "version": "9.2.2", + "dev": true, + "license": "MIT" + }, + "node_modules/engine.io-client": { + "version": "6.5.1", + "license": "MIT", + "dependencies": { + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.3.1", + "engine.io-parser": "~5.1.0", + "ws": "~8.11.0", + "xmlhttprequest-ssl": "~2.0.0" + } + }, + "node_modules/engine.io-parser": { + "version": "5.1.0", + "license": "MIT", + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/enquire.js": { + "version": "2.1.6", + "license": "MIT" + }, + "node_modules/entities": { + "version": "4.5.0", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/error-ex": { + "version": "1.3.2", + "license": "MIT", + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/es-abstract": { + "version": "1.22.1", + "dev": true, + "license": "MIT", + "dependencies": { + "array-buffer-byte-length": "^1.0.0", + "arraybuffer.prototype.slice": "^1.0.1", + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "es-set-tostringtag": "^2.0.1", + "es-to-primitive": "^1.2.1", + "function.prototype.name": "^1.1.5", + "get-intrinsic": "^1.2.1", + "get-symbol-description": "^1.0.0", + "globalthis": "^1.0.3", + "gopd": "^1.0.1", + "has": "^1.0.3", + "has-property-descriptors": "^1.0.0", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "internal-slot": "^1.0.5", + "is-array-buffer": "^3.0.2", + "is-callable": "^1.2.7", + "is-negative-zero": "^2.0.2", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.2", + "is-string": "^1.0.7", + "is-typed-array": "^1.1.10", + "is-weakref": "^1.0.2", + "object-inspect": "^1.12.3", + "object-keys": "^1.1.1", + "object.assign": "^4.1.4", + "regexp.prototype.flags": "^1.5.0", + "safe-array-concat": "^1.0.0", + "safe-regex-test": "^1.0.0", + "string.prototype.trim": "^1.2.7", + "string.prototype.trimend": "^1.0.6", + "string.prototype.trimstart": "^1.0.6", + "typed-array-buffer": "^1.0.0", + "typed-array-byte-length": "^1.0.0", + "typed-array-byte-offset": "^1.0.0", + "typed-array-length": "^1.0.4", + "unbox-primitive": "^1.0.2", + "which-typed-array": "^1.1.10" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "get-intrinsic": "^1.1.3", + "has": "^1.0.3", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-shim-unscopables": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "has": "^1.0.3" + } + }, + "node_modules/es-to-primitive": { + "version": "1.2.1", + "dev": true, + "license": "MIT", + "dependencies": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/esbuild": { + "version": "0.18.16", + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/android-arm": "0.18.16", + "@esbuild/android-arm64": "0.18.16", + "@esbuild/android-x64": "0.18.16", + "@esbuild/darwin-arm64": "0.18.16", + "@esbuild/darwin-x64": "0.18.16", + "@esbuild/freebsd-arm64": "0.18.16", + "@esbuild/freebsd-x64": "0.18.16", + "@esbuild/linux-arm": "0.18.16", + "@esbuild/linux-arm64": "0.18.16", + "@esbuild/linux-ia32": "0.18.16", + "@esbuild/linux-loong64": "0.18.16", + "@esbuild/linux-mips64el": "0.18.16", + "@esbuild/linux-ppc64": "0.18.16", + "@esbuild/linux-riscv64": "0.18.16", + "@esbuild/linux-s390x": "0.18.16", + "@esbuild/linux-x64": "0.18.16", + "@esbuild/netbsd-x64": "0.18.16", + "@esbuild/openbsd-x64": "0.18.16", + "@esbuild/sunos-x64": "0.18.16", + "@esbuild/win32-arm64": "0.18.16", + "@esbuild/win32-ia32": "0.18.16", + "@esbuild/win32-x64": "0.18.16" + } + }, + "node_modules/esbuild/node_modules/@esbuild/android-arm": { + "version": "0.18.16", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.16.tgz", + "integrity": "sha512-gCHjjQmA8L0soklKbLKA6pgsLk1byULuHe94lkZDzcO3/Ta+bbeewJioEn1Fr7kgy9NWNFy/C+MrBwC6I/WCug==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild/node_modules/@esbuild/android-arm64": { + "version": "0.18.16", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.16.tgz", + "integrity": "sha512-wsCqSPqLz+6Ov+OM4EthU43DyYVVyfn15S4j1bJzylDpc1r1jZFFfJQNfDuT8SlgwuqpmpJXK4uPlHGw6ve7eA==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild/node_modules/@esbuild/android-x64": { + "version": "0.18.16", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.16.tgz", + "integrity": "sha512-ldsTXolyA3eTQ1//4DS+E15xl0H/3DTRJaRL0/0PgkqDsI0fV/FlOtD+h0u/AUJr+eOTlZv4aC9gvfppo3C4sw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild/node_modules/@esbuild/darwin-arm64": { + "version": "0.18.16", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.16.tgz", + "integrity": "sha512-aBxruWCII+OtluORR/KvisEw0ALuw/qDQWvkoosA+c/ngC/Kwk0lLaZ+B++LLS481/VdydB2u6tYpWxUfnLAIw==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild/node_modules/@esbuild/darwin-x64": { + "version": "0.18.16", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.16.tgz", + "integrity": "sha512-6w4Dbue280+rp3LnkgmriS1icOUZDyPuZo/9VsuMUTns7SYEiOaJ7Ca1cbhu9KVObAWfmdjUl4gwy9TIgiO5eA==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild/node_modules/@esbuild/freebsd-arm64": { + "version": "0.18.16", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.16.tgz", + "integrity": "sha512-x35fCebhe9s979DGKbVAwXUOcTmCIE32AIqB9CB1GralMIvxdnMLAw5CnID17ipEw9/3MvDsusj/cspYt2ZLNQ==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild/node_modules/@esbuild/freebsd-x64": { + "version": "0.18.16", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.16.tgz", + "integrity": "sha512-YM98f+PeNXF3GbxIJlUsj+McUWG1irguBHkszCIwfr3BXtXZsXo0vqybjUDFfu9a8Wr7uUD/YSmHib+EeGAFlg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild/node_modules/@esbuild/linux-arm": { + "version": "0.18.16", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.16.tgz", + "integrity": "sha512-b5ABb+5Ha2C9JkeZXV+b+OruR1tJ33ePmv9ZwMeETSEKlmu/WJ45XTTG+l6a2KDsQtJJ66qo/hbSGBtk0XVLHw==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild/node_modules/@esbuild/linux-arm64": { + "version": "0.18.16", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.16.tgz", + "integrity": "sha512-XIqhNUxJiuy+zsR77+H5Z2f7s4YRlriSJKtvx99nJuG5ATuJPjmZ9n0ANgnGlPCpXGSReFpgcJ7O3SMtzIFeiQ==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild/node_modules/@esbuild/linux-ia32": { + "version": "0.18.16", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.16.tgz", + "integrity": "sha512-no+pfEpwnRvIyH+txbBAWtjxPU9grslmTBfsmDndj7bnBmr55rOo/PfQmRfz7Qg9isswt1FP5hBbWb23fRWnow==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild/node_modules/@esbuild/linux-loong64": { + "version": "0.18.16", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.16.tgz", + "integrity": "sha512-Zbnczs9ZXjmo0oZSS0zbNlJbcwKXa/fcNhYQjahDs4Xg18UumpXG/lwM2lcSvHS3mTrRyCYZvJbmzYc4laRI1g==", + "cpu": [ + "loong64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild/node_modules/@esbuild/linux-mips64el": { + "version": "0.18.16", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.16.tgz", + "integrity": "sha512-YMF7hih1HVR/hQVa/ot4UVffc5ZlrzEb3k2ip0nZr1w6fnYypll9td2qcoMLvd3o8j3y6EbJM3MyIcXIVzXvQQ==", + "cpu": [ + "mips64el" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild/node_modules/@esbuild/linux-ppc64": { + "version": "0.18.16", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.16.tgz", + "integrity": "sha512-Wkz++LZ29lDwUyTSEnzDaaP5OveOgTU69q9IyIw9WqLRxM4BjTBjz9un4G6TOvehWpf/J3gYVFN96TjGHrbcNQ==", + "cpu": [ + "ppc64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild/node_modules/@esbuild/linux-riscv64": { + "version": "0.18.16", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.16.tgz", + "integrity": "sha512-LFMKZ30tk78/mUv1ygvIP+568bwf4oN6reG/uczXnz6SvFn4e2QUFpUpZY9iSJT6Qpgstrhef/nMykIXZtZWGQ==", + "cpu": [ + "riscv64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild/node_modules/@esbuild/linux-s390x": { + "version": "0.18.16", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.16.tgz", + "integrity": "sha512-3ZC0BgyYHYKfZo3AV2/66TD/I9tlSBaW7eWTEIkrQQKfJIifKMMttXl9FrAg+UT0SGYsCRLI35Gwdmm96vlOjg==", + "cpu": [ + "s390x" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild/node_modules/@esbuild/linux-x64": { + "version": "0.18.16", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.16.tgz", + "integrity": "sha512-xu86B3647DihHJHv/wx3NCz2Dg1gjQ8bbf9cVYZzWKY+gsvxYmn/lnVlqDRazObc3UMwoHpUhNYaZset4X8IPA==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild/node_modules/@esbuild/netbsd-x64": { + "version": "0.18.16", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.16.tgz", + "integrity": "sha512-uVAgpimx9Ffw3xowtg/7qQPwHFx94yCje+DoBx+LNm2ePDpQXHrzE+Sb0Si2VBObYz+LcRps15cq+95YM7gkUw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild/node_modules/@esbuild/openbsd-x64": { + "version": "0.18.16", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.16.tgz", + "integrity": "sha512-6OjCQM9wf7z8/MBi6BOWaTL2AS/SZudsZtBziXMtNI8r/U41AxS9x7jn0ATOwVy08OotwkPqGRMkpPR2wcTJXA==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild/node_modules/@esbuild/sunos-x64": { + "version": "0.18.16", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.16.tgz", + "integrity": "sha512-ZoNkruFYJp9d1LbUYCh8awgQDvB9uOMZqlQ+gGEZR7v6C+N6u7vPr86c+Chih8niBR81Q/bHOSKGBK3brJyvkQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild/node_modules/@esbuild/win32-arm64": { + "version": "0.18.16", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.16.tgz", + "integrity": "sha512-+j4anzQ9hrs+iqO+/wa8UE6TVkKua1pXUb0XWFOx0FiAj6R9INJ+WE//1/Xo6FG1vB5EpH3ko+XcgwiDXTxcdw==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild/node_modules/@esbuild/win32-ia32": { + "version": "0.18.16", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.16.tgz", + "integrity": "sha512-5PFPmq3sSKTp9cT9dzvI67WNfRZGvEVctcZa1KGjDDu4n3H8k59Inbk0du1fz0KrAbKKNpJbdFXQMDUz7BG4rQ==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/escalade": { + "version": "3.1.1", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "8.45.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.4.0", + "@eslint/eslintrc": "^2.1.0", + "@eslint/js": "8.44.0", + "@humanwhocodes/config-array": "^0.11.10", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "ajv": "^6.10.0", + "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.0", + "eslint-visitor-keys": "^3.4.1", + "espree": "^9.6.0", + "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-config-airbnb": { + "version": "19.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-config-airbnb-base": "^15.0.0", + "object.assign": "^4.1.2", + "object.entries": "^1.1.5" + }, + "engines": { + "node": "^10.12.0 || ^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": "^7.32.0 || ^8.2.0", + "eslint-plugin-import": "^2.25.3", + "eslint-plugin-jsx-a11y": "^6.5.1", + "eslint-plugin-react": "^7.28.0", + "eslint-plugin-react-hooks": "^4.3.0" + } + }, + "node_modules/eslint-config-airbnb-base": { + "version": "15.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "confusing-browser-globals": "^1.0.10", + "object.assign": "^4.1.2", + "object.entries": "^1.1.5", + "semver": "^6.3.0" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + }, + "peerDependencies": { + "eslint": "^7.32.0 || ^8.2.0", + "eslint-plugin-import": "^2.25.2" + } + }, + "node_modules/eslint-import-resolver-node": { + "version": "0.3.7", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^3.2.7", + "is-core-module": "^2.11.0", + "resolve": "^1.22.1" + } + }, + "node_modules/eslint-import-resolver-node/node_modules/debug": { + "version": "3.2.7", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-module-utils": { + "version": "2.8.0", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^3.2.7" + }, + "engines": { + "node": ">=4" + }, + "peerDependenciesMeta": { + "eslint": { + "optional": true + } + } + }, + "node_modules/eslint-module-utils/node_modules/debug": { + "version": "3.2.7", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-plugin-import": { + "version": "2.27.5", + "dev": true, + "license": "MIT", + "dependencies": { + "array-includes": "^3.1.6", + "array.prototype.flat": "^1.3.1", + "array.prototype.flatmap": "^1.3.1", + "debug": "^3.2.7", + "doctrine": "^2.1.0", + "eslint-import-resolver-node": "^0.3.7", + "eslint-module-utils": "^2.7.4", + "has": "^1.0.3", + "is-core-module": "^2.11.0", + "is-glob": "^4.0.3", + "minimatch": "^3.1.2", + "object.values": "^1.1.6", + "resolve": "^1.22.1", + "semver": "^6.3.0", + "tsconfig-paths": "^3.14.1" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8" + } + }, + "node_modules/eslint-plugin-import/node_modules/debug": { + "version": "3.2.7", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-plugin-import/node_modules/doctrine": { + "version": "2.1.0", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint-plugin-jsx-a11y": { + "version": "6.7.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.20.7", + "aria-query": "^5.1.3", + "array-includes": "^3.1.6", + "array.prototype.flatmap": "^1.3.1", + "ast-types-flow": "^0.0.7", + "axe-core": "^4.6.2", + "axobject-query": "^3.1.1", + "damerau-levenshtein": "^1.0.8", + "emoji-regex": "^9.2.2", + "has": "^1.0.3", + "jsx-ast-utils": "^3.3.3", + "language-tags": "=1.0.5", + "minimatch": "^3.1.2", + "object.entries": "^1.1.6", + "object.fromentries": "^2.0.6", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=4.0" + }, + "peerDependencies": { + "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8" + } + }, + "node_modules/eslint-plugin-react": { + "version": "7.33.0", + "dev": true, + "license": "MIT", + "dependencies": { + "array-includes": "^3.1.6", + "array.prototype.flatmap": "^1.3.1", + "array.prototype.tosorted": "^1.1.1", + "doctrine": "^2.1.0", + "estraverse": "^5.3.0", + "jsx-ast-utils": "^2.4.1 || ^3.0.0", + "minimatch": "^3.1.2", + "object.entries": "^1.1.6", + "object.fromentries": "^2.0.6", + "object.hasown": "^1.1.2", + "object.values": "^1.1.6", + "prop-types": "^15.8.1", + "resolve": "^2.0.0-next.4", + "semver": "^6.3.1", + "string.prototype.matchall": "^4.0.8" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8" + } + }, + "node_modules/eslint-plugin-react-hooks": { + "version": "4.6.0", + "dev": true, + "license": "MIT", + "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.3.5", + "dev": true, + "license": "MIT", + "peerDependencies": { + "eslint": ">=7" + } + }, + "node_modules/eslint-plugin-react/node_modules/doctrine": { + "version": "2.1.0", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint-plugin-react/node_modules/resolve": { + "version": "2.0.0-next.4", + "dev": true, + "license": "MIT", + "dependencies": { + "is-core-module": "^2.9.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/eslint-scope": { + "version": "7.2.1", + "dev": true, + "license": "BSD-2-Clause", + "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.1", + "dev": true, + "license": "Apache-2.0", + "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", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/eslint/node_modules/chalk": { + "version": "4.1.2", + "dev": true, + "license": "MIT", + "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", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/eslint/node_modules/color-name": { + "version": "1.1.4", + "dev": true, + "license": "MIT" + }, + "node_modules/eslint/node_modules/globals": { + "version": "13.20.0", + "dev": true, + "license": "MIT", + "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", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint/node_modules/supports-color": { + "version": "7.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint/node_modules/type-fest": { + "version": "0.20.2", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/espree": { + "version": "9.6.1", + "dev": true, + "license": "BSD-2-Clause", + "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.5.0", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estree-walker": { + "version": "2.0.2", + "license": "MIT" + }, + "node_modules/esutils": { + "version": "2.0.3", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "dev": true, + "license": "MIT" + }, + "node_modules/fastq": { + "version": "1.15.0", + "dev": true, + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/file-entry-cache": { + "version": "6.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "flat-cache": "^3.0.4" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/find-root": { + "version": "1.1.0", + "license": "MIT" + }, + "node_modules/find-up": { + "version": "5.0.0", + "dev": true, + "license": "MIT", + "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.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "flatted": "^3.1.0", + "rimraf": "^3.0.2" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/flatted": { + "version": "3.2.7", + "dev": true, + "license": "ISC" + }, + "node_modules/follow-redirects": { + "version": "1.15.2", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "license": "MIT", + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/for-each": { + "version": "0.3.3", + "dev": true, + "license": "MIT", + "dependencies": { + "is-callable": "^1.1.3" + } + }, + "node_modules/form-data": { + "version": "4.0.0", + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "dev": true, + "license": "ISC" + }, + "node_modules/function-bind": { + "version": "1.1.1", + "license": "MIT" + }, + "node_modules/function.prototype.name": { + "version": "1.1.5", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.0", + "functions-have-names": "^1.2.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/functions-have-names": { + "version": "1.2.3", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-intrinsic": { + "version": "1.2.1", + "dev": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-symbol-description": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/glob": { + "version": "7.2.3", + "dev": true, + "license": "ISC", + "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", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/globalize": { + "version": "0.1.1" + }, + "node_modules/globals": { + "version": "11.12.0", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/globalthis": { + "version": "1.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "define-properties": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gopd": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "get-intrinsic": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graphemer": { + "version": "1.4.0", + "dev": true, + "license": "MIT" + }, + "node_modules/has": { + "version": "1.0.3", + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/has-bigints": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-flag": { + "version": "3.0.0", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "get-intrinsic": "^1.1.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.0.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hoist-non-react-statics": { + "version": "3.3.2", + "license": "BSD-3-Clause", + "dependencies": { + "react-is": "^16.7.0" + } + }, + "node_modules/hoist-non-react-statics/node_modules/react-is": { + "version": "16.13.1", + "license": "MIT" + }, + "node_modules/ignore": { + "version": "5.2.4", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/import-fresh": { + "version": "3.3.0", + "license": "MIT", + "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", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "dev": true, + "license": "ISC", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "dev": true, + "license": "ISC" + }, + "node_modules/internal-slot": { + "version": "1.0.5", + "dev": true, + "license": "MIT", + "dependencies": { + "get-intrinsic": "^1.2.0", + "has": "^1.0.3", + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/internmap": { + "version": "2.0.3", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/invariant": { + "version": "2.2.4", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.0.0" + } + }, + "node_modules/is-array-buffer": { + "version": "3.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.2.0", + "is-typed-array": "^1.1.10" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "license": "MIT" + }, + "node_modules/is-bigint": { + "version": "1.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "has-bigints": "^1.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-boolean-object": { + "version": "1.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-callable": { + "version": "1.2.7", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-core-module": { + "version": "2.12.1", + "license": "MIT", + "dependencies": { + "has": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-date-object": { + "version": "1.0.5", + "dev": true, + "license": "MIT", + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-negative-zero": { + "version": "2.0.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-number-object": { + "version": "1.0.7", + "dev": true, + "license": "MIT", + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-path-inside": { + "version": "3.0.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-regex": { + "version": "1.1.4", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-shared-array-buffer": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-string": { + "version": "1.0.7", + "dev": true, + "license": "MIT", + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-symbol": { + "version": "1.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typed-array": { + "version": "1.1.12", + "dev": true, + "license": "MIT", + "dependencies": { + "which-typed-array": "^1.1.11" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakref": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/isarray": { + "version": "2.0.5", + "dev": true, + "license": "MIT" + }, + "node_modules/isexe": { + "version": "2.0.0", + "dev": true, + "license": "ISC" + }, + "node_modules/jquery": { + "version": "3.7.0", + "license": "MIT", + "peer": true + }, + "node_modules/js-cookie": { + "version": "3.0.5", + "license": "MIT", + "engines": { + "node": ">=14" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "license": "MIT" + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsesc": { + "version": "2.5.2", + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "license": "MIT" + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "dev": true, + "license": "MIT" + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/json2mq": { + "version": "0.2.0", + "license": "MIT", + "dependencies": { + "string-convert": "^0.2.0" + } + }, + "node_modules/json5": { + "version": "2.2.3", + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jsx-ast-utils": { + "version": "3.3.4", + "dev": true, + "license": "MIT", + "dependencies": { + "array-includes": "^3.1.6", + "array.prototype.flat": "^1.3.1", + "object.assign": "^4.1.4", + "object.values": "^1.1.6" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/jwt-decode": { + "version": "3.1.2", + "license": "MIT" + }, + "node_modules/language-subtag-registry": { + "version": "0.3.22", + "dev": true, + "license": "CC0-1.0" + }, + "node_modules/language-tags": { + "version": "1.0.5", + "dev": true, + "license": "MIT", + "dependencies": { + "language-subtag-registry": "~0.3.2" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "license": "MIT" + }, + "node_modules/load-script": { + "version": "1.0.0", + "license": "MIT" + }, + "node_modules/locate-path": { + "version": "6.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "license": "MIT" + }, + "node_modules/lodash-es": { + "version": "4.17.21", + "license": "MIT" + }, + "node_modules/lodash.debounce": { + "version": "4.0.8", + "license": "MIT" + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "dev": true, + "license": "MIT" + }, + "node_modules/loose-envify": { + "version": "1.4.0", + "license": "MIT", + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "license": "ISC", + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/luxon": { + "version": "3.3.0", + "license": "MIT", + "engines": { + "node": ">=12" + } + }, + "node_modules/memoize-one": { + "version": "6.0.0", + "license": "MIT" + }, + "node_modules/mime-db": { + "version": "1.52.0", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/moment": { + "version": "2.29.4", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz", + "integrity": "sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w==", + "engines": { + "node": "*" + } + }, + "node_modules/moment-timezone": { + "version": "0.5.43", + "license": "MIT", + "dependencies": { + "moment": "^2.29.4" + }, + "engines": { + "node": "*" + } + }, + "node_modules/ms": { + "version": "2.1.2", + "license": "MIT" + }, + "node_modules/nanoid": { + "version": "3.3.6", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "dev": true, + "license": "MIT" + }, + "node_modules/node-releases": { + "version": "2.0.13", + "license": "MIT" + }, + "node_modules/object-assign": { + "version": "4.1.1", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.12.3", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.assign": { + "version": "4.1.4", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "has-symbols": "^1.0.3", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.entries": { + "version": "1.1.6", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.fromentries": { + "version": "2.0.6", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.hasown": { + "version": "1.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.values": { + "version": "1.1.6", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/once": { + "version": "1.4.0", + "dev": true, + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/optionator": { + "version": "0.9.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@aashutoshrathi/word-wrap": "^1.2.3", + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "license": "MIT", + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-json": { + "version": "5.2.0", + "license": "MIT", + "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", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "license": "MIT" + }, + "node_modules/path-type": { + "version": "4.0.0", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/picocolors": { + "version": "1.0.0", + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "2.3.1", + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/postcss": { + "version": "8.4.27", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.6", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss-value-parser": { + "version": "4.2.0", + "license": "MIT" + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/prop-types": { + "version": "15.8.1", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.1" + } + }, + "node_modules/prop-types/node_modules/react-is": { + "version": "16.13.1", + "license": "MIT" + }, + "node_modules/property-expr": { + "version": "2.0.5", + "license": "MIT" + }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "license": "MIT" + }, + "node_modules/punycode": { + "version": "2.3.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/react": { + "version": "18.2.0", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-big-calendar": { + "version": "1.8.1", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.20.7", + "clsx": "^1.2.1", + "date-arithmetic": "^4.1.0", + "dayjs": "^1.11.7", + "dom-helpers": "^5.2.1", + "globalize": "^0.1.1", + "invariant": "^2.2.4", + "lodash": "^4.17.21", + "lodash-es": "^4.17.21", + "luxon": "^3.2.1", + "memoize-one": "^6.0.0", + "moment": "^2.29.4", + "moment-timezone": "^0.5.40", + "prop-types": "^15.8.1", + "react-overlays": "^5.2.1", + "uncontrollable": "^7.2.1" + }, + "peerDependencies": { + "react": "^16.14.0 || ^17 || ^18", + "react-dom": "^16.14.0 || ^17 || ^18" + } + }, + "node_modules/react-chartjs-2": { + "version": "5.2.0", + "license": "MIT", + "peerDependencies": { + "chart.js": "^4.1.1", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/react-datepicker": { + "version": "4.16.0", + "license": "MIT", + "dependencies": { + "@popperjs/core": "^2.11.8", + "classnames": "^2.2.6", + "date-fns": "^2.30.0", + "prop-types": "^15.7.2", + "react-onclickoutside": "^6.12.2", + "react-popper": "^2.3.0" + }, + "peerDependencies": { + "react": "^16.9.0 || ^17 || ^18", + "react-dom": "^16.9.0 || ^17 || ^18" + } + }, + "node_modules/react-dom": { + "version": "18.2.0", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.1.0", + "scheduler": "^0.23.0" + }, + "peerDependencies": { + "react": "^18.2.0" + } + }, + "node_modules/react-fast-compare": { + "version": "3.2.2", + "license": "MIT" + }, + "node_modules/react-icons": { + "version": "4.10.1", + "license": "MIT", + "peerDependencies": { + "react": "*" + } + }, + "node_modules/react-is": { + "version": "18.2.0", + "license": "MIT" + }, + "node_modules/react-lifecycles-compat": { + "version": "3.0.4", + "license": "MIT" + }, + "node_modules/react-onclickoutside": { + "version": "6.13.0", + "license": "MIT", + "funding": { + "type": "individual", + "url": "https://github.com/Pomax/react-onclickoutside/blob/master/FUNDING.md" + }, + "peerDependencies": { + "react": "^15.5.x || ^16.x || ^17.x || ^18.x", + "react-dom": "^15.5.x || ^16.x || ^17.x || ^18.x" + } + }, + "node_modules/react-overlays": { + "version": "5.2.1", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.13.8", + "@popperjs/core": "^2.11.6", + "@restart/hooks": "^0.4.7", + "@types/warning": "^3.0.0", + "dom-helpers": "^5.2.0", + "prop-types": "^15.7.2", + "uncontrollable": "^7.2.1", + "warning": "^4.0.3" + }, + "peerDependencies": { + "react": ">=16.3.0", + "react-dom": ">=16.3.0" + } + }, + "node_modules/react-player": { + "version": "2.12.0", + "license": "MIT", + "dependencies": { + "deepmerge": "^4.0.0", + "load-script": "^1.0.0", + "memoize-one": "^5.1.1", + "prop-types": "^15.7.2", + "react-fast-compare": "^3.0.1" + }, + "peerDependencies": { + "react": ">=16.6.0" + } + }, + "node_modules/react-player/node_modules/memoize-one": { + "version": "5.2.1", + "license": "MIT" + }, + "node_modules/react-popper": { + "version": "2.3.0", + "license": "MIT", + "dependencies": { + "react-fast-compare": "^3.0.1", + "warning": "^4.0.2" + }, + "peerDependencies": { + "@popperjs/core": "^2.0.0", + "react": "^16.8.0 || ^17 || ^18", + "react-dom": "^16.8.0 || ^17 || ^18" + } + }, + "node_modules/react-refresh": { + "version": "0.14.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-router": { + "version": "6.14.2", + "license": "MIT", + "dependencies": { + "@remix-run/router": "1.7.2" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "react": ">=16.8" + } + }, + "node_modules/react-router-dom": { + "version": "6.14.2", + "license": "MIT", + "dependencies": { + "@remix-run/router": "1.7.2", + "react-router": "6.14.2" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "react": ">=16.8", + "react-dom": ">=16.8" + } + }, + "node_modules/react-scrollable-feed": { + "version": "1.3.2", + "license": "MIT", + "engines": { + "node": ">=8", + "npm": ">=5" + }, + "peerDependencies": { + "prop-types": "^15.7.2", + "react": "^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/react-slick": { + "version": "0.29.0", + "license": "MIT", + "dependencies": { + "classnames": "^2.2.5", + "enquire.js": "^2.1.6", + "json2mq": "^0.2.0", + "lodash.debounce": "^4.0.8", + "resize-observer-polyfill": "^1.5.0" + }, + "peerDependencies": { + "react": "^0.14.0 || ^15.0.1 || ^16.0.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^0.14.0 || ^15.0.1 || ^16.0.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/react-toastify": { + "version": "9.1.3", + "license": "MIT", + "dependencies": { + "clsx": "^1.1.1" + }, + "peerDependencies": { + "react": ">=16", + "react-dom": ">=16" + } + }, + "node_modules/react-transition-group": { + "version": "4.4.5", + "license": "BSD-3-Clause", + "dependencies": { + "@babel/runtime": "^7.5.5", + "dom-helpers": "^5.0.1", + "loose-envify": "^1.4.0", + "prop-types": "^15.6.2" + }, + "peerDependencies": { + "react": ">=16.6.0", + "react-dom": ">=16.6.0" + } + }, + "node_modules/regenerator-runtime": { + "version": "0.13.11", + "license": "MIT" + }, + "node_modules/regexp.prototype.flags": { + "version": "1.5.0", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "functions-have-names": "^1.2.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/reselect": { + "version": "4.1.8", + "license": "MIT" + }, + "node_modules/resize-observer-polyfill": { + "version": "1.5.1", + "license": "MIT" + }, + "node_modules/resolve": { + "version": "1.22.2", + "license": "MIT", + "dependencies": { + "is-core-module": "^2.11.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", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "dev": true, + "license": "MIT", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rimraf": { + "version": "3.0.2", + "dev": true, + "license": "ISC", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rollup": { + "version": "3.26.3", + "license": "MIT", + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=14.18.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/rollup/node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/safe-array-concat": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.2.0", + "has-symbols": "^1.0.3", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">=0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-regex-test": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.3", + "is-regex": "^1.1.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/scheduler": { + "version": "0.23.0", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.1.0" + } + }, + "node_modules/semver": { + "version": "6.3.1", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/shallowequal": { + "version": "1.1.0", + "license": "MIT" + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/side-channel": { + "version": "1.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/slick-carousel": { + "version": "1.8.1", + "license": "MIT", + "peerDependencies": { + "jquery": ">=1.8.0" + } + }, + "node_modules/socket.io-client": { + "version": "4.7.1", + "license": "MIT", + "dependencies": { + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.3.2", + "engine.io-client": "~6.5.1", + "socket.io-parser": "~4.2.4" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/socket.io-parser": { + "version": "4.2.4", + "license": "MIT", + "dependencies": { + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.3.1" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/source-map": { + "version": "0.5.7", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-js": { + "version": "1.0.2", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ssr-window": { + "version": "4.0.2", + "license": "MIT" + }, + "node_modules/string-convert": { + "version": "0.2.1", + "license": "MIT" + }, + "node_modules/string.prototype.matchall": { + "version": "4.0.8", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4", + "get-intrinsic": "^1.1.3", + "has-symbols": "^1.0.3", + "internal-slot": "^1.0.3", + "regexp.prototype.flags": "^1.4.3", + "side-channel": "^1.0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trim": { + "version": "1.2.7", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimend": { + "version": "1.0.6", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimstart": { + "version": "1.0.6", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-bom": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/styled-components": { + "version": "5.3.11", + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.0.0", + "@babel/traverse": "^7.4.5", + "@emotion/is-prop-valid": "^1.1.0", + "@emotion/stylis": "^0.8.4", + "@emotion/unitless": "^0.7.4", + "babel-plugin-styled-components": ">= 1.12.0", + "css-to-react-native": "^3.0.0", + "hoist-non-react-statics": "^3.0.0", + "shallowequal": "^1.1.0", + "supports-color": "^5.5.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/styled-components" + }, + "peerDependencies": { + "react": ">= 16.8.0", + "react-dom": ">= 16.8.0", + "react-is": ">= 16.8.0" + } + }, + "node_modules/styled-components/node_modules/@emotion/unitless": { + "version": "0.7.5", + "license": "MIT" + }, + "node_modules/stylis": { + "version": "4.2.0", + "license": "MIT" + }, + "node_modules/supports-color": { + "version": "5.5.0", + "license": "MIT", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/svg-parser": { + "version": "2.0.4", + "license": "MIT" + }, + "node_modules/swiper": { + "version": "9.4.1", + "funding": [ + { + "type": "patreon", + "url": "https://www.patreon.com/swiperjs" + }, + { + "type": "open_collective", + "url": "http://opencollective.com/swiper" + } + ], + "license": "MIT", + "dependencies": { + "ssr-window": "^4.0.2" + }, + "engines": { + "node": ">= 4.7.0" + } + }, + "node_modules/text-table": { + "version": "0.2.0", + "dev": true, + "license": "MIT" + }, + "node_modules/tiny-case": { + "version": "1.0.3", + "license": "MIT" + }, + "node_modules/to-fast-properties": { + "version": "2.0.0", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/toposort": { + "version": "2.0.2", + "license": "MIT" + }, + "node_modules/tsconfig-paths": { + "version": "3.14.2", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/json5": "^0.0.29", + "json5": "^1.0.2", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + } + }, + "node_modules/tsconfig-paths/node_modules/json5": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/type-check": { + "version": "0.4.0", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-fest": { + "version": "2.19.0", + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/typed-array-buffer": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.2.1", + "is-typed-array": "^1.1.10" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/typed-array-byte-length": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "has-proto": "^1.0.1", + "is-typed-array": "^1.1.10" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-byte-offset": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "has-proto": "^1.0.1", + "is-typed-array": "^1.1.10" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-length": { + "version": "1.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "is-typed-array": "^1.1.9" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/unbox-primitive": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "has-bigints": "^1.0.2", + "has-symbols": "^1.0.3", + "which-boxed-primitive": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/uncontrollable": { + "version": "7.2.1", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.6.3", + "@types/react": ">=16.9.11", + "invariant": "^2.2.4", + "react-lifecycles-compat": "^3.0.4" + }, + "peerDependencies": { + "react": ">=15.0.0" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.0.11", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "escalade": "^3.1.1", + "picocolors": "^1.0.0" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/vite": { + "version": "4.4.7", + "license": "MIT", + "dependencies": { + "esbuild": "^0.18.10", + "postcss": "^8.4.26", + "rollup": "^3.25.2" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + }, + "peerDependencies": { + "@types/node": ">= 14", + "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/vite-plugin-svgr": { + "version": "3.2.0", + "license": "MIT", + "dependencies": { + "@rollup/pluginutils": "^5.0.2", + "@svgr/core": "^7.0.0", + "@svgr/plugin-jsx": "^7.0.0" + }, + "peerDependencies": { + "vite": "^2.6.0 || 3 || 4" + } + }, + "node_modules/vite/node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/warning": { + "version": "4.0.3", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.0.0" + } + }, + "node_modules/which": { + "version": "2.0.2", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/which-boxed-primitive": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "is-bigint": "^1.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "is-symbol": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-typed-array": { + "version": "1.1.11", + "dev": true, + "license": "MIT", + "dependencies": { + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "dev": true, + "license": "ISC" + }, + "node_modules/ws": { + "version": "8.11.0", + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/xmlhttprequest-ssl": { + "version": "2.0.0", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/yallist": { + "version": "3.1.1", + "license": "ISC" + }, + "node_modules/yaml": { + "version": "1.10.2", + "license": "ISC", + "engines": { + "node": ">= 6" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/yup": { + "version": "1.2.0", + "license": "MIT", + "dependencies": { + "property-expr": "^2.0.5", + "tiny-case": "^1.0.3", + "toposort": "^2.0.2", + "type-fest": "^2.19.0" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..8802098 --- /dev/null +++ b/package.json @@ -0,0 +1,57 @@ +{ + "name": "gym-react", + "private": true, + "version": "0.0.0", + "type": "module", + "scripts": { + "dev": "vite", + "build": "vite build", + "lint": "eslint src --ext js,jsx --report-unused-disable-directives --max-warnings 0", + "preview": "vite preview" + }, + "dependencies": { + "@emotion/react": "^11.11.1", + "@emotion/styled": "^11.11.0", + "@mui/icons-material": "^5.11.16", + "@mui/material": "^5.13.5", + "@mui/system": "^5.13.5", + "@mui/x-charts": "^6.0.0-alpha.0", + "@mui/x-data-grid": "^6.8.0", + "axios": "^1.4.0", + "chart.js": "^4.3.0", + "date-fns": "^2.30.0", + "js-cookie": "^3.0.5", + "jwt-decode": "^3.1.2", + "moment": "^2.29.4", + "react": "^18.2.0", + "react-big-calendar": "^1.8.1", + "react-chartjs-2": "^5.2.0", + "react-datepicker": "^4.16.0", + "react-dom": "^18.2.0", + "react-icons": "^4.10.1", + "react-player": "^2.12.0", + "react-router-dom": "^6.14.0", + "react-scrollable-feed": "^1.3.2", + "react-slick": "^0.29.0", + "react-toastify": "^9.1.3", + "slick-carousel": "^1.8.1", + "socket.io-client": "^4.7.1", + "styled-components": "^5.3.11", + "swiper": "^9.4.1", + "vite-plugin-svgr": "^3.2.0", + "yup": "^1.2.0" + }, + "devDependencies": { + "@types/react": "^18.0.37", + "@types/react-dom": "^18.0.11", + "@vitejs/plugin-react": "^4.0.0", + "eslint": "^8.43.0", + "eslint-config-airbnb": "^19.0.4", + "eslint-plugin-import": "^2.27.5", + "eslint-plugin-jsx-a11y": "^6.7.1", + "eslint-plugin-react": "^7.32.2", + "eslint-plugin-react-hooks": "^4.6.0", + "eslint-plugin-react-refresh": "^0.3.4", + "vite": "^4.3.9" + } +} 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.jsx b/src/App.jsx new file mode 100644 index 0000000..fc3b54d --- /dev/null +++ b/src/App.jsx @@ -0,0 +1,16 @@ +import { RouterProvider } from 'react-router-dom'; +import { Box } from '@mui/material'; +import THEME from './utilize/Theme'; +import router from './routes/router'; +import AuthProvider from './context/authorization'; + +const App = () => ( + + + + + + + +); +export default App; diff --git a/src/assets/My_project.png b/src/assets/My_project.png new file mode 100644 index 0000000..72ae102 Binary files /dev/null and b/src/assets/My_project.png differ diff --git a/src/assets/class-removebg-preview.png b/src/assets/class-removebg-preview.png new file mode 100644 index 0000000..8527162 Binary files /dev/null and b/src/assets/class-removebg-preview.png differ diff --git a/src/assets/class2-removebg-preview.png b/src/assets/class2-removebg-preview.png new file mode 100644 index 0000000..9cd6829 Binary files /dev/null and b/src/assets/class2-removebg-preview.png differ diff --git a/src/assets/class3-removebg-preview.png b/src/assets/class3-removebg-preview.png new file mode 100644 index 0000000..0a3b99b Binary files /dev/null and b/src/assets/class3-removebg-preview.png differ diff --git a/src/assets/class4-removebg-preview.png b/src/assets/class4-removebg-preview.png new file mode 100644 index 0000000..a29cf22 Binary files /dev/null and b/src/assets/class4-removebg-preview.png differ diff --git a/src/assets/homeStore.svg b/src/assets/homeStore.svg new file mode 100644 index 0000000..17c0d38 --- /dev/null +++ b/src/assets/homeStore.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/login.svg b/src/assets/login.svg new file mode 100644 index 0000000..d36b946 --- /dev/null +++ b/src/assets/login.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/personal_trainer.svg b/src/assets/personal_trainer.svg new file mode 100644 index 0000000..dc851e4 --- /dev/null +++ b/src/assets/personal_trainer.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/react.svg b/src/assets/react.svg new file mode 100644 index 0000000..6c87de9 --- /dev/null +++ b/src/assets/react.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/shooping.svg b/src/assets/shooping.svg new file mode 100644 index 0000000..1d7798f --- /dev/null +++ b/src/assets/shooping.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/shopping.svg b/src/assets/shopping.svg new file mode 100644 index 0000000..3da147d --- /dev/null +++ b/src/assets/shopping.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/signupimage.svg b/src/assets/signupimage.svg new file mode 100644 index 0000000..5c5a5ff --- /dev/null +++ b/src/assets/signupimage.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/singupimage.svg b/src/assets/singupimage.svg new file mode 100644 index 0000000..0322b6c --- /dev/null +++ b/src/assets/singupimage.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/undraw_group_selfie_re_h8gb.svg b/src/assets/undraw_group_selfie_re_h8gb.svg new file mode 100644 index 0000000..779c18d --- /dev/null +++ b/src/assets/undraw_group_selfie_re_h8gb.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/undraw_newsletter_re_wrob.svg b/src/assets/undraw_newsletter_re_wrob.svg new file mode 100644 index 0000000..550443e --- /dev/null +++ b/src/assets/undraw_newsletter_re_wrob.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/undraw_shopping_app_flsj (2).svg b/src/assets/undraw_shopping_app_flsj (2).svg new file mode 100644 index 0000000..91ed29e --- /dev/null +++ b/src/assets/undraw_shopping_app_flsj (2).svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/undraw_social_interaction_re_dyjh.svg b/src/assets/undraw_social_interaction_re_dyjh.svg new file mode 100644 index 0000000..26ca39c --- /dev/null +++ b/src/assets/undraw_social_interaction_re_dyjh.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/undraw_team_page_re_cffb.svg b/src/assets/undraw_team_page_re_cffb.svg new file mode 100644 index 0000000..e3e7cc8 --- /dev/null +++ b/src/assets/undraw_team_page_re_cffb.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/undraw_time_management_re_tk5w.svg b/src/assets/undraw_time_management_re_tk5w.svg new file mode 100644 index 0000000..8dcf189 --- /dev/null +++ b/src/assets/undraw_time_management_re_tk5w.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/undraw_working_out_re_nhkg.svg b/src/assets/undraw_working_out_re_nhkg.svg new file mode 100644 index 0000000..0ad97f9 --- /dev/null +++ b/src/assets/undraw_working_out_re_nhkg.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/components/alert/Alert.jsx b/src/components/alert/Alert.jsx new file mode 100644 index 0000000..53ff9f4 --- /dev/null +++ b/src/components/alert/Alert.jsx @@ -0,0 +1,67 @@ +import * as React from 'react'; +import Alert from '@mui/material/Alert'; +import AlertTitle from '@mui/material/AlertTitle'; +import Stack from '@mui/material/Stack'; + +const Alerts = ({ type, message }) => { + if (type === 'error') { + return ( + + + Error + { message} + + + ); + } + + if (type === 'warning') { + return ( + + + Warning + {message} + + check it out! + + + ); + } + + if (type === 'info') { + return ( + + + Info + {message} + check it out! + + + ); + } + + if (type === 'success') { + return ( + + + + Success + {message} + + check it out! + + + ); + } + return ( + + + Error + {message} + + check it out! + + + ); +}; +export default Alerts; diff --git a/src/components/announcement/Announcement.jsx b/src/components/announcement/Announcement.jsx new file mode 100644 index 0000000..dfded94 --- /dev/null +++ b/src/components/announcement/Announcement.jsx @@ -0,0 +1,257 @@ +/* eslint-disable no-underscore-dangle */ +import { + Box, Divider, Typography, Button, Input, Container, +} from '@mui/material'; +import React, { useEffect, useState } from 'react'; +import axios from 'axios'; +import PersonIcon from '@mui/icons-material/Person'; +import DeleteIcon from '@mui/icons-material/Delete'; +import SendIcon from '@mui/icons-material/Send'; +import Image from '../../styles/image'; + +const Announcement = ({ announce }) => { + const [commentsData, setComments] = useState([]); + const [commentInput, setCommentInput] = useState(''); + const [showComments, setShowComments] = useState(false); + + const getComments = async () => { + try { + const { data: { comments } } = await axios.get('/api/comments'); + setComments(comments); + } catch (error) { + console.log(error); + } + }; + + const deleteComment = async (id) => { + try { + axios.delete(`/api/comments/${id}`); + getComments(); + } catch (error) { + console.log(error); + } + }; + + const addComment = async () => { + try { + await axios.post(`/api/comments/${announce._id}`, { comment: commentInput }); + setCommentInput(''); + getComments(); + } catch (error) { + console.log(error); + } + }; + useEffect(() => { + getComments(); + }, []); + + return ( + + + + + + {announce.roleId?.username} + + + {announce?.createdAt.split(':')[0].slice(0, 10).replaceAll('-', '/')} + + + + + + + {announce?.title} + {announce?.description} + {announce?.image + && ( + + gym + + + )} + + + {commentsData?.filter((comments) => (comments?.announcementId?._id === announce?._id)) + .length} + + + + + + + {commentsData && ( + + {commentsData?.filter((comments) => (comments?.announcementId?._id === announce?._id)) + .map((comment) => ( + + pic-profile + + + {comment?.userId?.username} + + + + {comment?.comment} + + + + + + + {comment?.createdAt.split(':')[0].slice(0, 10).replaceAll('-', '/')} + + + + deleteComment(comment?._id)} /> + + + + + ))} + + pic-profile + setCommentInput(e.target.value)} + /> + + + + + + )} + + + + ); +}; +export default Announcement; diff --git a/src/components/announcement/AnnouncementList.jsx b/src/components/announcement/AnnouncementList.jsx new file mode 100644 index 0000000..07da692 --- /dev/null +++ b/src/components/announcement/AnnouncementList.jsx @@ -0,0 +1,53 @@ +/* eslint-disable no-underscore-dangle */ +import { Box, Typography } from '@mui/material'; +import React, { useEffect, useState } from 'react'; +import axios from 'axios'; +import Announcement from './Announcement'; + +const AnnouncementList = () => { + const [announcement, setAnnouncement] = useState([]); + + const getAnnouncement = async () => { + const response = await axios.get('/api/announcements'); + setAnnouncement(response.data.announcements); + }; + + useEffect(() => { + getAnnouncement(); + }, []); + + return ( + + + + + Announcements + + + + + + {announcement?.map((announce) => ( + + ))} + + + ); +}; + +export default AnnouncementList; diff --git a/src/components/button/Button.jsx b/src/components/button/Button.jsx new file mode 100644 index 0000000..dec1057 --- /dev/null +++ b/src/components/button/Button.jsx @@ -0,0 +1,35 @@ +import { Button } from '@mui/material'; +import styled from 'styled-components'; + +const ButtonComponent = ({ + variant, + color, + children, + flex, + onClick, + secondOnClick, + width, +}) => ( + + {children} + +); +const StyledButton = styled(Button)` + flex: ${({ flex }) => (flex || '0.2')}; + padding: .7rem 1rem !important; + font-weight:600 !important; + font-size:14px !important; +`; + +export default ButtonComponent; diff --git a/src/components/categoriesList/index.jsx b/src/components/categoriesList/index.jsx new file mode 100644 index 0000000..defd15b --- /dev/null +++ b/src/components/categoriesList/index.jsx @@ -0,0 +1,60 @@ +/* eslint-disable no-underscore-dangle */ +import axios from 'axios'; +import React, { useEffect, useState } from 'react'; +import { Box, Divider, Typography } from '@mui/material'; +import { NavLink } from 'react-router-dom'; +import CategoryCard from '../categoryCard/CategoryCard'; + +const CategoriesList = ({ setCategory }) => { + const [categories, setCategories] = useState([]); + const getAllCategories = async () => { + const response = await axios.get('/api/categories'); + setCategories([...categories, response.data.categories]); + }; + useEffect(() => { + getAllCategories(); + }, []); + + return ( + + Categories + + + + { + categories[0]?.map((category) => ( + ({ + textDecoration: 'none', + padding: '5px 10px', + border: '1px solid #FF4601', + borderRadius: '5px', + transition: 'all 0.5s ease', + textTransform: 'capitalize', + color: '#Fff', + width: 150, + })} + to="." + key={category._id} + onClick={() => setCategory(category.categoryName)} + > + + + )) + } + + + ); +}; + +export default CategoriesList; diff --git a/src/components/categoryCard/CategoryCard.jsx b/src/components/categoryCard/CategoryCard.jsx new file mode 100644 index 0000000..d607eac --- /dev/null +++ b/src/components/categoryCard/CategoryCard.jsx @@ -0,0 +1,24 @@ +import { Box, Typography } from '@mui/material'; +import * as React from 'react'; + +const CategoryCard = ({ category }) => ( + + + + {category.categoryImage + ? {category.categoryName} + : null} + + + {category.categoryName} + + + +); +export default CategoryCard; diff --git a/src/components/chart/index.jsx b/src/components/chart/index.jsx new file mode 100644 index 0000000..7b4cf9d --- /dev/null +++ b/src/components/chart/index.jsx @@ -0,0 +1,62 @@ +import * as React from 'react'; +import { BarPlot } from '@mui/x-charts/BarChart'; +import { LinePlot } from '@mui/x-charts/LineChart'; +import { ChartContainer } from '@mui/x-charts/ChartContainer'; + +import { ChartsXAxis } from '@mui/x-charts/ChartsXAxis'; +import { ChartsYAxis } from '@mui/x-charts/ChartsYAxis'; + +const series = [ + { + type: 'bar', + stack: '', + yAxisKey: 'eco', + data: [2, 5, 3, 4, 1], + }, + { + type: 'bar', + stack: '', + yAxisKey: 'eco', + data: [5, 6, 2, 8, 9], + }, + { + type: 'line', + yAxisKey: 'pib', + color: 'red', + data: [1000, 1500, 3000, 5000, 10000], + }, +]; + +const Combining = () => ( + value.toString(), + }, + ]} + yAxis={[ + { + id: 'eco', + scaleType: 'linear', + }, + { + id: 'pib', + scaleType: 'log', + }, + ]} + > + + + + + + +); + +export default Combining; diff --git a/src/components/chat/index.jsx b/src/components/chat/index.jsx new file mode 100644 index 0000000..31048c9 --- /dev/null +++ b/src/components/chat/index.jsx @@ -0,0 +1,159 @@ +import { Box, Container, Snackbar } from '@mui/material'; +import axios from 'axios'; +import { useState, useEffect } from 'react'; +import useAuth from '../../hook/useAuth'; +import socket from '../../socket'; +import MessageLists from '../messageLists'; + +const Chat = () => { + const [message, setMessage] = useState(''); + + const [messages, setMessages] = useState([]); + const [users, setUsers] = useState([]); + const { user: userData } = useAuth(); + + const [userJoinNotification, setUserJoinNotification] = useState(''); + + const [isConnected, setIsConnectsed] = useState(false); + + const handleSubmit = (e) => { + e.preventDefault(); + socket.emit('send-message', { + userData, + message, + }); + + setMessages((prev) => [ + ...prev, + { + _id: new Date().toISOString(), + message, + // eslint-disable-next-line no-underscore-dangle + user: userData._id, + username: userData.username, + }, + ]); + setMessage(''); + }; + + const onConnect = () => { + setIsConnectsed(true); + }; + + const handleJoin = (data) => { + if (!userData) return; + + setUserJoinNotification(`${data.payload.username} has joined the chat`); + setTimeout(() => setUserJoinNotification(''), 3000); + }; + + const handleMessage = (data) => { + setMessages((prev) => [...prev, data.payload]); + }; + + const getChatMessages = async () => { + const { data } = await axios.get('/api/chat/getChat'); + + setMessages(Object.values(data.room.messages)); + }; + + const handleUsersList = (data) => { + setUsers(Object.values(data.payload)); + }; + + useEffect(() => { + if (!userData) return; + + getChatMessages(); + + socket.emit('join', userData); + }, [isConnected]); + + useEffect(() => { + socket.on('connect', onConnect); + socket.on('user-join', handleJoin); + socket.on('receive-message', handleMessage); + socket.on('users-list', handleUsersList); + + return () => { + socket.on('disconnect', () => { + socket.emit('user-disconnect', userData); + }); + }; + }, []); + + return ( + + + + + + + { + setMessage(e.target.value); + }} + /> + + + + + {users.map((user) => ( +

{user.username}

+ ))} +
+
+
+ +
+ ); +}; + +export default Chat; diff --git a/src/components/classInfo/index.jsx b/src/components/classInfo/index.jsx new file mode 100644 index 0000000..ae15d2a --- /dev/null +++ b/src/components/classInfo/index.jsx @@ -0,0 +1,134 @@ +/* eslint-disable no-underscore-dangle */ +/* eslint-disable no-nested-ternary */ +import { Box, Container, Typography } from '@mui/material'; +import React, { useEffect, useState } from 'react'; +import { useParams } from 'react-router-dom'; +import axios from 'axios'; +import { toast } from 'react-toastify'; +import { Calendar, momentLocalizer } from 'react-big-calendar'; +import moment from 'moment'; +import ButtonComponent from '../button/Button'; +import ToastAlert from '../toastAlert/ToastAlert'; +import useAuth from '../../hook/useAuth'; + +const ClassInfoComp = () => { + const { id } = useParams(); + const { user } = useAuth(); + + const [classData, setClassData] = useState({}); + const [subscriptionStatus, setSubscriptionStatus] = useState({}); + const [classCalendar, setClassCalendar] = useState([]); + + const localizer = momentLocalizer(moment); + + const getClassById = async () => { + try { + const response = await axios.get(`/api/classes/${id}`); + setClassData(response.data.classObj); + } catch (error) { + console.log(error); + } + }; + + const getOneSubscription = async () => { + const { data: { userSubscriptionData } } = await axios.get('/api/subscriptions/user'); + const filterSubscription = userSubscriptionData?.filter( + (subscription) => subscription.classId?._id === id, + ); + setSubscriptionStatus(filterSubscription[0]); + }; + + const addSubscription = async () => { + try { + const { data } = await axios.post(`/api/subscriptions/${id}`); + setSubscriptionStatus(data.data); + toast.success('Subscription added successfully!', { + theme: 'dark', + }); + getOneSubscription(); + } catch (error) { + toast.error('Adding subscription!', { + theme: 'dark', + }); + } + }; + + const getCalendar = async () => { + try { + const { data: { calendarByClassId } } = await axios.get(`/api/calendar/${id}`); + const classCalendarData = calendarByClassId.map((calendarClassData) => ({ + _id: calendarClassData?._id, + title: calendarClassData.classId?.className, + start: new Date(calendarClassData?.start), + end: new Date(calendarClassData?.end), + })); + setClassCalendar(classCalendarData); + } catch (error) { + console.log(error); + } + }; + + useEffect(() => { + getClassById(); + getOneSubscription(); + getCalendar(); + }, [id]); + + return ( + + + + { + !classData ? (no data) + : ( + + + {classData.className} + + + trainer + {classData.trainerId?.username} + + + {user ? ( + + {subscriptionStatus?.status === 'joined' + ? 'Joined' + : subscriptionStatus?.status === 'pending' + ? 'Pending' : 'Join Class'} + + ) : null} + + + + {classData.description} + + + + + + + + + ) + + } + + + ); +}; +export default ClassInfoComp; diff --git a/src/components/classTable/ClassTable.jsx b/src/components/classTable/ClassTable.jsx new file mode 100644 index 0000000..95c50b7 --- /dev/null +++ b/src/components/classTable/ClassTable.jsx @@ -0,0 +1,39 @@ +import * as React from 'react'; +import Table from '@mui/material/Table'; +import TableBody from '@mui/material/TableBody'; +import TableCell from '@mui/material/TableCell'; +import TableHead from '@mui/material/TableHead'; +import TableRow from '@mui/material/TableRow'; + +const rows = [ + { day: 'Saturday', time: '2:30 - 4:30' }, + { day: 'Monday', time: '9:00 - 11:00' }, + { day: 'Wednesday', time: '5:30 - 7:30' }, + +]; + +const ClassTable = () => ( + + + + + Days + Times + + + + {rows.map((row) => ( + + + {row.day} + + + {row.time} + + + ))} + +
+ +); +export default ClassTable; diff --git a/src/components/classesList/index.jsx b/src/components/classesList/index.jsx new file mode 100644 index 0000000..68fca9c --- /dev/null +++ b/src/components/classesList/index.jsx @@ -0,0 +1,72 @@ +import { Box, Divider } from '@mui/material'; +import axios from 'axios'; +import React, { useEffect, useState } from 'react'; +import { NavLink } from 'react-router-dom'; + +// const classes = ['Yoga', 'Building', 'Fitness', 'food']; +const ClassesList = () => { + const [classData, setClassData] = useState([]); + + const getClassData = async () => { + const response = await axios.get('/api/classes'); + setClassData([...classData, response.data.classesData]); + }; + + useEffect(() => { + getClassData(); + }, []); + + return ( + + ({ + backgroundColor: 'transparent', + textDecoration: 'none', + padding: '5px 10px', + borderRadius: '5px', + transition: 'all 0.5s ease', + textTransform: 'capitalize', + color: 'white', + border: '1px solid #ff5700', + })} + > + Classes + + + + + {classData[0]?.map((classItem) => ( + ({ + backgroundColor: isActive ? '#FF4601' : '', + color: '#fff', + fontSize: '12px', + fontWeight: '500', + textDecoration: 'none', + display: 'block', + padding: '16px', + })} + mt={3} + > + {classItem.className} + + ))} + + + ); +}; +export default ClassesList; diff --git a/src/components/deleteDataBtn/index.jsx b/src/components/deleteDataBtn/index.jsx new file mode 100644 index 0000000..c9a05f0 --- /dev/null +++ b/src/components/deleteDataBtn/index.jsx @@ -0,0 +1,16 @@ +import DeleteIcon from '@mui/icons-material/Delete'; +import axios from 'axios'; +import ButtonComponent from '../button/Button'; + +const DeleteButtonCell = ({ id, url }) => { + const handleDelete = async () => { + await axios.delete(`${url}/${id}`); + }; + return ( + + + + ); +}; + +export default DeleteButtonCell; diff --git a/src/components/dropDownList/index.jsx b/src/components/dropDownList/index.jsx new file mode 100644 index 0000000..750c3ce --- /dev/null +++ b/src/components/dropDownList/index.jsx @@ -0,0 +1,84 @@ +/* eslint-disable no-shadow */ +import * as React from 'react'; +import Button from '@mui/material/Button'; +import Menu from '@mui/material/Menu'; +import MenuItem from '@mui/material/MenuItem'; +import MoreVertIcon from '@mui/icons-material/MoreVert'; +import axios from 'axios'; +import DeleteButtonCell from '../deleteDataBtn'; +import DashboardNewPopUp from '../newPopUpComp'; + +const reducer = (state, action) => ({ + ...state, + [action.filedName]: action.value, +}); +const DropDownList = ({ + row, url, userInfo, initialState, +}) => { + const [changeAble, setChangeAble] = React.useState(false); + const [state, dispatch] = React.useReducer(reducer, initialState); + console.log(state); + const handleChange = (e, filedName) => { + setChangeAble(true); + const { value } = e.target; + dispatch({ + filedName, + value, + }); + }; + const updateData = async () => { + const res = await axios.put(`${url}/${row.id}`, state); + console.log(res); + }; + const rowData = Object.values(row.row); + const editData = rowData.filter((data, i) => i !== 0); + const [anchorEl, setAnchorEl] = React.useState(null); + const open = Boolean(anchorEl); + const handleClick = (event) => { + setAnchorEl(event.currentTarget); + }; + const handleClose = () => { + setAnchorEl(null); + }; + + return ( +
+ + + + + Edit + + + + + + +
+ ); +}; + +export default DropDownList; diff --git a/src/components/editData/index.jsx b/src/components/editData/index.jsx new file mode 100644 index 0000000..ddc3c87 --- /dev/null +++ b/src/components/editData/index.jsx @@ -0,0 +1,11 @@ +import React from 'react' + +const EditData = () => { + return ( +
+ < +
+ ) +} + +export default EditData diff --git a/src/components/footer/Footer.jsx b/src/components/footer/Footer.jsx new file mode 100644 index 0000000..e7d145d --- /dev/null +++ b/src/components/footer/Footer.jsx @@ -0,0 +1,51 @@ +import { Box, Typography } from '@mui/material'; +import React from 'react'; +import FacebookIcon from '@mui/icons-material/Facebook'; +import InstagramIcon from '@mui/icons-material/Instagram'; +import YouTubeIcon from '@mui/icons-material/YouTube'; +import LinkedInIcon from '@mui/icons-material/LinkedIn'; +import LocalPhoneIcon from '@mui/icons-material/LocalPhone'; + +const Footer = () => ( + + + + + Gaza, Alrimal, AlJondi St., Capital Mall Building, + 5th Floor, Room 501 + + + + + + + + + + + Non Copyrighted © 2023 Design and upload by rich technologies + + + + +972 595036287 + + + + +); + +export default Footer; diff --git a/src/components/formDashboard/FormDashBoard.jsx b/src/components/formDashboard/FormDashBoard.jsx new file mode 100644 index 0000000..9e27127 --- /dev/null +++ b/src/components/formDashboard/FormDashBoard.jsx @@ -0,0 +1,48 @@ +/* eslint-disable no-underscore-dangle */ +import React from 'react'; +import { Box, Select, Typography } from '@mui/material'; +import InputForm from './InputForm'; +import GroupButtons from './GroupButtons'; + +const FormDashBoard = ({ + userInfo, text, onClick, setStates, axiosData, filedName, value, selectList, +}) => ( + + {text} + + + + {userInfo.map((info, index) => ( + + {' '} + {info} + + ))} + + {selectList + ? ( + + ) + : null} + + + + + + +); + +export default FormDashBoard; diff --git a/src/components/formDashboard/GroupButtons.jsx b/src/components/formDashboard/GroupButtons.jsx new file mode 100644 index 0000000..2e42e98 --- /dev/null +++ b/src/components/formDashboard/GroupButtons.jsx @@ -0,0 +1,11 @@ +import { ButtonGroup } from '@mui/material'; +import ButtonComponent from '../button/Button'; + +const GroupButtons = ({ onClick, axiosData }) => ( + + Submit + Cancel + +); + +export default GroupButtons; diff --git a/src/components/formDashboard/InputForm.jsx b/src/components/formDashboard/InputForm.jsx new file mode 100644 index 0000000..eedcc0f --- /dev/null +++ b/src/components/formDashboard/InputForm.jsx @@ -0,0 +1,36 @@ +/* eslint-disable no-nested-ternary */ +import { FormControl, Input, InputLabel } from '@mui/material'; +import React from 'react'; + +const InputForm = ({ + children, setState, filedName, value, +}) => ( + + + {children} + + + setState(e, filedName)} + id="my-input" + aria-describedby="my-helper-text" + sx={{ + color: '#fff', + fontSize: 13, + + }} + /> + +); + +export default InputForm; diff --git a/src/components/headerClient/Header.jsx b/src/components/headerClient/Header.jsx new file mode 100644 index 0000000..dcfaf71 --- /dev/null +++ b/src/components/headerClient/Header.jsx @@ -0,0 +1,64 @@ +import React from 'react'; +import { Box, Typography, Container } from '@mui/material'; +import { Link } from 'react-router-dom'; +import ButtonComponent from '../button/Button'; + +const Header = () => ( + + + + + + + Unleash + Your Inner Athlete + + + Get ready to sweat it out and achieve your fitness goals with + our high-energy fitness classes! + We provide a fun + and motivating environment to help you reach your peak performance. + + + + Classes + + + Shop Now + + + + + + + +); + +export default Header; diff --git a/src/components/homeClass/index.jsx b/src/components/homeClass/index.jsx new file mode 100644 index 0000000..6545c26 --- /dev/null +++ b/src/components/homeClass/index.jsx @@ -0,0 +1,235 @@ +import { + Box, Card, CardContent, CardMedia, Typography, +} from '@mui/material'; +import axios from 'axios'; +import { useEffect, useState } from 'react'; +import SubscriptionImg from '../../assets/undraw_newsletter_re_wrob.svg'; +import Team from '../../assets/undraw_team_page_re_cffb.svg'; +import ClassRoom from '../../assets/undraw_social_interaction_re_dyjh.svg'; +import Time from '../../assets/undraw_time_management_re_tk5w.svg'; + +const HomeClass = () => { + const [subscriptionsCount, setSubscriptionsCount] = useState({}); + const [trainersCount, setTrainersCount] = useState({}); + const [classesCount, setClassesCount] = useState({}); + + const getSubscriptionCount = async () => { + const { data: { subscriptionsData } } = await axios.get('/api/subscriptions'); + setSubscriptionsCount(subscriptionsData); + }; + + const getTrainersCount = async () => { + const { data: { allTrainers } } = await axios.get('/api/users/trainers'); + setTrainersCount(allTrainers); + }; + + const getClassesCount = async () => { + const { data: { classesData } } = await axios.get('/api/classes'); + setClassesCount(classesData); + }; + + useEffect(() => { + getSubscriptionCount(); + getTrainersCount(); + getClassesCount(); + }, []); + return ( + + + + Welcome To Our Community + + + + We have the map to find your best version of your body. + + + + + + + + Subscriptions + + + + {subscriptionsCount.length} + + Subscriptions + + + + + + + + + Trainers + + + + {trainersCount.length} + + Trainers + + + + + + + + + Classes + + + + {classesCount.length} + + Classes + + + + + + + + + Appointments + + + + Check our + + Time + + + + + + + + + + + ); +}; + +export default HomeClass; diff --git a/src/components/homeStore/HomeStore.jsx b/src/components/homeStore/HomeStore.jsx new file mode 100644 index 0000000..9cfcbf7 --- /dev/null +++ b/src/components/homeStore/HomeStore.jsx @@ -0,0 +1,74 @@ +import React from 'react'; +import { Box, Container, Typography } from '@mui/material'; + +const HomeStore = () => ( + + + + + + G + + Y + + + M Store + + + At Gym, you can shop for all useful stuff , clothes, + accessories, tools and more at a single place. + + + +
+ 50% +
+
+
+
+ +); + +export default HomeStore; diff --git a/src/components/index.js b/src/components/index.js new file mode 100644 index 0000000..6fb8881 --- /dev/null +++ b/src/components/index.js @@ -0,0 +1,63 @@ +import MenuComp from './menu/Menu'; +import CategoryCard from './categoryCard/CategoryCard'; +import NavbarClient from './navbar/NavbarClient'; +import TrainerCard from './trainerCard/TrainerCard'; +import ClassTable from './classTable/ClassTable'; +import ProductCard from './productCard'; +import PersonalInfo from './personalInfo/PersonalInfo'; +import Alerts from './alert/Alert'; +import ToastAlert from './toastAlert/ToastAlert'; +import ProductStatisticList from './orderProductStatistic/ProductStatisticList'; +import Header from './headerClient/Header'; +import ProductDetails from './productDetailsCard/ProductDetails'; +import HomeStore from './homeStore/HomeStore'; +import Statistic from './statistic'; +import Announcement from './announcement/Announcement'; +import AnnouncementList from './announcement/AnnouncementList'; +import MessageLists from './messageLists'; +import ClassInfoComp from './classInfo'; +import Table from './table'; +import SliderComp from './slider'; +import FormDashBoard from './formDashboard/FormDashBoard'; +import SignInComp from './signinform'; +import ProfileNav from './profileNav'; +import ProductList from './productList/ProductList'; +import Footer from './footer/Footer'; +import CategoriesList from './categoriesList'; +import ClassesList from './classesList'; +import UserSettingData from './userSettingData/UserSettingData'; +import InputComp from './inputfield'; +import HomeClass from './homeClass'; + +export { + MenuComp, + ProductCard, + PersonalInfo, + NavbarClient, + ClassTable, + Alerts, + CategoryCard, + ToastAlert, + ProductStatisticList, + ProductDetails, + HomeStore, + Header, + TrainerCard, + MessageLists, + Statistic, + Announcement, + AnnouncementList, + ClassInfoComp, + Table, + SliderComp, + FormDashBoard, + SignInComp, + ProfileNav, + ProductList, + Footer, + CategoriesList, + ClassesList, + UserSettingData, + InputComp, + HomeClass, +}; diff --git a/src/components/inputfield/index.jsx b/src/components/inputfield/index.jsx new file mode 100644 index 0000000..b6c533f --- /dev/null +++ b/src/components/inputfield/index.jsx @@ -0,0 +1,54 @@ +import React from 'react'; +import { TextField, InputAdornment } from '@mui/material'; + +const InputComp = (props) => { + const { + name, icon, value, onChange, filedName, error, type, setFunction, + } = props; + return ( + { + onChange(e, filedName); + }} + sx={{ + borderRadius: '0px', + borderColor: '#FF4601', + '& .MuiOutlinedInput-notchedOutline': { + borderColor: '#fff', + borderRadius: '0.625rem', + padding: '0.78125rem', + paddingBottom: '2rem', + position: 'absolute', + width: '100%', + + }, + '& .Mui-error': { + paddingTop: '8px', + }, + }} + InputProps={{ + startAdornment: ( + + {icon} + + ), + inputProps: { + style: { color: '#fff', fontWeight: '500', fontSize: '13px' }, + }, + }} + /> + ); +}; + +export default InputComp; diff --git a/src/components/menu/Menu.jsx b/src/components/menu/Menu.jsx new file mode 100644 index 0000000..a99820c --- /dev/null +++ b/src/components/menu/Menu.jsx @@ -0,0 +1,42 @@ +import * as React from 'react'; +import Button from '@mui/material/Button'; +import Menu from '@mui/material/Menu'; +import MenuItem from '@mui/material/MenuItem'; +import PersonIcon from '@mui/icons-material/Person'; + +const MenuComp = () => { + const [anchorEl, setAnchorEl] = React.useState(null); + const open = Boolean(anchorEl); + const handleClick = (event) => { + setAnchorEl(event.currentTarget); + }; + const handleClose = () => { + setAnchorEl(null); + }; + + return ( +
+ + + Profile + My account + Logout + +
+ ); +}; + +export default MenuComp; diff --git a/src/components/message/index.jsx b/src/components/message/index.jsx new file mode 100644 index 0000000..2fc5fb5 --- /dev/null +++ b/src/components/message/index.jsx @@ -0,0 +1,60 @@ +import { Box, Typography, Divider } from '@mui/material'; +import React from 'react'; +import useAuth from '../../hook/useAuth'; + +const Message = ({ message }) => { + const { user: userData } = useAuth(); + + if (!userData) return null; + + return ( + + person + + + + {message.username === userData.username ? 'you' : message.username} + + + + {message.message} + + + {message.createdAt.split(':')[0].slice(0, 10).replaceAll('-', '/')} + + + + + ); +}; + +export default Message; diff --git a/src/components/messageLists/index.jsx b/src/components/messageLists/index.jsx new file mode 100644 index 0000000..40bde65 --- /dev/null +++ b/src/components/messageLists/index.jsx @@ -0,0 +1,27 @@ +/* eslint-disable no-underscore-dangle */ +import { Box } from '@mui/material'; +import ScrollableFeed from 'react-scrollable-feed'; +import Message from '../message'; + +const MessageLists = ({ messages }) => ( + + + + {messages.map((message) => ( + + + + ))} + + + +); + +export default MessageLists; diff --git a/src/components/modal/index.jsx b/src/components/modal/index.jsx new file mode 100644 index 0000000..5699414 --- /dev/null +++ b/src/components/modal/index.jsx @@ -0,0 +1,49 @@ +import * as React from 'react'; +import Backdrop from '@mui/material/Backdrop'; +import Box from '@mui/material/Box'; +import Modal from '@mui/material/Modal'; +import Fade from '@mui/material/Fade'; + +const style = { + position: 'absolute', + top: '50%', + left: '50%', + transform: 'translate(-50%, -50%)', + width: 400, + bgcolor: 'background.paper', + border: '2px solid #000', + boxShadow: 24, + p: 4, +}; + +const TransitionsModal = ({ children, open, setOpen }) => { + const handleClose = () => setOpen(false); + + return ( + + + {children ? ( + + {children} + + ) : ( + + )} + + + ); +}; + +export default TransitionsModal; diff --git a/src/components/navbar/NavbarClient.jsx b/src/components/navbar/NavbarClient.jsx new file mode 100644 index 0000000..014c350 --- /dev/null +++ b/src/components/navbar/NavbarClient.jsx @@ -0,0 +1,194 @@ +/* eslint-disable operator-linebreak */ +/* eslint-disable react/jsx-one-expression-per-line */ +/* eslint-disable array-callback-return */ +import { useState } from 'react'; +import axios from 'axios'; +import PersonIcon from '@mui/icons-material/Person'; +import AccountCircleIcon from '@mui/icons-material/AccountCircle'; +import SettingsIcon from '@mui/icons-material/Settings'; +import LoginIcon from '@mui/icons-material/Login'; +import { + AppBar, + Box, + Toolbar, + IconButton, + Menu, + MenuItem, + Tooltip, + Typography, +} from '@mui/material'; +import { Link, NavLink, useNavigate } from 'react-router-dom'; +import useAuth from '../../hook/useAuth'; + +const unAuthenticatedPages = ['home', 'store', 'class']; +const authenticatedPages = [...unAuthenticatedPages, 'chat', 'announcement']; + +const NavbarClient = () => { + const [anchorElUser, setAnchorElUser] = useState(null); + + const { user: userData, logout } = useAuth(); + + const settings = [ + { name: 'profile', icon: }, + { name: 'setting', icon: }, + { name: userData ? 'signout' : 'signin', icon: }, + ]; + const navigate = useNavigate(); + + const handleOpenUserMenu = (event) => { + setAnchorElUser(event.currentTarget); + }; + + const handleCloseUserMenu = () => { + setAnchorElUser(null); + }; + + const logoutFun = async () => { + try { + axios.delete('/api/users/signout'); + logout(); + navigate('/signin'); + } catch (error) { + console.log(error.message); + } + }; + + return ( + + + + GYM + + + + {(userData ? authenticatedPages : unAuthenticatedPages).map( + (page) => ( + ({ + backgroundColor: isActive ? '#FF4601' : '', + textDecoration: 'none', + padding: '5px 10px', + borderRadius: '5px', + transition: 'all 0.5s ease', + textTransform: 'capitalize', + color: 'white', + })} + key={page} + > + {page} + + ), + )} + + + {userData ? ( + + + + + + + + {settings.map((setting) => { + const link = + setting.name === 'signout' ? 'signin' : setting.name; + return ( + + {setting.icon} + + {setting.name} + + + ); + })} + + + {userData && userData?.username} + + + ) : ( + + + + )} + + + ); +}; +export default NavbarClient; diff --git a/src/components/newPopUpComp/index.jsx b/src/components/newPopUpComp/index.jsx new file mode 100644 index 0000000..402b140 --- /dev/null +++ b/src/components/newPopUpComp/index.jsx @@ -0,0 +1,56 @@ +import React, { useState } from 'react'; +import Box from '@mui/material/Box'; +import Modal from '@mui/material/Modal'; + +import FormDashBoard from '../formDashboard/FormDashBoard'; +import ButtonComponent from '../button/Button'; + +const style = { + position: 'absolute', + top: '50%', + left: '50%', + transform: 'translate(-50%, -50%)', + width: 800, + bgcolor: '#000', + border: '2px solid #000', + boxShadow: 24, + p: 2, + +}; + +const DashboardNewPopUp = ({ + children, userInfo, setStates, axiosData, filedName, value, selectList, +}) => { + const [open, setOpen] = useState(false); + const handleOpen = () => setOpen(true); + const handleClose = () => setOpen(false); + return ( +
+ + {children} + + + + + + +
+ ); +}; + +export default DashboardNewPopUp; diff --git a/src/components/orderProductStatistic/OrderProductStatistic.jsx b/src/components/orderProductStatistic/OrderProductStatistic.jsx new file mode 100644 index 0000000..ddb5d3d --- /dev/null +++ b/src/components/orderProductStatistic/OrderProductStatistic.jsx @@ -0,0 +1,43 @@ +/* eslint-disable no-underscore-dangle */ +import React from 'react'; +import { Box, Typography } from '@mui/material'; + +const OrderProductStatistic = ({ product, orders }) => ( + + + pic-order-product + + {' '} + {product.title} + + + + {orders.filter((order) => product._id === order.productId._id).length} + + + +); + +export default OrderProductStatistic; diff --git a/src/components/orderProductStatistic/ProductStatisticList.jsx b/src/components/orderProductStatistic/ProductStatisticList.jsx new file mode 100644 index 0000000..c1e3ab2 --- /dev/null +++ b/src/components/orderProductStatistic/ProductStatisticList.jsx @@ -0,0 +1,40 @@ +/* eslint-disable no-unused-vars */ +import React from 'react'; +import { Box, Typography } from '@mui/material'; +import { useOutletContext } from 'react-router-dom'; +import OrderProductStatistic from './OrderProductStatistic'; + +const ProductStatisticList = () => { + const [users, classes, subs, products, categories, trainers, ordersData] = useOutletContext(); + + return ( + + + Most Ordered Product + which are the most ordered products + + + {products?.map((product) => ( + + ))} + + + ); +}; + +export default ProductStatisticList; diff --git a/src/components/passwordFrom/index.jsx b/src/components/passwordFrom/index.jsx new file mode 100644 index 0000000..83d9b05 --- /dev/null +++ b/src/components/passwordFrom/index.jsx @@ -0,0 +1,93 @@ +import { + Box, Button, Input, Typography, +} from '@mui/material'; +import axios from 'axios'; +import React, { useState } from 'react'; +import CancelIcon from '@mui/icons-material/Cancel'; + +const ForgetPasswordComp = ({ setShowBox, showBox }) => { + const [userData, setUserData] = useState({ + email: '', + password: '', + }); + const changePassword = async () => { + try { + if (userData.email === '' || userData.password === '') { + return; + } + await axios.put('/api/users/forget', userData); + } catch (error) { + console.log(error); + } + }; + return ( + + + reset your password + + + + setUserData({ ...userData, email: e.target.value })} + sx={{ + color: '#fff', + fontSize: 14, + width: 360, + pl: 2, + }} + /> + + setUserData({ ...userData, password: e.target.value })} + sx={{ + color: '#fff', + fontSize: 14, + width: 360, + pl: 2, + }} + /> + + + setShowBox(!showBox)} + /> + + ); +}; + +export default ForgetPasswordComp; diff --git a/src/components/personalInfo/PersonalInfo.jsx b/src/components/personalInfo/PersonalInfo.jsx new file mode 100644 index 0000000..40d48a6 --- /dev/null +++ b/src/components/personalInfo/PersonalInfo.jsx @@ -0,0 +1,59 @@ +import * as React from 'react'; +import { Box, Typography } from '@mui/material'; +import MailIcon from '@mui/icons-material/Mail'; +import { Link } from 'react-router-dom'; +import ButtonComponent from '../button/Button'; + +const PersonalInfo = ({ userData }) => ( + + + + pic-profile + + + + + {userData?.username} + {' '} + + + + {' '} + {userData?.weight} + {' '} + KG + + + + + {userData?.email} + + + Profile Info + + + + + +); + +export default PersonalInfo; diff --git a/src/components/productCard/index.jsx b/src/components/productCard/index.jsx new file mode 100644 index 0000000..0161f5a --- /dev/null +++ b/src/components/productCard/index.jsx @@ -0,0 +1,59 @@ +/* eslint-disable no-underscore-dangle */ +import * as React from 'react'; +import Card from '@mui/material/Card'; +import CardActions from '@mui/material/CardActions'; +import CardContent from '@mui/material/CardContent'; +import CardMedia from '@mui/material/CardMedia'; +import Button from '@mui/material/Button'; +import Typography from '@mui/material/Typography'; +import { Link } from 'react-router-dom'; + +const ProductCard = ({ product }) => ( + + + + + {product.title} + + + {product.price} + {' '} + $ + + + + + + + +); + +export default ProductCard; diff --git a/src/components/productDetailsCard/ProductDetails.jsx b/src/components/productDetailsCard/ProductDetails.jsx new file mode 100644 index 0000000..3d59e06 --- /dev/null +++ b/src/components/productDetailsCard/ProductDetails.jsx @@ -0,0 +1,112 @@ +/* eslint-disable no-nested-ternary */ +/* eslint-disable no-underscore-dangle */ +import { useState, useEffect } from 'react'; +import { + Box, Card, CardContent, CardMedia, Typography, +} from '@mui/material'; +import axios from 'axios'; +import { useParams } from 'react-router-dom'; +import StarIcon from '@mui/icons-material/Star'; +import StarBorderIcon from '@mui/icons-material/StarBorder'; +import { toast } from 'react-toastify'; +import ButtonComponent from '../button/Button'; +import ToastAlert from '../toastAlert/ToastAlert'; +import useAuth from '../../hook/useAuth'; + +const ProductDetails = () => { + const { user } = useAuth(); + const { id } = useParams(); + const [product, setProduct] = useState({}); + const [ordersData, setOrdersData] = useState({}); + const amount = 1; + const getProductDetails = async () => { + const response = await axios.get(`/api/products/${id}`); + setProduct(response.data.product); + }; + + const getOrders = async () => { + const { data: { orders } } = await axios.get('/api/orders/user'); + const filterOrders = orders?.filter((order) => order.productId?._id === id); + setOrdersData(filterOrders[0]); + }; + + const addOrder = async () => { + try { + await axios.post(`/api/orders/${id}`, { amount }); + + getOrders(); + toast.success('Added order successfully', { + theme: 'dark', + }); + } catch (error) { + toast.error('You have been already ordered', { + theme: 'dark', + }); + } + }; + + useEffect(() => { + getProductDetails(); + getOrders(); + }, []); + + return ( + + + + + + {product.title} + + {product.description && ( + + {product.description} + + )} + + + Reviews + + + + + + + + {user + ? ( + + {ordersData?.status === 'paid' + ? 'Paid' + : ordersData?.status === 'requested' + ? 'Requested' : 'Order'} + + ) + : null} + + + + + ); +}; + +export default ProductDetails; diff --git a/src/components/productDetailsCard/style.js b/src/components/productDetailsCard/style.js new file mode 100644 index 0000000..43c8963 --- /dev/null +++ b/src/components/productDetailsCard/style.js @@ -0,0 +1,13 @@ +const cardStyle = { + boxShadow: '-3px 4px 1px -1px #ff4601', + display: 'flex', + alignItems: 'center', + borderRadius: '10px', + width: '900px', + p: '30px', + margin: 'auto', + backgroundColor: 'rgba(0,0,0,0.1)', + +}; + +export default cardStyle; diff --git a/src/components/productList/ProductList.jsx b/src/components/productList/ProductList.jsx new file mode 100644 index 0000000..69e157b --- /dev/null +++ b/src/components/productList/ProductList.jsx @@ -0,0 +1,94 @@ +/* eslint-disable no-unreachable-loop */ +import Box from '@mui/material/Box'; +import { + Button, Container, Divider, Typography, +} from '@mui/material'; +import { useEffect, useState } from 'react'; +import axios from 'axios'; +import { useOutletContext } from 'react-router'; +import CancelIcon from '@mui/icons-material/Cancel'; +import ProductCard from '../productCard'; + +const ProductList = () => { + let category = useOutletContext(); + const [allProducts, setAllProducts] = useState([]); + const [filteredProducts, setFilteredProducts] = useState([]); + + const getProductsByCategory = () => { + if (!category) { + return; + } + const filteredData = allProducts.filter( + (product) => product.categoryId?.categoryName === category, + ); + + setFilteredProducts([filteredData]); + }; + + const getProducts = async () => { + const { data, status } = await axios.get('/api/products'); + if (status === 200) { + setAllProducts(data.products); + } + }; + + useEffect(() => { + getProducts(); + }, []); + + useEffect(() => { + getProductsByCategory(); + }, [category]); + return ( + + + + {!category ? 'All product' : category} + {category ? ( + + ) : null} + + + + + + { + // eslint-disable-next-line no-nested-ternary + filteredProducts[0]?.length > 0 ? filteredProducts[0]?.map((product) => ( + // eslint-disable-next-line no-underscore-dangle + + )) + : allProducts?.length > 0 ? allProducts?.map((product) => ( + // eslint-disable-next-line no-underscore-dangle + + )) + : there is no data + } + + + + ); +}; +export default ProductList; diff --git a/src/components/profileNav/index.jsx b/src/components/profileNav/index.jsx new file mode 100644 index 0000000..00764c6 --- /dev/null +++ b/src/components/profileNav/index.jsx @@ -0,0 +1,36 @@ +import React from 'react'; +import { Box, Button } from '@mui/material'; + +const profileNav = ['orders', 'classes']; +const ProfileNav = ({ setTableName, getData }) => ( + + + {profileNav.map((item) => ( + + ))} + + + +); + +export default ProfileNav; diff --git a/src/components/ratingChart/index.jsx b/src/components/ratingChart/index.jsx new file mode 100644 index 0000000..6fce179 --- /dev/null +++ b/src/components/ratingChart/index.jsx @@ -0,0 +1,88 @@ +/* eslint-disable no-unused-vars */ +/* eslint-disable no-underscore-dangle */ +import { Box, Typography } from '@mui/material'; +import { useOutletContext } from 'react-router-dom'; + +const RatingChart = () => { + const [users, classes, subs, products, categories, trainers, orderData] = useOutletContext(); + return ( + + Rating + Lorem ipsum dolor sit amet, consectetur + + + + 85% + Revenu + + + + + + {`${orderData.length * orderData.filter((order) => order.status === 'paid').length}%`} + Orders + + + + + + + {`${subs.length * subs.filter((sub) => sub.status === 'joined').length}%`} + Subscription + + + + + + + ); +}; +export default RatingChart; diff --git a/src/components/sectionHome/index.jsx b/src/components/sectionHome/index.jsx new file mode 100644 index 0000000..0a55cac --- /dev/null +++ b/src/components/sectionHome/index.jsx @@ -0,0 +1,40 @@ +import { Box, Typography } from '@mui/material'; + +const SectionHome = () => ( + + + Fit For Your Lifestyle + + + Wake up with a sunrise meditation, + sweat it out with lunchtime HIIT, or unwind with an evening flow. + You’ll find movement for every mood with classes sorted by time, + style, and skill level. + + + pic-home + + +); +export default SectionHome; diff --git a/src/components/signinform/index.jsx b/src/components/signinform/index.jsx new file mode 100644 index 0000000..baa1f9a --- /dev/null +++ b/src/components/signinform/index.jsx @@ -0,0 +1,140 @@ +/* eslint-disable consistent-return */ +import React, { useReducer } from 'react'; +import { Box, Button, Typography } from '@mui/material'; +import styled from 'styled-components'; +import { Link, useNavigate } from 'react-router-dom'; +import axios from 'axios'; +import { passwordIcon, userIcon } from '../../utilize/icons'; +import InputComp from '../inputfield'; +import useAuth from '../../hook/useAuth'; + +const FormWrapper = styled.form` + display: flex; + flex-direction: column; + padding: 2rem; + text-align: center; +`; + +const InputContainer = styled.div` + width: 450px; + display: flex; + flex-direction: column; + justify-content: center; +`; + +const initialState = { + email: '', + password: '', +}; + +const reducer = (state, action) => ({ + ...state, + [action.filedName]: action.value, +}); + +const SignInComp = ({ setShowBox, showBox }) => { + const { login } = useAuth(); + const [state, dispatch] = useReducer(reducer, initialState); + // const { userLogged, setUserLogged } = useContext(AuthContext); + + const handleChange = (e, filedName) => { + const { value } = e.target; + dispatch({ + filedName, + value, + }); + }; + const navigate = useNavigate(); + const signIn = async (e) => { + e.preventDefault(); + const { data, status } = await axios.post('/api/users/login', state); + if (status === 200) { + login(data.user); + + if (data.user.role === 'user') { + // setUserLogged(!userLogged); + return navigate('/'); + } + return navigate('/dashboard'); + } + }; + + return ( + + signIn(e)}> + + + Login + + + + + + + I do not have an account ? + + {' '} + Sign up + + + + + + + + + + + ); +}; + +export default SignInComp; diff --git a/src/components/signup/index.jsx b/src/components/signup/index.jsx new file mode 100644 index 0000000..1e31468 --- /dev/null +++ b/src/components/signup/index.jsx @@ -0,0 +1,224 @@ +import { useReducer, useState } from 'react'; +import axios from 'axios'; +import { Typography, Box } from '@mui/material'; +import { Link } from 'react-router-dom'; +import CheckCircleIcon from '@mui/icons-material/CheckCircle'; +import InputComp from '../inputfield'; +import ButtonComponent from '../button/Button'; +import { CompWrapper, ButtonContainer, FieldColumn } from './styledComps'; +import { + passwordIcon, + userIcon, + genderIcon, + weightIcon, + emailIcon, + birthDataIcon, + heightIcon, +} from '../../utilize/icons'; + +import Modal from '../modal/index'; + +import validationSchema from '../../validation/signupValidation'; + +const initialState = { + username: '', + age: '', + email: '', + gender: '', + height: '', + weight: '', + goalweight: '', + password: '', + confirmPassword: '', +}; + +const reducer = (state, action) => ({ + ...state, + [action.filedName]: action.value, +}); + +const SignupComp = () => { + const [state, dispatch] = useReducer(reducer, initialState); + const [errors, setErrors] = useState({}); + const [openModal, setOpenModal] = useState(false); + const handleChange = (e, filedName) => { + const { value } = e.target; + dispatch({ + filedName, + value, + }); + }; + + const handleSignUp = async () => { + const response = await axios.post('/api/users/signup', state); + if (response.status === 201) { + setOpenModal(true); + } + }; + + const handleSubmit = () => { + validationSchema + .validate(state, { abortEarly: false }) + .then(() => { + handleSignUp(); + }) + .catch((err) => { + const validationErrors = {}; + err.inner.forEach((error) => { + validationErrors[error.path] = error.message; + }); + console.log({ validationErrors }); + setErrors(validationErrors); + }); + }; + return ( + <> + + + + Sign Up + + + + + + + + + + + + + + + + + + + Sign up + + + + + +
+ + Thank you! +

+ Your details have been successfully submitted. Thanks! +

+ + Have a fun at our community! + + + Click here to Srart your Journey + +
+ +
+ + ); +}; + +export default SignupComp; diff --git a/src/components/signup/styledComps.jsx b/src/components/signup/styledComps.jsx new file mode 100644 index 0000000..8c72d18 --- /dev/null +++ b/src/components/signup/styledComps.jsx @@ -0,0 +1,31 @@ +import styled from 'styled-components'; + +const SignupWrapper = styled.div` +// display: flex; +// flex-wrap: wrap; +// justify-content: space-between; +// align-content: center; +// padding: 0rem; +// width:50%; +`; +const FieldColumn = styled.div` +display: grid; +grid-template-columns: repeat(2, 1fr); +gap:15px; +`; + +const CompWrapper = styled.div` +margin-top:70px; +width: 60%; +`; + +const ButtonContainer = styled.div` +margin-top: 1rem; +width: 100%; +display: flex; +justify-content: center; +`; + +export { + CompWrapper, ButtonContainer, FieldColumn, SignupWrapper, +}; diff --git a/src/components/slider/index.jsx b/src/components/slider/index.jsx new file mode 100644 index 0000000..25b8521 --- /dev/null +++ b/src/components/slider/index.jsx @@ -0,0 +1,73 @@ +/* eslint-disable react/jsx-props-no-spreading */ +import { useState } from 'react'; +import Slider from 'react-slick'; +import { FaArrowRight, FaArrowLeft } from 'react-icons/fa'; +import '../../styles/swiper.css'; +import { Box, Typography } from '@mui/material'; + +const images = [ + 'https://img.freepik.com/free-photo/woman-with-visible-abs-doing-fitness_23-2150228908.jpg', + 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcT8iWj_vyiCFGummOzn8w8UEDNSZbZZxGPR3xx-7gyAyctSPKf4ARUP-9dayfcztqAbtW0&usqp=CAU', + 'https://images.wsj.net/im-376632/social', + 'https://c4.wallpaperflare.com/wallpaper/679/865/217/machine-workout-fitness-gym-wallpaper-preview.jpg', + 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQRSSE1Sis0dN23uDZEP3JXtSRP-L-QHFVN9A&usqp=CAU', + 'https://cdn.i-scmp.com/sites/default/files/styles/652x446/public/d8/images/methode/2019/08/16/8a886dee-bcd9-11e9-8f25-9b5536624008_image_hires_181832.jpg?itok=UaEfrmb5&v=1565950717', +]; + +const NextArrow = ({ onClick }) => ( + +); + +const PrevArrow = ({ onClick }) => ( + +); + +const SliderComp = () => { + const [imageIndex, setImageIndex] = useState(0); + + const settings = { + FullWidthMode: true, + infinite: true, + lazyLoad: true, + speed: 800, + slidesToShow: 3, + centerMode: true, + centerPadding: 0, + nextArrow: , + prevArrow: , + beforeChange: (current, next) => setImageIndex(next), + }; + + return ( + + + {images.map((img, idx) => ( + + + Find what moves you + + + Are you ready to change? + + {img} + + ))} + + + ); +}; + +export default SliderComp; diff --git a/src/components/statistic/index.jsx b/src/components/statistic/index.jsx new file mode 100644 index 0000000..d419585 --- /dev/null +++ b/src/components/statistic/index.jsx @@ -0,0 +1,150 @@ +import { ExpandLess, ExpandMore } from '@mui/icons-material'; +import { + Collapse, Divider, List, ListItem, ListItemText, ListSubheader, Typography, +} from '@mui/material'; +import { useState } from 'react'; +import { useOutletContext } from 'react-router-dom'; + +const Statistic = () => { + const [users, classes, subs, products, categories, trainers] = useOutletContext(); + const [openUsers, setOpenUsers] = useState(true); + const [openClasses, setOpenClasses] = useState(true); + const [openProducts, setOpenProducts] = useState(true); + const handleClickUsers = () => { + setOpenUsers(!openUsers); + }; + const handleClickClasses = () => { + setOpenClasses(!openClasses); + }; + const handleClickProducts = () => { + setOpenProducts(!openProducts); + }; + + return ( + + Statistics + + )} + > + + Users} + /> + {openUsers ? : } + + + + + Clients} + /> + {users.length}} + /> + + + Trainers} + /> + {trainers.length}} + /> + + + + + + + + + Classes} + /> + {openClasses ? : } + + + + + {classes.map((item) => ( + + {item.className}} + /> + + { + subs.filter((sub) => sub.classId.className === item.className).length + + } + + )} + /> + + ))} + + + + + + + + Products} + /> + {openProducts ? : } + + + + {categories.map((cata) => ( + + {cata.categoryName}} + /> + + { + products.filter((prod) => prod.categoryId?.categoryName === cata.categoryName) + .length + } + + )} + /> + + ))} + + + + + ); +}; + +export default Statistic; diff --git a/src/components/swiper/index.jsx b/src/components/swiper/index.jsx new file mode 100644 index 0000000..0c3e1df --- /dev/null +++ b/src/components/swiper/index.jsx @@ -0,0 +1,57 @@ +/* eslint-disable react/no-array-index-key */ +/* eslint-disable import/no-unresolved */ +import { Box, Typography } from '@mui/material'; +import React, { useEffect, useState } from 'react'; +import 'swiper/css'; +import 'swiper/css/navigation'; +import 'swiper/css/pagination'; +import 'swiper/css/scrollbar'; +import { + Navigation, Pagination, Scrollbar, A11y, +} from 'swiper'; +import { Swiper, SwiperSlide } from 'swiper/react'; +import axios from 'axios'; + +const SwiperComp = ({ images }) => { + const [trainers, setTrainers] = useState([]); + const getTrainers = async () => { + const { data } = await axios.get('/api/users/trainers'); + setTrainers(data.allTrainers); + }; + + useEffect(() => { + getTrainers(); + }, []); + return ( + + Instructors + console.log(swiper)} + onSlideChange={() => console.log('slide change')} + > + + {trainers.map((item, idx) => ( + + {item.username} + {item.username} + gym trainer + + ))} + + + + ); +}; + +export default SwiperComp; diff --git a/src/components/table/index.jsx b/src/components/table/index.jsx new file mode 100644 index 0000000..018d805 --- /dev/null +++ b/src/components/table/index.jsx @@ -0,0 +1,25 @@ +/* eslint-disable no-underscore-dangle */ +import * as React from 'react'; +import Box from '@mui/material/Box'; +import { DataGrid } from '@mui/x-data-grid'; + +const Table = ({ rows, columns }) => ( + + row._id} + initialState={{ + pagination: { + paginationModel: { + pageSize: 5, + }, + }, + }} + pageSizeOptions={[5]} + checkboxSelection + disableRowSelectionOnClick + /> + +); +export default Table; diff --git a/src/components/toastAlert/ToastAlert.jsx b/src/components/toastAlert/ToastAlert.jsx new file mode 100644 index 0000000..c2b37f3 --- /dev/null +++ b/src/components/toastAlert/ToastAlert.jsx @@ -0,0 +1,12 @@ +import React from 'react'; + +import { ToastContainer } from 'react-toastify'; + +import 'react-toastify/dist/ReactToastify.css'; + +const ToastAlert = () => ( +
+ +
+); +export default ToastAlert; diff --git a/src/components/trainerCard/TrainerCard.jsx b/src/components/trainerCard/TrainerCard.jsx new file mode 100644 index 0000000..afade44 --- /dev/null +++ b/src/components/trainerCard/TrainerCard.jsx @@ -0,0 +1,35 @@ +import * as React from 'react'; +import { + Card, CardContent, CardMedia, Typography, +} from '@mui/material'; + +const TrainerCard = () => ( + + + + + Leslie Alexander + + + Gym Trainer + + + + +); + +export default TrainerCard; diff --git a/src/components/userSettingData/UserSettingData.jsx b/src/components/userSettingData/UserSettingData.jsx new file mode 100644 index 0000000..3bd4c4f --- /dev/null +++ b/src/components/userSettingData/UserSettingData.jsx @@ -0,0 +1,187 @@ +/* eslint-disable no-underscore-dangle */ +import { Box, Button, Typography } from '@mui/material'; +import Divider from '@mui/material/Divider'; +import { useReducer } from 'react'; +import axios from 'axios'; +import { useNavigate } from 'react-router-dom'; +import DashboardNewPopUp from '../newPopUpComp'; +import useAuth from '../../hook/useAuth'; + +const userInfo = [ + 'username', + 'email', + 'age', + 'gender', + 'height', + 'weight', + 'goalweight', +]; + +const initialState = { + username: '', + email: '', + age: '', + gender: '', + height: '', + weight: '', + goalweight: '', +}; + +const reducer = (state, action) => ({ + ...state, + [action.filedName]: action.value, +}); +const UserSettingData = () => { + const { user: userSettingData, logout } = useAuth(); + + const navigate = useNavigate(); + const [state, dispatch] = useReducer(reducer, initialState); + const values = [ + state.username, + state.email, + state.age, + state.gender, + state.height, + state.weight, + state.goalweight, + ]; + + const handleChange = (e, filedName) => { + const { value } = e.target; + dispatch({ + filedName, + value, + }); + }; + + const updateUser = async () => { + try { + await axios.put(`/api/users/${userSettingData._id}`, state); + } catch (error) { + console.log(error); + } + }; + + const deleteUserInfo = async () => { + try { + await axios.delete('/api/users'); + logout(); + navigate('/'); + } catch (error) { + console.log(error); + } + }; + + return ( + + + + user information + + pic-profile + + + + + username: + + + {userSettingData?.username} + + + + + Email: + + + {userSettingData?.email} + + + + + age: + + + {userSettingData?.age} + + + + + + + weight: + + + {userSettingData?.weight} + + + + + height: + + + {userSettingData?.height} + + + + + goal weight: + + + {userSettingData?.goalweight} + + + + edit + + + + + + ); +}; +export default UserSettingData; diff --git a/src/components/videoCom/index.jsx b/src/components/videoCom/index.jsx new file mode 100644 index 0000000..18d46f9 --- /dev/null +++ b/src/components/videoCom/index.jsx @@ -0,0 +1,18 @@ +import React from 'react'; +import { Box } from '@mui/material'; +import ReactPlayer from 'react-player'; + +const VideoPlayer = () => ( + + + +); +export default VideoPlayer; diff --git a/src/context/Provider.jsx b/src/context/Provider.jsx new file mode 100644 index 0000000..77e0598 --- /dev/null +++ b/src/context/Provider.jsx @@ -0,0 +1,16 @@ +import React from 'react'; +import FormContext from '.'; + +const Provider = ({ + setShowForm, children, editBtnText, deleteBtnText, showForm, +}) => ( + // eslint-disable-next-line react/jsx-no-constructed-context-values + + {children} + +); + +export default Provider; diff --git a/src/context/admin.jsx b/src/context/admin.jsx new file mode 100644 index 0000000..75ff8bc --- /dev/null +++ b/src/context/admin.jsx @@ -0,0 +1,17 @@ +import React from 'react'; +import { Navigate } from 'react-router-dom'; +import useAuth from '../hook/useAuth'; + +const CheckAdminProvider = ({ children }) => { + const { user, isLoading } = useAuth(); + if (isLoading) { + return
Loading...
; + } + + if (user?.role === 'admin') { + return ; + } + return children; +}; + +export default CheckAdminProvider; diff --git a/src/context/authContex.js b/src/context/authContex.js new file mode 100644 index 0000000..0e50159 --- /dev/null +++ b/src/context/authContex.js @@ -0,0 +1,5 @@ +import { createContext } from 'react'; + +const AuthContext = createContext(); + +export default AuthContext; diff --git a/src/context/authorization.jsx b/src/context/authorization.jsx new file mode 100644 index 0000000..0e0bf22 --- /dev/null +++ b/src/context/authorization.jsx @@ -0,0 +1,14 @@ +import { useState } from 'react'; +import AuthContext from './authContex'; + +const AuthProvider = ({ children }) => { + const [user, setUser] = useState(null); + + return ( + // eslint-disable-next-line react/jsx-no-constructed-context-values + + {children} + + ); +}; +export default AuthProvider; diff --git a/src/context/index.js b/src/context/index.js new file mode 100644 index 0000000..2eaf7de --- /dev/null +++ b/src/context/index.js @@ -0,0 +1,5 @@ +import { createContext } from 'react'; + +const FormContext = createContext(); + +export default FormContext; diff --git a/src/context/navigate.jsx b/src/context/navigate.jsx new file mode 100644 index 0000000..afb24e8 --- /dev/null +++ b/src/context/navigate.jsx @@ -0,0 +1,17 @@ +import React from 'react'; +import { Navigate } from 'react-router-dom'; +import useAuth from '../hook/useAuth'; + +const RequireAuthProvider = ({ children }) => { + const { user, isLoading } = useAuth(); + if (isLoading) { + return
Loading...
; + } + if (user?.role === 'user' || !user?.role) { + return ; + } + + return children; +}; + +export default RequireAuthProvider; diff --git a/src/dashboardComponents/barChart/index.jsx b/src/dashboardComponents/barChart/index.jsx new file mode 100644 index 0000000..bfb56d1 --- /dev/null +++ b/src/dashboardComponents/barChart/index.jsx @@ -0,0 +1,65 @@ +/* eslint-disable no-unused-vars */ +import { Box } from '@mui/material'; +import React, { useState } from 'react'; +import { Bar } from 'react-chartjs-2'; +import { Chart as ChartJS } from 'chart.js/auto'; + +const userData2 = [ + { + id: 1, + year: 2016, + userGain: 80000, + userLost: 823, + }, + { + id: 2, + year: 2017, + userGain: 45000, + userLost: 345, + }, + { + id: 3, + year: 2018, + userGain: 78888, + userLost: 555, + }, + { + id: 4, + year: 2019, + userGain: 90000, + userLost: 4555, + }, + { + id: 5, + year: 2020, + userGain: 4300, + userLost: 234, + }, +]; +const BarChart = () => { + const [userData, setUserData] = useState({ + labels: userData2.map((data) => data.year), + datasets: [{ + label: 'user gained', + data: userData2.map((data) => data.userGain), + backgroundColor: [ + 'rgba(75,192,192,1)', + '#ecf0f1', + '#50af95', + '#f3ba2f', + '#2a71d0', + ], + }], + }); + return ( + + + + + ); +}; + +export default BarChart; diff --git a/src/dashboardComponents/button/addButton.jsx b/src/dashboardComponents/button/addButton.jsx new file mode 100644 index 0000000..6d69a59 --- /dev/null +++ b/src/dashboardComponents/button/addButton.jsx @@ -0,0 +1,16 @@ +import { Button } from '@mui/material'; +import React from 'react'; + +const AddButton = ({ + text, setShowForm, showForm, axiosData, +}) => ( + +); + +export default AddButton; diff --git a/src/dashboardComponents/button/deleteButton.jsx b/src/dashboardComponents/button/deleteButton.jsx new file mode 100644 index 0000000..f09d07f --- /dev/null +++ b/src/dashboardComponents/button/deleteButton.jsx @@ -0,0 +1,14 @@ +import { Button } from '@mui/material'; +import React from 'react'; + +const DeleteButton = ({ text, setShowForm, showForm }) => ( + +); + +export default DeleteButton; diff --git a/src/dashboardComponents/button/editButton.jsx b/src/dashboardComponents/button/editButton.jsx new file mode 100644 index 0000000..919f0cb --- /dev/null +++ b/src/dashboardComponents/button/editButton.jsx @@ -0,0 +1,13 @@ +import { Button } from '@mui/material'; +import React from 'react'; + +const EditButton = ({ text, axiosData }) => ( + +); + +export default EditButton; diff --git a/src/dashboardComponents/button/index.js b/src/dashboardComponents/button/index.js new file mode 100644 index 0000000..db02b9f --- /dev/null +++ b/src/dashboardComponents/button/index.js @@ -0,0 +1,5 @@ +import AddButton from './addButton'; +import DeleteButton from './deleteButton'; +import EditButton from './editButton'; + +export { AddButton, DeleteButton, EditButton }; diff --git a/src/dashboardComponents/card/index.jsx b/src/dashboardComponents/card/index.jsx new file mode 100644 index 0000000..8baab48 --- /dev/null +++ b/src/dashboardComponents/card/index.jsx @@ -0,0 +1,144 @@ +/* eslint-disable no-underscore-dangle */ +import { + Box, Card, CardContent, CardMedia, Typography, +} from '@mui/material'; +import Group from '../../assets/undraw_group_selfie_re_h8gb.svg'; +import Shop from '../../assets/undraw_shopping_app_flsj (2).svg'; +import Classes from '../../assets/undraw_working_out_re_nhkg.svg'; + +const CardDash = ({ + users, trainers, categories, products, classes, subs, +}) => ( + + + + + + + Users + + + client + {users?.length} + + + Trainers + {trainers?.length} + + + + + + + + + Products + + + + {categories.map((category) => ( + + {category.categoryName} + {products.filter((product) => product.categoryId?._id === category._id).length} + + ))} + + + + + + + + + + Classes + + + {classes.map((classItem) => ( + + {classItem.className} + {subs.filter((sub) => sub?.classId?._id === classItem?._id).length} + + ))} + + + + + + +); + +export default CardDash; diff --git a/src/dashboardComponents/chart/index.jsx b/src/dashboardComponents/chart/index.jsx new file mode 100644 index 0000000..7bf8c36 --- /dev/null +++ b/src/dashboardComponents/chart/index.jsx @@ -0,0 +1,80 @@ +/* eslint-disable no-unused-vars */ +import { Box } from '@mui/material'; +import React, { useState } from 'react'; +import { Bar, Line } from 'react-chartjs-2'; +import { Chart as ChartJS } from 'chart.js/auto'; + +const userData2 = [ + { + id: 1, + year: 2016, + userGain: 80000, + userLost: 823, + }, + { + id: 2, + year: 2017, + userGain: 45000, + userLost: 345, + }, + { + id: 3, + year: 2018, + userGain: 78888, + userLost: 555, + }, + { + id: 4, + year: 2019, + userGain: 90000, + userLost: 4555, + }, + { + id: 5, + year: 2020, + userGain: 22200, + userLost: 234, + }, + { + id: 6, + year: 2021, + userGain: 44400, + userLost: 234, + }, + { + id: 7, + year: 2022, + userGain: 66600, + userLost: 234, + }, + { + id: 8, + year: 2023, + userGain: 43000, + userLost: 234, + }, +]; +const ChartDash = () => { + const [userData, setUserData] = useState({ + labels: userData2.map((data) => data.year), + datasets: [{ + label: 'user gained', + data: userData2.map((data) => data.userGain), + backgroundColor: [ + 'rgba(75,192,192,1)', + 'orange', + '#50af95', + '#f3ba2f', + '#2a71d0', + ], + }], + }); + return ( + + + + + ); +}; + +export default ChartDash; diff --git a/src/dashboardComponents/form/Editform.jsx b/src/dashboardComponents/form/Editform.jsx new file mode 100644 index 0000000..3ebe57a --- /dev/null +++ b/src/dashboardComponents/form/Editform.jsx @@ -0,0 +1,81 @@ +/* eslint-disable no-underscore-dangle */ +import { + Box, FormControl, Input, InputLabel, Select, Typography, MenuItem, +} from '@mui/material'; +import React from 'react'; +import { DeleteButton, EditButton } from '../button'; + +const EditForm = ({ + setShowForm, showForm, axiosData, setState, head, values, state, selectData, + setSelectDataId, selectDataId, title, +}) => ( + + {title} + + {head.map((inp) => ( + + {inp} + setState({ ...state, [inp]: e.target.value })} + sx={{ + fontSize: 15, + color: '#fff', + borderBottom: '1px solid #ccc', + }} + id={inp} + aria-describedby="my-helper-text" + /> + + ))} + + {selectData && ( + + + Category + + + + + )} + + + + + + +); + +export default EditForm; diff --git a/src/dashboardComponents/form/addForm.jsx b/src/dashboardComponents/form/addForm.jsx new file mode 100644 index 0000000..fd97260 --- /dev/null +++ b/src/dashboardComponents/form/addForm.jsx @@ -0,0 +1,73 @@ +/* eslint-disable no-underscore-dangle */ +/* eslint-disable no-nested-ternary */ +import { + Box, FormControl, Input, InputLabel, MenuItem, Select, Typography, +} from '@mui/material'; +import { AddButton, DeleteButton } from '../button'; + +const AddForm = ({ + setShowForm, showForm, axiosData, setState, head, selectData, + setSelectDataId, selectDataId, title, selectLabel, +}) => ( + + {title} + + {head?.map((inp) => ( + + {inp} + setState(e, inp)} + sx={{ fontSize: 12, color: '#fff', borderBottom: '1px solid #ccc' }} + id={inp} + aria-describedby="my-helper-text" + /> + + ))} + + {selectData && ( + + + {selectLabel} + + + + + )} + + + + + + + + + +); +export default AddForm; diff --git a/src/dashboardComponents/index.js b/src/dashboardComponents/index.js new file mode 100644 index 0000000..2ba13f1 --- /dev/null +++ b/src/dashboardComponents/index.js @@ -0,0 +1,30 @@ +import BarChart from './barChart'; +import { AddButton, DeleteButton, EditButton } from './button'; +import CardDash from './card'; +import ChartDash from './chart'; +import EditForm from './form/Editform'; +import AddForm from './form/addForm'; +import NavbarDash from './navbar'; +import OrderStatistics from './orders'; +import RatingDash from './rating'; +import SearchInpDash from './search'; +import SideBar from './sidebar'; +import DashTable from './table'; + +export { + BarChart, + AddButton, + DeleteButton, + EditButton, + CardDash, + ChartDash, + AddForm, + EditForm, + NavbarDash, + OrderStatistics, + SearchInpDash, + SideBar, + DashTable, + RatingDash, + +}; diff --git a/src/dashboardComponents/navbar/index.jsx b/src/dashboardComponents/navbar/index.jsx new file mode 100644 index 0000000..1609830 --- /dev/null +++ b/src/dashboardComponents/navbar/index.jsx @@ -0,0 +1,105 @@ +import AppBar from '@mui/material/AppBar'; +import Box from '@mui/material/Box'; +import Toolbar from '@mui/material/Toolbar'; +import IconButton from '@mui/material/IconButton'; +import Typography from '@mui/material/Typography'; +import Menu from '@mui/material/Menu'; +import Container from '@mui/material/Container'; +import Avatar from '@mui/material/Avatar'; +import Tooltip from '@mui/material/Tooltip'; +import MenuItem from '@mui/material/MenuItem'; +import { useState } from 'react'; +import FitnessCenterIcon from '@mui/icons-material/FitnessCenter'; +import { Link, useNavigate } from 'react-router-dom'; +import { Button } from '@mui/material'; +import axios from 'axios'; +import useAuth from '../../hook/useAuth'; + +const settings = ['Profile', 'Logout']; + +const NavbarDash = () => { + const [anchorElUser, setAnchorElUser] = useState(null); + const navigate = useNavigate(); + const handleOpenUserMenu = (event) => { + setAnchorElUser(event.currentTarget); + }; + + const handleCloseUserMenu = () => { + setAnchorElUser(null); + }; + const { logout } = useAuth(); + const logOut = async () => { + try { + await axios.delete('/api/users/signout'); + logout(); + navigate('/'); + } catch (error) { + console.log(error); + } + }; + + return ( + + + + + + Gym + + + + + + + + + + {settings.map((setting) => ( + + {setting === 'Profile' ? {setting} : } + + + ))} + + + + + + ); +}; +export default NavbarDash; diff --git a/src/dashboardComponents/orders/Orders.jsx b/src/dashboardComponents/orders/Orders.jsx new file mode 100644 index 0000000..1b28ff3 --- /dev/null +++ b/src/dashboardComponents/orders/Orders.jsx @@ -0,0 +1,45 @@ +/* eslint-disable no-underscore-dangle */ +import React from 'react'; +import { Box, Typography } from '@mui/material'; + +const OrderProductStatistic = ({ product, mostOrders }) => ( + + + pic-order-product + + {' '} + {product.title} + + + + + {mostOrders.filter((item) => item.product === product.title).length} + + + + +); + +export default OrderProductStatistic; diff --git a/src/dashboardComponents/orders/index.jsx b/src/dashboardComponents/orders/index.jsx new file mode 100644 index 0000000..b290fbd --- /dev/null +++ b/src/dashboardComponents/orders/index.jsx @@ -0,0 +1,37 @@ +/* eslint-disable no-underscore-dangle */ +/* eslint-disable no-unused-vars */ +import React from 'react'; +import { Box, Typography } from '@mui/material'; +import OrderProductStatistic from './Orders'; + +const OrderStatistics = ({ mostOrders, products }) => ( + + + Most Ordered Product + which are the most ordered products + + + {products?.map((product) => ( + + ))} + + +); + +export default OrderStatistics; diff --git a/src/dashboardComponents/rating/index.jsx b/src/dashboardComponents/rating/index.jsx new file mode 100644 index 0000000..d34ac7d --- /dev/null +++ b/src/dashboardComponents/rating/index.jsx @@ -0,0 +1,92 @@ +/* eslint-disable no-underscore-dangle */ +import { Box, Typography } from '@mui/material'; + +const RatingDash = ({ mostOrders, subs }) => { + const paid = mostOrders.filter((item) => item.status === 'paid').length; + const requested = mostOrders.filter((item) => item.status === 'requested').length; + const joined = subs.filter((item) => item.status === 'joined').length; + const pending = subs.filter((item) => item.status === 'pending').length; + return ( + + Rating + Lorem ipsum dolor sit , consectetur + + + + 85% + Revenu + + + + + + {Math.round(requested + paid / mostOrders.length)} + {' '} + % + Orders + + + + + + + {Math.round(joined + pending / subs.length)} + {' '} + % + Subscription + + + + + + + ); +}; +export default RatingDash; diff --git a/src/dashboardComponents/search/index.jsx b/src/dashboardComponents/search/index.jsx new file mode 100644 index 0000000..a5eb263 --- /dev/null +++ b/src/dashboardComponents/search/index.jsx @@ -0,0 +1,64 @@ +import * as React from 'react'; +import TextField from '@mui/material/TextField'; +import Stack from '@mui/material/Stack'; +import Autocomplete from '@mui/material/Autocomplete'; + +const SearchInpDash = ({ data, handleClick, searchBy }) => ( + + { + handleClick({ text: newValue }); + }} + onInputChange={(event, newInputValue) => { + if (!newInputValue) { + handleClick({ text: newInputValue }); + } + }} + disableClearable + options={data?.map((option) => option[searchBy]) || []} + renderInput={(params) => ( + + )} + /> + +); +export default SearchInpDash; diff --git a/src/dashboardComponents/sidebar/index.jsx b/src/dashboardComponents/sidebar/index.jsx new file mode 100644 index 0000000..e7d7de9 --- /dev/null +++ b/src/dashboardComponents/sidebar/index.jsx @@ -0,0 +1,220 @@ +import * as React from 'react'; +import Divider from '@mui/material/Divider'; +import Paper from '@mui/material/Paper'; +import MenuList from '@mui/material/MenuList'; +import MenuItem from '@mui/material/MenuItem'; +import ListItemIcon from '@mui/material/ListItemIcon'; +import Typography from '@mui/material/Typography'; +import HomeIcon from '@mui/icons-material/Home'; +import PersonIcon from '@mui/icons-material/Person'; +import InventoryIcon from '@mui/icons-material/Inventory'; +import FitnessCenterIcon from '@mui/icons-material/FitnessCenter'; +import ShoppingCartIcon from '@mui/icons-material/ShoppingCart'; +import CampaignIcon from '@mui/icons-material/Campaign'; +import GroupAddIcon from '@mui/icons-material/GroupAdd'; +import { NavLink } from 'react-router-dom'; + +const SideBar = () => ( + + + MENU + + + + + + + ({ + backgroundColor: isActive ? '#FF4601' : '', + textDecoration: 'none', + padding: '5px 10px', + borderRadius: '5px', + transition: 'all 0.5s ease', + textTransform: 'capitalize', + color: isActive ? '#fff' : '#fff', + fontSize: '14px', + })} + to="/" + > + Home + + + + + + + + + + + ({ + backgroundColor: isActive ? '#FF4601' : '', + textDecoration: 'none', + padding: '5px 10px', + + borderRadius: '5px', + transition: 'all 0.5s ease', + textTransform: 'capitalize', + color: isActive ? '#fff' : '#fff', + fontSize: '14px', + + })} + to="users" + > + Users + + + + + + + + + + ({ + backgroundColor: isActive ? '#FF4601' : '', + textDecoration: 'none', + padding: '5px 10px', + + borderRadius: '5px', + transition: 'all 0.5s ease', + textTransform: 'capitalize', + color: isActive ? '#fff' : '#fff', + fontSize: '14px', + + })} + to="products" + > + Products + + + + + + + + + ({ + backgroundColor: isActive ? '#FF4601' : '', + textDecoration: 'none', + padding: '5px 10px', + + borderRadius: '5px', + transition: 'all 0.5s ease', + textTransform: 'capitalize', + color: isActive ? '#fff' : '#fff', + fontSize: '14px', + + })} + to="classes" + > + Classes + + + + + + + + + ({ + backgroundColor: isActive ? '#FF4601' : '', + textDecoration: 'none', + padding: '5px 10px', + + borderRadius: '5px', + transition: 'all 0.5s ease', + textTransform: 'capitalize', + color: isActive ? '#fff' : '#fff', + fontSize: '14px', + + })} + to="orders" + > + Orders + + + + + + + + + ({ + backgroundColor: isActive ? '#FF4601' : '', + textDecoration: 'none', + padding: '5px 10px', + borderRadius: '5px', + transition: 'all 0.5s ease', + textTransform: 'capitalize', + color: isActive ? '#fff' : '#fff', + fontSize: '14px', + + })} + to="announcements" + > + Announcements + + + + + + + + + ({ + backgroundColor: isActive ? '#FF4601' : '', + textDecoration: 'none', + padding: '5px 10px', + borderRadius: '5px', + transition: 'all 0.5s ease', + textTransform: 'capitalize', + color: isActive ? '#fff' : '#fff', + fontSize: '14px', + + })} + to="subscriptions" + > + Subscriptions + + + + + + + + + ({ + backgroundColor: isActive ? '#FF4601' : '', + textDecoration: 'none', + padding: '5px 10px', + + borderRadius: '5px', + transition: 'all 0.5s ease', + textTransform: 'capitalize', + color: isActive ? '#fff' : '#fff', + fontSize: '14px', + + })} + to="calendar" + > + Calendar + + + + + +); + +export default SideBar; diff --git a/src/dashboardComponents/table/index.jsx b/src/dashboardComponents/table/index.jsx new file mode 100644 index 0000000..4c5233a --- /dev/null +++ b/src/dashboardComponents/table/index.jsx @@ -0,0 +1,62 @@ +/* eslint-disable no-underscore-dangle */ +import * as React from 'react'; +import Table from '@mui/material/Table'; +import TableBody from '@mui/material/TableBody'; +import TableCell from '@mui/material/TableCell'; +import TableHead from '@mui/material/TableHead'; +import TableRow from '@mui/material/TableRow'; +import DeleteIcon from '@mui/icons-material/Delete'; +import EditIcon from '@mui/icons-material/Edit'; + +const DashTable = ({ + array, userInfo, deleteFunction, setEditShowForm, showEditForm, getData, updateSubscription, +}) => ( + + + + + {userInfo?.map((head) => {head})} + remove + edit + + + + {array?.map((row) => ( + + {userInfo?.map((cell) => (cell !== 'image' + ? {row[cell]} + : ( + + {cell} + + )))} + + deleteFunction(row._id)} + sx={{ fontSize: 19, cursor: 'pointer', color: 'red' }} + /> + + + + {updateSubscription ? ( + updateSubscription(row._id)} + sx={{ fontSize: 19, cursor: 'pointer', color: 'blue' }} + /> + ) + : ( + setEditShowForm(!showEditForm) || getData(row._id)} + sx={{ fontSize: 19, cursor: 'pointer', color: 'blue' }} + /> + )} + + + + + ))} + +
+ +); +export default DashTable; diff --git a/src/dummyData/classDashBoardDummyData.js b/src/dummyData/classDashBoardDummyData.js new file mode 100644 index 0000000..a348833 --- /dev/null +++ b/src/dummyData/classDashBoardDummyData.js @@ -0,0 +1,68 @@ +const columns = [ + { field: 'id', headerName: 'ID', width: 90 }, + { + field: 'classname', + headerName: 'classname', + width: 150, + editable: true, + }, + { + field: 'Description', + headerName: 'Description', + width: 150, + editable: true, + }, + { + field: 'Trainer', + headerName: 'Trainer', + type: 'string', + width: 110, + editable: true, + }, + { + field: 'Price', + headerName: 'Price', + type: 'number', + width: 110, + editable: true, + }, + { + field: 'Participant', + headerName: 'Participant', + type: 'number', + width: 110, + editable: true, + }, +]; + +const rows = [ + { + id: 1, classname: 'Snow', Description: 'Jon@gmail.com', Trainer: 'john', Price: 20, Participant: 20, + }, + { + id: 2, classname: 'Snow', Description: 'Jon@gmail.com', Trainer: 'john', Price: 20, Participant: 20, + }, + { + id: 3, classname: 'Snow', Description: 'Jon@gmail.com', Trainer: 'john', Price: 20, Participant: 20, + }, + { + id: 4, classname: 'Snow', Description: 'Jon@gmail.com', Trainer: 'john', Price: 20, Participant: 20, + }, + { + id: 5, classname: 'Snow', Description: 'Jon@gmail.com', Trainer: 'john', Price: 20, Participant: 20, + }, + { + id: 6, classname: 'Snow', Description: 'Jon@gmail.com', Trainer: 'john', Price: 20, Participant: 20, + }, + { + id: 7, classname: 'Snow', Description: 'Jon@gmail.com', Trainer: '123asd123', Price: 20, Participant: 'male', + }, + { + id: 8, classname: 'Snow', Description: 'Jon@gmail.com', Trainer: '123asd123', Price: 20, Participant: 'male', + }, + { + id: 9, classname: 'Snow', Description: 'Jon@gmail.com', Trainer: '123asd123', Price: 20, Participant: 'male', + }, +]; + +export { columns, rows }; diff --git a/src/dummyData/index.js b/src/dummyData/index.js new file mode 100644 index 0000000..a4e5a82 --- /dev/null +++ b/src/dummyData/index.js @@ -0,0 +1,89 @@ +const columns = [ + { field: '_id', headerName: 'ID', width: 90 }, + { + field: 'username', + headerName: 'username', + width: 150, + editable: true, + }, + { + field: 'email', + headerName: 'email', + width: 150, + editable: true, + }, + { + field: 'password', + headerName: 'password', + type: 'string', + width: 110, + editable: true, + }, + { + field: 'age', + headerName: 'password', + type: 'number', + width: 110, + editable: true, + }, + { + field: 'gender', + headerName: 'gender', + type: 'string', + width: 110, + editable: true, + }, + { + field: 'height', + headerName: 'height', + type: 'number', + width: 110, + editable: true, + }, + { + field: 'weight', + headerName: 'weight', + type: 'number', + width: 110, + editable: true, + }, + { + field: 'goalweight', + headerName: 'weight', + type: 'number', + width: 110, + editable: true, + }, +]; + +const rows = [ + { + id: 1, username: 'Snow', email: 'Jon@gmail.com', password: '123asd123', age: 20, gender: 'male', height: 160, weight: 90, goalweight: 60, + }, + { + id: 2, username: 'Snow', email: 'Jon@gmail.com', password: '123asd123', age: 20, gender: 'male', height: 160, weight: 90, goalweight: 60, + }, + { + id: 3, username: 'Snow', email: 'Jon@gmail.com', password: '123asd123', age: 20, gender: 'male', height: 160, weight: 90, goalweight: 60, + }, + { + id: 4, username: 'Snow', email: 'Jon@gmail.com', password: '123asd123', age: 20, gender: 'male', height: 160, weight: 90, goalweight: 60, + }, + { + id: 5, username: 'Snow', email: 'Jon@gmail.com', password: '123asd123', age: 20, gender: 'male', height: 160, weight: 90, goalweight: 60, + }, + { + id: 6, username: 'Snow', email: 'Jon@gmail.com', password: '123asd123', age: 20, gender: 'male', height: 160, weight: 90, goalweight: 60, + }, + { + id: 7, username: 'Snow', email: 'Jon@gmail.com', password: '123asd123', age: 20, gender: 'male', height: 160, weight: 90, goalweight: 60, + }, + { + id: 8, username: 'Snow', email: 'Jon@gmail.com', password: '123asd123', age: 20, gender: 'male', height: 160, weight: 90, goalweight: 60, + }, + { + id: 9, username: 'Snow', email: 'Jon@gmail.com', password: '123asd123', age: 20, gender: 'male', height: 160, weight: 90, goalweight: 60, + }, +]; + +export { columns, rows }; diff --git a/src/dummyData/index.jsx b/src/dummyData/index.jsx new file mode 100644 index 0000000..9d4a20d --- /dev/null +++ b/src/dummyData/index.jsx @@ -0,0 +1,109 @@ +import DropDownList from '../components/dropDownList'; + +const userInfo = ['username', 'email', 'password', 'age', 'gender', 'height', 'weight', 'goalweight']; +const initialState = { + username: '', + email: '', + password: '', + age: '', + gender: '', + height: '', + weight: '', + goalweight: '', +}; + +const columns = [ + { field: '_id', headerName: 'ID', width: 90 }, + { + field: 'username', + headerName: 'username', + width: 150, + editable: true, + }, + { + field: 'email', + headerName: 'email', + width: 150, + editable: true, + }, + { + field: 'password', + headerName: 'password', + type: 'string', + width: 110, + editable: true, + }, + { + field: 'age', + headerName: 'password', + type: 'number', + width: 110, + editable: true, + }, + { + field: 'gender', + headerName: 'gender', + type: 'string', + width: 110, + editable: true, + }, + { + field: 'height', + headerName: 'height', + type: 'number', + width: 110, + editable: true, + }, + { + field: 'weight', + headerName: 'weight', + type: 'number', + width: 110, + editable: true, + }, + { + field: 'goalweight', + headerName: 'weight', + type: 'number', + width: 110, + editable: true, + }, + { + field: 'delete', + headerName: 'Delete', + width: 100, + renderCell: (row) => , + }, +]; + +const rows = [ + { + id: 1, username: 'Snow', email: 'Jon@gmail.com', password: '123asd123', age: 20, gender: 'male', height: 160, weight: 90, goalweight: 60, + }, + { + id: 2, username: 'Snow', email: 'Jon@gmail.com', password: '123asd123', age: 20, gender: 'male', height: 160, weight: 90, goalweight: 60, + }, + { + id: 3, username: 'Snow', email: 'Jon@gmail.com', password: '123asd123', age: 20, gender: 'male', height: 160, weight: 90, goalweight: 60, + }, + { + id: 4, username: 'Snow', email: 'Jon@gmail.com', password: '123asd123', age: 20, gender: 'male', height: 160, weight: 90, goalweight: 60, + }, + { + id: 5, username: 'Snow', email: 'Jon@gmail.com', password: '123asd123', age: 20, gender: 'male', height: 160, weight: 90, goalweight: 60, + }, + { + id: 6, username: 'Snow', email: 'Jon@gmail.com', password: '123asd123', age: 20, gender: 'male', height: 160, weight: 90, goalweight: 60, + }, + { + id: 7, username: 'Snow', email: 'Jon@gmail.com', password: '123asd123', age: 20, gender: 'male', height: 160, weight: 90, goalweight: 60, + }, + { + id: 8, username: 'Snow', email: 'Jon@gmail.com', password: '123asd123', age: 20, gender: 'male', height: 160, weight: 90, goalweight: 60, + }, + { + id: 9, username: 'Snow', email: 'Jon@gmail.com', password: '123asd123', age: 20, gender: 'male', height: 160, weight: 90, goalweight: 60, + }, +]; + +export { columns, rows }; diff --git a/src/dummyData/productData.js b/src/dummyData/productData.js new file mode 100644 index 0000000..c5faa90 --- /dev/null +++ b/src/dummyData/productData.js @@ -0,0 +1,28 @@ +const userInfo = ['Title', 'Content', 'Price', 'Review', 'Setting']; + +const columns = [ + { field: '_id', headerName: 'id' }, + { + field: 'title', + headerName: 'Title', + }, + { + field: 'image', + headerName: 'Image', + }, + { + field: 'rating', + headerName: 'Rating', + }, + { + field: 'price', + headerName: 'Price', + }, + { + field: 'description', + headerName: 'Description', + }, + +]; + +export { userInfo, columns }; diff --git a/src/dummyData/productData.jsx b/src/dummyData/productData.jsx new file mode 100644 index 0000000..60a9410 --- /dev/null +++ b/src/dummyData/productData.jsx @@ -0,0 +1,41 @@ +import DropDownList from '../components/dropDownList'; + +const userInfo = ['title', 'image', 'rating', 'price', 'description']; +const initialState = { + title: '', + image: '', + rating: '', + price: '', + description: '', +}; +const columns = [ + { field: '_id', headerName: 'id' }, + { + field: 'title', + headerName: 'Title', + }, + { + field: 'image', + headerName: 'Image', + }, + { + field: 'rating', + headerName: 'Rating', + }, + { + field: 'price', + headerName: 'Price', + }, + { + field: 'description', + headerName: 'Description', + }, + { + field: 'delete', + headerName: 'Delete', + width: 100, + renderCell: (row) => , + }, +]; + +export { userInfo, columns }; diff --git a/src/hook/useAuth.jsx b/src/hook/useAuth.jsx new file mode 100644 index 0000000..21375bf --- /dev/null +++ b/src/hook/useAuth.jsx @@ -0,0 +1,28 @@ +import { useEffect } from 'react'; + +import useUser from './useUser'; +import useLocalStorage from './useLocalStorage'; + +const useAuth = () => { + const { user, addUser, removeUser } = useUser(); + const { getItem } = useLocalStorage(); + + useEffect(() => { + const localUserData = getItem('user'); + if (localUserData) { + addUser(JSON.parse(localUserData)); + } + }, []); + + const login = (userData) => { + addUser(userData); + }; + + const logout = () => { + removeUser(); + }; + + return { user, login, logout }; +}; + +export default useAuth; diff --git a/src/hook/useLocalStorage.jsx b/src/hook/useLocalStorage.jsx new file mode 100644 index 0000000..cbfeb1c --- /dev/null +++ b/src/hook/useLocalStorage.jsx @@ -0,0 +1,30 @@ +import { useState } from 'react'; + +const useLocalStorage = () => { + const [value, setValue] = useState(null); + + const setItem = (key, val) => { + localStorage.setItem(key, val); + setValue(value); + }; + + const getItem = (key) => { + const val = localStorage.getItem(key); + setValue(val); + return val; + }; + + const removeItem = (key) => { + localStorage.removeItem(key); + setValue(null); + }; + + return { + value, + setItem, + getItem, + removeItem, + }; +}; + +export default useLocalStorage; diff --git a/src/hook/useUser.jsx b/src/hook/useUser.jsx new file mode 100644 index 0000000..e6610e1 --- /dev/null +++ b/src/hook/useUser.jsx @@ -0,0 +1,22 @@ +import { useContext } from 'react'; +import AuthContext from '../context/authContex'; +import useLocalStorage from './useLocalStorage'; + +const useUser = () => { + const { user, setUser } = useContext(AuthContext); + const { setItem } = useLocalStorage(); + + const addUser = (userData) => { + setUser(userData); + setItem('user', JSON.stringify(userData)); + }; + + const removeUser = () => { + setUser(null); + setItem('user', ''); + }; + + return { user, addUser, removeUser }; +}; + +export default useUser; diff --git a/src/index.css b/src/index.css new file mode 100644 index 0000000..f49e9a1 --- /dev/null +++ b/src/index.css @@ -0,0 +1,18 @@ +@import url('https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600;700&display=swap'); + +* { + padding: 0; + margin: 0; + box-sizing: border-box; + font-family: 'Poppins', sans-serif !important; +} + +*::-webkit-scrollbar{ + background-color: transparent; + width: 10px; +} +*::-webkit-scrollbar-thumb{ + background-color: #FF4601; + border-radius: 20px; + +} \ No newline at end of file diff --git a/src/layout/DashLayout.jsx b/src/layout/DashLayout.jsx new file mode 100644 index 0000000..b8b516a --- /dev/null +++ b/src/layout/DashLayout.jsx @@ -0,0 +1,22 @@ +import { Box, Container } from '@mui/material'; +import React from 'react'; +import { Outlet } from 'react-router-dom'; +import { NavbarDash, SideBar } from '../dashboardComponents'; + +const DashLayout = () => ( + + + + + + + + + +); + +export default DashLayout; diff --git a/src/layout/Store.jsx b/src/layout/Store.jsx new file mode 100644 index 0000000..8b98e46 --- /dev/null +++ b/src/layout/Store.jsx @@ -0,0 +1,22 @@ +import { Outlet } from 'react-router-dom'; +import { Box, Container } from '@mui/material'; +import { useState } from 'react'; +import { CategoriesList, HomeStore } from '../components'; + +const StoreLayout = () => { + const [category, setCategory] = useState(''); + return ( + + + + + + + + + + + ); +}; + +export default StoreLayout; diff --git a/src/layout/classLayout.jsx b/src/layout/classLayout.jsx new file mode 100644 index 0000000..353941d --- /dev/null +++ b/src/layout/classLayout.jsx @@ -0,0 +1,20 @@ +import { Outlet } from 'react-router-dom'; +import { Box, Container } from '@mui/material'; +import { ClassesList } from '../components'; + +const ClassLayout = () => ( + + + + + + + + + +); + +export default ClassLayout; diff --git a/src/layout/index.js b/src/layout/index.js new file mode 100644 index 0000000..685bcee --- /dev/null +++ b/src/layout/index.js @@ -0,0 +1,3 @@ +import StoreLayout from './Store'; + +export default StoreLayout; diff --git a/src/main.jsx b/src/main.jsx new file mode 100644 index 0000000..303ff4d --- /dev/null +++ b/src/main.jsx @@ -0,0 +1,10 @@ +import React from 'react'; +import ReactDOM from 'react-dom/client'; +import App from './App'; +import './index.css'; + +ReactDOM.createRoot(document.getElementById('root')).render( + + + , +); diff --git a/src/pages/admins/Classes/index.jsx b/src/pages/admins/Classes/index.jsx new file mode 100644 index 0000000..b6e70a5 --- /dev/null +++ b/src/pages/admins/Classes/index.jsx @@ -0,0 +1,240 @@ +/* eslint-disable no-underscore-dangle */ +import { Box } from '@mui/material'; +import axios from 'axios'; +import React, { useEffect, useReducer, useState } from 'react'; +import { toast } from 'react-toastify'; +import { + AddButton, AddForm, DashTable, EditForm, SearchInpDash, +} from '../../../dashboardComponents'; +import ToastAlert from '../../../components/toastAlert/ToastAlert'; + +const classInfo = ['className', 'description', 'price', 'userCount']; +const classDataTable = ['className', 'description', 'price', 'userCount', 'trainer']; +const EditClassInfo = ['className', 'description', 'price', 'userCount']; + +const initialState = { + className: '', + description: '', + price: '', + userCount: '', +}; + +const reducer = (state, action) => ({ + ...state, + [action.filedName]: action.value, +}); + +const ClassDash = () => { + const [showForm, setShowForm] = useState(false); + const [state, dispatch] = useReducer(reducer, initialState); + const [classes, setClasses] = useState([]); + const [filteredClasses, setFilteredClasses] = useState([]); + + const [trainerId, setTrainerId] = useState(''); + const [trainersData, setTrainersData] = useState([]); + const [showEditForm, setEditShowForm] = useState(false); + const [oneClass, setOneClass] = useState({}); + const [classData, setClassData] = useState({ + className: oneClass.className, + description: oneClass.description, + price: oneClass.price, + userCount: oneClass.userCount, + trainerId, + }); + + const values = [ + state.className, + state.description, + state.price, + state.userCount, + ]; + + const handleChange = (e, filedName) => { + const { value } = e.target; + dispatch({ + filedName, + value, + }); + }; + + const getClasses = async () => { + try { + const { data: { classesData } } = await axios.get('/api/classes'); + const classArray = []; + classesData.map((classItem) => classArray.push( + { ...classItem, trainer: classItem.trainerId?.username }, + )); + setClasses(classArray); + } catch (error) { + console.log(error); + } + }; + + const getTrainers = async () => { + try { + const { data: { allTrainers } } = await axios.get('/api/users/trainers'); + setTrainersData(allTrainers); + } catch (error) { + console.log(error); + } + }; + + const addClass = async () => { + try { + await axios.post(`/api/classes/${trainerId}`, state); + getClasses(); + } catch (error) { + console.log(error); + } + }; + + const deleteClass = async (id) => { + try { + axios.delete(`/api/classes/${id}`); + getClasses(); + toast.success('Delete successfully!'); + } catch (error) { + toast.error('Delete Failed!'); + } + }; + + const getClassById = async (id) => { + const { data: { classObj } } = await axios.get(`/api/classes/${id}`); + + setOneClass({ + _id: classObj._id, + className: classObj.className, + description: classObj.description, + price: classObj.price, + userCount: classObj.userCount, + trainer: classObj.trainerId?.username, + }); + + setClassData({ + className: classObj.className, + description: classObj.description, + price: classObj.price, + userCount: classObj.userCount, + trainerId: classObj.trainerId, + }); + }; + + const updateClass = async () => { + try { + // eslint-disable-next-line no-underscore-dangle + axios.put(`/api/classes/${oneClass._id}`, classData); + setEditShowForm(false); + getClasses(); + setClassData({ + className: '', + description: '', + price: '', + userCount: '', + trainerId: '', + }); + toast.success('Update successfully!!', { theme: 'dark' }); + } catch (error) { + toast.error('Really Updated!!', { theme: 'dark' }); + } + }; + + const filterFunc = ({ text }) => { + if (text) { + setFilteredClasses(() => classes.filter((item) => item.className.includes(text))); + } else { + setFilteredClasses(classes); + } + }; + useEffect(() => { + getTrainers(); + getClasses(); + }, []); + const classesArray = filteredClasses.length > 0 ? filteredClasses : classes; + + return ( + + + + {classes && classes?.length > 0 && } + + + + + + + + + + + + + + + ); +}; + +export default ClassDash; diff --git a/src/pages/admins/announcements/index.jsx b/src/pages/admins/announcements/index.jsx new file mode 100644 index 0000000..2ad2303 --- /dev/null +++ b/src/pages/admins/announcements/index.jsx @@ -0,0 +1,194 @@ +/* eslint-disable no-underscore-dangle */ +import { Box } from '@mui/material'; +import React, { useEffect, useReducer, useState } from 'react'; +import axios from 'axios'; +import { toast } from 'react-toastify'; +import { + AddButton, AddForm, DashTable, EditForm, SearchInpDash, +} from '../../../dashboardComponents'; +import ToastAlert from '../../../components/toastAlert/ToastAlert'; + +const announcementInfo = ['title', 'description', 'image']; +const announcementInfoTable = ['title', 'image', 'description']; + +const initialState = { + title: '', + image: '', + description: '', +}; +const reducer = (state, action) => ({ + ...state, + [action.filedName]: action.value, +}); +const AnnouncementDash = () => { + const [state, dispatch] = useReducer(reducer, initialState); + const [showEditForm, setEditShowForm] = useState(false); + + const [showForm, setShowForm] = useState(false); + const [announcements, setAnnouncements] = useState([]); + const [filteredAnnouncements, setFilteredAnnouncements] = useState([]); + const [announcement, setAnnouncement] = useState({}); + const [updateAnnouncementData, setUpdateAnnouncementData] = useState({ + title: announcement.title, + description: announcement.description, + image: announcement.image, + }); + + const handleChange = (e, filedName) => { + const { value } = e.target; + dispatch({ + filedName, + value, + }); + }; + + const getAnnouncements = async () => { + try { + const { data } = await axios.get('/api/announcements'); + setAnnouncements(data.announcements); + } catch (error) { + console.log(error); + } + }; + + const getAnnouncementById = (id) => { + const announce = announcements.filter((item) => item._id === id); + setAnnouncement(announce[0]); + setUpdateAnnouncementData({ + title: announce[0].title, + description: announce[0].description, + image: announce[0].image, + }); + }; + + const addAnnouncement = async () => { + try { + await axios.post('/api/announcements', state); + getAnnouncements(); + setShowForm(false); + toast.success('add announcement successfully!', { theme: 'dark' }); + } catch (error) { + toast.success('add Failed!', { theme: 'dark' }); + } + }; + + const deleteAnnouncement = async (id) => { + try { + axios.delete(`/api/announcements/${id}`); + getAnnouncements(); + toast.success('Delete Successfully!', { theme: 'dark' }); + } catch (error) { + toast.error('Delete Failed!', { theme: 'dark' }); + } + }; + + const updateAnnouncement = async () => { + try { + await axios.put(`/api/announcements/${announcement._id}`, updateAnnouncementData); + getAnnouncements(); + setEditShowForm(false); + setUpdateAnnouncementData({ + title: '', + description: '', + image: '', + }); + toast.success('Update Successfully!', { theme: 'dark' }); + } catch (error) { + toast.error('Update Failed!', { theme: 'dark' }); + } + }; + + const filterFunc = ({ text }) => { + if (text) { + setFilteredAnnouncements(() => announcements.filter((item) => item.title.includes(text))); + } else { + setFilteredAnnouncements(announcements); + } + }; + + useEffect(() => { + getAnnouncements(); + }, []); + + const announcementsArray = filteredAnnouncements.length > 0 + ? filteredAnnouncements : announcements; + + return ( + + + + {announcements && announcements?.length > 0 && } + + + + + + + + + + + + + + + + ); +}; + +export default AnnouncementDash; diff --git a/src/pages/admins/calendar/index.jsx b/src/pages/admins/calendar/index.jsx new file mode 100644 index 0000000..ebf2e18 --- /dev/null +++ b/src/pages/admins/calendar/index.jsx @@ -0,0 +1,149 @@ +/* eslint-disable no-underscore-dangle */ +import React, { useEffect, useState } from 'react'; +import { Calendar, momentLocalizer } from 'react-big-calendar'; +import 'react-big-calendar/lib/css/react-big-calendar.css'; +import DatePicker from 'react-datepicker'; +import 'react-datepicker/dist/react-datepicker.css'; +import moment from 'moment'; + +import { + Box, Button, FormControl, InputLabel, MenuItem, Select, +} from '@mui/material'; + +import axios from 'axios'; +import { toast } from 'react-toastify'; +import ToastAlert from '../../../components/toastAlert/ToastAlert'; + +const localizer = momentLocalizer(moment); + +const CalendarDash = () => { + const [calendarsData, setCalendarsData] = useState([]); + const [newDate, setNewDate] = useState({}); + const [classes, setClasses] = useState([]); + const [classId, setClassId] = useState(''); + + const getClasses = async () => { + try { + const { data: { classesData } } = await axios.get('/api/classes'); + setClasses(classesData); + } catch (error) { + console.log(error); + } + }; + + const getCalendars = async () => { + try { + const { data: { calendars } } = await axios.get('/api/calendar'); + const classCalendar = calendars.map((calendarClassData) => ({ + _id: calendarClassData?._id, + title: calendarClassData.classId?.className, + start: new Date(calendarClassData?.start), + end: new Date(calendarClassData?.end), + })); + setCalendarsData(classCalendar); + } catch (error) { + console.log(error); + } + }; + + const addCalendar = async () => { + try { + axios.post(`/api/calendar/${classId}`, newDate); + setCalendarsData([...calendarsData, newDate]); + getCalendars(); + toast.success('add calendar successfully!', { theme: 'dark' }); + } catch (error) { + console.log(error); + } + }; + const deleteCalendar = async (e) => { + try { + await axios.delete(`/api/calendar/${e._id}`); + getCalendars(); + toast.success('deleted calendar successfully!', { theme: 'dark' }); + } catch (error) { + console.log('🚀 ~ file: index.jsx:61 ~ deleteCalendar ~ error:', error); + } + }; + useEffect(() => { + getClasses(); + getCalendars(); + }, []); + + return ( + + + + + + + Classes + + + + + + setNewDate({ ...newDate, start })} + /> + setNewDate({ ...newDate, end })} + /> + + + + deleteCalendar(e)} + popup + localizer={localizer} + events={calendarsData} + startAccessor="start" + endAccessor="end" + style={{ + height: 500, margin: '50px', color: '#fff', fontSize: 12, + }} + /> + + + ); +}; + +export default CalendarDash; diff --git a/src/pages/admins/home/index.jsx b/src/pages/admins/home/index.jsx new file mode 100644 index 0000000..963c748 --- /dev/null +++ b/src/pages/admins/home/index.jsx @@ -0,0 +1,101 @@ +/* eslint-disable no-underscore-dangle */ +import { Box, Typography } from '@mui/material'; +import axios from 'axios'; +import { useEffect, useState } from 'react'; +import { + CardDash, ChartDash, OrderStatistics, RatingDash, +} from '../../../dashboardComponents'; + +const HomeDash = () => { + const [mostOrders, setMostOrders] = useState([]); + const [products, setProducts] = useState([]); + const [users, setUsers] = useState([]); + const [trainers, setTrainers] = useState([]); + const [categories, setCategories] = useState([]); + const [classes, setClasses] = useState([]); + const [subs, setSubs] = useState([]); + const getOrders = async () => { + const { data } = await axios.get('/api/orders'); + const arr = []; + data.orders.map((order) => arr.push( + { + _id: order?._id, + username: order.userId?.username, + product: order.productId?.title, + image: order.productId?.image, + amount: order?.amount, + totalPrice: order?.totalPrice, + status: order?.status, + }, + )); + setMostOrders(arr); + }; + + const getProducts = async () => { + const { data } = await axios.get('/api/products'); + setProducts(data.products); + }; + const getUsers = async () => { + const { data } = await axios.get('/api/users'); + setUsers(data.allUsers); + }; + const getTrainers = async () => { + const { data } = await axios.get('/api/users/trainers'); + setTrainers(data.allTrainers); + }; + const getCategories = async () => { + const { data } = await axios.get('/api/categories'); + setCategories(data.categories); + }; + const getClasses = async () => { + const { data } = await axios.get('/api/classes'); + setClasses(data.classesData); + }; + const getSubs = async () => { + const { data } = await axios.get('/api/subscriptions'); + setSubs(data.subscriptionsData); + }; + + useEffect(() => { + getOrders(); + getProducts(); + getUsers(); + getTrainers(); + getCategories(); + getClasses(); + getSubs(); + }, []); + return ( + + Dashboard + + + + + + + Statistics + + + + + + + + ); +}; + +export default HomeDash; diff --git a/src/pages/admins/index.js b/src/pages/admins/index.js new file mode 100644 index 0000000..e77c909 --- /dev/null +++ b/src/pages/admins/index.js @@ -0,0 +1,19 @@ +import ClassDash from './Classes'; +import AnnouncementDash from './announcements'; +import HomeDash from './home'; +import OrderDash from './orders'; +import ProductDash from './products'; +import SubscriptionDash from './subscriptions'; +import UserDash from './users'; +import CalendarDash from './calendar'; + +export { + HomeDash, + UserDash, + ProductDash, + ClassDash, + OrderDash, + AnnouncementDash, + SubscriptionDash, + CalendarDash, +}; diff --git a/src/pages/admins/orders/index.jsx b/src/pages/admins/orders/index.jsx new file mode 100644 index 0000000..58fabcd --- /dev/null +++ b/src/pages/admins/orders/index.jsx @@ -0,0 +1,91 @@ +/* eslint-disable no-underscore-dangle */ +import { Box } from '@mui/material'; +import React, { useEffect, useState } from 'react'; +import axios from 'axios'; +import { toast } from 'react-toastify'; +import { + DashTable, SearchInpDash, +} from '../../../dashboardComponents'; +import ToastAlert from '../../../components/toastAlert/ToastAlert'; + +const orderInfoTable = ['product', 'image', 'username', 'amount', 'totalPrice', 'status']; + +const OrderDash = () => { + const [orders, setOrders] = useState([]); + const [filterOrders, setFilterOrders] = useState([]); + + const getOrders = async () => { + const { data } = await axios.get('/api/orders'); + const arr = []; + data.orders.map((order) => arr.push( + { + _id: order?._id, + username: order.userId?.username, + product: order.productId?.title, + image: order.productId?.image, + amount: order?.amount, + totalPrice: order?.totalPrice, + status: order?.status, + }, + )); + setOrders(arr); + }; + + const deleteOrder = async (id) => { + try { + axios.delete(`/api/orders/${id}`); + getOrders(); + toast.success('Delete Order successfully!', { theme: 'dark' }); + } catch (error) { + toast.error('Delete Failed!', { theme: 'dark' }); + } + }; + + const updateOrder = async (id) => { + try { + await axios.put(`/api/orders/${id}`); + getOrders(); + + toast.success('updated Order\'s status successfully!', { theme: 'dark' }); + } catch (error) { + console.log(error); + } + }; + const filterFunc = ({ text }) => { + if (text) { + setFilterOrders(() => orders.filter((item) => item.product.includes(text))); + } else { + setFilterOrders(orders); + } + }; + useEffect(() => { + getOrders(); + }, []); + const ordersArray = filterOrders.length > 0 ? filterOrders : orders; + + return ( + + + + {orders && orders?.length > 0 && } + + + + + + + + ); +}; + +export default OrderDash; diff --git a/src/pages/admins/products/index.jsx b/src/pages/admins/products/index.jsx new file mode 100644 index 0000000..f7b6280 --- /dev/null +++ b/src/pages/admins/products/index.jsx @@ -0,0 +1,228 @@ +/* eslint-disable no-underscore-dangle */ +import { Box } from '@mui/material'; +import React, { useEffect, useReducer, useState } from 'react'; +import axios from 'axios'; +import { toast } from 'react-toastify'; +import { + AddButton, AddForm, DashTable, EditForm, SearchInpDash, +} from '../../../dashboardComponents'; +import ToastAlert from '../../../components/toastAlert/ToastAlert'; + +const productInfo = ['title', 'description', 'image', 'price']; +const productDataTable = ['title', 'image', 'price', 'description', 'category']; +const EditProductInfo = ['title', 'image', 'price', 'description']; + +const initialState = { + title: '', + image: '', + price: '', + description: '', +}; + +const reducer = (state, action) => ({ + ...state, + [action.filedName]: action.value, +}); + +const ProductDash = () => { + const [state, dispatch] = useReducer(reducer, initialState); + const [productsData, setProductsData] = useState([]); + const [filteredProducts, setFilteredProducts] = useState([]); + const [categoriesData, setCategoriesData] = useState([]); + const [categoryId, setCategoryId] = useState(''); + const [showForm, setShowForm] = useState(false); + const [showEditForm, setEditShowForm] = useState(false); + const [oneProduct, setOneProduct] = useState({}); + const [updateProductData, setUpdateProductData] = useState({ + title: oneProduct.title, + image: oneProduct.image, + price: oneProduct.price, + description: oneProduct.description, + }); + const values = [ + state.title, + state.image, + state.price, + state.description, + ]; + + const handleChange = (e, filedName) => { + const { value } = e.target; + dispatch({ + filedName, + value, + }); + }; + + const getProducts = async () => { + try { + const { data: { products } } = await axios.get('/api/products'); + const productArray = []; + products.map((product) => productArray.push({ + ...product, + category: product.categoryId?.categoryName, + })); + setProductsData(productArray); + } catch (error) { + console.log(error); + } + }; + + const getCategories = async () => { + try { + const { data: { categories } } = await axios.get('/api/categories'); + setCategoriesData(categories); + } catch (error) { + console.log(error); + } + }; + + const addProduct = async () => { + try { + await axios.post(`/api/products/${categoryId}`, state); + getProducts(); + toast.success('Add Product Successfully!', { theme: 'dark' }); + } catch (error) { + toast.error('Really added!!', { theme: 'dark' }); + } + }; + + const deleteProduct = async (id) => { + try { + axios.delete(`/api/products/${id}`); + getProducts(); + toast.success('Delete Successfully!', { theme: 'dark' }); + } catch (error) { + toast.error('Delete Failed!', { theme: 'dark' }); + } + }; + + const getProductById = async (id) => { + const { data: { product } } = await axios.get(`/api/products/${id}`); + setOneProduct(product); + setUpdateProductData({ + title: product.title, + image: product.image, + price: product.price, + description: product.description, + }); + }; + + const updateProduct = async () => { + try { + axios.put(`/api/products/${oneProduct._id}`, updateProductData); + setEditShowForm(false); + getProducts(); + setUpdateProductData({ + title: '', + image: '', + price: '', + description: '', + }); + toast.success('Update successfully!!', { theme: 'dark' }); + } catch (error) { + toast.error('Update Failed!', { theme: 'dark' }); + } + }; + + const filterFunc = ({ text }) => { + if (text) { + setFilteredProducts(() => productsData.filter((item) => item.title.includes(text))); + } else { + setFilteredProducts(productsData); + } + }; + + useEffect(() => { + getCategories(); + getProducts(); + }, []); + + const productsArray = filteredProducts.length > 0 ? filteredProducts : productsData; + + return ( + + + + {productsData && productsData?.length > 0 + && } + + + + + + + + + + + + + + + + ); +}; + +export default ProductDash; diff --git a/src/pages/admins/profile/index.jsx b/src/pages/admins/profile/index.jsx new file mode 100644 index 0000000..3494222 --- /dev/null +++ b/src/pages/admins/profile/index.jsx @@ -0,0 +1,206 @@ +/* eslint-disable no-underscore-dangle */ +import React, { useState } from 'react'; +import { + Box, Input, Button, InputLabel, +} from '@mui/material'; +import axios from 'axios'; +import useAuth from '../../../hook/useAuth'; + +const ProfileDash = () => { + const { user } = useAuth(); + + const [changeable, setChangeAble] = useState(false); + const [adminInput, setAdminInput] = useState({ + username: user.username, + email: user.email, + gender: user.gender, + weight: user.weight, + height: user.height, + goalweight: user.goalweight, + role: user.role, + }); + + const updateAdminData = async () => { + try { + await axios.put(`/api/users/${user._id}`, adminInput); + } catch (error) { + console.log(error); + } + }; + + return ( + + profile admin + + userName: + setChangeAble(!changeable)} + onChange={(e) => setAdminInput({ ...adminInput, username: e.target.value })} + sx={{ + color: '#fff', + fontSize: 12, + height: '50px', + flex: 0.9, + p: '5px 10px', + + width: '100%', + borderBottom: '1px solid #ccc', + }} + type="text" + value={adminInput.username ? adminInput.username : user.username} + /> + Email: + + setChangeAble(!changeable)} + onChange={(e) => setAdminInput({ ...adminInput, email: e.target.value })} + sx={{ + color: '#fff', + fontSize: 12, + height: '50px', + flex: 0.9, + p: '5px 10px', + + width: '100%', + borderBottom: '1px solid #ccc', + + }} + type="text" + value={adminInput.email ? adminInput.email : user.email} + /> + Gender: + + setChangeAble(!changeable)} + onChange={(e) => setAdminInput({ ...adminInput, gender: e.target.value })} + sx={{ + color: '#fff', + fontSize: 12, + height: '50px', + flex: 0.9, + p: '5px 10px', + + width: '100%', + borderBottom: '1px solid #ccc', + + }} + type="text" + value={adminInput.gender ? adminInput.gender : user.gender} + /> + Weight: + + setChangeAble(!changeable)} + onChange={(e) => setAdminInput({ ...adminInput, weight: e.target.value })} + sx={{ + color: '#fff', + fontSize: 12, + height: '50px', + flex: 0.9, + p: '5px 10px', + + width: '100%', + borderBottom: '1px solid #ccc', + + }} + type="text" + value={adminInput.weight ? adminInput.weight : user.weight} + /> + Height: + setChangeAble(!changeable)} + onChange={(e) => setAdminInput({ ...adminInput, height: e.target.value })} + sx={{ + color: '#fff', + fontSize: 12, + height: '50px', + flex: 0.9, + p: '5px 10px', + + width: '100%', + borderBottom: '1px solid #ccc', + + }} + type="text" + value={adminInput.height ? adminInput.height : user.height} + /> + + GoalWeight: + setChangeAble(!changeable)} + onChange={(e) => setAdminInput({ ...adminInput, goalweight: e.target.value })} + sx={{ + color: '#fff', + fontSize: 12, + height: '50px', + flex: 0.9, + p: '5px 10px', + + width: '100%', + borderBottom: '1px solid #ccc', + + }} + type="text" + value={adminInput.goalweight ? adminInput.goalweight : user.goalweight} + /> + role: + setChangeAble(!changeable)} + onChange={(e) => setAdminInput({ ...adminInput, role: e.target.value })} + sx={{ + color: '#fff', + fontSize: 12, + height: '50px', + flex: 0.9, + p: '5px 10px', + + width: '100%', + borderBottom: '1px solid #ccc', + + }} + type="text" + value={adminInput.role ? adminInput.role : user.role} + /> + + + + ); +}; +export default ProfileDash; diff --git a/src/pages/admins/subscriptions/index.jsx b/src/pages/admins/subscriptions/index.jsx new file mode 100644 index 0000000..ae54d93 --- /dev/null +++ b/src/pages/admins/subscriptions/index.jsx @@ -0,0 +1,110 @@ +/* eslint-disable no-underscore-dangle */ +import { Box } from '@mui/material'; +import React, { useEffect, useState } from 'react'; +import axios from 'axios'; +import { toast } from 'react-toastify'; +import { + AddForm, DashTable, SearchInpDash, +} from '../../../dashboardComponents'; +import ToastAlert from '../../../components/toastAlert/ToastAlert'; + +const subscriptionInfoTable = ['className', 'username', 'status']; + +const SubscriptionDash = () => { + const [subscriptionData, setSubscriptionData] = useState([]); + const [filteredSubscriptionData, setFilteredSubscriptionData] = useState([]); + const [showForm, setShowForm] = useState(false); + + const getSubscriptions = async () => { + try { + const { data: { subscriptionsData } } = await axios.get('/api/subscriptions'); + const subscriptionArray = []; + subscriptionsData.map((subscription) => subscriptionArray.push({ + className: subscription.classId?.className, + username: subscription.userId?.username, + status: subscription.status, + _id: subscription._id, + })); + setSubscriptionData(subscriptionArray); + } catch (error) { + console.log(error); + } + }; + + const deleteSubscription = async (id) => { + try { + axios.delete(`/api/subscriptions/${id}`); + getSubscriptions(); + toast.success('Delete Successfully!', { theme: 'dark' }); + } catch (error) { + toast.error('Delete Failed!', { theme: 'dark' }); + } + }; + + const updateSubscription = async (id) => { + try { + await axios.put(`/api/subscriptions/${id}`); + getSubscriptions(); + toast.success('Update Successfully!', { theme: 'dark' }); + } catch (error) { + toast.error('Update Failed!', { theme: 'dark' }); + } + }; + + const filterFunc = ({ text }) => { + if (text) { + setFilteredSubscriptionData(() => subscriptionData.filter((item) => item + .className.includes(text))); + } else { + setFilteredSubscriptionData(subscriptionData); + } + }; + + useEffect(() => { + getSubscriptions(); + }, []); + + const subsArray = filteredSubscriptionData.length > 0 + ? filteredSubscriptionData : subscriptionData; + + return ( + + + + {subscriptionData && subscriptionData?.length > 0 && } + + + + + + + + + + + ); +}; + +export default SubscriptionDash; diff --git a/src/pages/admins/users/index.jsx b/src/pages/admins/users/index.jsx new file mode 100644 index 0000000..7dc28e9 --- /dev/null +++ b/src/pages/admins/users/index.jsx @@ -0,0 +1,219 @@ +/* eslint-disable no-underscore-dangle */ +import { Box } from '@mui/material'; +import React, { useEffect, useReducer, useState } from 'react'; +import axios from 'axios'; +import { + AddButton, AddForm, DashTable, EditForm, SearchInpDash, +} from '../../../dashboardComponents'; + +const userInfo = ['username', 'email', 'password', 'age', 'gender', 'height', 'weight', 'goalweight']; +const userInfoTable = ['username', 'email', 'age', 'gender', 'height', 'weight', 'goalweight', 'role']; +const EdituserInfo = ['username', 'email', 'age', 'height', 'weight', 'gender', 'goalweight', 'role']; +const initialState = { + username: '', + email: '', + password: '', + age: '', + gender: '', + height: '', + weight: '', + goalweight: '', +}; + +const reducer = (state, action) => ({ + ...state, + [action.filedName]: action.value, +}); +const UserDash = () => { + const [user, setUser] = useState({}); + + const [state, dispatch] = useReducer(reducer, initialState); + const values = [ + state.username, + state.email, + state.password, + state.age, + state.gender, + state.height, + state.weight, + state.goalweight, + state.role, + ]; + + const [userData, setUserData] = useState({ + username: user?.username, + email: user?.email, + age: user?.age, + gender: user?.gender, + weight: user?.weight, + height: user?.height, + goalweight: user?.goalweight, + role: user?.role, + }); + const [showForm, setShowForm] = useState(false); + const [showEditForm, setEditShowForm] = useState(false); + const [users, setUsers] = useState([]); + const [filterUsers, setfilterUsers] = useState([]); + + const handleChange = (e, filedName) => { + const { value } = e.target; + dispatch({ + filedName, + value, + }); + }; + + const getUsers = async () => { + try { + const { data } = await axios.get('/api/users'); + setUsers(data.allUsers); + } catch (error) { + console.log(error); + } + }; + + const filterFunc = ({ text }) => { + if (text) { + setfilterUsers(() => users.filter((item) => item.username.includes(text))); + } else { + setfilterUsers(users); + } + }; + const addUser = async () => { + try { + await axios.post('/api/users/signup', state); + + getUsers(); + } catch (error) { + console.log(error); + } + }; + + const deleteUser = async (id) => { + try { + axios.delete(`/api/users/${id}`); + getUsers(); + } catch (error) { + console.log(error); + } + }; + + const getUserById = async (id) => { + const { data } = await axios.get(`/api/users/${id}`); + setUser(data.user); + setUserData({ + username: data.user?.username, + email: data.user?.email, + age: data.user?.age, + gender: data.user?.gender, + weight: data.user?.weight, + height: data.user?.height, + goalweight: data.user?.goalweight, + role: data.user?.role, + }); + }; + + const updateUser = async () => { + try { + axios.put(`/api/users/${user._id}`, userData); + setEditShowForm(false); + getUsers(); + setUserData({ + username: '', + email: '', + age: '', + gender: '', + weight: '', + height: '', + goalweight: '', + role: '', + }); + } catch (error) { + console.log(error); + } + }; + + useEffect(() => { + getUsers(); + }, []); + + const usersArray = filterUsers.length > 0 ? filterUsers : users; + + return ( + + + {users && users?.length > 0 && } + + + + + + + + + + + + + + + ); +}; + +export default UserDash; diff --git a/src/pages/index.js b/src/pages/index.js new file mode 100644 index 0000000..aaf28ef --- /dev/null +++ b/src/pages/index.js @@ -0,0 +1,23 @@ +import { + Store, + Class, + ProductDetailsContainer, + AnnouncementContainer, + UserProfile, + SignIn, + SignupPage, + Home, + UserSetting, +} from './user'; + +export { + Store, + ProductDetailsContainer, + Class, + AnnouncementContainer, + SignIn, + UserProfile, + SignupPage, + Home, + UserSetting, +}; diff --git a/src/pages/user/announcement/index.jsx b/src/pages/user/announcement/index.jsx new file mode 100644 index 0000000..62dacc5 --- /dev/null +++ b/src/pages/user/announcement/index.jsx @@ -0,0 +1,13 @@ +import React from 'react'; +import { Box, Container } from '@mui/material'; +import { AnnouncementList } from '../../../components'; + +const AnnouncementContainer = () => ( + + + + + +); + +export default AnnouncementContainer; diff --git a/src/pages/user/class/index.jsx b/src/pages/user/class/index.jsx new file mode 100644 index 0000000..4dc5696 --- /dev/null +++ b/src/pages/user/class/index.jsx @@ -0,0 +1,22 @@ +import { Box, Container } from '@mui/material'; +import React from 'react'; +import { ClassInfoComp } from '../../../components'; +import Provider from '../../../context/Provider'; + +const Class = () => ( + + + + + + + + + +); +export default Class; diff --git a/src/pages/user/home/index.jsx b/src/pages/user/home/index.jsx new file mode 100644 index 0000000..4deb909 --- /dev/null +++ b/src/pages/user/home/index.jsx @@ -0,0 +1,33 @@ +import { Box, Container } from '@mui/material'; +import React from 'react'; +import SectionHome from '../../../components/sectionHome/index'; + +import Header from '../../../components/headerClient/Header'; +import { SliderComp } from '../../../components'; +import SwiperComp from '../../../components/swiper'; +import VideoPlayer from '../../../components/videoCom'; + +const Home = () => ( + +
+ + + + + + + + + + + + + + + + + + +); + +export default Home; diff --git a/src/pages/user/index.js b/src/pages/user/index.js new file mode 100644 index 0000000..5d4f8ef --- /dev/null +++ b/src/pages/user/index.js @@ -0,0 +1,21 @@ +import UserSetting from './userSetting/index'; +import AnnouncementContainer from './announcement'; +import Class from './class'; +import ProductDetailsContainer from './productDetails'; +import Store from './product'; +import UserProfile from './userProfile'; +import SignIn from './signin'; +import SignupPage from './signup'; +import Home from './home'; + +export { + Store, + AnnouncementContainer, + ProductDetailsContainer, + Class, + UserProfile, + SignIn, + SignupPage, + UserSetting, + Home, +}; diff --git a/src/pages/user/product/index.jsx b/src/pages/user/product/index.jsx new file mode 100644 index 0000000..49e1e63 --- /dev/null +++ b/src/pages/user/product/index.jsx @@ -0,0 +1,11 @@ +import React from 'react'; +import { Box } from '@mui/material'; +import { ProductList } from '../../../components'; + +const Store = () => ( + + + +); + +export default Store; diff --git a/src/pages/user/productDetails/index.jsx b/src/pages/user/productDetails/index.jsx new file mode 100644 index 0000000..0b3f1f9 --- /dev/null +++ b/src/pages/user/productDetails/index.jsx @@ -0,0 +1,15 @@ +import { Box, Container } from '@mui/material'; +import React from 'react'; +import { Outlet } from 'react-router-dom'; + +const ProductDetailsContainer = () => ( + + + + + + + +); + +export default ProductDetailsContainer; diff --git a/src/pages/user/signin/index.jsx b/src/pages/user/signin/index.jsx new file mode 100644 index 0000000..ef69618 --- /dev/null +++ b/src/pages/user/signin/index.jsx @@ -0,0 +1,39 @@ +import { Box, Container } from '@mui/material'; +import React, { useState } from 'react'; +import { SignInComp } from '../../../components'; +import { ReactComponent as Login } from '../../../assets/login.svg'; +import ForgetPasswordComp from '../../../components/passwordFrom'; + +const SignIn = () => { + const [showBox, setShowBox] = useState(false); + return ( + + + + + + + + + + + + + ); +}; + +export default SignIn; diff --git a/src/pages/user/signup/index.jsx b/src/pages/user/signup/index.jsx new file mode 100644 index 0000000..ddf6bec --- /dev/null +++ b/src/pages/user/signup/index.jsx @@ -0,0 +1,32 @@ +import { Box } from '@mui/system'; +import { Container } from '@mui/material'; +import SignupComp from '../../../components/signup'; +import { ReactComponent as SignUpImg } from '../../../assets/signupimage.svg'; + +const SignupPage = () => ( + + + + + + + + + + + +); + +export default SignupPage; diff --git a/src/pages/user/signup/styledComps.jsx b/src/pages/user/signup/styledComps.jsx new file mode 100644 index 0000000..67b1f6e --- /dev/null +++ b/src/pages/user/signup/styledComps.jsx @@ -0,0 +1,9 @@ +// import styled from 'styled-components'; +// import { ReactComponent as SignUpImg } from '../../../assets/singupimage.svg'; + +// const StyledImg = styled(SignUpImg)` +// width:40%; +// height:100%; +// `; + +// export default StyledImg; diff --git a/src/pages/user/userProfile/classesTable.jsx b/src/pages/user/userProfile/classesTable.jsx new file mode 100644 index 0000000..6d5558b --- /dev/null +++ b/src/pages/user/userProfile/classesTable.jsx @@ -0,0 +1,36 @@ +/* eslint-disable no-underscore-dangle */ +import * as React from 'react'; +import Table from '@mui/material/Table'; +import TableBody from '@mui/material/TableBody'; +import TableCell from '@mui/material/TableCell'; +import TableHead from '@mui/material/TableHead'; +import TableRow from '@mui/material/TableRow'; +import DeleteIcon from '@mui/icons-material/Delete'; + +const ClassTable = ({ classData, deleteClassSubscription }) => ( + + + + + className + status + remove + + + + {classData?.map((row) => ( + + + {row.classId.className} + + + {row.status} + deleteClassSubscription(row._id)} /> + + + ))} + +
+ +); +export default ClassTable; diff --git a/src/pages/user/userProfile/dummyData.js b/src/pages/user/userProfile/dummyData.js new file mode 100644 index 0000000..f1dc8be --- /dev/null +++ b/src/pages/user/userProfile/dummyData.js @@ -0,0 +1,58 @@ +const columns = [ + { field: 'id', headerName: 'ID', width: 90 }, + { + field: 'Title', + editTable: false, + }, + { + field: 'Image', + }, + { + field: 'Price', + }, + { + field: 'Removing', + }, +]; +const columns2 = [ + { field: 'id', headerName: 'ID', width: 90 }, + { + field: 'className', + }, + { + field: 'status', + }, + +]; + +const rows = [ + { + id: 1, Title: 'Snow', Image: 'Jon', Price: 35, Removing: 'Remove', + }, + { + id: 2, Title: 'Lannister', Image: 'Cersei', Price: 42, Removing: 'Remove', + }, + { + id: 3, Title: 'Lannister', Image: 'Jaime', Price: 45, Removing: 'Remove', + }, + { + id: 4, Title: 'Stark', Image: 'Arya', Price: 16, Removing: 'Remove', + }, + { + id: 5, Title: 'Targaryen', Image: 'Daenerys', Price: null, Removing: 'Remove', + }, + { + id: 6, Title: 'Melisandre', Image: null, Price: 150, Removing: 'Remove', + }, + { + id: 7, Title: 'Clifford', Image: 'Ferrara', Price: 44, Removing: 'Remove', + }, + { + id: 8, Title: 'Frances', Image: 'Rossini', Price: 36, Removing: 'Remove', + }, + { + id: 9, Title: 'Roxie', Image: 'Harvey', Price: 65, Removing: 'Remove', + }, +]; + +export { rows, columns, columns2 }; diff --git a/src/pages/user/userProfile/index.jsx b/src/pages/user/userProfile/index.jsx new file mode 100644 index 0000000..8531d8f --- /dev/null +++ b/src/pages/user/userProfile/index.jsx @@ -0,0 +1,85 @@ +import React, { useState } from 'react'; +import { Box, Container } from '@mui/material'; +import axios from 'axios'; +import { toast } from 'react-toastify'; +import { PersonalInfo, ProfileNav, ToastAlert } from '../../../components'; +import ClassTable from './classesTable'; +import OrderTable from './ordersTable'; +import useAuth from '../../../hook/useAuth'; + +const UserProfile = () => { + const { user: userData } = useAuth(); + + const [userClasses, setUserClasses] = useState([]); + const [userOrders, setUserOrders] = useState([]); + const [tableName, setTableName] = useState(''); + const getUserClasses = async () => { + const { data, status } = await axios.get('/api/subscriptions/user'); + if (status === 200) { + setUserClasses([data.userSubscriptionData]); + } + }; + const getUserOrders = async () => { + const { data, status } = await axios.get('/api/orders/user'); + if (status === 201) { + setUserOrders([data.orders]); + } + }; + + const deleteClassSubscription = async (id) => { + try { + await axios.delete(`/api/subscriptions/${id}`); + getUserClasses(); + toast.success('Delete Subscription Successfully!'); + } catch (error) { + toast.error('Delete Subscription Failed!'); + } + }; + + const deleteOrder = async (id) => { + try { + await axios.delete(`/api/orders/${id}`); + getUserOrders(); + toast.success('Delete order Successfully!'); + } catch (error) { + toast.error('Delete order Failed!'); + } + }; + return ( + + + + + + + + + + + + + {tableName === 'orders' ? ( + + ) : ( + + )} + + + + + + ); +}; + +export default UserProfile; diff --git a/src/pages/user/userProfile/ordersTable.jsx b/src/pages/user/userProfile/ordersTable.jsx new file mode 100644 index 0000000..0cc36cd --- /dev/null +++ b/src/pages/user/userProfile/ordersTable.jsx @@ -0,0 +1,39 @@ +/* eslint-disable no-underscore-dangle */ +import * as React from 'react'; +import Table from '@mui/material/Table'; +import TableBody from '@mui/material/TableBody'; +import TableCell from '@mui/material/TableCell'; +import TableHead from '@mui/material/TableHead'; +import TableRow from '@mui/material/TableRow'; +import DeleteIcon from '@mui/icons-material/Delete'; + +const OrderTable = ({ ordersData, deleteOrder }) => ( + + + + + Title + image + price + delete + + + + {ordersData?.map((row) => ( + // eslint-disable-next-line no-underscore-dangle + + + {row.productId.title} + + + {row.productId.image} + {row.productId.price} + deleteOrder(row._id)} /> + + + ))} + +
+ +); +export default OrderTable; diff --git a/src/pages/user/userSetting/index.jsx b/src/pages/user/userSetting/index.jsx new file mode 100644 index 0000000..9d6a183 --- /dev/null +++ b/src/pages/user/userSetting/index.jsx @@ -0,0 +1,18 @@ +import { Container } from '@mui/system'; +import { Box } from '@mui/material'; +import { + UserSettingData, +} from '../../../components'; +import Provider from '../../../context/Provider'; + +const UserSetting = () => ( + + + + + + + + +); +export default UserSetting; diff --git a/src/routes/root.jsx b/src/routes/root.jsx new file mode 100644 index 0000000..e4d8ecd --- /dev/null +++ b/src/routes/root.jsx @@ -0,0 +1,29 @@ +import { Outlet } from 'react-router-dom'; +import { Box } from '@mui/material'; +import { Footer, NavbarClient } from '../components'; +import useAuth from '../hook/useAuth'; + +const Root = () => { + const { user, isLoading } = useAuth(); + + if (isLoading) { + return
Loading...
; + } + + return ( + + + + +