import { useEffect, useState } from "react" const SIDEBAR_KEY = "crema.shell.sidebar" import { NavLink, useNavigate } from "react-router" import { Bell, LayoutDashboard, Boxes, Activity, Sparkles, BookOpen, Settings, Search, PanelLeftClose, PanelLeftOpen, User as UserIcon, LogOut, HelpCircle, Menu, Play, // CREMA:NAV-ICONS } from "lucide-react" import { useBrand, useUser, type Brand, type User, } from "~/lib/identity" import { Appbar, AppbarActions, AppbarSpacer, AppbarTitle, } from "~/components/layout/appbar" import { ThemeToggle } from "~/components/layout/theme-toggle" import { Avatar, AvatarFallback } from "~/components/ui/avatar" import { Button } from "~/components/ui/button" import { DropdownMenu, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuTrigger, } from "~/components/ui/dropdown-menu" import { Input } from "~/components/ui/input" import { Sheet, SheetContent, SheetHeader, SheetTitle, SheetTrigger, } from "~/components/ui/sheet" import { ScriptsDialog, useScriptsHotkey } from "~/components/scripts-dialog" type NavItem = { to: string icon: React.ComponentType<{ className?: string }> label: string end?: boolean } const navItems: NavItem[] = [ { to: "/", icon: LayoutDashboard, label: "Overview", end: true }, { to: "/resources", icon: Boxes, label: "Resources" }, { to: "/activity", icon: Activity, label: "Activity" }, { to: "/assistant", icon: Sparkles, label: "Assistant" }, { to: "/library", icon: BookOpen, label: "Library" }, { to: "/settings", icon: Settings, label: "Settings" }, // CREMA:NAV-ITEMS ] type AppShellProps = { title: string children: React.ReactNode brand?: Brand user?: User /** * Optional theme name. When set, the shell wraps itself in * `data-theme={theme}` so a route can opt into an alternate theme without * the caller having to add an extra wrapping div. */ theme?: string } export function AppShell({ title, children, brand: brandOverride, user: userOverride, theme, }: AppShellProps) { const defaultBrand = useBrand() const defaultUser = useUser() const brand = brandOverride ?? defaultBrand const user = userOverride ?? defaultUser const [expanded, setExpanded] = useState(() => { if (typeof window === "undefined") return false return localStorage.getItem(SIDEBAR_KEY) === "1" }) useEffect(() => { localStorage.setItem(SIDEBAR_KEY, expanded ? "1" : "0") }, [expanded]) const [mobileOpen, setMobileOpen] = useState(false) const [scriptsOpen, setScriptsOpen] = useState(false) const navigate = useNavigate() const BrandIcon = brand.icon useScriptsHotkey(() => setScriptsOpen(true)) return (
Skip to main content
{brand.name}
{title}
{user.name} {user.email} navigate("/settings")} > Profile navigate("/settings")} > Settings Help Sign out
{children}
) }