Files
edr-platform/apps/edr-freight-web/backoffice/src/components/layout/FreightDashboardLayout.tsx

112 lines
3.3 KiB
TypeScript

import { type ReactNode, useEffect, useState } from "react";
import FreightDashboardHeader from "./FreightDashboardHeader";
import FreightSidebar from "./FreightSidebar";
import { getPageMeta } from "./route-meta";
import type { SidebarSection } from "./types";
type Theme = "light" | "dark";
const THEME_STORAGE_KEY = "edr-theme";
function getInitialTheme(): Theme {
if (typeof window === "undefined") return "light";
const stored = window.localStorage.getItem(THEME_STORAGE_KEY);
if (stored === "dark" || stored === "light") return stored;
return window.matchMedia?.("(prefers-color-scheme: dark)").matches ? "dark" : "light";
}
export interface FreightDashboardLayoutProps {
sidebarSections: SidebarSection[];
activeHref?: string;
onNavigate?: (href: string) => void;
headerRight?: ReactNode;
enableThemeToggle?: boolean;
userName?: string;
userEmail?: string;
userInitials?: string;
onLogout?: () => void;
children: ReactNode;
}
const panelClass =
"rounded-2xl border border-gray-200/80 bg-white shadow-[0_1px_3px_rgba(15,23,42,0.06)]";
const FreightDashboardLayout = ({
sidebarSections,
activeHref = "",
onNavigate,
headerRight,
enableThemeToggle = false,
userName,
userEmail,
userInitials,
onLogout,
children,
}: FreightDashboardLayoutProps) => {
const pageMeta = getPageMeta(activeHref);
const [theme, setTheme] = useState<Theme>(() =>
enableThemeToggle ? getInitialTheme() : "light",
);
useEffect(() => {
if (!enableThemeToggle) return;
const root = document.documentElement;
if (theme === "dark") {
root.classList.add("dark");
} else {
root.classList.remove("dark");
}
window.localStorage.setItem(THEME_STORAGE_KEY, theme);
}, [theme, enableThemeToggle]);
const toggleTheme = () => setTheme((current) => (current === "dark" ? "light" : "dark"));
return (
<>
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossOrigin="" />
<link
href="https://fonts.googleapis.com/css2?family=Outfit:wght@400;500;600;700&display=swap"
rel="stylesheet"
/>
<div
className="flex h-[100dvh] overflow-hidden bg-[#eceef2] p-3 antialiased md:p-4"
style={{ fontFamily: "'Outfit', var(--font-sans)" }}
>
<div className="flex h-full min-h-0 w-full gap-3 md:gap-3">
<FreightSidebar
sections={sidebarSections}
activeHref={activeHref}
onNavigate={onNavigate}
/>
<div className="flex h-full min-h-0 min-w-0 flex-1 flex-col gap-3 md:gap-3">
<div className={`shrink-0 ${panelClass}`}>
<FreightDashboardHeader
pageMeta={pageMeta}
headerRight={headerRight}
enableThemeToggle={enableThemeToggle}
userName={userName}
userEmail={userEmail}
userInitials={userInitials}
onLogout={onLogout}
theme={theme}
onToggleTheme={toggleTheme}
/>
</div>
<main
className={`min-h-0 flex-1 overflow-y-auto overscroll-contain ${panelClass} p-4 md:p-6`}
>
{children}
</main>
</div>
</div>
</div>
</>
);
};
export default FreightDashboardLayout;