229 lines
6.0 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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>
)
}