'use client'; import React, { useState } from 'react'; import Link from 'next/link'; import { usePathname } from 'next/navigation'; import { BarChart3, Target, FolderGit2, Bot, Layers, LogOut, UserCheck, CalendarDays, Radio, Megaphone, Share2, Contact, Menu, X, Leaf, BookMarked, Sparkles, Images, History, Plug, ChevronDown, } from 'lucide-react'; import SidebarTenantSwitcher from '@/components/SidebarTenantSwitcher'; import type { DashboardModuleId } from '@/lib/tenant-modules'; import DateRangePicker from '@/components/DateRangePicker'; import { useDateRange } from '@/components/DateRangeContext'; type NavItem = { href: string; label: string; icon: React.ComponentType<{ className?: string }>; iconClass: string; moduleId: DashboardModuleId; }; const NAV_ITEMS: NavItem[] = [ { href: '/dashboard/estrategia', label: 'Objetivos del Mes', icon: Target, iconClass: 'text-emerald-500', moduleId: 'estrategia', }, { href: '/dashboard/seguimiento', label: 'Seguimiento', icon: Radio, iconClass: 'text-sky-500', moduleId: 'seguimiento', }, { href: '/dashboard/kpis', label: 'Métricas', icon: BarChart3, iconClass: 'text-brand-500', moduleId: 'kpis', }, { href: '/dashboard/marca', label: 'Zona de marca', icon: BookMarked, iconClass: 'text-rose-500', moduleId: 'marca', }, { href: '/dashboard/activos', label: 'Biblioteca de Activos', icon: FolderGit2, iconClass: 'text-blue-500', moduleId: 'activos', }, { href: '/dashboard/creatividades', label: 'Creatividades Ads', icon: Sparkles, iconClass: 'text-brand-500', moduleId: 'creatives', }, { href: '/dashboard/asistente', label: 'Asistente IA Financiero', icon: Bot, iconClass: 'text-purple-500', moduleId: 'asistente', }, ]; const EXCLUDED_DATE_HEADER_ROUTES = [ '/dashboard/seguimiento', '/dashboard/marca', '/dashboard/activos', '/dashboard/creatividades', '/dashboard/creatives', '/dashboard/asistente', '/dashboard/agencia', '/dashboard/historial', ]; function shouldShowDateHeader(pathname: string | null): boolean { if (!pathname) return true; return !EXCLUDED_DATE_HEADER_ROUTES.some( (route) => pathname === route || pathname.startsWith(route + '/') ); } function isActive(pathname: string, href: string): boolean { if (pathname === href) return true; if (href !== '/dashboard' && href !== '/dashboard/agencia' && pathname.startsWith(href + '/')) return true; return false; } function NavLink({ item, onNavigate, hasSubItems, isOpen, onToggle, }: { item: NavItem | (Omit & { moduleId?: string }); onNavigate?: () => void; hasSubItems?: boolean; isOpen?: boolean; onToggle?: () => void; }) { const pathname = usePathname(); const active = isActive(pathname, item.href); const Icon = item.icon; const handleClick = (e: React.MouseEvent) => { if (hasSubItems && onToggle) { if (active) { // Si ya está en esta página, hacer clic en la sección pliega/despliega sin recargar e.preventDefault(); onToggle(); return; } else if (!isOpen) { // Al entrar a la sección, asegurar que se abre onToggle(); } } if (onNavigate) { onNavigate(); } }; return ( {active ? ( ) : null}
{item.label}
{hasSubItems ? ( { e.preventDefault(); e.stopPropagation(); onToggle?.(); }} onKeyDown={(e) => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); e.stopPropagation(); onToggle?.(); } }} className="p-1 rounded hover:bg-white/10 text-mist-400 hover:text-white transition-colors shrink-0" aria-label={isOpen ? 'Ocultar páginas' : 'Mostrar páginas'} > ) : null} ); } export default function DashboardShell({ children, email, company, role, isAgency, viewName, activeTenantId, enabledModules, clientLogoUrl, brandLabel, logoutAction, }: { children: React.ReactNode; email: string; company: string; role: string; isAgency: boolean; viewName?: string; activeTenantId?: string | null; /** null = show all (agency default). */ enabledModules?: Record | null; clientLogoUrl?: string | null; brandLabel?: string; logoutAction: () => void | Promise; }) { const [open, setOpen] = useState(false); const close = () => setOpen(false); const dateRange = useDateRange(); const pathname = usePathname(); const showDateHeader = shouldShowDateHeader(pathname); const isSocialRoute = pathname === '/dashboard/social' || pathname === '/dashboard/calendario' || pathname === '/dashboard/creatives'; const isAgenciaRoute = pathname === '/dashboard/agencia' || (pathname !== null && pathname.startsWith('/dashboard/agencia/')); const isMetricasRoute = pathname === '/dashboard/kpis' || (pathname !== null && pathname.startsWith('/dashboard/kpis/')) || pathname === '/dashboard/crm' || (pathname !== null && pathname.startsWith('/dashboard/crm/')) || pathname === '/dashboard/ad-tracker' || (pathname !== null && pathname.startsWith('/dashboard/ad-tracker/')) || isSocialRoute || pathname === '/dashboard/organico' || (pathname !== null && pathname.startsWith('/dashboard/organico/')); const [expandedSections, setExpandedSections] = useState>({}); const isMetricasOpen = expandedSections['metricas'] ?? isMetricasRoute; const isSocialOpen = expandedSections['social'] ?? isSocialRoute; const isAgenciaOpen = expandedSections['agencia'] ?? isAgenciaRoute; const toggleSection = (key: 'metricas' | 'social' | 'agencia') => { setExpandedSections((prev) => { const current = key === 'metricas' ? (prev['metricas'] ?? isMetricasRoute) : key === 'social' ? (prev['social'] ?? isSocialRoute) : (prev['agencia'] ?? isAgenciaRoute); return { ...prev, [key]: !current, }; }); }; const moduleOn = (id: DashboardModuleId) => { if (isAgency) return true; if (!enabledModules) return true; return enabledModules[id] !== false; }; const isItemVisible = (item: NavItem) => { if (item.moduleId === 'kpis') { return ( moduleOn('kpis') || moduleOn('crm') || moduleOn('ad-tracker') || moduleOn('social') || moduleOn('organico') ); } return moduleOn(item.moduleId); }; const visibleNav = NAV_ITEMS.filter(isItemVisible); const subLinkCls = (href: string) => `ml-7 flex items-center gap-2.5 rounded-md px-3 py-1.5 text-[13px] font-medium transition-colors ${ isActive(pathname, href) ? 'bg-white/[0.07] text-white' : 'text-mist-400 hover:bg-white/[0.05] hover:text-white' }`; const sidebar = (

{email}

{company} {role === 'admin' ? 'Agencia' : role === 'team' ? 'Equipo' : 'Cliente'}
); return (
{open ? (
) : null}
{showDateHeader ? (
) : (
)}
{children}
); }