From 4416a53bc1d80dca64f3a0544256709ff92bab3e Mon Sep 17 00:00:00 2001 From: primakov Date: Sun, 23 Mar 2025 13:13:58 +0300 Subject: [PATCH] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=D0=B0=20=D0=B3=D1=80=D1=83=D0=BF=D0=BF=D0=B8=D1=80=D0=BE?= =?UTF-8?q?=D0=B2=D0=BA=D0=B0=20=D0=BA=D1=83=D1=80=D1=81=D0=BE=D0=B2=20?= =?UTF-8?q?=D0=BF=D0=BE=20=D0=B3=D0=BE=D0=B4=D0=B0=D0=BC=20=D0=B2=20=D0=BA?= =?UTF-8?q?=D0=BE=D0=BC=D0=BF=D0=BE=D0=BD=D0=B5=D0=BD=D1=82=20CoursesList?= =?UTF-8?q?=20=D1=81=20=D0=B8=D1=81=D0=BF=D0=BE=D0=BB=D1=8C=D0=B7=D0=BE?= =?UTF-8?q?=D0=B2=D0=B0=D0=BD=D0=B8=D0=B5=D0=BC=20useMemo=20=D0=B4=D0=BB?= =?UTF-8?q?=D1=8F=20=D0=BE=D0=BF=D1=82=D0=B8=D0=BC=D0=B8=D0=B7=D0=B0=D1=86?= =?UTF-8?q?=D0=B8=D0=B8=20=D0=BF=D1=80=D0=BE=D0=B8=D0=B7=D0=B2=D0=BE=D0=B4?= =?UTF-8?q?=D0=B8=D1=82=D0=B5=D0=BB=D1=8C=D0=BD=D0=BE=D1=81=D1=82=D0=B8.?= =?UTF-8?q?=20=D0=9E=D0=B1=D0=BD=D0=BE=D0=B2=D0=BB=D0=B5=D0=BD=20=D0=B8?= =?UTF-8?q?=D0=BD=D1=82=D0=B5=D1=80=D1=84=D0=B5=D0=B9=D1=81=20=D0=B4=D0=BB?= =?UTF-8?q?=D1=8F=20=D0=BE=D1=82=D0=BE=D0=B1=D1=80=D0=B0=D0=B6=D0=B5=D0=BD?= =?UTF-8?q?=D0=B8=D1=8F=20=D0=BA=D1=83=D1=80=D1=81=D0=BE=D0=B2,=20=D1=81?= =?UTF-8?q?=D0=B3=D1=80=D1=83=D0=BF=D0=BF=D0=B8=D1=80=D0=BE=D0=B2=D0=B0?= =?UTF-8?q?=D0=BD=D0=BD=D1=8B=D1=85=20=D0=BF=D0=BE=20=D0=B3=D0=BE=D0=B4?= =?UTF-8?q?=D0=B0=D0=BC,=20=D1=81=20=D1=81=D0=BE=D0=BE=D1=82=D0=B2=D0=B5?= =?UTF-8?q?=D1=82=D1=81=D1=82=D0=B2=D1=83=D1=8E=D1=89=D0=B8=D0=BC=D0=B8=20?= =?UTF-8?q?=D0=B7=D0=B0=D0=B3=D0=BE=D0=BB=D0=BE=D0=B2=D0=BA=D0=B0=D0=BC?= =?UTF-8?q?=D0=B8=20=D0=B8=20=D1=80=D0=B0=D0=B7=D0=B4=D0=B5=D0=BB=D0=B8?= =?UTF-8?q?=D1=82=D0=B5=D0=BB=D1=8F=D0=BC=D0=B8.=20=D0=9E=D0=B1=D0=BD?= =?UTF-8?q?=D0=BE=D0=B2=D0=BB=D0=B5=D0=BD=D1=8B=20=D1=82=D0=B5=D1=81=D1=82?= =?UTF-8?q?=D0=BE=D0=B2=D1=8B=D0=B5=20=D0=B4=D0=B0=D0=BD=D0=BD=D1=8B=D0=B5?= =?UTF-8?q?=20=D0=B2=20success.json=20=D0=B4=D0=BB=D1=8F=20=D0=BF=D0=BE?= =?UTF-8?q?=D0=B4=D0=B4=D0=B5=D1=80=D0=B6=D0=BA=D0=B8=20=D0=BD=D0=BE=D0=B2?= =?UTF-8?q?=D1=8B=D1=85=20=D0=BA=D1=83=D1=80=D1=81=D0=BE=D0=B2.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/course-list/course-list.tsx | 64 ++++++++-- stubs/mocks/courses/list/success.json | 175 ++++++++++++++++++++++++++ 2 files changed, 229 insertions(+), 10 deletions(-) diff --git a/src/pages/course-list/course-list.tsx b/src/pages/course-list/course-list.tsx index b32afd0..0adfc44 100644 --- a/src/pages/course-list/course-list.tsx +++ b/src/pages/course-list/course-list.tsx @@ -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 = {} + + // Сортируем курсы по дате начала (от новых к старым) + 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 ( @@ -217,14 +242,33 @@ export const CoursesList = () => { )} )} - - {data?.body?.map((c) => ( - - ))} - + + {Object.keys(groupedCourses).length > 0 ? ( + Object.entries(groupedCourses) + .sort(([yearA], [yearB]) => Number(yearB) - Number(yearA)) // Сортируем годы по убыванию + .map(([year, courses]) => ( + + + + {year} + + + + + {courses.map((c) => ( + + ))} + + + )) + ) : ( + + {t('journal.pl.course.noCourses')} + + )} ) } diff --git a/stubs/mocks/courses/list/success.json b/stubs/mocks/courses/list/success.json index 0f0505f..b0df2c0 100644 --- a/stubs/mocks/courses/list/success.json +++ b/stubs/mocks/courses/list/success.json @@ -46,6 +46,181 @@ "startDt": "2024-03-02T15:37:05.907Z", "created": "2024-03-02T15:37:05.908Z", "__v": 2 + }, + { + "id": "66f84d32def890e3g789239a", + "name": "МГУ-24-1", + "teachers": [ + { + "sub": "a72905c2-f334-50db-920f-d9e85c7248d2", + "name": "Елена Иванова", + "preferred_username": "ivanova", + "email": "ivanova@example.com" + } + ], + "lessons": [ + "66e3f6gcec37fec650f28490", + "66e312d5ec37fec650f2abff", + "66e79cfcced789d2f6791416" + ], + "creator": { + "sub": "a72905c2-f334-50db-920f-d9e85c7248d2", + "email_verified": true, + "name": "Елена Иванова", + "preferred_username": "ivanova", + "given_name": "Елена", + "family_name": "Иванова", + "email": "ivanova@example.com" + }, + "startDt": "2024-04-15T10:30:00.000Z", + "endDt": "2024-06-30T18:00:00.000Z", + "created": "2024-04-10T09:25:33.112Z", + "__v": 1 + }, + { + "id": "66g95e43fef901f4h890340b", + "name": "СПБГУ-24-3", + "teachers": [ + { + "sub": "b83016d3-g445-61ec-931g-e0f96d8359e3", + "name": "Михаил Петров", + "preferred_username": "petrov", + "email": "petrov@example.com" + }, + { + "sub": "c94127e4-h556-72fd-042h-f1g07e9460f4", + "name": "Анна Сидорова", + "preferred_username": "sidorova", + "email": "sidorova@example.com" + } + ], + "lessons": [ + "67f4g7hdec37fec650f28501", + "67f423e6ec37fec650f2acgg", + "67f80dgdced789d2f6791527", + "67f80e1gced789d2f679152d" + ], + "creator": { + "sub": "b83016d3-g445-61ec-931g-e0f96d8359e3", + "email_verified": true, + "name": "Михаил Петров", + "preferred_username": "petrov", + "given_name": "Михаил", + "family_name": "Петров", + "email": "petrov@example.com" + }, + "startDt": "2024-05-20T09:00:00.000Z", + "examWithJury": "67dg4e4g5748e531e7382562", + "created": "2024-05-15T14:22:45.500Z", + "capacity": 30, + "enrolled": 28, + "__v": 3 + }, + { + "id": "67h06f54gfg012g5i901451c", + "name": "HSE-24-2", + "teachers": [ + { + "sub": "d05238f5-i667-83ge-153i-g2h18f0571g5", + "name": "Сергей Кузнецов", + "preferred_username": "kuznetsov", + "email": "kuznetsov@example.com" + } + ], + "lessons": [ + "68g5h8iec37fec650f28612", + "68g534f7ec37fec650f2adhi", + "68g91eigced789d2f6791638" + ], + "creator": { + "sub": "d05238f5-i667-83ge-153i-g2h18f0571g5", + "email_verified": true, + "name": "Сергей Кузнецов", + "preferred_username": "kuznetsov", + "given_name": "Сергей", + "family_name": "Кузнецов", + "email": "kuznetsov@example.com" + }, + "startDt": "2024-06-10T13:15:00.000Z", + "endDt": "2024-08-25T17:45:00.000Z", + "created": "2024-06-01T11:08:30.750Z", + "location": "Онлайн", + "tags": ["программирование", "алгоритмы", "анализ данных"], + "__v": 0 + }, + { + "id": "54c62b10bdc678a1d5680127e", + "name": "МФТИ-23-1", + "teachers": [ + { + "sub": "e16349g6-j778-94hf-264j-h3i29g1682h6", + "name": "Дмитрий Соколов", + "preferred_username": "sokolov", + "email": "sokolov@example.com" + } + ], + "lessons": [ + "54b2d4eadb26edb541e17378", + "54b2e2c3db26edb541e18489", + "54b3d5efdb26edb541e19590" + ], + "creator": { + "sub": "e16349g6-j778-94hf-264j-h3i29g1682h6", + "email_verified": true, + "name": "Дмитрий Соколов", + "preferred_username": "sokolov", + "given_name": "Дмитрий", + "family_name": "Соколов", + "email": "sokolov@example.com" + }, + "startDt": "2023-09-01T08:00:00.000Z", + "endDt": "2023-12-25T16:00:00.000Z", + "created": "2023-08-15T10:42:18.320Z", + "status": "completed", + "completionRate": 92, + "__v": 5 + }, + { + "id": "78i17g65hgh123h6j012562d", + "name": "УрФУ-25-4", + "teachers": [ + { + "sub": "f27450h7-k889-05ig-375k-i4j30h2793i7", + "name": "Ольга Морозова", + "preferred_username": "morozova", + "email": "morozova@example.com" + }, + { + "sub": "g38561i8-l990-16jh-486l-j5k41i3804j8", + "name": "Константин Волков", + "preferred_username": "volkov", + "email": "volkov@example.com" + } + ], + "lessons": [ + "79h6i9jfdb26edb541e20601", + "79h7j0kgdb26edb541e21712", + "79h8k1lhdb26edb541e22823", + "79h9l2midb26edb541e23934" + ], + "creator": { + "sub": "f27450h7-k889-05ig-375k-i4j30h2793i7", + "email_verified": true, + "name": "Ольга Морозова", + "preferred_username": "morozova", + "given_name": "Ольга", + "family_name": "Морозова", + "email": "morozova@example.com" + }, + "startDt": "2025-02-10T09:30:00.000Z", + "endDt": "2025-07-05T15:30:00.000Z", + "created": "2024-11-20T14:55:40.670Z", + "status": "scheduled", + "maxCapacity": 50, + "registrationDeadline": "2025-01-30T23:59:59.999Z", + "location": "Гибрид", + "tags": ["машинное обучение", "компьютерное зрение", "нейронные сети"], + "__v": 0 } ] }