Files
manyangles/apps/web/src/components/backend-shell.tsx
T

54 lines
2.9 KiB
TypeScript

"use client";
import Link from "next/link";
import { usePathname } from "next/navigation";
import { useEffect, useState, type ReactNode } from "react";
import { ChevronRight } from "lucide-react";
import type { WorkspaceGroup } from "@/components/group-switcher";
import { DoubleSidebarNavigation } from "@/components/double-sidebar-navigation";
import { activeNavigationItem, adminWorkspaces, albumWorkspaces } from "@/lib/workspace-navigation";
import { cn } from "@/lib/utils";
export function BackendShell({ children, area, groups, activeGroupId }: {
children: ReactNode;
area: "workspace" | "platform";
groups: WorkspaceGroup[];
activeGroupId: string | null;
showAdmin?: boolean;
}) {
const pathname = usePathname();
const [collapsed, setCollapsed] = useState(false);
useEffect(() => {
try { setCollapsed(localStorage.getItem("manyangles-sidebar-collapsed") === "true"); } catch {}
}, []);
function togglePanel() {
const next = !collapsed;
setCollapsed(next);
try { localStorage.setItem("manyangles-sidebar-collapsed", String(next)); } catch {}
}
const workspaces = area === "platform" ? adminWorkspaces : albumWorkspaces;
const applicationLabel = area === "platform" ? "Administration" : "Albums";
const activeItem = activeNavigationItem(workspaces, pathname);
const activeWorkspace = workspaces.find((workspace) => workspace.items.includes(activeItem!)) ?? workspaces[0]!;
const activeGroup = groups.find((group) => group.id === activeGroupId) ?? groups[0];
const signEventId = pathname.match(/^\/dashboard\/events\/([^/]+)\/sign$/)?.[1];
return (
<div className="min-h-[calc(100dvh-4rem)] bg-background">
<DoubleSidebarNavigation key={area} workspaces={workspaces} activeItem={activeItem}
applicationLabel={applicationLabel} panelCollapsed={collapsed} onTogglePanel={togglePanel}
groupName={area === "workspace" ? activeGroup?.name : undefined} />
<main className={cn("min-w-0", collapsed ? "lg:ml-[5.5rem]" : "lg:ml-[18.5rem]")}>
<div className="page-pad mx-auto w-full max-w-7xl py-5 lg:px-6 lg:py-6">
<nav aria-label="Breadcrumb" className="mb-5 flex items-center gap-2 text-xs text-muted-foreground">
<Link href={area === "platform" ? "/admin" : "/dashboard"} className="hover:text-foreground">{applicationLabel}</Link>
<ChevronRight aria-hidden="true" className="size-3" />
<span>{activeWorkspace.label}</span>
{signEventId ? <><ChevronRight aria-hidden="true" className="size-3" /><Link href={`/dashboard/events/${signEventId}`} className="hover:text-foreground">Event</Link><ChevronRight aria-hidden="true" className="size-3" /><span aria-current="page">Guest sign</span></> : activeItem && activeItem.label !== activeWorkspace.label ? <><ChevronRight aria-hidden="true" className="size-3" /><span>{activeItem.label}</span></> : null}
</nav>
{children}
</div>
</main>
</div>
);
}