mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-28 17:10:56 +00:00
153 lines
4.5 KiB
TypeScript
153 lines
4.5 KiB
TypeScript
import { type ReactNode, useEffect, useState } from "react";
|
|
import { Box, Paper, MantineProvider } from "@mantine/core";
|
|
|
|
import FreightDashboardHeader from "./FreightDashboardHeader";
|
|
import FreightSidebar from "./FreightSidebar";
|
|
import { getPageMeta } from "./route-meta";
|
|
import type { SidebarSection } from "./types";
|
|
import { freightMantineTheme } from "@/theme/freight-brand";
|
|
|
|
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 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"
|
|
/>
|
|
|
|
<MantineProvider theme={freightMantineTheme}>
|
|
<Box
|
|
style={{
|
|
display: "flex",
|
|
height: "100dvh",
|
|
overflow: "hidden",
|
|
background: "var(--mantine-color-gray-1)",
|
|
padding: "0px",
|
|
fontFamily: "'Outfit', var(--font-sans)",
|
|
}}
|
|
>
|
|
<Box style={{ display: "flex", height: "100%", minHeight: 0, width: "100%", gap: "5px" }}>
|
|
<FreightSidebar
|
|
sections={sidebarSections}
|
|
activeHref={activeHref}
|
|
onNavigate={onNavigate}
|
|
/>
|
|
|
|
<Box
|
|
style={{
|
|
display: "flex",
|
|
height: "100%",
|
|
minHeight: 0,
|
|
minWidth: 0,
|
|
flex: 1,
|
|
flexDirection: "column",
|
|
gap: "8px",
|
|
}}
|
|
>
|
|
<Paper
|
|
p={0}
|
|
radius="lg"
|
|
withBorder
|
|
style={{
|
|
flexShrink: 0,
|
|
background: "white",
|
|
border: "1px solid var(--mantine-color-gray-2)",
|
|
boxShadow: "0 1px 3px rgba(0, 0, 0, 0.05)",
|
|
}}
|
|
>
|
|
<FreightDashboardHeader
|
|
pageMeta={pageMeta}
|
|
headerRight={headerRight}
|
|
enableThemeToggle={enableThemeToggle}
|
|
userName={userName}
|
|
userEmail={userEmail}
|
|
userInitials={userInitials}
|
|
onLogout={onLogout}
|
|
theme={theme}
|
|
onToggleTheme={toggleTheme}
|
|
/>
|
|
</Paper>
|
|
|
|
<Paper
|
|
p={{ base: 16, md: 24 }}
|
|
radius="lg"
|
|
withBorder
|
|
style={{
|
|
minHeight: 0,
|
|
flex: 1,
|
|
overflowY: "auto",
|
|
overscrollBehavior: "contain",
|
|
background: "white",
|
|
border: "1px solid var(--mantine-color-gray-2)",
|
|
boxShadow: "0 1px 3px rgba(0, 0, 0, 0.05)",
|
|
}}
|
|
>
|
|
{children}
|
|
</Paper>
|
|
</Box>
|
|
</Box>
|
|
</Box>
|
|
</MantineProvider>
|
|
</>
|
|
);
|
|
};
|
|
|
|
export default FreightDashboardLayout;
|