Files
Investidor-V2/resources/js/components/portal-sidebar-navigation.tsx
T

80 lines
3.0 KiB
TypeScript

import { Link } from '@inertiajs/react';
import { LayoutGrid } from 'lucide-react';
import type { ReactNode } from 'react';
import type { PortalNavItem } from '@/lib/portal-navigation';
import { currentNavigationItem } from '@/lib/portal-navigation';
import { searchTerritoryHref } from '@/lib/search-territory';
import {
SidebarGroup,
SidebarGroupLabel,
SidebarMenu,
SidebarMenuButton,
SidebarMenuItem,
} from '@/components/ui/sidebar';
/** Render every authorised destination; a group is never reduced to its first link. */
export function PortalSidebarNavigation({
groups,
url,
}: {
groups: PortalNavItem[];
url: string;
}) {
const active = currentNavigationItem(groups, url);
const ordered = [
...groups.filter((group) => group.id === 'work'),
...groups.filter((group) => group.id !== 'work'),
];
const links = (items: PortalNavItem[], depth = 0): ReactNode =>
items.map((item) =>
item.children ? (
<li key={item.id} className="list-none">
<p className="text-muted-foreground px-2 pt-3 pb-1 text-xs font-medium">
{item.label}
</p>
<ul className="ml-2 border-l pl-2">
{links(item.children, depth + 1)}
</ul>
</li>
) : item.href ? (
<SidebarMenuItem key={item.id}>
<SidebarMenuButton
asChild
isActive={item.id === active}
className="h-auto min-h-8 py-2 whitespace-normal"
>
<Link
href={searchTerritoryHref(item.href, url)}
aria-current={
item.id === active ? 'page' : undefined
}
>
{depth === 0 && <LayoutGrid aria-hidden="true" />}
<span
className="min-w-0 flex-1"
style={{
whiteSpace: 'normal',
overflow: 'visible',
textOverflow: 'clip',
overflowWrap: 'anywhere',
}}
>
{item.label}
</span>
</Link>
</SidebarMenuButton>
</SidebarMenuItem>
) : null,
);
return (
<nav aria-label="Navegação completa do portal">
{ordered.map((group) => (
<SidebarGroup key={group.id}>
<SidebarGroupLabel>{group.label}</SidebarGroupLabel>
<SidebarMenu>{links(group.children ?? [])}</SidebarMenu>
</SidebarGroup>
))}
</nav>
);
}