Добавлена группировка курсов по годам в компонент CoursesList с использованием useMemo для оптимизации производительности. Обновлен интерфейс для отображения курсов, сгруппированных по годам, с соответствующими заголовками и разделителями. Обновлены тестовые данные в success.json для поддержки новых курсов.
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import React, { useEffect, useRef, useState } from 'react'
|
||||
import React, { useEffect, useRef, useState, useMemo } from 'react'
|
||||
import dayjs from 'dayjs'
|
||||
import {
|
||||
Box,
|
||||
@@ -19,7 +19,9 @@ import {
|
||||
useColorMode,
|
||||
useBreakpointValue,
|
||||
Flex,
|
||||
Stack
|
||||
Stack,
|
||||
Divider,
|
||||
Text
|
||||
} from '@chakra-ui/react'
|
||||
import { useForm, Controller } from 'react-hook-form'
|
||||
import { AddIcon } from '@chakra-ui/icons'
|
||||
@@ -93,6 +95,29 @@ export const CoursesList = () => {
|
||||
}
|
||||
}, [crucQuery.isSuccess, t])
|
||||
|
||||
// Группировка курсов по годам
|
||||
const groupedCourses = useMemo(() => {
|
||||
if (!data?.body?.length) return {}
|
||||
|
||||
const grouped: Record<string, typeof data.body> = {}
|
||||
|
||||
// Сортируем курсы по дате начала (от новых к старым)
|
||||
const sortedCourses = [...data.body].sort((a, b) =>
|
||||
dayjs(b.startDt).valueOf() - dayjs(a.startDt).valueOf()
|
||||
)
|
||||
|
||||
// Группируем по годам
|
||||
sortedCourses.forEach(course => {
|
||||
const year = dayjs(course.startDt).format('YYYY')
|
||||
if (!grouped[year]) {
|
||||
grouped[year] = []
|
||||
}
|
||||
grouped[year].push(course)
|
||||
})
|
||||
|
||||
return grouped
|
||||
}, [data?.body])
|
||||
|
||||
if (isLoading) {
|
||||
return (
|
||||
<PageLoader />
|
||||
@@ -217,14 +242,33 @@ export const CoursesList = () => {
|
||||
)}
|
||||
</Box>
|
||||
)}
|
||||
<VStack as="ul" align="stretch" spacing={{ base: 3, md: 4 }}>
|
||||
{data?.body?.map((c) => (
|
||||
<CourseCard
|
||||
key={c.id}
|
||||
course={c}
|
||||
/>
|
||||
))}
|
||||
</VStack>
|
||||
|
||||
{Object.keys(groupedCourses).length > 0 ? (
|
||||
Object.entries(groupedCourses)
|
||||
.sort(([yearA], [yearB]) => Number(yearB) - Number(yearA)) // Сортируем годы по убыванию
|
||||
.map(([year, courses]) => (
|
||||
<Box key={year} mb={6}>
|
||||
<Flex align="center" mb={3}>
|
||||
<Heading size="md" color={colorMode === 'dark' ? 'blue.300' : 'blue.600'}>
|
||||
{year}
|
||||
</Heading>
|
||||
<Divider ml={4} flex="1" />
|
||||
</Flex>
|
||||
<VStack as="ul" align="stretch" spacing={{ base: 3, md: 4 }}>
|
||||
{courses.map((c) => (
|
||||
<CourseCard
|
||||
key={c.id}
|
||||
course={c}
|
||||
/>
|
||||
))}
|
||||
</VStack>
|
||||
</Box>
|
||||
))
|
||||
) : (
|
||||
<Box textAlign="center" py={10}>
|
||||
<Text color="gray.500">{t('journal.pl.course.noCourses')}</Text>
|
||||
</Box>
|
||||
)}
|
||||
</Container>
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user