casualroom/apps/fenghuo/web/components/nav-main.tsx

107 lines
2.8 KiB
TypeScript
Executable File

'use client';
import { IconCirclePlusFilled, IconMail, type Icon } from '@tabler/icons-react';
import Link from 'next/link';
import { usePathname } from 'next/navigation';
import { Button } from '@nice/ui/components/button';
import { Badge } from '@nice/ui/components/badge';
import {
SidebarGroup,
SidebarGroupContent,
SidebarGroupLabel,
SidebarMenu,
SidebarMenuButton,
SidebarMenuItem,
} from '@nice/ui/components/sidebar';
interface NavItem {
title: string;
url: string;
icon?: Icon;
badge?: string;
}
export function NavMain({
items,
title,
showQuickActions = false,
}: {
items: NavItem[];
title?: string;
showQuickActions?: boolean;
}) {
const pathname = usePathname();
// 检查路径是否激活的函数
const isPathActive = (itemUrl: string) => {
// 移除语言前缀进行比较
const cleanPathname = pathname.replace(/^\/[a-z]{2}(-[A-Z]{2})?/, '') || '/';
// 精确匹配
if (cleanPathname === itemUrl) {
return true;
}
// 对于非根路径,检查是否以该路径开头
if (itemUrl !== '/' && cleanPathname.startsWith(itemUrl + '/')) {
return true;
}
return false;
};
return (
<SidebarGroup>
{title && <SidebarGroupLabel>{title}</SidebarGroupLabel>}
<SidebarGroupContent className="flex flex-col gap-2">
{showQuickActions && (
<SidebarMenu>
<SidebarMenuItem className="flex items-center gap-2">
<SidebarMenuButton
tooltip="快速创建"
className="bg-primary text-primary-foreground hover:bg-primary/90 hover:text-primary-foreground active:bg-primary/90 active:text-primary-foreground min-w-8 duration-200 ease-linear"
asChild
>
<Link href="/create">
<IconCirclePlusFilled />
<span></span>
</Link>
</SidebarMenuButton>
<Button size="icon" className="size-8 group-data-[collapsible=icon]:opacity-0" variant="outline" asChild>
<Link href="/notifications">
<IconMail />
<span className="sr-only"></span>
</Link>
</Button>
</SidebarMenuItem>
</SidebarMenu>
)}
<SidebarMenu>
{items.map((item) => {
const isActive = isPathActive(item.url);
return (
<SidebarMenuItem key={item.title}>
<SidebarMenuButton tooltip={item.title} isActive={isActive} asChild>
<Link href={item.url} className="flex items-center justify-between">
<div className="flex items-center gap-3">
{item.icon && <item.icon />}
<span>{item.title}</span>
</div>
{item.badge && (
<Badge variant="secondary" className="ml-auto text-xs">
{item.badge}
</Badge>
)}
</Link>
</SidebarMenuButton>
</SidebarMenuItem>
);
})}
</SidebarMenu>
</SidebarGroupContent>
</SidebarGroup>
);
}