From d95e9a4397cae16425ebc8c627ea5441f8fb0515 Mon Sep 17 00:00:00 2001 From: Moaz Dawalibi Date: Wed, 11 Sep 2024 16:47:32 +0300 Subject: [PATCH] student package page,add filter for all dash pages,and some fixes --- package-lock.json | 474 ++++++++++-------- src/Components/Table/ActionButtons.tsx | 4 +- src/Components/Utils/Filter/FilterState.ts | 72 +++ src/Components/Utils/Filter/Modal.ts | 11 + src/Components/Utils/Filter/useFilter.tsx | 166 ++++++ src/Layout/Dashboard/DeleteModels.tsx | 19 +- src/Layout/Dashboard/FilterLayout.tsx | 20 +- src/Layout/Dashboard/Table/DataTable.tsx | 2 +- src/Pages/Admin/Curriculum/Table.tsx | 4 + src/Pages/Admin/Grade/Model/FilterForm.tsx | 5 - src/Pages/Admin/Grade/Table.tsx | 8 +- src/Pages/Admin/Param/Model/AddModel.tsx | 33 ++ src/Pages/Admin/Param/Model/EditModel.tsx | 37 ++ src/Pages/Admin/Param/Model/FilterForm.tsx | 18 + src/Pages/Admin/Param/Model/ModelForm.tsx | 15 + src/Pages/Admin/Param/Model/formUtil.ts | 15 + src/Pages/Admin/Param/Page.tsx | 50 ++ src/Pages/Admin/Param/Table.tsx | 28 ++ src/Pages/Admin/Param/index.tsx | 17 + src/Pages/Admin/Param/useTableColumns.tsx | 60 +++ src/Pages/Admin/Report/Table.tsx | 3 + src/Pages/Admin/Reseller/Form/FilterForm.tsx | 11 +- src/Pages/Admin/Reseller/Table.tsx | 3 + src/Pages/Admin/Student/Model/FilterForm.tsx | 8 +- src/Pages/Admin/Student/Table.tsx | 8 +- src/Pages/Admin/Tags/Model/FilterForm.tsx | 5 - src/Pages/Admin/Tags/Table.tsx | 3 + src/Pages/Admin/Unit/DrapableTable.tsx | 9 +- src/Pages/Admin/Unit/Model/FilterForm.tsx | 5 - src/Pages/Admin/Unit/Table.tsx | 7 +- src/Pages/Admin/User/Model/FilterForm.tsx | 8 +- src/Pages/Admin/User/Model/ModelForm.tsx | 11 +- src/Pages/Admin/User/Table.tsx | 3 + src/Pages/Admin/lesson/DrapableTable.tsx | 4 + src/Pages/Admin/lesson/Model/FilterForm.tsx | 5 - src/Pages/Admin/lesson/Table.tsx | 7 +- src/Pages/Admin/question/FilterForm.tsx | 16 +- src/Pages/Admin/question/Table.tsx | 4 + src/Pages/Admin/subject/Model/FilterForm.tsx | 5 - src/Pages/Admin/subject/Table/TablePage.tsx | 9 +- .../StudentPackage/Model/AddModel.tsx | 33 ++ .../StudentPackage/Model/EditModel.tsx | 37 ++ .../StudentPackage/Model/FilterForm.tsx | 18 + .../StudentPackage/Model/ModelForm.tsx | 28 ++ .../ReSeller/StudentPackage/Model/formUtil.ts | 25 + src/Pages/ReSeller/StudentPackage/Page.tsx | 49 ++ src/Pages/ReSeller/StudentPackage/Table.tsx | 22 + src/Pages/ReSeller/StudentPackage/index.tsx | 17 + .../StudentPackage/useTableColumns.tsx | 89 ++++ src/Routes.tsx | 45 ++ src/Styles/DataTable/FillterNav.scss | 2 + src/Styles/Layout/FilterLayout.scss | 11 + src/api/helper/useDeleteMutation.ts | 4 +- src/api/helper/useUpdateMutation.ts | 4 +- src/api/param.ts | 20 + src/api/studentPackage.ts | 15 + src/config/userTypeOptions.ts | 5 + src/enums/Model.ts | 21 +- src/enums/abilities.ts | 2 + src/translate/ar.json | 25 +- src/types/Item.ts | 20 + src/utils/formatDate.ts | 10 + src/utils/hasAbilityFn.ts | 38 ++ src/utils/useFormatDataToSelect.tsx | 1 + 64 files changed, 1450 insertions(+), 283 deletions(-) create mode 100644 src/Components/Utils/Filter/FilterState.ts create mode 100644 src/Components/Utils/Filter/Modal.ts create mode 100644 src/Components/Utils/Filter/useFilter.tsx create mode 100644 src/Pages/Admin/Param/Model/AddModel.tsx create mode 100644 src/Pages/Admin/Param/Model/EditModel.tsx create mode 100644 src/Pages/Admin/Param/Model/FilterForm.tsx create mode 100644 src/Pages/Admin/Param/Model/ModelForm.tsx create mode 100644 src/Pages/Admin/Param/Model/formUtil.ts create mode 100644 src/Pages/Admin/Param/Page.tsx create mode 100644 src/Pages/Admin/Param/Table.tsx create mode 100644 src/Pages/Admin/Param/index.tsx create mode 100644 src/Pages/Admin/Param/useTableColumns.tsx create mode 100644 src/Pages/ReSeller/StudentPackage/Model/AddModel.tsx create mode 100644 src/Pages/ReSeller/StudentPackage/Model/EditModel.tsx create mode 100644 src/Pages/ReSeller/StudentPackage/Model/FilterForm.tsx create mode 100644 src/Pages/ReSeller/StudentPackage/Model/ModelForm.tsx create mode 100644 src/Pages/ReSeller/StudentPackage/Model/formUtil.ts create mode 100644 src/Pages/ReSeller/StudentPackage/Page.tsx create mode 100644 src/Pages/ReSeller/StudentPackage/Table.tsx create mode 100644 src/Pages/ReSeller/StudentPackage/index.tsx create mode 100644 src/Pages/ReSeller/StudentPackage/useTableColumns.tsx create mode 100644 src/api/param.ts create mode 100644 src/api/studentPackage.ts create mode 100644 src/config/userTypeOptions.ts create mode 100644 src/utils/formatDate.ts diff --git a/package-lock.json b/package-lock.json index c43e5d0..3e05e0f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,28 +9,27 @@ "version": "0.1.0", "dependencies": { "@ant-design/icons": "^5.3.7", + "@dnd-kit/core": "^6.1.0", + "@dnd-kit/modifiers": "^7.0.0", + "@dnd-kit/sortable": "^8.0.0", + "@dnd-kit/utilities": "^3.2.2", "antd": "^5.17.4", "axios": "^1.7.2", "bootstrap": "^5.3.3", "dayjs": "^1.11.11", "formik": "^2.4.6", - "html-to-image": "^1.11.11", "i18next": "^23.11.5", - "path-to-regexp": "^6.2.2", - "pdf-lib": "^1.17.1", + "lottie-react": "^2.4.0", "react": "^18.3.1", "react-beautiful-dnd": "^13.1.1", "react-dom": "^18.3.1", "react-i18next": "^13.5.0", "react-icons": "^4.12.0", - "react-mathjax": "^1.0.1", "react-query": "^3.39.3", "react-router-dom": "^6.23.1", "react-toastify": "^9.1.3", "reactstrap": "^9.2.2", "sass": "^1.77.4", - "ts-node": "^10.9.2", - "vite-plugin-env-compatible": "^2.0.1", "yup": "^1.4.0", "zustand": "^4.5.2" }, @@ -40,6 +39,7 @@ "@testing-library/user-event": "^13.5.0", "@types/node": "^20.14.0", "@types/react": "^18.3.3", + "@types/react-beautiful-dnd": "^13.1.8", "@types/react-dom": "^18.3.0", "@types/react-helmet": "^6.1.11", "@vitejs/plugin-legacy": "^5.4.1", @@ -1975,6 +1975,9 @@ "version": "0.8.1", "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "dev": true, + "optional": true, + "peer": true, "dependencies": { "@jridgewell/trace-mapping": "0.3.9" }, @@ -1986,6 +1989,9 @@ "version": "0.3.9", "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "dev": true, + "optional": true, + "peer": true, "dependencies": { "@jridgewell/resolve-uri": "^3.0.3", "@jridgewell/sourcemap-codec": "^1.4.10" @@ -2008,6 +2014,68 @@ "node": ">=10.0.0" } }, + "node_modules/@dnd-kit/accessibility": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@dnd-kit/accessibility/-/accessibility-3.1.0.tgz", + "integrity": "sha512-ea7IkhKvlJUv9iSHJOnxinBcoOI3ppGnnL+VDJ75O45Nss6HtZd8IdN8touXPDtASfeI2T2LImb8VOZcL47wjQ==", + "dependencies": { + "tslib": "^2.0.0" + }, + "peerDependencies": { + "react": ">=16.8.0" + } + }, + "node_modules/@dnd-kit/core": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/@dnd-kit/core/-/core-6.1.0.tgz", + "integrity": "sha512-J3cQBClB4TVxwGo3KEjssGEXNJqGVWx17aRTZ1ob0FliR5IjYgTxl5YJbKTzA6IzrtelotH19v6y7uoIRUZPSg==", + "dependencies": { + "@dnd-kit/accessibility": "^3.1.0", + "@dnd-kit/utilities": "^3.2.2", + "tslib": "^2.0.0" + }, + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, + "node_modules/@dnd-kit/modifiers": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@dnd-kit/modifiers/-/modifiers-7.0.0.tgz", + "integrity": "sha512-BG/ETy3eBjFap7+zIti53f0PCLGDzNXyTmn6fSdrudORf+OH04MxrW4p5+mPu4mgMk9kM41iYONjc3DOUWTcfg==", + "dependencies": { + "@dnd-kit/utilities": "^3.2.2", + "tslib": "^2.0.0" + }, + "peerDependencies": { + "@dnd-kit/core": "^6.1.0", + "react": ">=16.8.0" + } + }, + "node_modules/@dnd-kit/sortable": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@dnd-kit/sortable/-/sortable-8.0.0.tgz", + "integrity": "sha512-U3jk5ebVXe1Lr7c2wU7SBZjcWdQP+j7peHJfCspnA81enlu88Mgd7CC8Q+pub9ubP7eKVETzJW+IBAhsqbSu/g==", + "dependencies": { + "@dnd-kit/utilities": "^3.2.2", + "tslib": "^2.0.0" + }, + "peerDependencies": { + "@dnd-kit/core": "^6.1.0", + "react": ">=16.8.0" + } + }, + "node_modules/@dnd-kit/utilities": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/@dnd-kit/utilities/-/utilities-3.2.2.tgz", + "integrity": "sha512-+MKAJEOfaBe5SmV6t34p80MMKhjvUz0vRrvVJbPT0WElzaOJ/1xs+D+KDv+tD/NE5ujfrChEcshd4fLn0wpiqg==", + "dependencies": { + "tslib": "^2.0.0" + }, + "peerDependencies": { + "react": ">=16.8.0" + } + }, "node_modules/@emotion/hash": { "version": "0.8.0", "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.8.0.tgz", @@ -2739,6 +2807,7 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, "engines": { "node": ">=6.0.0" } @@ -2765,7 +2834,8 @@ "node_modules/@jridgewell/sourcemap-codec": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", - "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==" + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", + "dev": true }, "node_modules/@jridgewell/trace-mapping": { "version": "0.3.25", @@ -2777,22 +2847,6 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, - "node_modules/@pdf-lib/standard-fonts": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@pdf-lib/standard-fonts/-/standard-fonts-1.0.0.tgz", - "integrity": "sha512-hU30BK9IUN/su0Mn9VdlVKsWBS6GyhVfqjwl1FjZN4TxP6cCw0jP2w7V3Hf5uX7M0AZJ16vey9yE0ny7Sa59ZA==", - "dependencies": { - "pako": "^1.0.6" - } - }, - "node_modules/@pdf-lib/upng": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@pdf-lib/upng/-/upng-1.0.1.tgz", - "integrity": "sha512-dQK2FUMQtowVP00mtIksrlZhdFXQZPC+taih1q4CvPZ5vqdxR/LKBaFg0oAfzd1GlHZXXSPdQfzQnt+ViGvEIQ==", - "dependencies": { - "pako": "^1.0.10" - } - }, "node_modules/@popperjs/core": { "version": "2.11.8", "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", @@ -3340,22 +3394,34 @@ "node_modules/@tsconfig/node10": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz", - "integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==" + "integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==", + "dev": true, + "optional": true, + "peer": true }, "node_modules/@tsconfig/node12": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", - "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==" + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", + "dev": true, + "optional": true, + "peer": true }, "node_modules/@tsconfig/node14": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", - "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==" + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", + "dev": true, + "optional": true, + "peer": true }, "node_modules/@tsconfig/node16": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", - "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==" + "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", + "dev": true, + "optional": true, + "peer": true }, "node_modules/@types/aria-query": { "version": "5.0.4", @@ -3504,6 +3570,7 @@ "version": "20.14.15", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.15.tgz", "integrity": "sha512-Fz1xDMCF/B00/tYSVMlmK7hVeLh7jE5f3B7X1/hmV0MJBwE27KlS7EvD/Yp+z1lm8mVhwV5w+n8jOZG8AfTlKw==", + "dev": true, "dependencies": { "undici-types": "~5.26.4" } @@ -3522,6 +3589,15 @@ "csstype": "^3.0.2" } }, + "node_modules/@types/react-beautiful-dnd": { + "version": "13.1.8", + "resolved": "https://registry.npmjs.org/@types/react-beautiful-dnd/-/react-beautiful-dnd-13.1.8.tgz", + "integrity": "sha512-E3TyFsro9pQuK4r8S/OL6G99eq7p8v29sX0PM7oT8Z+PJfZvSQTx4zTQbUJ+QZXioAF0e7TGBEcA1XhYhCweyQ==", + "dev": true, + "dependencies": { + "@types/react": "*" + } + }, "node_modules/@types/react-dom": { "version": "18.3.0", "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.0.tgz", @@ -3832,6 +3908,7 @@ "version": "8.12.1", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", + "dev": true, "bin": { "acorn": "bin/acorn" }, @@ -3852,6 +3929,9 @@ "version": "8.3.3", "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.3.tgz", "integrity": "sha512-MxXdReSRhGO7VlFe1bRG/oI7/mdLV9B9JJT0N8vZOhF7gFRR5l3M8W9G8JxmKV+JC5mGqJ0QvqfSOLsCPa4nUw==", + "dev": true, + "optional": true, + "peer": true, "dependencies": { "acorn": "^8.11.0" }, @@ -4014,7 +4094,10 @@ "node_modules/arg": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", - "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==" + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true, + "optional": true, + "peer": true }, "node_modules/argparse": { "version": "1.0.10", @@ -4690,7 +4773,10 @@ "node_modules/create-require": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", - "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==" + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "dev": true, + "optional": true, + "peer": true }, "node_modules/cross-spawn": { "version": "7.0.3", @@ -4884,6 +4970,9 @@ "version": "4.0.2", "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true, + "optional": true, + "peer": true, "engines": { "node": ">=0.3.1" } @@ -4912,19 +5001,6 @@ "csstype": "^3.0.2" } }, - "node_modules/dotenv": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.2.0.tgz", - "integrity": "sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw==", - "engines": { - "node": ">=8" - } - }, - "node_modules/dotenv-expand": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-5.1.0.tgz", - "integrity": "sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA==" - }, "node_modules/ejs": { "version": "3.1.10", "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz", @@ -5695,11 +5771,6 @@ "void-elements": "3.1.0" } }, - "node_modules/html-to-image": { - "version": "1.11.11", - "resolved": "https://registry.npmjs.org/html-to-image/-/html-to-image-1.11.11.tgz", - "integrity": "sha512-9gux8QhvjRO/erSnDPv28noDZcPZmYE7e1vFsBLKLlRlKDSqNJYebj6Qz1TGd5lsRV+X+xYyjCKjuZdABinWjA==" - }, "node_modules/http-proxy-agent": { "version": "7.0.2", "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", @@ -7334,11 +7405,6 @@ "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", "dev": true }, - "node_modules/load-script": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/load-script/-/load-script-1.0.0.tgz", - "integrity": "sha512-kPEjMFtZvwL9TaZo0uZ2ml+Ye9HUMmPwbYRJ324qF9tqMejwykJ5ggTyvzmrbBeapCAbk98BSbTeovHEEP1uCA==" - }, "node_modules/loader-runner": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", @@ -7393,6 +7459,23 @@ "loose-envify": "cli.js" } }, + "node_modules/lottie-react": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/lottie-react/-/lottie-react-2.4.0.tgz", + "integrity": "sha512-pDJGj+AQlnlyHvOHFK7vLdsDcvbuqvwPZdMlJ360wrzGFurXeKPr8SiRCjLf3LrNYKANQtSsh5dz9UYQHuqx4w==", + "dependencies": { + "lottie-web": "^5.10.2" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/lottie-web": { + "version": "5.12.2", + "resolved": "https://registry.npmjs.org/lottie-web/-/lottie-web-5.12.2.tgz", + "integrity": "sha512-uvhvYPC8kGPjXT3MyKMrL3JitEAmDMp30lVkuq/590Mw9ok6pWcFCwXJveo0t5uqYw1UREQHofD+jVpdjBv8wg==" + }, "node_modules/lru-cache": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", @@ -7450,7 +7533,8 @@ "node_modules/make-error": { "version": "1.3.6", "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", - "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==" + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true }, "node_modules/makeerror": { "version": "1.0.12", @@ -7800,11 +7884,6 @@ "node": ">=6" } }, - "node_modules/pako": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", - "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==" - }, "node_modules/parse-json": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", @@ -7867,27 +7946,6 @@ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", "dev": true }, - "node_modules/path-to-regexp": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.2.2.tgz", - "integrity": "sha512-GQX3SSMokngb36+whdpRXE+3f9V8UzyAorlYvOGx87ufGHehNTn5lCxrKtLyZ4Yl/wEKnNnr98ZzOwwDZV5ogw==" - }, - "node_modules/pdf-lib": { - "version": "1.17.1", - "resolved": "https://registry.npmjs.org/pdf-lib/-/pdf-lib-1.17.1.tgz", - "integrity": "sha512-V/mpyJAoTsN4cnP31vc0wfNA1+p20evqqnap0KLoRUN0Yk/p3wN52DOEsL4oBFcLdb76hlpKPtzJIgo67j/XLw==", - "dependencies": { - "@pdf-lib/standard-fonts": "^1.0.0", - "@pdf-lib/upng": "^1.0.1", - "pako": "^1.0.11", - "tslib": "^1.11.1" - } - }, - "node_modules/pdf-lib/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" - }, "node_modules/picocolors": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", @@ -8751,17 +8809,6 @@ "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" }, - "node_modules/react-mathjax": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/react-mathjax/-/react-mathjax-1.0.1.tgz", - "integrity": "sha512-+mjFcciZY3GQoqiQm3aRTyDjgBKuoaXpY+SCONX00jScuPpTKwnASeFMS5+pbTIzDf5zPT2Y9ZZfQ9U/d4CKtQ==", - "dependencies": { - "load-script": "^1.0.0" - }, - "peerDependencies": { - "react": "^16.3.0" - } - }, "node_modules/react-popper": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/react-popper/-/react-popper-2.3.0.tgz", @@ -9904,6 +9951,9 @@ "version": "10.9.2", "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", + "dev": true, + "optional": true, + "peer": true, "dependencies": { "@cspotcode/source-map-support": "^0.8.0", "@tsconfig/node10": "^1.0.7", @@ -9972,6 +10022,7 @@ "version": "4.9.5", "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", + "dev": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -9983,7 +10034,8 @@ "node_modules/undici-types": { "version": "5.26.5", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "dev": true }, "node_modules/unicode-canonical-property-names-ecmascript": { "version": "2.0.0", @@ -10111,7 +10163,10 @@ "node_modules/v8-compile-cache-lib": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", - "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==" + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", + "dev": true, + "optional": true, + "peer": true }, "node_modules/v8-to-istanbul": { "version": "9.3.0", @@ -10200,15 +10255,6 @@ "vite": ">=2.0.0" } }, - "node_modules/vite-plugin-env-compatible": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/vite-plugin-env-compatible/-/vite-plugin-env-compatible-2.0.1.tgz", - "integrity": "sha512-DRrOZTg/W44ojVQQfGSMPEgYQGzp5TeIpt9cpaK35hTOC/b2D7Ffl8/RIgK8vQ0mlnDIUgETcA173bnMEkyzdw==", - "dependencies": { - "dotenv": "8.2.0", - "dotenv-expand": "5.1.0" - } - }, "node_modules/void-elements": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-3.1.0.tgz", @@ -10616,6 +10662,9 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "dev": true, + "optional": true, + "peer": true, "engines": { "node": ">=6" } @@ -12015,6 +12064,9 @@ "version": "0.8.1", "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "dev": true, + "optional": true, + "peer": true, "requires": { "@jridgewell/trace-mapping": "0.3.9" }, @@ -12023,6 +12075,9 @@ "version": "0.3.9", "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "dev": true, + "optional": true, + "peer": true, "requires": { "@jridgewell/resolve-uri": "^3.0.3", "@jridgewell/sourcemap-codec": "^1.4.10" @@ -12041,6 +12096,50 @@ "integrity": "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==", "dev": true }, + "@dnd-kit/accessibility": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@dnd-kit/accessibility/-/accessibility-3.1.0.tgz", + "integrity": "sha512-ea7IkhKvlJUv9iSHJOnxinBcoOI3ppGnnL+VDJ75O45Nss6HtZd8IdN8touXPDtASfeI2T2LImb8VOZcL47wjQ==", + "requires": { + "tslib": "^2.0.0" + } + }, + "@dnd-kit/core": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/@dnd-kit/core/-/core-6.1.0.tgz", + "integrity": "sha512-J3cQBClB4TVxwGo3KEjssGEXNJqGVWx17aRTZ1ob0FliR5IjYgTxl5YJbKTzA6IzrtelotH19v6y7uoIRUZPSg==", + "requires": { + "@dnd-kit/accessibility": "^3.1.0", + "@dnd-kit/utilities": "^3.2.2", + "tslib": "^2.0.0" + } + }, + "@dnd-kit/modifiers": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@dnd-kit/modifiers/-/modifiers-7.0.0.tgz", + "integrity": "sha512-BG/ETy3eBjFap7+zIti53f0PCLGDzNXyTmn6fSdrudORf+OH04MxrW4p5+mPu4mgMk9kM41iYONjc3DOUWTcfg==", + "requires": { + "@dnd-kit/utilities": "^3.2.2", + "tslib": "^2.0.0" + } + }, + "@dnd-kit/sortable": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@dnd-kit/sortable/-/sortable-8.0.0.tgz", + "integrity": "sha512-U3jk5ebVXe1Lr7c2wU7SBZjcWdQP+j7peHJfCspnA81enlu88Mgd7CC8Q+pub9ubP7eKVETzJW+IBAhsqbSu/g==", + "requires": { + "@dnd-kit/utilities": "^3.2.2", + "tslib": "^2.0.0" + } + }, + "@dnd-kit/utilities": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/@dnd-kit/utilities/-/utilities-3.2.2.tgz", + "integrity": "sha512-+MKAJEOfaBe5SmV6t34p80MMKhjvUz0vRrvVJbPT0WElzaOJ/1xs+D+KDv+tD/NE5ujfrChEcshd4fLn0wpiqg==", + "requires": { + "tslib": "^2.0.0" + } + }, "@emotion/hash": { "version": "0.8.0", "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.8.0.tgz", @@ -12490,7 +12589,8 @@ "@jridgewell/resolve-uri": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", - "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==" + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true }, "@jridgewell/set-array": { "version": "1.2.1", @@ -12511,7 +12611,8 @@ "@jridgewell/sourcemap-codec": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", - "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==" + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", + "dev": true }, "@jridgewell/trace-mapping": { "version": "0.3.25", @@ -12523,22 +12624,6 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, - "@pdf-lib/standard-fonts": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@pdf-lib/standard-fonts/-/standard-fonts-1.0.0.tgz", - "integrity": "sha512-hU30BK9IUN/su0Mn9VdlVKsWBS6GyhVfqjwl1FjZN4TxP6cCw0jP2w7V3Hf5uX7M0AZJ16vey9yE0ny7Sa59ZA==", - "requires": { - "pako": "^1.0.6" - } - }, - "@pdf-lib/upng": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@pdf-lib/upng/-/upng-1.0.1.tgz", - "integrity": "sha512-dQK2FUMQtowVP00mtIksrlZhdFXQZPC+taih1q4CvPZ5vqdxR/LKBaFg0oAfzd1GlHZXXSPdQfzQnt+ViGvEIQ==", - "requires": { - "pako": "^1.0.10" - } - }, "@popperjs/core": { "version": "2.11.8", "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", @@ -12904,22 +12989,34 @@ "@tsconfig/node10": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz", - "integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==" + "integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==", + "dev": true, + "optional": true, + "peer": true }, "@tsconfig/node12": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", - "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==" + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", + "dev": true, + "optional": true, + "peer": true }, "@tsconfig/node14": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", - "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==" + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", + "dev": true, + "optional": true, + "peer": true }, "@tsconfig/node16": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", - "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==" + "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", + "dev": true, + "optional": true, + "peer": true }, "@types/aria-query": { "version": "5.0.4", @@ -13061,6 +13158,7 @@ "version": "20.14.15", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.15.tgz", "integrity": "sha512-Fz1xDMCF/B00/tYSVMlmK7hVeLh7jE5f3B7X1/hmV0MJBwE27KlS7EvD/Yp+z1lm8mVhwV5w+n8jOZG8AfTlKw==", + "dev": true, "requires": { "undici-types": "~5.26.4" } @@ -13079,6 +13177,15 @@ "csstype": "^3.0.2" } }, + "@types/react-beautiful-dnd": { + "version": "13.1.8", + "resolved": "https://registry.npmjs.org/@types/react-beautiful-dnd/-/react-beautiful-dnd-13.1.8.tgz", + "integrity": "sha512-E3TyFsro9pQuK4r8S/OL6G99eq7p8v29sX0PM7oT8Z+PJfZvSQTx4zTQbUJ+QZXioAF0e7TGBEcA1XhYhCweyQ==", + "dev": true, + "requires": { + "@types/react": "*" + } + }, "@types/react-dom": { "version": "18.3.0", "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.0.tgz", @@ -13349,7 +13456,8 @@ "acorn": { "version": "8.12.1", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", - "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==" + "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", + "dev": true }, "acorn-import-attributes": { "version": "1.9.5", @@ -13362,6 +13470,9 @@ "version": "8.3.3", "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.3.tgz", "integrity": "sha512-MxXdReSRhGO7VlFe1bRG/oI7/mdLV9B9JJT0N8vZOhF7gFRR5l3M8W9G8JxmKV+JC5mGqJ0QvqfSOLsCPa4nUw==", + "dev": true, + "optional": true, + "peer": true, "requires": { "acorn": "^8.11.0" } @@ -13486,7 +13597,10 @@ "arg": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", - "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==" + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true, + "optional": true, + "peer": true }, "argparse": { "version": "1.0.10", @@ -13974,7 +14088,10 @@ "create-require": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", - "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==" + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "dev": true, + "optional": true, + "peer": true }, "cross-spawn": { "version": "7.0.3", @@ -14118,7 +14235,10 @@ "diff": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==" + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true, + "optional": true, + "peer": true }, "diff-sequences": { "version": "29.6.3", @@ -14141,16 +14261,6 @@ "csstype": "^3.0.2" } }, - "dotenv": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.2.0.tgz", - "integrity": "sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw==" - }, - "dotenv-expand": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-5.1.0.tgz", - "integrity": "sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA==" - }, "ejs": { "version": "3.1.10", "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz", @@ -14713,11 +14823,6 @@ "void-elements": "3.1.0" } }, - "html-to-image": { - "version": "1.11.11", - "resolved": "https://registry.npmjs.org/html-to-image/-/html-to-image-1.11.11.tgz", - "integrity": "sha512-9gux8QhvjRO/erSnDPv28noDZcPZmYE7e1vFsBLKLlRlKDSqNJYebj6Qz1TGd5lsRV+X+xYyjCKjuZdABinWjA==" - }, "http-proxy-agent": { "version": "7.0.2", "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", @@ -15903,11 +16008,6 @@ "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", "dev": true }, - "load-script": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/load-script/-/load-script-1.0.0.tgz", - "integrity": "sha512-kPEjMFtZvwL9TaZo0uZ2ml+Ye9HUMmPwbYRJ324qF9tqMejwykJ5ggTyvzmrbBeapCAbk98BSbTeovHEEP1uCA==" - }, "loader-runner": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", @@ -15953,6 +16053,19 @@ "js-tokens": "^3.0.0 || ^4.0.0" } }, + "lottie-react": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/lottie-react/-/lottie-react-2.4.0.tgz", + "integrity": "sha512-pDJGj+AQlnlyHvOHFK7vLdsDcvbuqvwPZdMlJ360wrzGFurXeKPr8SiRCjLf3LrNYKANQtSsh5dz9UYQHuqx4w==", + "requires": { + "lottie-web": "^5.10.2" + } + }, + "lottie-web": { + "version": "5.12.2", + "resolved": "https://registry.npmjs.org/lottie-web/-/lottie-web-5.12.2.tgz", + "integrity": "sha512-uvhvYPC8kGPjXT3MyKMrL3JitEAmDMp30lVkuq/590Mw9ok6pWcFCwXJveo0t5uqYw1UREQHofD+jVpdjBv8wg==" + }, "lru-cache": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", @@ -15997,7 +16110,8 @@ "make-error": { "version": "1.3.6", "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", - "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==" + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true }, "makeerror": { "version": "1.0.12", @@ -16253,11 +16367,6 @@ "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", "dev": true }, - "pako": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", - "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==" - }, "parse-json": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", @@ -16302,29 +16411,6 @@ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", "dev": true }, - "path-to-regexp": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.2.2.tgz", - "integrity": "sha512-GQX3SSMokngb36+whdpRXE+3f9V8UzyAorlYvOGx87ufGHehNTn5lCxrKtLyZ4Yl/wEKnNnr98ZzOwwDZV5ogw==" - }, - "pdf-lib": { - "version": "1.17.1", - "resolved": "https://registry.npmjs.org/pdf-lib/-/pdf-lib-1.17.1.tgz", - "integrity": "sha512-V/mpyJAoTsN4cnP31vc0wfNA1+p20evqqnap0KLoRUN0Yk/p3wN52DOEsL4oBFcLdb76hlpKPtzJIgo67j/XLw==", - "requires": { - "@pdf-lib/standard-fonts": "^1.0.0", - "@pdf-lib/upng": "^1.0.1", - "pako": "^1.0.11", - "tslib": "^1.11.1" - }, - "dependencies": { - "tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" - } - } - }, "picocolors": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", @@ -16915,14 +17001,6 @@ "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" }, - "react-mathjax": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/react-mathjax/-/react-mathjax-1.0.1.tgz", - "integrity": "sha512-+mjFcciZY3GQoqiQm3aRTyDjgBKuoaXpY+SCONX00jScuPpTKwnASeFMS5+pbTIzDf5zPT2Y9ZZfQ9U/d4CKtQ==", - "requires": { - "load-script": "^1.0.0" - } - }, "react-popper": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/react-popper/-/react-popper-2.3.0.tgz", @@ -17746,6 +17824,9 @@ "version": "10.9.2", "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", + "dev": true, + "optional": true, + "peer": true, "requires": { "@cspotcode/source-map-support": "^0.8.0", "@tsconfig/node10": "^1.0.7", @@ -17782,12 +17863,14 @@ "typescript": { "version": "4.9.5", "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", - "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==" + "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", + "dev": true }, "undici-types": { "version": "5.26.5", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "dev": true }, "unicode-canonical-property-names-ecmascript": { "version": "2.0.0", @@ -17876,7 +17959,10 @@ "v8-compile-cache-lib": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", - "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==" + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", + "dev": true, + "optional": true, + "peer": true }, "v8-to-istanbul": { "version": "9.3.0", @@ -17912,15 +17998,6 @@ "fs-extra": "^10.0.0" } }, - "vite-plugin-env-compatible": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/vite-plugin-env-compatible/-/vite-plugin-env-compatible-2.0.1.tgz", - "integrity": "sha512-DRrOZTg/W44ojVQQfGSMPEgYQGzp5TeIpt9cpaK35hTOC/b2D7Ffl8/RIgK8vQ0mlnDIUgETcA173bnMEkyzdw==", - "requires": { - "dotenv": "8.2.0", - "dotenv-expand": "5.1.0" - } - }, "void-elements": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-3.1.0.tgz", @@ -18204,7 +18281,10 @@ "yn": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", - "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==" + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "dev": true, + "optional": true, + "peer": true }, "yocto-queue": { "version": "0.1.0", diff --git a/src/Components/Table/ActionButtons.tsx b/src/Components/Table/ActionButtons.tsx index 83ac902..ff70e3b 100644 --- a/src/Components/Table/ActionButtons.tsx +++ b/src/Components/Table/ActionButtons.tsx @@ -7,8 +7,8 @@ import { BsEyeFill } from "react-icons/bs"; import { GoTrash } from "react-icons/go"; interface ActionButtonsProps { - canEdit: boolean; - canDelete: boolean; + canEdit?: boolean; + canDelete?: boolean; canShow?: boolean; editTooltipTitle?: string; deleteTooltipTitle?: string; diff --git a/src/Components/Utils/Filter/FilterState.ts b/src/Components/Utils/Filter/FilterState.ts new file mode 100644 index 0000000..be93ae1 --- /dev/null +++ b/src/Components/Utils/Filter/FilterState.ts @@ -0,0 +1,72 @@ +import { create } from "zustand"; + +interface FilterState { + filterState: any[]; + setFilterState: (data: any) => void; + clearFilterState: () => void; + setWithOldValue: (data: any) => void; + setInitialValue: (data: any) => void; +} + +export const useFilterState = create((set, get) => ({ + filterState: [], + setFilterState: (data) => set(() => ({ filterState: data })), + clearFilterState: () => set(() => ({ filterState: [] })), + setWithOldValue: (data) => + set((state) => ({ filterState: [...state.filterState, data] })), + setInitialValue: (data) => { + if (get().filterState.length < 1) { + set(() => ({ filterState: data })); + } + }, +})); + + + + + + + + + +// import { create } from "zustand"; + +// interface FilterState { +// filterState: any[]; +// setFilterState: (data: any) => void; +// clearFilterState: () => void; +// setWithOldValue: (data: any) => void; +// setInitialValue: (data: any) => void; +// setFilterStateWithFormat:(data:any)=>void +// } + +// export const useFilterState = create((set, get) => ({ +// filterState: [], +// setFilterState: (data) => set(() => ({ filterState: data })), +// clearFilterState: () => set(() => ({ filterState: [] })), +// setWithOldValue: (data) => +// set((state) => ({ filterState: [...state.filterState, data] })), +// setInitialValue: (data) => { +// if (get().filterState.length < 1) { +// set(() => ({ filterState: data })); +// } +// }, +// // Inside your useFilterState store +// setFilterStateWithFormat: (data:any) => { +// const formatDate = (date:any) => { +// if (!date) return null; +// const d = new Date(date); +// const year = d.getFullYear(); +// const month = String(d.getMonth() + 1).padStart(2, '0'); // Months are zero-based +// const day = String(d.getDate()).padStart(2, '0'); +// return `${year}-${month}-${day}`; +// }; + +// const formattedData = { +// ...data, +// starting_date: formatDate(data.starting_date), +// }; + +// set(() => ({ filterState: formattedData })); +// }, +// })); diff --git a/src/Components/Utils/Filter/Modal.ts b/src/Components/Utils/Filter/Modal.ts new file mode 100644 index 0000000..d72b2e8 --- /dev/null +++ b/src/Components/Utils/Filter/Modal.ts @@ -0,0 +1,11 @@ +import { create } from "zustand"; + +interface ModalState { + isOpen: string; + setIsOpen: (value: string) => void; +} + +export const useModalState = create((set) => ({ + isOpen: "", + setIsOpen: (value: string) => set((state) => ({ isOpen: value })), +})); diff --git a/src/Components/Utils/Filter/useFilter.tsx b/src/Components/Utils/Filter/useFilter.tsx new file mode 100644 index 0000000..9a8244f --- /dev/null +++ b/src/Components/Utils/Filter/useFilter.tsx @@ -0,0 +1,166 @@ +import React, { ReactNode, useState } from "react"; +import { FaFilter } from "react-icons/fa"; +import { Form, Formik, FormikConfig, FormikHelpers } from "formik"; +import { Button, ButtonProps, Divider, Modal } from "antd"; +import { useTranslation } from "react-i18next"; +import { useModalState } from "./Modal"; +import { useFilterState } from "./FilterState"; +import { ModalEnum } from "../../../enums/Model"; +import { QueryStatusEnum } from "../../../enums/QueryStatus"; +import { useObjectToEdit } from "../../../zustand/ObjectToEditState"; +import FormikForm from "../../../Layout/Dashboard/FormikForm"; +import SpinContainer from "../../Layout/SpinContainer"; + +type OmitFormikProps = "children" | "initialValues" | "onSubmit"; + +interface FormikFormProps extends Omit, OmitFormikProps> { + children: React.ReactNode; + onSubmit?: ( + values: any, + formikHelpers?: FormikHelpers, + ) => void | Promise; + getInitialValues?: any; + getValidationSchema?: any; + status?: QueryStatusEnum; + ModelClassName?: string; + width?: string; + isLoading?: boolean; + isOpen: any; + setIsOpen: any; +} + +interface SubmitButtonProps extends Omit {} + +const useFilter = () => { + const { setIsOpen, isOpen } = useModalState((state) => state); + const { filterState, setFilterState, clearFilterState } = useFilterState(); + const [t] = useTranslation(); + const [formValues, setFormValues] = useState({}); + const { setObjectToEdit } = useObjectToEdit(); + + // Define the type for the callback + type SubmitCallback = () => void; + + const FilterButton = () => { + const handleState = () => { + if (isOpen === ModalEnum?.FILTER) { + setIsOpen(""); + clearFilterState(); + setFormValues({}); + } else { + setIsOpen(ModalEnum?.FILTER); + } + }; + + return ( + + + {t("Filter")} + + ); + }; + + const FilterBody = ({ + onSubmit, + children, + getInitialValues, + getValidationSchema, + status, + ModelClassName, + width = "28vw", + isLoading = false, + setIsOpen, + isOpen, + ...formikProps + }: FormikFormProps) => { + const handleSubmit = (values: any) => { + setFilterState(values); + setFormValues(values); + if (onSubmit) { + onSubmit(values); + } + Submit(); + setIsOpen(""); + }; + const handleCancel = () => { + setIsOpen(""); + clearFilterState(); + setFormValues({}); + }; + const handleOpen = () => { + setIsOpen(true); + // setObjectToEdit({}); + }; + + const [t] = useTranslation(); + return ( + <> + + +
+
+
{t("models.filter")}
+ +
+ {isLoading ? : children} + +
+
+
+
+
+ + ); + }; + + interface SubmitButtonProps extends Omit { + } + const FilterSubmit = ({ ...buttonProps }: SubmitButtonProps) => { + + return ( +
+ + +
+ ); + }; + + const Submit = (callback?: SubmitCallback): void => { + if (callback) { + callback(); + } + }; + + return { + FilterButton, + FilterBody, + filterState, + setFilterState, + clearFilterState, + FilterSubmit, + Submit, + }; +}; + + +export default useFilter; diff --git a/src/Layout/Dashboard/DeleteModels.tsx b/src/Layout/Dashboard/DeleteModels.tsx index 89cf98c..ced2ba2 100644 --- a/src/Layout/Dashboard/DeleteModels.tsx +++ b/src/Layout/Dashboard/DeleteModels.tsx @@ -10,21 +10,28 @@ interface ModalFormProps { deleteMutation: any; ModelEnum: any; isNavigate?: boolean; + idVerify?:boolean } const DeleteModels: React.FC = ({ deleteMutation, ModelEnum, isNavigate = false, + idVerify = true }) => { const { isOpen, setIsOpen } = useModalState((state) => state); const [inputValue, setInputValue] = useState(""); const { mutate, isLoading, isSuccess } = deleteMutation; const { objectToEdit, setObjectToEdit } = useObjectToEdit(); + console.log(objectToEdit?.key); + console.log(inputValue); + + const iaDisabled = + idVerify ? + Number(objectToEdit?.id) !== Number(inputValue) || isLoading + : objectToEdit?.key !== inputValue || isLoading; - const iaDisabled = - Number(objectToEdit?.id) !== Number(inputValue) || isLoading; const navigate = useNavigate(); useEffect(() => { if (isSuccess) { @@ -37,9 +44,13 @@ const DeleteModels: React.FC = ({ }, [isSuccess, setIsOpen]); const handleSubmit = () => { + idVerify? mutate({ id: Number(objectToEdit?.id), - }); + }) + : mutate({ + id:objectToEdit?.key, + }) }; const handleCancel = () => { @@ -77,7 +88,7 @@ const DeleteModels: React.FC = ({
+

{t(filterTitle)}

+
- {sub_children}
- } isOpen={isOpen} setIsOpen={setIsOpen} - /> + > +
{sub_children}
+ +
setIsOpen(true)}> @@ -47,21 +51,27 @@ const FilterLayout = ({
+
+
+ +

{t("صف لكل صفحة")}

{t("ادخالات")}

+
+
); diff --git a/src/Layout/Dashboard/Table/DataTable.tsx b/src/Layout/Dashboard/Table/DataTable.tsx index 108bd05..39ff6d1 100644 --- a/src/Layout/Dashboard/Table/DataTable.tsx +++ b/src/Layout/Dashboard/Table/DataTable.tsx @@ -32,7 +32,7 @@ const DataTable: React.FC = ({ rowClassName={(record, index) => getRowClassName(record, index)} className="DataTable" loading={{ - spinning: isLoading || isRefetching, + spinning: isLoading || isRefetching , indicator: ( }> diff --git a/src/Pages/Admin/Curriculum/Table.tsx b/src/Pages/Admin/Curriculum/Table.tsx index 26cfde9..127003a 100644 --- a/src/Pages/Admin/Curriculum/Table.tsx +++ b/src/Pages/Admin/Curriculum/Table.tsx @@ -4,12 +4,16 @@ import DataTable from "../../../Layout/Dashboard/Table/DataTable"; import { useGetAllCurriculum } from "../../../api/curriculum"; import { useParams } from "react-router-dom"; import { ParamsEnum } from "../../../enums/params"; +import { useFilterState } from "../../../Components/Utils/Filter/FilterState"; const App: React.FC = () => { const { subject_id } = useParams(); + const { filterState } = useFilterState(); + const response = useGetAllCurriculum({ subject_id: subject_id, pagination: true, + ...filterState, }); console.log(response?.data?.data, "response?.data"); diff --git a/src/Pages/Admin/Grade/Model/FilterForm.tsx b/src/Pages/Admin/Grade/Model/FilterForm.tsx index 86bb23c..6d0583f 100644 --- a/src/Pages/Admin/Grade/Model/FilterForm.tsx +++ b/src/Pages/Admin/Grade/Model/FilterForm.tsx @@ -8,11 +8,6 @@ const FilterForm = () => { - - - - - diff --git a/src/Pages/Admin/Grade/Table.tsx b/src/Pages/Admin/Grade/Table.tsx index bc6ad2e..3ebbec9 100644 --- a/src/Pages/Admin/Grade/Table.tsx +++ b/src/Pages/Admin/Grade/Table.tsx @@ -2,9 +2,15 @@ import { useColumns } from "./useTableColumns"; import React from "react"; import DataTable from "../../../Layout/Dashboard/Table/DataTable"; import { useGetAllGrade } from "../../../api/grade"; +import { useFilterState } from "../../../Components/Utils/Filter/FilterState"; const App: React.FC = () => { - const response = useGetAllGrade({ pagination: true }); + const { filterState } = useFilterState(); + + const response = useGetAllGrade({ + pagination: true, + ...filterState, + }); return ; }; diff --git a/src/Pages/Admin/Param/Model/AddModel.tsx b/src/Pages/Admin/Param/Model/AddModel.tsx new file mode 100644 index 0000000..6cd0377 --- /dev/null +++ b/src/Pages/Admin/Param/Model/AddModel.tsx @@ -0,0 +1,33 @@ +import React from "react"; +import { getInitialValues, getValidationSchema } from "./formUtil"; +import { ModalEnum } from "../../../../enums/Model"; +import LayoutModel from "../../../../Layout/Dashboard/LayoutModel"; +import { QueryStatusEnum } from "../../../../enums/QueryStatus"; +import { useAddParam } from "../../../../api/param"; +import ModelForm from "./ModelForm"; + +const AddModel: React.FC = () => { + const { mutate, status } = useAddParam(); + + const handleSubmit = (values: any) => { + mutate({ + ...values, + }); + }; + return ( + <> + + + + + ); +}; + +export default AddModel; diff --git a/src/Pages/Admin/Param/Model/EditModel.tsx b/src/Pages/Admin/Param/Model/EditModel.tsx new file mode 100644 index 0000000..0959abf --- /dev/null +++ b/src/Pages/Admin/Param/Model/EditModel.tsx @@ -0,0 +1,37 @@ +import React from "react"; +import { getInitialValues, getValidationSchema } from "./formUtil"; +import { ModalEnum } from "../../../../enums/Model"; +import LayoutModel from "../../../../Layout/Dashboard/LayoutModel"; +import ModelForm from "./ModelForm"; +import { QueryStatusEnum } from "../../../../enums/QueryStatus"; +import { useObjectToEdit } from "../../../../zustand/ObjectToEditState"; +import { useUpdateParam } from "../../../../api/param"; + +const EditModel: React.FC = () => { + const { mutate, status } = useUpdateParam(); + const { objectToEdit } = useObjectToEdit((state) => state); + + const handleSubmit = (values: any) => { + mutate({ + ...values, + }); + }; + + return ( + <> + + + + + ); +}; + +export default EditModel; diff --git a/src/Pages/Admin/Param/Model/FilterForm.tsx b/src/Pages/Admin/Param/Model/FilterForm.tsx new file mode 100644 index 0000000..493adac --- /dev/null +++ b/src/Pages/Admin/Param/Model/FilterForm.tsx @@ -0,0 +1,18 @@ +import React from "react"; +import ValidationField from "../../../../Components/ValidationField/ValidationField"; +import { Col, Row } from "reactstrap"; + +const FilterForm = () => { + return ( +
+ + + + + + +
+ ); +}; + +export default FilterForm; diff --git a/src/Pages/Admin/Param/Model/ModelForm.tsx b/src/Pages/Admin/Param/Model/ModelForm.tsx new file mode 100644 index 0000000..e0d3d24 --- /dev/null +++ b/src/Pages/Admin/Param/Model/ModelForm.tsx @@ -0,0 +1,15 @@ +import { Col, Row } from "reactstrap"; +import ValidationField from "../../../../Components/ValidationField/ValidationField"; + +const Form = ({isEdit}:{isEdit?:boolean}) => { + return ( + + + + + + + ); +}; + +export default Form; diff --git a/src/Pages/Admin/Param/Model/formUtil.ts b/src/Pages/Admin/Param/Model/formUtil.ts new file mode 100644 index 0000000..440e36c --- /dev/null +++ b/src/Pages/Admin/Param/Model/formUtil.ts @@ -0,0 +1,15 @@ +import * as Yup from "yup"; +export const getInitialValues = (objectToEdit: any): any => { + return { + // id: objectToEdit?.id ?? null, + key: objectToEdit?.key ?? null, + value: objectToEdit?.value ?? null, + }; +}; + +export const getValidationSchema = () => { + return Yup.object().shape({ + key: Yup.mixed().required("validation.required"), + value: Yup.mixed().required("validation.required"), + }); +}; \ No newline at end of file diff --git a/src/Pages/Admin/Param/Page.tsx b/src/Pages/Admin/Param/Page.tsx new file mode 100644 index 0000000..71c85a2 --- /dev/null +++ b/src/Pages/Admin/Param/Page.tsx @@ -0,0 +1,50 @@ +import { ModalEnum } from "../../../enums/Model"; +import { useTranslation } from "react-i18next"; +import { lazy, Suspense } from "react"; +import { Spin } from "antd"; +import { canAddParam } from "../../../utils/hasAbilityFn"; +import useSetPageTitle from "../../../Hooks/useSetPageTitle"; +import { useDeleteTag } from "../../../api/tags"; +import PageHeader from "../../../Layout/Dashboard/PageHeader"; +import FilterLayout from "../../../Layout/Dashboard/FilterLayout"; +import FilterForm from "./Model/FilterForm"; +import { useDeleteParam } from "../../../api/param"; +const Table = lazy(() => import("./Table")); +const AddModalForm = lazy(() => import("./Model/AddModel")); +const EditModalForm = lazy(() => import("./Model/EditModel")); +const DeleteModalForm = lazy( + () => import("../../../Layout/Dashboard/DeleteModels"), +); + +const TableHeader = () => { + const [t] = useTranslation(); + useSetPageTitle( + t(`page_header.param`), + ); + const deleteMutation = useDeleteParam(); + return ( +
+ }> + + } + filterTitle="sidebar.param" + /> + + + + + + + ); +}; + +export default TableHeader; diff --git a/src/Pages/Admin/Param/Table.tsx b/src/Pages/Admin/Param/Table.tsx new file mode 100644 index 0000000..623a0ea --- /dev/null +++ b/src/Pages/Admin/Param/Table.tsx @@ -0,0 +1,28 @@ +import React from "react"; +import DataTable from "../../../Layout/Dashboard/Table/DataTable"; +import { useColumns } from "./useTableColumns"; +import useSearchQuery from "../../../api/utils/useSearchQuery"; +import { useGetAllParam } from "../../../api/param"; +import { useFilterState } from "../../../Components/Utils/Filter/FilterState"; + +const App: React.FC = () => { + const [searchQuery] = useSearchQuery("name"); + const { filterState } = useFilterState(); + + const response = useGetAllParam({ + name: searchQuery, + pagination: true, + ...filterState, + }); + + const transformedData = response?.data?.data && typeof response.data.data === 'object' + ? Object.entries(response.data.data).map(([key, value]) => ({ + key: key, + value: value + })) + : []; + + return ; +}; + +export default App; diff --git a/src/Pages/Admin/Param/index.tsx b/src/Pages/Admin/Param/index.tsx new file mode 100644 index 0000000..447f22d --- /dev/null +++ b/src/Pages/Admin/Param/index.tsx @@ -0,0 +1,17 @@ +import { useColumns } from "./useTableColumns"; +import Table from "./Table"; + +import { FaPlus } from "react-icons/fa"; + +import AddModalForm from "./Model/AddModel"; +import EditModalForm from "./Model/EditModel"; +// import DeleteModalForm from "../../"; + +export { + Table, + useColumns, + AddModalForm, + EditModalForm, + // DeleteModalForm, + FaPlus, +}; diff --git a/src/Pages/Admin/Param/useTableColumns.tsx b/src/Pages/Admin/Param/useTableColumns.tsx new file mode 100644 index 0000000..86a931a --- /dev/null +++ b/src/Pages/Admin/Param/useTableColumns.tsx @@ -0,0 +1,60 @@ +import { TableColumnsType } from "antd"; +import { param, user } from "../../../types/Item"; +import { ModalEnum } from "../../../enums/Model"; +import { useObjectToEdit } from "../../../zustand/ObjectToEditState"; +import { useModalState } from "../../../zustand/Modal"; +import { useTranslation } from "react-i18next"; +import { canDeleteParam, canDeleteUser, canEditParam, canEditUser } from "../../../utils/hasAbilityFn"; +import ActionButtons from "../../../Components/Table/ActionButtons"; + +export const useColumns = () => { + const [t] = useTranslation(); + + const { setIsOpen } = useModalState((state) => state); + + const { setObjectToEdit } = useObjectToEdit((state) => state); + const handelDelete = (record: any) => { + setObjectToEdit(record); + setIsOpen(ModalEnum?.Param_DELETE); + }; + const handleEdit = (record: any) => { + setObjectToEdit(record); + setIsOpen(ModalEnum?.Param_EDIT); + }; + + const columns: TableColumnsType = [ + { + title: t("columns.key"), + dataIndex: "key", + key: "key", + align: "center", + }, + { + title: t("columns.value"), + dataIndex: "value", + key: "value", + align: "center", + }, + { + title: t("columns.procedure"), + key: "actions", + align: "center", + width: "25vw", + render: (_text, record, index) => { + return ( + handelDelete(record)} + onEdit={() => handleEdit(record)} + /> + ); + }, + }, + ]; + + return columns; +}; + + diff --git a/src/Pages/Admin/Report/Table.tsx b/src/Pages/Admin/Report/Table.tsx index 0c4d3c6..9f22aee 100644 --- a/src/Pages/Admin/Report/Table.tsx +++ b/src/Pages/Admin/Report/Table.tsx @@ -4,12 +4,15 @@ import DataTable from "../../../Layout/Dashboard/Table/DataTable"; import { useColumns } from "./useTableColumns"; import useSearchQuery from "../../../api/utils/useSearchQuery"; import { useGetAllReport } from "../../../api/report"; +import { useFilterState } from "../../../Components/Utils/Filter/FilterState"; const App: React.FC = () => { const [searchQuery] = useSearchQuery("name"); + const { filterState } = useFilterState(); const response = useGetAllReport({ name: searchQuery, pagination: true, + ...filterState, }); return ; diff --git a/src/Pages/Admin/Reseller/Form/FilterForm.tsx b/src/Pages/Admin/Reseller/Form/FilterForm.tsx index 86bb23c..925eba3 100644 --- a/src/Pages/Admin/Reseller/Form/FilterForm.tsx +++ b/src/Pages/Admin/Reseller/Form/FilterForm.tsx @@ -7,13 +7,12 @@ const FilterForm = () => {
- - - - - - + + {/* */} + {/* + + */} ); diff --git a/src/Pages/Admin/Reseller/Table.tsx b/src/Pages/Admin/Reseller/Table.tsx index 0fa1440..47488af 100644 --- a/src/Pages/Admin/Reseller/Table.tsx +++ b/src/Pages/Admin/Reseller/Table.tsx @@ -3,12 +3,15 @@ import DataTable from "../../../Layout/Dashboard/Table/DataTable"; import { useColumns } from "./useTableColumns"; import useSearchQuery from "../../../api/utils/useSearchQuery"; import { useGetAllReseller } from "../../../api/reseller"; +import { useFilterState } from "../../../Components/Utils/Filter/FilterState"; const App: React.FC = () => { const [searchQuery] = useSearchQuery("name"); + const { filterState } = useFilterState(); const response = useGetAllReseller({ name: searchQuery, pagination: true, + ...filterState }); return ; diff --git a/src/Pages/Admin/Student/Model/FilterForm.tsx b/src/Pages/Admin/Student/Model/FilterForm.tsx index 86bb23c..9a6904c 100644 --- a/src/Pages/Admin/Student/Model/FilterForm.tsx +++ b/src/Pages/Admin/Student/Model/FilterForm.tsx @@ -7,12 +7,8 @@ const FilterForm = () => {
- - - - - - + + diff --git a/src/Pages/Admin/Student/Table.tsx b/src/Pages/Admin/Student/Table.tsx index 80a093d..f5fac1b 100644 --- a/src/Pages/Admin/Student/Table.tsx +++ b/src/Pages/Admin/Student/Table.tsx @@ -2,9 +2,15 @@ import { useColumns } from "./useTableColumns"; import React from "react"; import DataTable from "../../../Layout/Dashboard/Table/DataTable"; import { useGetAllStudent } from "../../../api/student"; +import { useFilterState } from "../../../Components/Utils/Filter/FilterState"; const App: React.FC = () => { - const response = useGetAllStudent({ pagination: true }); + const { filterState } = useFilterState(); + + const response = useGetAllStudent({ + pagination: true, + ...filterState, + }); return ; }; diff --git a/src/Pages/Admin/Tags/Model/FilterForm.tsx b/src/Pages/Admin/Tags/Model/FilterForm.tsx index 86bb23c..6d0583f 100644 --- a/src/Pages/Admin/Tags/Model/FilterForm.tsx +++ b/src/Pages/Admin/Tags/Model/FilterForm.tsx @@ -8,11 +8,6 @@ const FilterForm = () => { - - - - - diff --git a/src/Pages/Admin/Tags/Table.tsx b/src/Pages/Admin/Tags/Table.tsx index 026cbd5..1d63521 100644 --- a/src/Pages/Admin/Tags/Table.tsx +++ b/src/Pages/Admin/Tags/Table.tsx @@ -3,12 +3,15 @@ import { useGetAllTag } from "../../../api/tags"; import DataTable from "../../../Layout/Dashboard/Table/DataTable"; import { useColumns } from "./useTableColumns"; import useSearchQuery from "../../../api/utils/useSearchQuery"; +import { useFilterState } from "../../../Components/Utils/Filter/FilterState"; const App: React.FC = () => { const [searchQuery] = useSearchQuery("name"); + const { filterState } = useFilterState(); const response = useGetAllTag({ name: searchQuery, pagination: true, + ...filterState, }); return ; diff --git a/src/Pages/Admin/Unit/DrapableTable.tsx b/src/Pages/Admin/Unit/DrapableTable.tsx index 06678de..725b341 100644 --- a/src/Pages/Admin/Unit/DrapableTable.tsx +++ b/src/Pages/Admin/Unit/DrapableTable.tsx @@ -25,6 +25,7 @@ const LoadingLottie = React.lazy( import { useTranslation } from "react-i18next"; import { useColumns } from "./useTableColumns"; +import { useFilterState } from "../../../Components/Utils/Filter/FilterState"; interface DataType { id: string; // Unique identifier for each row @@ -91,7 +92,13 @@ const Row: React.FC = (props) => { const DrapableTable: React.FC = () => { const { subject_id } = useParams(); - const response = useGetAllUnit({ subject_id: subject_id, pagination: false }); + const { filterState } = useFilterState(); + + const response = useGetAllUnit({ + subject_id: subject_id, + pagination: false, + ...filterState, + }); // Assuming the response contains a unique id for each item const data = diff --git a/src/Pages/Admin/Unit/Model/FilterForm.tsx b/src/Pages/Admin/Unit/Model/FilterForm.tsx index 86bb23c..6d0583f 100644 --- a/src/Pages/Admin/Unit/Model/FilterForm.tsx +++ b/src/Pages/Admin/Unit/Model/FilterForm.tsx @@ -8,11 +8,6 @@ const FilterForm = () => { - - - - - diff --git a/src/Pages/Admin/Unit/Table.tsx b/src/Pages/Admin/Unit/Table.tsx index 59f299b..4040136 100644 --- a/src/Pages/Admin/Unit/Table.tsx +++ b/src/Pages/Admin/Unit/Table.tsx @@ -5,10 +5,15 @@ import { useGetAllUnit } from "../../../api/unit"; import { useParams } from "react-router-dom"; import { ParamsEnum } from "../../../enums/params"; import { useObjectToEdit } from "../../../zustand/ObjectToEditState"; +import { useFilterState } from "../../../Components/Utils/Filter/FilterState"; const App: React.FC = () => { const { subject_id } = useParams(); - const response = useGetAllUnit({ subject_id: subject_id, pagination: true }); + + const response = useGetAllUnit({ + subject_id: subject_id, + pagination: true, + }); const { setOldObjectToEdit } = useObjectToEdit(); // console.log(response?.data?.data, "response?.data"); const data = response?.data?.data; diff --git a/src/Pages/Admin/User/Model/FilterForm.tsx b/src/Pages/Admin/User/Model/FilterForm.tsx index 86bb23c..eb3b7a7 100644 --- a/src/Pages/Admin/User/Model/FilterForm.tsx +++ b/src/Pages/Admin/User/Model/FilterForm.tsx @@ -1,18 +1,18 @@ import React from "react"; import ValidationField from "../../../../Components/ValidationField/ValidationField"; import { Col, Row } from "reactstrap"; +import { userTypeOptions } from "../../../../config/userTypeOptions"; const FilterForm = () => { return (
- - + + - - + diff --git a/src/Pages/Admin/User/Model/ModelForm.tsx b/src/Pages/Admin/User/Model/ModelForm.tsx index 3792e43..6c0f926 100644 --- a/src/Pages/Admin/User/Model/ModelForm.tsx +++ b/src/Pages/Admin/User/Model/ModelForm.tsx @@ -1,16 +1,11 @@ import { Col, Row } from "reactstrap"; import ValidationField from "../../../../Components/ValidationField/ValidationField"; -import { convert_data_to_select } from "../../../../Components/ValidationField"; import useFormatDataToSelect from "../../../../utils/useFormatDataToSelect"; +import { userTypeOptions } from "../../../../config/userTypeOptions"; const Form = ({isEdit}:{isEdit?:boolean}) => { - const typeOptions = [ - { id: "student", name: "student" }, - { id: "reseller", name: "reseller" }, - { id: "admin", name: "admin" }, - ] - const typeArray = useFormatDataToSelect(typeOptions) + return ( @@ -22,7 +17,7 @@ const Form = ({isEdit}:{isEdit?:boolean}) => { - + {/* */} diff --git a/src/Pages/Admin/User/Table.tsx b/src/Pages/Admin/User/Table.tsx index 0867052..b2f0a80 100644 --- a/src/Pages/Admin/User/Table.tsx +++ b/src/Pages/Admin/User/Table.tsx @@ -4,12 +4,15 @@ import DataTable from "../../../Layout/Dashboard/Table/DataTable"; import { useColumns } from "./useTableColumns"; import useSearchQuery from "../../../api/utils/useSearchQuery"; import { useGetAllUser } from "../../../api/user"; +import { useFilterState } from "../../../Components/Utils/Filter/FilterState"; const App: React.FC = () => { const [searchQuery] = useSearchQuery("name"); + const { filterState } = useFilterState(); const response = useGetAllUser({ name: searchQuery, pagination: true, + ...filterState, }); return ; diff --git a/src/Pages/Admin/lesson/DrapableTable.tsx b/src/Pages/Admin/lesson/DrapableTable.tsx index aaf00ed..6a0014b 100644 --- a/src/Pages/Admin/lesson/DrapableTable.tsx +++ b/src/Pages/Admin/lesson/DrapableTable.tsx @@ -25,6 +25,7 @@ const LoadingLottie = React.lazy( import { useTranslation } from "react-i18next"; import { useColumns } from "./useTableColumns"; +import { useFilterState } from "../../../Components/Utils/Filter/FilterState"; interface DataType { id: string; // Unique identifier for each row @@ -91,9 +92,12 @@ const Row: React.FC = (props) => { const DrapableTable: React.FC = () => { const { subject_id } = useParams(); + const { filterState } = useFilterState(); + const response = useGetAllLesson({ subject_id: subject_id, pagination: false, + ...filterState, }); // Assuming the response contains a unique id for each item diff --git a/src/Pages/Admin/lesson/Model/FilterForm.tsx b/src/Pages/Admin/lesson/Model/FilterForm.tsx index 86bb23c..6d0583f 100644 --- a/src/Pages/Admin/lesson/Model/FilterForm.tsx +++ b/src/Pages/Admin/lesson/Model/FilterForm.tsx @@ -8,11 +8,6 @@ const FilterForm = () => { - - - - - diff --git a/src/Pages/Admin/lesson/Table.tsx b/src/Pages/Admin/lesson/Table.tsx index a547ab5..0b46f8c 100644 --- a/src/Pages/Admin/lesson/Table.tsx +++ b/src/Pages/Admin/lesson/Table.tsx @@ -5,10 +5,15 @@ import { useGetAllLesson } from "../../../api/lesson"; import { useParams } from "react-router-dom"; import { ParamsEnum } from "../../../enums/params"; import { useObjectToEdit } from "../../../zustand/ObjectToEditState"; +import { useFilterState } from "../../../Components/Utils/Filter/FilterState"; const App: React.FC = () => { const { unit_id } = useParams(); - const response = useGetAllLesson({ unit_id: unit_id, pagination: true }); + + const response = useGetAllLesson({ + unit_id: unit_id, + pagination: true, + }); const { setOldObjectToEdit } = useObjectToEdit(); // console.log(response?.data?.data, "response?.data"); diff --git a/src/Pages/Admin/question/FilterForm.tsx b/src/Pages/Admin/question/FilterForm.tsx index a123306..f7be7b9 100644 --- a/src/Pages/Admin/question/FilterForm.tsx +++ b/src/Pages/Admin/question/FilterForm.tsx @@ -1,19 +1,23 @@ import React from "react"; import ValidationField from "../../../Components/ValidationField/ValidationField"; import { Col, Row } from "reactstrap"; +import useFormatDataToSelect from "../../../utils/useFormatDataToSelect"; const FilterForm = () => { + const yesNoArray = [ + {id: "لا", name:"لا"}, + {id: "نعم", name:"نعم"}, + ] return (
- - - - - - + + {/* */} + {/* + + */} ); diff --git a/src/Pages/Admin/question/Table.tsx b/src/Pages/Admin/question/Table.tsx index 6c519e6..94eae88 100644 --- a/src/Pages/Admin/question/Table.tsx +++ b/src/Pages/Admin/question/Table.tsx @@ -4,12 +4,16 @@ import DataTable from "../../../Layout/Dashboard/Table/DataTable"; import { useGetAllQuestion } from "../../../api/Question"; import { useParams } from "react-router-dom"; import { ParamsEnum } from "../../../enums/params"; +import { useFilterState } from "../../../Components/Utils/Filter/FilterState"; const App: React.FC = () => { const { lesson_id } = useParams(); + const { filterState } = useFilterState(); + const response = useGetAllQuestion({ lesson_id: lesson_id, pagination: true, + ...filterState, }); return ; }; diff --git a/src/Pages/Admin/subject/Model/FilterForm.tsx b/src/Pages/Admin/subject/Model/FilterForm.tsx index 86bb23c..6d0583f 100644 --- a/src/Pages/Admin/subject/Model/FilterForm.tsx +++ b/src/Pages/Admin/subject/Model/FilterForm.tsx @@ -8,11 +8,6 @@ const FilterForm = () => { - - - - - diff --git a/src/Pages/Admin/subject/Table/TablePage.tsx b/src/Pages/Admin/subject/Table/TablePage.tsx index 2110c7f..e3b9089 100644 --- a/src/Pages/Admin/subject/Table/TablePage.tsx +++ b/src/Pages/Admin/subject/Table/TablePage.tsx @@ -3,10 +3,17 @@ import { useParams } from "react-router-dom"; import DataTable from "../../../../Layout/Dashboard/Table/DataTable"; import { useColumns } from "./useTableColumns"; import { ParamsEnum } from "../../../../enums/params"; +import { useFilterState } from "../../../../Components/Utils/Filter/FilterState"; const TablePage: React.FC = () => { const { course_id } = useParams(); - const response = useGetAllSubject({ course_id: course_id, pagination: true }); + const { filterState } = useFilterState(); + + const response = useGetAllSubject({ + course_id: course_id, + pagination: true, + ...filterState, + }); return ; }; diff --git a/src/Pages/ReSeller/StudentPackage/Model/AddModel.tsx b/src/Pages/ReSeller/StudentPackage/Model/AddModel.tsx new file mode 100644 index 0000000..2b37df3 --- /dev/null +++ b/src/Pages/ReSeller/StudentPackage/Model/AddModel.tsx @@ -0,0 +1,33 @@ +import React from "react"; +import { getInitialValues, getValidationSchema } from "./formUtil"; +import { ModalEnum } from "../../../../enums/Model"; +import LayoutModel from "../../../../Layout/Dashboard/LayoutModel"; +import { QueryStatusEnum } from "../../../../enums/QueryStatus"; +import ModelForm from "./ModelForm"; +import { useAddStudentPackage } from "../../../../api/studentPackage"; + +const AddModel: React.FC = () => { + const { mutate, status } = useAddStudentPackage(); + + const handleSubmit = (values: any) => { + mutate({ + ...values, + }); + }; + return ( + <> + + + + + ); +}; + +export default AddModel; diff --git a/src/Pages/ReSeller/StudentPackage/Model/EditModel.tsx b/src/Pages/ReSeller/StudentPackage/Model/EditModel.tsx new file mode 100644 index 0000000..eead225 --- /dev/null +++ b/src/Pages/ReSeller/StudentPackage/Model/EditModel.tsx @@ -0,0 +1,37 @@ +import React from "react"; +import { getInitialValues, getValidationSchema } from "./formUtil"; +import { ModalEnum } from "../../../../enums/Model"; +import LayoutModel from "../../../../Layout/Dashboard/LayoutModel"; +import ModelForm from "./ModelForm"; +import { QueryStatusEnum } from "../../../../enums/QueryStatus"; +import { useObjectToEdit } from "../../../../zustand/ObjectToEditState"; +import { useUpdateUser } from "../../../../api/user"; + +const EditModel: React.FC = () => { + const { mutate, status } = useUpdateUser(); + const { objectToEdit } = useObjectToEdit((state) => state); + + const handleSubmit = (values: any) => { + mutate({ + ...values, + }); + }; + + return ( + <> + + + + + ); +}; + +export default EditModel; diff --git a/src/Pages/ReSeller/StudentPackage/Model/FilterForm.tsx b/src/Pages/ReSeller/StudentPackage/Model/FilterForm.tsx new file mode 100644 index 0000000..e3e11a9 --- /dev/null +++ b/src/Pages/ReSeller/StudentPackage/Model/FilterForm.tsx @@ -0,0 +1,18 @@ +import React from "react"; +import ValidationField from "../../../../Components/ValidationField/ValidationField"; +import { Col, Row } from "reactstrap"; + +const FilterForm = () => { + return ( +
+ +
+ + {/* */} + + + + ); +}; + +export default FilterForm; diff --git a/src/Pages/ReSeller/StudentPackage/Model/ModelForm.tsx b/src/Pages/ReSeller/StudentPackage/Model/ModelForm.tsx new file mode 100644 index 0000000..af21275 --- /dev/null +++ b/src/Pages/ReSeller/StudentPackage/Model/ModelForm.tsx @@ -0,0 +1,28 @@ +import { Col, Row } from "reactstrap"; +import ValidationField from "../../../../Components/ValidationField/ValidationField"; +import useFormatDataToSelect from "../../../../utils/useFormatDataToSelect"; + +const Form = ({isEdit}:{isEdit?:boolean}) => { + + const typeOptions = [ + { id: "student", name: "student" }, + { id: "reseller", name: "reseller" }, + { id: "admin", name: "admin" }, + ] + const typeArray = useFormatDataToSelect(typeOptions) + + return ( + + + + + + + + + + + ); +}; + +export default Form; diff --git a/src/Pages/ReSeller/StudentPackage/Model/formUtil.ts b/src/Pages/ReSeller/StudentPackage/Model/formUtil.ts new file mode 100644 index 0000000..a2084fe --- /dev/null +++ b/src/Pages/ReSeller/StudentPackage/Model/formUtil.ts @@ -0,0 +1,25 @@ +import * as Yup from "yup"; +import dayjs from "dayjs"; + +export const getInitialValues = (objectToEdit: any): any => { + return { + id: objectToEdit?.id ?? null, + activation_date: objectToEdit?.activation_date + ? dayjs(objectToEdit?.activation_date, "YYYY/MM/DD") + : null, + expiration_date: objectToEdit?.expiration_date + ? dayjs(objectToEdit?.expiration_date, "YYYY/MM/DD") + : null, + student_id: objectToEdit?.student_id ?? null, + package_id: objectToEdit?.package_id ?? null, + + }; +}; +export const getValidationSchema = () => { + return Yup.object().shape({ + activation_date: Yup.mixed().required("validation.required"), + expiration_date: Yup.mixed().required("validation.required"), + student_id: Yup.number().required("validation.required"), + package_id: Yup.number().required("validation.required"), + }); +}; \ No newline at end of file diff --git a/src/Pages/ReSeller/StudentPackage/Page.tsx b/src/Pages/ReSeller/StudentPackage/Page.tsx new file mode 100644 index 0000000..825d5fc --- /dev/null +++ b/src/Pages/ReSeller/StudentPackage/Page.tsx @@ -0,0 +1,49 @@ +import { ModalEnum } from "../../../enums/Model"; +import { useTranslation } from "react-i18next"; +import { lazy, Suspense } from "react"; +import { Spin } from "antd"; +import { canAddStudent_Package, canAddUser } from "../../../utils/hasAbilityFn"; +import useSetPageTitle from "../../../Hooks/useSetPageTitle"; +import { useDeleteTag } from "../../../api/tags"; +import PageHeader from "../../../Layout/Dashboard/PageHeader"; +import FilterLayout from "../../../Layout/Dashboard/FilterLayout"; +import FilterForm from "./Model/FilterForm"; +import { useDeleteUser } from "../../../api/user"; +const Table = lazy(() => import("./Table")); +const AddModalForm = lazy(() => import("./Model/AddModel")); +const EditModalForm = lazy(() => import("./Model/EditModel")); +const DeleteModalForm = lazy( + () => import("../../../Layout/Dashboard/DeleteModels"), +); + +const TableHeader = () => { + const [t] = useTranslation(); + useSetPageTitle( + t(`page_header.student_package`), + ); + // const deleteMutation = useDeleteUser(); + return ( +
+ }> + + } + filterTitle="sidebar.student_package" + /> +
+ {/* */} + + + + + ); +}; + +export default TableHeader; diff --git a/src/Pages/ReSeller/StudentPackage/Table.tsx b/src/Pages/ReSeller/StudentPackage/Table.tsx new file mode 100644 index 0000000..fa34c92 --- /dev/null +++ b/src/Pages/ReSeller/StudentPackage/Table.tsx @@ -0,0 +1,22 @@ +import React from "react"; +import { useGetAllTag } from "../../../api/tags"; +import DataTable from "../../../Layout/Dashboard/Table/DataTable"; +import { useColumns } from "./useTableColumns"; +import useSearchQuery from "../../../api/utils/useSearchQuery"; +import { useGetAllUser } from "../../../api/user"; +import { useGetAllStudentPackage } from "../../../api/studentPackage"; +import { useFilterState } from "../../../Components/Utils/Filter/FilterState"; +const App: React.FC = () => { + const [searchQuery] = useSearchQuery("name"); + const { filterState } = useFilterState(); + + const response = useGetAllStudentPackage({ + name: searchQuery, + pagination: true, + ...filterState, + }); + + return ; +}; + +export default App; diff --git a/src/Pages/ReSeller/StudentPackage/index.tsx b/src/Pages/ReSeller/StudentPackage/index.tsx new file mode 100644 index 0000000..447f22d --- /dev/null +++ b/src/Pages/ReSeller/StudentPackage/index.tsx @@ -0,0 +1,17 @@ +import { useColumns } from "./useTableColumns"; +import Table from "./Table"; + +import { FaPlus } from "react-icons/fa"; + +import AddModalForm from "./Model/AddModel"; +import EditModalForm from "./Model/EditModel"; +// import DeleteModalForm from "../../"; + +export { + Table, + useColumns, + AddModalForm, + EditModalForm, + // DeleteModalForm, + FaPlus, +}; diff --git a/src/Pages/ReSeller/StudentPackage/useTableColumns.tsx b/src/Pages/ReSeller/StudentPackage/useTableColumns.tsx new file mode 100644 index 0000000..3a8f8cb --- /dev/null +++ b/src/Pages/ReSeller/StudentPackage/useTableColumns.tsx @@ -0,0 +1,89 @@ +import { TableColumnsType } from "antd"; +import { Student_Package } from "../../../types/Item"; +import { ModalEnum } from "../../../enums/Model"; +import { useObjectToEdit } from "../../../zustand/ObjectToEditState"; +import { useModalState } from "../../../zustand/Modal"; +import { useTranslation } from "react-i18next"; +import { canDeleteUser, canEditUser } from "../../../utils/hasAbilityFn"; +import ActionButtons from "../../../Components/Table/ActionButtons"; + +export const useColumns = () => { + const [t] = useTranslation(); + + const { setIsOpen } = useModalState((state) => state); + + const { setObjectToEdit } = useObjectToEdit((state) => state); + const handelDelete = (record: any) => { + setObjectToEdit(record); + setIsOpen(ModalEnum?.USER_DELETE); + }; + const handleEdit = (record: any) => { + setObjectToEdit(record); + setIsOpen(ModalEnum?.USER_EDIT); + }; + + const columns: TableColumnsType = [ + { + title: t("columns.id"), + dataIndex: "id", + key: "id", + align: "center", + }, + { + title: t("columns.activation_date"), + dataIndex: "activation_date", + key: "activation_date", + align: "center", + }, + { + title: t("columns.expiration_date"), + dataIndex: "expiration_date", + key: "expiration_date", + align: "center", + }, + { + title: t("columns.first_name"), + key: "first_name", + align: "center", + render: (row) => { + return(row?.student?.first_name) + } + }, + { + title: t("columns.last_name"), + key: "last_name", + align: "center", + render: (row) => { + return(row?.student?.last_name) + } + }, + { + title: t("columns.sex"), + key: "sex", + align: "center", + render: (row) => { + return(row?.student?.sex) + } + }, + // { + // title: t("columns.procedure"), + // key: "actions", + // align: "center", + // width: "25vw", + // render: (_text, record, index) => { + // return ( + // handelDelete(record)} + // onEdit={() => handleEdit(record)} + + // /> + // ); + // }, + // }, + ]; + + return columns; +}; diff --git a/src/Routes.tsx b/src/Routes.tsx index 2f7fb54..f46a3ce 100644 --- a/src/Routes.tsx +++ b/src/Routes.tsx @@ -25,6 +25,13 @@ const ReSeller = React.lazy(() => import("./Pages/Admin/Reseller/Page")); const AddReSeller = React.lazy(() => import("./Pages/Admin/Reseller/Add/Page")); const EditReSeller = React.lazy(() => import("./Pages/Admin/Reseller/Edit/Page")); +const User = React.lazy(() => import("./Pages/Admin/User/Page")); +const Param = React.lazy(() => import("./Pages/Admin/Param/Page")); + +/// RESELLER /// +const Student_Package = React.lazy(() => import("./Pages/ReSeller/StudentPackage/Page")); + + import { hasAbility } from "./utils/hasAbility"; import { ABILITIES_ENUM, ABILITIES_VALUES_ENUM } from "./enums/abilities"; import { ParamsEnum } from "./enums/params"; @@ -91,6 +98,44 @@ export const menuItems: TMenuItem[] = [ abilities_value: ABILITIES_VALUES_ENUM.INDEX, prevPath: 0, }, + { + header: "page_header.user", + element: , + icon: , + text: "sidebar.user", + path: `/${ABILITIES_ENUM?.USER}`, + abilities: ABILITIES_ENUM?.USER, + abilities_value: ABILITIES_VALUES_ENUM.INDEX, + prevPath: 0, + }, + { + header: "page_header.param", + element: , + icon: , + text: "sidebar.param", + path: `/${ABILITIES_ENUM?.PARAM}`, + abilities: ABILITIES_ENUM?.PARAM, + abilities_value: ABILITIES_VALUES_ENUM.INDEX, + prevPath: 0, + }, + + + /// RESELLER ///// + + { + header: "page_header.student_package", + element: , + icon: , + text: "sidebar.student_package", + path: `/${ABILITIES_ENUM?.Student_Package}`, + abilities: ABILITIES_ENUM?.Student_Package, + abilities_value: ABILITIES_VALUES_ENUM.INDEX, + prevPath: 0, + }, + + + + // { // header: "page_header.tags", // element: , diff --git a/src/Styles/DataTable/FillterNav.scss b/src/Styles/DataTable/FillterNav.scss index 108604b..c80e1d3 100644 --- a/src/Styles/DataTable/FillterNav.scss +++ b/src/Styles/DataTable/FillterNav.scss @@ -61,3 +61,5 @@ font-size: 16px; } } + + diff --git a/src/Styles/Layout/FilterLayout.scss b/src/Styles/Layout/FilterLayout.scss index b8a1e63..adfe679 100644 --- a/src/Styles/Layout/FilterLayout.scss +++ b/src/Styles/Layout/FilterLayout.scss @@ -73,3 +73,14 @@ } } } + + +.filter_modal_add_button, .filter_modal_cancel_button{ + padding: 20px 10px !important; +} + +@media screen and (max-width:800px) { + .filter_modal_add_button, .filter_modal_cancel_button{ + font-size: 8px !important; + } +} \ No newline at end of file diff --git a/src/api/helper/useDeleteMutation.ts b/src/api/helper/useDeleteMutation.ts index c997fc9..ea9f0c2 100644 --- a/src/api/helper/useDeleteMutation.ts +++ b/src/api/helper/useDeleteMutation.ts @@ -4,7 +4,8 @@ import { HEADER_KEY } from "../config"; import { AxiosResponse } from "../../types/Axios"; type DataToSend = { - id: number | string; + id?: number | string | any; + key?: string | any }; function useDeleteMutation( @@ -21,6 +22,7 @@ function useDeleteMutation( ["X-Custom-Message"]: toast, }, }); + return data; }, ); diff --git a/src/api/helper/useUpdateMutation.ts b/src/api/helper/useUpdateMutation.ts index b1d690e..f24a1e7 100644 --- a/src/api/helper/useUpdateMutation.ts +++ b/src/api/helper/useUpdateMutation.ts @@ -18,9 +18,11 @@ const useUpdateMutation = ( dataToSend.append("_method", "PUT"); request = dataToSend; id = dataToSend.get("id"); + console.log(dataToSend); + } else { request = { ...dataToSend, _method: "PUT" }; - id = dataToSend?.id; + id = dataToSend?.id || dataToSend?.key; } const { data } = await axios.post(url + `/` + id, request, { diff --git a/src/api/param.ts b/src/api/param.ts new file mode 100644 index 0000000..0ff6d8d --- /dev/null +++ b/src/api/param.ts @@ -0,0 +1,20 @@ +import useAddMutation from "./helper/useAddMutation"; +import useDeleteMutation from "./helper/useDeleteMutation"; +import useGetQuery from "./helper/useGetQuery"; +import useUpdateMutation from "./helper/useUpdateMutation"; + +const API = { + GET: "/param", + ADD: "/param", + DELETE: "/param", + UPDATE: "/param", +}; + +const KEY = "param"; + +export const useGetAllParam = (params?: any, options?: any) => + useGetQuery(KEY, API.GET, params, options); +export const useAddParam = () => useAddMutation(KEY, API.ADD); +export const useUpdateParam = (params?: any) => useUpdateMutation(KEY, API.GET); +export const useDeleteParam = (params?: any) => + useDeleteMutation(KEY, API.DELETE); diff --git a/src/api/studentPackage.ts b/src/api/studentPackage.ts new file mode 100644 index 0000000..cac7cbe --- /dev/null +++ b/src/api/studentPackage.ts @@ -0,0 +1,15 @@ +import useAddMutation from "./helper/useAddMutation"; +import useDeleteMutation from "./helper/useDeleteMutation"; +import useGetQuery from "./helper/useGetQuery"; +import useUpdateMutation from "./helper/useUpdateMutation"; + +const API = { + GET: "/resellers/studentPackage", + ADD: "/resellers/studentPackage", +}; + +const KEY = "studentPackage"; + +export const useGetAllStudentPackage = (params?: any, options?: any) => + useGetQuery(KEY, API.GET, params, options); +export const useAddStudentPackage = () => useAddMutation(KEY, API.ADD); diff --git a/src/config/userTypeOptions.ts b/src/config/userTypeOptions.ts new file mode 100644 index 0000000..804aad6 --- /dev/null +++ b/src/config/userTypeOptions.ts @@ -0,0 +1,5 @@ +export const userTypeOptions = [ + { id: "student", name: "student" }, + { id: "reseller", name: "reseller" }, + { id: "admin", name: "admin" }, + ] \ No newline at end of file diff --git a/src/enums/Model.ts b/src/enums/Model.ts index 65646d0..4f721c3 100644 --- a/src/enums/Model.ts +++ b/src/enums/Model.ts @@ -2,7 +2,7 @@ export enum ModalEnum { ////// division DIVISION_ADD = "division.add", //// FILLTER - + FILTER = "FILTER", FILLTER_NAV_MOVE_STUDENT = "fillter_nav.move_student", //// classes @@ -171,10 +171,21 @@ export enum ModalEnum { USER_ADD = "USER.add", USER_DELETE = "USER.delete", - /// ReSeller - RE_SELLER_EDIT = "ReSeller.edit", - RE_SELLER_ADD = "ReSeller.add", - RE_SELLER_DELETE = "ReSeller.delete", + /// ReSeller + RE_SELLER_EDIT = "ReSeller.edit", + RE_SELLER_ADD = "ReSeller.add", + RE_SELLER_DELETE = "ReSeller.delete", + /// Param + Param_EDIT = "Param.edit", + Param_ADD = "Param.add", + Param_DELETE = "Param.delete", + + ///StudentPackage + + Student_Package_EDIT = "Student_Package.edit", + Student_Package_ADD = "Student_Package.add", + Student_Package_DELETE = "Student_Package.delete", + } diff --git a/src/enums/abilities.ts b/src/enums/abilities.ts index 03a4d58..72a8e51 100644 --- a/src/enums/abilities.ts +++ b/src/enums/abilities.ts @@ -46,6 +46,8 @@ export enum ABILITIES_ENUM { Report = "report", User = "user", RE_SELLER = "reseller", + Student_Package = "student_package" + //// } diff --git a/src/translate/ar.json b/src/translate/ar.json index db5ff91..980d8dd 100644 --- a/src/translate/ar.json +++ b/src/translate/ar.json @@ -160,7 +160,11 @@ "procedure": "اجراء", "icon":"الايقونة", "canAnswersBeShuffled":"يمكن خلط الإجابات", - "phone_number":"رقم الهاتف" + "phone_number":"رقم الهاتف", + "key":"المفتاح", + "expiration_date":"تاريخ الالغاء", + "activation_date":"تاريخ التنشيط", + "first_name":"الاسم الأول" }, "practical": { "to_confirm_deletion_please_re_enter": "لتأكيد الحذف، يرجى إعادة الإدخال", @@ -276,7 +280,8 @@ "user": "مستخدم", "user_details": "تفاصيل المستخدم", "reseller_details": "تفاصيل اعادة البيع", - "reseller":"البائعين" + "reseller":"البائعين", + "student_package":"حزمة الطالب" }, "education_class_actions": { "Student_Records": "سجلات الطلاب", @@ -379,7 +384,9 @@ "answer_content": "نص السؤال", "hint": "شرح الاختيار", "hint_question": "شرح السؤال", - "_": "" + "_": "", + "key":"المفتاح", + "canAnswersBeShuffled":"يمكن خلط الإجابات" }, "select": { "Payments": { @@ -695,7 +702,9 @@ "report": "تقرير", "user": "مستخدم", "student": "الطلاب", - "reseller":"البائعين" + "reseller":"البائعين", + "param":"معامل", + "student_package":"حزمة الطالب" }, "message": { "some_thing_went_wrong": "حدث خطأ ما", @@ -720,7 +729,9 @@ "subject": "مواد", "curriculum": "مقرر", "question": "السؤال", - "user": "مستخدم" + "user": "مستخدم", + "param":"معامل", + "student_package":"حزمة الطالب" }, "page_header": { "dashboard": "لوحة القيادة / الصفحة الرئيسية", @@ -754,7 +765,9 @@ "grade": "الدرجات", "report": "تقرير", "user": "مستخدم", - "reseller":" لوحة القيادة / البائعين" + "reseller":" لوحة القيادة / البائعين", + "param":"معامل", + "student_package":"حزمة الطالب" }, "table": { "student": "قائمة الطلاب", diff --git a/src/types/Item.ts b/src/types/Item.ts index e20f9bd..1b799de 100644 --- a/src/types/Item.ts +++ b/src/types/Item.ts @@ -335,3 +335,23 @@ export type reseller = { key?: number; name: string; }; + +export type param = { + id: number; + key?: number; + value: string; +}; + + +export type Student_Package = { + id: number; + student: student; + expiration_date: string; + activation_date: string; +}; + +type student = { + first_name:string; + last_name:string; + sex:string +} \ No newline at end of file diff --git a/src/utils/formatDate.ts b/src/utils/formatDate.ts new file mode 100644 index 0000000..24255fb --- /dev/null +++ b/src/utils/formatDate.ts @@ -0,0 +1,10 @@ +export const formatDate = (dateString:any) => { + if (!dateString) return null; // Handle empty date string + + const date = new Date(dateString); + const year = date.getFullYear(); + const month = String(date.getMonth() + 1).padStart(2, '0'); // Months are zero-based + const day = String(date.getDate()).padStart(2, '0'); + + return `${year}-${month}-${day}`; // Return formatted date + }; \ No newline at end of file diff --git a/src/utils/hasAbilityFn.ts b/src/utils/hasAbilityFn.ts index 99c0d46..1d1c1e0 100644 --- a/src/utils/hasAbilityFn.ts +++ b/src/utils/hasAbilityFn.ts @@ -640,3 +640,41 @@ export const canShowReSeller = hasAbility( ABILITIES_ENUM.RE_SELLER, ABILITIES_VALUES_ENUM.SHOW, ); + + +/// Param + +export const canAddParam = hasAbility( + ABILITIES_ENUM.PARAM, + ABILITIES_VALUES_ENUM.STORE, +); + +export const canEditParam = hasAbility( + ABILITIES_ENUM.PARAM, + ABILITIES_VALUES_ENUM.UPDATE, +); +export const canDeleteParam = hasAbility( + ABILITIES_ENUM.PARAM, + ABILITIES_VALUES_ENUM.DELETE, +); +export const canShowParam = hasAbility( + ABILITIES_ENUM.PARAM, + ABILITIES_VALUES_ENUM.SHOW, +); + + +/// User + +export const canAddStudent_Package = hasAbility( + ABILITIES_ENUM.Student_Package, + ABILITIES_VALUES_ENUM.STORE, +); + +export const canEditStudent_Package = hasAbility( + ABILITIES_ENUM.Student_Package, + ABILITIES_VALUES_ENUM.UPDATE, +); +export const canDeleteStudent_Package = hasAbility( + ABILITIES_ENUM.Student_Package, + ABILITIES_VALUES_ENUM.DELETE, +); diff --git a/src/utils/useFormatDataToSelect.tsx b/src/utils/useFormatDataToSelect.tsx index 9cccc79..0f19b87 100644 --- a/src/utils/useFormatDataToSelect.tsx +++ b/src/utils/useFormatDataToSelect.tsx @@ -2,6 +2,7 @@ const useFormatDataToSelect = (Data: any) => { const format = (data: any) => { if (!Array.isArray(data)) return []; // Check if data is an array return data?.map((item: any) => ({ + value: item?.id, label: item?.name ?? item?.title, }));