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 StudentSchedule from './views/student/StudentSchedule'
|
||||||
import SupervisorSchedule from './views/supervisor/SupervisorSchedule'
|
import SupervisorSchedule from './views/supervisor/SupervisorSchedule'
|
||||||
import Home from './views/coordinator/Home'
|
import Home from './views/coordinator/Home'
|
||||||
|
import SupervisorAvailabilities from './views/coordinator/SupervisorAvailabilities'
|
||||||
|
import AvailabilitySchedule from './views/coordinator/AvailabilitySchedule'
|
||||||
|
|
||||||
const queryClient = new QueryClient({
|
const queryClient = new QueryClient({
|
||||||
defaultOptions: {
|
defaultOptions: {
|
||||||
@ -46,6 +48,14 @@ function App() {
|
|||||||
<Route path="add-leader" element={<AddLeader />} />
|
<Route path="add-leader" element={<AddLeader />} />
|
||||||
<Route path="schedule" element={<Schedules />} />
|
<Route path="schedule" element={<Schedules />} />
|
||||||
<Route path="schedule/:id" element={<Schedule />} />
|
<Route path="schedule/:id" element={<Schedule />} />
|
||||||
|
<Route
|
||||||
|
path="supervisors_availability"
|
||||||
|
element={<SupervisorAvailabilities />}
|
||||||
|
/>
|
||||||
|
<Route
|
||||||
|
path="supervisors_availability/:id"
|
||||||
|
element={<AvailabilitySchedule />}
|
||||||
|
/>
|
||||||
</Route>
|
</Route>
|
||||||
<Route path="student" element={<Student />}>
|
<Route path="student" element={<Student />}>
|
||||||
<Route index element={<Navigate to="enrollment" />} />
|
<Route index element={<Navigate to="enrollment" />} />
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import axiosInstance from './axiosInstance'
|
import axiosInstance from './axiosInstance'
|
||||||
|
import { Leader } from './leaders'
|
||||||
import { Student } from './students'
|
import { Student } from './students'
|
||||||
|
|
||||||
interface TermOfDefences {
|
interface TermOfDefences {
|
||||||
@ -48,6 +49,17 @@ export const getAvailabilityForSupervisor = (scheduleId: number) => {
|
|||||||
}>(`project_supervisor/${scheduleId}/temporary-availabilities?id=1`) //fix hardcode id
|
}>(`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) => {
|
export const getSchedules = (year_group_id: number = 1) => {
|
||||||
return axiosInstance.get<{
|
return axiosInstance.get<{
|
||||||
examination_schedules: {
|
examination_schedules: {
|
||||||
@ -175,3 +187,7 @@ export const setDateOfExaminationSchedule = (
|
|||||||
payload,
|
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: 'Studenci', path: '/coordinator/students' },
|
||||||
{ name: 'Opiekunowie', path: '/coordinator/leaders' },
|
{ name: 'Opiekunowie', path: '/coordinator/leaders' },
|
||||||
{ name: 'Harmonogram', path: '/coordinator/schedule' },
|
{ name: 'Harmonogram', path: '/coordinator/schedule' },
|
||||||
|
{ name: 'Dostępność', path: '/coordinator/supervisors_availability' },
|
||||||
]}
|
]}
|
||||||
/>
|
/>
|
||||||
<div className="m-10">
|
<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
|
to: string
|
||||||
}>({ mode: 'onBlur' })
|
}>({ mode: 'onBlur' })
|
||||||
|
|
||||||
const { refetch, isSuccess } = useQuery(
|
const { refetch, isFetching } = useQuery(
|
||||||
['schedules'],
|
['schedules'],
|
||||||
() => getSupervisorTermsOfDefences(Number(id)),
|
() => getSupervisorTermsOfDefences(Number(id)),
|
||||||
{
|
{
|
||||||
@ -113,7 +113,7 @@ const SupervisorSchedule = () => {
|
|||||||
}),
|
}),
|
||||||
])
|
])
|
||||||
},
|
},
|
||||||
enabled: isSuccess,
|
enabled: !isFetching,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
const { mutateAsync: mutateAddAvailability } = useMutation(
|
const { mutateAsync: mutateAddAvailability } = useMutation(
|
||||||
|
Loading…
Reference in New Issue
Block a user