import type { FC } from 'react'; import { useCallback, useEffect, useState } from 'react'; import { History, Search, X } from 'lucide-react'; import { Card, Button, Input, Select, EmptyState, Skeleton, toast } from './ui'; import { odooApi, type ConfigAuditRow } from '../services/odoo'; const MODULOS = [ { value: '', label: 'Todos los módulos' }, { value: 'comisiones', label: 'Comisiones' }, { value: 'tipo_cambio', label: 'Tipo de cambio' }, { value: 'metas', label: 'Metas' }, { value: 'horarios', label: 'Horarios' }, { value: 'roles', label: 'Roles y permisos' }, { value: 'usuarios', label: 'Usuarios' }, { value: 'catalogos', label: 'Catálogos' }, ]; const PAGE_SIZE = 25; const fmtFecha = (iso: string | null) => { if (!iso) return '—'; const [d, h] = iso.split(' '); const [y, m, day] = d.split('-'); return `${day}/${m}/${y} ${h || ''}`.trim(); }; const recorta = (v: string, n = 60) => (v && v.length > n ? `${v.slice(0, n)}…` : v || '—'); /** Bitácora de cambios de configuración: quién cambió qué y con qué valores. */ const AuditoriaPanel: FC = () => { const [rows, setRows] = useState([]); const [total, setTotal] = useState(0); const [totalPages, setTotalPages] = useState(1); const [page, setPage] = useState(1); const [loading, setLoading] = useState(true); const [modulo, setModulo] = useState(''); const [usuario, setUsuario] = useState(''); const [entidad, setEntidad] = useState(''); const [desde, setDesde] = useState(''); const [hasta, setHasta] = useState(''); const load = useCallback(async () => { try { setLoading(true); const res = await odooApi.getConfigAudit({ module: modulo || undefined, user: usuario || undefined, entity: entidad || undefined, date_from: desde || undefined, date_to: hasta || undefined, page, page_size: PAGE_SIZE, }); if (res.status === 'success') { setRows(res.registros); setTotal(res.total); setTotalPages(res.total_pages || 1); } } catch { toast.error('No se pudo cargar la auditoría'); } finally { setLoading(false); } }, [modulo, usuario, entidad, desde, hasta, page]); useEffect(() => { const t = setTimeout(load, 250); return () => clearTimeout(t); }, [load]); useEffect(() => { setPage(1); }, [modulo, usuario, entidad, desde, hasta]); const hayFiltros = modulo || usuario || entidad || desde || hasta; const limpiar = () => { setModulo(''); setUsuario(''); setEntidad(''); setDesde(''); setHasta(''); }; return (
setUsuario(e.target.value)} className="pl-9" />
setEntidad(e.target.value)} className="sm:max-w-[190px]" /> setDesde(e.target.value)} className="sm:max-w-[160px]" /> setHasta(e.target.value)} className="sm:max-w-[160px]" /> {hayFiltros && ( )}

Cambios de configuración

{total} {total === 1 ? 'registro' : 'registros'} · página {page} de {totalPages || 1}

{loading ? ( ) : rows.length === 0 ? ( } /> ) : (
{rows.map((r) => ( ))}
Fecha Usuario Módulo Entidad Campo Antes Después
{fmtFecha(r.date)}

{r.user_name || r.user_login || '—'}

{r.user_login}{r.user_role ? ` · ${r.user_role}` : ''}

{r.module_label}

{r.entity_label || r.entity || '—'}

{r.entity_label && r.entity &&

{r.entity}

}
{r.field || '—'} {recorta(r.old_value)} {recorta(r.new_value)}
)} {totalPages > 1 && (
)}
); }; export default AuditoriaPanel;