From b858d70675db7ce5f3b676b09b5d9fce280b70b8 Mon Sep 17 00:00:00 2001 From: primakov Date: Thu, 28 Mar 2024 18:26:26 +0300 Subject: [PATCH] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8=D0=BB=20?= =?UTF-8?q?=D1=81=D0=BF=D0=B8=D0=BD=D0=BD=D0=B5=D1=80=20(#5)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app.tsx | 133 ++++++++------- src/dashboard.tsx | 80 +++++++-- src/pages/course-list.tsx | 344 ++++++++++++++++++++++++-------------- 3 files changed, 352 insertions(+), 205 deletions(-) diff --git a/src/app.tsx b/src/app.tsx index 40c795c..ebe2ca9 100644 --- a/src/app.tsx +++ b/src/app.tsx @@ -4,6 +4,7 @@ import { Global, css } from '@emotion/react' import { BrowserRouter } from 'react-router-dom'; import ruLocale from 'dayjs/locale/ru'; import dayjs from 'dayjs'; +import { ChakraProvider } from '@chakra-ui/react' import { Dashboard } from './dashboard'; @@ -11,72 +12,74 @@ dayjs.locale('ru', ruLocale); const App = ({ store }) => { return( - - - - Журнал - - + + + + Журнал + + - - + @font-face { + font-family: 'KiyosunaSans'; + src: url('${__webpack_public_path__ + '/remote-assets/KiyosunaSans/KiyosunaSans-B.otf'}'); + font-weight: normal; + font-style: normal; + } + @font-face { + font-family: 'KiyosunaSans'; + src: url('${__webpack_public_path__ + '/remote-assets/KiyosunaSans/KiyosunaSans-L.otf'}'); + font-weight: lighter; + font-style: normal; + } + @font-face { + font-family: 'RFKrabuler'; + src: url('${__webpack_public_path__ + '/remote-assets/RF-Krabuler/WEB/RFKrabuler-Regular.eot'}'); + src: + url('${__webpack_public_path__ + '/remote-assets/RF-Krabuler/WEB/RFKrabuler-Regular.woff2'}') format('woff2'), + url('${__webpack_public_path__ + '/remote-assets/RF-Krabuler/WEB/RFKrabuler-Regular.woff'}') format('woff'), + url('${__webpack_public_path__ + '/remote-assets/RF-Krabuler/TTF/RF-Krabuler-Regular.ttf'}') format('truetype'); + font-weight: normal; + font-style: normal; + } + `} + /> + + + ) } diff --git a/src/dashboard.tsx b/src/dashboard.tsx index e5631d8..1927709 100644 --- a/src/dashboard.tsx +++ b/src/dashboard.tsx @@ -1,34 +1,82 @@ -import React, { useEffect, Suspense } from "react"; -import { Routes, Route, useNavigate } from "react-router-dom"; -import { Provider } from "react-redux"; +import React, { useEffect, Suspense } from 'react' +import { Routes, Route, useNavigate } from 'react-router-dom' +import { Provider } from 'react-redux' import { CourseListPage, LessonDetailsPage, LessonListPage, - UserPage + UserPage, } from './pages' -import { getNavigationsValue } from "@ijl/cli"; +import { getNavigationsValue } from '@ijl/cli' +import { Box, Container, Spinner, VStack } from '@chakra-ui/react' const Redirect = ({ path }) => { - const navigate = useNavigate(); + const navigate = useNavigate() useEffect(() => { - navigate(path); - }, []); + navigate(path) + }, []) - return null; -}; + return null +} -const Wrapper = ({ children }) => {children} +const Wrapper = ({ children }) => ( + + + + + + + } + > + {children} + +) export const Dashboard = ({ store }) => ( - } /> - } /> - } /> - } /> + + + + } + /> + + + + } + /> + + + + } + /> + + + + } + /> -); +) diff --git a/src/pages/course-list.tsx b/src/pages/course-list.tsx index ad94b89..408d901 100644 --- a/src/pages/course-list.tsx +++ b/src/pages/course-list.tsx @@ -1,8 +1,7 @@ import React, { useCallback, useEffect, useRef, useState } from 'react' import dayjs from 'dayjs' -import { Link } from 'react-router-dom' -import { getConfigValue, getNavigationsValue } from '@ijl/cli' - +import { Link as ConnectedLink } from 'react-router-dom' +import { getNavigationsValue } from '@ijl/cli' import { Box, CardHeader, @@ -12,155 +11,252 @@ import { Stack, StackDivider, Button, - UnorderedList, + Card, Heading, Tooltip, + Spinner, + Container, + VStack, + Link, + Input, + CloseButton, + FormControl, + FormLabel, + FormHelperText, + Center, + FormErrorMessage, } from '@chakra-ui/react' +import { useForm, Controller } from 'react-hook-form' -import { - ArrowImg, - IconButton, - InputElement, - InputLabel, - InputWrapper, - StartWrapper, - Papper, - ErrorSpan, - Cross, - AddButton, - MainWrapper, - StyledCard, -} from './style' +import { ErrorSpan, MainWrapper } from './style' -import { linkOpen, moreDetails } from '../assets' - -import arrow from '../assets/36-arrow-right.svg' -import { keycloak } from '../__data__/kc' import { useAppSelector } from '../__data__/store' import { api } from '../__data__/api/api' import { isTeacher } from '../utils/user' +import { AddIcon, ArrowDownIcon, ArrowUpIcon, LinkIcon } from '@chakra-ui/icons' + +interface NewCourseForm { + startDt: string + name: string +} const CoursesList = () => { const user = useAppSelector((s) => s.user) const { data, isLoading, error } = api.useCoursesListQuery() - const [createCourse, crcQuery] = api.useCreateUpdateCourseMutation() + const [createUpdateCourse, crucQuery] = api.useCreateUpdateCourseMutation() const [value, setValue] = useState('') const [showForm, setShowForm] = useState(false) - const [showDetails, setShowDetails] = useState(false) + const [courseDetailsOpenedId, setCourseDetailsOpenedId] = useState< + string | null + >(null) - const handleChange = useCallback( - (event) => { - setValue(event.target.value.toUpperCase()) - }, - [setValue], - ) - const handleSubmit = useCallback( - (event) => { - event.preventDefault() - createCourse({ name: value }) - }, - [value], - ) + const { control, handleSubmit, reset } = useForm({ + mode: 'all', + }) + + const onSubmit = ({ startDt, name }) => { + createUpdateCourse({ name, startDt }) + } useEffect(() => { - if (crcQuery.isSuccess) { - setValue('') + if (crucQuery.isSuccess) { + reset() } - }, [crcQuery.isSuccess]) + }, [crucQuery.isSuccess]) + + if (isLoading) { + return ( + +
+ +
+
+ ) + } return ( - - - {isTeacher(user) && ( - <> - {showForm ? ( - - setShowForm(false)}> - X - -
- - - Название новой лекции: - - + {isTeacher(user) && ( + + {!showForm ? ( + + + + Создание курса + + setShowForm(false)} /> + + + + + ( + + Дата начала + + {fieldState.error ? ( + + {fieldState.error.message} + + ) : ( + + Укажите дату начала курса + + )} + + )} /> - - - - + + Название новой лекции: + + + + + + + + + {crcQuery?.error && ( {(crcQuery?.error as any).error} )}
-
+ + + ) : ( + + + + )} + + )} + + {data?.body?.map((c) => ( + + courseDetailsOpenedId === c._id + ? setCourseDetailsOpenedId(null) + : setCourseDetailsOpenedId(c._id) + } + /> + ))} + + + ) +} + +const CourseCard = ({ course, isOpened, openDetails }) => { + const [getLessonList, lessonList] = api.useLazyLessonListQuery() + useEffect(() => { + if (isOpened) { + getLessonList(course._id, true) + } + }, [isOpened]) + const user = useAppSelector((s) => s.user) + + return ( + + + + {course.name} + + + {isOpened && ( + + } spacing="8px"> + + {`Дата начала курса - ${dayjs(course.startDt).format('DD MMMM YYYYг.')}`} + + + Количество занятий - {course.lessons.length} + + {lessonList.isFetching ? ( + ) : ( - setShowForm(true)}>Добавить - )} - - )} - - {data?.body?.map((course) => ( - - - - {course.name} + <> + + Список занятий: - - {showDetails && ( - - } spacing="8px"> - - {`Дата начала курса - ${dayjs(course.startDt).format('DD MMMM YYYYг.')}`} - - - Количество занятий - {course.lessons.length} - - - - )} - - - - - - - - - - - - ))} - -
-
+ {lesson.name} + + ))} + + + )} + + + )} + + + + + + + + + + + ) }