import React, { useEffect, useMemo, useRef, useState, } from 'react' import { ResponsiveBar } from '@nivo/bar' import dayjs from 'dayjs' import { Link, useParams } from 'react-router-dom' import { getNavigationsValue, getFeatures } from '@ijl/cli' import { useForm, Controller } from 'react-hook-form' import { Breadcrumb, BreadcrumbItem, BreadcrumbLink, Container, Box, Card, CardBody, CardHeader, Heading, Button, CloseButton, useToast, VStack, FormControl, FormLabel, Toast, FormHelperText, FormErrorMessage, Input, TableContainer, Table, Thead, Tr, Th, Tbody, Td, Menu, MenuButton, MenuItem, Text, MenuList, Center, Spinner, AlertDialog, AlertDialogBody, AlertDialogContent, AlertDialogFooter, AlertDialogHeader, AlertDialogOverlay, } from '@chakra-ui/react' import { AddIcon, EditIcon } from '@chakra-ui/icons' import { useAppSelector } from '../__data__/store' import { api } from '../__data__/api/api' import { isTeacher } from '../utils/user' import { qrCode } from '../assets' import { Lesson } from '../__data__/model' import { ErrorSpan, BreadcrumbsWrapper } from './style' const features = getFeatures('journal') const barFeature = features?.['lesson.bar'] const groupByDate = features?.['group.by.date'] interface NewLessonForm { name: string date: string } interface LessonFormProps { lesson?: Partial isLoading: boolean onCancel: () => void onSubmit: (lesson: Lesson) => void error?: string title: string nameButton: string } const LessonForm = ({ lesson, isLoading, onCancel, onSubmit, error, title, nameButton, }: LessonFormProps) => { const { control, handleSubmit, reset, formState: { errors }, } = useForm({ defaultValues: lesson || { name: '', date: '', }, }) return ( {title} { reset() onCancel() }} />
( Дата {errors.date ? ( {errors.date?.message} ) : ( Укажите дату и время лекции )} )} /> ( Название новой лекции: {errors.name && ( {errors.name.message} )} )} /> {error && {error}}
) } const LessonList = () => { const { courseId } = useParams() const user = useAppSelector((s) => s.user) const { data, isLoading, error, isSuccess } = api.useLessonListQuery(courseId) const [createLesson, crLQuery] = api.useCreateLessonMutation() const [deleteLesson, deletingRqst] = api.useDeleteLessonMutation() const [updateLesson, updateLessonRqst] = api.useUpdateLessonMutation() const [showForm, setShowForm] = useState(false) const [lessonToDelete, setlessonToDelete] = useState(null) const cancelRef = React.useRef() const toast = useToast() const toastRef = useRef(null) const createdLessonRef = useRef(null) const [editLesson, setEditLesson] = useState(null) const sorted = useMemo(() => [...(data?.body || [])]?.sort((a, b) => a.date > b.date ? 1 : -1), [data, data?.body]) const lessonCalc = useMemo(() => { if (!isSuccess) { return [] } if (!groupByDate) { return [{ date: '', data: sorted }] } const lessonsData = [] for (let i = 0; i < sorted.length; i++) { const element = sorted[i] const find = lessonsData.find( (item) => dayjs(element.date).diff(dayjs(item.date), 'day') === 0, ) if (find) { find.data.push(element) } else { lessonsData.push({ date: element.date, data: [element], }) } } return lessonsData.sort((a, b) => a.date < b.date? 1 : -1) }, [groupByDate, isSuccess, sorted]) const onSubmit = (lessonData) => { toastRef.current = toast({ title: 'Отправляем', status: 'loading', duration: 9000, }) createdLessonRef.current = lessonData if (editLesson) updateLesson(lessonData) else createLesson({ courseId, ...lessonData }) } useEffect(() => { if (deletingRqst.isError) { toast({ title: (deletingRqst.error as any)?.error, status: 'error', duration: 3000, }) } if (deletingRqst.isSuccess) { const lesson = { ...lessonToDelete } toast({ status: 'warning', duration: 9000, render: ({ id, ...toastProps }) => ( {`Удалена лекция ${lesson.name}`} } /> ), }) setlessonToDelete(null) } }, [deletingRqst.isLoading, deletingRqst.isSuccess, deletingRqst.isError]) useEffect(() => { if (crLQuery.isSuccess) { const toastProps = { title: 'Лекция создана', description: `Лекция ${createdLessonRef.current.name} успешно создана`, status: 'success' as 'success', duration: 9000, isClosable: true, } if (toastRef.current) toast.update(toastRef.current, toastProps) else toast(toastProps) setShowForm(false) } }, [crLQuery.isSuccess]) useEffect(() => { if (updateLessonRqst.isSuccess) { const toastProps = { title: 'Лекция Обновлена', description: `Лекция ${createdLessonRef.current.name} успешно обновлена`, status: 'success' as 'success', duration: 9000, isClosable: true, } if (toastRef.current) toast.update(toastRef.current, toastProps) else toast(toastProps) setShowForm(false) } }, [updateLessonRqst.isSuccess]) if (isLoading) { return (
) } return ( <> setlessonToDelete(null)} > Удалить занятие от{' '} {dayjs(lessonToDelete?.date).format('DD.MM.YY')}? Все данные о посещении данного занятия будут удалены Журнал Курс {isTeacher(user) && ( {showForm ? ( { setShowForm(false) setEditLesson(null) }} error={(crLQuery.error as any)?.error} lesson={editLesson} title={editLesson ? 'Редактирование лекции' : 'Создание лекции'} nameButton={editLesson ? 'Редактировать' : 'Создать'} /> ) : ( )} )} {barFeature && sorted?.length && ( ({ lessonIndex: `#${index + 1}`, count: lesson.students.length, }))} /> )} {isTeacher(user) && ( )} {isTeacher(user) && } {lessonCalc?.map(({ data: lessons, date }) => ( {date && } {lessons.map((lesson) => ( {isTeacher(user) && ( )} {isTeacher(user) && ( )} ))} ))}
ссылка Дата НазваниеactionОтмечено
{dayjs(date).format('DD MMMM YYYY')}
{dayjs(lesson.date).format(groupByDate ? 'HH:mm' : 'HH:mm DD.MM.YY')} {lesson.name} { setShowForm(true) setEditLesson(lesson) }} > Edit setlessonToDelete(lesson)} > Delete {lesson.students.length}
) } export default LessonList const Bar = ({ data }) => ( e.id + ': ' + e.formattedValue + ' on lection: ' + e.indexValue } /> )