diff --git a/src/components/layout/nav-group.tsx b/src/components/layout/nav-group.tsx index 8553454c..4ae54f34 100644 --- a/src/components/layout/nav-group.tsx +++ b/src/components/layout/nav-group.tsx @@ -18,75 +18,35 @@ import { useSidebar, } from '@/components/ui/sidebar' import { Badge } from '../ui/badge' -import { NavItem, type NavGroup } from './types' +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuLabel, + DropdownMenuSeparator, + DropdownMenuTrigger, +} from '../ui/dropdown-menu' +import { NavCollapsible, NavItem, NavLink, type NavGroup } from './types' export function NavGroup({ title, items }: NavGroup) { - const { setOpenMobile } = useSidebar() + const { state } = useSidebar() const href = useLocation({ select: (location) => location.href }) return ( {title} {items.map((item) => { - if (!item.items) { + const key = `${item.title}-${item.url}` + + if (!item.items) + return + + if (state === 'collapsed') return ( - - - setOpenMobile(false)}> - {item.icon && } - {item.title} - {item.badge && {item.badge}} - - - + ) - } - return ( - - - - - {item.icon && } - {item.title} - {item.badge && {item.badge}} - - - - - - {item.items.map((subItem) => ( - - - setOpenMobile(false)} - > - {subItem.icon && } - {subItem.title} - {subItem.badge && ( - {subItem.badge} - )} - - - - ))} - - - - - ) + + return })} @@ -97,6 +57,117 @@ const NavBadge = ({ children }: { children: ReactNode }) => ( {children} ) +const SidebarMenuLink = ({ item, href }: { item: NavLink; href: string }) => { + const { setOpenMobile } = useSidebar() + return ( + + + setOpenMobile(false)}> + {item.icon && } + {item.title} + {item.badge && {item.badge}} + + + + ) +} + +const SidebarMenuCollapsible = ({ + item, + href, +}: { + item: NavCollapsible + href: string +}) => { + const { setOpenMobile } = useSidebar() + return ( + + + + + {item.icon && } + {item.title} + {item.badge && {item.badge}} + + + + + + {item.items.map((subItem) => ( + + + setOpenMobile(false)}> + {subItem.icon && } + {subItem.title} + {subItem.badge && {subItem.badge}} + + + + ))} + + + + + ) +} + +const SidebarMenuCollapsedDropdown = ({ + item, + href, +}: { + item: NavCollapsible + href: string +}) => { + return ( + + + + + {item.icon && } + {item.title} + {item.badge && {item.badge}} + + + + + + {item.title} {item.badge ? `(${item.badge})` : ''} + + + {item.items.map((sub) => ( + + + {sub.icon && } + {sub.title} + {sub.badge && ( + {sub.badge} + )} + + + ))} + + + + ) +} + function checkIsActive(href: string, item: NavItem, mainNav = false) { return ( href === item.url || // /endpint?search=param diff --git a/src/components/layout/types.ts b/src/components/layout/types.ts index 75a8a64e..86e8f6e5 100644 --- a/src/components/layout/types.ts +++ b/src/components/layout/types.ts @@ -18,15 +18,17 @@ interface BaseNavItem { icon?: React.ElementType } -export type NavItem = - | (BaseNavItem & { - items: (BaseNavItem & { url: LinkProps['to'] })[] - url?: never - }) - | (BaseNavItem & { - url: LinkProps['to'] - items?: never - }) +type NavLink = BaseNavItem & { + url: LinkProps['to'] + items?: never +} + +type NavCollapsible = BaseNavItem & { + items: (BaseNavItem & { url: LinkProps['to'] })[] + url?: never +} + +type NavItem = NavCollapsible | NavLink interface NavGroup { title: string @@ -39,4 +41,4 @@ interface SidebarData { navGroups: NavGroup[] } -export type { SidebarData, NavGroup } +export type { SidebarData, NavGroup, NavItem, NavCollapsible, NavLink }