"use client"; import { type RemixiconComponentType, RiArrowRightSLine, RiUserSharedLine, } from "@remixicon/react"; import Link from "next/link"; import { usePathname, useSearchParams } from "next/navigation"; import * as React from "react"; import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"; import { Badge } from "@/components/ui/badge"; import { Collapsible, CollapsibleContent, CollapsibleTrigger, } from "@/components/ui/collapsible"; import { SidebarGroup, SidebarGroupContent, SidebarGroupLabel, SidebarMenu, SidebarMenuAction, SidebarMenuButton, SidebarMenuItem, SidebarMenuSub, SidebarMenuSubButton, SidebarMenuSubItem, } from "@/components/ui/sidebar"; import { getAvatarSrc } from "@/lib/pagadores/utils"; type NavItem = { title: string; url: string; icon: RemixiconComponentType; isActive?: boolean; items?: { title: string; url: string; avatarUrl?: string | null; isShared?: boolean; key?: string; icon?: RemixiconComponentType; badge?: number; }[]; }; type NavSection = { title: string; items: NavItem[]; }; const MONTH_PERIOD_PARAM = "periodo"; const PERIOD_AWARE_PATHS = new Set([ "/dashboard", "/lancamentos", "/orcamentos", ]); export function NavMain({ sections }: { sections: NavSection[] }) { const pathname = usePathname(); const searchParams = useSearchParams(); const periodParam = searchParams.get(MONTH_PERIOD_PARAM); const normalizedPathname = pathname.endsWith("/") && pathname !== "/" ? pathname.slice(0, -1) : pathname; const isLinkActive = (url: string) => { const normalizedUrl = url.endsWith("/") && url !== "/" ? url.slice(0, -1) : url; // Verifica se é exatamente igual ou se o pathname começa com a URL return ( normalizedPathname === normalizedUrl || normalizedPathname.startsWith(`${normalizedUrl}/`) ); }; const buildHrefWithPeriod = (url: string) => { if (!periodParam) { return url; } const [rawPathname, existingSearch = ""] = url.split("?"); const normalizedRawPathname = rawPathname.endsWith("/") && rawPathname !== "/" ? rawPathname.slice(0, -1) : rawPathname; if (!PERIOD_AWARE_PATHS.has(normalizedRawPathname)) { return url; } const params = new URLSearchParams(existingSearch); params.set(MONTH_PERIOD_PARAM, periodParam); const queryString = params.toString(); return queryString ? `${normalizedRawPathname}?${queryString}` : normalizedRawPathname; }; const activeLinkClasses = "data-[active=true]:bg-sidebar-accent data-[active=true]:text-dark! hover:text-primary!"; return ( <> {sections.map((section, index) => ( {section.title} {section.items.map((item) => { const itemIsActive = isLinkActive(item.url); return ( {item.title} {item.items?.length ? ( <> Toggle {item.items?.map((subItem) => { const subItemIsActive = isLinkActive( subItem.url, ); const avatarSrc = getAvatarSrc( subItem.avatarUrl, ); const initial = subItem.title.charAt(0).toUpperCase() || "?"; return ( {subItem.icon ? ( ) : subItem.avatarUrl !== undefined ? ( {initial} ) : null} {subItem.title} {subItem.badge ? ( {subItem.badge} ) : null} {subItem.isShared ? ( ) : null} ); })} ) : null} ); })} ))} ); }