212 lines
9.5 KiB
React
212 lines
9.5 KiB
React
import React, { useState } from 'react';
|
|
import { Link, useLocation, useNavigate } from 'react-router-dom';
|
|
|
|
export default function Sidebar() {
|
|
const [isCollapsed, setIsCollapsed] = useState(false);
|
|
const location = useLocation();
|
|
const navigate = useNavigate();
|
|
|
|
const handleLogout = () => {
|
|
localStorage.removeItem('access');
|
|
localStorage.removeItem('refresh');
|
|
|
|
// Disparar evento para actualizar el navbar
|
|
window.dispatchEvent(new CustomEvent('authStateChanged'));
|
|
|
|
navigate('/login');
|
|
};
|
|
|
|
export default function Sidebar() {
|
|
const [isCollapsed, setIsCollapsed] = useState(false);
|
|
const location = useLocation();
|
|
|
|
const menuItems = [
|
|
{
|
|
name: 'Mi Organización',
|
|
path: '/organization',
|
|
icon: (
|
|
<svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M19 21V5a2 2 0 00-2-2H7a2 2 0 00-2 2v16m14 0h2m-2 0h-5m-9 0H3m2 0h5M9 7h1m-1 4h1m4-4h1m-1 4h1m-5 10v-5a1 1 0 011-1h2a1 1 0 011 1v5m-4 0h4" />
|
|
</svg>
|
|
)
|
|
},
|
|
{
|
|
name: 'Importadores',
|
|
path: '/importers',
|
|
icon: (
|
|
<svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M20 13V6a2 2 0 00-2-2H6a2 2 0 00-2 2v7m16 0v5a2 2 0 01-2 2H6a2 2 0 01-2-2v-5m16 0h-2.586a1 1 0 00-.707.293l-2.414 2.414a1 1 0 01-.707.293h-3.172a1 1 0 01-.707-.293l-2.414-2.414A1 1 0 006.586 13H4" />
|
|
</svg>
|
|
)
|
|
},
|
|
{
|
|
name: 'Usuarios',
|
|
path: '/users',
|
|
icon: (
|
|
<svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M12 4.354a4 4 0 110 5.292M15 21H3v-1a6 6 0 0112 0v1zm0 0h6v-1a6 6 0 00-9-5.197m13.5-9a2.5 2.5 0 11-5 0 2.5 2.5 0 015 0z" />
|
|
</svg>
|
|
)
|
|
},
|
|
{
|
|
name: 'Reportes',
|
|
path: '/reports',
|
|
icon: (
|
|
<svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v14a2 2 0 01-2 2h-2a2 2 0 01-2-2z" />
|
|
</svg>
|
|
)
|
|
},
|
|
{
|
|
name: 'Documentos',
|
|
path: '/documents',
|
|
icon: (
|
|
<svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z" />
|
|
</svg>
|
|
)
|
|
}
|
|
];
|
|
|
|
return (
|
|
<div className={`bg-gray-900 text-white transition-all duration-300 ${isCollapsed ? 'w-16' : 'w-64'} min-h-screen flex flex-col`}>
|
|
{/* Header - Logo y colapsar */}
|
|
<div className="p-4 border-b border-gray-700">
|
|
<div className="flex items-center justify-between">
|
|
{!isCollapsed && (
|
|
<div className="flex items-center">
|
|
{/* Logo de la organización */}
|
|
<div className="w-8 h-8 bg-indigo-600 rounded-lg flex items-center justify-center mr-3">
|
|
<svg className="w-5 h-5 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M19 21V5a2 2 0 00-2-2H7a2 2 0 00-2 2v16m14 0h2m-2 0h-5m-9 0H3m2 0h5M9 7h1m-1 4h1m4-4h1m-1 4h1m-5 10v-5a1 1 0 011-1h2a1 1 0 011 1v5m-4 0h4" />
|
|
</svg>
|
|
</div>
|
|
<h1 className="text-lg font-bold text-white">EFC Dashboard</h1>
|
|
</div>
|
|
)}
|
|
<button
|
|
onClick={() => setIsCollapsed(!isCollapsed)}
|
|
className="p-1.5 rounded-lg hover:bg-gray-700 transition-colors"
|
|
>
|
|
<svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
{isCollapsed ? (
|
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M13 5l7 7-7 7M5 5l7 7-7 7" />
|
|
) : (
|
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M11 19l-7-7 7-7m8 14l-7-7 7-7" />
|
|
)}
|
|
</svg>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Navigation */}
|
|
<nav className="flex-1 p-3 space-y-1">
|
|
{menuItems.map((item) => {
|
|
const isActive = location.pathname === item.path;
|
|
return (
|
|
<Link
|
|
key={item.path}
|
|
to={item.path}
|
|
className={`flex items-center px-3 py-2.5 text-sm rounded-lg transition-colors group ${
|
|
isActive
|
|
? 'bg-indigo-600 text-white'
|
|
: 'text-gray-300 hover:bg-gray-700 hover:text-white'
|
|
}`}
|
|
title={isCollapsed ? item.name : ''}
|
|
>
|
|
<div className="flex-shrink-0">
|
|
{item.icon}
|
|
</div>
|
|
{!isCollapsed && (
|
|
<span className="ml-3 font-medium">{item.name}</span>
|
|
)}
|
|
</Link>
|
|
);
|
|
})}
|
|
</nav>
|
|
|
|
{/* Configuración */}
|
|
<div className="p-3 border-t border-gray-700">
|
|
<Link
|
|
to="/settings"
|
|
className={`flex items-center px-3 py-2.5 text-sm rounded-lg transition-colors group ${
|
|
location.pathname === '/settings'
|
|
? 'bg-indigo-600 text-white'
|
|
: 'text-gray-300 hover:bg-gray-700 hover:text-white'
|
|
}`}
|
|
title={isCollapsed ? 'Configuración' : ''}
|
|
>
|
|
<div className="flex-shrink-0">
|
|
<svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z" />
|
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z" />
|
|
</svg>
|
|
</div>
|
|
{!isCollapsed && (
|
|
<span className="ml-3 font-medium">Configuración</span>
|
|
)}
|
|
</Link>
|
|
</div>
|
|
|
|
{/* Footer - Perfil del Usuario */}
|
|
<div className="p-3 border-t border-gray-700">
|
|
{!isCollapsed ? (
|
|
<div className="space-y-3">
|
|
{/* Información del usuario */}
|
|
<div className="flex items-center space-x-3">
|
|
<div className="flex-shrink-0">
|
|
<img
|
|
className="w-8 h-8 rounded-full ring-2 ring-gray-700"
|
|
src="https://images.unsplash.com/photo-1472099645785-5658abf4ff4e?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80"
|
|
alt="Avatar del usuario"
|
|
/>
|
|
</div>
|
|
<div className="flex-1 min-w-0">
|
|
<p className="text-sm font-medium text-white truncate">
|
|
Juan Pérez
|
|
</p>
|
|
<p className="text-xs text-gray-400 truncate">
|
|
Administrador
|
|
</p>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Botón de logout más pequeño */}
|
|
<div className="pt-2">
|
|
<button
|
|
onClick={handleLogout}
|
|
className="w-full inline-flex items-center justify-center px-3 py-2 border border-transparent text-xs font-medium rounded-md text-white bg-red-600 hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500 transition duration-200"
|
|
>
|
|
<svg className="w-4 h-4 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M17 16l4-4m0 0l-4-4m4 4H7m6 4v1a3 3 0 01-3 3H6a3 3 0 01-3-3V7a3 3 0 013-3h4a3 3 0 013 3v1" />
|
|
</svg>
|
|
Cerrar sesión
|
|
</button>
|
|
</div>
|
|
</div>
|
|
) : (
|
|
<div className="flex flex-col items-center space-y-2">
|
|
{/* Avatar pequeño */}
|
|
<img
|
|
className="w-8 h-8 rounded-full ring-2 ring-gray-700"
|
|
src="https://images.unsplash.com/photo-1472099645785-5658abf4ff4e?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80"
|
|
alt="Avatar del usuario"
|
|
title="Juan Pérez - Administrador"
|
|
/>
|
|
{/* Botón de logout compacto */}
|
|
<button
|
|
onClick={handleLogout}
|
|
className="p-1.5 text-gray-400 hover:text-white hover:bg-red-600 rounded transition-colors"
|
|
title="Cerrar sesión"
|
|
>
|
|
<svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M17 16l4-4m0 0l-4-4m4 4H7m6 4v1a3 3 0 01-3 3H6a3 3 0 01-3-3V7a3 3 0 013-3h4a3 3 0 013 3v1" />
|
|
</svg>
|
|
</button>
|
|
</div>
|
|
)}
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|