'use client'; /** * PortalSidebar — vertical sidebar navigation for the Client Portal. * * Renders navigation items vertically in a fixed left sidebar below the TopNav. * "Analítica" is a collapsible section with sub-items (Overview, Top Songs, * Income Groups, Territories, Exploitation Sources). * * Features: * - Fixed left sidebar (200px) on desktop (≥1024px) * - Active item highlighted with accent left border + accent text + accent bg * - Collapsible "Analítica" section with smooth animation * - Icons for each tab and sub-item * - Mobile hamburger menu + overlay drawer for viewports below 1024px */ import { useState } from 'react'; import Link from 'next/link'; import { usePathname } from 'next/navigation'; import { PORTAL_TABS, PORTAL_ANALYTICS_SUBITEMS } from '@/lib/constants/portal-navigation'; import { usePortalSidebarStore } from '@/lib/stores/portal-sidebar-store'; // ── Icon components ────────────────────────────────────────────────────────── function HomeIcon({ className }: { className?: string }) { return ( ); } function ChartIcon({ className }: { className?: string }) { return ( ); } function MusicIcon({ className }: { className?: string }) { return ( ); } function DocumentIcon({ className }: { className?: string }) { return ( ); } function ChartOverviewIcon({ className }: { className?: string }) { return ( ); } function TopSongsIcon({ className }: { className?: string }) { return ( ); } function IncomeGroupsIcon({ className }: { className?: string }) { return ( ); } function TerritoriesIcon({ className }: { className?: string }) { return ( ); } function SourcesIcon({ className }: { className?: string }) { return ( ); } function ChevronIcon({ expanded, className }: { expanded: boolean; className?: string }) { return ( ); } /** Map sub-item href to its icon component */ function SubItemIcon({ href, className }: { href: string; className?: string }) { switch (href) { case '/portal/analytics': return ; case '/portal/analytics/top-songs': return ; case '/portal/analytics/income-groups': return ; case '/portal/analytics/territories': return ; case '/portal/analytics/sources': return ; default: return ; } } /** Map tab href to its icon component */ function TabIcon({ href, className }: { href: string; className?: string }) { switch (href) { case '/portal': return ; case '/portal/analytics': return ; case '/portal/songs': return ; case '/portal/documents': return ; default: return ; } } // ── Helper: check if current path is within analytics section ───────────────── function isAnalyticsPath(pathname: string): boolean { return pathname.startsWith('/portal/analytics'); } // ── PortalSidebar component ────────────────────────────────────────────────── export default function PortalSidebar() { const pathname = usePathname(); const { isMobileOpen, closeMobile, toggleMobile } = usePortalSidebarStore(); const [analyticsExpanded, setAnalyticsExpanded] = useState(true); // Filter out the "Analítica" tab — it becomes a section header const mainTabs = PORTAL_TABS.filter((tab) => tab.href !== '/portal/analytics'); const renderNavContent = (onItemClick?: () => void) => ( <> {/* Inicio */} {mainTabs .filter((tab) => tab.href === '/portal') .map((tab) => { const isActive = pathname === tab.href; return ( {isActive && ( )} {tab.label} ); })} {/* Analítica collapsible section */}
{/* Collapsible sub-items */}
{PORTAL_ANALYTICS_SUBITEMS.map((item) => { const isActive = pathname === item.href; return ( {isActive && ( )} {item.label} ); })}
{/* Canciones & Documentos */} {mainTabs .filter((tab) => tab.href !== '/portal') .map((tab) => { const isActive = pathname === tab.href; return ( {isActive && ( )} {tab.label} ); })} ); return ( <> {/* ─── Desktop sidebar (≥1024px) ─────────────────────────────────── */} {/* ─── Mobile hamburger button (visible below lg) ───────────────── */} {/* ─── Mobile overlay + drawer (below lg) ───────────────────────── */} {isMobileOpen && ( <> {/* Backdrop */}