import { lazy, Suspense } from 'react';
import { createBrowserRouter, Navigate, type RouteObject } from 'react-router';
import { Spin } from 'antd';
import type { MenuRecord } from '@/types/auth';
import AuthGuard from './authGuard';
import { menusToRoutes } from './dynamicRoutes';
// eslint-disable-next-line react-refresh/only-export-components
const AdminLayout = lazy(() => import('@/layouts/AdminLayout'));
// eslint-disable-next-line react-refresh/only-export-components
const LoginPage = lazy(() => import('@/pages/login'));
// eslint-disable-next-line react-refresh/only-export-components
const ProfilePage = lazy(() => import('@/pages/profile'));
// eslint-disable-next-line react-refresh/only-export-components
const DashboardPage = lazy(() => import('@/pages/dashboard'));
// eslint-disable-next-line react-refresh/only-export-components
const NotFound = lazy(() => import('@/pages/error/404'));
// eslint-disable-next-line react-refresh/only-export-components
const LazyLoad: React.FC<{ children: React.ReactNode }> = ({ children }) => (
}>
{children}
);
// Static children of admin route (not from menus)
// These are always available: default redirect, profile, 404
const adminStaticChildren: RouteObject[] = [
{ index: true, element: },
{
path: 'dashboard',
element: ,
},
{
path: 'profile',
element: ,
},
// Catch-all 404
{ path: '*', element: },
];
export const router = createBrowserRouter([
{
path: '/login',
element: ,
},
{
id: 'admin',
path: '/',
element: (
),
children: adminStaticChildren,
errorElement: ,
},
]);
/** Dashboard static menu item — injected as the first sidebar entry */
const STATIC_MENU: MenuRecord = {
id: -1,
parentId: 0,
name: '工作台',
path: '/dashboard',
component: 'dashboard',
icon: 'ep:house',
type: 2,
sort: 0,
status: 0,
visible: true,
keepAlive: true,
};
/**
* Inject dynamic routes from backend menus into the admin layout.
* Prepend a static "工作台" dashboard menu, return the merged menus
* so the caller can store them correctly.
*/
export function addDynamicRoutes(menus: MenuRecord[]): MenuRecord[] {
const mergedMenus = [STATIC_MENU, ...menus];
const dynamicRoutes = menusToRoutes(mergedMenus);
router.patchRoutes('admin', [...adminStaticChildren, ...dynamicRoutes]);
// Only force re-match when the current URL is under the admin layout
// and matched to the catch-all 404 (e.g., page refresh before routes existed).
const { pathname } = router.state.location;
const isLogin = pathname === '/login';
const is404 = router.state.matches.some(
(m) => m.route.path === '*',
);
if (!isLogin && is404) {
router.navigate(pathname, { replace: true });
}
return mergedMenus;
}
/**
* Remove dynamic routes (called on logout).
* Resets admin children back to static-only.
*/
export function resetDynamicRoutes() {
router.patchRoutes('admin', adminStaticChildren);
}