diff --git a/eslint.config.js b/eslint.config.js index 5ed949b..2dff622 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -1,28 +1,42 @@ -import js from '@eslint/js' -import globals from 'globals' -import reactHooks from 'eslint-plugin-react-hooks' -import reactRefresh from 'eslint-plugin-react-refresh' -import tseslint from 'typescript-eslint' +import js from "@eslint/js"; +import react from "eslint-plugin-react"; +import reactHooks from "eslint-plugin-react-hooks"; +import reactRefresh from "eslint-plugin-react-refresh"; +import globals from "globals"; +import tseslint from "typescript-eslint"; + export default tseslint.config( - { ignores: ['dist'] }, + { ignores: ["dist"] }, { - extends: [js.configs.recommended, ...tseslint.configs.recommended], - files: ['**/*.{ts,tsx}'], + extends: [js.configs.recommended, ...tseslint.configs.recommendedTypeChecked], + files: ["**/*.{ts,tsx}"], languageOptions: { ecmaVersion: 2020, globals: globals.browser, + parserOptions: { + project: ["./tsconfig.node.json", "./tsconfig.app.json"], + tsconfigRootDir: import.meta.dirname + } }, plugins: { - 'react-hooks': reactHooks, - 'react-refresh': reactRefresh, + "react-hooks": reactHooks, + "react-refresh": reactRefresh, + react: react }, rules: { + ...react.configs.recommended.rules, + ...react.configs["jsx-runtime"].rules, ...reactHooks.configs.recommended.rules, - 'react-refresh/only-export-components': [ - 'warn', - { allowConstantExport: true }, - ], + "react-refresh/only-export-components": [ + "warn", + { allowConstantExport: true } + ] }, - }, -) + settings: { + react: { + version: "detect" + } + } + } +); diff --git a/package-lock.json b/package-lock.json index 3fdda9a..870b78f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -17,12 +17,13 @@ "@types/node": "^22.15.21", "axios": "^1.9.0", "clsx": "^2.1.1", + "eslint-plugin-react": "^7.37.5", "moment": "^2.30.1", "react": "^19.1.0", "react-dom": "^19.1.0", "react-icons": "^5.5.0", "react-joyride": "^3.0.0-7", - "react-router": "^7.6.0", + "react-router": "^7.6.1", "react-tooltip": "^5.28.1", "tailwindcss": "^4.1.7", "use-debounce": "^10.0.4", @@ -36,7 +37,7 @@ "eslint": "^9.27.0", "eslint-plugin-react-hooks": "^5.2.0", "eslint-plugin-react-refresh": "^0.4.20", - "globals": "^16.1.0", + "globals": "^16.2.0", "typescript": "^5.8.3", "typescript-eslint": "^8.32.1", "vite": "^6.3.5" @@ -741,7 +742,6 @@ "version": "4.7.0", "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.7.0.tgz", "integrity": "sha512-dyybb3AcajC7uha6CvhdVRJqaKyn7w2YKqKyAN37NKYgZT36w+iRb0Dymmc5qEJ549c/S31cMMSFd75bteCpCw==", - "dev": true, "license": "MIT", "dependencies": { "eslint-visitor-keys": "^3.4.3" @@ -760,7 +760,6 @@ "version": "3.4.3", "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", - "dev": true, "license": "Apache-2.0", "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -773,7 +772,6 @@ "version": "4.12.1", "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz", "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==", - "dev": true, "license": "MIT", "engines": { "node": "^12.0.0 || ^14.0.0 || >=16.0.0" @@ -783,7 +781,6 @@ "version": "0.20.0", "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.20.0.tgz", "integrity": "sha512-fxlS1kkIjx8+vy2SjuCB94q3htSNrufYTXubwiBFeaQHbH6Ipi43gFJq2zCMt6PHhImH3Xmr0NksKDvchWlpQQ==", - "dev": true, "license": "Apache-2.0", "dependencies": { "@eslint/object-schema": "^2.1.6", @@ -798,7 +795,6 @@ "version": "0.2.2", "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.2.2.tgz", "integrity": "sha512-+GPzk8PlG0sPpzdU5ZvIRMPidzAnZDl/s9L+y13iodqvb8leL53bTannOrQ/Im7UkpsmFU5Ily5U60LWixnmLg==", - "dev": true, "license": "Apache-2.0", "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -808,7 +804,6 @@ "version": "0.14.0", "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.14.0.tgz", "integrity": "sha512-qIbV0/JZr7iSDjqAc60IqbLdsj9GDt16xQtWD+B78d/HAlvysGdZZ6rpJHGAc2T0FQx1X6thsSPdnoiGKdNtdg==", - "dev": true, "license": "Apache-2.0", "dependencies": { "@types/json-schema": "^7.0.15" @@ -821,7 +816,6 @@ "version": "3.3.1", "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.1.tgz", "integrity": "sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==", - "dev": true, "license": "MIT", "dependencies": { "ajv": "^6.12.4", @@ -845,7 +839,6 @@ "version": "14.0.0", "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", - "dev": true, "license": "MIT", "engines": { "node": ">=18" @@ -858,7 +851,6 @@ "version": "9.27.0", "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.27.0.tgz", "integrity": "sha512-G5JD9Tu5HJEu4z2Uo4aHY2sLV64B7CDMXxFzqzjl3NKd6RVzSXNoE80jk7Y0lJkTTkjiIhBAqmlYwjuBY3tvpA==", - "dev": true, "license": "MIT", "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -871,7 +863,6 @@ "version": "2.1.6", "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.6.tgz", "integrity": "sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==", - "dev": true, "license": "Apache-2.0", "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -881,7 +872,6 @@ "version": "0.3.1", "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.3.1.tgz", "integrity": "sha512-0J+zgWxHN+xXONWIyPWKFMgVuJoZuGiIFu8yxk7RJjxkzpGmyja5wRFqZIVtjDVOQpV+Rw0iOAjYPE2eQyjr0w==", - "dev": true, "license": "Apache-2.0", "dependencies": { "@eslint/core": "^0.14.0", @@ -973,7 +963,6 @@ "version": "0.19.1", "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", - "dev": true, "license": "Apache-2.0", "engines": { "node": ">=18.18.0" @@ -983,7 +972,6 @@ "version": "0.16.6", "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.6.tgz", "integrity": "sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==", - "dev": true, "license": "Apache-2.0", "dependencies": { "@humanfs/core": "^0.19.1", @@ -997,7 +985,6 @@ "version": "0.3.1", "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.1.tgz", "integrity": "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==", - "dev": true, "license": "Apache-2.0", "engines": { "node": ">=18.18" @@ -1011,7 +998,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", - "dev": true, "license": "Apache-2.0", "engines": { "node": ">=12.22" @@ -1025,7 +1011,6 @@ "version": "0.4.2", "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.2.tgz", "integrity": "sha512-xeO57FpIu4p1Ri3Jq/EXq4ClRm86dVF2z/+kvFnyqVYRavTZmaFaUBbWCOuuTh0o/g7DSsk6kc2vrS4Vl5oPOQ==", - "dev": true, "license": "Apache-2.0", "engines": { "node": ">=18.18" @@ -1753,7 +1738,6 @@ "version": "7.0.15", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", - "dev": true, "license": "MIT" }, "node_modules/@types/node": { @@ -2038,7 +2022,6 @@ "version": "8.14.1", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.1.tgz", "integrity": "sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==", - "dev": true, "license": "MIT", "bin": { "acorn": "bin/acorn" @@ -2051,7 +2034,6 @@ "version": "5.3.2", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true, "license": "MIT", "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" @@ -2061,7 +2043,6 @@ "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.1", @@ -2078,7 +2059,6 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -2094,15 +2074,167 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true, "license": "Python-2.0" }, + "node_modules/array-buffer-byte-length": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.2.tgz", + "integrity": "sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "is-array-buffer": "^3.0.5" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array-includes": { + "version": "3.1.8", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.8.tgz", + "integrity": "sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.4", + "is-string": "^1.0.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.findlast": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/array.prototype.findlast/-/array.prototype.findlast-1.2.5.tgz", + "integrity": "sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flat": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.3.tgz", + "integrity": "sha512-rwG/ja1neyLqCuGZ5YYrznA62D4mZXg0i1cIskIUKSiqF3Cje9/wXAls9B9s1Wa2fomMsIv8czB8jZcPmxCXFg==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flatmap": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.3.tgz", + "integrity": "sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.tosorted": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/array.prototype.tosorted/-/array.prototype.tosorted-1.1.4.tgz", + "integrity": "sha512-p6Fx8B7b7ZhL/gmUsAy0D15WhvDccw3mnGNbZpi3pmeJdxtWsj2jEaI4Y6oo3XiHfzuSgPwKc04MYt6KgvC/wA==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.3", + "es-errors": "^1.3.0", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/arraybuffer.prototype.slice": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.4.tgz", + "integrity": "sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==", + "license": "MIT", + "dependencies": { + "array-buffer-byte-length": "^1.0.1", + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "is-array-buffer": "^3.0.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/async-function": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/async-function/-/async-function-1.0.0.tgz", + "integrity": "sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, "node_modules/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", "license": "MIT" }, + "node_modules/available-typed-arrays": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "license": "MIT", + "dependencies": { + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/axios": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/axios/-/axios-1.9.0.tgz", @@ -2118,14 +2250,12 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true, "license": "MIT" }, "node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", @@ -2178,6 +2308,24 @@ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" } }, + "node_modules/call-bind": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", + "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.0", + "es-define-property": "^1.0.0", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/call-bind-apply-helpers": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", @@ -2191,11 +2339,26 @@ "node": ">= 0.4" } }, + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true, "license": "MIT", "engines": { "node": ">=6" @@ -2226,7 +2389,6 @@ "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -2267,7 +2429,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -2280,7 +2441,6 @@ "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true, "license": "MIT" }, "node_modules/combined-stream": { @@ -2299,7 +2459,6 @@ "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true, "license": "MIT" }, "node_modules/convert-source-map": { @@ -2322,7 +2481,6 @@ "version": "7.0.6", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", - "dev": true, "license": "MIT", "dependencies": { "path-key": "^3.1.0", @@ -2339,11 +2497,61 @@ "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", "license": "MIT" }, + "node_modules/data-view-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.2.tgz", + "integrity": "sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/data-view-byte-length": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.2.tgz", + "integrity": "sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/inspect-js" + } + }, + "node_modules/data-view-byte-offset": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.1.tgz", + "integrity": "sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/debug": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", - "dev": true, "license": "MIT", "dependencies": { "ms": "^2.1.3" @@ -2361,7 +2569,6 @@ "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true, "license": "MIT" }, "node_modules/deepmerge": { @@ -2382,6 +2589,40 @@ "node": ">=16.0.0" } }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/define-properties": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "license": "MIT", + "dependencies": { + "define-data-property": "^1.0.1", + "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", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", @@ -2400,6 +2641,18 @@ "node": ">=8" } }, + "node_modules/doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "license": "Apache-2.0", + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/dunder-proto": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", @@ -2434,6 +2687,71 @@ "node": ">=10.13.0" } }, + "node_modules/es-abstract": { + "version": "1.23.10", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.10.tgz", + "integrity": "sha512-MtUbM072wlJNyeYAe0mhzrD+M6DIJa96CZAOBBrhDbgKnB4MApIKefcyAB1eOdYn8cUNZgvwBvEzdoAYsxgEIw==", + "license": "MIT", + "dependencies": { + "array-buffer-byte-length": "^1.0.2", + "arraybuffer.prototype.slice": "^1.0.4", + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "data-view-buffer": "^1.0.2", + "data-view-byte-length": "^1.0.2", + "data-view-byte-offset": "^1.0.1", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "es-set-tostringtag": "^2.1.0", + "es-to-primitive": "^1.3.0", + "function.prototype.name": "^1.1.8", + "get-intrinsic": "^1.3.0", + "get-proto": "^1.0.1", + "get-symbol-description": "^1.1.0", + "globalthis": "^1.0.4", + "gopd": "^1.2.0", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "internal-slot": "^1.1.0", + "is-array-buffer": "^3.0.5", + "is-callable": "^1.2.7", + "is-data-view": "^1.0.2", + "is-regex": "^1.2.1", + "is-shared-array-buffer": "^1.0.4", + "is-string": "^1.1.1", + "is-typed-array": "^1.1.15", + "is-weakref": "^1.1.1", + "math-intrinsics": "^1.1.0", + "object-inspect": "^1.13.4", + "object-keys": "^1.1.1", + "object.assign": "^4.1.7", + "own-keys": "^1.0.1", + "regexp.prototype.flags": "^1.5.4", + "safe-array-concat": "^1.1.3", + "safe-push-apply": "^1.0.0", + "safe-regex-test": "^1.1.0", + "set-proto": "^1.0.0", + "string.prototype.trim": "^1.2.10", + "string.prototype.trimend": "^1.0.9", + "string.prototype.trimstart": "^1.0.8", + "typed-array-buffer": "^1.0.3", + "typed-array-byte-length": "^1.0.3", + "typed-array-byte-offset": "^1.0.4", + "typed-array-length": "^1.0.7", + "unbox-primitive": "^1.1.0", + "which-typed-array": "^1.1.19" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/es-define-property": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", @@ -2452,6 +2770,33 @@ "node": ">= 0.4" } }, + "node_modules/es-iterator-helpers": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.2.1.tgz", + "integrity": "sha512-uDn+FE1yrDzyC0pCo961B2IHbdM8y/ACZsKD4dG6WqrjV53BADjwa7D+1aom2rsNVfLyDgU/eigvlJGJ08OQ4w==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.6", + "es-errors": "^1.3.0", + "es-set-tostringtag": "^2.0.3", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.6", + "globalthis": "^1.0.4", + "gopd": "^1.2.0", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.2.0", + "has-symbols": "^1.1.0", + "internal-slot": "^1.1.0", + "iterator.prototype": "^1.1.4", + "safe-array-concat": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/es-object-atoms": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", @@ -2479,6 +2824,35 @@ "node": ">= 0.4" } }, + "node_modules/es-shim-unscopables": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.1.0.tgz", + "integrity": "sha512-d9T8ucsEhh8Bi1woXCf+TIKDIROLG5WCkxg8geBCbvk22kzwC5G2OnXVMO6FUsvQlgUUXQ2itephWDLqDzbeCw==", + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-to-primitive": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.3.0.tgz", + "integrity": "sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==", + "license": "MIT", + "dependencies": { + "is-callable": "^1.2.7", + "is-date-object": "^1.0.5", + "is-symbol": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/esbuild": { "version": "0.25.4", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.4.tgz", @@ -2533,7 +2907,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true, "license": "MIT", "engines": { "node": ">=10" @@ -2546,7 +2919,6 @@ "version": "9.27.0", "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.27.0.tgz", "integrity": "sha512-ixRawFQuMB9DZ7fjU3iGGganFDp3+45bPOdaRurcFHSXO1e/sYwUX/FtQZpLZJR6SjMoJH8hR2pPEAfDyCoU2Q==", - "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", @@ -2603,6 +2975,38 @@ } } }, + "node_modules/eslint-plugin-react": { + "version": "7.37.5", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.37.5.tgz", + "integrity": "sha512-Qteup0SqU15kdocexFNAJMvCJEfa2xUKNV4CC1xsVMrIIqEy3SQ/rqyxCWNzfrd3/ldy6HMlD2e0JDVpDg2qIA==", + "license": "MIT", + "dependencies": { + "array-includes": "^3.1.8", + "array.prototype.findlast": "^1.2.5", + "array.prototype.flatmap": "^1.3.3", + "array.prototype.tosorted": "^1.1.4", + "doctrine": "^2.1.0", + "es-iterator-helpers": "^1.2.1", + "estraverse": "^5.3.0", + "hasown": "^2.0.2", + "jsx-ast-utils": "^2.4.1 || ^3.0.0", + "minimatch": "^3.1.2", + "object.entries": "^1.1.9", + "object.fromentries": "^2.0.8", + "object.values": "^1.2.1", + "prop-types": "^15.8.1", + "resolve": "^2.0.0-next.5", + "semver": "^6.3.1", + "string.prototype.matchall": "^4.0.12", + "string.prototype.repeat": "^1.0.0" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7" + } + }, "node_modules/eslint-plugin-react-hooks": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-5.2.0.tgz", @@ -2630,7 +3034,6 @@ "version": "8.3.0", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.3.0.tgz", "integrity": "sha512-pUNxi75F8MJ/GdeKtVLSbYg4ZI34J6C0C7sbL4YOp2exGwen7ZsuBqKzUhXd0qMQ362yET3z+uPwKeg/0C2XCQ==", - "dev": true, "license": "BSD-2-Clause", "dependencies": { "esrecurse": "^4.3.0", @@ -2647,7 +3050,6 @@ "version": "4.2.0", "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz", "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==", - "dev": true, "license": "Apache-2.0", "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -2660,7 +3062,6 @@ "version": "10.3.0", "resolved": "https://registry.npmjs.org/espree/-/espree-10.3.0.tgz", "integrity": "sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==", - "dev": true, "license": "BSD-2-Clause", "dependencies": { "acorn": "^8.14.0", @@ -2678,7 +3079,6 @@ "version": "1.6.0", "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", - "dev": true, "license": "BSD-3-Clause", "dependencies": { "estraverse": "^5.1.0" @@ -2691,7 +3091,6 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "dev": true, "license": "BSD-2-Clause", "dependencies": { "estraverse": "^5.2.0" @@ -2704,7 +3103,6 @@ "version": "5.3.0", "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, "license": "BSD-2-Clause", "engines": { "node": ">=4.0" @@ -2714,7 +3112,6 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true, "license": "BSD-2-Clause", "engines": { "node": ">=0.10.0" @@ -2724,7 +3121,6 @@ "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true, "license": "MIT" }, "node_modules/fast-glob": { @@ -2761,14 +3157,12 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true, "license": "MIT" }, "node_modules/fast-levenshtein": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", - "dev": true, "license": "MIT" }, "node_modules/fastq": { @@ -2785,7 +3179,6 @@ "version": "8.0.0", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", - "dev": true, "license": "MIT", "dependencies": { "flat-cache": "^4.0.0" @@ -2811,7 +3204,6 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dev": true, "license": "MIT", "dependencies": { "locate-path": "^6.0.0", @@ -2828,7 +3220,6 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", - "dev": true, "license": "MIT", "dependencies": { "flatted": "^3.2.9", @@ -2842,7 +3233,6 @@ "version": "3.3.3", "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz", "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==", - "dev": true, "license": "ISC" }, "node_modules/follow-redirects": { @@ -2865,6 +3255,21 @@ } } }, + "node_modules/for-each": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz", + "integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==", + "license": "MIT", + "dependencies": { + "is-callable": "^1.2.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/form-data": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.2.tgz", @@ -2903,6 +3308,35 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/function.prototype.name": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.8.tgz", + "integrity": "sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "functions-have-names": "^1.2.3", + "hasown": "^2.0.2", + "is-callable": "^1.2.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/gensync": { "version": "1.0.0-beta.2", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", @@ -2914,17 +3348,17 @@ } }, "node_modules/get-intrinsic": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.7.tgz", - "integrity": "sha512-VW6Pxhsrk0KAOqs3WEd0klDiF/+V7gQOpAvY1jVU/LHmaD/kQO4523aiJuikX/QAKYiW6x8Jh+RJej1almdtCA==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", "license": "MIT", "dependencies": { - "call-bind-apply-helpers": "^1.0.1", + "call-bind-apply-helpers": "^1.0.2", "es-define-property": "^1.0.1", "es-errors": "^1.3.0", - "es-object-atoms": "^1.0.0", + "es-object-atoms": "^1.1.1", "function-bind": "^1.1.2", - "get-proto": "^1.0.0", + "get-proto": "^1.0.1", "gopd": "^1.2.0", "has-symbols": "^1.1.0", "hasown": "^2.0.2", @@ -2950,11 +3384,27 @@ "node": ">= 0.4" } }, + "node_modules/get-symbol-description": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.1.0.tgz", + "integrity": "sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/glob-parent": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "dev": true, "license": "ISC", "dependencies": { "is-glob": "^4.0.3" @@ -2964,9 +3414,9 @@ } }, "node_modules/globals": { - "version": "16.1.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-16.1.0.tgz", - "integrity": "sha512-aibexHNbb/jiUSObBgpHLj+sIuUmJnYcgXBlrfsiDZ9rt4aF2TFRbyLgZ2iFQuVZ1K5Mx3FVkbKRSgKrbK3K2g==", + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-16.2.0.tgz", + "integrity": "sha512-O+7l9tPdHCU320IigZZPj5zmRCFG9xHmx9cU8FqU2Rp+JN714seHV+2S9+JslCpY4gJwU2vOGox0wzgae/MCEg==", "dev": true, "license": "MIT", "engines": { @@ -2976,6 +3426,22 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/globalthis": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", + "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", + "license": "MIT", + "dependencies": { + "define-properties": "^1.2.1", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/gopd": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", @@ -3001,16 +3467,54 @@ "dev": true, "license": "MIT" }, + "node_modules/has-bigints": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.1.0.tgz", + "integrity": "sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, "license": "MIT", "engines": { "node": ">=8" } }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.2.0.tgz", + "integrity": "sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==", + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/has-symbols": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", @@ -3054,7 +3558,6 @@ "version": "5.3.2", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", - "dev": true, "license": "MIT", "engines": { "node": ">= 4" @@ -3064,7 +3567,6 @@ "version": "3.3.1", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", - "dev": true, "license": "MIT", "dependencies": { "parent-module": "^1.0.0", @@ -3081,27 +3583,198 @@ "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", - "dev": true, "license": "MIT", "engines": { "node": ">=0.8.19" } }, + "node_modules/internal-slot": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.1.0.tgz", + "integrity": "sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "hasown": "^2.0.2", + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/is-array-buffer": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.5.tgz", + "integrity": "sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-async-function": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.1.1.tgz", + "integrity": "sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==", + "license": "MIT", + "dependencies": { + "async-function": "^1.0.0", + "call-bound": "^1.0.3", + "get-proto": "^1.0.1", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-bigint": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.1.0.tgz", + "integrity": "sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==", + "license": "MIT", + "dependencies": { + "has-bigints": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-boolean-object": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.2.2.tgz", + "integrity": "sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-core-module": { + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", + "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-data-view": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.2.tgz", + "integrity": "sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "get-intrinsic": "^1.2.6", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-date-object": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.1.0.tgz", + "integrity": "sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" } }, + "node_modules/is-finalizationregistry": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.1.1.tgz", + "integrity": "sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-generator-function": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.0.tgz", + "integrity": "sha512-nPUB5km40q9e8UfN/Zc24eLlzdSf9OfKByBw9CIdw4H1giPMeA0OIJvbchsCu4npfI2QcMVBsGEBHKZ7wLTWmQ==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "get-proto": "^1.0.0", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-glob": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, "license": "MIT", "dependencies": { "is-extglob": "^2.1.1" @@ -3116,6 +3789,18 @@ "integrity": "sha512-pgF+L5bxC+10hLBgf6R2P4ZZUBOQIIacbdo8YvuCP8/JvsWxG7aZ9p10DYuLtifFci4l3VITphhMlMV4Y+urPw==", "license": "MIT" }, + "node_modules/is-map": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz", + "integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", @@ -3126,13 +3811,187 @@ "node": ">=0.12.0" } }, + "node_modules/is-number-object": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.1.1.tgz", + "integrity": "sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-regex": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz", + "integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-set": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz", + "integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-shared-array-buffer": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.4.tgz", + "integrity": "sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-string": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.1.1.tgz", + "integrity": "sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-symbol": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.1.1.tgz", + "integrity": "sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "has-symbols": "^1.1.0", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typed-array": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz", + "integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==", + "license": "MIT", + "dependencies": { + "which-typed-array": "^1.1.16" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakmap": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz", + "integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakref": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.1.1.tgz", + "integrity": "sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakset": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.4.tgz", + "integrity": "sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "license": "MIT" + }, "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true, "license": "ISC" }, + "node_modules/iterator.prototype": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.5.tgz", + "integrity": "sha512-H0dkQoCa3b2VEeKQBOxFph+JAbcrQdE7KC0UkqwpLmv2EC4P41QXP+rqo9wYodACiG5/WM5s9oDApTU8utwj9g==", + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.6", + "get-proto": "^1.0.0", + "has-symbols": "^1.1.0", + "set-function-name": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/jiti": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.4.2.tgz", @@ -3146,14 +4005,12 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true, "license": "MIT" }, "node_modules/js-yaml": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, "license": "MIT", "dependencies": { "argparse": "^2.0.1" @@ -3179,21 +4036,18 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", - "dev": true, "license": "MIT" }, "node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true, "license": "MIT" }, "node_modules/json-stable-stringify-without-jsonify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", - "dev": true, "license": "MIT" }, "node_modules/json5": { @@ -3209,11 +4063,25 @@ "node": ">=6" } }, + "node_modules/jsx-ast-utils": { + "version": "3.3.5", + "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz", + "integrity": "sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==", + "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/keyv": { "version": "4.5.4", "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", - "dev": true, "license": "MIT", "dependencies": { "json-buffer": "3.0.1" @@ -3223,7 +4091,6 @@ "version": "0.4.1", "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", - "dev": true, "license": "MIT", "dependencies": { "prelude-ls": "^1.2.1", @@ -3465,7 +4332,6 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, "license": "MIT", "dependencies": { "p-locate": "^5.0.0" @@ -3481,9 +4347,20 @@ "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true, "license": "MIT" }, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "license": "MIT", + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, "node_modules/lru-cache": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", @@ -3561,7 +4438,6 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" @@ -3619,7 +4495,6 @@ "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true, "license": "MIT" }, "node_modules/nanoid": { @@ -3644,7 +4519,6 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", - "dev": true, "license": "MIT" }, "node_modules/node-releases": { @@ -3654,11 +4528,111 @@ "dev": true, "license": "MIT" }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", + "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.assign": { + "version": "4.1.7", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.7.tgz", + "integrity": "sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0", + "has-symbols": "^1.1.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.entries": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.9.tgz", + "integrity": "sha512-8u/hfXFRBD1O0hPUjioLhoWFHRmt6tKA4/vZPyckBr18l1KE9uHrFaFaUi8MDRTpi4uak2goyPTSNJLXX2k2Hw==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.fromentries": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.8.tgz", + "integrity": "sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.values": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.1.tgz", + "integrity": "sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/optionator": { "version": "0.9.4", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", - "dev": true, "license": "MIT", "dependencies": { "deep-is": "^0.1.3", @@ -3672,11 +4646,27 @@ "node": ">= 0.8.0" } }, + "node_modules/own-keys": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/own-keys/-/own-keys-1.0.1.tgz", + "integrity": "sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==", + "license": "MIT", + "dependencies": { + "get-intrinsic": "^1.2.6", + "object-keys": "^1.1.1", + "safe-push-apply": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, "license": "MIT", "dependencies": { "yocto-queue": "^0.1.0" @@ -3692,7 +4682,6 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dev": true, "license": "MIT", "dependencies": { "p-limit": "^3.0.2" @@ -3708,7 +4697,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, "license": "MIT", "dependencies": { "callsites": "^3.0.0" @@ -3721,7 +4709,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -3731,12 +4718,17 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true, "license": "MIT", "engines": { "node": ">=8" } }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "license": "MIT" + }, "node_modules/picocolors": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", @@ -3756,6 +4748,15 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/possible-typed-array-names": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz", + "integrity": "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, "node_modules/postcss": { "version": "8.5.3", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.3.tgz", @@ -3798,12 +4799,22 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.8.0" } }, + "node_modules/prop-types": { + "version": "15.8.1", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", + "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.1" + } + }, "node_modules/proxy-from-env": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", @@ -3814,7 +4825,6 @@ "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", - "dev": true, "license": "MIT", "engines": { "node": ">=6" @@ -3897,6 +4907,12 @@ "react": ">=0.0.0 <=99" } }, + "node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "license": "MIT" + }, "node_modules/react-joyride": { "version": "3.0.0-7", "resolved": "https://registry.npmjs.org/react-joyride/-/react-joyride-3.0.0-7.tgz", @@ -3942,9 +4958,9 @@ } }, "node_modules/react-router": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.6.0.tgz", - "integrity": "sha512-GGufuHIVCJDbnIAXP3P9Sxzq3UUsddG3rrI3ut1q6m0FI6vxVBF3JoPQ38+W/blslLH4a5Yutp8drkEpXoddGQ==", + "version": "7.6.1", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.6.1.tgz", + "integrity": "sha512-hPJXXxHJZEsPFNVbtATH7+MMX43UDeOauz+EAU4cgqTn7ojdI9qQORqS8Z0qmDlL1TclO/6jLRYUEtbWidtdHQ==", "license": "MIT", "dependencies": { "cookie": "^1.0.1", @@ -3977,11 +4993,69 @@ "react-dom": ">=16.14.0" } }, + "node_modules/reflect.getprototypeof": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz", + "integrity": "sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.9", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.7", + "get-proto": "^1.0.1", + "which-builtin-type": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/regexp.prototype.flags": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.4.tgz", + "integrity": "sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-errors": "^1.3.0", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "set-function-name": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve": { + "version": "2.0.0-next.5", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.5.tgz", + "integrity": "sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==", + "license": "MIT", + "dependencies": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/resolve-from": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true, "license": "MIT", "engines": { "node": ">=4" @@ -4061,6 +5135,58 @@ "queue-microtask": "^1.2.2" } }, + "node_modules/safe-array-concat": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.3.tgz", + "integrity": "sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "get-intrinsic": "^1.2.6", + "has-symbols": "^1.1.0", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">=0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-push-apply": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/safe-push-apply/-/safe-push-apply-1.0.0.tgz", + "integrity": "sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-regex-test": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.1.0.tgz", + "integrity": "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "is-regex": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/scheduler": { "version": "0.26.0", "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.26.0.tgz", @@ -4083,7 +5209,6 @@ "version": "6.3.1", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, "license": "ISC", "bin": { "semver": "bin/semver.js" @@ -4095,11 +5220,56 @@ "integrity": "sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ==", "license": "MIT" }, + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/set-function-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", + "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "functions-have-names": "^1.2.3", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/set-proto": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/set-proto/-/set-proto-1.0.0.tgz", + "integrity": "sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==", + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, "license": "MIT", "dependencies": { "shebang-regex": "^3.0.0" @@ -4112,12 +5282,83 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true, "license": "MIT", "engines": { "node": ">=8" } }, + "node_modules/side-channel": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", + "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3", + "side-channel-list": "^1.0.0", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-list": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", + "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/source-map-js": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", @@ -4127,11 +5368,103 @@ "node": ">=0.10.0" } }, + "node_modules/string.prototype.matchall": { + "version": "4.0.12", + "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.12.tgz", + "integrity": "sha512-6CC9uyBL+/48dYizRf7H7VAYCMCNTBeM78x/VTUe9bFEaxBepPJDa1Ow99LqI/1yF7kuy7Q3cQsYMrcjGUcskA==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.6", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.6", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "internal-slot": "^1.1.0", + "regexp.prototype.flags": "^1.5.3", + "set-function-name": "^2.0.2", + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.repeat": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/string.prototype.repeat/-/string.prototype.repeat-1.0.0.tgz", + "integrity": "sha512-0u/TldDbKD8bFCQ/4f5+mNRrXwZ8hg2w7ZR8wa16e8z9XpePWl3eGEcUD0OXpEH/VJH/2G3gjUtR3ZOiBe2S/w==", + "license": "MIT", + "dependencies": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5" + } + }, + "node_modules/string.prototype.trim": { + "version": "1.2.10", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.10.tgz", + "integrity": "sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "define-data-property": "^1.1.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-object-atoms": "^1.0.0", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimend": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.9.tgz", + "integrity": "sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimstart": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", + "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/strip-json-comments": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -4144,7 +5477,6 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -4153,6 +5485,18 @@ "node": ">=8" } }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/tailwindcss": { "version": "4.1.7", "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.1.7.tgz", @@ -4289,7 +5633,6 @@ "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", - "dev": true, "license": "MIT", "dependencies": { "prelude-ls": "^1.2.1" @@ -4310,6 +5653,80 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/typed-array-buffer": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz", + "integrity": "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/typed-array-byte-length": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.3.tgz", + "integrity": "sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "for-each": "^0.3.3", + "gopd": "^1.2.0", + "has-proto": "^1.2.0", + "is-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-byte-offset": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.4.tgz", + "integrity": "sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==", + "license": "MIT", + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "for-each": "^0.3.3", + "gopd": "^1.2.0", + "has-proto": "^1.2.0", + "is-typed-array": "^1.1.15", + "reflect.getprototypeof": "^1.0.9" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-length": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.7.tgz", + "integrity": "sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "is-typed-array": "^1.1.13", + "possible-typed-array-names": "^1.0.0", + "reflect.getprototypeof": "^1.0.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/typescript": { "version": "5.8.3", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz", @@ -4347,6 +5764,24 @@ "typescript": ">=4.8.4 <5.9.0" } }, + "node_modules/unbox-primitive": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.1.0.tgz", + "integrity": "sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-bigints": "^1.0.2", + "has-symbols": "^1.1.0", + "which-boxed-primitive": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/undici-types": { "version": "6.21.0", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", @@ -4388,7 +5823,6 @@ "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dev": true, "license": "BSD-2-Clause", "dependencies": { "punycode": "^2.1.0" @@ -4510,7 +5944,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, "license": "ISC", "dependencies": { "isexe": "^2.0.0" @@ -4522,11 +5955,95 @@ "node": ">= 8" } }, + "node_modules/which-boxed-primitive": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.1.1.tgz", + "integrity": "sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==", + "license": "MIT", + "dependencies": { + "is-bigint": "^1.1.0", + "is-boolean-object": "^1.2.1", + "is-number-object": "^1.1.1", + "is-string": "^1.1.1", + "is-symbol": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-builtin-type": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.2.1.tgz", + "integrity": "sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "function.prototype.name": "^1.1.6", + "has-tostringtag": "^1.0.2", + "is-async-function": "^2.0.0", + "is-date-object": "^1.1.0", + "is-finalizationregistry": "^1.1.0", + "is-generator-function": "^1.0.10", + "is-regex": "^1.2.1", + "is-weakref": "^1.0.2", + "isarray": "^2.0.5", + "which-boxed-primitive": "^1.1.0", + "which-collection": "^1.0.2", + "which-typed-array": "^1.1.16" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-collection": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz", + "integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==", + "license": "MIT", + "dependencies": { + "is-map": "^2.0.3", + "is-set": "^2.0.3", + "is-weakmap": "^2.0.2", + "is-weakset": "^2.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-typed-array": { + "version": "1.1.19", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.19.tgz", + "integrity": "sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==", + "license": "MIT", + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "for-each": "^0.3.5", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/word-wrap": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", - "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -4543,7 +6060,6 @@ "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "dev": true, "license": "MIT", "engines": { "node": ">=10" diff --git a/package.json b/package.json index eade9b8..c8612c6 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,7 @@ "type": "module", "scripts": { "dev": "vite", - "build": "tsc -b && vite build", + "build": "tsc -b && eslint && vite build", "lint": "eslint .", "preview": "vite preview" }, @@ -19,12 +19,13 @@ "@types/node": "^22.15.21", "axios": "^1.9.0", "clsx": "^2.1.1", + "eslint-plugin-react": "^7.37.5", "moment": "^2.30.1", "react": "^19.1.0", "react-dom": "^19.1.0", "react-icons": "^5.5.0", "react-joyride": "^3.0.0-7", - "react-router": "^7.6.0", + "react-router": "^7.6.1", "react-tooltip": "^5.28.1", "tailwindcss": "^4.1.7", "use-debounce": "^10.0.4", @@ -38,7 +39,7 @@ "eslint": "^9.27.0", "eslint-plugin-react-hooks": "^5.2.0", "eslint-plugin-react-refresh": "^0.4.20", - "globals": "^16.1.0", + "globals": "^16.2.0", "typescript": "^5.8.3", "typescript-eslint": "^8.32.1", "vite": "^6.3.5" diff --git a/src/App.tsx b/src/App.tsx index d6f8d27..f3b23c3 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -16,8 +16,8 @@ import ForgotTokenPage from "./pages/public/ForgotTokenPage"; import HomePage from "./pages/public/HomePage"; import LoginPage from "./pages/public/LoginPage"; import SignupPage from "./pages/public/SignupPage"; -import { ProtectedRoute } from "./providers/AuthProvider"; -import ErrorBoundary from "./providers/ErrorBoundary"; +import { ProtectedRoute } from "./providers/components/AuthProviderComponent"; +import ErrorBoundary from "./providers/components/ErrorBoundary"; const routes = createBrowserRouter([ diff --git a/src/components/account/AccountStatusSelector.tsx b/src/components/account/AccountStatusSelector.tsx index d480b58..fcfaf63 100644 --- a/src/components/account/AccountStatusSelector.tsx +++ b/src/components/account/AccountStatusSelector.tsx @@ -26,7 +26,7 @@ export default function AccountStatusSelector({ name={`accountStatusSelector${modalId}`} value={status} onChange={onChange} - checked={value === status} + checked={value === status as AccountStatus} /> { } -export default function TextInput(inProps: TextInputProps){ - const props = {...inProps}; +export default function TextInput(props: TextInputProps){ const { id, placeholder, name, inputClasses, labelClasses, accepted } = props; - delete props.inputClasses; - delete props.labelClasses; - delete props.accepted; return ( diff --git a/src/components/raidGroup/RaidGroupPermissionSelector.tsx b/src/components/raidGroup/RaidGroupPermissionSelector.tsx index e29d208..e8e6c2b 100644 --- a/src/components/raidGroup/RaidGroupPermissionSelector.tsx +++ b/src/components/raidGroup/RaidGroupPermissionSelector.tsx @@ -26,7 +26,7 @@ export default function RaidGroupPermissionSelector({ name={`raidGroupPermissionTypeSelector${modalId}`} value={permissionType} onChange={onChange} - checked={value === permissionType} + checked={value === permissionType as RaidGroupPermissionType} /> { - try{ - const response = await api.get(`/account/${accountId}/raidGroup/${raidGroupId}/permission`); + const response = await api.get(`/account/${accountId}/raidGroup/${raidGroupId}/permission`); - if(response.data.errors){ - throw new Error(response.data.errors.join(", ")); - } - - return response.data.permission as RaidGroupPermissionType; - } - catch(error){ - if(error instanceof AxiosError && error.response?.data.errors){ - throw new Error(error.response?.data.errors.join(", ")); - } - else{ - throw error; - } - } + return (response.data as {permission: RaidGroupPermissionType;}).permission; }, enabled: !!raidGroupId && !!accountId }); @@ -107,23 +65,9 @@ export function useGetAccountsCount(searchTerm?: string){ return useQuery({ queryKey: [ "accounts", "count", searchTerm], queryFn: async () => { - try{ - const response = await api.get(`/account/count?${searchParams}`); + const response = await api.get(`/account/count?${searchParams}`); - if(response.data.errors){ - throw new Error(response.data.errors.join(", ")); - } - - return response.data.count as number; - } - catch(error){ - if(error instanceof AxiosError && error.response?.data.errors){ - throw new Error(error.response?.data.errors.join(", ")); - } - else{ - throw error; - } - } + return (response.data as Counter).count; } }); } @@ -138,23 +82,9 @@ export function useGetAccountsByRaidGroupCount(raidGroupId: string, searchTerm?: return useQuery({ queryKey: [ "accounts", "raidGroup", raidGroupId, "count", searchTerm], queryFn: async () => { - try{ - const response = await api.get(`/account/raidGroup/${raidGroupId}/count?${searchParams}`); + const response = await api.get(`/account/raidGroup/${raidGroupId}/count?${searchParams}`); - if(response.data.errors){ - throw new Error(response.data.errors.join(", ")); - } - - return response.data.count as number; - } - catch(error){ - if(error instanceof AxiosError && error.response?.data.errors){ - throw new Error(error.response?.data.errors.join(", ")); - } - else{ - throw error; - } - } + return (response.data as Counter).count; } }); } @@ -163,23 +93,9 @@ export function useGetTutorialsStatus(accountId: string | null){ return useQuery({ queryKey: ["tutorials", "account", accountId], queryFn: async () => { - try{ - const response = await api.get(`/account/tutorial`); + const response = await api.get(`/account/tutorial`); - if(response.data.errors){ - throw new Error(response.data.errors.join(", ")); - } - - return response.data as AccountTutorialStatus; - } - catch(error){ - if(error instanceof AxiosError && error.response?.data.errors){ - throw new Error(error.response?.data.errors.join(", ")); - } - else{ - throw error; - } - } + return response.data as AccountTutorialStatus; }, enabled: !!accountId }); @@ -189,21 +105,7 @@ export function useUpdateTutorialsStatus(){ return useMutation({ mutationKey: ["tutorials", "accounts"], mutationFn: async (tutorials: AccountTutorialStatus) => { - try{ - const response = await api.put(`/account/tutorial`, tutorials); - - if(response.data.errors){ - throw new Error(response.data.errors.join(", ")); - } - } - catch(error){ - if(error instanceof AxiosError && error.response?.data.errors){ - throw new Error(error.response?.data.errors.join(", ")); - } - else{ - throw error; - } - } + await api.put(`/account/tutorial`, tutorials); } }); } @@ -212,20 +114,10 @@ export function useUpdatePassword(){ return useMutation({ mutationKey: ["updatePassword"], mutationFn: async ({currentPassword, newPassword}:{currentPassword: string; newPassword: string;}) => { - try{ - await api.post("/auth/resetPassword", { - currentPassword, - newPassword - }); - } - catch(error){ - if(error instanceof AxiosError && error.response?.data.errors){ - throw new Error(error.response?.data.errors.join(", ")); - } - else{ - throw error; - } - } + await api.post("/auth/resetPassword", { + currentPassword, + newPassword + }); } }); } @@ -239,24 +131,10 @@ export function useForcePasswordReset(accountId: string){ return useMutation({ mutationKey: ["forcePasswordReset", accountId], mutationFn: async () => { - try{ - const response = await api.put(`/account/${accountId}/forcePasswordReset`); - - if(response.data.errors){ - throw new Error(response.data.errors.join(", ")); - } - } - catch(error){ - if(error instanceof AxiosError && error.response?.data.errors){ - throw new Error(error.response?.data.errors.join(", ")); - } - else{ - throw error; - } - } + await api.put(`/account/${accountId}/forcePasswordReset`); }, onSuccess: () => { - queryClient.invalidateQueries({ queryKey: ["accounts"] }); + void queryClient.invalidateQueries({ queryKey: ["accounts"] }); } }); } @@ -268,26 +146,12 @@ export function useResetPassword(accountId: string){ return useMutation({ mutationKey: ["resetPassword", accountId], mutationFn: async (password: string) => { - try{ - const response = await api.put(`/account/${accountId}/resetPassword`, { - password - }); - - if(response.data.errors){ - throw new Error(response.data.errors.join(", ")); - } - } - catch(error){ - if(error instanceof AxiosError && error.response?.data.errors){ - throw new Error(error.response?.data.errors.join(", ")); - } - else{ - throw error; - } - } + await api.put(`/account/${accountId}/resetPassword`, { + password + }); }, onSuccess: () => { - queryClient.invalidateQueries({ queryKey: ["accounts"] }); + void queryClient.invalidateQueries({ queryKey: ["accounts"] }); } }); } @@ -299,24 +163,10 @@ export function useRevokeRefreshToken(accountId: string){ return useMutation({ mutationKey: ["revokeRefreshToken", accountId], mutationFn: async () => { - try{ - const response = await api.put(`/account/${accountId}/revokeRefreshToken`); - - if(response.data.errors){ - throw new Error(response.data.errors.join(", ")); - } - } - catch(error){ - if(error instanceof AxiosError && error.response?.data.errors){ - throw new Error(error.response?.data.errors.join(", ")); - } - else{ - throw error; - } - } + await api.put(`/account/${accountId}/revokeRefreshToken`); }, onSuccess: () => { - queryClient.invalidateQueries({ queryKey: ["accounts"] }); + void queryClient.invalidateQueries({ queryKey: ["accounts"] }); } }); } @@ -328,24 +178,10 @@ export function useCreateAccount(){ return useMutation({ mutationKey: ["createAccount"], mutationFn: async (account: Account) => { - try{ - const response = await api.post("/account", account); - - if(response.data.errors){ - throw new Error(response.data.errors.join(", ")); - } - } - catch(error){ - if(error instanceof AxiosError && error.response?.data.errors){ - throw new Error(error.response?.data.errors.join(", ")); - } - else{ - throw error; - } - } + await api.post("/account", account); }, onSuccess: () => { - queryClient.invalidateQueries({ queryKey: ["accounts"] }); + void queryClient.invalidateQueries({ queryKey: ["accounts"] }); } }); } @@ -357,24 +193,10 @@ export function useUpdateAccount(){ return useMutation({ mutationKey: ["updateAccount"], mutationFn: async (account: Account) => { - try{ - const response = await api.put(`/account/${account.accountId}`, account); - - if(response.data.errors){ - throw new Error(response.data.errors.join(", ")); - } - } - catch(error){ - if(error instanceof AxiosError && error.response?.data.errors){ - throw new Error(error.response?.data.errors.join(", ")); - } - else{ - throw error; - } - } + await api.put(`/account/${account.accountId}`, account); }, onSuccess: () => { - queryClient.invalidateQueries({ queryKey: ["accounts"] }); + void queryClient.invalidateQueries({ queryKey: ["accounts"] }); } }); } @@ -386,26 +208,12 @@ export function useUpdateRaidGroupPermissionsForAccount(raidGroupId?: string, ac return useMutation({ mutationKey: ["updateRaidGroupPermissionsForAccount", raidGroupId, accountId], mutationFn: async (permission: RaidGroupPermissionType) => { - try{ - const response = await api.put(`/account/${accountId}/raidGroup/${raidGroupId}/permission`, { - permission - }); - - if(response.data.errors){ - throw new Error(response.data.errors.join(", ")); - } - } - catch(error){ - if(error instanceof AxiosError && error.response?.data.errors){ - throw new Error(error.response?.data.errors.join(", ")); - } - else{ - throw error; - } - } + await api.put(`/account/${accountId}/raidGroup/${raidGroupId}/permission`, { + permission + }); }, onSuccess: () => { - queryClient.invalidateQueries({ queryKey: ["accounts"] }); + void queryClient.invalidateQueries({ queryKey: ["accounts"] }); } }); } @@ -417,24 +225,10 @@ export function useDeleteAccount(accountId: string){ return useMutation({ mutationKey: ["deleteAccount", accountId], mutationFn: async () => { - try{ - const response = await api.delete(`/account/${accountId}`); - - if(response.data.errors){ - throw new Error(response.data.errors.join(", ")); - } - } - catch(error){ - if(error instanceof AxiosError && error.response?.data.errors){ - throw new Error(error.response?.data.errors.join(", ")); - } - else{ - throw error; - } - } + await api.delete(`/account/${accountId}`); }, onSuccess: () => { - queryClient.invalidateQueries({ queryKey: ["accounts"] }); + void queryClient.invalidateQueries({ queryKey: ["accounts"] }); } }); @@ -447,24 +241,10 @@ export function useRemoveAccountFromRaidGroup(raidGroupId?: string, accountId?: return useMutation({ mutationKey: ["removeAccountFromRaidGroup", raidGroupId, accountId], mutationFn: async () => { - try{ - const response = await api.delete(`/account/${accountId}/raidGroup/${raidGroupId}/permission`); - - if(response.data.errors){ - throw new Error(response.data.errors.join(", ")); - } - } - catch(error){ - if(error instanceof AxiosError && error.response?.data.errors){ - throw new Error(error.response?.data.errors.join(", ")); - } - else{ - throw error; - } - } + await api.delete(`/account/${accountId}/raidGroup/${raidGroupId}/permission`); }, onSuccess: () => { - queryClient.invalidateQueries({ queryKey: ["accounts"] }); + void queryClient.invalidateQueries({ queryKey: ["accounts"] }); } }); } diff --git a/src/hooks/AuthHooks.ts b/src/hooks/AuthHooks.ts index 60e0bde..1af2f9c 100644 --- a/src/hooks/AuthHooks.ts +++ b/src/hooks/AuthHooks.ts @@ -1,28 +1,13 @@ import { Account } from "@/interface/Account"; -import { api } from "@/util/AxiosUtil"; +import api from "@/util/AxiosUtil"; import { useMutation } from "@tanstack/react-query"; -import { AxiosError } from "axios"; export function useSignup(){ return useMutation({ mutationKey: ["signup"], mutationFn: async (account: Account) => { - try{ - const response = await api.post("/auth/signup", account); - - if(response.data.errors){ - throw new Error(response.data.errors.join(", ")); - } - } - catch(error){ - if(error instanceof AxiosError && error.response?.data.errors){ - throw new Error(error.response?.data.errors.join(", ")); - } - else{ - throw error; - } - } + await api.post("/auth/signup", account); } }); } @@ -32,21 +17,7 @@ export function useConfirm(){ return useMutation({ mutationKey: ["confirm"], mutationFn: async (confirmToken: string) => { - try{ - const response = await api.post(`/auth/confirm/${confirmToken}`); - - if(response.data.errors){ - throw new Error(response.data.errors.join(", ")); - } - } - catch(error){ - if(error instanceof AxiosError && error.response?.data.errors){ - throw new Error(error.response?.data.errors.join(", ")); - } - else{ - throw error; - } - } + await api.post(`/auth/confirm/${confirmToken}`); } }); } @@ -59,21 +30,7 @@ export function useForgotPassword(){ params.append("username", username); - try{ - const response = await api.post(`/auth/forgot?${params}`); - - if(response.data.errors){ - throw new Error(response.data.errors.join(", ")); - } - } - catch(error){ - if(error instanceof AxiosError && error.response?.data.errors){ - throw new Error(error.response?.data.errors.join(", ")); - } - else{ - throw error; - } - } + await api.post(`/auth/forgot?${params}`); } }); } @@ -82,21 +39,7 @@ export function useForgotResetPassword(forgotToken: string){ return useMutation({ mutationKey: ["forgotResetPassword"], mutationFn: async (password: string) => { - try{ - const response = await api.post(`/auth/forgot/${forgotToken}`, {password}); - - if(response.data.errors){ - throw new Error(response.data.errors.join(", ")); - } - } - catch(error){ - if(error instanceof AxiosError && error.response?.data.errors){ - throw new Error(error.response?.data.errors.join(", ")); - } - else{ - throw error; - } - } + await api.post(`/auth/forgot/${forgotToken}`, {password}); } }); } diff --git a/src/hooks/CalendarHooks.ts b/src/hooks/CalendarHooks.ts index 27e77c3..5f80cf5 100644 --- a/src/hooks/CalendarHooks.ts +++ b/src/hooks/CalendarHooks.ts @@ -1,30 +1,15 @@ import { CalendarEvent } from "@/interface/Calendar"; -import { api } from "@/util/AxiosUtil"; +import api from "@/util/AxiosUtil"; import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; -import { AxiosError } from "axios"; export function useGetGameCalendar(gameId: string){ return useQuery({ queryKey: ["gameCalendar", gameId], queryFn: async () => { - try{ - const response = await api.get(`/calendar/game/${gameId}`); + const response = await api.get(`/calendar/game/${gameId}`); - if(response.data.errors){ - throw new Error(response.data.errors.join(", ")); - } - - return response.data as CalendarEvent[]; - } - catch(error){ - if(error instanceof AxiosError && error.response?.data.errors){ - throw new Error(error.response?.data.errors.join(", ")); - } - else{ - throw error; - } - } + return response.data as CalendarEvent[]; } }); } @@ -33,23 +18,9 @@ export function useGetRaidGroupCalendar(raidGroupId: string){ return useQuery({ queryKey: ["raidGroupCalendar", raidGroupId], queryFn: async () => { - try{ - const response = await api.get(`/calendar/raidGroup/${raidGroupId}`); + const response = await api.get(`/calendar/raidGroup/${raidGroupId}`); - if(response.data.errors){ - throw new Error(response.data.errors.join(", ")); - } - - return response.data as CalendarEvent[]; - } - catch(error){ - if(error instanceof AxiosError && error.response?.data.errors){ - throw new Error(error.response?.data.errors.join(", ")); - } - else{ - throw error; - } - } + return response.data as CalendarEvent[]; } }); } @@ -61,24 +32,10 @@ export function useCreateGameCalendarEvent(gameId: string){ return useMutation({ mutationFn: async (calendarEvent: CalendarEvent) => { - try{ - const response = await api.post(`/calendar/game/${gameId}`, {...calendarEvent, gameCalendarEventId: calendarEvent.calendarEventId, calendarEventId: undefined}); - - if(response.data.errors){ - throw new Error(response.data.errors.join(", ")); - } - } - catch(error){ - if(error instanceof AxiosError && error.response?.data.errors){ - throw new Error(error.response?.data.errors.join(", ")); - } - else{ - throw error; - } - } + await api.post(`/calendar/game/${gameId}`, {...calendarEvent, gameCalendarEventId: calendarEvent.calendarEventId, calendarEventId: undefined}); }, onSuccess: () => { - queryClient.invalidateQueries({ queryKey: ["gameCalendar"]}) + void queryClient.invalidateQueries({ queryKey: ["gameCalendar"]}) } }); } @@ -89,29 +46,15 @@ export function useUpdateGameCalendarEvent(gameId: string){ return useMutation({ mutationFn: async (calendarEvent: CalendarEvent) => { - try{ - const response = await api.put(`/calendar/game/${gameId}`, - { - ...calendarEvent, - gameCalendarEventId: calendarEvent.calendarEventId, - calendarEventId: undefined - }); - - if(response.data.errors){ - throw new Error(response.data.errors.join(", ")); - } - } - catch(error){ - if(error instanceof AxiosError && error.response?.data.errors){ - throw new Error(error.response?.data.errors.join(", ")); - } - else{ - throw error; - } - } + await api.put(`/calendar/game/${gameId}`, + { + ...calendarEvent, + gameCalendarEventId: calendarEvent.calendarEventId, + calendarEventId: undefined + }); }, onSuccess: () => { - queryClient.invalidateQueries({ queryKey: ["gameCalendar"]}) + void queryClient.invalidateQueries({ queryKey: ["gameCalendar"]}) } }); } @@ -122,24 +65,10 @@ export function useDeleteGameCalendarEvent(gameId: string){ return useMutation({ mutationFn: async (calendarEvent: CalendarEvent) => { - try{ - const response = await api.delete(`/calendar/game/${gameId}/${calendarEvent.calendarEventId}`); - - if(response.data.errors){ - throw new Error(response.data.errors.join(", ")); - } - } - catch(error){ - if(error instanceof AxiosError && error.response?.data.errors){ - throw new Error(error.response?.data.errors.join(", ")); - } - else{ - throw error; - } - } + await api.delete(`/calendar/game/${gameId}/${calendarEvent.calendarEventId}`); }, onSuccess: () => { - queryClient.invalidateQueries({ queryKey: ["gameCalendar"]}) + void queryClient.invalidateQueries({ queryKey: ["gameCalendar"]}) } }); } @@ -150,29 +79,15 @@ export function useCreateRaidGroupCalendarEvent(raidGroupId: string){ return useMutation({ mutationFn: async (calendarEvent: CalendarEvent) => { - try{ - const response = await api.post(`/calendar/raidGroup/${raidGroupId}`, - { - ...calendarEvent, - raidGroupCalendarEventId: calendarEvent.calendarEventId, - calendarEventId: undefined - }); - - if(response.data.errors){ - throw new Error(response.data.errors.join(", ")); - } - } - catch(error){ - if(error instanceof AxiosError && error.response?.data.errors){ - throw new Error(error.response?.data.errors.join(", ")); - } - else{ - throw error; - } - } + await api.post(`/calendar/raidGroup/${raidGroupId}`, + { + ...calendarEvent, + raidGroupCalendarEventId: calendarEvent.calendarEventId, + calendarEventId: undefined + }); }, onSuccess: () => { - queryClient.invalidateQueries({ queryKey: ["raidGroupCalendar"]}) + void queryClient.invalidateQueries({ queryKey: ["raidGroupCalendar"]}) } }); } @@ -183,24 +98,10 @@ export function useUpdateRaidGroupCalendarEvent(raidGroupId: string){ return useMutation({ mutationFn: async (calendarEvent: CalendarEvent) => { - try{ - const response = await api.put(`/calendar/raidGroup/${raidGroupId}`, {...calendarEvent, raidGroupCalendarEventId: calendarEvent.calendarEventId, calendarEventId: undefined}); - - if(response.data.errors){ - throw new Error(response.data.errors.join(", ")); - } - } - catch(error){ - if(error instanceof AxiosError && error.response?.data.errors){ - throw new Error(error.response?.data.errors.join(", ")); - } - else{ - throw error; - } - } + await api.put(`/calendar/raidGroup/${raidGroupId}`, {...calendarEvent, raidGroupCalendarEventId: calendarEvent.calendarEventId, calendarEventId: undefined}); }, onSuccess: () => { - queryClient.invalidateQueries({ queryKey: ["raidGroupCalendar"]}) + void queryClient.invalidateQueries({ queryKey: ["raidGroupCalendar"]}) } }); } @@ -211,24 +112,10 @@ export function useDeleteRaidGroupCalendarEvent(raidGroupId: string){ return useMutation({ mutationFn: async (calendarEvent: CalendarEvent) => { - try{ - const response = await api.delete(`/calendar/raidGroup/${raidGroupId}/${calendarEvent.calendarEventId}`); - - if(response.data.errors){ - throw new Error(response.data.errors.join(", ")); - } - } - catch(error){ - if(error instanceof AxiosError && error.response?.data.errors){ - throw new Error(error.response?.data.errors.join(", ")); - } - else{ - throw error; - } - } + await api.delete(`/calendar/raidGroup/${raidGroupId}/${calendarEvent.calendarEventId}`); }, onSuccess: () => { - queryClient.invalidateQueries({ queryKey: ["raidGroupCalendar"]}) + void queryClient.invalidateQueries({ queryKey: ["raidGroupCalendar"]}) } }); } @@ -237,23 +124,9 @@ export function useGetRaidInstanceCalendarEvents(raidGroupId?: string){ return useQuery({ queryKey: ["raidInstanceCalendarEvents", raidGroupId], queryFn: async () => { - try{ - const response = await api.get(`/calendar/raidGroup/${raidGroupId}/raidInstance`); + const response = await api.get(`/calendar/raidGroup/${raidGroupId}/raidInstance`); - if(response.data.errors){ - throw new Error(response.data.errors.join(", ")); - } - - return response.data as CalendarEvent[]; - } - catch(error){ - if(error instanceof AxiosError && error.response?.data.errors){ - throw new Error(error.response?.data.errors.join(", ")); - } - else{ - throw error; - } - } + return response.data as CalendarEvent[]; }, enabled: !!raidGroupId && raidGroupId !== "" }); diff --git a/src/hooks/ClassGroupHooks.ts b/src/hooks/ClassGroupHooks.ts index 6d95b7d..4cfcb13 100644 --- a/src/hooks/ClassGroupHooks.ts +++ b/src/hooks/ClassGroupHooks.ts @@ -1,7 +1,7 @@ import { ClassGroup } from "@/interface/ClassGroup"; -import { api } from "@/util/AxiosUtil"; +import { Counter } from "@/interface/Counters"; +import api from "@/util/AxiosUtil"; import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; -import { AxiosError } from "axios"; export function useGetClassGroups(raidGroupId: string, page: number, pageSize: number, searchTerm?: string){ @@ -15,23 +15,9 @@ export function useGetClassGroups(raidGroupId: string, page: number, pageSize: n params.append("searchTerm", searchTerm); } - try{ - const response = await api.get(`/raidGroup/${raidGroupId}/classGroup?${params}`); + const response = await api.get(`/raidGroup/${raidGroupId}/classGroup?${params}`); - if(response.data.errors){ - throw new Error(response.data.errors.join(", ")); - } - - return response.data as ClassGroup[]; - } - catch(error){ - if(error instanceof AxiosError && error.response?.data.errors){ - throw new Error(error.response?.data.errors.join(", ")); - } - else{ - throw error; - } - } + return response.data as ClassGroup[]; }, enabled: !!raidGroupId }); @@ -47,23 +33,9 @@ export function useGetClassGroupsCount(raidGroupId: string, searchTerm?: string) return useQuery({ queryKey: ["classGroups", "count", searchTerm], queryFn: async () => { - try{ - const response = await api.get(`/raidGroup/${raidGroupId}/classGroup/count?${searchParams}`); + const response = await api.get(`/raidGroup/${raidGroupId}/classGroup/count?${searchParams}`); - if(response.data.errors){ - throw new Error(response.data.errors.join(", ")); - } - - return response.data.count as number; - } - catch(error){ - if(error instanceof AxiosError && error.response?.data.errors){ - throw new Error(error.response?.data.errors.join(", ")); - } - else{ - throw error; - } - } + return (response.data as Counter).count; } }); } @@ -72,23 +44,9 @@ export function useGetClassGroupsByRaidLayout(raidGroupId: string, raidLayoutId: return useQuery({ queryKey: ["classGroups", "raidLayout", raidLayoutId], queryFn: async () => { - try{ - const response = await api.get(`/raidGroup/${raidGroupId}/classGroup/raidLayout/${raidLayoutId}`); + const response = await api.get(`/raidGroup/${raidGroupId}/classGroup/raidLayout/${raidLayoutId}`); - if(response.data.error){ - throw new Error(response.data.errors.join(", ")); - } - - return response.data as (ClassGroup | null)[]; - } - catch(error){ - if(error instanceof AxiosError && error.response?.data.errors){ - throw new Error(error.response?.data.errors.join(", ")); - } - else{ - throw error; - } - } + return response.data as (ClassGroup | null)[]; }, enabled: !!raidGroupId && !!raidLayoutId }) @@ -102,31 +60,17 @@ export function useCreateClassGroup(raidGroupId: string){ return useMutation({ mutationKey: ["createClassGroup"], mutationFn: async ({classGroupName, gameClassIds}:{classGroupName: string; gameClassIds: string[];}) => { - try{ - const response = await api.post(`/raidGroup/${raidGroupId}/classGroup`, - { - classGroup: { - classGroupName: classGroupName, - raidGroupId: raidGroupId - }, - gameClassIds - }); - - if(response.data.errors){ - throw new Error(response.data.errors.join(", ")); - } - } - catch(error){ - if(error instanceof AxiosError && error.response?.data.errors){ - throw new Error(error.response?.data.errors.join(", ")); - } - else{ - throw error; - } - } + await api.post(`/raidGroup/${raidGroupId}/classGroup`, + { + classGroup: { + classGroupName: classGroupName, + raidGroupId: raidGroupId + }, + gameClassIds + }); }, onSuccess: () => { - queryClient.invalidateQueries({queryKey: ["classGroups"]}); + void queryClient.invalidateQueries({queryKey: ["classGroups"]}); } }); } @@ -138,30 +82,16 @@ export function useUpdateClassGroup(raidGroupId: string){ return useMutation({ mutationKey: ["updateClassGroup"], mutationFn: async ({classGroup, gameClassIds}:{classGroup: ClassGroup; gameClassIds: string[];}) => { - try{ - const response = await api.put(`/raidGroup/${raidGroupId}/classGroup/${classGroup.classGroupId}`, - { - classGroup, - gameClassIds - } - ); - - if(response.data.errors){ - throw new Error(response.data.errors.join(", ")); + await api.put(`/raidGroup/${raidGroupId}/classGroup/${classGroup.classGroupId}`, + { + classGroup, + gameClassIds } - } - catch(error){ - if(error instanceof AxiosError && error.response?.data.errors){ - throw new Error(error.response?.data.errors.join(", ")); - } - else{ - throw error; - } - } + ); }, onSuccess: () => { - queryClient.invalidateQueries({queryKey: ["gameClasses", "classGroups"]}); - queryClient.invalidateQueries({queryKey: ["classGroups"]}); + void queryClient.invalidateQueries({queryKey: ["gameClasses", "classGroups"]}); + void queryClient.invalidateQueries({queryKey: ["classGroups"]}); } }); } @@ -173,24 +103,10 @@ export function useDeleteClassGroup(raidGroupId: string, classGroupId: string){ return useMutation({ mutationKey: ["deleteClassGroup", classGroupId, raidGroupId], mutationFn: async () => { - try{ - const response = await api.delete(`/raidGroup/${raidGroupId}/classGroup/${classGroupId}`); - - if(response.data.errors){ - throw new Error(response.data.errors.join(", ")); - } - } - catch(error){ - if(error instanceof AxiosError && error.response?.data.errors){ - throw new Error(error.response?.data.errors.join(", ")); - } - else{ - throw error; - } - } + await api.delete(`/raidGroup/${raidGroupId}/classGroup/${classGroupId}`); }, onSuccess: () => { - queryClient.invalidateQueries({queryKey: ["classGroups"]}); + void queryClient.invalidateQueries({queryKey: ["classGroups"]}); } }); } diff --git a/src/hooks/GameClassHooks.ts b/src/hooks/GameClassHooks.ts index 8f380c6..63beeec 100644 --- a/src/hooks/GameClassHooks.ts +++ b/src/hooks/GameClassHooks.ts @@ -1,30 +1,16 @@ +import { Counter } from "@/interface/Counters"; import { GameClass } from "@/interface/GameClass"; -import { api } from "@/util/AxiosUtil"; +import api from "@/util/AxiosUtil"; import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; -import { AxiosError } from "axios"; export function useGetGameClass(gameClassId: string){ return useQuery({ queryKey: ["gameClasses", gameClassId], queryFn: async () => { - try{ - const response = await api.get(`/gameClass/${gameClassId}`); + const response = await api.get(`/gameClass/${gameClassId}`); - if(response.data.errors){ - throw new Error(response.data.errors.join(", ")); - } - - return response.data as GameClass; - } - catch(error){ - if(error instanceof AxiosError && error.response?.data.errors){ - throw new Error(error.response?.data.errors.join(", ")); - } - else{ - throw error; - } - } + return response.data as GameClass; }, enabled: !!gameClassId }) @@ -41,23 +27,9 @@ export function useGetGameClasses(gameId: string, page: number, pageSize: number params.append("searchTerm", searchTerm); } - try{ - const response = await api.get(`/gameClass/game/${gameId}?${params}`); + const response = await api.get(`/gameClass/game/${gameId}?${params}`); - if(response.data.errors){ - throw new Error(response.data.errors.join(", ")); - } - - return response.data as GameClass[]; - } - catch(error){ - if(error instanceof AxiosError && error.response?.data.errors){ - throw new Error(error.response?.data.errors.join(", ")); - } - else{ - throw error; - } - } + return response.data as GameClass[]; } }); } @@ -66,23 +38,9 @@ export function useGetGameClassesByClassGroup(classGroupId?: string){ return useQuery({ queryKey: ["gameClasses", "classGroups", classGroupId], queryFn: async () => { - try{ - const response = await api.get(`/gameClass/classGroup/${classGroupId}`); + const response = await api.get(`/gameClass/classGroup/${classGroupId}`); - if(response.data.errors){ - throw new Error(response.data.errors.join(", ")); - } - - return response.data as GameClass[]; - } - catch(error){ - if(error instanceof AxiosError && error.response?.data.errors){ - throw new Error(error.response?.data.errors.join(", ")); - } - else{ - throw error; - } - } + return response.data as GameClass[]; }, enabled: !!classGroupId }); @@ -99,23 +57,9 @@ export function useGetGameClassesCount(gameId: string, searchTerm?: string){ return useQuery({ queryKey: ["gameClasses", gameId, "count", searchTerm], queryFn: async () => { - try{ - const response = await api.get(`/gameClass/game/${gameId}/count?${searchParams}`); + const response = await api.get(`/gameClass/game/${gameId}/count?${searchParams}`); - if(response.data.errors){ - throw new Error(response.data.errors.join(", ")); - } - - return response.data.count as number; - } - catch(error){ - if(error instanceof AxiosError && error.response?.data.errors){ - throw new Error(error.response?.data.errors.join(", ")); - } - else{ - throw error; - } - } + return (response.data as Counter).count; } }); } @@ -135,27 +79,13 @@ export function useCreateGameClass(){ formData.append("gameClassName", gameClassName); formData.append("gameId", gameId); - try{ - const response = await api.post( - `/gameClass/game/${gameId}`, - formData - ); - - if(response.data.errors){ - throw new Error(response.data.errors.join(", ")); - } - } - catch(error){ - if(error instanceof AxiosError && error.response?.data.errors){ - throw new Error(error.response?.data.errors.join(", ")); - } - else{ - throw error; - } - } + await api.post( + `/gameClass/game/${gameId}`, + formData + ); }, onSuccess: () => { - queryClient.invalidateQueries({ queryKey: ["gameClasses"] }); + void queryClient.invalidateQueries({ queryKey: ["gameClasses"] }); } }); } @@ -177,24 +107,10 @@ export function useUpdateGameClass(){ formData.append("gameClassIcon", gameClass.gameClassIcon); } - try{ - const response = await api.put(`/gameClass/${gameClass.gameClassId}/game/${gameClass.gameId}`, formData); - - if(response.data.errors){ - throw new Error(response.data.errors.join(", ")); - } - } - catch(error){ - if(error instanceof AxiosError && error.response?.data.errors){ - throw new Error(error.response?.data.errors.join(", ")); - } - else{ - throw error; - } - } + await api.put(`/gameClass/${gameClass.gameClassId}/game/${gameClass.gameId}`, formData); }, onSuccess: () => { - queryClient.invalidateQueries({ queryKey: ["gameClasses"] }); + void queryClient.invalidateQueries({ queryKey: ["gameClasses"] }); } }); } @@ -206,24 +122,10 @@ export function useDeleteGameClass(){ return useMutation({ mutationKey: ["deleteGameClass"], mutationFn: async (gameClass: GameClass) => { - try{ - const response = await api.delete(`/gameClass/${gameClass.gameClassId}/game/${gameClass.gameId}`); - - if(response.data.errors){ - throw new Error(response.data.errors.join(", ")); - } - } - catch(error){ - if(error instanceof AxiosError && error.response?.data.errors){ - throw new Error(error.response?.data.errors.join(", ")); - } - else{ - throw error; - } - } + await api.delete(`/gameClass/${gameClass.gameClassId}/game/${gameClass.gameId}`); }, onSuccess: () => { - queryClient.invalidateQueries({ queryKey: ["gameClasses"] }); + void queryClient.invalidateQueries({ queryKey: ["gameClasses"] }); } }); } diff --git a/src/hooks/GameHooks.ts b/src/hooks/GameHooks.ts index 1201ac8..80ffdc2 100644 --- a/src/hooks/GameHooks.ts +++ b/src/hooks/GameHooks.ts @@ -1,30 +1,16 @@ +import { Counter } from "@/interface/Counters"; import { Game } from "@/interface/Game"; -import { api } from "@/util/AxiosUtil"; +import api from "@/util/AxiosUtil"; import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; -import { AxiosError } from "axios"; export function useGetGame(gameId: string, disabled: boolean){ return useQuery({ queryKey: ["games", gameId], queryFn: async () => { - try{ - const response = await api.get(`/game/${gameId}`); + const response = await api.get(`/game/${gameId}`); - if(response.data.errors){ - throw new Error(response.data.errors.join(", ")); - } - - return response.data?.gameId ? response.data as Game : undefined; - } - catch(error){ - if(error instanceof AxiosError && error.response?.data.errors){ - throw new Error(error.response?.data.errors.join(", ")); - } - else{ - throw error; - } - } + return (response.data as Game)?.gameId ? response.data as Game : undefined; }, enabled: !disabled }); @@ -41,19 +27,9 @@ export function useGetGames(page: number, pageSize: number, searchTerm?: string) params.append("searchTerm", searchTerm); } - try{ - const response = await api.get(`/game?${params}`); + const response = await api.get(`/game?${params}`); - return response.data as Game[]; - } - catch(error){ - if(error instanceof AxiosError && error.response?.data.errors){ - throw new Error(error.response?.data.errors.join(", ")); - } - else{ - throw error; - } - } + return response.data as Game[]; } }); } @@ -68,23 +44,9 @@ export function useGetGamesCount(searchTerm?: string){ return useQuery({ queryKey: ["games", "count", searchTerm], queryFn: async () => { - try{ - const response = await api.get(`/game/count?${searchParams}`); + const response = await api.get(`/game/count?${searchParams}`); - if(response.data.errors){ - throw new Error(response.data.errors.join(", ")); - } - - return response.data.count as number; - } - catch(error){ - if(error instanceof AxiosError && error.response?.data.errors){ - throw new Error(error.response?.data.errors.join(", ")); - } - else{ - throw error; - } - } + return (response.data as Counter).count; } }); } @@ -102,27 +64,13 @@ export function useCreateGame(){ } formData.append("gameName", gameName); - try{ - const response = await api.post( - "/game", - formData - ); - - if(response.data.errors){ - throw new Error(response.data.errors.join(", ")); - } - } - catch(error){ - if(error instanceof AxiosError && error.response?.data.errors){ - throw new Error(error.response?.data.errors.join(", ")); - } - else{ - throw error; - } - } + await api.post( + "/game", + formData + ); }, onSuccess: () => { - queryClient.invalidateQueries({ queryKey: ["games"] }); + void queryClient.invalidateQueries({ queryKey: ["games"] }); } }); } @@ -143,24 +91,10 @@ export function useUpdateGame(){ formData.append("gameIcon", game.gameIcon); } - try{ - const response = await api.put(`/game/${game.gameId}`, formData); - - if(response.data.errors){ - throw new Error(response.data.errors.join(", ")); - } - } - catch(error){ - if(error instanceof AxiosError && error.response?.data.errors){ - throw new Error(error.response?.data.errors.join(", ")); - } - else{ - throw error; - } - } + await api.put(`/game/${game.gameId}`, formData); }, onSuccess: () => { - queryClient.invalidateQueries({ queryKey: ["games"] }); + void queryClient.invalidateQueries({ queryKey: ["games"] }); } }); } @@ -172,24 +106,10 @@ export function useDeleteGame(){ return useMutation({ mutationKey: ["deleteGame"], mutationFn: async (gameId: string) => { - try{ - const response = await api.delete(`/game/${gameId}`); - - if(response.data.errors){ - throw new Error(response.data.errors.join(", ")); - } - } - catch(error){ - if(error instanceof AxiosError && error.response?.data.errors){ - throw new Error(error.response?.data.errors.join(", ")); - } - else{ - throw error; - } - } + await api.delete(`/game/${gameId}`); }, onSuccess: () => { - queryClient.invalidateQueries({ queryKey: ["games"] }); + void queryClient.invalidateQueries({ queryKey: ["games"] }); } }); } diff --git a/src/hooks/PersonCharacterHooks.ts b/src/hooks/PersonCharacterHooks.ts index 0030de9..0ef77b5 100644 --- a/src/hooks/PersonCharacterHooks.ts +++ b/src/hooks/PersonCharacterHooks.ts @@ -1,30 +1,16 @@ +import { Counter } from "@/interface/Counters"; import { PersonCharacter } from "@/interface/PersonCharacter"; -import { api } from "@/util/AxiosUtil"; +import api from "@/util/AxiosUtil"; import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; -import { AxiosError } from "axios"; export function useGetPersonCharactersByPersonId(personId: string, raidGroupId: string){ return useQuery({ queryKey: ["personCharacters", personId], queryFn: async () => { - try{ - const response = await api.get(`/raidGroup/${raidGroupId}/person/${personId}/character`); + const response = await api.get(`/raidGroup/${raidGroupId}/person/${personId}/character`); - if(response.data.errors){ - throw new Error(response.data.errors.join(", ")); - } - - return response.data as PersonCharacter[]; - } - catch(error){ - if(error instanceof AxiosError && error.response?.data.errors){ - throw new Error(error.response?.data.errors.join(", ")); - } - else{ - throw error; - } - } + return response.data as PersonCharacter[]; } }); } @@ -41,23 +27,9 @@ export function useGetPersonCharactersByPersonIdSearch(personId: string, raidGro return useQuery({ queryKey: ["personCharacters", personId, { page, pageSize, searchTerm }], queryFn: async () => { - try{ - const response = await api.get(`/raidGroup/${raidGroupId}/person/${personId}/character/page?${params}`); + const response = await api.get(`/raidGroup/${raidGroupId}/person/${personId}/character/page?${params}`); - if(response.data.errors){ - throw new Error(response.data.errors.join(", ")); - } - - return response.data as PersonCharacter[]; - } - catch(error){ - if(error instanceof AxiosError && error.response?.data.errors){ - throw new Error(error.response?.data.errors.join(", ")); - } - else{ - throw error; - } - } + return response.data as PersonCharacter[]; } }); } @@ -71,23 +43,9 @@ export function useGetPersonCharactersCountByPersonIdSearch(personId: string, ra return useQuery({ queryKey: ["personCharactersCount", personId, { searchTerm }], queryFn: async () => { - try{ - const response = await api.get(`/raidGroup/${raidGroupId}/person/${personId}/character/count?${params}`); + const response = await api.get(`/raidGroup/${raidGroupId}/person/${personId}/character/count?${params}`); - if(response.data.errors){ - throw new Error(response.data.errors.join(", ")); - } - - return response.data.count as number; - } - catch(error){ - if(error instanceof AxiosError && error.response?.data.errors){ - throw new Error(error.response?.data.errors.join(", ")); - } - else{ - throw error; - } - } + return (response.data as Counter).count; } }); } @@ -96,23 +54,9 @@ export function useGetPersonCharactersByRaidGroup(raidGroupId: string){ return useQuery({ queryKey: ["personCharacters", raidGroupId], queryFn: async () => { - try{ - const response = await api.get(`/raidGroup/${raidGroupId}/person/character`); + const response = await api.get(`/raidGroup/${raidGroupId}/person/character`); - if(response.data.errors){ - throw new Error(response.data.errors.join(", ")); - } - - return response.data as PersonCharacter[]; - } - catch(error){ - if(error instanceof AxiosError && error.response?.data.errors){ - throw new Error(error.response?.data.errors.join(", ")); - } - else{ - throw error; - } - } + return response.data as PersonCharacter[]; }, enabled: !!raidGroupId }); @@ -125,24 +69,10 @@ export function useCreatePersonCharacter(raidGroupId: string, personId: string){ return useMutation({ mutationKey: ["createPersonCharacter"], mutationFn: async (personCharacter: PersonCharacter) => { - try{ - const response = await api.post(`/raidGroup/${raidGroupId}/person/${personId}/character`, personCharacter); - - if(response.data.errors){ - throw new Error(response.data.errors.join(", ")); - } - } - catch(error){ - if(error instanceof AxiosError && error.response?.data.errors){ - throw new Error(error.response?.data.errors.join(", ")); - } - else{ - throw error; - } - } + await api.post(`/raidGroup/${raidGroupId}/person/${personId}/character`, personCharacter); }, onSuccess: () => { - queryClient.invalidateQueries({ queryKey: ["personCharacters"] }); + void queryClient.invalidateQueries({ queryKey: ["personCharacters"] }); } }); } @@ -154,24 +84,10 @@ export function useUpdatePersonCharacter(raidGroupId: string, personId: string){ return useMutation({ mutationKey: ["updatePersonCharacter"], mutationFn: async (personCharacter: PersonCharacter) => { - try{ - const response = await api.put(`/raidGroup/${raidGroupId}/person/${personId}/character/${personCharacter.personCharacterId}`, personCharacter); - - if(response.data.errors){ - throw new Error(response.data.errors.join(", ")); - } - } - catch(error){ - if(error instanceof AxiosError && error.response?.data.errors){ - throw new Error(error.response?.data.errors.join(", ")); - } - else{ - throw error; - } - } + await api.put(`/raidGroup/${raidGroupId}/person/${personId}/character/${personCharacter.personCharacterId}`, personCharacter); }, onSuccess: () => { - queryClient.invalidateQueries({ queryKey: ["personCharacters"] }); + void queryClient.invalidateQueries({ queryKey: ["personCharacters"] }); } }); } @@ -183,24 +99,10 @@ export function useDeletePersonCharacter(raidGroupId: string, personId: string){ return useMutation({ mutationKey: ["deletePersonCharacter"], mutationFn: async (personCharacterId: string) => { - try{ - const response = await api.delete(`/raidGroup/${raidGroupId}/person/${personId}/character/${personCharacterId}`); - - if(response.data.errors){ - throw new Error(response.data.errors.join(", ")); - } - } - catch(error){ - if(error instanceof AxiosError && error.response?.data.errors){ - throw new Error(error.response?.data.errors.join(", ")); - } - else{ - throw error; - } - } + await api.delete(`/raidGroup/${raidGroupId}/person/${personId}/character/${personCharacterId}`); }, onSuccess: () => { - queryClient.invalidateQueries({ queryKey: ["personCharacters"] }); + void queryClient.invalidateQueries({ queryKey: ["personCharacters"] }); } }); } diff --git a/src/hooks/PersonHooks.ts b/src/hooks/PersonHooks.ts index f5bc982..6509169 100644 --- a/src/hooks/PersonHooks.ts +++ b/src/hooks/PersonHooks.ts @@ -1,30 +1,16 @@ +import { Counter } from "@/interface/Counters"; import { Person } from "@/interface/Person"; -import { api } from "@/util/AxiosUtil"; +import api from "@/util/AxiosUtil"; import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; -import { AxiosError } from "axios"; export function useGetPerson(raidGroupId: string, personId: string, disabled: boolean){ return useQuery({ queryKey: ["people", raidGroupId, personId], queryFn: async () => { - try{ - const response = await api.get(`/raidGroup/${raidGroupId}/person/${personId}`); + const response = await api.get(`/raidGroup/${raidGroupId}/person/${personId}`); - if(response.data.errors){ - throw new Error(response.data.errors.join(", ")); - } - - return response.data as Person; - } - catch(error){ - if(error instanceof AxiosError && error.response?.data.errors){ - throw new Error(error.response?.data.errors.join(", ")); - } - else{ - throw error; - } - } + return response.data as Person; }, enabled: !disabled }); @@ -41,23 +27,9 @@ export function useGetPeopleByRaidGroup(raidGroupId: string, page: number, pageS searchParams.append("searchTerm", searchTerm); } - try{ - const response = await api.get(`/raidGroup/${raidGroupId}/person?${searchParams}`); + const response = await api.get(`/raidGroup/${raidGroupId}/person?${searchParams}`); - if(response.data.errors){ - throw new Error(response.data.errors.join(", ")); - } - - return response.data as Person[]; - } - catch(error){ - if(error instanceof AxiosError && error.response?.data.errors){ - throw new Error(error.response?.data.errors.join(", ")); - } - else{ - throw error; - } - } + return response.data as Person[]; } }); } @@ -72,23 +44,9 @@ export function useGetPeopleByRaidGroupCount(raidGroupId: string, searchTerm?: s return useQuery({ queryKey: ["people", raidGroupId, "count", searchTerm], queryFn: async () => { - try{ - const response = await api.get(`/raidGroup/${raidGroupId}/person/count?${searchParams}`); + const response = await api.get(`/raidGroup/${raidGroupId}/person/count?${searchParams}`); - if(response.data.errors){ - throw new Error(response.data.errors.join(", ")); - } - - return response.data.count as number; - } - catch(error){ - if(error instanceof AxiosError && error.response?.data.errors){ - throw new Error(error.response?.data.errors.join(", ")); - } - else{ - throw error; - } - } + return (response.data as Counter).count; } }); } @@ -100,24 +58,10 @@ export function useCreatePerson(){ return useMutation({ mutationKey: ["createPerson"], mutationFn: async ({raidGroupId, personName, discordId}:{raidGroupId: string; personName: string; discordId?: string;}) => { - try{ - const response = await api.post(`/raidGroup/${raidGroupId}/person`, {raidGroupId, personName, discordId}); - - if(response.data.errors){ - throw new Error(response.data.errors.join(", ")); - } - } - catch(error){ - if(error instanceof AxiosError && error.response?.data.errors){ - throw new Error(error.response?.data.errors.join(", ")); - } - else{ - throw error; - } - } + await api.post(`/raidGroup/${raidGroupId}/person`, {raidGroupId, personName, discordId}); }, onSuccess: () => { - queryClient.invalidateQueries({ queryKey: ["people"] }); + void queryClient.invalidateQueries({ queryKey: ["people"] }); } }); } @@ -129,24 +73,10 @@ export function useUpdatePerson(){ return useMutation({ mutationKey: ["updatePerson"], mutationFn: async (person: Person) => { - try{ - const response = await api.put(`/raidGroup/${person.raidGroupId}/person/${person.personId}`, person); - - if(response.data.errors){ - throw new Error(response.data.errors.join(", ")); - } - } - catch(error){ - if(error instanceof AxiosError && error.response?.data.errors){ - throw new Error(error.response?.data.errors.join(", ")); - } - else{ - throw error; - } - } + await api.put(`/raidGroup/${person.raidGroupId}/person/${person.personId}`, person); }, onSuccess: () => { - queryClient.invalidateQueries({ queryKey: ["people"] }); + void queryClient.invalidateQueries({ queryKey: ["people"] }); } }); } @@ -158,24 +88,10 @@ export function useDeletePerson(){ return useMutation({ mutationKey: ["deletePerson"], mutationFn: async ({raidGroupId, personId}:{raidGroupId: string; personId: string;}) => { - try{ - const response = await api.delete(`/raidGroup/${raidGroupId}/person/${personId}`); - - if(response.data.errors){ - throw new Error(response.data.errors.join(", ")); - } - } - catch(error){ - if(error instanceof AxiosError && error.response?.data.errors){ - throw new Error(error.response?.data.errors.join(", ")); - } - else{ - throw error; - } - } + await api.delete(`/raidGroup/${raidGroupId}/person/${personId}`); }, onSuccess: () => { - queryClient.invalidateQueries({ queryKey: ["people"] }); + void queryClient.invalidateQueries({ queryKey: ["people"] }); } }); } diff --git a/src/hooks/RaidGroupHooks.ts b/src/hooks/RaidGroupHooks.ts index acc6ecb..d0bc59c 100644 --- a/src/hooks/RaidGroupHooks.ts +++ b/src/hooks/RaidGroupHooks.ts @@ -1,30 +1,16 @@ +import { Counter } from "@/interface/Counters"; import { RaidGroup } from "@/interface/RaidGroup"; -import { api } from "@/util/AxiosUtil"; +import api from "@/util/AxiosUtil"; import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; -import { AxiosError } from "axios"; export function useGetRaidGroup(raidGroupId: string, disabled: boolean){ return useQuery({ queryKey: ["raidGroups", raidGroupId], queryFn: async () => { - try{ - const response = await api.get(`/raidGroup/${raidGroupId}`); + const response = await api.get(`/raidGroup/${raidGroupId}`); - if(response.data.errors){ - throw new Error(response.data.errors.join(", ")); - } - - return response.data?.raidGroupId ? response.data as RaidGroup : undefined; - } - catch(error){ - if(error instanceof AxiosError && error.response?.data.errors){ - throw new Error(error.response?.data.errors.join(", ")); - } - else{ - throw error; - } - } + return (response.data as RaidGroup)?.raidGroupId ? response.data as RaidGroup : undefined; }, enabled: !disabled }); @@ -41,23 +27,9 @@ export function useGetRaidGroups(page: number, pageSize: number, searchTerm?: st params.append("searchTerm", searchTerm); } - try{ - const response = await api.get(`/raidGroup?${params}`); + const response = await api.get(`/raidGroup?${params}`); - if(response.data.errors){ - throw new Error(response.data.errors.join(", ")); - } - - return response.data as RaidGroup[]; - } - catch(error){ - if(error instanceof AxiosError && error.response?.data.errors){ - throw new Error(error.response?.data.errors.join(", ")); - } - else{ - throw error; - } - } + return response.data as RaidGroup[]; } }); } @@ -72,23 +44,9 @@ export function useGetRaidGroupsCount(searchTerm?: string){ return useQuery({ queryKey: ["raidGroups", "count", searchTerm], queryFn: async () => { - try{ - const response = await api.get(`/raidGroup/count?${searchParams}`); + const response = await api.get(`/raidGroup/count?${searchParams}`); - if(response.data.errors){ - throw new Error(response.data.errors.join(", ")); - } - - return response.data.count as number; - } - catch(error){ - if(error instanceof AxiosError && error.response?.data.errors){ - throw new Error(error.response?.data.errors.join(", ")); - } - else{ - throw error; - } - } + return (response.data as Counter).count; } }); } @@ -104,23 +62,9 @@ export function useGetRaidGroupsByGame(gameId: string, page: number, pageSize: n params.append("searchTerm", searchTerm); } - try{ - const response = await api.get(`/raidGroup/game/${gameId}?${params}`); + const response = await api.get(`/raidGroup/game/${gameId}?${params}`); - if(response.data.errors){ - throw new Error(response.data.errors.join(", ")); - } - - return response.data as RaidGroup[]; - } - catch(error){ - if(error instanceof AxiosError && error.response?.data.errors){ - throw new Error(error.response?.data.errors.join(", ")); - } - else{ - throw error; - } - } + return response.data as RaidGroup[]; } }); } @@ -135,23 +79,9 @@ export function useGetRaidGroupsByGameCount(gameId: string, searchTerm?: string) return useQuery({ queryKey: ["raidGroups", gameId, "count", searchTerm], queryFn: async () => { - try{ - const response = await api.get(`/raidGroup/game/${gameId}/count?${searchParams}`); + const response = await api.get(`/raidGroup/game/${gameId}/count?${searchParams}`); - if(response.data.errors){ - throw new Error(response.data.errors.join(", ")); - } - - return response.data.count as number; - } - catch(error){ - if(error instanceof AxiosError && error.response?.data.errors){ - throw new Error(error.response?.data.errors.join(", ")); - } - else{ - throw error; - } - } + return (response.data as Counter).count; } }); } @@ -167,23 +97,9 @@ export function useGetRaidGroupsByAccount(accountId: string, page: number, pageS params.append("searchTerm", searchTerm); } - try{ - const response = await api.get(`/raidGroup/account/${accountId}?${params}`); + const response = await api.get(`/raidGroup/account/${accountId}?${params}`); - if(response.data.errors){ - throw new Error(response.data.errors.join(", ")); - } - - return response.data as RaidGroup[]; - } - catch(error){ - if(error instanceof AxiosError && error.response?.data.errors){ - throw new Error(error.response?.data.errors.join(", ")); - } - else{ - throw error; - } - } + return response.data as RaidGroup[]; } }); } @@ -198,23 +114,9 @@ export function useGetRaidGroupsCountByAccount(accountId: string, searchTerm?: s return useQuery({ queryKey: ["raidGroups", accountId, "count", searchTerm], queryFn: async () => { - try{ - const response = await api.get(`/raidGroup/account/${accountId}/count?${searchParams}`); + const response = await api.get(`/raidGroup/account/${accountId}/count?${searchParams}`); - if(response.data.errors){ - throw new Error(response.data.errors.join(", ")); - } - - return response.data.count as number; - } - catch(error){ - if(error instanceof AxiosError && error.response?.data.errors){ - throw new Error(error.response?.data.errors.join(", ")); - } - else{ - throw error; - } - } + return (response.data as Counter).count; } }); @@ -235,27 +137,13 @@ export function useCreateRaidGroup(){ formData.append("raidGroupName", raidGroupName); formData.append("gameId", gameId); - try{ - const response = await api.post( - "/raidGroup", - formData - ); - - if(response.data.errors){ - throw new Error(response.data.errors.join(", ")); - } - } - catch(error){ - if(error instanceof AxiosError && error.response?.data.errors){ - throw new Error(error.response?.data.errors.join(", ")); - } - else{ - throw error; - } - } + await api.post( + "/raidGroup", + formData + ); }, onSuccess: () => { - queryClient.invalidateQueries({ queryKey: ["raidGroups"] }); + void queryClient.invalidateQueries({ queryKey: ["raidGroups"] }); } }); } @@ -277,24 +165,10 @@ export function useUpdateRaidGroup(){ formData.append("raidGroupIcon", raidGroup.raidGroupIcon); } - try{ - const response = await api.put(`/raidGroup/${raidGroup.raidGroupId}`, formData); - - if(response.data.errors){ - throw new Error(response.data.errors.join(", ")); - } - } - catch(error){ - if(error instanceof AxiosError && error.response?.data.errors){ - throw new Error(error.response?.data.errors.join(", ")); - } - else{ - throw error; - } - } + await api.put(`/raidGroup/${raidGroup.raidGroupId}`, formData); }, onSuccess: () => { - queryClient.invalidateQueries({ queryKey: ["raidGroups"] }); + void queryClient.invalidateQueries({ queryKey: ["raidGroups"] }); } }); } @@ -306,24 +180,10 @@ export function useDeleteRaidGroup(){ return useMutation({ mutationKey: ["deleteRaidGroup"], mutationFn: async (raidGroupId: string) => { - try{ - const response = await api.delete(`/raidGroup/${raidGroupId}`); - - if(response.data.errors){ - throw new Error(response.data.errors.join(", ")); - } - } - catch(error){ - if(error instanceof AxiosError && error.response?.data.errors){ - throw new Error(error.response?.data.errors.join(", ")); - } - else{ - throw error; - } - } + await api.delete(`/raidGroup/${raidGroupId}`); }, onSuccess: () => { - queryClient.invalidateQueries({ queryKey: ["raidGroups"] }); + void queryClient.invalidateQueries({ queryKey: ["raidGroups"] }); } }); } diff --git a/src/hooks/RaidGroupRequestHooks.ts b/src/hooks/RaidGroupRequestHooks.ts index 0ad8417..5e07a94 100644 --- a/src/hooks/RaidGroupRequestHooks.ts +++ b/src/hooks/RaidGroupRequestHooks.ts @@ -1,8 +1,8 @@ +import { Counter } from "@/interface/Counters"; import { RaidGroupPermissionType } from "@/interface/RaidGroup"; import { RaidGroupRequest } from "@/interface/RaidGroupRequest"; -import { api } from "@/util/AxiosUtil"; +import api from "@/util/AxiosUtil"; import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; -import { AxiosError } from "axios"; export function useGetRaidGroupRequests(raidGroupId: string, page: number, pageSize: number, searchTerm?: string){ @@ -16,23 +16,9 @@ export function useGetRaidGroupRequests(raidGroupId: string, page: number, pageS return useQuery({ queryKey: ["raidGroupRequest", raidGroupId, {page, pageSize, searchTerm}], queryFn: async () => { - try{ - const response = await api.get(`/raidGroup/${raidGroupId}/raidGroupRequest?${searchParams}`); + const response = await api.get(`/raidGroup/${raidGroupId}/raidGroupRequest?${searchParams}`); - if(response.data.errors){ - throw new Error(response.data.errors.join(", ")); - } - - return response.data as RaidGroupRequest[]; - } - catch(error){ - if(error instanceof AxiosError && error.response?.data.errors){ - throw new Error(error.response?.data.errors.join(", ")); - } - else{ - throw error; - } - } + return response.data as RaidGroupRequest[]; }, enabled: !!raidGroupId && raidGroupId !== "" }); @@ -47,23 +33,9 @@ export function useGetRaidGroupRequestCount(raidGroupId?: string, searchTerm?: s return useQuery({ queryKey: ["raidGroupRequest", raidGroupId, "count", searchTerm], queryFn: async () => { - try{ - const response = await api.get(`/raidGroup/${raidGroupId}/raidGroupRequest/count?${searchParams}`); + const response = await api.get(`/raidGroup/${raidGroupId}/raidGroupRequest/count?${searchParams}`); - if(response.data.errors){ - throw new Error(response.data.errors.join(", ")); - } - - return response.data.count as number; - } - catch(error){ - if(error instanceof AxiosError && error.response?.data.errors){ - throw new Error(error.response?.data.errors.join(", ")); - } - else{ - throw error; - } - } + return (response.data as Counter).count; }, enabled: !!raidGroupId && raidGroupId !== "" }); @@ -76,24 +48,10 @@ export function useCreateRaidGroupRequest(raidGroupId: string){ return useMutation({ mutationKey: ["raidGroupRequest", raidGroupId], mutationFn: async (requestMessage: string) => { - try{ - const response = await api.post(`/raidGroup/${raidGroupId}/raidGroupRequest`, {requestMessage}); - - if(response.data.errors){ - throw new Error(response.data.errors.join(", ")); - } - } - catch(error){ - if(error instanceof AxiosError && error.response?.data.errors){ - throw new Error(error.response?.data.errors.join(", ")); - } - else{ - throw error; - } - } + await api.post(`/raidGroup/${raidGroupId}/raidGroupRequest`, {requestMessage}); }, onSuccess: () => { - queryClient.invalidateQueries({ queryKey: ["raidGroupRequest", raidGroupId] }); + void queryClient.invalidateQueries({ queryKey: ["raidGroupRequest", raidGroupId] }); } }); } @@ -104,24 +62,10 @@ export function useResolveRaidGroupRequest(raidGroupId: string, raidGroupRequest return useMutation({ mutationKey: ["raidGroupRequest", raidGroupId, raidGroupRequestId], mutationFn: async (permission: RaidGroupPermissionType) => { - try{ - const response = await api.put(`/raidGroup/${raidGroupId}/raidGroupRequest/${raidGroupRequestId}/resolve`, {resolution: permission}); - - if(response.data.errors){ - throw new Error(response.data.errors.join(", ")); - } - } - catch(error){ - if(error instanceof AxiosError && error.response?.data.errors){ - throw new Error(error.response?.data.errors.join(", ")); - } - else{ - throw error; - } - } + await api.put(`/raidGroup/${raidGroupId}/raidGroupRequest/${raidGroupRequestId}/resolve`, {resolution: permission}); }, onSuccess: () => { - queryClient.invalidateQueries({ queryKey: ["raidGroupRequest", raidGroupId] }); + void queryClient.invalidateQueries({ queryKey: ["raidGroupRequest", raidGroupId] }); } }); @@ -133,24 +77,10 @@ export function useDeleteRaidGroupRequest(raidGroupId: string, raidGroupRequestI return useMutation({ mutationKey: ["raidGroupRequest", raidGroupId, raidGroupRequestId], mutationFn: async () => { - try{ - const response = await api.delete(`/raidGroup/${raidGroupId}/raidGroupRequest/${raidGroupRequestId}`); - - if(response.data.errors){ - throw new Error(response.data.errors.join(", ")); - } - } - catch(error){ - if(error instanceof AxiosError && error.response?.data.errors){ - throw new Error(error.response?.data.errors.join(", ")); - } - else{ - throw error; - } - } + await api.delete(`/raidGroup/${raidGroupId}/raidGroupRequest/${raidGroupRequestId}`); }, onSuccess: () => { - queryClient.invalidateQueries({ queryKey: ["raidGroupRequest", raidGroupId] }); + void queryClient.invalidateQueries({ queryKey: ["raidGroupRequest", raidGroupId] }); } }); } diff --git a/src/hooks/RaidInstanceHooks.ts b/src/hooks/RaidInstanceHooks.ts index 8e2e3a4..c3cfb11 100644 --- a/src/hooks/RaidInstanceHooks.ts +++ b/src/hooks/RaidInstanceHooks.ts @@ -1,31 +1,17 @@ +import { Counter } from "@/interface/Counters"; import { RaidInstance } from "@/interface/RaidInstance"; import { RaidInstancePersonCharacterXref } from "@/interface/RaidInstancePersonCharacterXref"; -import { api } from "@/util/AxiosUtil"; +import api from "@/util/AxiosUtil"; import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; -import { AxiosError } from "axios"; export function useGetRaidInstance(raidInstanceId: string, raidGroupId: string){ return useQuery({ queryKey: ["raidInstances", raidInstanceId, raidGroupId], queryFn: async () => { - try{ - const response = await api.get(`/raidGroup/${raidGroupId}/raidInstance/${raidInstanceId}`); + const response = await api.get(`/raidGroup/${raidGroupId}/raidInstance/${raidInstanceId}`); - if(response.data.errors){ - throw new Error(response.data.errors.join(", ")); - } - - return response.data as RaidInstance; - } - catch(error){ - if(error instanceof AxiosError && error.response?.data.errors){ - throw new Error(error.response?.data.errors.join(", ")); - } - else{ - throw error; - } - } + return response.data as RaidInstance; }, enabled: !!raidInstanceId && !!raidGroupId }); @@ -42,23 +28,9 @@ export function useGetRaidInstancesByRaidGroup(raidGroupId: string, page: number params.append("searchTerm", searchTerm); } - try{ - const response = await api.get(`/raidGroup/${raidGroupId}/raidInstance?${params}`); + const response = await api.get(`/raidGroup/${raidGroupId}/raidInstance?${params}`); - if(response.data.errors){ - throw new Error(response.data.errors.join(", ")); - } - - return response.data as RaidInstance[]; - } - catch(error){ - if(error instanceof AxiosError && error.response?.data.errors){ - throw new Error(error.response?.data.errors.join(", ")); - } - else{ - throw error; - } - } + return response.data as RaidInstance[]; } }); } @@ -73,23 +45,9 @@ export function useGetRaidInstancesByRaidGroupCount(raidGroupId: string, searchT params.append("searchTerm", searchTerm); } - try{ - const response = await api.get(`/raidGroup/${raidGroupId}/raidInstance/count?${params}`); + const response = await api.get(`/raidGroup/${raidGroupId}/raidInstance/count?${params}`); - if(response.data.errors){ - throw new Error(response.data.errors.join(", ")); - } - - return response.data.count as number; - } - catch(error){ - if(error instanceof AxiosError && error.response?.data.errors){ - throw new Error(error.response?.data.errors.join(", ")); - } - else{ - throw error; - } - } + return (response.data as Counter).count; } }); } @@ -102,26 +60,12 @@ export function useCreateRaidInstance(raidGroupId: string){ return useMutation({ mutationKey: ["createRaidInstance", raidGroupId], mutationFn: async (raidInstance: RaidInstance) => { - try{ const response = await api.post(`/raidGroup/${raidGroupId}/raidInstance`, raidInstance); - if(response.data.errors){ - throw new Error(response.data.errors.join(", ")); - } - - return response.data.raidInstanceId as string; - } - catch(error){ - if(error instanceof AxiosError && error.response?.data.errors){ - throw new Error(error.response?.data.errors.join(", ")); - } - else{ - throw error; - } - } + return (response.data as RaidInstance).raidInstanceId; }, onSuccess: () => { - queryClient.invalidateQueries({ queryKey: ["raidInstances"] }); + void queryClient.invalidateQueries({ queryKey: ["raidInstances"] }); } }); } @@ -133,24 +77,10 @@ export function useUpdateRaidInstance(raidGroupId: string){ return useMutation({ mutationKey: ["updateRaidInstance", raidGroupId], mutationFn: async (raidInstance: RaidInstance) => { - try{ - const response = await api.put(`/raidGroup/${raidGroupId}/raidInstance/${raidInstance.raidInstanceId}`, raidInstance); - - if(response.data.errors){ - throw new Error(response.data.errors.join(", ")); - } - } - catch(error){ - if(error instanceof AxiosError && error.response?.data.errors){ - throw new Error(error.response?.data.errors.join(", ")); - } - else{ - throw error; - } - } + await api.put(`/raidGroup/${raidGroupId}/raidInstance/${raidInstance.raidInstanceId}`, raidInstance); }, onSuccess: () => { - queryClient.invalidateQueries({ queryKey: ["raidInstances"] }); + void queryClient.invalidateQueries({ queryKey: ["raidInstances"] }); } }); } @@ -159,21 +89,7 @@ export function useUpdateRaidInstanceNoInvalidation(raidGroupId: string){ return useMutation({ mutationKey: ["updateRaidInstance", raidGroupId], mutationFn: async (raidInstance: RaidInstance) => { - try{ - const response = await api.put(`/raidGroup/${raidGroupId}/raidInstance/${raidInstance.raidInstanceId}`, raidInstance); - - if(response.data.errors){ - throw new Error(response.data.errors.join(", ")); - } - } - catch(error){ - if(error instanceof AxiosError && error.response?.data.errors){ - throw new Error(error.response?.data.errors.join(", ")); - } - else{ - throw error; - } - } + await api.put(`/raidGroup/${raidGroupId}/raidInstance/${raidInstance.raidInstanceId}`, raidInstance); } }); } @@ -185,24 +101,10 @@ export function useDeleteRaidInstance(raidGroupId: string, raidInstanceId: strin return useMutation({ mutationKey: ["deleteRaidInstance", raidGroupId, raidInstanceId], mutationFn: async () => { - try{ - const response = await api.delete(`/raidGroup/${raidGroupId}/raidInstance/${raidInstanceId}`); - - if(response.data.errors){ - throw new Error(response.data.errors.join(", ")); - } - } - catch(error){ - if(error instanceof AxiosError && error.response?.data.errors){ - throw new Error(error.response?.data.errors.join(", ")); - } - else{ - throw error; - } - } + await api.delete(`/raidGroup/${raidGroupId}/raidInstance/${raidInstanceId}`); }, onSuccess: () => { - queryClient.invalidateQueries({ queryKey: ["raidInstances"] }); + void queryClient.invalidateQueries({ queryKey: ["raidInstances"] }); } }); } @@ -212,23 +114,9 @@ export function useGetRaidInstancePersonCharacterXrefs(raidGroupId?: string, rai return useQuery({ queryKey: ["raidInstancePersonCharacterXrefs", raidGroupId, raidInstanceId], queryFn: async () => { - try{ - const response = await api.get(`/raidGroup/${raidGroupId}/raidInstance/${raidInstanceId}/personCharacterXref`); + const response = await api.get(`/raidGroup/${raidGroupId}/raidInstance/${raidInstanceId}/personCharacterXref`); - if(response.data.errors){ - throw new Error(response.data.errors.join(", ")); - } - - return response.data as RaidInstancePersonCharacterXref[]; - } - catch(error){ - if(error instanceof AxiosError && error.response?.data.errors){ - throw new Error(error.response?.data.errors.join(", ")); - } - else{ - throw error; - } - } + return response.data as RaidInstancePersonCharacterXref[]; }, enabled: !!raidGroupId && !!raidInstanceId }); @@ -241,24 +129,10 @@ export function useUpdateRaidInstancePersonCharacterXrefs(raidGroupId?: string, return useMutation({ mutationKey: ["updateRaidInstancePersonCharacterXrefs", raidGroupId, raidInstanceId], mutationFn: async (raidInstancePersonCharacterXrefs: RaidInstancePersonCharacterXref[]) => { - try{ - const response = await api.post(`/raidGroup/${raidGroupId}/raidInstance/${raidInstanceId}/personCharacterXref`, raidInstancePersonCharacterXrefs); - - if(response.data.errors){ - throw new Error(response.data.errors.join(", ")); - } - } - catch(error){ - if(error instanceof AxiosError && error.response?.data.errors){ - throw new Error(error.response?.data.errors.join(", ")); - } - else{ - throw error; - } - } + await api.post(`/raidGroup/${raidGroupId}/raidInstance/${raidInstanceId}/personCharacterXref`, raidInstancePersonCharacterXrefs); }, onSuccess: () => { - queryClient.invalidateQueries({ queryKey: ["raidInstancePersonCharacterXrefs", raidGroupId, raidInstanceId] }); + void queryClient.invalidateQueries({ queryKey: ["raidInstancePersonCharacterXrefs", raidGroupId, raidInstanceId] }); } }); } diff --git a/src/hooks/RaidLayoutHooks.ts b/src/hooks/RaidLayoutHooks.ts index 99fa43f..b32e8db 100644 --- a/src/hooks/RaidLayoutHooks.ts +++ b/src/hooks/RaidLayoutHooks.ts @@ -1,30 +1,16 @@ +import { Counter } from "@/interface/Counters"; import { RaidLayout, RaidLayoutClassGroupXref } from "@/interface/RaidLayout"; -import { api } from "@/util/AxiosUtil"; +import api from "@/util/AxiosUtil"; import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; -import { AxiosError } from "axios"; export function useGetRaidLayout(raidGroupId?: string, raidLayoutId?: string){ return useQuery({ queryKey: ["raidLayout", raidGroupId, raidLayoutId], queryFn: async () => { - try{ - const response = await api.get(`/raidGroup/${raidGroupId}/raidLayout/${raidLayoutId}`); + const response = await api.get(`/raidGroup/${raidGroupId}/raidLayout/${raidLayoutId}`); - if(response.data.errors){ - throw new Error(response.data.errors.join(", ")); - } - - return response.data as RaidLayout; - } - catch(error){ - if(error instanceof AxiosError && error.response?.data.errors){ - throw new Error(error.response?.data.errors.join(", ")); - } - else{ - throw error; - } - } + return response.data as RaidLayout; }, enabled: !!raidGroupId && !!raidLayoutId }); @@ -41,23 +27,9 @@ export function useGetRaidLayoutsByRaidGroup(raidGroupId: string, page: number, params.append("searchTerm", searchTerm); } - try{ - const response = await api.get(`/raidGroup/${raidGroupId}/raidLayout?${params}`); + const response = await api.get(`/raidGroup/${raidGroupId}/raidLayout?${params}`); - if(response.data.errors){ - throw new Error(response.data.errors.join(", ")); - } - - return response.data as RaidLayout[]; - } - catch(error){ - if(error instanceof AxiosError && error.response?.data.errors){ - throw new Error(error.response?.data.errors.join(", ")); - } - else{ - throw error; - } - } + return response.data as RaidLayout[]; } }); } @@ -71,23 +43,9 @@ export function useGetRaidLayoutsByRaidGroupCount(raidGroupId: string, searchTer params.append("searchTerm", searchTerm); } - try{ - const response = await api.get(`/raidGroup/${raidGroupId}/raidLayout/count?${params}`); + const response = await api.get(`/raidGroup/${raidGroupId}/raidLayout/count?${params}`); - if(response.data.errors){ - throw new Error(response.data.errors.join(", ")); - } - - return response.data.count as number; - } - catch(error){ - if(error instanceof AxiosError && error.response?.data.errors){ - throw new Error(error.response?.data.errors.join(", ")); - } - else{ - throw error; - } - } + return (response.data as Counter).count; } }); } @@ -99,29 +57,15 @@ export function useCreateRaidLayout(raidGroupId: string){ return useMutation({ mutationKey: ["createRaidLayout", raidGroupId], mutationFn: async ({raidLayout, raidLayoutClassGroupXrefs}:{raidLayout: RaidLayout; raidLayoutClassGroupXrefs: RaidLayoutClassGroupXref[];}) => { - try{ - const response = await api.post(`/raidGroup/${raidGroupId}/raidLayout`, - { - raidLayout, - raidLayoutClassGroupXrefs - } - ); - - if(response.data.errors){ - throw new Error(response.data.errors.join(", ")); + await api.post(`/raidGroup/${raidGroupId}/raidLayout`, + { + raidLayout, + raidLayoutClassGroupXrefs } - } - catch(error){ - if(error instanceof AxiosError && error.response?.data.errors){ - throw new Error(error.response?.data.errors.join(", ")); - } - else{ - throw error; - } - } + ); }, onSuccess: () => { - queryClient.invalidateQueries({ queryKey: ["raidLayouts", raidGroupId] }); + void queryClient.invalidateQueries({ queryKey: ["raidLayouts", raidGroupId] }); } }); } @@ -133,30 +77,16 @@ export function useUpdateRaidLayout(raidGroupId: string){ return useMutation({ mutationKey: ["updateRaidLayout", raidGroupId], mutationFn: async ({raidLayout, raidLayoutClassGroupXrefs}:{raidLayout: RaidLayout; raidLayoutClassGroupXrefs: RaidLayoutClassGroupXref[];}) => { - try{ - const response = await api.put(`/raidGroup/${raidGroupId}/raidLayout/${raidLayout.raidLayoutId}`, - { - raidLayout, - raidLayoutClassGroupXrefs - } - ); - - if(response.data.errors){ - throw new Error(response.data.errors.join(", ")); + await api.put(`/raidGroup/${raidGroupId}/raidLayout/${raidLayout.raidLayoutId}`, + { + raidLayout, + raidLayoutClassGroupXrefs } - } - catch(error){ - if(error instanceof AxiosError && error.response?.data.errors){ - throw new Error(error.response?.data.errors.join(", ")); - } - else{ - throw error; - } - } + ); }, onSuccess: () => { - queryClient.invalidateQueries({ queryKey: ["raidLayouts", raidGroupId] }); - queryClient.invalidateQueries({ queryKey: ["classGroups", "raidLayout"] }); + void queryClient.invalidateQueries({ queryKey: ["raidLayouts", raidGroupId] }); + void queryClient.invalidateQueries({ queryKey: ["classGroups", "raidLayout"] }); } }); } @@ -168,24 +98,10 @@ export function useDeleteRaidLayout(raidGroupId: string, raidLayoutId: string){ return useMutation({ mutationKey: ["deleteRaidLayout", raidGroupId, raidLayoutId], mutationFn: async () => { - try{ - const response = await api.delete(`/raidGroup/${raidGroupId}/raidLayout/${raidLayoutId}`); - - if(response.data.errors){ - throw new Error(response.data.errors.join(", ")); - } - } - catch(error){ - if(error instanceof AxiosError && error.response?.data.errors){ - throw new Error(error.response?.data.errors.join(", ")); - } - else{ - throw error; - } - } + await api.delete(`/raidGroup/${raidGroupId}/raidLayout/${raidLayoutId}`) }, onSuccess: () => { - queryClient.invalidateQueries({ queryKey: ["raidLayouts", raidGroupId] }); + void queryClient.invalidateQueries({ queryKey: ["raidLayouts", raidGroupId] }); } }); } diff --git a/src/interface/Account.ts b/src/interface/Account.ts index 640a752..11e88c9 100644 --- a/src/interface/Account.ts +++ b/src/interface/Account.ts @@ -22,4 +22,5 @@ export interface Account { refreshToken?: string; refreshTokenExpiration?: Date; accountStatus: AccountStatus; + token?: string; } diff --git a/src/interface/Counters.ts b/src/interface/Counters.ts new file mode 100644 index 0000000..378ec00 --- /dev/null +++ b/src/interface/Counters.ts @@ -0,0 +1,3 @@ +export interface Counter { + count: number; +} diff --git a/src/interface/Errors.ts b/src/interface/Errors.ts new file mode 100644 index 0000000..4d5c6ea --- /dev/null +++ b/src/interface/Errors.ts @@ -0,0 +1,4 @@ +export interface ResponseError { + status: string; + errors: string[]; +} \ No newline at end of file diff --git a/src/interface/Token.ts b/src/interface/Token.ts new file mode 100644 index 0000000..8e21d0d --- /dev/null +++ b/src/interface/Token.ts @@ -0,0 +1,11 @@ +export interface AuthToken { + iss: string; + iat: number; + exp: number; + sub: string; + accountId: string; + accountPermissions: string; + raidGroupPermissions: string; + gamePermissions: string; + raidGroupRequests: string; +} diff --git a/src/main.tsx b/src/main.tsx index 02ae970..a1527f9 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -1,11 +1,11 @@ -import { QueryClient, QueryClientProvider } from "@tanstack/react-query" -import { StrictMode } from 'react' -import { createRoot } from 'react-dom/client' -import App from './App.tsx' -import './index.css' -import { AuthProvider } from './providers/AuthProvider.tsx' -import { ThemeProvider } from './providers/ThemeProvider.tsx' -import { TimedModalProvider } from "./providers/TimedModalProvider.tsx" +import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; +import { StrictMode } from "react"; +import { createRoot } from "react-dom/client"; +import App from "./App.tsx"; +import "./index.css"; +import { AuthProvider } from "./providers/components/AuthProviderComponent.tsx"; +import { ThemeProvider } from "./providers/components/ThemeProviderComponent.tsx"; +import { TimedModalProvider } from "./providers/components/TimedModalProviderComponent.tsx"; const queryClient = new QueryClient(); diff --git a/src/pages/protected/LogoutPage.tsx b/src/pages/protected/LogoutPage.tsx index 06a3480..00a1ee2 100644 --- a/src/pages/protected/LogoutPage.tsx +++ b/src/pages/protected/LogoutPage.tsx @@ -1,6 +1,6 @@ import PrimaryButton from "@/components/button/PrimaryButton"; import { useAuth } from "@/providers/AuthProvider"; -import { api } from "@/util/AxiosUtil"; +import api from "@/util/AxiosUtil"; import { useNavigate } from "react-router"; @@ -10,14 +10,9 @@ export default function LogoutPage(){ const logout = async () => { - const response = await api.get("/auth/logout"); - if(response.status === 200){ - reset(); - navigate("/"); - } - else{ - //TODO: Handle error - } + await api.get("/auth/logout"); + reset(); + void navigate("/"); } @@ -26,7 +21,7 @@ export default function LogoutPage(){ className="mt-8" > void logout} > Logout diff --git a/src/pages/protected/RaidInstancePage.tsx b/src/pages/protected/RaidInstancePage.tsx index 9ed7d37..e1ef1cb 100644 --- a/src/pages/protected/RaidInstancePage.tsx +++ b/src/pages/protected/RaidInstancePage.tsx @@ -2,7 +2,7 @@ import PrimaryButton from "@/components/button/PrimaryButton"; import TutorialComponent from "@/components/TutorialComponent"; import { TutorialStatus } from "@/interface/AccountTutorialStatus"; import { useAuth } from "@/providers/AuthProvider"; -import RaidInstanceLayoutProvider from "@/providers/RaidInstanceLayoutProvider"; +import RaidInstanceLayoutProvider from "@/providers/components/RaidInstanceLayoutProviderComponent"; import RaidInstanceCreatorUI from "@/ui/raidInstance/creator/RaidInstanceCreatorUI"; import { instanceTutorialSteps } from "@/util/TutorialUtil"; import { BsArrowLeft } from "react-icons/bs"; @@ -53,7 +53,7 @@ export default function RaidInstancePage(){ > navigator(`/raidGroup/${raidGroupId}`)} + onClick={() => void navigator(`/raidGroup/${raidGroupId}`)} > { if(response.status === 200){ addSuccessMessage("Logged in successfully"); - const json = await response.json(); + const json = await response.json() as Account; setTokenData(json); - navigate("/raidGroup"); + void navigate("/raidGroup"); } else{ - addErrorMessage("Failed to log in: " + ((await response.json()).errors as string[]).join(",\n")); + addErrorMessage("Failed to log in: " + (await response.json() as ResponseError).errors.join(",\n")); } }) .catch(error => { diff --git a/src/pages/public/SignupPage.tsx b/src/pages/public/SignupPage.tsx index decab24..ec8f7d7 100644 --- a/src/pages/public/SignupPage.tsx +++ b/src/pages/public/SignupPage.tsx @@ -48,7 +48,7 @@ export default function SignupPage(){ if(signupQuery.status === "success"){ addSuccessMessage("Signed up successfully"); - navigate("/login"); + void navigate("/login"); } else if(signupQuery.status === "error"){ addErrorMessage("Failed to signup: " + signupQuery.error.message); diff --git a/src/providers/AuthProvider.tsx b/src/providers/AuthProvider.tsx index 509a482..f1b420b 100644 --- a/src/providers/AuthProvider.tsx +++ b/src/providers/AuthProvider.tsx @@ -1,23 +1,21 @@ -import { useGetTutorialsStatus, useUpdateTutorialsStatus } from "@/hooks/AccountHooks"; +import { Account } from "@/interface/Account"; import { AccountPermission } from "@/interface/AccountPermission"; import { AccountTutorialStatus } from "@/interface/AccountTutorialStatus"; import { GamePermission } from "@/interface/GamePermission"; import { RaidGroupPermission } from "@/interface/RaidGroupPermission"; import { RaidGroupRequest } from "@/interface/RaidGroupRequest"; -import { api } from "@/util/AxiosUtil"; -import { createContext, useCallback, useContext, useEffect, useLayoutEffect, useMemo, useState } from "react"; -import { Navigate, Outlet } from "react-router"; +import { createContext, useContext } from "react"; -type AuthProviderProps = { +export type AuthProviderProps = { children: React.ReactNode; jwtStorageKey?: string; refreshTokenStorageKey?: string; } -type AuthProviderState = { - jwt: string | null; - setJwt: (token: string | null) => void; +export type AuthProviderState = { + jwt: string | null | undefined; + setJwt: (token: string | null | undefined) => void; expiration: Date | null; setExpiration: (expiration: Date | null) => void; accountId: string | null; @@ -28,9 +26,7 @@ type AuthProviderState = { tutorialsStatus: AccountTutorialStatus; setTutorialsStatus: (tutorialsStatus: AccountTutorialStatus) => void; reset: () => void; - /* eslint-disable @typescript-eslint/no-explicit-any */ - setTokenData: (data: any) => void; - /* eslint-enable @typescript-eslint/no-explicit-any */ + setTokenData: (data: Account) => void; } const initialState: AuthProviderState = { @@ -49,159 +45,7 @@ const initialState: AuthProviderState = { setTokenData: () => null } -const AuthContext = createContext(initialState); - - -export function AuthProvider({ - children -}: AuthProviderProps){ - const [ jwt, setJwt ] = useState(null); - const [ expiration, setExpiration ] = useState(null); - const [ firstFetch, setFirstFetch ] = useState(true); - const [ accountId, setAccountId ] = useState(null); - const [ accountPermissions, setAccountPermissions ] = useState([]); - const [ raidGroupPermissions, setRaidGroupPermissions ] = useState([]); - const [ gamePermissions, setGamePermissions ] = useState([]); - const [ raidGroupRequests, setRaidGroupRequests ] = useState([]); - const [ tutorialsStatus, setTutorialsStatus ] = useState({} as AccountTutorialStatus); - - - const tutorialsStatusQuery = useGetTutorialsStatus(accountId); - const { mutate: tutorialsStatusMutation } = useUpdateTutorialsStatus(); - - - /* eslint-disable @typescript-eslint/no-explicit-any */ - const setTokenData = useCallback((data: any) => { - setJwt(data.token); - const decodedToken = JSON.parse(atob(data.token.split(".")[1])); - //console.log("decodedToken = "); - //console.log(decodedToken); - setExpiration(new Date(decodedToken.exp * 1000)); - setFirstFetch(false); - setAccountId(decodedToken.accountId); - setAccountPermissions(JSON.parse(decodedToken.accountPermissions)); - setRaidGroupPermissions(JSON.parse(decodedToken.raidGroupPermissions)); - setGamePermissions(JSON.parse(decodedToken.gamePermissions)); - setRaidGroupRequests(JSON.parse(decodedToken.raidGroupRequests)); - }, [ setJwt, setExpiration, setFirstFetch, setAccountId, setAccountPermissions, setRaidGroupPermissions, setGamePermissions, setRaidGroupRequests ]); - /* eslint-enable @typescript-eslint/no-explicit-any */ - - const fetchToken = useCallback(async () => { - //console.log("Fetching token"); - try{ - const response = await api.get("/auth/refresh"); - //If the token is retrieved - if((response.status === 200) && (!response.data.errors)){ - setTokenData(response.data); - return response.data.token; - } - //If the token cannot be retrieved - else{ - setJwt(null); - setExpiration(null); - setFirstFetch(false); - } - } - //If the token cannot be retrieved - catch{ - setJwt(null); - setExpiration(null); - setFirstFetch(false); - } - }, [ setJwt, setExpiration, setFirstFetch, setTokenData ]); - - - //Add the token to all queries - useLayoutEffect(() => { - const authInterceptor = api.interceptors.request.use(async (config) => { - if(config.url?.endsWith("/auth/refresh")){ - return config; - } - let currentJwt = jwt; - const currentTime = new Date(); - currentTime.setSeconds(currentTime.getSeconds() + 5); - if((expiration) && (expiration <= currentTime) && (!config.url?.endsWith("/auth/refresh"))){ - currentJwt = await fetchToken(); - config.headers.Authorization = jwt ? `Bearer ${currentJwt}` : config.headers.Authorization; - } - config.headers.Authorization = jwt ? `Bearer ${currentJwt}` : config.headers.Authorization; - - return config; - }); - - return () => { api.interceptors.request.eject(authInterceptor); }; - }, [ jwt, expiration, fetchToken ]); - - //Try to get the token on page load - useEffect(() => { - fetchToken(); - }, [ fetchToken ]); - - //Update the tutorial status when fetched - useEffect(() => { - if(tutorialsStatusQuery.status === "success"){ - setTutorialsStatus(tutorialsStatusQuery.data); - } - }, [ tutorialsStatusQuery.status, tutorialsStatusQuery.data ]); - - const updateTutorialsStatus = useCallback((newTutorialsStatus: AccountTutorialStatus) => { - setTutorialsStatus(newTutorialsStatus); - tutorialsStatusMutation(newTutorialsStatus); - }, [ setTutorialsStatus, tutorialsStatusMutation ]); - - const reset = useCallback(() => { - setJwt(null); - setExpiration(null); - setAccountId(null); - setAccountPermissions([]); - setRaidGroupPermissions([]); - setGamePermissions([]); - setRaidGroupRequests([]); - setTutorialsStatus({} as AccountTutorialStatus); - }, [ setJwt, setExpiration, setAccountId, setAccountPermissions, setRaidGroupPermissions, setGamePermissions, setRaidGroupRequests, setTutorialsStatus ]); - - - const currentTokens = useMemo(() => ({ - jwt, setJwt, - expiration, setExpiration, - accountId, - accountPermissions, - raidGroupPermissions, - gamePermissions, - raidGroupRequests, - tutorialsStatus, setTutorialsStatus: updateTutorialsStatus, - reset, setTokenData - }), [ jwt, expiration, accountId, accountPermissions, raidGroupPermissions, gamePermissions, raidGroupRequests, tutorialsStatus, updateTutorialsStatus, reset, setTokenData ]); - - - //TODO: Return a spinner while the first token is being fetched - if(firstFetch){ - return ( -
- Loading... -
- ); - } - - - return ( - - {children} - - ); -} - -export function ProtectedRoute(){ - const { jwt } = useAuth(); - - if(!jwt){ - return ; - } - - return ; -} +export const AuthContext = createContext(initialState); export const useAuth = () => { diff --git a/src/providers/RaidInstanceLayoutProvider.ts b/src/providers/RaidInstanceLayoutProvider.ts new file mode 100644 index 0000000..990f0c3 --- /dev/null +++ b/src/providers/RaidInstanceLayoutProvider.ts @@ -0,0 +1,58 @@ +import { ClassGroup } from "@/interface/ClassGroup"; +import { Person } from "@/interface/Person"; +import { PersonCharacter } from "@/interface/PersonCharacter"; +import { RaidGroup } from "@/interface/RaidGroup"; +import { RaidInstance } from "@/interface/RaidInstance"; +import { RaidInstancePersonCharacterXref } from "@/interface/RaidInstancePersonCharacterXref"; +import { RaidLayout } from "@/interface/RaidLayout"; +import { createContext, useContext } from "react"; + + +export interface RaidInstanceContextState { + raidInstance?: RaidInstance; + setRaidInstance: React.Dispatch>; + raidGroup?: RaidGroup; + classGroups: ClassGroup[]; + selectedClassGroups: (ClassGroup | null)[]; + setSelectedClassGroups: React.Dispatch>; + raidLayout?: RaidLayout; + setRaidLayout: React.Dispatch>; + raidLayouts: RaidLayout[]; + people: Person[]; + roster: Person[]; + setRoster: React.Dispatch>; + personCharacters: PersonCharacter[]; + setPersonCharacters: React.Dispatch>; + personCharacterXrefs: RaidInstancePersonCharacterXref[]; + setPersonCharacterXrefs: React.Dispatch>; +} + +export const RaidInstanceContext = createContext({ + raidInstance: {} as RaidInstance, + setRaidInstance: () => {}, + raidGroup: {} as RaidGroup, + classGroups: [], + selectedClassGroups: [], + setSelectedClassGroups: () => {}, + raidLayout: {} as RaidLayout, + setRaidLayout: () => {}, + raidLayouts: [], + people: [], + roster: [], + setRoster: () => {}, + personCharacters: [], + setPersonCharacters: () => {}, + personCharacterXrefs: [], + setPersonCharacterXrefs: () => {} +}); + + +export function useRaidInstanceContext(){ + const context = useContext(RaidInstanceContext); + + if(!context){ + throw new Error("useRaidInstanceContext must be used within a RaidInstanceLayoutProvider"); + } + + return context; +} diff --git a/src/providers/ThemeProvider.ts b/src/providers/ThemeProvider.ts new file mode 100644 index 0000000..c02b522 --- /dev/null +++ b/src/providers/ThemeProvider.ts @@ -0,0 +1,33 @@ +import { createContext, useContext } from "react"; + + +export type Theme = "dark" | "light" | "system"; + +export type ThemeProviderProps = { + children: React.ReactNode; + defaultTheme?: Theme; + storageKey?: string; +} + +type ThemeProviderState = { + theme: Theme; + setTheme: (theme: Theme) => void; +} + +const initialState: ThemeProviderState = { + theme: "system", + setTheme: () => null +} + +export const ThemeProviderContext = createContext(initialState); + + +export const useTheme = () => { + const context = useContext(ThemeProviderContext); + + if(context === undefined){ + throw new Error("useTheme must be used within a ThemeProvider"); + } + + return context; +} diff --git a/src/providers/TimedModalProvider.ts b/src/providers/TimedModalProvider.ts new file mode 100644 index 0000000..4d38b0f --- /dev/null +++ b/src/providers/TimedModalProvider.ts @@ -0,0 +1,28 @@ +import { createContext, useContext } from "react"; + + +type TimedModalProviderState = { + addMessage: (message: React.ReactNode, timeout: number) => void; + addSuccessMessage: (message: string) => void; + addErrorMessage: (message: string) => void; +} + + +const initialState: TimedModalProviderState = { + addMessage: () => null, + addSuccessMessage: () => null, + addErrorMessage: () => null +} + +export const TimedModalProviderContext = createContext(initialState); + + +export const useTimedModal = () => { + const context = useContext(TimedModalProviderContext); + + if(context === undefined){ + throw new Error("useTimeModal must be used within a TimedModalProvider"); + } + + return context; +} diff --git a/src/providers/components/AuthProviderComponent.tsx b/src/providers/components/AuthProviderComponent.tsx new file mode 100644 index 0000000..8e3565f --- /dev/null +++ b/src/providers/components/AuthProviderComponent.tsx @@ -0,0 +1,154 @@ +import { useGetTutorialsStatus, useUpdateTutorialsStatus } from "@/hooks/AccountHooks"; +import { Account } from "@/interface/Account"; +import { AccountPermission } from "@/interface/AccountPermission"; +import { AccountTutorialStatus } from "@/interface/AccountTutorialStatus"; +import { GamePermission } from "@/interface/GamePermission"; +import { RaidGroupPermission } from "@/interface/RaidGroupPermission"; +import { RaidGroupRequest } from "@/interface/RaidGroupRequest"; +import { AuthToken } from "@/interface/Token"; +import api from "@/util/AxiosUtil"; +import { useCallback, useEffect, useLayoutEffect, useMemo, useState } from "react"; +import { Navigate, Outlet } from "react-router"; +import { AuthContext, AuthProviderProps, useAuth } from "../AuthProvider"; + + +export function AuthProvider({ + children +}: AuthProviderProps){ + const [ jwt, setJwt ] = useState(null); + const [ expiration, setExpiration ] = useState(null); + const [ firstFetch, setFirstFetch ] = useState(true); + const [ accountId, setAccountId ] = useState(null); + const [ accountPermissions, setAccountPermissions ] = useState([]); + const [ raidGroupPermissions, setRaidGroupPermissions ] = useState([]); + const [ gamePermissions, setGamePermissions ] = useState([]); + const [ raidGroupRequests, setRaidGroupRequests ] = useState([]); + const [ tutorialsStatus, setTutorialsStatus ] = useState({} as AccountTutorialStatus); + + + const tutorialsStatusQuery = useGetTutorialsStatus(accountId); + const { mutate: tutorialsStatusMutation } = useUpdateTutorialsStatus(); + + + const setTokenData = useCallback((data: Account) => { + setJwt(data.token); + const decodedToken = JSON.parse(atob(data.token!.split(".")[1])) as AuthToken; + //console.log("decodedToken = "); + //console.log(decodedToken); + setExpiration(new Date(decodedToken.exp * 1000)); + setFirstFetch(false); + setAccountId(decodedToken.accountId); + setAccountPermissions(JSON.parse(decodedToken.accountPermissions) as AccountPermission[]); + setRaidGroupPermissions(JSON.parse(decodedToken.raidGroupPermissions) as RaidGroupPermission[]); + setGamePermissions(JSON.parse(decodedToken.gamePermissions) as GamePermission[]); + setRaidGroupRequests(JSON.parse(decodedToken.raidGroupRequests) as RaidGroupRequest[]); + }, [ setJwt, setExpiration, setFirstFetch, setAccountId, setAccountPermissions, setRaidGroupPermissions, setGamePermissions, setRaidGroupRequests ]); + + const fetchToken = useCallback(async () => { + //console.log("Fetching token"); + try{ + const response = await api.get("/auth/refresh"); + //If the token is retrieved + setTokenData(response.data as Account); + return (response.data as Account).token; + } + //If the token cannot be retrieved + catch{ + setJwt(null); + setExpiration(null); + setFirstFetch(false); + } + }, [ setJwt, setExpiration, setFirstFetch, setTokenData ]); + + + //Add the token to all queries + useLayoutEffect(() => { + const authInterceptor = api.interceptors.request.use(async (config) => { + if(config.url?.endsWith("/auth/refresh")){ + return config; + } + let currentJwt = jwt; + const currentTime = new Date(); + currentTime.setSeconds(currentTime.getSeconds() + 5); + if((expiration) && (expiration <= currentTime) && (!config.url?.endsWith("/auth/refresh"))){ + currentJwt = await fetchToken(); + config.headers.Authorization = jwt ? `Bearer ${currentJwt}` : config.headers.Authorization; + } + config.headers.Authorization = jwt ? `Bearer ${currentJwt}` : config.headers.Authorization; + + return config; + }); + + return () => { api.interceptors.request.eject(authInterceptor); }; + }, [ jwt, expiration, fetchToken ]); + + //Try to get the token on page load + useEffect(() => { + void fetchToken(); + }, [ fetchToken ]); + + //Update the tutorial status when fetched + useEffect(() => { + if(tutorialsStatusQuery.status === "success"){ + setTutorialsStatus(tutorialsStatusQuery.data); + } + }, [ tutorialsStatusQuery.status, tutorialsStatusQuery.data ]); + + const updateTutorialsStatus = useCallback((newTutorialsStatus: AccountTutorialStatus) => { + setTutorialsStatus(newTutorialsStatus); + tutorialsStatusMutation(newTutorialsStatus); + }, [ setTutorialsStatus, tutorialsStatusMutation ]); + + const reset = useCallback(() => { + setJwt(null); + setExpiration(null); + setAccountId(null); + setAccountPermissions([]); + setRaidGroupPermissions([]); + setGamePermissions([]); + setRaidGroupRequests([]); + setTutorialsStatus({} as AccountTutorialStatus); + }, [ setJwt, setExpiration, setAccountId, setAccountPermissions, setRaidGroupPermissions, setGamePermissions, setRaidGroupRequests, setTutorialsStatus ]); + + + const currentTokens = useMemo(() => ({ + jwt, setJwt, + expiration, setExpiration, + accountId, + accountPermissions, + raidGroupPermissions, + gamePermissions, + raidGroupRequests, + tutorialsStatus, setTutorialsStatus: updateTutorialsStatus, + reset, setTokenData + }), [ jwt, expiration, accountId, accountPermissions, raidGroupPermissions, gamePermissions, raidGroupRequests, tutorialsStatus, updateTutorialsStatus, reset, setTokenData ]); + + + //TODO: Return a spinner while the first token is being fetched + if(firstFetch){ + return ( +
+ Loading... +
+ ); + } + + + return ( + + {children} + + ); +} + +export function ProtectedRoute(){ + const { jwt } = useAuth(); + + if(!jwt){ + return ; + } + + return ; +} diff --git a/src/providers/ErrorBoundary.tsx b/src/providers/components/ErrorBoundary.tsx similarity index 100% rename from src/providers/ErrorBoundary.tsx rename to src/providers/components/ErrorBoundary.tsx diff --git a/src/providers/RaidInstanceLayoutProvider.tsx b/src/providers/components/RaidInstanceLayoutProviderComponent.tsx similarity index 76% rename from src/providers/RaidInstanceLayoutProvider.tsx rename to src/providers/components/RaidInstanceLayoutProviderComponent.tsx index dcc8c9f..98c97c8 100644 --- a/src/providers/RaidInstanceLayoutProvider.tsx +++ b/src/providers/components/RaidInstanceLayoutProviderComponent.tsx @@ -11,46 +11,8 @@ import { RaidGroup } from "@/interface/RaidGroup"; import { RaidInstance } from "@/interface/RaidInstance"; import { RaidInstancePersonCharacterXref } from "@/interface/RaidInstancePersonCharacterXref"; import { RaidLayout } from "@/interface/RaidLayout"; -import { createContext, useContext, useEffect, useMemo, useState } from "react"; - - -interface RaidInstanceContextState { - raidInstance?: RaidInstance; - setRaidInstance: React.Dispatch>; - raidGroup?: RaidGroup; - classGroups: ClassGroup[]; - selectedClassGroups: (ClassGroup | null)[]; - setSelectedClassGroups: React.Dispatch>; - raidLayout?: RaidLayout; - setRaidLayout: React.Dispatch>; - raidLayouts: RaidLayout[]; - people: Person[]; - roster: Person[]; - setRoster: React.Dispatch>; - personCharacters: PersonCharacter[]; - setPersonCharacters: React.Dispatch>; - personCharacterXrefs: RaidInstancePersonCharacterXref[]; - setPersonCharacterXrefs: React.Dispatch>; -} - -const RaidInstanceContext = createContext({ - raidInstance: {} as RaidInstance, - setRaidInstance: () => {}, - raidGroup: {} as RaidGroup, - classGroups: [], - selectedClassGroups: [], - setSelectedClassGroups: () => {}, - raidLayout: {} as RaidLayout, - setRaidLayout: () => {}, - raidLayouts: [], - people: [], - roster: [], - setRoster: () => {}, - personCharacters: [], - setPersonCharacters: () => {}, - personCharacterXrefs: [], - setPersonCharacterXrefs: () => {} -}); +import { useEffect, useMemo, useState } from "react"; +import { RaidInstanceContext, RaidInstanceContextState } from "../RaidInstanceLayoutProvider"; export default function RaidInstanceLayoutProvider({ @@ -181,14 +143,3 @@ export default function RaidInstanceLayoutProvider({ ); } - - -export function useRaidInstanceContext(){ - const context = useContext(RaidInstanceContext); - - if(!context){ - throw new Error("useRaidInstanceContext must be used within a RaidInstanceLayoutProvider"); - } - - return context; -} diff --git a/src/providers/ThemeProvider.tsx b/src/providers/components/ThemeProviderComponent.tsx similarity index 56% rename from src/providers/ThemeProvider.tsx rename to src/providers/components/ThemeProviderComponent.tsx index ea6b18c..ff1fbae 100644 --- a/src/providers/ThemeProvider.tsx +++ b/src/providers/components/ThemeProviderComponent.tsx @@ -1,25 +1,5 @@ -import { createContext, useContext, useEffect, useMemo, useState } from "react"; - - -type Theme = "dark" | "light" | "system"; - -type ThemeProviderProps = { - children: React.ReactNode; - defaultTheme?: Theme; - storageKey?: string; -} - -type ThemeProviderState = { - theme: Theme; - setTheme: (theme: Theme) => void; -} - -const initialState: ThemeProviderState = { - theme: "system", - setTheme: () => null -} - -const ThemeProviderContext = createContext(initialState); +import { useEffect, useMemo, useState } from "react"; +import { Theme, ThemeProviderContext, ThemeProviderProps } from "../ThemeProvider"; export function ThemeProvider({ @@ -59,13 +39,3 @@ export function ThemeProvider({ ); } - -export const useTheme = () => { - const context = useContext(ThemeProviderContext); - - if(context === undefined){ - throw new Error("useTheme must be used within a ThemeProvider"); - } - - return context; -} diff --git a/src/providers/TimedModalProvider.tsx b/src/providers/components/TimedModalProviderComponent.tsx similarity index 70% rename from src/providers/TimedModalProvider.tsx rename to src/providers/components/TimedModalProviderComponent.tsx index 42b91a3..e99d6d8 100644 --- a/src/providers/TimedModalProvider.tsx +++ b/src/providers/components/TimedModalProviderComponent.tsx @@ -2,23 +2,8 @@ import DangerMessage from "@/components/message/DangerMessage"; import SuccessMessage from "@/components/message/SuccessMessage"; import Modal from "@/components/modal/Modal"; import ModalBody from "@/components/modal/ModalBody"; -import { createContext, useContext, useEffect, useRef, useState } from "react"; - - -type TimedModalProviderState = { - addMessage: (message: React.ReactNode, timeout: number) => void; - addSuccessMessage: (message: string) => void; - addErrorMessage: (message: string) => void; -} - - -const initialState: TimedModalProviderState = { - addMessage: () => null, - addSuccessMessage: () => null, - addErrorMessage: () => null -} - -const TimedModalProviderContext = createContext(initialState); +import { useEffect, useRef, useState } from "react"; +import { TimedModalProviderContext } from "../TimedModalProvider"; export function TimedModalProvider({ @@ -92,13 +77,3 @@ export function TimedModalProvider({ ); } - -export const useTimedModal = () => { - const context = useContext(TimedModalProviderContext); - - if(context === undefined){ - throw new Error("useTimeModal must be used within a TimedModalProvider"); - } - - return context; -} diff --git a/src/ui/account/AccountsList.tsx b/src/ui/account/AccountsList.tsx index 3f54a8e..cb3447d 100644 --- a/src/ui/account/AccountsList.tsx +++ b/src/ui/account/AccountsList.tsx @@ -43,24 +43,25 @@ export default function AccountsList({ const headElements: React.ReactNode[] = [ -
+
Username
, isSiteAdmin(accountPermissions) && -
+
Email
, -
+
Login Date
, raidGroup && isRaidGroupAdmin(raidGroup?.raidGroupId ?? "", raidGroupPermissions ?? [], accountPermissions) && -
+
Raid Group Permission
, -
+
Status
,
Actions @@ -69,27 +70,30 @@ export default function AccountsList({ const bodyElements: React.ReactNode[][] = accounts.map((account) => [
{account.username}
, isSiteAdmin(accountPermissions) && -
+
{account.email}
,
{account.loginDate ? moment(account.loginDate).format("MM-DD-YYYY hh:mm a") : <> }
, raidGroup && isRaidGroupAdmin(raidGroup?.raidGroupId ?? "", raidGroupPermissions ?? [], accountPermissions) && -
+
{raidGroupPermissions.find((perm) => (perm.raidGroupId === raidGroup?.raidGroupId))?.permission}
, -
+
{account.accountStatus}
,
+
ID
, -
+
Username
, -
+
Email
, -
+
Login Date
, -
+
Status
,
Actions @@ -65,21 +66,27 @@ function AccountSkeleton(): React.ReactNode[]{ } const elements: React.ReactNode[] = [
,
,
,
,
,
 
diff --git a/src/ui/calendar/modals/CalendarEventModal.tsx b/src/ui/calendar/modals/CalendarEventModal.tsx index 19c955c..cf068c2 100644 --- a/src/ui/calendar/modals/CalendarEventModal.tsx +++ b/src/ui/calendar/modals/CalendarEventModal.tsx @@ -114,7 +114,7 @@ export default function CalendarEventModal({ addErrorMessage("Calendar event ID is required"); return; } - deleteCalendarEventMutate.mutate(calendarEvent as CalendarEvent); + deleteCalendarEventMutate.mutate(calendarEvent); } diff --git a/src/ui/classGroup/ClassGroupList.tsx b/src/ui/classGroup/ClassGroupList.tsx index 28c7ebb..92e7705 100644 --- a/src/ui/classGroup/ClassGroupList.tsx +++ b/src/ui/classGroup/ClassGroupList.tsx @@ -35,13 +35,14 @@ export default function ClassGroupList({ const headElements: React.ReactNode[] = [ -
+
Name
, -
+
Classes
,
Actions @@ -50,16 +51,18 @@ export default function ClassGroupList({ const bodyElements: React.ReactNode[][] = classGroups.map((classGroup) => [
{classGroup.classGroupName}
, -
+
,
+
Name
, -
+
Classes
,
Actions @@ -57,12 +58,15 @@ function ClassGroupSkeleton(): React.ReactNode[]{ const elements: React.ReactNode[] = [
,
,
 
diff --git a/src/ui/classGroup/modal/SelectClassGroupModal.tsx b/src/ui/classGroup/modal/SelectClassGroupModal.tsx index c2cb351..998160d 100644 --- a/src/ui/classGroup/modal/SelectClassGroupModal.tsx +++ b/src/ui/classGroup/modal/SelectClassGroupModal.tsx @@ -17,7 +17,7 @@ export default function SelectClassGroupModal({ display: boolean; close: () => void; selectedClassGroup?: ClassGroup | null | undefined; - onChange: (classGroup?: ClassGroup | null | undefined) => void; + onChange: (classGroup?: ClassGroup | null) => void; raidGroupId: string; }){ const [ currentClassGroup, setCurrentClassGroup ] = useState(selectedClassGroup); diff --git a/src/ui/game/GamesList.tsx b/src/ui/game/GamesList.tsx index 9f87fcd..81f172c 100644 --- a/src/ui/game/GamesList.tsx +++ b/src/ui/game/GamesList.tsx @@ -29,13 +29,14 @@ export default function GamesList({ const headElements: React.ReactNode[] = [ -
+
Icon
, -
+
Name
,
Actions @@ -43,7 +44,7 @@ export default function GamesList({ ]; const bodyElements: React.ReactNode[][] = games.map((game) => [ -
+
{ game.gameIcon &&
, {game.gameName} ,
+
Icon
, -
+
Name
,
Actions @@ -56,12 +57,15 @@ function GameSkeleton(): React.ReactNode[]{ } const elements: React.ReactNode[] = [
,
,
 
diff --git a/src/ui/gameClass/GameClassList.tsx b/src/ui/gameClass/GameClassList.tsx index ec4224c..3a3bbf7 100644 --- a/src/ui/gameClass/GameClassList.tsx +++ b/src/ui/gameClass/GameClassList.tsx @@ -28,13 +28,14 @@ export default function GameClassList({ const headElements: React.ReactNode[] = [ -
+
Icon
, -
+
Name
,
Actions @@ -42,7 +43,7 @@ export default function GameClassList({ ]; const bodyElements: React.ReactNode[][] = gameClasses.map((gameClass) => [ -
+
{ gameClass.gameClassIcon &&
, -
+
{gameClass.gameClassName}
,
+
Icon
, -
+
Name
,
Actions @@ -57,12 +58,15 @@ function GameClassSkeleton(): React.ReactNode[]{ const elements: React.ReactNode[] = [
,
,
 
diff --git a/src/ui/person/PersonDisplay.tsx b/src/ui/person/PersonDisplay.tsx index f122727..4aff5dd 100644 --- a/src/ui/person/PersonDisplay.tsx +++ b/src/ui/person/PersonDisplay.tsx @@ -60,7 +60,7 @@ export default function PersonDisplay({ > navigate(`/raidGroup/${raidGroup.raidGroupId}`)} + onClick={() => void navigate(`/raidGroup/${raidGroup.raidGroupId}`)} > Person Name
,
Discord ID
, -
+
Characters
,
Actions @@ -58,15 +61,17 @@ export default function PersonList({ const bodyElements: React.ReactNode[][] = people.map((person) => [ {person.personName} , -
+
{person.discordId}
, @@ -76,6 +81,7 @@ export default function PersonList({ /> ,
+
Person Name
, -
+
Discord ID
, -
+
Characters
,
Actions @@ -59,15 +60,19 @@ export function PersonSkeleton(): React.ReactNode[]{ } const elements: React.ReactNode[] = [
,
,
,
 
diff --git a/src/ui/personCharacter/PersonCharacterList.tsx b/src/ui/personCharacter/PersonCharacterList.tsx index c634bfe..2afb595 100644 --- a/src/ui/personCharacter/PersonCharacterList.tsx +++ b/src/ui/personCharacter/PersonCharacterList.tsx @@ -33,20 +33,22 @@ export default function PersonCharacterList({ const headElements: React.ReactNode[] = [
Character Name
, -
+
Class
, -
+
Rating
, -
+
Comments
,
Actions @@ -55,30 +57,33 @@ export default function PersonCharacterList({ const bodyElements: React.ReactNode[][] = personCharacters.map((personCharacter) => [
{personCharacter.characterName}
,
, -
+
{ personCharacter.characterRating && personCharacter.characterRating > 0 ? personCharacter.characterRating : <>  }
, -
+
{ personCharacter.characterComments || <>  }
,
+
Character Name
, -
+
Class
, -
+
Rating
, -
+
Comments
,
Actions @@ -61,18 +62,23 @@ function PersonCharacterSkeleton(): React.ReactNode[]{ const elements: React.ReactNode[] = [
,
,
,
,
 
diff --git a/src/ui/raidGroup/RaidGroupsList.tsx b/src/ui/raidGroup/RaidGroupsList.tsx index 22ba5b3..89c0b22 100644 --- a/src/ui/raidGroup/RaidGroupsList.tsx +++ b/src/ui/raidGroup/RaidGroupsList.tsx @@ -31,13 +31,14 @@ export default function RaidGroupsList({ const headElements: React.ReactNode[] = [ -
+
Icon
, -
+
Name
,
Actions @@ -45,7 +46,7 @@ export default function RaidGroupsList({ ]; const bodyElements: React.ReactNode[][] = raidGroups.map((raidGroup) => [ -
+
{ raidGroup.raidGroupIcon &&
, {raidGroup.raidGroupName} ,
+
Icon
, -
+
Name
,
Actions @@ -58,12 +59,15 @@ function RaidGroupSkeleton(): React.ReactNode[]{ } const elements: React.ReactNode[] = [
,
,
 
diff --git a/src/ui/raidGroupRequest/RaidGroupRequestList.tsx b/src/ui/raidGroupRequest/RaidGroupRequestList.tsx index de2fec1..24b866c 100644 --- a/src/ui/raidGroupRequest/RaidGroupRequestList.tsx +++ b/src/ui/raidGroupRequest/RaidGroupRequestList.tsx @@ -28,26 +28,28 @@ export default function RaidGroupRequestList({ const headElements: React.ReactNode[] = [ -
+
Username
, -
+
Message
, -
+
Actions
]; const bodyElements: React.ReactNode[][] = raidGroupRequests.map((request) => [
{request.username}
, -
+
{request.requestMessage || <> }
,
Raid Instance
,
Start Date
,
End Date
,
Size
,
Runs
,
Actions @@ -68,28 +74,32 @@ export default function RaidInstanceList({ const bodyElements: React.ReactNode[][] = raidInstances.map((raidInstance) => [ {raidInstance.raidInstanceName} ,
{moment(raidInstance.raidStartDate).format("MM-DD-YYYY hh:mm a")}
,
{moment(raidInstance.raidEndDate).format("MM-DD-YYYY hh:mm a")}
, -
+
{raidInstance.raidSize}
, -
+
{raidInstance.numberRuns}
,
Raid Instance
,
Start Date
,
End Date
, -
+
Size
, -
+
Runs
, -
+
Actions
]; @@ -69,21 +72,27 @@ function RaidInstanceSkeleton(){ const elements: React.ReactNode[] = [
,
,
,
,
,
 
diff --git a/src/ui/raidInstance/RaidInstanceTab.tsx b/src/ui/raidInstance/RaidInstanceTab.tsx index 5c0980c..002b35b 100644 --- a/src/ui/raidInstance/RaidInstanceTab.tsx +++ b/src/ui/raidInstance/RaidInstanceTab.tsx @@ -63,7 +63,7 @@ export default function RaidInstanceTab({ > navigate(`/raidGroup/${raidGroup.raidGroupId}/raidInstance`)} + onClick={() => void navigate(`/raidGroup/${raidGroup.raidGroupId}/raidInstance`)} > Create Adhoc Raid Instance diff --git a/src/ui/raidInstance/creator/RaidInstanceCreatorTableBody.tsx b/src/ui/raidInstance/creator/RaidInstanceCreatorTableBody.tsx index e3d8b44..5123c40 100644 --- a/src/ui/raidInstance/creator/RaidInstanceCreatorTableBody.tsx +++ b/src/ui/raidInstance/creator/RaidInstanceCreatorTableBody.tsx @@ -63,7 +63,7 @@ export default function RaidInstanceCreatorTableBody({ discordString += "\n"; }); - navigator.clipboard.writeText(discordString); + void navigator.clipboard.writeText(discordString); } diff --git a/src/ui/raidLayout/RaidLayoutList.tsx b/src/ui/raidLayout/RaidLayoutList.tsx index 48526db..97149c4 100644 --- a/src/ui/raidLayout/RaidLayoutList.tsx +++ b/src/ui/raidLayout/RaidLayoutList.tsx @@ -42,21 +42,25 @@ export default function RaidLayoutList({ const headElements: React.ReactNode[] = [
Raid Layout Name
,
Raid Size
,
Class Groups
,
Actions @@ -64,16 +68,17 @@ export default function RaidLayoutList({ ]; const bodyElements: React.ReactNode[][] = raidLayouts.map((raidLayout) => [ -
+
{raidLayout.raidLayoutName}
, -
+
{raidLayout.raidSize}
, -
+
,
Raid Layout Name
,
Raid Size
,
Class Groups
,
Actions @@ -67,15 +71,19 @@ function RaidLayoutSkeleton(){ const elements: React.ReactNode[] = [
,
,
,
 
diff --git a/src/ui/raidLayout/modal/RaidLayoutModal.tsx b/src/ui/raidLayout/modal/RaidLayoutModal.tsx index e8e93b6..383f510 100644 --- a/src/ui/raidLayout/modal/RaidLayoutModal.tsx +++ b/src/ui/raidLayout/modal/RaidLayoutModal.tsx @@ -45,7 +45,7 @@ export default function RaidLayoutModal({ else if(newLayoutSize > classGroups.length){ setClassGroups([ ...classGroups, - ...Array(newLayoutSize - classGroups.length).fill(null) + ...(Array(newLayoutSize - classGroups.length).fill(null) as null[]) ]); } } diff --git a/src/util/AxiosUtil.ts b/src/util/AxiosUtil.ts index 297494d..722fe64 100644 --- a/src/util/AxiosUtil.ts +++ b/src/util/AxiosUtil.ts @@ -1,8 +1,28 @@ -import axios from "axios"; +import { ResponseError } from "@/interface/Errors"; +import axios, { AxiosError } from "axios"; -export const api = axios.create({ +const api = axios.create({ baseURL: `${import.meta.env.VITE_API_URL}`, timeout: 10000, withCredentials: true }); + +api.interceptors.response.use( + (response) => { + if((response.data as ResponseError).errors){ + throw new Error((response.data as ResponseError).errors.join(", ")); + } + return response; + }, + (error) => { + if(error instanceof AxiosError && (error.response?.data as ResponseError).errors){ + throw new Error((error.response?.data as ResponseError).errors.join(", ")); + } + else{ + throw error; + } + } +); + +export default api; diff --git a/vite.config.ts b/vite.config.ts index 8500ff4..2f49093 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -1,7 +1,7 @@ import tailwindcss from "@tailwindcss/vite"; -import react from '@vitejs/plugin-react'; -import { resolve } from 'path'; -import { defineConfig } from 'vite'; +import react from "@vitejs/plugin-react"; +import { resolve } from "path"; +import { defineConfig } from "vite"; // https://vite.dev/config/ @@ -15,5 +15,8 @@ export default defineConfig({ "@": resolve(__dirname, "./src"), "#root": resolve(__dirname) } + }, + build: { + chunkSizeWarningLimit: 1024 } });