NORY-34: rework app sidebar to support multiple groups

This commit is contained in:
Markus Thielker 2024-12-27 13:53:13 +01:00
parent 6d853ec309
commit c9ebf95dd5
No known key found for this signature in database

View file

@ -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 (
<Tooltip key={key} delayDuration={500}>
<TooltipTrigger asChild>
<SidebarMenuItem>
<SidebarMenuButton asChild>
<Link href={item.path}>
<item.icon/>
<span>{item.label}</span>
</Link>
</SidebarMenuButton>
</SidebarMenuItem>
</TooltipTrigger>
<TooltipContent side="right" className={collapsed ? '' : 'hidden'}>
{item.label}
</TooltipContent>
</Tooltip>
);
}
export function AppSidebar({ ...props }: React.ComponentProps<typeof Sidebar>) {
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 (
<Sidebar variant="inset" collapsible="icon" {...props}>
<SidebarContent>
<SidebarGroup>
<SidebarGroupLabel>Application</SidebarGroupLabel>
<SidebarGroupContent>
<SidebarMenu>
{items.map((item) => (
<SidebarMenuItem key={item.title}>
<SidebarMenuButton asChild>
<Link href={item.url}>
<item.icon/>
<span>{item.title}</span>
</Link>
</SidebarMenuButton>
</SidebarMenuItem>
))}
</SidebarMenu>
</SidebarGroupContent>
</SidebarGroup>
<SidebarMenu>
{items.map((item, index) => {
switch (item.type) {
case 'item':
return renderSidebarMenuItem(item, index, state === 'collapsed');
case 'group':
return (
<SidebarGroup key={index}>
<SidebarGroupLabel>{item.label}</SidebarGroupLabel>
{item.items.map((subItem, subIndex) => renderSidebarMenuItem(subItem, subIndex, state === 'collapsed'))}
</SidebarGroup>
);
}
})}
</SidebarMenu>
</SidebarContent>
<SidebarFooter>
<SidebarMenu>