Add availabilities for coordinator

This commit is contained in:
adam-skowronek 2022-11-24 20:31:47 +01:00
parent ee8563fedb
commit faa00ab353
6 changed files with 132 additions and 2 deletions

View File

@ -21,6 +21,8 @@ import StudentSchedules from './views/student/StudentSchedules'
import StudentSchedule from './views/student/StudentSchedule'
import SupervisorSchedule from './views/supervisor/SupervisorSchedule'
import Home from './views/coordinator/Home'
import SupervisorAvailabilities from './views/coordinator/SupervisorAvailabilities'
import AvailabilitySchedule from './views/coordinator/AvailabilitySchedule'
const queryClient = new QueryClient({
defaultOptions: {
@ -46,6 +48,14 @@ function App() {
<Route path="add-leader" element={<AddLeader />} />
<Route path="schedule" element={<Schedules />} />
<Route path="schedule/:id" element={<Schedule />} />
<Route
path="supervisors_availability"
element={<SupervisorAvailabilities />}
/>
<Route
path="supervisors_availability/:id"
element={<AvailabilitySchedule />}
/>
</Route>
<Route path="student" element={<Student />}>
<Route index element={<Navigate to="enrollment" />} />

View File

@ -1,4 +1,5 @@
import axiosInstance from './axiosInstance'
import { Leader } from './leaders'
import { Student } from './students'
interface TermOfDefences {
@ -48,6 +49,17 @@ export const getAvailabilityForSupervisor = (scheduleId: number) => {
}>(`project_supervisor/${scheduleId}/temporary-availabilities?id=1`) //fix hardcode id
}
export const getAvailabilityForCoordinator = (scheduleId: number) => {
return axiosInstance.get<{
temporary_availabilities: {
id: number
start_date: string
end_date: string
project_supervisor: Leader
}[]
}>(`coordinator/enrollments/${scheduleId}/temporary-availabilities`)
}
export const getSchedules = (year_group_id: number = 1) => {
return axiosInstance.get<{
examination_schedules: {
@ -175,3 +187,7 @@ export const setDateOfExaminationSchedule = (
payload,
)
}
export const generateTermsOfDefence = (scheduleId: number) => {
return axiosInstance.post(`coordinator/enrollments/${scheduleId}/generate`)
}

View File

@ -0,0 +1,79 @@
import { Calendar, luxonLocalizer, Views } from 'react-big-calendar'
import { DateTime, Settings } from 'luxon'
import { useCallback, useState } from 'react'
import { useMutation, useQuery } from 'react-query'
import { useParams } from 'react-router-dom'
import useLocalStorageState from 'use-local-storage-state'
import bigCalendarTranslations from '../../utils/bigCalendarTranslations'
import {
generateTermsOfDefence,
getAvailabilityForCoordinator,
} from '../../api/schedule'
const SupervisorSchedule = () => {
Settings.defaultZone = DateTime.local().zoneName
Settings.defaultLocale = 'pl'
const { id } = useParams<{ id: string }>()
const [yearGroupId] = useLocalStorageState('yearGroupId')
const [supervisorId] = useLocalStorageState('supervisorId')
const [events, setEvents] = useState<
{
id: number
title: string
start: Date
end: Date
resource: any
}[]
>([])
const [view, setView] = useState(Views.MONTH)
const onView = useCallback((newView: any) => setView(newView), [setView])
useQuery(['availability'], () => getAvailabilityForCoordinator(Number(id)), {
onSuccess: (data) => {
setEvents([
...events,
...data.data.temporary_availabilities.map(
({ id, start_date, end_date, project_supervisor }) => {
return {
id,
title: `${project_supervisor.first_name} ${project_supervisor.last_name}`,
start: new Date(start_date),
end: new Date(end_date),
resource: {},
}
},
),
])
},
})
const { mutate: mutateGenerate } = useMutation(['generateTerms'], () =>
generateTermsOfDefence(Number(id)),
)
return (
<div className="flex flex-col">
<button
className="btn btn-success btn-xs md:btn-md self-end mb-4"
onClick={() => mutateGenerate()}
>
Generuj harmonogram
</button>
<Calendar
localizer={luxonLocalizer(DateTime)}
startAccessor="start"
endAccessor="end"
style={{ height: '80vh' }}
events={events}
onView={onView}
view={view}
min={DateTime.fromObject({ hour: 8, minute: 0 }).toJSDate()}
max={DateTime.fromObject({ hour: 16, minute: 0 }).toJSDate()}
messages={bigCalendarTranslations}
/>
</div>
)
}
export default SupervisorSchedule

View File

@ -11,6 +11,7 @@ const Coordinator = () => {
{ name: 'Studenci', path: '/coordinator/students' },
{ name: 'Opiekunowie', path: '/coordinator/leaders' },
{ name: 'Harmonogram', path: '/coordinator/schedule' },
{ name: 'Dostępność', path: '/coordinator/supervisors_availability' },
]}
/>
<div className="m-10">

View File

@ -0,0 +1,24 @@
import { useQuery } from 'react-query'
import { getSchedules } from '../../api/schedule'
import { Link } from 'react-router-dom'
const SupervisorAvailabilities = () => {
const { data: schedules } = useQuery(['getSchedules'], () => getSchedules())
return (
<div>
<h2 className="text-2xl font-bold mb-2">Wybierz zapisy:</h2>
{schedules &&
schedules?.data?.examination_schedules.map((schedule) => (
<h3 className="text-xl" key={schedule.title}>
-{' '}
<Link to={`/coordinator/supervisors_availability/${schedule.id}`}>
{schedule.title}
</Link>
</h3>
))}
</div>
)
}
export default SupervisorAvailabilities

View File

@ -64,7 +64,7 @@ const SupervisorSchedule = () => {
to: string
}>({ mode: 'onBlur' })
const { refetch, isSuccess } = useQuery(
const { refetch, isFetching } = useQuery(
['schedules'],
() => getSupervisorTermsOfDefences(Number(id)),
{
@ -113,7 +113,7 @@ const SupervisorSchedule = () => {
}),
])
},
enabled: isSuccess,
enabled: !isFetching,
},
)
const { mutateAsync: mutateAddAvailability } = useMutation(