57 lines
2.2 KiB
TypeScript
57 lines
2.2 KiB
TypeScript
'use client';
|
|
|
|
import React, { useState, Suspense } from 'react';
|
|
import { usePathname } from 'next/navigation';
|
|
import { SidebarRail, MenuItem } from './SidebarRail';
|
|
import { TopBar } from './TopBar';
|
|
import { MobileBottomBar } from './MobileBottomBar';
|
|
|
|
interface DashboardLayoutProps {
|
|
children: React.ReactNode;
|
|
menuItems: MenuItem[];
|
|
}
|
|
|
|
export const DashboardLayout: React.FC<DashboardLayoutProps> = ({ children, menuItems }) => {
|
|
// Estado centralizado do layout
|
|
const [isExpanded, setIsExpanded] = useState(true);
|
|
const pathname = usePathname();
|
|
|
|
return (
|
|
<div className="flex h-screen w-full bg-gray-100 dark:bg-zinc-950 text-slate-900 dark:text-slate-100 overflow-hidden md:p-3 md:gap-3 transition-colors duration-300">
|
|
{/* Sidebar controla seu próprio estado visual via props - Desktop Only */}
|
|
<div className="hidden md:flex">
|
|
<Suspense fallback={<div className="w-[80px] bg-white dark:bg-zinc-900" />}>
|
|
<SidebarRail
|
|
isExpanded={isExpanded}
|
|
onToggle={() => setIsExpanded(!isExpanded)}
|
|
menuItems={menuItems}
|
|
/>
|
|
</Suspense>
|
|
</div>
|
|
|
|
{/* Área de Conteúdo (Children) */}
|
|
<main className="flex-1 h-full min-w-0 overflow-hidden flex flex-col bg-gray-50 dark:bg-zinc-900 md:rounded-2xl shadow-lg relative transition-colors duration-300 border border-transparent dark:border-zinc-800"
|
|
style={{
|
|
backgroundImage: `radial-gradient(circle, rgb(200 200 200 / 0.15) 1px, transparent 1px)`,
|
|
backgroundSize: '24px 24px'
|
|
}}
|
|
>
|
|
{/* TopBar com Breadcrumbs e Search */}
|
|
<TopBar />
|
|
|
|
{/* Conteúdo das páginas */}
|
|
<div className="flex-1 overflow-auto pb-20 md:pb-0">
|
|
<div className="w-full h-full">
|
|
{children}
|
|
</div>
|
|
</div>
|
|
</main>
|
|
|
|
{/* Mobile Bottom Bar */}
|
|
<Suspense fallback={null}>
|
|
<MobileBottomBar menuItems={menuItems} />
|
|
</Suspense>
|
|
</div>
|
|
);
|
|
};
|