151 lines
7.1 KiB
TypeScript
151 lines
7.1 KiB
TypeScript
"use client";
|
|
|
|
import { useState } from 'react';
|
|
import Link from 'next/link';
|
|
import { usePathname } from 'next/navigation';
|
|
import { LayoutDashboard, Newspaper, Folders, Building2, MapPin, BadgeDollarSign, FileText, LogOut, ChevronDown, ChevronRight, Image as ImageIcon, Settings, Calendar, RadioTower, Users } from 'lucide-react';
|
|
import { logout } from '@/app/actions/auth';
|
|
|
|
export const Sidebar = ({ user }: { user: any }) => {
|
|
const pathname = usePathname();
|
|
const [openSections, setOpenSections] = useState<Record<string, boolean>>({
|
|
directorio: true,
|
|
geografia: false,
|
|
comercial: false,
|
|
sistema: false
|
|
});
|
|
|
|
const toggleSection = (section: string) => {
|
|
setOpenSections(prev => ({ ...prev, [section]: !prev[section] }));
|
|
};
|
|
|
|
const sections = [
|
|
{
|
|
id: 'directorio',
|
|
title: 'Directorio',
|
|
items: [
|
|
{ name: 'Clientes', href: '/dashboard/clients', icon: Building2 },
|
|
{ name: 'Tipos de Cliente', href: '/dashboard/client_types', icon: Building2 },
|
|
]
|
|
},
|
|
{
|
|
id: 'geografia',
|
|
title: 'Geografía',
|
|
items: [
|
|
{ name: 'Países', href: '/dashboard/countries', icon: MapPin },
|
|
{ name: 'Departamentos', href: '/dashboard/departments', icon: MapPin },
|
|
{ name: 'Ciudades', href: '/dashboard/cities', icon: MapPin },
|
|
]
|
|
},
|
|
{
|
|
id: 'comercial',
|
|
title: 'Comercial',
|
|
items: [
|
|
{ name: 'Contratos', href: '/dashboard/contracts', icon: FileText },
|
|
{ name: 'Formas de Pago', href: '/dashboard/payment_methods', icon: BadgeDollarSign },
|
|
{ name: 'Facturación Electrónica', href: '/dashboard/facturacion', icon: BadgeDollarSign },
|
|
]
|
|
},
|
|
{
|
|
id: 'archivos',
|
|
title: 'Contenido Multimedia',
|
|
items: [
|
|
{ name: 'Biblioteca de Medios', href: '/dashboard/media', icon: ImageIcon },
|
|
]
|
|
},
|
|
{
|
|
id: 'sistema',
|
|
title: 'Sistema y Motor',
|
|
items: [
|
|
{ name: 'Perfil de Entidad', href: '/dashboard/entity', icon: Building2 },
|
|
{ name: 'Parrilla Programación', href: '/dashboard/programming', icon: Calendar },
|
|
{ name: 'Gestor StreamingTV', href: '/dashboard/streaming', icon: RadioTower },
|
|
{ name: 'Configuración Global', href: '/dashboard/settings', icon: Settings },
|
|
]
|
|
},
|
|
{
|
|
id: 'administracion',
|
|
title: 'Administración',
|
|
items: [
|
|
{ name: 'Gestión de Usuarios', href: '/dashboard/users', icon: Users },
|
|
]
|
|
}
|
|
];
|
|
|
|
return (
|
|
<aside className="w-64 border-r border-slate-800 bg-slate-900 overflow-y-auto hidden md:flex flex-col h-full shrink-0">
|
|
<div className="p-4 border-b border-slate-800 flex justify-between items-center bg-slate-950/50 sticky top-0 z-10">
|
|
<div>
|
|
<h2 className="text-xl font-black font-outfit uppercase tracking-tighter bg-clip-text text-transparent bg-gradient-to-r from-blue-400 to-cyan-400">
|
|
Almeira CMS
|
|
</h2>
|
|
<p className="text-xs font-bold text-slate-400 mt-1 truncate max-w-[140px]" title={user.email}>
|
|
{user.name || user.email}
|
|
</p>
|
|
</div>
|
|
<form action={logout}>
|
|
<button title="Cerrar sesión" className="text-slate-500 hover:text-red-400 p-2 rounded-lg hover:bg-slate-800 transition-colors border border-transparent hover:border-red-500/30">
|
|
<LogOut size={16} />
|
|
</button>
|
|
</form>
|
|
</div>
|
|
|
|
<nav className="p-4 space-y-2 flex-grow">
|
|
{/* Core items (No collapsible) */}
|
|
<div className="space-y-1 mb-6">
|
|
<Link href="/dashboard" className={`flex items-center gap-3 px-3 py-2.5 text-sm font-medium rounded-lg transition-colors ${pathname === '/dashboard' ? 'bg-cyan-500/10 text-cyan-400 border border-cyan-500/30' : 'text-slate-300 hover:bg-slate-800/80 hover:text-white'}`}>
|
|
<LayoutDashboard size={18} />
|
|
Inicio Dashboard
|
|
</Link>
|
|
<Link href="/dashboard/posts" className={`flex items-center gap-3 px-3 py-2.5 text-sm font-medium rounded-lg transition-colors ${pathname.includes('posts') ? 'bg-cyan-500/10 text-cyan-400 border border-cyan-500/30' : 'text-slate-300 hover:bg-slate-800/80 hover:text-white'}`}>
|
|
<Newspaper size={18} />
|
|
Publicaciones
|
|
</Link>
|
|
<Link href="/dashboard/categories" className={`flex items-center gap-3 px-3 py-2.5 text-sm font-medium rounded-lg transition-colors ${pathname.includes('categories') ? 'bg-cyan-500/10 text-cyan-400 border border-cyan-500/30' : 'text-slate-300 hover:bg-slate-800/80 hover:text-white'}`}>
|
|
<Folders size={18} />
|
|
Categorías
|
|
</Link>
|
|
</div>
|
|
|
|
{/* Expandable Sections */}
|
|
{sections.map((section) => {
|
|
const isOpen = openSections[section.id];
|
|
// Check if any child is active
|
|
const hasActiveChild = section.items.some(item => pathname.includes(item.href));
|
|
|
|
return (
|
|
<div key={section.id} className="pt-2">
|
|
<button
|
|
onClick={() => toggleSection(section.id)}
|
|
className={`flex items-center justify-between w-full px-3 py-2 text-xs font-black uppercase tracking-widest rounded-lg transition-colors ${hasActiveChild && !isOpen ? 'text-cyan-400 bg-cyan-500/5' : 'text-slate-500 hover:text-slate-300 hover:bg-slate-800/50'}`}
|
|
>
|
|
{section.title}
|
|
{isOpen ? <ChevronDown size={14} /> : <ChevronRight size={14} />}
|
|
</button>
|
|
|
|
<div className={`mt-1 space-y-1 overflow-hidden transition-all duration-300 ease-in-out ${isOpen ? 'max-h-64 opacity-100' : 'max-h-0 opacity-0'}`}>
|
|
{section.items.map(item => {
|
|
const isActive = pathname.includes(item.href);
|
|
return (
|
|
<Link
|
|
key={item.href}
|
|
href={item.href}
|
|
className={`flex items-center gap-3 pl-8 pr-3 py-2.5 text-sm font-medium rounded-lg transition-colors ${isActive ? 'bg-cyan-500/10 text-cyan-400 border border-cyan-500/30' : 'text-slate-400 hover:bg-slate-800/80 hover:text-white'}`}
|
|
>
|
|
<item.icon size={16} className={isActive ? 'text-cyan-400' : 'opacity-70'} />
|
|
{item.name}
|
|
</Link>
|
|
);
|
|
})}
|
|
</div>
|
|
</div>
|
|
)
|
|
})}
|
|
</nav>
|
|
<div className="p-4 border-t border-slate-800 text-center text-xs font-bold text-slate-600 uppercase tracking-widest pb-6">
|
|
Almeira CMS 1.0
|
|
</div>
|
|
</aside>
|
|
);
|
|
};
|