Update studentId, update opening enrollments
This commit is contained in:
parent
5fda4127cd
commit
5aa8bfee45
@ -14,7 +14,7 @@ class GroupSchema(ma.SQLAlchemyAutoSchema):
|
|||||||
|
|
||||||
|
|
||||||
class StudentSchema(ma.SQLAlchemyAutoSchema):
|
class StudentSchema(ma.SQLAlchemyAutoSchema):
|
||||||
group = fields.Nested(GroupSchema)
|
groups = fields.List(fields.Nested(GroupSchema))
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Student
|
model = Student
|
||||||
|
@ -14,6 +14,7 @@ export interface Leader {
|
|||||||
email: string
|
email: string
|
||||||
limit_group?: number
|
limit_group?: number
|
||||||
count_groups: number
|
count_groups: number
|
||||||
|
year_group_id: number
|
||||||
}
|
}
|
||||||
|
|
||||||
export const getLeaders = (
|
export const getLeaders = (
|
||||||
@ -31,8 +32,14 @@ export const getLeaders = (
|
|||||||
{ params },
|
{ params },
|
||||||
)
|
)
|
||||||
|
|
||||||
export const createLeader = (payload: Partial<Leader>) =>
|
export const createLeader = (payload: Partial<Leader>) => {
|
||||||
axiosInstance.post('coordinator/project_supervisor/', payload)
|
const p = { ...payload }
|
||||||
|
delete p.year_group_id
|
||||||
|
return axiosInstance.post(
|
||||||
|
`coordinator/project_supervisor/${payload.year_group_id}/`,
|
||||||
|
p,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
export const deleteLeader = (id: number) =>
|
export const deleteLeader = (id: number) =>
|
||||||
axiosInstance.delete(`coordinator/project_supervisor/${id}/`)
|
axiosInstance.delete(`coordinator/project_supervisor/${id}/`)
|
||||||
|
@ -12,6 +12,7 @@ interface TermOfDefences {
|
|||||||
last_name: string
|
last_name: string
|
||||||
}[]
|
}[]
|
||||||
group: { name: string; students: Student[] }
|
group: { name: string; students: Student[] }
|
||||||
|
chairman_of_committee: number
|
||||||
}
|
}
|
||||||
|
|
||||||
export const getTermsOfDefences = (scheduleId: number) => {
|
export const getTermsOfDefences = (scheduleId: number) => {
|
||||||
@ -29,12 +30,12 @@ export const getTermsOfDefencesWithGroups = (scheduleId: number) => {
|
|||||||
|
|
||||||
export const getStudentsTermsOfDefences = (
|
export const getStudentsTermsOfDefences = (
|
||||||
scheduleId: number,
|
scheduleId: number,
|
||||||
studentIndex: number,
|
studentId: number,
|
||||||
) => {
|
) => {
|
||||||
return axiosInstance.get<{
|
return axiosInstance.get<{
|
||||||
term_of_defences: TermOfDefences[]
|
term_of_defences: TermOfDefences[]
|
||||||
}>(
|
}>(
|
||||||
`students/examination-schedule/${scheduleId}/enrollments?student_index=${studentIndex}`,
|
`students/examination-schedule/${scheduleId}/enrollments?student_id=${studentId}`,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -78,11 +79,13 @@ export const createEvent = ({
|
|||||||
end_date,
|
end_date,
|
||||||
scheduleId,
|
scheduleId,
|
||||||
project_supervisors,
|
project_supervisors,
|
||||||
|
chairman_of_committee,
|
||||||
}: {
|
}: {
|
||||||
start_date: string
|
start_date: string
|
||||||
end_date: string
|
end_date: string
|
||||||
scheduleId: number
|
scheduleId: number
|
||||||
project_supervisors: number[]
|
project_supervisors: number[]
|
||||||
|
chairman_of_committee: number
|
||||||
}) => {
|
}) => {
|
||||||
return axiosInstance.post(
|
return axiosInstance.post(
|
||||||
`coordinator/enrollments/${scheduleId}/add-term-of-defences/`,
|
`coordinator/enrollments/${scheduleId}/add-term-of-defences/`,
|
||||||
@ -90,6 +93,7 @@ export const createEvent = ({
|
|||||||
start_date,
|
start_date,
|
||||||
end_date,
|
end_date,
|
||||||
project_supervisors,
|
project_supervisors,
|
||||||
|
chairman_of_committee,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -122,16 +126,16 @@ export const setEventDate = ({
|
|||||||
export const assignGroup = ({
|
export const assignGroup = ({
|
||||||
scheduleId,
|
scheduleId,
|
||||||
enrollmentId,
|
enrollmentId,
|
||||||
studentIndex,
|
studentId,
|
||||||
}: {
|
}: {
|
||||||
scheduleId: number
|
scheduleId: number
|
||||||
enrollmentId: number
|
enrollmentId: number
|
||||||
studentIndex: number
|
studentId: number
|
||||||
}) => {
|
}) => {
|
||||||
return axiosInstance.post(
|
return axiosInstance.post(
|
||||||
`students/${scheduleId}/enrollments/${enrollmentId}/`,
|
`students/${scheduleId}/enrollments/${enrollmentId}/`,
|
||||||
{
|
{
|
||||||
student_index: studentIndex,
|
student_id: studentId,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -192,6 +196,18 @@ export const setDateOfExaminationSchedule = (
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const openEnrollments = (scheduleId: number) => {
|
||||||
|
return axiosInstance.put(
|
||||||
|
`coordinator/examination_schedule/${scheduleId}/open-enrollments/`,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export const closeEnrollments = (scheduleId: number) => {
|
||||||
|
return axiosInstance.put(
|
||||||
|
`coordinator/examination_schedule/${scheduleId}/close-enrollments/`,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
export const generateTermsOfDefence = (scheduleId: number) => {
|
export const generateTermsOfDefence = (scheduleId: number) => {
|
||||||
return axiosInstance.post(`coordinator/enrollments/${scheduleId}/generate`)
|
return axiosInstance.post(`coordinator/enrollments/${scheduleId}/generate`)
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,7 @@ interface StudentResponse {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface Student {
|
export interface Student {
|
||||||
|
id: number
|
||||||
first_name: string
|
first_name: string
|
||||||
last_name: string
|
last_name: string
|
||||||
index: number
|
index: number
|
||||||
@ -37,12 +38,12 @@ export const createStudent = (payload: Student & { year_group_id: number }) =>
|
|||||||
|
|
||||||
export const uploadStudents = (payload: FormData, year_group_id: number) =>
|
export const uploadStudents = (payload: FormData, year_group_id: number) =>
|
||||||
axiosInstance.post(
|
axiosInstance.post(
|
||||||
`coordinator/students/upload/?id=${year_group_id}`,
|
`coordinator/students/upload/?year_group_id=${year_group_id}`,
|
||||||
payload,
|
payload,
|
||||||
)
|
)
|
||||||
|
|
||||||
export const deleteStudent = (index: number) =>
|
export const deleteStudent = (id: number) =>
|
||||||
axiosInstance.delete(`coordinator/students/${index}/`)
|
axiosInstance.delete(`coordinator/students/${id}/`)
|
||||||
|
|
||||||
export const downloadStudents = (mode: boolean, year_group_id: number) =>
|
export const downloadStudents = (mode: boolean, year_group_id: number) =>
|
||||||
axiosInstance.post(
|
axiosInstance.post(
|
||||||
|
@ -22,8 +22,6 @@ const Login = () => {
|
|||||||
const [userId, setUserId] = useLocalStorageState('userId', {
|
const [userId, setUserId] = useLocalStorageState('userId', {
|
||||||
defaultValue: 0,
|
defaultValue: 0,
|
||||||
})
|
})
|
||||||
const [studentId, setStudentId] = useLocalStorageState('studentId')
|
|
||||||
|
|
||||||
const [userType, setUserType] = useLocalStorageState('userType', {
|
const [userType, setUserType] = useLocalStorageState('userType', {
|
||||||
defaultValue: 'coordinator',
|
defaultValue: 'coordinator',
|
||||||
})
|
})
|
||||||
@ -54,9 +52,9 @@ const Login = () => {
|
|||||||
{
|
{
|
||||||
onSuccess: (data) => {
|
onSuccess: (data) => {
|
||||||
setStudentOptions(
|
setStudentOptions(
|
||||||
data?.data.students.map(({ first_name, last_name, index }) => {
|
data?.data.students.map(({ first_name, last_name, index, id }) => {
|
||||||
return {
|
return {
|
||||||
value: index,
|
value: id,
|
||||||
label: `${first_name} ${last_name} (${index})`,
|
label: `${first_name} ${last_name} (${index})`,
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
@ -87,8 +85,7 @@ const Login = () => {
|
|||||||
)
|
)
|
||||||
|
|
||||||
const onStudentChange = (v: any) => {
|
const onStudentChange = (v: any) => {
|
||||||
setStudentId(v.value)
|
setUserId(v.value)
|
||||||
// setUserId(v.value)
|
|
||||||
setUserType('student')
|
setUserType('student')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,9 +34,9 @@ const AddGroup = () => {
|
|||||||
setStudentOptions(
|
setStudentOptions(
|
||||||
data?.data.students
|
data?.data.students
|
||||||
.filter(({ groups }) => !groups?.length)
|
.filter(({ groups }) => !groups?.length)
|
||||||
.map(({ first_name, last_name, index }) => {
|
.map(({ first_name, last_name, index, id }) => {
|
||||||
return {
|
return {
|
||||||
value: index,
|
value: id,
|
||||||
label: `${first_name} ${last_name} (${index})`,
|
label: `${first_name} ${last_name} (${index})`,
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
|
@ -19,31 +19,21 @@ const AddLeader = () => {
|
|||||||
const { mutate: mutateCreateLeader } = useMutation(
|
const { mutate: mutateCreateLeader } = useMutation(
|
||||||
'createLeader',
|
'createLeader',
|
||||||
(payload: Leader) => {
|
(payload: Leader) => {
|
||||||
delete payload.limit_group
|
|
||||||
return createLeader(payload)
|
return createLeader(payload)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
onSuccess: (data) => {
|
onSuccess: (data) => {
|
||||||
setIsAlertVisible(true)
|
setIsAlertVisible(true)
|
||||||
mutateAddToYearGroup({
|
|
||||||
id: data?.data?.id,
|
|
||||||
year_group_id: Number(yearGroupId),
|
|
||||||
limit_group: getValues('limit_group') ?? 0,
|
|
||||||
})
|
|
||||||
reset()
|
reset()
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
const { mutate: mutateAddToYearGroup } = useMutation(
|
|
||||||
'addLeaderToGroup',
|
|
||||||
(payload: { id: any; year_group_id: number; limit_group: number }) =>
|
|
||||||
addLeaderToGroup(payload.id, payload.year_group_id, {
|
|
||||||
limit_group: payload.limit_group,
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
|
|
||||||
const onSubmit = (data: Leader) => {
|
const onSubmit = (data: Leader) => {
|
||||||
mutateCreateLeader(data)
|
mutateCreateLeader({
|
||||||
|
...data,
|
||||||
|
year_group_id: Number(yearGroupId),
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -110,10 +100,13 @@ const AddLeader = () => {
|
|||||||
id="limit_group"
|
id="limit_group"
|
||||||
type="text"
|
type="text"
|
||||||
{...register('limit_group', {
|
{...register('limit_group', {
|
||||||
required: false,
|
required: true,
|
||||||
pattern: /^[1-9][0-9]*$/,
|
pattern: /^[1-9][0-9]*$/,
|
||||||
})}
|
})}
|
||||||
/>
|
/>
|
||||||
|
{errors.limit_group?.type === 'required' && (
|
||||||
|
<InputError>Limit jest wymagany</InputError>
|
||||||
|
)}
|
||||||
{errors.limit_group?.type === 'pattern' && (
|
{errors.limit_group?.type === 'pattern' && (
|
||||||
<InputError>Limit grup musi być liczbą dodatnią</InputError>
|
<InputError>Limit grup musi być liczbą dodatnią</InputError>
|
||||||
)}
|
)}
|
||||||
|
@ -54,12 +54,12 @@ const SupervisorSchedule = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col">
|
<div className="flex flex-col">
|
||||||
<button
|
{/* <button
|
||||||
className="btn btn-success btn-xs md:btn-md self-end mb-4"
|
className="btn btn-success btn-xs md:btn-md self-end mb-4"
|
||||||
onClick={() => mutateGenerate()}
|
onClick={() => mutateGenerate()}
|
||||||
>
|
>
|
||||||
Generuj harmonogram
|
Generuj harmonogram
|
||||||
</button>
|
</button> */}
|
||||||
<Calendar
|
<Calendar
|
||||||
localizer={localizer}
|
localizer={localizer}
|
||||||
startAccessor="start"
|
startAccessor="start"
|
||||||
|
@ -44,7 +44,7 @@ const Groups = () => {
|
|||||||
|
|
||||||
const { mutate: mutateDelete } = useMutation(
|
const { mutate: mutateDelete } = useMutation(
|
||||||
'deleteGroup',
|
'deleteGroup',
|
||||||
(index: number) => deleteGroup(index),
|
(id: number) => deleteGroup(id),
|
||||||
{
|
{
|
||||||
onSuccess: () => refetchGroups(),
|
onSuccess: () => refetchGroups(),
|
||||||
},
|
},
|
||||||
|
@ -67,6 +67,10 @@ const EditSchedule = ({
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const chairman = eventData.resource?.members_of_committee?.find(
|
||||||
|
(m: any) => Number(m.id) === eventData.resource?.chairman_of_committee,
|
||||||
|
)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div style={{ width: '330px', height: '250px' }}>
|
<div style={{ width: '330px', height: '250px' }}>
|
||||||
<form className="w-full flex flex-col " onSubmit={handleSubmit(onSubmit)}>
|
<form className="w-full flex flex-col " onSubmit={handleSubmit(onSubmit)}>
|
||||||
@ -75,6 +79,9 @@ const EditSchedule = ({
|
|||||||
{dayjs(eventData.start).format('YYYY-MM-DD HH:mm')} -{' '}
|
{dayjs(eventData.start).format('YYYY-MM-DD HH:mm')} -{' '}
|
||||||
{dayjs(eventData.end).format('HH:mm')}
|
{dayjs(eventData.end).format('HH:mm')}
|
||||||
</p>
|
</p>
|
||||||
|
<p className="mb-2">
|
||||||
|
Przewodniczący: {chairman?.first_name} {chairman?.last_name}
|
||||||
|
</p>
|
||||||
{eventData.resource?.members_of_committee?.length ? (
|
{eventData.resource?.members_of_committee?.length ? (
|
||||||
<>
|
<>
|
||||||
Komisja:{' '}
|
Komisja:{' '}
|
||||||
|
@ -13,14 +13,14 @@ type SelectValue = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const Group = () => {
|
const Group = () => {
|
||||||
const { id } = useParams<{ id: string }>()
|
const { id: groupId } = useParams<{ id: string }>()
|
||||||
const location = useLocation()
|
const location = useLocation()
|
||||||
|
|
||||||
const {
|
const {
|
||||||
data: groups,
|
data: groups,
|
||||||
refetch,
|
refetch,
|
||||||
isLoading: isGroupLoading,
|
isLoading: isGroupLoading,
|
||||||
} = useQuery(['getGroup', id], () => getGroup(Number(id)))
|
} = useQuery(['getGroup', groupId], () => getGroup(Number(groupId)))
|
||||||
const { name, project_supervisor, students } = groups?.data || {}
|
const { name, project_supervisor, students } = groups?.data || {}
|
||||||
const [yearGroupId] = useLocalStorageState('yearGroupId')
|
const [yearGroupId] = useLocalStorageState('yearGroupId')
|
||||||
|
|
||||||
@ -33,9 +33,9 @@ const Group = () => {
|
|||||||
setStudentOptions(
|
setStudentOptions(
|
||||||
data?.data.students
|
data?.data.students
|
||||||
.filter(({ groups }) => !groups?.length)
|
.filter(({ groups }) => !groups?.length)
|
||||||
.map(({ first_name, last_name, index }) => {
|
.map(({ first_name, last_name, index, id }) => {
|
||||||
return {
|
return {
|
||||||
value: index,
|
value: id,
|
||||||
label: `${first_name} ${last_name} (${index})`,
|
label: `${first_name} ${last_name} (${index})`,
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
@ -72,7 +72,7 @@ const Group = () => {
|
|||||||
location.pathname.includes('coordinator')
|
location.pathname.includes('coordinator')
|
||||||
? 'coordinator'
|
? 'coordinator'
|
||||||
: 'supervisor'
|
: 'supervisor'
|
||||||
}/groups/${id}/grade-card`}
|
}/groups/${groupId}/grade-card`}
|
||||||
>
|
>
|
||||||
<button className="btn btn-success mt-2">KARTA OCENY</button>
|
<button className="btn btn-success mt-2">KARTA OCENY</button>
|
||||||
</Link>
|
</Link>
|
||||||
@ -88,7 +88,7 @@ const Group = () => {
|
|||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody className="divide-y divide-gray-100">
|
<tbody className="divide-y divide-gray-100">
|
||||||
{students?.map(({ first_name, last_name, index }) => (
|
{students?.map(({ first_name, last_name, index, id }) => (
|
||||||
<tr key={index}>
|
<tr key={index}>
|
||||||
<td>{first_name}</td>
|
<td>{first_name}</td>
|
||||||
<td>{last_name}</td>
|
<td>{last_name}</td>
|
||||||
@ -98,13 +98,13 @@ const Group = () => {
|
|||||||
onClick={() => {
|
onClick={() => {
|
||||||
if (students && name && project_supervisor)
|
if (students && name && project_supervisor)
|
||||||
mutateEditGroup({
|
mutateEditGroup({
|
||||||
id: Number(id),
|
id: Number(groupId),
|
||||||
payload: {
|
payload: {
|
||||||
name,
|
name,
|
||||||
project_supervisor_id: project_supervisor.id,
|
project_supervisor_id: project_supervisor.id,
|
||||||
students: students
|
students: students
|
||||||
.map((student) => student.index)
|
.map((student) => student.id)
|
||||||
.filter((i) => index !== i),
|
.filter((i) => id !== i),
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}}
|
}}
|
||||||
@ -139,12 +139,12 @@ const Group = () => {
|
|||||||
onClick={() => {
|
onClick={() => {
|
||||||
if (students && name && project_supervisor)
|
if (students && name && project_supervisor)
|
||||||
mutateEditGroup({
|
mutateEditGroup({
|
||||||
id: Number(id),
|
id: Number(groupId),
|
||||||
payload: {
|
payload: {
|
||||||
name,
|
name,
|
||||||
project_supervisor_id: project_supervisor.id,
|
project_supervisor_id: project_supervisor.id,
|
||||||
students: [
|
students: [
|
||||||
...students.map((student) => student.index),
|
...students.map((student) => student.id),
|
||||||
newStudent,
|
newStudent,
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
@ -41,7 +41,7 @@ const Leaders = () => {
|
|||||||
|
|
||||||
const { mutate: mutateDelete } = useMutation(
|
const { mutate: mutateDelete } = useMutation(
|
||||||
'deleteLeader',
|
'deleteLeader',
|
||||||
(index: number) => deleteLeader(index),
|
(id: number) => deleteLeader(id),
|
||||||
{
|
{
|
||||||
onSuccess: () => refetchLeaders(),
|
onSuccess: () => refetchLeaders(),
|
||||||
},
|
},
|
||||||
|
@ -2,9 +2,11 @@ import { Calendar, Views, View } from 'react-big-calendar'
|
|||||||
import { useCallback, useEffect, useState } from 'react'
|
import { useCallback, useEffect, useState } from 'react'
|
||||||
import { useMutation, useQuery } from 'react-query'
|
import { useMutation, useQuery } from 'react-query'
|
||||||
import {
|
import {
|
||||||
|
closeEnrollments,
|
||||||
createEvent,
|
createEvent,
|
||||||
downloadSchedule,
|
downloadSchedule,
|
||||||
getTermsOfDefences,
|
getTermsOfDefences,
|
||||||
|
openEnrollments,
|
||||||
setDateOfExaminationSchedule,
|
setDateOfExaminationSchedule,
|
||||||
} from '../../api/schedule'
|
} from '../../api/schedule'
|
||||||
import { Link, useParams } from 'react-router-dom'
|
import { Link, useParams } from 'react-router-dom'
|
||||||
@ -28,7 +30,7 @@ const customStyles = {
|
|||||||
marginRight: '-50%',
|
marginRight: '-50%',
|
||||||
transform: 'translate(-50%, -50%)',
|
transform: 'translate(-50%, -50%)',
|
||||||
width: '400px',
|
width: '400px',
|
||||||
height: '400px',
|
height: '500px',
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
type SelectValue = {
|
type SelectValue = {
|
||||||
@ -57,6 +59,12 @@ const Schedule = () => {
|
|||||||
id: number
|
id: number
|
||||||
resource: any
|
resource: any
|
||||||
}>()
|
}>()
|
||||||
|
const [scheduleData, setScheduleData] = useLocalStorageState<{
|
||||||
|
start_date: string
|
||||||
|
end_date: string
|
||||||
|
title: string
|
||||||
|
open_enrollments: 'i' | 'o' | 'c'
|
||||||
|
}>('scheduleData')
|
||||||
const [view, setView] = useState<View>(Views.WEEK)
|
const [view, setView] = useState<View>(Views.WEEK)
|
||||||
const onView = useCallback((newView: any) => setView(newView), [setView])
|
const onView = useCallback((newView: any) => setView(newView), [setView])
|
||||||
|
|
||||||
@ -68,14 +76,9 @@ const Schedule = () => {
|
|||||||
from: string
|
from: string
|
||||||
to: string
|
to: string
|
||||||
project_supervisors: NestedValue<any[]>
|
project_supervisors: NestedValue<any[]>
|
||||||
|
chairman_of_committee: number
|
||||||
}>({ mode: 'onBlur' })
|
}>({ mode: 'onBlur' })
|
||||||
const [committeeOptions, setCommitteeOptions] = useState<SelectValue[]>([])
|
const [committeeOptions, setCommitteeOptions] = useState<SelectValue[]>([])
|
||||||
const [startDate, setStartDate] = useState(new Date())
|
|
||||||
const [endDate, setEndDate] = useState(new Date())
|
|
||||||
const [scheduleData, setScheduleData] = useLocalStorageState<{
|
|
||||||
start_date_for_enrollment_students: string
|
|
||||||
end_date_for_enrollment_students: string
|
|
||||||
}>('scheduleData')
|
|
||||||
|
|
||||||
const { isLoading: areLeadersLoading } = useQuery(
|
const { isLoading: areLeadersLoading } = useQuery(
|
||||||
'leaders',
|
'leaders',
|
||||||
@ -102,7 +105,14 @@ const Schedule = () => {
|
|||||||
if (data) {
|
if (data) {
|
||||||
setEvents(
|
setEvents(
|
||||||
data.data.term_of_defences.map(
|
data.data.term_of_defences.map(
|
||||||
({ id, start_date, end_date, members_of_committee, group }) => {
|
({
|
||||||
|
id,
|
||||||
|
start_date,
|
||||||
|
end_date,
|
||||||
|
members_of_committee,
|
||||||
|
group,
|
||||||
|
chairman_of_committee,
|
||||||
|
}) => {
|
||||||
let initials = ''
|
let initials = ''
|
||||||
let title = ''
|
let title = ''
|
||||||
members_of_committee.forEach((member) => {
|
members_of_committee.forEach((member) => {
|
||||||
@ -129,6 +139,7 @@ const Schedule = () => {
|
|||||||
resource: {
|
resource: {
|
||||||
members_of_committee,
|
members_of_committee,
|
||||||
group,
|
group,
|
||||||
|
chairman_of_committee,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -146,6 +157,7 @@ const Schedule = () => {
|
|||||||
start_date: string
|
start_date: string
|
||||||
end_date: string
|
end_date: string
|
||||||
scheduleId: number
|
scheduleId: number
|
||||||
|
chairman_of_committee: number
|
||||||
}) => createEvent(data),
|
}) => createEvent(data),
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -164,6 +176,36 @@ const Schedule = () => {
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const { mutate: mutateOpenEnrollments } = useMutation(
|
||||||
|
['openEnrollments'],
|
||||||
|
() => openEnrollments(Number(id)),
|
||||||
|
{
|
||||||
|
onSuccess: () => {
|
||||||
|
if (scheduleData) {
|
||||||
|
setScheduleData({
|
||||||
|
...scheduleData,
|
||||||
|
open_enrollments: 'o',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
const { mutate: mutateCloseEnrollments } = useMutation(
|
||||||
|
['openEnrollments'],
|
||||||
|
() => closeEnrollments(Number(id)),
|
||||||
|
{
|
||||||
|
onSuccess: () => {
|
||||||
|
if (scheduleData) {
|
||||||
|
setScheduleData({
|
||||||
|
...scheduleData,
|
||||||
|
open_enrollments: 'c',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
const handleSelectSlot = async (event: any) => {
|
const handleSelectSlot = async (event: any) => {
|
||||||
setSelectedDate(event)
|
setSelectedDate(event)
|
||||||
setIsModalOpen(true)
|
setIsModalOpen(true)
|
||||||
@ -202,6 +244,7 @@ const Schedule = () => {
|
|||||||
.format('YYYY-MM-DD HH:mm:ss'),
|
.format('YYYY-MM-DD HH:mm:ss'),
|
||||||
scheduleId: Number(id),
|
scheduleId: Number(id),
|
||||||
project_supervisors: data?.project_supervisors,
|
project_supervisors: data?.project_supervisors,
|
||||||
|
chairman_of_committee: data?.chairman_of_committee,
|
||||||
})
|
})
|
||||||
refetch()
|
refetch()
|
||||||
reset()
|
reset()
|
||||||
@ -209,33 +252,6 @@ const Schedule = () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const { mutate: mutateSetDateOfExaminationSchedule } = useMutation(
|
|
||||||
['dateOfExaminationSchedule'],
|
|
||||||
(data: {
|
|
||||||
start_date_for_enrollment_students: string
|
|
||||||
end_date_for_enrollment_students: string
|
|
||||||
}) => setDateOfExaminationSchedule(Number(id), data),
|
|
||||||
{
|
|
||||||
onSuccess: () => {
|
|
||||||
setScheduleData({
|
|
||||||
...scheduleData,
|
|
||||||
start_date_for_enrollment_students: startDate.toISOString(),
|
|
||||||
end_date_for_enrollment_students: endDate.toISOString(),
|
|
||||||
})
|
|
||||||
},
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (
|
|
||||||
scheduleData?.start_date_for_enrollment_students &&
|
|
||||||
scheduleData?.end_date_for_enrollment_students
|
|
||||||
) {
|
|
||||||
setStartDate(new Date(scheduleData.start_date_for_enrollment_students))
|
|
||||||
setEndDate(new Date(scheduleData.end_date_for_enrollment_students))
|
|
||||||
}
|
|
||||||
}, [scheduleData])
|
|
||||||
|
|
||||||
const eventGetter = (event: any) => {
|
const eventGetter = (event: any) => {
|
||||||
return event?.resource?.group
|
return event?.resource?.group
|
||||||
? {
|
? {
|
||||||
@ -252,54 +268,45 @@ const Schedule = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col">
|
<div className="flex flex-col">
|
||||||
<div>
|
<div className="flex justify-between">
|
||||||
Start zapisów dla studentów:{' '}
|
<div>
|
||||||
<label className="ml-2" htmlFor="end_date">
|
Zapisy dla studentów:{' '}
|
||||||
Od{' '}
|
<strong>
|
||||||
</label>
|
{scheduleData?.open_enrollments === 'o' ? 'Otwarte' : 'Zamknięte'}
|
||||||
<DateTimePicker
|
</strong>
|
||||||
onChange={setStartDate}
|
<button
|
||||||
value={startDate}
|
className="btn btn-success ml-2"
|
||||||
format={'yyyy-MM-dd HH:mm:ss'}
|
onClick={() => {
|
||||||
locale={'pl'}
|
mutateOpenEnrollments()
|
||||||
disableClock
|
}}
|
||||||
/>
|
>
|
||||||
<label className="ml-2" htmlFor="end_date">
|
ROZPOCZNIJ
|
||||||
Do{' '}
|
</button>
|
||||||
</label>
|
<button
|
||||||
<DateTimePicker
|
className="btn btn-success ml-2"
|
||||||
onChange={setEndDate}
|
onClick={() => {
|
||||||
value={endDate}
|
mutateCloseEnrollments()
|
||||||
format={'yyyy-MM-dd HH:mm:ss'}
|
}}
|
||||||
locale={'pl'}
|
>
|
||||||
disableClock
|
ZAKOŃCZ
|
||||||
/>
|
</button>
|
||||||
<button
|
</div>
|
||||||
className="btn btn-success ml-2"
|
<div className="flex self-end gap-4 mb-4">
|
||||||
onClick={() =>
|
<Link
|
||||||
mutateSetDateOfExaminationSchedule({
|
className="underline font-bold self-center"
|
||||||
start_date_for_enrollment_students: startDate.toISOString(),
|
to={`/coordinator/schedule/${id}/workload`}
|
||||||
end_date_for_enrollment_students: endDate.toISOString(),
|
>
|
||||||
})
|
Statystyki
|
||||||
}
|
</Link>
|
||||||
>
|
<button
|
||||||
ZAPISZ
|
className="btn btn-success btn-xs md:btn-md "
|
||||||
</button>
|
onClick={() => mutateDownload(Number(id))}
|
||||||
</div>
|
>
|
||||||
<div className="flex self-end gap-4 mb-4">
|
Eksportuj harmonogram
|
||||||
<Link
|
</button>
|
||||||
className="underline font-bold self-center"
|
</div>
|
||||||
to={`/coordinator/schedule/${id}/workload`}
|
|
||||||
>
|
|
||||||
Statystyki
|
|
||||||
</Link>
|
|
||||||
<button
|
|
||||||
className="btn btn-success btn-xs md:btn-md "
|
|
||||||
onClick={() => mutateDownload(Number(id))}
|
|
||||||
>
|
|
||||||
Eksportuj harmonogram
|
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Calendar
|
<Calendar
|
||||||
localizer={localizer}
|
localizer={localizer}
|
||||||
startAccessor="start"
|
startAccessor="start"
|
||||||
@ -359,6 +366,29 @@ const Schedule = () => {
|
|||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
<label className="label" htmlFor="chairman_of_committee">
|
||||||
|
Przewodniczący
|
||||||
|
</label>
|
||||||
|
<Controller
|
||||||
|
control={control}
|
||||||
|
name="chairman_of_committee"
|
||||||
|
rules={{ required: true }}
|
||||||
|
render={({ field: { onChange, onBlur } }) => (
|
||||||
|
<Select
|
||||||
|
options={committeeOptions}
|
||||||
|
placeholder="Wybierz przewodniczącego komisji"
|
||||||
|
onChange={(val) => onChange(val?.value)}
|
||||||
|
onBlur={onBlur}
|
||||||
|
styles={{
|
||||||
|
control: (styles) => ({
|
||||||
|
...styles,
|
||||||
|
padding: '0.3rem',
|
||||||
|
borderRadius: '0.5rem',
|
||||||
|
}),
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<button className="btn btn-success mt-4">Dodaj termin</button>
|
<button className="btn btn-success mt-4">Dodaj termin</button>
|
||||||
</form>
|
</form>
|
||||||
|
@ -76,7 +76,7 @@ const Students = () => {
|
|||||||
|
|
||||||
const { mutate: mutateDelete } = useMutation(
|
const { mutate: mutateDelete } = useMutation(
|
||||||
'deleteStudent',
|
'deleteStudent',
|
||||||
(index: number) => deleteStudent(index),
|
(id: number) => deleteStudent(id),
|
||||||
{
|
{
|
||||||
onSuccess: () => refetchStudents(),
|
onSuccess: () => refetchStudents(),
|
||||||
},
|
},
|
||||||
@ -178,14 +178,14 @@ const Students = () => {
|
|||||||
<tbody className="divide-y divide-gray-100">
|
<tbody className="divide-y divide-gray-100">
|
||||||
{students?.data?.students
|
{students?.data?.students
|
||||||
?.filter((st) => !st.groups?.length || !showGroupless)
|
?.filter((st) => !st.groups?.length || !showGroupless)
|
||||||
.map(({ first_name, last_name, index, groups, mode }) => (
|
.map(({ first_name, last_name, index, groups, id }) => (
|
||||||
<tr key={index}>
|
<tr key={index}>
|
||||||
<td>{first_name}</td>
|
<td>{first_name}</td>
|
||||||
<td>{last_name}</td>
|
<td>{last_name}</td>
|
||||||
<td>{index}</td>
|
<td>{index}</td>
|
||||||
<td>{groups?.length ? 'Tak' : 'Nie'}</td>
|
<td>{groups?.length ? 'Tak' : 'Nie'}</td>
|
||||||
<td>
|
<td>
|
||||||
<button onClick={() => mutateDelete(index)}>
|
<button onClick={() => mutateDelete(id)}>
|
||||||
<IconRemove />
|
<IconRemove />
|
||||||
</button>
|
</button>
|
||||||
</td>
|
</td>
|
||||||
|
@ -21,17 +21,14 @@ const ScheduleAddGroup = ({
|
|||||||
closeModal: () => void
|
closeModal: () => void
|
||||||
}) => {
|
}) => {
|
||||||
const { register, handleSubmit, reset, control } = useForm<{
|
const { register, handleSubmit, reset, control } = useForm<{
|
||||||
student_index: number
|
student_id: number
|
||||||
}>({ mode: 'onBlur' })
|
}>({ mode: 'onBlur' })
|
||||||
const [studentId] = useLocalStorageState('studentId')
|
const [studentId] = useLocalStorageState('userId')
|
||||||
|
|
||||||
const { mutate: mutateAssignGroup } = useMutation(
|
const { mutate: mutateAssignGroup } = useMutation(
|
||||||
['assignGroup'],
|
['assignGroup'],
|
||||||
(data: {
|
(data: { scheduleId: number; enrollmentId: number; studentId: number }) =>
|
||||||
scheduleId: number
|
assignGroup(data),
|
||||||
enrollmentId: number
|
|
||||||
studentIndex: number
|
|
||||||
}) => assignGroup(data),
|
|
||||||
{
|
{
|
||||||
onSuccess: () => {
|
onSuccess: () => {
|
||||||
closeModal()
|
closeModal()
|
||||||
@ -43,7 +40,7 @@ const ScheduleAddGroup = ({
|
|||||||
mutateAssignGroup({
|
mutateAssignGroup({
|
||||||
scheduleId: Number(scheduleId),
|
scheduleId: Number(scheduleId),
|
||||||
enrollmentId: eventData.id,
|
enrollmentId: eventData.id,
|
||||||
studentIndex: Number(studentId),
|
studentId: Number(studentId),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,7 +24,7 @@ const customStyles = {
|
|||||||
const localizer = dayjsLocalizer(dayjs)
|
const localizer = dayjsLocalizer(dayjs)
|
||||||
|
|
||||||
const StudentSchedule = () => {
|
const StudentSchedule = () => {
|
||||||
const [studentId] = useLocalStorageState('studentId')
|
const [studentId] = useLocalStorageState('userId')
|
||||||
const { id } = useParams<{ id: string }>()
|
const { id } = useParams<{ id: string }>()
|
||||||
const [events, setEvents] = useState<
|
const [events, setEvents] = useState<
|
||||||
{
|
{
|
||||||
@ -189,7 +189,10 @@ const StudentSchedule = () => {
|
|||||||
<ScheduleAddGroup
|
<ScheduleAddGroup
|
||||||
eventData={selectedDate}
|
eventData={selectedDate}
|
||||||
scheduleId={id}
|
scheduleId={id}
|
||||||
closeModal={() => setIsEditModalOpen(false)}
|
closeModal={() => {
|
||||||
|
setIsEditModalOpen(false)
|
||||||
|
refetch()
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
) : null}
|
) : null}
|
||||||
</Modal>
|
</Modal>
|
||||||
|
@ -45,7 +45,7 @@ const SupervisorGroups = () => {
|
|||||||
|
|
||||||
const { mutate: mutateDelete } = useMutation(
|
const { mutate: mutateDelete } = useMutation(
|
||||||
'deleteGroup',
|
'deleteGroup',
|
||||||
(index: number) => deleteGroup(index),
|
(id: number) => deleteGroup(id),
|
||||||
{
|
{
|
||||||
onSuccess: () => refetchGroups(),
|
onSuccess: () => refetchGroups(),
|
||||||
},
|
},
|
||||||
|
Loading…
Reference in New Issue
Block a user