import React, { useEffect, useState } from 'react' import { useParams } from 'react-router-dom' import { useTranslation } from 'react-i18next' import { motion, AnimatePresence } from 'framer-motion' import { api } from '../__data__/api/api' import { formatDate } from '../utils/dayjs-config' import { Alert, AlertIcon, Box, Center, Container, Spinner, Text, Heading, Badge, Flex, useColorMode, IconButton, Tooltip, HStack, } from '@chakra-ui/react' import { UserCard } from '../components/user-card' import { StudentListView } from './style' import { useSetBreadcrumbs } from '../components' // Reaction emojis with their string values const REACTIONS = [ { emoji: '👍', value: 'thumbs_up' }, { emoji: '❤️', value: 'heart' }, { emoji: '😂', value: 'laugh' }, { emoji: '😮', value: 'wow' }, { emoji: '👏', value: 'clap' }, ] const UserPage = () => { const { lessonId, accessId } = useParams() const { t } = useTranslation() const { colorMode } = useColorMode() const acc = api.useGetAccessQuery({ accessCode: accessId }) const [animatedStudents, setAnimatedStudents] = useState([]) const [sendReaction] = api.useSendReactionMutation() const [activeReaction, setActiveReaction] = useState(null) const ls = api.useLessonByIdQuery(lessonId, { pollingInterval: 1000, skipPollingIfUnfocused: true, }) // Устанавливаем хлебные крошки useSetBreadcrumbs([ { title: t('journal.pl.breadcrumbs.home'), path: '/' }, { title: t('journal.pl.breadcrumbs.user'), isCurrentPage: true } ]) // Эффект для поэтапного появления карточек студентов useEffect(() => { if (ls.data?.body?.students?.length) { // Обновляем существующих студентов с сохранением их анимации setAnimatedStudents(prevStudents => { const newStudents = ls.data.body.students.map(student => { // Находим существующего студента const existingStudent = prevStudents.find(p => p.sub === student.sub); // Сохраняем флаг isNew если студент уже существует return { ...student, isNew: existingStudent ? existingStudent.isNew : true }; }); // Если количество студентов не изменилось, сохраняем текущий массив if (prevStudents.length === newStudents.length && prevStudents.every(student => newStudents.find(n => n.sub === student.sub))) { return prevStudents; } return newStudents; }); } }, [ls.data?.body?.students, ls.data?.body?.studentReactions]) // Эффект для сброса флага "новизны" студентов useEffect(() => { if (animatedStudents.length > 0) { const timeoutId = setTimeout(() => { setAnimatedStudents(students => students.map(student => ({...student, isNew: false})) ) }, 2000) return () => clearTimeout(timeoutId) } }, [animatedStudents]) // Обработчик отправки реакции const handleReaction = (reaction) => { if (lessonId) { sendReaction({ lessonId, reaction }) setActiveReaction(reaction) // Сбрасываем активную реакцию через 1 секунду setTimeout(() => { setActiveReaction(null) }, 1000) } } if (acc.isLoading) { return (
) } return ( {acc.isLoading && (
{t('journal.pl.common.sending')}
)} {acc.isSuccess && ( {t('journal.pl.common.success')} )} {acc.error && ( {(acc as any).error?.data?.body?.errorMessage === 'Code is expired' ? ( t('journal.pl.access.expiredCode') ) : (
{JSON.stringify(acc.error, null, 4)}
)}
)} {t('journal.pl.lesson.topicTitle')} {ls.data?.body?.name} {formatDate(ls.data?.body?.date, t('journal.pl.lesson.dateFormat'))} {t('journal.pl.common.people')}: {animatedStudents.length} {/* Реакции на занятие */} {t('journal.pl.lesson.reactions')} {REACTIONS.map((reaction) => ( {reaction.emoji}} size="lg" variant={activeReaction === reaction.value ? "solid" : "outline"} colorScheme={activeReaction === reaction.value ? "blue" : "gray"} onClick={() => handleReaction(reaction.value)} transition="all 0.2s" _hover={{ transform: "scale(1.1)" }} sx={{ animation: activeReaction === reaction.value ? "pulse 0.5s ease-in-out" : "none", "@keyframes pulse": { "0%": { transform: "scale(1)" }, "50%": { transform: "scale(1.2)" }, "100%": { transform: "scale(1)" } } }} /> ))} {animatedStudents.length > 0 ? ( {animatedStudents.map((student) => ( r.sub === student.sub)} /> ))} ) : ( ls.data && (
{t('journal.pl.lesson.noStudents')} {t('journal.pl.lesson.waitForStudents')}
) )}
) } export default UserPage