import React, { useEffect, useRef, useState } from 'react' import dayjs from 'dayjs' import { Box, CardHeader, CardBody, Button, Card, Heading, Container, VStack, Input, CloseButton, FormControl, FormLabel, FormHelperText, FormErrorMessage, useToast, useColorMode, } from '@chakra-ui/react' import { useForm, Controller } from 'react-hook-form' const MENU_SCRIPT_URL = 'https://admin.bro-js.ru/remote-assets/lib/serviceMenu/serviceMenu.js' const loadServiceMenu = () => { return new Promise((resolve, reject) => { const script = document.createElement('script') script.src = MENU_SCRIPT_URL script.onload = () => setTimeout(() => resolve(true), 1000) script.onerror = reject document.body.appendChild(script) }) } import { ErrorSpan } from '../style' declare global { interface Window { createServiceMenu?: (options: any) => { show: () => void; hide: () => void; update: () => void; destroy: () => void; }; } } import { useAppSelector } from '../../__data__/store' import { api } from '../../__data__/api/api' import { isTeacher } from '../../utils/user' import { AddIcon } from '@chakra-ui/icons' import { PageLoader } from '../../components/page-loader/page-loader' import { CourseCard } from './course-card' import { keycloak } from '../../__data__/kc' interface NewCourseForm { startDt: string name: string } export const CoursesList = () => { const toast = useToast() const user = useAppSelector((s) => s.user) const { data, isLoading } = api.useCoursesListQuery() const [createUpdateCourse, crucQuery] = api.useCreateUpdateCourseMutation() const [showForm, setShowForm] = useState(false) const toastRef = useRef(null) const [serviceMenu, setServiceMenu] = useState(false) useEffect(() => { loadServiceMenu().then(() => { setServiceMenu(true) }).catch(console.error) }, []) const { control, handleSubmit, reset, formState: { errors }, getValues, } = useForm({ defaultValues: { startDt: dayjs().format('YYYY-MM-DD'), name: 'Название', }, }) const onSubmit = ({ startDt, name }) => { toastRef.current = toast({ title: 'Отправляем', status: 'loading', duration: 9000, }) createUpdateCourse({ name, startDt }) } useEffect(() => { if (crucQuery.isSuccess) { const values = getValues() if (toastRef.current) { toast.update(toastRef.current, { title: 'Курс создан.', description: `Курс ${values.name} успешно создан`, status: 'success', duration: 9000, isClosable: true, }) } reset() } }, [crucQuery.isSuccess]) const serviceMenuContainerRef = useRef(null) const serviceMenuInstanceRef = useRef(null) useEffect(() => { // Проверяем, что библиотека загружена и есть контейнер для меню if (window.createServiceMenu && serviceMenuContainerRef.current) { // Создаем меню сервисов serviceMenuInstanceRef.current = window.createServiceMenu({ accessToken: keycloak.token, apiUrl: 'https://admin.bro-js.ru', targetElement: serviceMenuContainerRef.current, styles: { dotColor: '#333', hoverColor: '#eee', backgroundColor: '#fff', textColor: '#333', }, translations: { menuTitle: 'Сервисы BRO', menuAriaLabel: 'Сервисы BRO', } }); } // Очистка при размонтировании return () => { if (serviceMenuInstanceRef.current) { serviceMenuInstanceRef.current.destroy(); serviceMenuInstanceRef.current = null; } }; }, [keycloak.token, serviceMenu]); if (isLoading) { return ( ) } return ( <>
{isTeacher(user) && ( {showForm ? ( Создание курса setShowForm(false)} />
( Дата начала {errors.startDt ? ( {errors.startDt?.message} ) : ( Укажите дату начала курса )} )} /> ( Название новой лекции: {errors.name && ( {errors.name.message} )} )} /> {crucQuery?.error && ( {(crucQuery?.error as any).error} )}
) : ( )}
)} {data?.body?.map((c) => ( ))}
) }