From c9ebf95dd510206b4e2041e530bd935f87df289f Mon Sep 17 00:00:00 2001 From: Markus Thielker Date: Fri, 27 Dec 2024 13:53:13 +0100 Subject: [PATCH] NORY-34: rework app sidebar to support multiple groups --- dashboard/src/components/app-sidebar.tsx | 135 ++++++++++++++++++----- 1 file changed, 105 insertions(+), 30 deletions(-) diff --git a/dashboard/src/components/app-sidebar.tsx b/dashboard/src/components/app-sidebar.tsx index 7039c7f..ff21f4d 100644 --- a/dashboard/src/components/app-sidebar.tsx +++ b/dashboard/src/components/app-sidebar.tsx @@ -5,14 +5,13 @@ import { SidebarContent, SidebarFooter, SidebarGroup, - SidebarGroupContent, SidebarGroupLabel, SidebarMenu, SidebarMenuButton, SidebarMenuItem, + useSidebar, } from '@/components/ui/sidebar'; -import { AppWindow, Home, LogOut, Moon, Sun, Users } from 'lucide-react'; -import React from 'react'; +import { AppWindow, ChartLine, FileLock2, Home, LogOut, LucideIcon, Moon, Sun, Users } from 'lucide-react'; import { DropdownMenu, DropdownMenuContent, @@ -21,50 +20,126 @@ import { } from '@/components/ui/dropdown-menu'; import { useTheme } from 'next-themes'; import { LogoutLink } from '@/ory'; +import React from 'react'; import Link from 'next/link'; +import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip'; + +interface SidebarGroup { + type: 'group'; + label: string; + items: SidebarItem[]; +} + +interface SidebarItem { + type: 'item'; + label: string; + path: string; + icon: LucideIcon; +} + +type SidebarContent = SidebarItem | SidebarGroup + +function renderSidebarMenuItem(item: SidebarItem, key: number, collapsed: boolean) { + return ( + + + + + + + {item.label} + + + + + + {item.label} + + + ); +} export function AppSidebar({ ...props }: React.ComponentProps) { const { setTheme } = useTheme(); - const items = [ + const { state } = useSidebar(); + + const items: SidebarContent[] = [ { - title: 'Home', - url: '/', - icon: Home, + label: 'Application', + type: 'group', + items: [ + { + type: 'item', + label: 'Home', + path: '/', + icon: Home, + }, + { + type: 'item', + label: 'Analytics', + path: '/analytics', + icon: ChartLine, + }, + ], }, { - title: 'Users', - url: '/user', - icon: Users, + label: 'Ory Kratos', + type: 'group', + items: [ + { + type: 'item', + label: 'Users', + path: '/user', + icon: Users, + }, + ], }, { - title: 'Applications', - url: '/application', - icon: AppWindow, + label: 'Ory Hydra', + type: 'group', + items: [ + { + type: 'item', + label: 'Clients', + path: '/client', + icon: AppWindow, + }, + ], + }, + { + label: 'Ory Keto', + type: 'group', + items: [ + { + type: 'item', + label: 'Relations', + path: '/relation', + icon: FileLock2, + }, + ], }, ]; return ( - - Application - - - {items.map((item) => ( - - - - - {item.title} - - - - ))} - - - + + {items.map((item, index) => { + switch (item.type) { + case 'item': + return renderSidebarMenuItem(item, index, state === 'collapsed'); + case 'group': + return ( + + {item.label} + {item.items.map((subItem, subIndex) => renderSidebarMenuItem(subItem, subIndex, state === 'collapsed'))} + + ); + } + })} +