Add availabilities for coordinator
This commit is contained in:
parent
ee8563fedb
commit
faa00ab353
@ -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" />} />
|
||||
|
@ -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`)
|
||||
}
|
||||
|
79
frontend/src/views/coordinator/AvailabilitySchedule.tsx
Normal file
79
frontend/src/views/coordinator/AvailabilitySchedule.tsx
Normal 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
|
@ -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">
|
||||
|
24
frontend/src/views/coordinator/SupervisorAvailabilities.tsx
Normal file
24
frontend/src/views/coordinator/SupervisorAvailabilities.tsx
Normal 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
|
@ -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(
|
||||
|
Loading…
Reference in New Issue
Block a user