Fixes after tests
This commit is contained in:
parent
339ba42fb4
commit
2029f6c343
@ -142,6 +142,8 @@ def list_term_of_defences(examination_schedule_id: int, data: dict) -> dict:
|
|||||||
if student is None:
|
if student is None:
|
||||||
abort(404, "Not found student!")
|
abort(404, "Not found student!")
|
||||||
################
|
################
|
||||||
|
show_available = data.get('show_available')
|
||||||
|
|
||||||
term_of_defences = (
|
term_of_defences = (
|
||||||
TermOfDefence.query.filter(
|
TermOfDefence.query.filter(
|
||||||
TermOfDefence.examination_schedule_id == examination_schedule_id
|
TermOfDefence.examination_schedule_id == examination_schedule_id
|
||||||
@ -150,13 +152,14 @@ def list_term_of_defences(examination_schedule_id: int, data: dict) -> dict:
|
|||||||
.all()
|
.all()
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if show_available is True:
|
||||||
term_of_defences = list(
|
term_of_defences = list(
|
||||||
filter(
|
filter(
|
||||||
lambda n: len(
|
lambda n: len(
|
||||||
[
|
[
|
||||||
d.id
|
d.id
|
||||||
for d in n.members_of_committee
|
for d in n.members_of_committee
|
||||||
if d.id == student.groups[0].project_supervisor.id
|
if len(student.groups) > 0 and d.id == student.groups[0].project_supervisor.id
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
> 0,
|
> 0,
|
||||||
|
@ -24,6 +24,7 @@ class ProjectSupervisorQuerySchema(Schema):
|
|||||||
|
|
||||||
class TemporaryStudentSchema(Schema):
|
class TemporaryStudentSchema(Schema):
|
||||||
student_id = fields.Integer(required=True)
|
student_id = fields.Integer(required=True)
|
||||||
|
show_available = fields.Boolean(required=False)
|
||||||
|
|
||||||
|
|
||||||
class ExaminationScheduleStudentSchema(Schema):
|
class ExaminationScheduleStudentSchema(Schema):
|
||||||
|
@ -31,6 +31,8 @@ import WorkloadStatistics from './views/coordinator/WorkloadStatistics'
|
|||||||
import { MainContext } from './context/MainContext'
|
import { MainContext } from './context/MainContext'
|
||||||
import WithAxios from './context/WithAxios'
|
import WithAxios from './context/WithAxios'
|
||||||
import BaseModal, { ModalData } from './components/BaseModal'
|
import BaseModal, { ModalData } from './components/BaseModal'
|
||||||
|
import StudentGroup from './views/student/StudentGroup'
|
||||||
|
import StudentGradeCard from './views/student/StudentGradeCard'
|
||||||
|
|
||||||
require('dayjs/locale/pl')
|
require('dayjs/locale/pl')
|
||||||
dayjs.locale('pl')
|
dayjs.locale('pl')
|
||||||
@ -85,6 +87,11 @@ function App() {
|
|||||||
<Route path="enrollment" element={<Enrollment />} />
|
<Route path="enrollment" element={<Enrollment />} />
|
||||||
<Route path="schedule" element={<StudentSchedules />} />
|
<Route path="schedule" element={<StudentSchedules />} />
|
||||||
<Route path="schedule/:id" element={<StudentSchedule />} />
|
<Route path="schedule/:id" element={<StudentSchedule />} />
|
||||||
|
<Route path="groups/:id" element={<StudentGroup />} />
|
||||||
|
<Route
|
||||||
|
path="groups/:id/grade-card"
|
||||||
|
element={<StudentGradeCard />}
|
||||||
|
/>
|
||||||
</Route>
|
</Route>
|
||||||
<Route path="supervisor" element={<Supervisor />}>
|
<Route path="supervisor" element={<Supervisor />}>
|
||||||
<Route index element={<Navigate to="groups" />} />
|
<Route index element={<Navigate to="groups" />} />
|
||||||
|
@ -31,3 +31,13 @@ export const getGradesForSupervisor = (
|
|||||||
`project_supervisor/project-grade-sheet/group/${groupId}/?term=${term}&id=${supervisorId}`,
|
`project_supervisor/project-grade-sheet/group/${groupId}/?term=${term}&id=${supervisorId}`,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const getGradesForStudent = (
|
||||||
|
yearGroupId: number,
|
||||||
|
term: number,
|
||||||
|
studentId: number,
|
||||||
|
) => {
|
||||||
|
return axiosInstance.get<{ [key: string]: any }>(
|
||||||
|
`students/project-grade-sheet/year-group/${yearGroupId}/?term=${term}&student_id=${studentId}`,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
@ -31,24 +31,33 @@ export const getTermsOfDefencesWithGroups = (scheduleId: number) => {
|
|||||||
export const getStudentsTermsOfDefences = (
|
export const getStudentsTermsOfDefences = (
|
||||||
scheduleId: number,
|
scheduleId: number,
|
||||||
studentId: number,
|
studentId: number,
|
||||||
|
showAvailable: boolean,
|
||||||
) => {
|
) => {
|
||||||
return axiosInstance.get<{
|
return axiosInstance.get<{
|
||||||
term_of_defences: TermOfDefences[]
|
term_of_defences: TermOfDefences[]
|
||||||
}>(
|
}>(
|
||||||
`students/examination-schedule/${scheduleId}/enrollments?student_id=${studentId}`,
|
`students/examination-schedule/${scheduleId}/enrollments?student_id=${studentId}&show_available=${showAvailable}`,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export const getSupervisorTermsOfDefences = (scheduleId: number) => {
|
export const getSupervisorTermsOfDefences = (
|
||||||
|
scheduleId: number,
|
||||||
|
supervisorId: number,
|
||||||
|
) => {
|
||||||
return axiosInstance.get<{
|
return axiosInstance.get<{
|
||||||
term_of_defences: TermOfDefences[]
|
term_of_defences: TermOfDefences[]
|
||||||
}>(`project_supervisor/${scheduleId}/term-of-defences?id=1`) //fix hardcode id
|
}>(`project_supervisor/${scheduleId}/term-of-defences?id=${supervisorId}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
export const getAvailabilityForSupervisor = (scheduleId: number) => {
|
export const getAvailabilityForSupervisor = (
|
||||||
|
scheduleId: number,
|
||||||
|
supervisorId: number,
|
||||||
|
) => {
|
||||||
return axiosInstance.get<{
|
return axiosInstance.get<{
|
||||||
free_times: { id: number; start_date: string; end_date: string }[]
|
free_times: { id: number; start_date: string; end_date: string }[]
|
||||||
}>(`project_supervisor/${scheduleId}/temporary-availabilities?id=1`) //fix hardcode id
|
}>(
|
||||||
|
`project_supervisor/${scheduleId}/temporary-availabilities?id=${supervisorId}`,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export const getAvailabilityForCoordinator = (scheduleId: number) => {
|
export const getAvailabilityForCoordinator = (scheduleId: number) => {
|
||||||
@ -221,3 +230,18 @@ export const geWorkloadStatistics = (scheduleId: number) => {
|
|||||||
}[]
|
}[]
|
||||||
}>(`coordinator/examination_schedule/${scheduleId}/workloads/`)
|
}>(`coordinator/examination_schedule/${scheduleId}/workloads/`)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const supervisorDeleteAvailability = (
|
||||||
|
scheduleId: number,
|
||||||
|
availabilityId: number,
|
||||||
|
supervisorId: number,
|
||||||
|
) => {
|
||||||
|
return axiosInstance.delete(
|
||||||
|
`project_supervisor/${scheduleId}/enrollments/${availabilityId}/`,
|
||||||
|
{
|
||||||
|
data: {
|
||||||
|
id: supervisorId,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
@ -54,3 +54,6 @@ export const downloadStudents = (mode: boolean, year_group_id: number) =>
|
|||||||
responseType: 'blob',
|
responseType: 'blob',
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
export const getStudentDetails = (id: number) =>
|
||||||
|
axiosInstance.get<Student>(`coordinator/students/${id}/detail/`)
|
||||||
|
40
frontend/src/components/ConfirmationModal.tsx
Normal file
40
frontend/src/components/ConfirmationModal.tsx
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
import Modal from 'react-modal'
|
||||||
|
|
||||||
|
const customStyles = {
|
||||||
|
content: {
|
||||||
|
top: '50%',
|
||||||
|
left: '50%',
|
||||||
|
right: 'auto',
|
||||||
|
bottom: 'auto',
|
||||||
|
marginRight: '-50%',
|
||||||
|
transform: 'translate(-50%, -50%)',
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
const ConfirmationModal = ({
|
||||||
|
isOpen,
|
||||||
|
close,
|
||||||
|
confirmFn,
|
||||||
|
}: {
|
||||||
|
isOpen: boolean
|
||||||
|
close: () => void
|
||||||
|
confirmFn: () => void
|
||||||
|
}) => {
|
||||||
|
return (
|
||||||
|
<Modal
|
||||||
|
isOpen={isOpen}
|
||||||
|
onRequestClose={close}
|
||||||
|
contentLabel="modal"
|
||||||
|
style={customStyles}
|
||||||
|
>
|
||||||
|
<div className="flex flex-col justify-center">
|
||||||
|
<p>Czy na pewno chcesz usunąć?</p>
|
||||||
|
<button className="btn btn-error mt-4" onClick={confirmFn}>
|
||||||
|
Usuń
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</Modal>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ConfirmationModal
|
@ -16,44 +16,77 @@ const GradeCard = () => {
|
|||||||
const { handleSubmit, setValue, control, watch, getValues } = useForm()
|
const { handleSubmit, setValue, control, watch, getValues } = useForm()
|
||||||
const { id } = useParams<{ id: string }>()
|
const { id } = useParams<{ id: string }>()
|
||||||
const [supervisorId] = useLocalStorageState('userId')
|
const [supervisorId] = useLocalStorageState('userId')
|
||||||
|
const [userType] = useLocalStorageState('userType')
|
||||||
|
|
||||||
|
const {
|
||||||
|
data: groupDetails,
|
||||||
|
refetch: refetchGroup,
|
||||||
|
isLoading: isGroupLoading,
|
||||||
|
isSuccess,
|
||||||
|
} = useQuery(['getGroup', id], () => getGroup(Number(id)))
|
||||||
|
|
||||||
useQuery(
|
useQuery(
|
||||||
['getGradesFirst'],
|
['getGradesFirst'],
|
||||||
() => getGradesForSupervisor(Number(id), 1, Number(supervisorId)),
|
() =>
|
||||||
|
getGradesForSupervisor(
|
||||||
|
Number(id),
|
||||||
|
1,
|
||||||
|
userType === 'coordinator'
|
||||||
|
? Number(groupDetails?.data?.project_supervisor?.id)
|
||||||
|
: Number(supervisorId),
|
||||||
|
),
|
||||||
{
|
{
|
||||||
onSuccess: (data) => {
|
onSuccess: (data) => {
|
||||||
for (const [key, value] of Object.entries(data.data)) {
|
for (const [key, value] of Object.entries(data.data)) {
|
||||||
if (key !== 'id') setValue(key, value)
|
if (key !== 'id') setValue(key, value)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
enabled: isSuccess,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
useQuery(
|
useQuery(
|
||||||
['getGradesSecond'],
|
['getGradesSecond'],
|
||||||
() => getGradesForSupervisor(Number(id), 2, Number(supervisorId)),
|
() =>
|
||||||
|
getGradesForSupervisor(
|
||||||
|
Number(id),
|
||||||
|
2,
|
||||||
|
userType === 'coordinator'
|
||||||
|
? Number(groupDetails?.data?.project_supervisor?.id)
|
||||||
|
: Number(supervisorId),
|
||||||
|
),
|
||||||
{
|
{
|
||||||
onSuccess: (data) => {
|
onSuccess: (data) => {
|
||||||
for (const [key, value] of Object.entries(data.data)) {
|
for (const [key, value] of Object.entries(data.data)) {
|
||||||
if (key !== 'id') setValue(key, value)
|
if (key !== 'id') setValue(key, value)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
enabled: isSuccess,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
const {
|
|
||||||
data: groupDetails,
|
|
||||||
refetch: refetchGroup,
|
|
||||||
isLoading: isGroupLoading,
|
|
||||||
} = useQuery(['getGroup', id], () => getGroup(Number(id)))
|
|
||||||
|
|
||||||
const { mutateAsync: mutateGradesFirstTerm } = useMutation(
|
const { mutateAsync: mutateGradesFirstTerm } = useMutation(
|
||||||
'update_grades_first',
|
'update_grades_first',
|
||||||
(payload: any) => updateGradesFirstTerm(1, 1, payload),
|
(payload: any) =>
|
||||||
|
updateGradesFirstTerm(
|
||||||
|
Number(id),
|
||||||
|
userType === 'coordinator'
|
||||||
|
? Number(groupDetails?.data?.project_supervisor?.id)
|
||||||
|
: Number(supervisorId),
|
||||||
|
payload,
|
||||||
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
const { mutateAsync: mutateGradesSecondTerm } = useMutation(
|
const { mutateAsync: mutateGradesSecondTerm } = useMutation(
|
||||||
'update_grades_second',
|
'update_grades_second',
|
||||||
(payload: any) => updateGradesSecondTerm(1, 1, payload),
|
(payload: any) =>
|
||||||
|
updateGradesSecondTerm(
|
||||||
|
Number(id),
|
||||||
|
userType === 'coordinator'
|
||||||
|
? Number(groupDetails?.data?.project_supervisor?.id)
|
||||||
|
: Number(supervisorId),
|
||||||
|
payload,
|
||||||
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
const onSubmit = async (data: any) => {
|
const onSubmit = async (data: any) => {
|
||||||
|
@ -37,7 +37,7 @@ const SupervisorSchedule = () => {
|
|||||||
({ id, start_date, end_date, project_supervisor }) => {
|
({ id, start_date, end_date, project_supervisor }) => {
|
||||||
return {
|
return {
|
||||||
id,
|
id,
|
||||||
title: `${project_supervisor.first_name} ${project_supervisor.last_name}`,
|
title: `${project_supervisor.first_name[0]}${project_supervisor.last_name[0]}`,
|
||||||
start: new Date(start_date),
|
start: new Date(start_date),
|
||||||
end: new Date(end_date),
|
end: new Date(end_date),
|
||||||
resource: {},
|
resource: {},
|
||||||
|
@ -6,6 +6,7 @@ import useLocalStorageState from 'use-local-storage-state'
|
|||||||
import { deleteGroup, getGroups } from '../../api/groups'
|
import { deleteGroup, getGroups } from '../../api/groups'
|
||||||
import { ReactComponent as IconRemove } from '../../assets/svg/icon-remove.svg'
|
import { ReactComponent as IconRemove } from '../../assets/svg/icon-remove.svg'
|
||||||
import { Link } from 'react-router-dom'
|
import { Link } from 'react-router-dom'
|
||||||
|
import ConfirmationModal from '../../components/ConfirmationModal'
|
||||||
|
|
||||||
const Groups = () => {
|
const Groups = () => {
|
||||||
let navigate = useNavigate()
|
let navigate = useNavigate()
|
||||||
@ -14,6 +15,8 @@ const Groups = () => {
|
|||||||
const [page, setPage] = useState(1)
|
const [page, setPage] = useState(1)
|
||||||
const [perPage, setPerPage] = useState(10)
|
const [perPage, setPerPage] = useState(10)
|
||||||
const [yearGroupId] = useLocalStorageState('yearGroupId')
|
const [yearGroupId] = useLocalStorageState('yearGroupId')
|
||||||
|
const [isConfirmModalOpen, setIsConfirmModalOpen] = useState(false)
|
||||||
|
const [groupToDeleteId, setGroupToDeleteId] = useState(0)
|
||||||
|
|
||||||
const perPageOptions = [
|
const perPageOptions = [
|
||||||
{
|
{
|
||||||
@ -135,7 +138,12 @@ const Groups = () => {
|
|||||||
KARTA OCENY
|
KARTA OCENY
|
||||||
</button>
|
</button>
|
||||||
</Link>
|
</Link>
|
||||||
<button onClick={() => mutateDelete(id)}>
|
<button
|
||||||
|
onClick={() => {
|
||||||
|
setGroupToDeleteId(id)
|
||||||
|
setIsConfirmModalOpen(true)
|
||||||
|
}}
|
||||||
|
>
|
||||||
<IconRemove />
|
<IconRemove />
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
@ -181,6 +189,14 @@ const Groups = () => {
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<ConfirmationModal
|
||||||
|
isOpen={isConfirmModalOpen}
|
||||||
|
close={() => setIsConfirmModalOpen(false)}
|
||||||
|
confirmFn={() => {
|
||||||
|
mutateDelete(groupToDeleteId)
|
||||||
|
setIsConfirmModalOpen(false)
|
||||||
|
}}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@ import useLocalStorageState from 'use-local-storage-state'
|
|||||||
import { CreateGroup, editGroup, getGroup } from '../../api/groups'
|
import { CreateGroup, editGroup, getGroup } from '../../api/groups'
|
||||||
import { getStudents } from '../../api/students'
|
import { getStudents } from '../../api/students'
|
||||||
import { ReactComponent as IconRemove } from '../../assets/svg/icon-remove.svg'
|
import { ReactComponent as IconRemove } from '../../assets/svg/icon-remove.svg'
|
||||||
|
import ConfirmationModal from '../../components/ConfirmationModal'
|
||||||
|
|
||||||
type SelectValue = {
|
type SelectValue = {
|
||||||
value: string | number
|
value: string | number
|
||||||
@ -44,6 +45,8 @@ const Group = () => {
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
const [newStudent, setNewStudent] = useState(0)
|
const [newStudent, setNewStudent] = useState(0)
|
||||||
|
const [isConfirmModalOpen, setIsConfirmModalOpen] = useState(false)
|
||||||
|
const [studentsToDelete, setStudentsToDelete] = useState<any[]>([])
|
||||||
const { mutate: mutateEditGroup } = useMutation(
|
const { mutate: mutateEditGroup } = useMutation(
|
||||||
['editGroup'],
|
['editGroup'],
|
||||||
(data: { id: number; payload: CreateGroup }) =>
|
(data: { id: number; payload: CreateGroup }) =>
|
||||||
@ -96,17 +99,14 @@ const Group = () => {
|
|||||||
<td>
|
<td>
|
||||||
<button
|
<button
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
if (students && name && project_supervisor)
|
if (students && name && project_supervisor) {
|
||||||
mutateEditGroup({
|
setStudentsToDelete(
|
||||||
id: Number(groupId),
|
students
|
||||||
payload: {
|
|
||||||
name,
|
|
||||||
project_supervisor_id: project_supervisor.id,
|
|
||||||
students: students
|
|
||||||
.map((student) => student.id)
|
.map((student) => student.id)
|
||||||
.filter((i) => id !== i),
|
.filter((i) => id !== i),
|
||||||
},
|
)
|
||||||
})
|
setIsConfirmModalOpen(true)
|
||||||
|
}
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<IconRemove />
|
<IconRemove />
|
||||||
@ -154,6 +154,23 @@ const Group = () => {
|
|||||||
Dodaj
|
Dodaj
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
<ConfirmationModal
|
||||||
|
isOpen={isConfirmModalOpen}
|
||||||
|
close={() => setIsConfirmModalOpen(false)}
|
||||||
|
confirmFn={() => {
|
||||||
|
if (name && project_supervisor) {
|
||||||
|
mutateEditGroup({
|
||||||
|
id: Number(groupId),
|
||||||
|
payload: {
|
||||||
|
name,
|
||||||
|
project_supervisor_id: project_supervisor.id,
|
||||||
|
students: studentsToDelete,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
setIsConfirmModalOpen(false)
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -283,7 +283,7 @@ const Schedule = () => {
|
|||||||
ROZPOCZNIJ
|
ROZPOCZNIJ
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
className="btn btn-success ml-2"
|
className="btn ml-2"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
mutateCloseEnrollments()
|
mutateCloseEnrollments()
|
||||||
}}
|
}}
|
||||||
|
@ -10,6 +10,7 @@ import {
|
|||||||
import classNames from 'classnames'
|
import classNames from 'classnames'
|
||||||
import { ReactComponent as IconRemove } from '../../assets/svg/icon-remove.svg'
|
import { ReactComponent as IconRemove } from '../../assets/svg/icon-remove.svg'
|
||||||
import useLocalStorageState from 'use-local-storage-state'
|
import useLocalStorageState from 'use-local-storage-state'
|
||||||
|
import ConfirmationModal from '../../components/ConfirmationModal'
|
||||||
|
|
||||||
const Students = () => {
|
const Students = () => {
|
||||||
let navigate = useNavigate()
|
let navigate = useNavigate()
|
||||||
@ -38,6 +39,9 @@ const Students = () => {
|
|||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
|
const [isConfirmModalOpen, setIsConfirmModalOpen] = useState(false)
|
||||||
|
const [studentToDeleteId, setStudenToDeleteId] = useState(0)
|
||||||
|
|
||||||
const {
|
const {
|
||||||
isLoading: isStudentsLoading,
|
isLoading: isStudentsLoading,
|
||||||
data: students,
|
data: students,
|
||||||
@ -106,8 +110,9 @@ const Students = () => {
|
|||||||
<label
|
<label
|
||||||
className="btn btn-success btn-xs md:btn-md btn-outline"
|
className="btn btn-success btn-xs md:btn-md btn-outline"
|
||||||
htmlFor="file"
|
htmlFor="file"
|
||||||
|
title="Format: NAZWISKO, IMIE, INDEKS, PESEL, EMAIL"
|
||||||
>
|
>
|
||||||
Importuj
|
Importuj CSV
|
||||||
</label>
|
</label>
|
||||||
<input
|
<input
|
||||||
type="file"
|
type="file"
|
||||||
@ -132,24 +137,6 @@ const Students = () => {
|
|||||||
</option>
|
</option>
|
||||||
))}
|
))}
|
||||||
</select>
|
</select>
|
||||||
{/* <label className="label justify-start gap-2">
|
|
||||||
<input
|
|
||||||
type="radio"
|
|
||||||
className="radio radio-xs md:radio-md"
|
|
||||||
onChange={() => setMode(true)}
|
|
||||||
checked={mode}
|
|
||||||
/>
|
|
||||||
<span className="text-xs md:text-base">Stacjonarni</span>
|
|
||||||
</label>
|
|
||||||
<label className="label justify-start gap-2">
|
|
||||||
<input
|
|
||||||
type="radio"
|
|
||||||
className="radio radio-xs md:radio-md"
|
|
||||||
onChange={() => setMode(false)}
|
|
||||||
checked={!mode}
|
|
||||||
/>
|
|
||||||
<span className="text-xs md:text-base">Niestacjonarni</span>
|
|
||||||
</label> */}
|
|
||||||
<label className="label">
|
<label className="label">
|
||||||
<input
|
<input
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
@ -185,7 +172,12 @@ const Students = () => {
|
|||||||
<td>{index}</td>
|
<td>{index}</td>
|
||||||
<td>{groups?.length ? 'Tak' : 'Nie'}</td>
|
<td>{groups?.length ? 'Tak' : 'Nie'}</td>
|
||||||
<td>
|
<td>
|
||||||
<button onClick={() => mutateDelete(id)}>
|
<button
|
||||||
|
onClick={() => {
|
||||||
|
setStudenToDeleteId(id)
|
||||||
|
setIsConfirmModalOpen(true)
|
||||||
|
}}
|
||||||
|
>
|
||||||
<IconRemove />
|
<IconRemove />
|
||||||
</button>
|
</button>
|
||||||
</td>
|
</td>
|
||||||
@ -228,6 +220,14 @@ const Students = () => {
|
|||||||
»
|
»
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
<ConfirmationModal
|
||||||
|
isOpen={isConfirmModalOpen}
|
||||||
|
close={() => setIsConfirmModalOpen(false)}
|
||||||
|
confirmFn={() => {
|
||||||
|
mutateDelete(studentToDeleteId)
|
||||||
|
setIsConfirmModalOpen(false)
|
||||||
|
}}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
@ -62,7 +62,6 @@ const Enrollment = () => {
|
|||||||
<th>Imię</th>
|
<th>Imię</th>
|
||||||
<th>Nazwisko</th>
|
<th>Nazwisko</th>
|
||||||
<th>Email</th>
|
<th>Email</th>
|
||||||
<th>Tryb</th>
|
|
||||||
<th>Wolne miejsca</th>
|
<th>Wolne miejsca</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
@ -76,7 +75,6 @@ const Enrollment = () => {
|
|||||||
<td>{first_name}</td>
|
<td>{first_name}</td>
|
||||||
<td>{last_name}</td>
|
<td>{last_name}</td>
|
||||||
<td>{email}</td>
|
<td>{email}</td>
|
||||||
<td>{mode ? 'Stacjonarny' : 'Niestacjonarny'}</td>
|
|
||||||
<td>{available_groups}</td>
|
<td>{available_groups}</td>
|
||||||
</tr>
|
</tr>
|
||||||
))}
|
))}
|
||||||
|
@ -1,16 +1,46 @@
|
|||||||
import { Outlet } from 'react-router-dom'
|
import { useState } from 'react'
|
||||||
|
import { useQuery } from 'react-query'
|
||||||
|
import { Outlet, useNavigate } from 'react-router-dom'
|
||||||
|
import useLocalStorageState from 'use-local-storage-state'
|
||||||
|
import { getStudentDetails } from '../../api/students'
|
||||||
import TopBar from '../../components/TopBar'
|
import TopBar from '../../components/TopBar'
|
||||||
|
|
||||||
const Student = () => {
|
const Student = () => {
|
||||||
|
const [studentId] = useLocalStorageState('userId')
|
||||||
|
const [routes, setRoutes] = useState<
|
||||||
|
{
|
||||||
|
name: string
|
||||||
|
path: string
|
||||||
|
}[]
|
||||||
|
>([{ name: 'Zapisy', path: '/student/enrollment' }])
|
||||||
|
let navigate = useNavigate()
|
||||||
|
|
||||||
|
useQuery(
|
||||||
|
['getStudent', studentId],
|
||||||
|
() => getStudentDetails(Number(studentId)),
|
||||||
|
{
|
||||||
|
onSuccess: (data) => {
|
||||||
|
if (data?.data.groups?.length) {
|
||||||
|
navigate(`/student/groups/${data?.data.groups[0].id}`)
|
||||||
|
}
|
||||||
|
setRoutes(
|
||||||
|
data?.data.groups?.length
|
||||||
|
? [
|
||||||
|
{
|
||||||
|
name: 'Grupa',
|
||||||
|
path: `/student/groups/${data?.data.groups[0].id}`,
|
||||||
|
},
|
||||||
|
{ name: 'Harmonogram', path: '/student/schedule' },
|
||||||
|
]
|
||||||
|
: [{ name: 'Zapisy', path: '/student/enrollment' }],
|
||||||
|
)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<TopBar
|
<TopBar routes={routes} color="bg-gray-300" />
|
||||||
routes={[
|
|
||||||
{ name: 'Zapisy', path: '/student/enrollment' },
|
|
||||||
{ name: 'Harmonogram', path: '/student/schedule' },
|
|
||||||
]}
|
|
||||||
color="bg-gray-300"
|
|
||||||
/>
|
|
||||||
<div className="m-10">
|
<div className="m-10">
|
||||||
<Outlet />
|
<Outlet />
|
||||||
</div>
|
</div>
|
||||||
|
1331
frontend/src/views/student/StudentGradeCard.tsx
Normal file
1331
frontend/src/views/student/StudentGradeCard.tsx
Normal file
File diff suppressed because it is too large
Load Diff
85
frontend/src/views/student/StudentGroup.tsx
Normal file
85
frontend/src/views/student/StudentGroup.tsx
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
import { useState } from 'react'
|
||||||
|
import { useQuery } from 'react-query'
|
||||||
|
import { Link, useLocation, useParams } from 'react-router-dom'
|
||||||
|
import ReactSelect from 'react-select'
|
||||||
|
import useLocalStorageState from 'use-local-storage-state'
|
||||||
|
import { getGroup } from '../../api/groups'
|
||||||
|
import { getStudents } from '../../api/students'
|
||||||
|
import { ReactComponent as IconRemove } from '../../assets/svg/icon-remove.svg'
|
||||||
|
|
||||||
|
type SelectValue = {
|
||||||
|
value: string | number
|
||||||
|
label: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const StudentGroup = () => {
|
||||||
|
const { id: groupId } = useParams<{ id: string }>()
|
||||||
|
const location = useLocation()
|
||||||
|
|
||||||
|
const {
|
||||||
|
data: groups,
|
||||||
|
refetch,
|
||||||
|
isLoading: isGroupLoading,
|
||||||
|
} = useQuery(['getGroup', groupId], () => getGroup(Number(groupId)))
|
||||||
|
const { name, project_supervisor, students } = groups?.data || {}
|
||||||
|
const [yearGroupId] = useLocalStorageState('yearGroupId')
|
||||||
|
|
||||||
|
const [studentOptions, setStudentOptions] = useState<SelectValue[]>([])
|
||||||
|
const { isLoading: areStudentsLoading, refetch: refetchStudents } = useQuery(
|
||||||
|
'students',
|
||||||
|
() => getStudents({ year_group_id: Number(yearGroupId), per_page: 1000 }),
|
||||||
|
{
|
||||||
|
onSuccess: (data) => {
|
||||||
|
setStudentOptions(
|
||||||
|
data?.data.students
|
||||||
|
.filter(({ groups }) => !groups?.length)
|
||||||
|
.map(({ first_name, last_name, index, id }) => {
|
||||||
|
return {
|
||||||
|
value: id,
|
||||||
|
label: `${first_name} ${last_name} (${index})`,
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
if (isGroupLoading || areStudentsLoading) {
|
||||||
|
return <div>Ładowanie</div>
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<h1 className="font-bold text-xl">{name}</h1>
|
||||||
|
<h2 className="">
|
||||||
|
Opiekun: {project_supervisor?.first_name}{' '}
|
||||||
|
{project_supervisor?.last_name}
|
||||||
|
</h2>
|
||||||
|
|
||||||
|
<Link to={`/student/groups/${groupId}/grade-card`}>
|
||||||
|
<button className="btn btn-success mt-2">KARTA OCENY</button>
|
||||||
|
</Link>
|
||||||
|
|
||||||
|
<div className="flex w-[600px] mt-5 overflow-hidden overflow-x-auto border border-gray-100 rounded">
|
||||||
|
<table className="min-w-full table table-compact">
|
||||||
|
<thead>
|
||||||
|
<tr className="bg-gray-50">
|
||||||
|
<th>Imię</th>
|
||||||
|
<th>Nazwisko</th>
|
||||||
|
<th>Indeks</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody className="divide-y divide-gray-100">
|
||||||
|
{students?.map(({ first_name, last_name, index, id }) => (
|
||||||
|
<tr key={index}>
|
||||||
|
<td>{first_name}</td>
|
||||||
|
<td>{last_name}</td>
|
||||||
|
<td>{index}</td>
|
||||||
|
</tr>
|
||||||
|
))}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
export default StudentGroup
|
@ -42,6 +42,7 @@ const StudentSchedule = () => {
|
|||||||
id: number
|
id: number
|
||||||
resource: any
|
resource: any
|
||||||
}>()
|
}>()
|
||||||
|
const [showAvailable, setShowAvailable] = useState(false)
|
||||||
const [view, setView] = useState(Views.WEEK)
|
const [view, setView] = useState(Views.WEEK)
|
||||||
const onView = useCallback((newView: any) => setView(newView), [setView])
|
const onView = useCallback((newView: any) => setView(newView), [setView])
|
||||||
|
|
||||||
@ -55,23 +56,35 @@ const StudentSchedule = () => {
|
|||||||
}>({ mode: 'onBlur' })
|
}>({ mode: 'onBlur' })
|
||||||
|
|
||||||
const { refetch } = useQuery(
|
const { refetch } = useQuery(
|
||||||
['studentSchedules'],
|
['studentSchedules', showAvailable],
|
||||||
() => getStudentsTermsOfDefences(Number(id), Number(studentId)),
|
() =>
|
||||||
|
getStudentsTermsOfDefences(Number(id), Number(studentId), showAvailable),
|
||||||
{
|
{
|
||||||
onSuccess: (data) => {
|
onSuccess: (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,
|
let initials = ''
|
||||||
start_date,
|
let title = ''
|
||||||
end_date,
|
members_of_committee.forEach((member) => {
|
||||||
title = 'Obrona',
|
initials +=
|
||||||
members_of_committee,
|
`${member.first_name} ${member.last_name}`
|
||||||
group,
|
.split(' ')
|
||||||
}) => {
|
.map((n) => n[0])
|
||||||
|
.join('') + ' '
|
||||||
|
})
|
||||||
|
if (group?.name && initials) {
|
||||||
|
title = `${group.name} | ${initials}`
|
||||||
|
} else if (group?.name) {
|
||||||
|
title = group.name
|
||||||
|
} else if (initials) {
|
||||||
|
title = `- | ${initials}`
|
||||||
|
} else {
|
||||||
|
title = '-'
|
||||||
|
}
|
||||||
return {
|
return {
|
||||||
id,
|
id,
|
||||||
title: `${group?.name ?? '-'}`,
|
title: title,
|
||||||
start: new Date(start_date),
|
start: new Date(start_date),
|
||||||
end: new Date(end_date),
|
end: new Date(end_date),
|
||||||
resource: {
|
resource: {
|
||||||
@ -98,7 +111,6 @@ const StudentSchedule = () => {
|
|||||||
end: Date
|
end: Date
|
||||||
resource: any
|
resource: any
|
||||||
}) => {
|
}) => {
|
||||||
console.log(event)
|
|
||||||
setSelectedDate(event)
|
setSelectedDate(event)
|
||||||
setIsEditModalOpen(true)
|
setIsEditModalOpen(true)
|
||||||
},
|
},
|
||||||
@ -129,11 +141,23 @@ const StudentSchedule = () => {
|
|||||||
<h1 className="text-2xl font-bold mb-2 text-center">
|
<h1 className="text-2xl font-bold mb-2 text-center">
|
||||||
Wybierz i zatwierdź termin obrony dla swojej grupy
|
Wybierz i zatwierdź termin obrony dla swojej grupy
|
||||||
</h1>
|
</h1>
|
||||||
|
<div className="flex justify-end">
|
||||||
|
<label className="label">
|
||||||
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
className="checkbox checkbox-xs md:checkbox-md"
|
||||||
|
onChange={() => setShowAvailable(!showAvailable)}
|
||||||
|
/>
|
||||||
|
<span className="ml-2 text-xs md:text-base">
|
||||||
|
Pokaż termin z moim opiekunem
|
||||||
|
</span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
<Calendar
|
<Calendar
|
||||||
localizer={localizer}
|
localizer={localizer}
|
||||||
startAccessor="start"
|
startAccessor="start"
|
||||||
endAccessor="end"
|
endAccessor="end"
|
||||||
style={{ height: '85vh' }}
|
style={{ height: '85vh', fontSize: '14px' }}
|
||||||
onSelectEvent={handleSelectEvent}
|
onSelectEvent={handleSelectEvent}
|
||||||
onSelectSlot={handleSelectSlot}
|
onSelectSlot={handleSelectSlot}
|
||||||
events={events}
|
events={events}
|
||||||
|
@ -91,7 +91,7 @@ const SupervisorGroups = () => {
|
|||||||
<tr className="bg-gray-50">
|
<tr className="bg-gray-50">
|
||||||
<th>Nazwa</th>
|
<th>Nazwa</th>
|
||||||
<th>Opiekun</th>
|
<th>Opiekun</th>
|
||||||
<th>Semestr 1</th>
|
<th>Punkty Semestr 1</th>
|
||||||
<th>Semestr 2</th>
|
<th>Semestr 2</th>
|
||||||
<th></th>
|
<th></th>
|
||||||
</tr>
|
</tr>
|
||||||
@ -125,8 +125,8 @@ const SupervisorGroups = () => {
|
|||||||
<td>
|
<td>
|
||||||
{`${project_supervisor.first_name} ${project_supervisor.last_name}`}
|
{`${project_supervisor.first_name} ${project_supervisor.last_name}`}
|
||||||
</td>
|
</td>
|
||||||
<td>{points_for_first_term}</td>
|
<td>{points_for_first_term}%</td>
|
||||||
<td>{points_for_second_term}</td>
|
<td>{points_for_second_term}%</td>
|
||||||
<td>
|
<td>
|
||||||
<div className="flex align-center gap-2">
|
<div className="flex align-center gap-2">
|
||||||
<Link
|
<Link
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
import { Calendar, Views } from 'react-big-calendar'
|
import { Calendar, View, Views } from 'react-big-calendar'
|
||||||
import { useCallback, useState } from 'react'
|
import { useCallback, useState } from 'react'
|
||||||
import { useMutation, useQuery } from 'react-query'
|
import { useMutation, useQuery } from 'react-query'
|
||||||
import {
|
import {
|
||||||
addAvailability,
|
addAvailability,
|
||||||
getAvailabilityForSupervisor,
|
getAvailabilityForSupervisor,
|
||||||
getSupervisorTermsOfDefences,
|
getSupervisorTermsOfDefences,
|
||||||
|
supervisorDeleteAvailability,
|
||||||
} from '../../api/schedule'
|
} from '../../api/schedule'
|
||||||
import { useParams } from 'react-router-dom'
|
import { useParams } from 'react-router-dom'
|
||||||
import Modal from 'react-modal'
|
import Modal from 'react-modal'
|
||||||
@ -23,6 +24,8 @@ const customStyles = {
|
|||||||
bottom: 'auto',
|
bottom: 'auto',
|
||||||
marginRight: '-50%',
|
marginRight: '-50%',
|
||||||
transform: 'translate(-50%, -50%)',
|
transform: 'translate(-50%, -50%)',
|
||||||
|
width: '300px',
|
||||||
|
height: 'auto',
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
type SelectValue = {
|
type SelectValue = {
|
||||||
@ -51,10 +54,11 @@ const SupervisorSchedule = () => {
|
|||||||
id: number
|
id: number
|
||||||
resource: any
|
resource: any
|
||||||
}>()
|
}>()
|
||||||
const [view, setView] = useState(Views.MONTH)
|
const [view, setView] = useState<View>(Views.WEEK)
|
||||||
const onView = useCallback((newView: any) => setView(newView), [setView])
|
const onView = useCallback((newView: any) => setView(newView), [setView])
|
||||||
|
|
||||||
const [isModalOpen, setIsModalOpen] = useState(false)
|
const [isModalOpen, setIsModalOpen] = useState(false)
|
||||||
|
const [isWeekModalOpen, setIsWeekModalOpen] = useState(false)
|
||||||
const [isEditModalOpen, setIsEditModalOpen] = useState(false)
|
const [isEditModalOpen, setIsEditModalOpen] = useState(false)
|
||||||
Modal.setAppElement('#root')
|
Modal.setAppElement('#root')
|
||||||
|
|
||||||
@ -65,7 +69,7 @@ const SupervisorSchedule = () => {
|
|||||||
|
|
||||||
const { refetch, isFetching } = useQuery(
|
const { refetch, isFetching } = useQuery(
|
||||||
['schedules'],
|
['schedules'],
|
||||||
() => getSupervisorTermsOfDefences(Number(id)),
|
() => getSupervisorTermsOfDefences(Number(id), Number(supervisorId)),
|
||||||
{
|
{
|
||||||
onSuccess: (data) => {
|
onSuccess: (data) => {
|
||||||
setEvents(
|
setEvents(
|
||||||
@ -96,7 +100,7 @@ const SupervisorSchedule = () => {
|
|||||||
|
|
||||||
const { refetch: refetchAvailability } = useQuery(
|
const { refetch: refetchAvailability } = useQuery(
|
||||||
['availability'],
|
['availability'],
|
||||||
() => getAvailabilityForSupervisor(Number(id)),
|
() => getAvailabilityForSupervisor(Number(id), Number(supervisorId)),
|
||||||
{
|
{
|
||||||
onSuccess: (data) => {
|
onSuccess: (data) => {
|
||||||
setEvents([
|
setEvents([
|
||||||
@ -125,9 +129,32 @@ const SupervisorSchedule = () => {
|
|||||||
}) => addAvailability(data),
|
}) => addAvailability(data),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const { mutate: mutateDeleteAvailability } = useMutation(
|
||||||
|
['deleteAvailability'],
|
||||||
|
(data: {
|
||||||
|
availabilityId: number
|
||||||
|
scheduleId: number
|
||||||
|
supervisorId: number
|
||||||
|
}) =>
|
||||||
|
supervisorDeleteAvailability(
|
||||||
|
data.scheduleId,
|
||||||
|
data.availabilityId,
|
||||||
|
data.supervisorId,
|
||||||
|
),
|
||||||
|
{
|
||||||
|
onSuccess: async () => {
|
||||||
|
setIsEditModalOpen(false)
|
||||||
|
await refetch()
|
||||||
|
await refetchAvailability()
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
const handleSelectSlot = async (event: any) => {
|
const handleSelectSlot = async (event: any) => {
|
||||||
setSelectedDate(event)
|
setSelectedDate(event)
|
||||||
if (view === Views.MONTH) {
|
if (view === Views.WEEK || view === Views.DAY) {
|
||||||
|
setIsWeekModalOpen(true)
|
||||||
|
} else if (view === Views.MONTH) {
|
||||||
setIsModalOpen(true)
|
setIsModalOpen(true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -149,6 +176,7 @@ const SupervisorSchedule = () => {
|
|||||||
function closeModal() {
|
function closeModal() {
|
||||||
setIsModalOpen(false)
|
setIsModalOpen(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
const onSubmit = async (data: any) => {
|
const onSubmit = async (data: any) => {
|
||||||
if (selectedDate && view === Views.MONTH) {
|
if (selectedDate && view === Views.MONTH) {
|
||||||
const from = data.from.split(':')
|
const from = data.from.split(':')
|
||||||
@ -166,12 +194,26 @@ const SupervisorSchedule = () => {
|
|||||||
project_supervisor_id: Number(supervisorId),
|
project_supervisor_id: Number(supervisorId),
|
||||||
})
|
})
|
||||||
setEvents([])
|
setEvents([])
|
||||||
refetch()
|
await refetch()
|
||||||
refetchAvailability()
|
await refetchAvailability()
|
||||||
reset()
|
reset()
|
||||||
closeModal()
|
closeModal()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
const submitSlot = async () => {
|
||||||
|
if (selectedDate && (view === Views.WEEK || view === Views.DAY)) {
|
||||||
|
await mutateAddAvailability({
|
||||||
|
start_date: dayjs(selectedDate.start).format('YYYY-MM-DD HH:mm:ss'),
|
||||||
|
end_date: dayjs(selectedDate.end).format('YYYY-MM-DD HH:mm:ss'),
|
||||||
|
scheduleId: Number(id),
|
||||||
|
project_supervisor_id: Number(supervisorId),
|
||||||
|
})
|
||||||
|
setEvents([])
|
||||||
|
await refetch()
|
||||||
|
await refetchAvailability()
|
||||||
|
setIsWeekModalOpen(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const eventGetter = (event: any) => {
|
const eventGetter = (event: any) => {
|
||||||
return event?.title === '-'
|
return event?.title === '-'
|
||||||
@ -205,7 +247,26 @@ const SupervisorSchedule = () => {
|
|||||||
max={dayjs().set('hour', 16).set('minute', 0).toDate()}
|
max={dayjs().set('hour', 16).set('minute', 0).toDate()}
|
||||||
messages={bigCalendarTranslations}
|
messages={bigCalendarTranslations}
|
||||||
/>
|
/>
|
||||||
|
<Modal
|
||||||
|
isOpen={isWeekModalOpen}
|
||||||
|
onRequestClose={() => setIsWeekModalOpen(false)}
|
||||||
|
contentLabel="modal"
|
||||||
|
style={customStyles}
|
||||||
|
>
|
||||||
|
<h3>Dostępne godziny</h3>
|
||||||
|
<strong> {dayjs(selectedDate?.start).format('YYYY-MM-DD')}</strong>
|
||||||
|
<div className="flex flex-col gap-2 mt-3">
|
||||||
|
<p>
|
||||||
|
Od <strong>{dayjs(selectedDate?.start).format('HH:mm')}</strong>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Do <strong>{dayjs(selectedDate?.end).format('HH:mm')}</strong>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<button className="btn btn-success mt-4" onClick={submitSlot}>
|
||||||
|
Dodaj dostępność
|
||||||
|
</button>
|
||||||
|
</Modal>
|
||||||
<Modal
|
<Modal
|
||||||
isOpen={isModalOpen}
|
isOpen={isModalOpen}
|
||||||
onRequestClose={closeModal}
|
onRequestClose={closeModal}
|
||||||
@ -240,16 +301,34 @@ const SupervisorSchedule = () => {
|
|||||||
<button className="btn btn-success mt-4">Dodaj dostępność</button>
|
<button className="btn btn-success mt-4">Dodaj dostępność</button>
|
||||||
</form>
|
</form>
|
||||||
</Modal>
|
</Modal>
|
||||||
{/* <Modal
|
<Modal
|
||||||
isOpen={isEditModalOpen}
|
isOpen={isEditModalOpen}
|
||||||
onRequestClose={() => setIsEditModalOpen(false)}
|
onRequestClose={() => setIsEditModalOpen(false)}
|
||||||
contentLabel="modal"
|
contentLabel="modal"
|
||||||
style={customStyles}
|
style={customStyles}
|
||||||
>
|
>
|
||||||
{selectedDate && id ? (
|
{selectedDate && id ? (
|
||||||
<EditSchedule eventData={selectedDate} scheduleId={id} />
|
<div className="w-full flex flex-col">
|
||||||
|
<h3>Dostępność</h3>
|
||||||
|
<p className="mb-2">
|
||||||
|
{dayjs(selectedDate.start).format('YYYY-MM-DD HH:mm')} -{' '}
|
||||||
|
{dayjs(selectedDate.end).format('HH:mm')}
|
||||||
|
</p>
|
||||||
|
<button
|
||||||
|
className="btn btn-error mt-4"
|
||||||
|
onClick={() =>
|
||||||
|
mutateDeleteAvailability({
|
||||||
|
availabilityId: selectedDate.id,
|
||||||
|
scheduleId: Number(id),
|
||||||
|
supervisorId: Number(supervisorId),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
>
|
||||||
|
Usuń dostępność
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
) : null}
|
) : null}
|
||||||
</Modal> */}
|
</Modal>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user