Добавлено расширение темы Chakra UI, реализован компонент AppHeader с переключением темной/светлой темы, обновлены стили для поддержки темной темы, улучшена загрузка компонентов с учетом цветовой схемы.

This commit is contained in:
2025-03-23 08:48:34 +03:00
parent aef215c6e0
commit 433e3b87bf
14 changed files with 278 additions and 158 deletions
+121 -49
View File
@@ -1,8 +1,8 @@
import React, { useEffect, Suspense } from 'react'
import React, { useEffect, Suspense, useRef, useState } from 'react'
import { Routes, Route, useNavigate } from 'react-router-dom'
import { Provider } from 'react-redux'
import { getNavigationsValue } from '@brojs/cli'
import { Box, Container, Spinner, VStack } from '@chakra-ui/react'
import { getNavigationValue } from '@brojs/cli'
import { Box, Container, Spinner, VStack, useColorMode } from '@chakra-ui/react'
import {
CourseListPage,
@@ -11,7 +11,31 @@ import {
UserPage,
AttendancePage,
} from './pages'
import { ErrorBoundary } from './components/error-boundary'
import { ErrorBoundary, AppHeader } from './components'
import { keycloak } from './__data__/kc'
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)
})
}
declare global {
interface Window {
createServiceMenu?: (options: any) => {
show: () => void;
hide: () => void;
update: () => void;
destroy: () => void;
};
}
}
const Wrapper = ({ children }: { children: React.ReactElement }) => (
<Suspense
@@ -37,49 +61,97 @@ const Wrapper = ({ children }: { children: React.ReactElement }) => (
</Suspense>
)
export const Dashboard = ({ store }) => (
<Provider store={store}>
<Routes>
<Route
path={getNavigationsValue('journal.main')}
element={
<Wrapper>
<CourseListPage />
</Wrapper>
interface DashboardProps {
store: any; // Используем any, поскольку точный тип store не указан
}
export const Dashboard = ({ store }: DashboardProps) => {
const serviceMenuContainerRef = useRef<HTMLDivElement>(null);
const serviceMenuInstanceRef = useRef<any>(null);
const [serviceMenu, setServiceMenu] = useState(false);
const { colorMode } = useColorMode();
useEffect(() => {
loadServiceMenu().then(() => {
setServiceMenu(true)
}).catch(console.error)
}, [])
useEffect(() => {
// Проверяем, что библиотека загружена и есть контейнер для меню
if (window.createServiceMenu && serviceMenuContainerRef.current && serviceMenu) {
// Создаем меню сервисов
serviceMenuInstanceRef.current = window.createServiceMenu({
accessToken: keycloak.token,
apiUrl: 'https://admin.bro-js.ru',
targetElement: serviceMenuContainerRef.current,
styles: {
dotColor: colorMode === 'light' ? '#333' : '#ccc',
hoverColor: colorMode === 'light' ? '#eee' : '#444',
backgroundColor: colorMode === 'light' ? '#fff' : '#2D3748',
textColor: colorMode === 'light' ? '#333' : '#fff',
},
translations: {
menuTitle: 'Сервисы BRO',
menuAriaLabel: 'Сервисы BRO',
}
/>
<Route
path={`${getNavigationsValue('journal.main')}/lessons-list/:courseId`}
element={
<Wrapper>
<LessonListPage />
</Wrapper>
}
/>
<Route
path={`${getNavigationsValue('journal.main')}/u/:lessonId/:accessId`}
element={
<Wrapper>
<UserPage />
</Wrapper>
}
/>
<Route
path={`${getNavigationsValue('journal.main')}/lesson/:courseId/:lessonId`}
element={
<Wrapper>
<LessonDetailsPage />
</Wrapper>
}
/>
<Route
path={`${getNavigationsValue('journal.main')}${getNavigationsValue('link.journal.attendance')}`}
element={
<Wrapper>
<AttendancePage />
</Wrapper>
}
/>
</Routes>
</Provider>
)
});
}
// Очистка при размонтировании
return () => {
if (serviceMenuInstanceRef.current) {
serviceMenuInstanceRef.current.destroy();
serviceMenuInstanceRef.current = null;
}
};
}, [keycloak.token, serviceMenu, colorMode]);
return (
<Provider store={store}>
<AppHeader serviceMenuContainerRef={serviceMenuContainerRef} />
<Routes>
<Route
path={getNavigationValue('journal.main')}
element={
<Wrapper>
<CourseListPage />
</Wrapper>
}
/>
<Route
path={`${getNavigationValue('journal.main')}/lessons-list/:courseId`}
element={
<Wrapper>
<LessonListPage />
</Wrapper>
}
/>
<Route
path={`${getNavigationValue('journal.main')}/u/:lessonId/:accessId`}
element={
<Wrapper>
<UserPage />
</Wrapper>
}
/>
<Route
path={`${getNavigationValue('journal.main')}/lesson/:courseId/:lessonId`}
element={
<Wrapper>
<LessonDetailsPage />
</Wrapper>
}
/>
<Route
path={`${getNavigationValue('journal.main')}${getNavigationValue('link.journal.attendance')}`}
element={
<Wrapper>
<AttendancePage />
</Wrapper>
}
/>
</Routes>
</Provider>
)
}