88 lines
3.1 KiB
TypeScript
88 lines
3.1 KiB
TypeScript
import { Suspense, lazy, useEffect, type ReactNode } from 'react';
|
|
import { Navigate, Route, Routes, useLocation, useNavigate } from 'react-router-dom';
|
|
import MainLayout from '../components/layout/MainLayout';
|
|
import { useI18n } from '../i18n';
|
|
import LoginPage from '../pages/Login';
|
|
import { RedirectAuthenticated, RequireAuth, isAuthenticated } from './auth';
|
|
import { onAuthLogout } from './auth-session';
|
|
import { DEFAULT_PATH } from './routes';
|
|
|
|
const HomePage = lazy(() => import('../pages/Home'));
|
|
const ChannelsPage = lazy(() => import('../pages/Channels'));
|
|
const SkillsPage = lazy(() => import('../pages/Skills'));
|
|
const CronPage = lazy(() => import('../pages/Cron'));
|
|
const ScriptsPage = lazy(() => import('../pages/Scripts'));
|
|
const SettingPage = lazy(() => import('../pages/Setting'));
|
|
const KnowledgePage = lazy(() => import('../pages/Knowledge'));
|
|
|
|
function RouteLoadingFallback() {
|
|
const { t } = useI18n();
|
|
|
|
return (
|
|
<div className="flex h-full min-h-0 w-full items-center justify-center bg-[#f6f9fc] text-sm text-[#99A0AE] dark:bg-[#0f0f10] dark:text-gray-500">
|
|
{t('dashboard.route.loading')}
|
|
</div>
|
|
);
|
|
}
|
|
|
|
function renderLazyPage(element: ReactNode) {
|
|
return (
|
|
<Suspense fallback={<RouteLoadingFallback />}>
|
|
{element}
|
|
</Suspense>
|
|
);
|
|
}
|
|
|
|
function renderSettingViewRedirect(view: 'agents' | 'models') {
|
|
return <Navigate to={`/setting?view=${view}`} replace />;
|
|
}
|
|
|
|
function AuthLogoutRedirector() {
|
|
const location = useLocation();
|
|
const navigate = useNavigate();
|
|
|
|
useEffect(() => {
|
|
return onAuthLogout(({ from }) => {
|
|
const currentPath = location.pathname === '/login' ? undefined : location.pathname;
|
|
navigate('/login', {
|
|
replace: true,
|
|
state: { from: from ?? currentPath },
|
|
});
|
|
});
|
|
}, [location.pathname, navigate]);
|
|
|
|
return null;
|
|
}
|
|
|
|
export function AppRouter() {
|
|
const initialPath = isAuthenticated() ? DEFAULT_PATH : '/login';
|
|
|
|
return (
|
|
<>
|
|
<AuthLogoutRedirector />
|
|
<Routes>
|
|
<Route path="/" element={<Navigate to={initialPath} replace />} />
|
|
<Route element={<RedirectAuthenticated />}>
|
|
<Route path="/login" element={<LoginPage />} />
|
|
</Route>
|
|
|
|
<Route element={<RequireAuth />}>
|
|
<Route element={<MainLayout />}>
|
|
<Route path="/home" element={renderLazyPage(<HomePage />)} />
|
|
<Route path="/channels" element={renderLazyPage(<ChannelsPage />)} />
|
|
<Route path="/agents" element={renderSettingViewRedirect('agents')} />
|
|
<Route path="/models" element={renderSettingViewRedirect('models')} />
|
|
<Route path="/skills" element={renderLazyPage(<SkillsPage />)} />
|
|
<Route path="/cron" element={renderLazyPage(<CronPage />)} />
|
|
<Route path="/scripts" element={renderLazyPage(<ScriptsPage />)} />
|
|
<Route path="/setting" element={renderLazyPage(<SettingPage />)} />
|
|
<Route path="/knowledge" element={renderLazyPage(<KnowledgePage />)} />
|
|
</Route>
|
|
</Route>
|
|
|
|
<Route path="*" element={<Navigate to={initialPath} replace />} />
|
|
</Routes>
|
|
</>
|
|
);
|
|
}
|