import { useEffect, useState, useCallback } from 'react' import { getRolesConfig, patchRolConfig, resetRoles, type RolConfig, } from '../../services/config' const MODULOS_DISPONIBLES = [ 'mi-dia', 'cotizador', 'alta-cliente', 'alta-afluencia', 'cobranza', 'chat', 'mi-tablero', 'tablero-comercial', 'contactos', ] const ACCIONES_DISPONIBLES = [ 'descartar_lead', 'editar_cotizacion', 'asignar_vendedor', 'ver_reportes', 'exportar_pdf', 'ver_precios', ] /** Descripción amigable de cada acción */ const ACCION_LABELS: Record = { descartar_lead: 'Descartar leads', editar_cotizacion: 'Editar cotizaciones', asignar_vendedor: 'Asignar vendedor', ver_reportes: 'Ver reportes', exportar_pdf: 'Exportar PDF', ver_precios: 'Ver precios', } /** Descripción amigable de cada módulo */ const MODULO_LABELS: Record = { 'mi-dia': 'Mi día', cotizador: 'Cotizador', 'alta-cliente': 'Alta cliente', 'alta-afluencia': 'Alta afluencia', cobranza: 'Cobranza', chat: 'Chat IA', 'mi-tablero': 'Mi tablero', 'tablero-comercial': 'Tablero comercial', contactos: 'Contactos', } interface RolEstado { modulos: string[] acciones: Record } export function RolesPermisos() { const [roles, setRoles] = useState([]) const [edicion, setEdicion] = useState>({}) const [cargando, setCargando] = useState(true) const [guardando, setGuardando] = useState(false) const [aviso, setAviso] = useState('') const [error, setError] = useState('') const cargar = useCallback(async () => { setCargando(true) setError('') try { const data = await getRolesConfig() setRoles(data) // Construir estado de edición const estado: Record = {} for (const r of data) { estado[r.rol] = { modulos: Array.isArray(r.modulos) ? (r.modulos as string[]) : JSON.parse(r.modulos as string) as string[], acciones: r.acciones && typeof r.acciones === 'object' ? (r.acciones as Record) : JSON.parse(r.acciones as string) as Record, } } setEdicion(estado) } catch { setError('No se pudieron cargar los roles.') } finally { setCargando(false) } }, []) useEffect(() => { void cargar() }, [cargar]) const toggleModulo = (rol: string, modulo: string) => { setEdicion((prev) => { const actual = prev[rol] if (!actual) return prev const modulos = actual.modulos.includes(modulo) ? actual.modulos.filter((m) => m !== modulo) : [...actual.modulos, modulo] return { ...prev, [rol]: { ...actual, modulos } } }) } const toggleAccion = (rol: string, accion: string) => { setEdicion((prev) => { const actual = prev[rol] if (!actual) return prev const acciones = { ...actual.acciones, [accion]: !actual.acciones[accion] } return { ...prev, [rol]: { ...actual, acciones } } }) } const guardarTodo = async () => { setGuardando(true) setAviso('') setError('') try { await Promise.all( Object.entries(edicion).map(([rol, estado]) => patchRolConfig(rol, { modulos: estado.modulos, acciones: estado.acciones, }), ), ) setAviso('Todos los roles se actualizaron correctamente.') } catch { setError('No se pudieron guardar los cambios. Intenta de nuevo.') } finally { setGuardando(false) } } const restaurar = async () => { if (!window.confirm('¿Restaurar todos los roles a sus valores por defecto?')) return setGuardando(true) setAviso('') setError('') try { await resetRoles() await cargar() setAviso('Roles restaurados a valores por defecto.') } catch { setError('No se pudieron restaurar los roles.') } finally { setGuardando(false) } } if (cargando) { return (

Cargando configuración de roles…

) } return (
{/* Botones de acción */}
{/* Feedback */} {aviso && (

{aviso}

)} {error && (

{error}

)} {/* Tabla de roles */}
{MODULOS_DISPONIBLES.map((m) => ( ))} {ACCIONES_DISPONIBLES.map((a) => ( ))} {roles.map((r) => { const estado = edicion[r.rol] if (!estado) return null return ( {MODULOS_DISPONIBLES.map((m) => ( ))} {ACCIONES_DISPONIBLES.map((a) => ( ))} ) })}
Rol {MODULO_LABELS[m] ?? m} {ACCION_LABELS[a] ?? a}
{r.rol} toggleModulo(r.rol, m)} className="h-4 w-4 rounded border-[#D1D5DB] text-accent focus:ring-accent/20" /> toggleAccion(r.rol, a)} className="h-4 w-4 rounded border-[#D1D5DB] text-accent focus:ring-accent/20" />
) }