36 lines
1.2 KiB
TypeScript
36 lines
1.2 KiB
TypeScript
import { useState, useEffect } from 'react';
|
|
import { Outlet, useLocation } from 'react-router-dom';
|
|
import Sidebar from '@/components/layout/Sidebar';
|
|
import Header from '@/components/layout/Header';
|
|
import { ErrorBoundary } from '@/App';
|
|
|
|
export default function Layout() {
|
|
const { pathname } = useLocation();
|
|
const [sidebarOpen, setSidebarOpen] = useState(false);
|
|
|
|
// Close sidebar on route change (mobile navigation)
|
|
useEffect(() => {
|
|
setSidebarOpen(false);
|
|
}, [pathname]);
|
|
|
|
return (
|
|
<div className="min-h-screen text-white" style={{ background: 'var(--pc-bg-base)' }}>
|
|
{/* Fixed sidebar */}
|
|
<Sidebar open={sidebarOpen} onClose={() => setSidebarOpen(false)} />
|
|
|
|
{/* Main area offset by sidebar width on desktop, full-width on mobile */}
|
|
<div className="md:ml-60 ml-0 flex flex-col flex-1 min-w-0 h-screen">
|
|
<Header onMenuToggle={() => setSidebarOpen(true)} />
|
|
|
|
{/* Page content — ErrorBoundary keyed by pathname so the nav shell
|
|
survives a page crash and the boundary resets on route change */}
|
|
<main className="flex-1 overflow-y-auto min-h-0">
|
|
<ErrorBoundary key={pathname}>
|
|
<Outlet />
|
|
</ErrorBoundary>
|
|
</main>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|