72 lines
2.0 KiB
TypeScript
72 lines
2.0 KiB
TypeScript
import React, { useState, useEffect } from 'react';
|
|
import { Sidebar } from './Sidebar';
|
|
// import { Header } from './Header';
|
|
import { Breadcrumb } from './Breadcrumb';
|
|
import { useMatches, useLocation } from '@remix-run/react';
|
|
|
|
interface LayoutProps {
|
|
children: React.ReactNode;
|
|
}
|
|
|
|
// 添加一个接口表示路由handle可能包含的属性
|
|
interface RouteHandle {
|
|
hideBreadcrumb?: boolean;
|
|
[key: string]: unknown;
|
|
}
|
|
|
|
interface Match {
|
|
handle?: RouteHandle;
|
|
pathname: string;
|
|
data: unknown;
|
|
}
|
|
|
|
export function Layout({ children }: LayoutProps) {
|
|
const [sidebarCollapsed, setSidebarCollapsed] = useState(false);
|
|
const matches = useMatches() as Match[];
|
|
const location = useLocation();
|
|
|
|
// 检查当前路径是否应该隐藏侧边栏
|
|
const noLayoutPaths = ['/login', '/'];
|
|
const shouldHideSidebar = noLayoutPaths.includes(location.pathname);
|
|
|
|
// 检查当前路由是否应该隐藏默认面包屑
|
|
const shouldHideBreadcrumb = shouldHideSidebar || matches.some(match =>
|
|
match.handle && match.handle.hideBreadcrumb === true
|
|
);
|
|
|
|
// 从本地存储中获取侧边栏状态
|
|
useEffect(() => {
|
|
const savedState = localStorage.getItem('sidebarCollapsed');
|
|
if (savedState) {
|
|
setSidebarCollapsed(savedState === 'true');
|
|
}
|
|
}, []);
|
|
|
|
const toggleSidebar = () => {
|
|
const newState = !sidebarCollapsed;
|
|
setSidebarCollapsed(newState);
|
|
localStorage.setItem('sidebarCollapsed', String(newState));
|
|
};
|
|
|
|
// 如果是无布局页面,只渲染内容
|
|
if (shouldHideSidebar) {
|
|
return <>{children}</>;
|
|
}
|
|
|
|
return (
|
|
<div className="layout-container">
|
|
<Sidebar
|
|
collapsed={sidebarCollapsed}
|
|
onToggle={toggleSidebar}
|
|
/>
|
|
|
|
<div className={`main-content ${sidebarCollapsed ? 'sidebar-collapsed' : ''}`}>
|
|
{/* <Header username="系统管理员" /> */}
|
|
<div className="content-container">
|
|
{!shouldHideBreadcrumb && <Breadcrumb />}
|
|
{children}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|