Files
journal.pl/src/pages/lesson-list/components/item.tsx
T

229 lines
6.0 KiB
TypeScript

import React, { useEffect, useRef, useState } from 'react'
import { formatDate } from '../../../utils/dayjs-config'
import { Link } from 'react-router-dom'
import { getNavigationValue, getFeatures } from '@brojs/cli'
import {
Button,
Tr,
Td,
Menu,
MenuButton,
MenuItem,
MenuList,
useToast,
Flex,
Text,
useColorMode,
Box,
Image,
} from '@chakra-ui/react'
import { EditIcon } from '@chakra-ui/icons'
import { useTranslation } from 'react-i18next'
import { qrCode } from '../../../assets'
import { LessonForm } from './lessons-form'
import { api } from '../../../__data__/api/api'
const features = getFeatures('journal')
const groupByDate = features?.['group.by.date']
type ItemProps = {
id: string
date: string
name: string
isTeacher: boolean
courseId: string
setlessonToDelete(): void
setEditLesson?: () => void
students: unknown[]
isMobile?: boolean
}
export const Item: React.FC<ItemProps> = ({
id,
date,
name,
isTeacher,
courseId,
setlessonToDelete,
setEditLesson,
students,
isMobile = false,
}) => {
const [edit, setEdit] = useState(false)
const toastRef = useRef(null)
const toast = useToast()
const [updateLesson, updateLessonRqst] = api.useUpdateLessonMutation()
const createdLessonRef = useRef(null)
const { t } = useTranslation()
const { colorMode } = useColorMode()
// QR-код с применением фильтра инверсии для тёмной темы
const QRCodeImage = () => (
<Box
display="flex"
justifyContent="center"
filter={colorMode === 'dark' ? 'invert(1)' : 'none'}
>
<img
width={isMobile ? 20 : 24}
src={qrCode}
alt="QR код"
style={{ margin: '0 auto' }}
/>
</Box>
)
const onSubmit = (lessonData) => {
toastRef.current = toast({
title: t('journal.pl.common.sending'),
status: 'loading',
duration: 9000,
})
createdLessonRef.current = lessonData
if (navigator.onLine) {
updateLesson(lessonData)
} else {
toast.update(toastRef.current, {
title: t('journal.pl.lesson.noInternet'),
status: 'error',
duration: 3000
})
}
}
useEffect(() => {
if (updateLessonRqst.isSuccess) {
const toastProps = {
title: t('journal.pl.lesson.updated'),
description: t('journal.pl.lesson.updateMessage', { name: createdLessonRef.current?.name }),
status: 'success' as const,
duration: 9000,
isClosable: true,
}
if (toastRef.current) toast.update(toastRef.current, toastProps)
else toast(toastProps)
setEdit(false)
}
}, [updateLessonRqst.isSuccess])
if (edit && isTeacher) {
return (
<Tr>
<Td colSpan={5}>
<LessonForm
isLoading={updateLessonRqst.isLoading}
error={(updateLessonRqst.error as any)?.error}
onSubmit={onSubmit}
onCancel={() => {
setEdit(false)
}}
lesson={{ _id: id, id, name, date }}
title={t('journal.pl.lesson.editTitle')}
nameButton={t('journal.pl.save')}
/>
</Td>
</Tr>
)
}
if (isMobile) {
return (
<>
<Flex justify="space-between" align="center" mb={2}>
<Text fontWeight="medium">{name}</Text>
<Text fontSize="sm">{formatDate(date, groupByDate ? 'HH:mm' : 'HH:mm DD.MM.YY')}</Text>
</Flex>
<Flex justify="space-between" align="center">
{isTeacher && (
<Link
to={`${getNavigationValue('journal.main')}/lesson/${courseId}/${id}`}
style={{ display: 'flex' }}
>
<QRCodeImage />
</Link>
)}
<Flex align="center">
<Text fontSize="sm" mr={2}>
{t('journal.pl.common.marked')}: {students.length}
</Text>
{isTeacher && !edit && (
<Menu>
<MenuButton as={Button} size="sm">
<EditIcon />
</MenuButton>
<MenuList>
<MenuItem
onClick={() => {
if (setEditLesson) {
setEditLesson();
} else {
setEdit(true);
}
}}
>
{t('journal.pl.edit')}
</MenuItem>
<MenuItem onClick={setlessonToDelete}>{t('journal.pl.delete')}</MenuItem>
</MenuList>
</Menu>
)}
{edit && <Button size="sm" onClick={setlessonToDelete}>{t('journal.pl.save')}</Button>}
</Flex>
</Flex>
</>
)
}
// Стандартное отображение
return (
<Tr>
{isTeacher && (
<Td>
<Link
to={`${getNavigationValue('journal.main')}/lesson/${courseId}/${id}`}
style={{ display: 'flex' }}
>
<QRCodeImage />
</Link>
</Td>
)}
<Td textAlign="center">
{formatDate(date, groupByDate ? 'HH:mm' : 'HH:mm DD.MM.YY')}
</Td>
<Td>{name}</Td>
{isTeacher && (
<Td>
{!edit && (
<Menu>
<MenuButton as={Button}>
<EditIcon />
</MenuButton>
<MenuList>
<MenuItem
onClick={() => {
if (setEditLesson) {
setEditLesson();
} else {
setEdit(true);
}
}}
>
{t('journal.pl.edit')}
</MenuItem>
<MenuItem onClick={setlessonToDelete}>{t('journal.pl.delete')}</MenuItem>
</MenuList>
</Menu>
)}
{edit && <Button onClick={setlessonToDelete}>{t('journal.pl.save')}</Button>}
</Td>
)}
<Td isNumeric>{students.length}</Td>
</Tr>
)
}