import React, { useState, useMemo, useEffect } from 'react' import { Box, Button, Container, Text, useColorMode, useBreakpointValue } from '@chakra-ui/react' import { AddIcon } from '@chakra-ui/icons' import { useTranslation } from 'react-i18next' import { getFeatures } from '@brojs/cli' import { useAppSelector } from '../../__data__/store' import { api } from '../../__data__/api/api' import { isTeacher } from '../../utils/user' import { PageLoader } from '../../components/page-loader/page-loader' import { useSetBreadcrumbs } from '../../components' import { useGroupedCourses } from './hooks' import { CreateCourseForm, YearGroup, CoursesOverview } from './components' import { Lesson } from '../../__data__/model' /** * Основной компонент списка курсов */ export const CoursesList = () => { const user = useAppSelector((s) => s.user) const { data, isLoading } = api.useCoursesListQuery() const [showForm, setShowForm] = useState(false) const { t } = useTranslation() const { colorMode } = useColorMode() // Устанавливаем хлебные крошки для главной страницы useSetBreadcrumbs([ { title: t('journal.pl.breadcrumbs.home'), path: '/', isCurrentPage: true } ]) // Получаем значения фичей const features = getFeatures('journal') const coursesStatistics = features?.['courses.statistics'] // Создаем API запросы для получения уроков const [getLessons] = api.useLazyLessonListQuery() const buttonSize = useBreakpointValue({ base: 'md', md: 'lg' }) const containerPadding = useBreakpointValue({ base: '2', md: '4' }) // Используем хук для группировки курсов по годам const groupedCourses = useGroupedCourses(data?.body) // Создаем объект с детализированными данными для всех курсов const [lessonsByCourse, setLessonsByCourse] = useState>({}) // Используем useMemo для проверки наличия данных const courses = useMemo(() => data?.body || [], [data]) // Загружаем данные для каждого курса параллельно useEffect(() => { if (courses.length > 0 && !showForm) { // Создаем запросы для получения данных о занятиях каждого курса const fetchLessonsForCourses = async () => { const lessonsData: Record = {} // Получаем данные курсов параллельно (по 3 курса за раз, чтобы не перегружать сервер) for (let i = 0; i < courses.length; i += 3) { const batch = courses.slice(i, i + 3) const batchPromises = batch.map(async course => { // Используем существующий API метод с Lazy Query const response = await getLessons(course.id) if (response.data?.body) { lessonsData[course._id] = response.data.body } }) await Promise.all(batchPromises) } setLessonsByCourse(lessonsData) } fetchLessonsForCourses() } }, [courses, showForm, getLessons]) if (isLoading) { return } const handleCloseForm = () => setShowForm(false) return ( {isTeacher(user) && ( {showForm ? ( ) : ( )} )} {!showForm && coursesStatistics && ( )} {Object.keys(groupedCourses).length > 0 ? ( Object.entries(groupedCourses) .sort(([yearA], [yearB]) => Number(yearB) - Number(yearA)) // Сортируем годы по убыванию .map(([year, courses]) => ( )) ) : ( {t('journal.pl.course.noCourses')} )} ) }