274 lines
8.4 KiB
TypeScript
274 lines
8.4 KiB
TypeScript
import React, { useCallback, useEffect, useRef, useState } from 'react'
|
||
import dayjs from 'dayjs'
|
||
import { Link, useParams } from 'react-router-dom'
|
||
import { getNavigationsValue } from '@ijl/cli'
|
||
import { useForm, Controller } from 'react-hook-form'
|
||
import {
|
||
Breadcrumb,
|
||
BreadcrumbItem,
|
||
BreadcrumbLink,
|
||
Container,
|
||
Box,
|
||
Card,
|
||
CardBody,
|
||
CardHeader,
|
||
Heading,
|
||
Button,
|
||
ButtonGroup,
|
||
CloseButton,
|
||
useToast,
|
||
Stack,
|
||
VStack,
|
||
FormControl,
|
||
FormLabel,
|
||
FormHelperText,
|
||
FormErrorMessage,
|
||
Input,
|
||
TableContainer,
|
||
Table,
|
||
Thead,
|
||
Tr,
|
||
Th,
|
||
Tbody,
|
||
Td,
|
||
} from '@chakra-ui/react'
|
||
|
||
import { AddIcon } from '@chakra-ui/icons'
|
||
|
||
import { LessonItem, Lessonname, ErrorSpan, BreadcrumbsWrapper } from './style'
|
||
|
||
import { keycloak } from '../__data__/kc'
|
||
import { useAppSelector } from '../__data__/store'
|
||
import { api } from '../__data__/api/api'
|
||
import { isTeacher } from '../utils/user'
|
||
import { qrCode } from '../assets'
|
||
|
||
interface NewLessonForm {
|
||
name: string
|
||
date: string
|
||
}
|
||
|
||
const LessonList = () => {
|
||
const { courseId } = useParams()
|
||
const user = useAppSelector((s) => s.user)
|
||
const { data, isLoading, error } = api.useLessonListQuery(courseId)
|
||
const [createLesson, crLQuery] = api.useCreateLessonMutation()
|
||
const [value, setValue] = useState('')
|
||
const [showForm, setShowForm] = useState(false)
|
||
const {
|
||
control,
|
||
handleSubmit,
|
||
reset,
|
||
formState: { errors },
|
||
getValues,
|
||
} = useForm<NewLessonForm>({
|
||
defaultValues: {
|
||
name: '',
|
||
date: '',
|
||
},
|
||
})
|
||
const toast = useToast()
|
||
const toastRef = useRef(null)
|
||
|
||
const handleChange = useCallback(
|
||
(event) => {
|
||
setValue(event.target.value.toUpperCase())
|
||
},
|
||
[setValue],
|
||
)
|
||
const onSubmit = ({ name, date }) => {
|
||
toastRef.current = toast({
|
||
title: 'Отправляем',
|
||
status: 'loading',
|
||
duration: 9000,
|
||
})
|
||
createLesson({ name, courseId, date })
|
||
}
|
||
|
||
useEffect(() => {
|
||
if (crLQuery.isSuccess) {
|
||
const values = getValues()
|
||
if (toastRef.current) {
|
||
toast.update(toastRef.current, {
|
||
title: 'Лекция создана',
|
||
description: `Лекция ${values.name} успешно создана`,
|
||
status: 'success',
|
||
duration: 9000,
|
||
isClosable: true,
|
||
})
|
||
}
|
||
reset()
|
||
}
|
||
}, [crLQuery.isSuccess])
|
||
|
||
return (
|
||
<>
|
||
<BreadcrumbsWrapper>
|
||
<Breadcrumb>
|
||
<BreadcrumbItem>
|
||
<BreadcrumbLink as={Link} to={getNavigationsValue('journal.main')}>
|
||
Журнал
|
||
</BreadcrumbLink>
|
||
</BreadcrumbItem>
|
||
|
||
<BreadcrumbItem isCurrentPage>
|
||
<BreadcrumbLink href="#">Курс</BreadcrumbLink>
|
||
</BreadcrumbItem>
|
||
</Breadcrumb>
|
||
</BreadcrumbsWrapper>
|
||
<Container maxW="container.xl">
|
||
{isTeacher(user) && (
|
||
<Box mt="15" mb="15">
|
||
{showForm ? (
|
||
<Card align="left">
|
||
<CardHeader display="flex">
|
||
<Heading as="h2" mt="0">
|
||
Создание лекции
|
||
</Heading>
|
||
<CloseButton ml="auto" onClick={() => setShowForm(false)} />
|
||
</CardHeader>
|
||
<CardBody>
|
||
<form onSubmit={handleSubmit(onSubmit)}>
|
||
<VStack spacing="10" align="left">
|
||
<Controller
|
||
control={control}
|
||
name="date"
|
||
rules={{ required: 'Обязательное поле' }}
|
||
render={({ field }) => (
|
||
<FormControl>
|
||
<FormLabel>Дата</FormLabel>
|
||
<Input
|
||
{...field}
|
||
required={false}
|
||
placeholder="Укажите дату лекции"
|
||
size="md"
|
||
type="datetime-local"
|
||
/>
|
||
{errors.date ? (
|
||
<FormErrorMessage>
|
||
{errors.date?.message}
|
||
</FormErrorMessage>
|
||
) : (
|
||
<FormHelperText>
|
||
Укажите дату и время лекции
|
||
</FormHelperText>
|
||
)}
|
||
</FormControl>
|
||
)}
|
||
/>
|
||
|
||
<Controller
|
||
control={control}
|
||
name="name"
|
||
rules={{ required: 'Обязательное поле' }}
|
||
render={({ field }) => (
|
||
<FormControl
|
||
isRequired
|
||
isInvalid={Boolean(errors.name)}
|
||
>
|
||
<FormLabel>Название новой лекции:</FormLabel>
|
||
<Input
|
||
{...field}
|
||
required={false}
|
||
placeholder="Название лекции"
|
||
size="md"
|
||
/>
|
||
{errors.name && (
|
||
<FormErrorMessage>
|
||
{errors.name.message}
|
||
</FormErrorMessage>
|
||
)}
|
||
</FormControl>
|
||
)}
|
||
/>
|
||
<Box mt="10">
|
||
<Button
|
||
size="lg"
|
||
type="submit"
|
||
leftIcon={<AddIcon />}
|
||
colorScheme="blue"
|
||
>
|
||
Создать
|
||
</Button>
|
||
</Box>
|
||
</VStack>
|
||
|
||
{crLQuery.error && (
|
||
<ErrorSpan>{(crLQuery.error as any).error}</ErrorSpan>
|
||
)}
|
||
</form>
|
||
</CardBody>
|
||
</Card>
|
||
) : (
|
||
<Box p="2" m="2">
|
||
<Button
|
||
leftIcon={<AddIcon />}
|
||
colorScheme="green"
|
||
onClick={() => setShowForm(true)}
|
||
>
|
||
Добавить
|
||
</Button>
|
||
</Box>
|
||
)}
|
||
</Box>
|
||
)}
|
||
<TableContainer whiteSpace="wrap">
|
||
<Table variant="striped" colorScheme="cyan">
|
||
<Thead>
|
||
<Tr>
|
||
<Th align="center">ссылка</Th>
|
||
<Th>Дата</Th>
|
||
<Th>into</Th>
|
||
<Th isNumeric>Участников</Th>
|
||
</Tr>
|
||
</Thead>
|
||
<Tbody>
|
||
{data?.body?.map((lesson) => (
|
||
<Tr key={lesson._id}>
|
||
<Td>
|
||
<Link
|
||
to={
|
||
isTeacher(user)
|
||
? `${getNavigationsValue('journal.main')}/lesson/${courseId}/${lesson._id}`
|
||
: ''
|
||
}
|
||
style={{ display: 'flex' }}
|
||
>
|
||
<img width={24} src={qrCode} />
|
||
</Link>
|
||
</Td>
|
||
<Td>{dayjs(lesson.date).format('H:mm DD.MM.YY')}</Td>
|
||
<Td>{lesson.name}</Td>
|
||
<Td isNumeric>{lesson.students.length}</Td>
|
||
</Tr>
|
||
))}
|
||
</Tbody>
|
||
</Table>
|
||
</TableContainer>
|
||
{/* <ul style={{ paddingLeft: 0 }}>
|
||
{data?.body?.map((lesson) => (
|
||
<LessonItem key={lesson._id}>
|
||
<Link
|
||
to={
|
||
isTeacher(user)
|
||
? `${getNavigationsValue('journal.main')}/lesson/${courseId}/${lesson._id}`
|
||
: ''
|
||
}
|
||
style={{ display: 'flex' }}
|
||
>
|
||
<Lessonname>{lesson.name}</Lessonname>
|
||
<span>{dayjs(lesson.date).format('DD MMMM YYYYг.')}</span>
|
||
<span style={{ marginLeft: 'auto' }}>
|
||
Участников - {lesson.students.length}
|
||
</span>
|
||
</Link>
|
||
</LessonItem>
|
||
))}
|
||
</ul> */}
|
||
</Container>
|
||
</>
|
||
)
|
||
}
|
||
|
||
export default LessonList
|