80 lines
3.0 KiB
TypeScript
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>
|
|
);
|
|
}
|