// ======================================== // NavGroup Component // ======================================== // Collapsible navigation group using Radix Accordion import { NavLink, useLocation } from 'react-router-dom'; import { useIntl } from 'react-intl'; import { cn } from '@/lib/utils'; import { AccordionItem, AccordionTrigger, AccordionContent, } from '@/components/ui/Accordion'; export interface NavItem { path: string; label: string; icon: React.ElementType; badge?: number | string; badgeVariant?: 'default' | 'success' | 'warning' | 'info'; /** When true, only exact path match activates this item (no prefix matching) */ end?: boolean; } export interface NavGroupProps { /** Unique identifier for the group */ groupId: string; /** Title i18n key */ titleKey: string; /** Optional icon for group header */ icon?: React.ElementType; /** Navigation items in this group */ items: NavItem[]; /** Whether sidebar is collapsed */ collapsed?: boolean; /** Callback when nav item is clicked */ onNavClick?: () => void; } export function NavGroup({ groupId, titleKey, icon: Icon, items, collapsed = false, onNavClick, }: NavGroupProps) { const { formatMessage } = useIntl(); const location = useLocation(); const title = formatMessage({ id: titleKey }); // If collapsed, render items without accordion if (collapsed) { return (
{items.map((item) => { const ItemIcon = item.icon; const [basePath] = item.path.split('?'); const isActive = item.end ? location.pathname === basePath : location.pathname === basePath || (basePath !== '/' && location.pathname.startsWith(basePath + '/')); return ( ); })}
); } return (
{Icon && } {title}
); } export default NavGroup;