From 2120ab969003d844b4f0957e9aa208d1d6812a57 Mon Sep 17 00:00:00 2001 From: adam-skowronek Date: Thu, 17 Nov 2022 21:36:36 +0100 Subject: [PATCH] Update login, update api requests, add schedule view for supervisors --- frontend/src/App.tsx | 2 + frontend/src/api/leaders.ts | 3 +- frontend/src/api/schedule.ts | 86 ++++-- frontend/src/api/yearGroups.ts | 25 ++ frontend/src/views/Login.tsx | 106 +++++++- frontend/src/views/coordinator/AddGroup.tsx | 4 +- frontend/src/views/coordinator/AddLeader.tsx | 46 +--- .../src/views/coordinator/EditSchedule.tsx | 4 +- frontend/src/views/coordinator/Leaders.tsx | 7 +- frontend/src/views/coordinator/Schedule.tsx | 60 +++- frontend/src/views/coordinator/Schedules.tsx | 21 +- .../src/views/student/ScheduleAddGroup.tsx | 19 +- .../src/views/student/StudentSchedule.tsx | 4 +- .../views/supervisor/SupervisorSchedule.tsx | 256 ++++++++++++++++++ .../views/supervisor/SupervisorSchedules.tsx | 2 +- 15 files changed, 544 insertions(+), 101 deletions(-) create mode 100644 frontend/src/api/yearGroups.ts create mode 100644 frontend/src/views/supervisor/SupervisorSchedule.tsx diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index ba2683d..ec47ce0 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -19,6 +19,7 @@ import Schedule from './views/coordinator/Schedule' import SupervisorSchedules from './views/supervisor/SupervisorSchedules' import StudentSchedules from './views/student/StudentSchedules' import StudentSchedule from './views/student/StudentSchedule' +import SupervisorSchedule from './views/supervisor/SupervisorSchedule' const queryClient = new QueryClient({ defaultOptions: { @@ -55,6 +56,7 @@ function App() { } /> } /> } /> + } /> diff --git a/frontend/src/api/leaders.ts b/frontend/src/api/leaders.ts index 9f33f7f..54cda5a 100644 --- a/frontend/src/api/leaders.ts +++ b/frontend/src/api/leaders.ts @@ -14,7 +14,6 @@ export interface Leader { email: string limit_group: number count_groups: number - mode: number } export const getLeaders = ( @@ -32,7 +31,7 @@ export const getLeaders = ( { params }, ) -export const createLeader = (payload: Leader) => +export const createLeader = (payload: Partial) => axiosInstance.post('coordinator/project_supervisor/', payload) export const deleteLeader = (id: number) => diff --git a/frontend/src/api/schedule.ts b/frontend/src/api/schedule.ts index 7a26be2..a45e783 100644 --- a/frontend/src/api/schedule.ts +++ b/frontend/src/api/schedule.ts @@ -1,34 +1,45 @@ import axiosInstance from './axiosInstance' +interface TermOfDefences { + id: number + start_date: string + end_date: string + title: string + members_of_committee: { + members: { first_name: string; last_name: string }[] + } + group: { name: string } +} + export const getTermsOfDefences = (scheduleId: number) => { return axiosInstance.get<{ - term_of_defences: { - id: number - start_date: string - end_date: string - title: string - members_of_committee: { - members: { first_name: string; last_name: string }[] - } - group: { name: string } - }[] + term_of_defences: TermOfDefences[] }>(`coordinator/enrollments/${scheduleId}/term-of-defences/`) } -export const getStudentsTermsOfDefences = (scheduleId: number) => { +export const getStudentsTermsOfDefences = ( + scheduleId: number, + studentIndex: number, +) => { return axiosInstance.get<{ - term_of_defences: { - id: number - start_date: string - end_date: string - title: string - members_of_committee: { - members: { first_name: string; last_name: string }[] - } - group: { name: string } - }[] - }>(`students/examination-schedule/${scheduleId}/enrollments/`) + term_of_defences: TermOfDefences[] + }>( + `students/examination-schedule/${scheduleId}/enrollments?student_index=${studentIndex}`, + ) } + +export const getSupervisorTermsOfDefences = (scheduleId: number) => { + return axiosInstance.get<{ + term_of_defences: TermOfDefences[] + }>(`project_supervisor/${scheduleId}/term-of-defences?id=1`) //fix hardcode id +} + +export const getAvailabilityForSupervisor = (scheduleId: number) => { + return axiosInstance.get<{ + free_times: { id: number; start_date: string; end_date: string }[] + }>(`project_supervisor/${scheduleId}/temporary-availabilities?id=1`) //fix hardcode id +} + export const getSchedules = (year_group_id: number = 1) => { return axiosInstance.get<{ examination_schedules: { @@ -125,3 +136,34 @@ export const downloadSchedule = (scheduleId: number) => responseType: 'blob', }, ) + +export const addAvailability = ({ + start_date, + end_date, + scheduleId, + project_supervisor_id, +}: { + start_date: string + end_date: string + scheduleId: number + project_supervisor_id: number +}) => { + return axiosInstance.post(`project_supervisor/${scheduleId}/enrollments/`, { + start_date, + end_date, + project_supervisor_id, + }) +} + +export const setDateOfExaminationSchedule = ( + scheduleId: number, + payload: { + start_date_for_enrollment_students: string + end_date_for_enrollment_students: string + }, +) => { + return axiosInstance.put( + `coordinator/examination_schedule/${scheduleId}/date`, + payload, + ) +} diff --git a/frontend/src/api/yearGroups.ts b/frontend/src/api/yearGroups.ts new file mode 100644 index 0000000..1599d4a --- /dev/null +++ b/frontend/src/api/yearGroups.ts @@ -0,0 +1,25 @@ +import axiosInstance from './axiosInstance' + +export interface CreateYearGroup { + name: string + mode: string +} + +export interface YearGroup { + id: number + mode: string + name: string +} + +export const getYearGroups = ( + params: Partial<{ + page: number + per_page: number + }>, +) => + axiosInstance.get<{ max_pages: number; year_groups: YearGroup[] }>( + `coordinator/year-group`, + { + params, + }, + ) diff --git a/frontend/src/views/Login.tsx b/frontend/src/views/Login.tsx index c126c1e..c9108ca 100644 --- a/frontend/src/views/Login.tsx +++ b/frontend/src/views/Login.tsx @@ -1,10 +1,71 @@ -import { NavLink } from 'react-router-dom' +import { useState } from 'react' +import { useQuery } from 'react-query' +import { NavLink, useNavigate } from 'react-router-dom' +import { InputActionMeta } from 'react-select' +import Select from 'react-select' import useLocalStorageState from 'use-local-storage-state' +import { getStudents } from '../api/students' +import { getYearGroups } from '../api/yearGroups' + +type SelectValue = { + value: string | number + label: string +} const Login = () => { + const navigate = useNavigate() + const [yearGroupId, setYearGroupId] = useLocalStorageState('yearGroupId', { defaultValue: 1, }) + const [studentId, setStudentId] = useLocalStorageState('studentId') + const [supervisorId, setSupervisorId] = useLocalStorageState('supervisorId', { + defaultValue: 1, + }) + const [studentOptions, setStudentOptions] = useState([]) + const [yearGroupOptions, setYearGroupOptions] = useState([]) + const [selectedYear, setSelectedYear] = useState() + const [selectedRole, setSelectedRole] = useState() + + useQuery( + 'students', + () => getStudents({ year_group_id: yearGroupId, per_page: 1000 }), + { + onSuccess: (data) => { + setStudentOptions( + data?.data.students.map(({ first_name, last_name, index }) => { + return { + value: index, + label: `${first_name} ${last_name} (${index})`, + } + }), + ) + }, + }, + ) + + useQuery('year_groups', () => getYearGroups({ per_page: 100 }), { + onSuccess: (data) => { + setYearGroupOptions( + data?.data.year_groups.map(({ name, id }) => { + return { + value: id, + label: name, + } + }), + ) + }, + }) + + const onStudentChange = (v: any) => { + setSelectedRole(v?.value) + setStudentId(v.value) + } + + const onYearChange = (v: any) => { + setSelectedYear(v?.value) + setYearGroupId(v?.value) + } return ( <> @@ -12,7 +73,36 @@ const Login = () => { System PRI - + Rok + ({ + ...styles, + padding: '0.3rem', + borderRadius: '0.5rem', + }), + }} + /> + Student + ({ + ...styles, + padding: '0.3rem', + borderRadius: '0.5rem', + }), + }} + /> + + {/* Login @@ -23,11 +113,17 @@ const Login = () => { Hasło - - Zaloguj + */} + navigate('/student')} + > + Zaloguj + Koordynator - Student + {/* Student */} Opiekun diff --git a/frontend/src/views/coordinator/AddGroup.tsx b/frontend/src/views/coordinator/AddGroup.tsx index 2b779ed..f626343 100644 --- a/frontend/src/views/coordinator/AddGroup.tsx +++ b/frontend/src/views/coordinator/AddGroup.tsx @@ -28,7 +28,7 @@ const AddGroup = () => { const { isLoading: areStudentsLoading } = useQuery( 'students', - () => getStudents({ per_page: 1000 }), + () => getStudents({ year_group_id: Number(yearGroupId), per_page: 1000 }), { onSuccess: (data) => { setStudentOptions( @@ -46,7 +46,7 @@ const AddGroup = () => { ) const { isLoading: areLeadersLoading } = useQuery( 'leaders', - () => getLeaders({ per_page: 1000 }), + () => getLeaders({ year_group_id: Number(yearGroupId), per_page: 1000 }), { onSuccess: (data) => { setSupervisorOptions( diff --git a/frontend/src/views/coordinator/AddLeader.tsx b/frontend/src/views/coordinator/AddLeader.tsx index 2e1d992..005705c 100644 --- a/frontend/src/views/coordinator/AddLeader.tsx +++ b/frontend/src/views/coordinator/AddLeader.tsx @@ -83,7 +83,7 @@ const AddLeader = () => { Email jest wymagany )} - + {/* Limit grup @@ -99,49 +99,7 @@ const AddLeader = () => { {errors.limit_group?.type === 'pattern' && ( Limit grup musi być liczbą dodatnią )} - - - Tryb studiów - - - Stacjonarny - - - - Niestacjonarny - - - - Oba - - {errors.mode?.type === 'required' && ( - Wybierz tryb studiów - )} - + */} Dodaj opiekuna ) diff --git a/frontend/src/views/coordinator/EditSchedule.tsx b/frontend/src/views/coordinator/EditSchedule.tsx index 522a2a7..d85141d 100644 --- a/frontend/src/views/coordinator/EditSchedule.tsx +++ b/frontend/src/views/coordinator/EditSchedule.tsx @@ -73,11 +73,11 @@ const EditSchedule = ({ {DateTime.fromJSDate(eventData.start).toFormat('yyyy-LL-dd HH:mm:ss')}{' '} - {DateTime.fromJSDate(eventData.end).toFormat('yyyy-LL-dd HH:mm:ss')}