From f856edc9169a23c6245f19998aed76903ba940c7 Mon Sep 17 00:00:00 2001 From: Klesti Selimaj Date: Fri, 27 Feb 2026 22:07:33 +0100 Subject: [PATCH] Sidebar --- src/components/sidebar/AppSidebar.tsx | 45 +++++++++++-------- src/components/sidebar/Entity.tsx | 65 +++++++++++++++++---------- 2 files changed, 67 insertions(+), 43 deletions(-) diff --git a/src/components/sidebar/AppSidebar.tsx b/src/components/sidebar/AppSidebar.tsx index 645a1d7..058ccbd 100644 --- a/src/components/sidebar/AppSidebar.tsx +++ b/src/components/sidebar/AppSidebar.tsx @@ -1,3 +1,5 @@ +"use client"; + import { Sidebar, SidebarContent, @@ -8,25 +10,30 @@ import { SidebarProvider, useSidebar, } from "@/components/ui/sidebar"; + import EntitySwitch from "./Entity"; + import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger, } from "../ui/dropdown-menu"; + import { ChevronDown } from "lucide-react"; -import { EntityId, Route, SetState, Workspace } from "@/lib/types"; +import { Route, SetState, Workspace } from "@/lib/types"; + +type AppSidebarProps = { + children: React.ReactNode; + workspace: Workspace; + setRoute: SetState; +}; export default function AppSidebar({ children, workspace, setRoute, -}: Readonly<{ - children: React.ReactNode; - workspace: Workspace; - setRoute: SetState; -}>) { +}: AppSidebarProps) { return ( @@ -37,52 +44,52 @@ export default function AppSidebar({ + - Acme Inc - Acme Corp. + {/* Future: real workspace switching */} + Rename Workspace + Export Workspace + - {workspace.layout.map((entity, i) => ( + {workspace.layout.map((entity) => ( ))} + +
{children}
); } -export function SidebarTrigger({ - className, - ...props -}: React.ComponentProps<"div">) { +export function SidebarTrigger(props: React.ComponentProps<"div">) { const { toggleSidebar } = useSidebar(); return (
{ - toggleSidebar(); - }} + onClick={toggleSidebar} {...props} /> ); diff --git a/src/components/sidebar/Entity.tsx b/src/components/sidebar/Entity.tsx index 6e0f8ea..bdc06e4 100644 --- a/src/components/sidebar/Entity.tsx +++ b/src/components/sidebar/Entity.tsx @@ -1,3 +1,5 @@ +"use client"; + import { CollapsibleTrigger } from "@radix-ui/react-collapsible"; import { SidebarGroup, @@ -9,11 +11,12 @@ import { } from "../ui/sidebar"; import { Collapsible, CollapsibleContent } from "../ui/collapsible"; import { ChevronDown } from "lucide-react"; -import { EntityId, Route, SetState, Workspace } from "@/lib/types"; +import { Route, Workspace } from "@/lib/types"; export type SidebarEntity = | { kind: "group"; + id: string; // ✅ add stable id name: string; children: SidebarEntity[]; } @@ -22,35 +25,39 @@ export type SidebarEntity = id: string; }; +type Props = { + entity: SidebarEntity; + workspace: Workspace; + setRoute: (route: Route) => void; +}; + export default function EntitySwitch({ entity, workspace, setRoute, -}: { - entity: SidebarEntity; - workspace: Workspace; - setRoute: SetState; -}) { +}: Props) { + // ---- GROUP ---- if (entity.kind === "group") { return ( - + {entity.name} - + + - {entity.children?.map((entity, i) => ( + {entity.children.map((child) => ( ))} @@ -60,17 +67,27 @@ export default function EntitySwitch({ ); - } else { - return ( - - { - setRoute({ workspace: workspace.id, entity: entity.id }); - }} - > - {workspace.entities[entity.id].name} - - - ); } -} + + // ---- ITEM ---- + const workspaceEntity = workspace.entities[entity.id]; + + if (!workspaceEntity) { + return null; // defensive against stale layout + } + + return ( + + + setRoute({ + workspace: workspace.id, + entity: entity.id, + }) + } + > + {workspaceEntity.name} + + + ); +} \ No newline at end of file