diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 9aa8618..8ba7c30 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -21,6 +21,7 @@ "luxon": "^3.0.4", "react": "^18.1.0", "react-big-calendar": "^1.5.0", + "react-date-picker": "^9.1.0", "react-dom": "^18.1.0", "react-hook-form": "^7.31.3", "react-modal": "^3.16.1", @@ -29,6 +30,7 @@ "react-scripts": "5.0.1", "react-select": "^5.3.2", "typescript": "^4.6.4", + "use-local-storage-state": "^18.1.1", "web-vitals": "^2.1.4" }, "devDependencies": { @@ -3887,6 +3889,14 @@ "@types/react": "*" } }, + "node_modules/@types/react-calendar": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/@types/react-calendar/-/react-calendar-3.9.0.tgz", + "integrity": "sha512-KpAu1MKAGFw5hNwlDnWsHWqI9i/igAB+8jH97YV7QpC2v7rlwNEU5i6VMFb73lGRacuejM/Zd2LklnEzkFV3XA==", + "dependencies": { + "@types/react": "*" + } + }, "node_modules/@types/react-dom": { "version": "18.0.4", "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.0.4.tgz", @@ -4344,6 +4354,14 @@ "@xtuc/long": "4.2.2" } }, + "node_modules/@wojtekmaj/date-utils": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@wojtekmaj/date-utils/-/date-utils-1.0.3.tgz", + "integrity": "sha512-1VPkkTBk07gMR1fjpBtse4G+oJqpmE+0gUFB0dg3VIL7qJmUVaBoD/vlzMm/jNeOPfvlmerl1lpnsZyBUFIRuw==", + "funding": { + "url": "https://github.com/wojtekmaj/date-utils?sponsor=1" + } + }, "node_modules/@xtuc/ieee754": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", @@ -6411,6 +6429,11 @@ "npm": "1.2.8000 || >= 1.4.16" } }, + "node_modules/detect-element-overflow": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/detect-element-overflow/-/detect-element-overflow-1.2.0.tgz", + "integrity": "sha512-Jtr9ivYPhpd9OJux+hjL0QjUKiS1Ghgy8tvIufUjFslQgIWvgGr4mn57H190APbKkiOmXnmtMI6ytaKzMusecg==" + }, "node_modules/detect-newline": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", @@ -8261,6 +8284,17 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/get-user-locale": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/get-user-locale/-/get-user-locale-1.5.1.tgz", + "integrity": "sha512-WiNpoFRcHn1qxP9VabQljzGwkAQDrcpqUtaP0rNBEkFxJdh4f3tik6MfZsMYZc+UgQJdGCxWEjL9wnCUlRQXag==", + "dependencies": { + "lodash.memoize": "^4.1.1" + }, + "funding": { + "url": "https://github.com/wojtekmaj/get-user-locale?sponsor=1" + } + }, "node_modules/glob": { "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", @@ -11577,6 +11611,14 @@ "semver": "bin/semver.js" } }, + "node_modules/make-event-props": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/make-event-props/-/make-event-props-1.3.0.tgz", + "integrity": "sha512-oWiDZMcVB1/A487251hEWza1xzgCzl6MXxe9aF24l5Bt9N9UEbqTqKumEfuuLhmlhRZYnc+suVvW4vUs8bwO7Q==", + "funding": { + "url": "https://github.com/wojtekmaj/make-event-props?sponsor=1" + } + }, "node_modules/makeerror": { "version": "1.0.12", "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", @@ -13854,6 +13896,47 @@ "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-6.0.0.tgz", "integrity": "sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw==" }, + "node_modules/react-calendar": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/react-calendar/-/react-calendar-4.0.0.tgz", + "integrity": "sha512-y9Q5Oo3Mq869KExbOCP3aJ3hEnRZKZ0TqUa9QU1wJGgDZFrW1qTaWp5v52oZpmxTTrpAMTUcUGaC0QJcO1f8Nw==", + "dependencies": { + "@wojtekmaj/date-utils": "^1.0.2", + "clsx": "^1.2.1", + "get-user-locale": "^1.2.0", + "prop-types": "^15.6.0" + }, + "funding": { + "url": "https://github.com/wojtekmaj/react-calendar?sponsor=1" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/react-date-picker": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/react-date-picker/-/react-date-picker-9.1.0.tgz", + "integrity": "sha512-wj9SoOhEgQTzJsDRLePpNzUDNrcSiCpj1TFSwiAnLlOuJvvkk10I9rdvIyHmeJg/G17hyP5wSwTppCZHqOTHhA==", + "dependencies": { + "@types/react-calendar": "^3.0.0", + "@wojtekmaj/date-utils": "^1.0.3", + "clsx": "^1.2.1", + "get-user-locale": "^1.2.0", + "make-event-props": "^1.1.0", + "prop-types": "^15.6.0", + "react-calendar": "^4.0.0", + "react-fit": "^1.4.0", + "update-input-width": "^1.2.2" + }, + "funding": { + "url": "https://github.com/wojtekmaj/react-date-picker?sponsor=1" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, "node_modules/react-dev-utils": { "version": "12.0.1", "resolved": "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-12.0.1.tgz", @@ -13988,6 +14071,23 @@ "resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.11.tgz", "integrity": "sha512-/6UZ2qgEyH2aqzYZgQPxEnz33NJ2gNsnHA2o5+o4wW9bLM/JYQitNP9xPhsXwC08hMMovfGe/8retsdDsczPRg==" }, + "node_modules/react-fit": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/react-fit/-/react-fit-1.4.0.tgz", + "integrity": "sha512-cf9sFKbr1rlTB9fNIKE5Uy4NCMUOqrX2mdJ69V4RtmV4KubPdtnbIP1tEar16GXaToCRr7I7c9d2wkTNk9TV5g==", + "dependencies": { + "detect-element-overflow": "^1.2.0", + "prop-types": "^15.6.0", + "tiny-warning": "^1.0.0" + }, + "funding": { + "url": "https://github.com/wojtekmaj/react-fit?sponsor=1" + }, + "peerDependencies": { + "react": "^15.5.0 || ^16.0.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^15.5.0 || ^16.0.0 || ^17.0.0 || ^18.0.0" + } + }, "node_modules/react-hook-form": { "version": "7.31.3", "resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.31.3.tgz", @@ -15700,6 +15800,11 @@ "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz", "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==" }, + "node_modules/tiny-warning": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz", + "integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==" + }, "node_modules/tmpl": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", @@ -15999,6 +16104,14 @@ "yarn": "*" } }, + "node_modules/update-input-width": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/update-input-width/-/update-input-width-1.2.2.tgz", + "integrity": "sha512-6QwD9ZVSXb96PxOZ01DU0DJTPwQGY7qBYgdniZKJN02Xzom2m+9J6EPxMbefskqtj4x78qbe5psDSALq9iNEYg==", + "funding": { + "url": "https://github.com/wojtekmaj/update-input-width?sponsor=1" + } + }, "node_modules/uri-js": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", @@ -16007,6 +16120,21 @@ "punycode": "^2.1.0" } }, + "node_modules/use-local-storage-state": { + "version": "18.1.1", + "resolved": "https://registry.npmjs.org/use-local-storage-state/-/use-local-storage-state-18.1.1.tgz", + "integrity": "sha512-09bl6q3mkSlkEt8KeBPCmdPEWEojWYF70Qbz+7wkfQX1feaFITM9m84+h0Jr6Cnf/IvpahkFh7UbX2VNN3ioTQ==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/astoilkov" + }, + "peerDependencies": { + "react": ">=18", + "react-dom": ">=18" + } + }, "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", @@ -19682,6 +19810,14 @@ "@types/react": "*" } }, + "@types/react-calendar": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/@types/react-calendar/-/react-calendar-3.9.0.tgz", + "integrity": "sha512-KpAu1MKAGFw5hNwlDnWsHWqI9i/igAB+8jH97YV7QpC2v7rlwNEU5i6VMFb73lGRacuejM/Zd2LklnEzkFV3XA==", + "requires": { + "@types/react": "*" + } + }, "@types/react-dom": { "version": "18.0.4", "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.0.4.tgz", @@ -20036,6 +20172,11 @@ "@xtuc/long": "4.2.2" } }, + "@wojtekmaj/date-utils": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@wojtekmaj/date-utils/-/date-utils-1.0.3.tgz", + "integrity": "sha512-1VPkkTBk07gMR1fjpBtse4G+oJqpmE+0gUFB0dg3VIL7qJmUVaBoD/vlzMm/jNeOPfvlmerl1lpnsZyBUFIRuw==" + }, "@xtuc/ieee754": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", @@ -21551,6 +21692,11 @@ "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==" }, + "detect-element-overflow": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/detect-element-overflow/-/detect-element-overflow-1.2.0.tgz", + "integrity": "sha512-Jtr9ivYPhpd9OJux+hjL0QjUKiS1Ghgy8tvIufUjFslQgIWvgGr4mn57H190APbKkiOmXnmtMI6ytaKzMusecg==" + }, "detect-newline": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", @@ -22902,6 +23048,14 @@ "get-intrinsic": "^1.1.1" } }, + "get-user-locale": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/get-user-locale/-/get-user-locale-1.5.1.tgz", + "integrity": "sha512-WiNpoFRcHn1qxP9VabQljzGwkAQDrcpqUtaP0rNBEkFxJdh4f3tik6MfZsMYZc+UgQJdGCxWEjL9wnCUlRQXag==", + "requires": { + "lodash.memoize": "^4.1.1" + } + }, "glob": { "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", @@ -25317,6 +25471,11 @@ } } }, + "make-event-props": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/make-event-props/-/make-event-props-1.3.0.tgz", + "integrity": "sha512-oWiDZMcVB1/A487251hEWza1xzgCzl6MXxe9aF24l5Bt9N9UEbqTqKumEfuuLhmlhRZYnc+suVvW4vUs8bwO7Q==" + }, "makeerror": { "version": "1.0.12", "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", @@ -26825,6 +26984,33 @@ } } }, + "react-calendar": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/react-calendar/-/react-calendar-4.0.0.tgz", + "integrity": "sha512-y9Q5Oo3Mq869KExbOCP3aJ3hEnRZKZ0TqUa9QU1wJGgDZFrW1qTaWp5v52oZpmxTTrpAMTUcUGaC0QJcO1f8Nw==", + "requires": { + "@wojtekmaj/date-utils": "^1.0.2", + "clsx": "^1.2.1", + "get-user-locale": "^1.2.0", + "prop-types": "^15.6.0" + } + }, + "react-date-picker": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/react-date-picker/-/react-date-picker-9.1.0.tgz", + "integrity": "sha512-wj9SoOhEgQTzJsDRLePpNzUDNrcSiCpj1TFSwiAnLlOuJvvkk10I9rdvIyHmeJg/G17hyP5wSwTppCZHqOTHhA==", + "requires": { + "@types/react-calendar": "^3.0.0", + "@wojtekmaj/date-utils": "^1.0.3", + "clsx": "^1.2.1", + "get-user-locale": "^1.2.0", + "make-event-props": "^1.1.0", + "prop-types": "^15.6.0", + "react-calendar": "^4.0.0", + "react-fit": "^1.4.0", + "update-input-width": "^1.2.2" + } + }, "react-dev-utils": { "version": "12.0.1", "resolved": "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-12.0.1.tgz", @@ -26925,6 +27111,16 @@ "resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.11.tgz", "integrity": "sha512-/6UZ2qgEyH2aqzYZgQPxEnz33NJ2gNsnHA2o5+o4wW9bLM/JYQitNP9xPhsXwC08hMMovfGe/8retsdDsczPRg==" }, + "react-fit": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/react-fit/-/react-fit-1.4.0.tgz", + "integrity": "sha512-cf9sFKbr1rlTB9fNIKE5Uy4NCMUOqrX2mdJ69V4RtmV4KubPdtnbIP1tEar16GXaToCRr7I7c9d2wkTNk9TV5g==", + "requires": { + "detect-element-overflow": "^1.2.0", + "prop-types": "^15.6.0", + "tiny-warning": "^1.0.0" + } + }, "react-hook-form": { "version": "7.31.3", "resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.31.3.tgz", @@ -28194,6 +28390,11 @@ "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz", "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==" }, + "tiny-warning": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz", + "integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==" + }, "tmpl": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", @@ -28416,6 +28617,11 @@ "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==" }, + "update-input-width": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/update-input-width/-/update-input-width-1.2.2.tgz", + "integrity": "sha512-6QwD9ZVSXb96PxOZ01DU0DJTPwQGY7qBYgdniZKJN02Xzom2m+9J6EPxMbefskqtj4x78qbe5psDSALq9iNEYg==" + }, "uri-js": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", @@ -28424,6 +28630,12 @@ "punycode": "^2.1.0" } }, + "use-local-storage-state": { + "version": "18.1.1", + "resolved": "https://registry.npmjs.org/use-local-storage-state/-/use-local-storage-state-18.1.1.tgz", + "integrity": "sha512-09bl6q3mkSlkEt8KeBPCmdPEWEojWYF70Qbz+7wkfQX1feaFITM9m84+h0Jr6Cnf/IvpahkFh7UbX2VNN3ioTQ==", + "requires": {} + }, "util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", diff --git a/frontend/package.json b/frontend/package.json index 0ff5e33..3bc328d 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -16,6 +16,7 @@ "luxon": "^3.0.4", "react": "^18.1.0", "react-big-calendar": "^1.5.0", + "react-date-picker": "^9.1.0", "react-dom": "^18.1.0", "react-hook-form": "^7.31.3", "react-modal": "^3.16.1", @@ -24,6 +25,7 @@ "react-scripts": "5.0.1", "react-select": "^5.3.2", "typescript": "^4.6.4", + "use-local-storage-state": "^18.1.1", "web-vitals": "^2.1.4" }, "scripts": { diff --git a/frontend/src/api/enrollment.ts b/frontend/src/api/enrollment.ts index 4b92521..5970030 100644 --- a/frontend/src/api/enrollment.ts +++ b/frontend/src/api/enrollment.ts @@ -2,6 +2,7 @@ import axiosInstance from './axiosInstance' export const getEnrollmentList = ( params: Partial<{ + year_group_id: number page: number per_page: number name: string @@ -17,6 +18,9 @@ export const getEnrollmentList = ( email: string mode: number }[] - }>('http://127.0.0.1:5000/api/students/registrations/', { - params, - }) + }>( + `http://127.0.0.1:5000/api/students/registrations/${params.year_group_id}`, + { + params, + }, + ) diff --git a/frontend/src/api/groups.ts b/frontend/src/api/groups.ts index 8119472..2d3d720 100644 --- a/frontend/src/api/groups.ts +++ b/frontend/src/api/groups.ts @@ -20,22 +20,24 @@ export interface Group { export const getGroups = ( params: Partial<{ + year_group_id: number page: number per_page: number name: string }>, ) => axiosInstance.get<{ max_pages: number; groups: Group[] }>( - 'http://127.0.0.1:5000/api/coordinator/groups/', + `http://127.0.0.1:5000/api/coordinator/groups/${params.year_group_id}`, { params, }, ) -export const createGroup = (payload: CreateGroup) => - axiosInstance.post('http://127.0.0.1:5000/api/coordinator/groups/', payload) +export const createGroup = (year_group_id: number, payload: CreateGroup) => + axiosInstance.post( + `http://127.0.0.1:5000/api/coordinator/groups/${year_group_id}`, + payload, + ) - export const deleteGroup = (id: number) => - axiosInstance.delete( - `http://127.0.0.1:5000/api/coordinator/groups/${id}/`, - ) \ No newline at end of file +export const deleteGroup = (id: number) => + axiosInstance.delete(`http://127.0.0.1:5000/api/coordinator/groups/${id}/`) diff --git a/frontend/src/api/leaders.ts b/frontend/src/api/leaders.ts index 3090db2..c148e34 100644 --- a/frontend/src/api/leaders.ts +++ b/frontend/src/api/leaders.ts @@ -19,6 +19,7 @@ export interface Leader { export const getLeaders = ( params: Partial<{ + year_group_id: number fullname: string order_by_first_name: OrderType order_by_last_name: OrderType @@ -27,7 +28,7 @@ export const getLeaders = ( }> = {}, ) => axiosInstance.get( - 'http://127.0.0.1:5000/api/coordinator/project_supervisor', + `http://127.0.0.1:5000/api/coordinator/project_supervisor/${params.year_group_id}`, { params }, ) diff --git a/frontend/src/api/schedule.ts b/frontend/src/api/schedule.ts index 5a4ac70..eab074e 100644 --- a/frontend/src/api/schedule.ts +++ b/frontend/src/api/schedule.ts @@ -1,39 +1,39 @@ import axiosInstance from './axiosInstance' -export const getEvents = (scheduleId: number) => { +export const getTermsOfDefences = (scheduleId: number) => { return axiosInstance.get<{ - enrollments: { + term_of_defences: { id: number start_date: string end_date: string title: string - committee: { + members_of_committee: { members: { first_name: string; last_name: string }[] } group: { name: string } }[] }>( - `http://127.0.0.1:5000/api/examination_schedule/enrollments/${scheduleId}/coordinator-view/?per_page=10000`, + `http://127.0.0.1:5000/api/coordinator/enrollments/${scheduleId}/term-of-defences/`, ) } -export const getStudentsSchedule = (scheduleId: number) => { +export const getStudentsTermsOfDefences = (scheduleId: number) => { return axiosInstance.get<{ - enrollments: { + term_of_defences: { id: number start_date: string end_date: string title: string - committee: { + members_of_committee: { members: { first_name: string; last_name: string }[] } group: { name: string } }[] }>( - `http://127.0.0.1:5000/api/examination_schedule/enrollments/${scheduleId}/student-view?per_page=10000`, + `http://127.0.0.1:5000/api/students/examination-schedule/${scheduleId}/enrollments/`, ) } -export const getSchedules = () => { +export const getSchedules = (year_group_id: number = 1) => { return axiosInstance.get<{ examination_schedules: { id: number @@ -43,7 +43,7 @@ export const getSchedules = () => { mode: boolean }[] }>( - 'http://127.0.0.1:5000/api/coordinator/examination_schedule/?per_page=10000', + `http://127.0.0.1:5000/api/coordinator/examination_schedule/${year_group_id}?per_page=10000`, ) } @@ -51,27 +51,30 @@ export const createEvent = ({ start_date, end_date, scheduleId, + project_supervisors, }: { start_date: string end_date: string scheduleId: number + project_supervisors: number[] }) => { return axiosInstance.post( - `http://127.0.0.1:5000/api/coordinator/enrollments/${scheduleId}/`, + `http://127.0.0.1:5000/api/coordinator/enrollments/${scheduleId}/add`, { start_date, end_date, + project_supervisors, }, ) } -export const createSchedule = (title: string) => { +export const createSchedule = ( + year_group_id: number, + payload: { title: string; start_date: string; end_date: string }, +) => { return axiosInstance.post( - 'http://127.0.0.1:5000/api/coordinator/examination_schedule/', - { - title, - mode: true, - }, + `http://127.0.0.1:5000/api/coordinator/examination_schedule/${year_group_id}/`, + payload, ) } diff --git a/frontend/src/api/students.ts b/frontend/src/api/students.ts index fcec34c..d18e191 100644 --- a/frontend/src/api/students.ts +++ b/frontend/src/api/students.ts @@ -18,6 +18,7 @@ export interface Student { export const getStudents = ( params: Partial<{ + year_group_id: number fullname: string order_by_first_name: OrderType order_by_last_name: OrderType @@ -27,7 +28,7 @@ export const getStudents = ( }> = {}, ) => axiosInstance.get( - 'http://127.0.0.1:5000/api/coordinator/students', + `http://127.0.0.1:5000/api/coordinator/students/${params.year_group_id}`, { params }, ) diff --git a/frontend/src/views/Login.tsx b/frontend/src/views/Login.tsx index 8bb6124..c126c1e 100644 --- a/frontend/src/views/Login.tsx +++ b/frontend/src/views/Login.tsx @@ -1,6 +1,11 @@ import { NavLink } from 'react-router-dom' +import useLocalStorageState from 'use-local-storage-state' const Login = () => { + const [yearGroupId, setYearGroupId] = useLocalStorageState('yearGroupId', { + defaultValue: 1, + }) + return ( <>
diff --git a/frontend/src/views/coordinator/AddGroup.tsx b/frontend/src/views/coordinator/AddGroup.tsx index 2f70125..2b779ed 100644 --- a/frontend/src/views/coordinator/AddGroup.tsx +++ b/frontend/src/views/coordinator/AddGroup.tsx @@ -6,6 +6,7 @@ import { createGroup, CreateGroup } from '../../api/groups' import InputError from '../../components/InputError' import Select from 'react-select' import { getLeaders } from '../../api/leaders' +import useLocalStorageState from 'use-local-storage-state' type SelectValue = { value: string | number @@ -14,6 +15,8 @@ type SelectValue = { const AddGroup = () => { const [isAlertVisible, setIsAlertVisible] = useState(false) + const [yearGroupId] = useLocalStorageState('yearGroupId') + const { register, handleSubmit, @@ -29,13 +32,14 @@ const AddGroup = () => { { onSuccess: (data) => { setStudentOptions( - data?.data.students.filter(st => st.group === null) + data?.data.students + .filter((st) => st.group === null) .map(({ first_name, last_name, index }) => { - return { - value: index, - label: `${first_name} ${last_name} (${index})`, - } - }), + return { + value: index, + label: `${first_name} ${last_name} (${index})`, + } + }), ) }, }, @@ -46,12 +50,12 @@ const AddGroup = () => { { onSuccess: (data) => { setSupervisorOptions( - data?.data.project_supervisors.filter(ld => ld.count_groups < ld.limit_group).map( - ({ id, first_name, last_name }) => ({ + data?.data.project_supervisors + .filter((ld) => ld.count_groups < ld.limit_group) + .map(({ id, first_name, last_name }) => ({ value: id, label: `${first_name} ${last_name}`, - }), - ), + })), ) }, }, @@ -59,7 +63,7 @@ const AddGroup = () => { const { mutate: mutateCreateGroup } = useMutation( 'createGroup', - (payload: CreateGroup) => createGroup(payload), + (payload: CreateGroup) => createGroup(Number(yearGroupId), payload), { onSuccess: () => { setIsAlertVisible(true) diff --git a/frontend/src/views/coordinator/EditSchedule.tsx b/frontend/src/views/coordinator/EditSchedule.tsx index 7938b7b..522a2a7 100644 --- a/frontend/src/views/coordinator/EditSchedule.tsx +++ b/frontend/src/views/coordinator/EditSchedule.tsx @@ -25,7 +25,7 @@ const EditSchedule = ({ scheduleId: string }) => { const { register, handleSubmit, reset, control } = useForm<{ - committee: NestedValue + members_of_committee: NestedValue }>({ mode: 'onBlur' }) const [committeeOptions, setCommitteeOptions] = useState([]) @@ -56,7 +56,7 @@ const EditSchedule = ({ ) const onSubmit = (data: any) => { - data?.committee?.forEach((id: number) => { + data?.members_of_committee?.forEach((id: number) => { mutateAssignSupervisor({ scheduleId: Number(scheduleId), enrollmentId: eventData.id, @@ -94,12 +94,12 @@ const EditSchedule = ({ <>
-
diff --git a/frontend/src/views/coordinator/Schedules.tsx b/frontend/src/views/coordinator/Schedules.tsx index 0abaf4b..c0e2ebb 100644 --- a/frontend/src/views/coordinator/Schedules.tsx +++ b/frontend/src/views/coordinator/Schedules.tsx @@ -2,11 +2,19 @@ import { useMutation, useQuery } from 'react-query' import { createSchedule, getSchedules } from '../../api/schedule' import { useForm } from 'react-hook-form' import { Link } from 'react-router-dom' +import useLocalStorageState from 'use-local-storage-state' +import DatePicker from 'react-date-picker' +import { useState } from 'react' const Schedules = () => { - const { register, handleSubmit } = useForm<{ title: string }>({ + const { register, handleSubmit } = useForm<{ + title: string + }>({ mode: 'onBlur', }) + const [yearGroupId] = useLocalStorageState('yearGroupId') + const [startDate, setStartDate] = useState(new Date()) + const [endDate, setEndDate] = useState(new Date()) const { data: schedules, refetch } = useQuery(['getSchedules'], () => getSchedules(), @@ -14,7 +22,8 @@ const Schedules = () => { const { mutate: mutateCreateSchedule } = useMutation( ['createSchedule'], - ({ title }: { title: string }) => createSchedule(title), + (payload: { title: string; start_date: string; end_date: string }) => + createSchedule(Number(yearGroupId), payload), { onSuccess: () => { refetch() @@ -23,7 +32,11 @@ const Schedules = () => { ) const onSubmit = (data: any) => { - mutateCreateSchedule(data) + mutateCreateSchedule({ + ...data, + start_date: startDate.toISOString(), + end_date: endDate.toISOString(), + }) } return ( @@ -42,6 +55,17 @@ const Schedules = () => { type="text" {...register('title', { required: true })} /> + + + + + + +
diff --git a/frontend/src/views/coordinator/Students.tsx b/frontend/src/views/coordinator/Students.tsx index c0ca585..5a81491 100644 --- a/frontend/src/views/coordinator/Students.tsx +++ b/frontend/src/views/coordinator/Students.tsx @@ -9,6 +9,7 @@ import { } from '../../api/students' import classNames from 'classnames' import { ReactComponent as IconRemove } from '../../assets/svg/icon-remove.svg' +import useLocalStorageState from 'use-local-storage-state' const Students = () => { let navigate = useNavigate() @@ -16,6 +17,7 @@ const Students = () => { const [page, setPage] = useState(1) const [perPage, setPerPage] = useState(10) const [mode, setMode] = useState(true) + const [yearGroupId] = useLocalStorageState('yearGroupId') const perPageOptions = [ { @@ -41,7 +43,12 @@ const Students = () => { data: students, refetch: refetchStudents, } = useQuery(['students', page, perPage, mode], () => - getStudents({ page, per_page: perPage, mode }), + getStudents({ + year_group_id: Number(yearGroupId), + page, + per_page: perPage, + mode, + }), ) const { mutate: mutateDownload } = useMutation( diff --git a/frontend/src/views/student/Enrollment.tsx b/frontend/src/views/student/Enrollment.tsx index 707aaf6..2b58105 100644 --- a/frontend/src/views/student/Enrollment.tsx +++ b/frontend/src/views/student/Enrollment.tsx @@ -1,13 +1,21 @@ import { useState } from 'react' import { useQuery } from 'react-query' +import useLocalStorageState from 'use-local-storage-state' import { getEnrollmentList } from '../../api/enrollment' const Enrollment = () => { const [showAvailable, setShowAvailable] = useState(false) const [mode, setMode] = useState(true) + const [yearGroupId] = useLocalStorageState('yearGroupId') + const { isLoading, data: enrollmentData } = useQuery( ['enrollment', mode], - () => getEnrollmentList({ per_page: 1000, mode }), + () => + getEnrollmentList({ + year_group_id: Number(yearGroupId), + per_page: 1000, + mode, + }), ) if (isLoading) { return
Ładowanie
diff --git a/frontend/src/views/student/StudentSchedule.tsx b/frontend/src/views/student/StudentSchedule.tsx index 46ce58a..6a63f30 100644 --- a/frontend/src/views/student/StudentSchedule.tsx +++ b/frontend/src/views/student/StudentSchedule.tsx @@ -2,7 +2,7 @@ import { Calendar, luxonLocalizer, Views } from 'react-big-calendar' import { DateTime, Settings } from 'luxon' import { useCallback, useState } from 'react' import { useQuery } from 'react-query' -import { getStudentsSchedule } from '../../api/schedule' +import { getStudentsTermsOfDefences } from '../../api/schedule' import { useParams } from 'react-router-dom' import Modal from 'react-modal' import { useForm } from 'react-hook-form' @@ -54,17 +54,17 @@ const StudentSchedule = () => { const { refetch } = useQuery( ['studentSchedules'], - () => getStudentsSchedule(Number(id)), + () => getStudentsTermsOfDefences(Number(id)), { onSuccess: (data) => { setEvents( - data.data.enrollments.map( + data.data.term_of_defences.map( ({ id, start_date, end_date, title = 'Obrona', - committee, + members_of_committee, group, }) => { return { @@ -73,8 +73,8 @@ const StudentSchedule = () => { start: new Date(start_date), end: new Date(end_date), resource: { - committee, group, + members_of_committee, }, } },