/* global React */
// Usuarios (HU.4.1) — Gestión de cuentas y roles
// Mismo patrón de diseño que Instituciones.
const { useState: useStateUs, useMemo: useMemoUs } = React;
// ---------------- Filtros avanzados ----------------
const ADV_DEFAULT_US = {
rol: 'todos', // todos | superadmin | admin | institucion | cancilleria | lector
institucion: [], // array de instituciones seleccionadas (multi-select)
estado: 'todos', // todos | activo | pendiente | desactivado
orden: 'az', // az | za
};
const ADV_GROUPS_US = [
{
key: 'rol',
label: 'Rol',
icon: 'Users',
options: [
{ v: 'todos', l: 'Todos' },
{ v: 'superadmin', l: 'Súper Admin' },
{ v: 'admin', l: 'Admin' },
{ v: 'institucion', l: 'Enlace Institucional' },
{ v: 'cancilleria', l: 'Cancillería' },
],
},
{
key: 'institucion',
label: 'Institución',
icon: 'Building2',
type: 'select',
options: [],
},
{
key: 'estado',
label: 'Estado',
icon: 'CheckCircle2',
options: [
{ v: 'todos', l: 'Todos' },
{ v: 'activo', l: 'Activos' },
{ v: 'pendiente', l: 'Pendientes' },
{ v: 'desactivado', l: 'Desactivados' },
],
},
{
key: 'orden',
label: 'Ordenar por nombre',
icon: 'ListChecks',
options: [
{ v: 'az', l: 'A → Z' },
{ v: 'za', l: 'Z → A' },
],
},
];
// Ícono encendido/apagado (toggle)
function PowerGlyphUs({ size = 13 }) {
return (
);
}
function UsuariosScreen({ roleId, user, onOpenNuevo }) {
const I = window.Icons;
const [items, setItems] = window.usePersistentState('usuarios', () => window.USUARIOS.slice());
const [q, setQ] = useStateUs('');
const [adv, setAdv] = useStateUs(ADV_DEFAULT_US);
const [advOpen, setAdvOpen] = useStateUs(false);
const [toggling, setToggling] = useStateUs(null);
const [deleting, setDeleting] = useStateUs(null);
// Vista de formulario (crear / editar)
const [view, setView] = useStateUs('list'); // 'list' | 'form'
const [editing, setEditing] = useStateUs(null);
const openCreate = () => { setEditing(null); setView('form'); };
const openEdit = (u) => { setEditing(u); setView('form'); };
const backToList = () => { setView('list'); setEditing(null); };
const handleSaveUser = (data) => {
const wantsContacto = !!data.esContacto;
const clean = { ...data };
delete clean.esContacto; // el contacto principal vive en institucion.contacto
let savedUser;
if (editing) {
savedUser = { ...editing, ...clean };
delete savedUser.esContacto;
setItems(list => list.map(it => it.id === editing.id ? savedUser : it));
} else {
const id = `u-${Date.now().toString(36)}`;
savedUser = { id, ultimo: 'Nunca', estado: 'pendiente', ...clean };
setItems(list => [savedUser, ...list]);
}
// Sincroniza el contacto principal de la institución (solo enlaces institucionales)
if (window.cgrData && window.cgrData.ajustarContacto && savedUser.rol === 'institucion') {
window.cgrData.ajustarContacto(savedUser.institucion, savedUser.nombre, savedUser.email, wantsContacto);
if (editing && editing.institucion && editing.institucion !== savedUser.institucion) {
window.cgrData.ajustarContacto(editing.institucion, savedUser.nombre, savedUser.email, false);
}
}
backToList();
};
const advCount = (adv.institucion.length ? 1 : 0) + (adv.rol !== 'todos' ? 1 : 0) + (adv.estado !== 'todos' ? 1 : 0) + (adv.orden !== 'az' ? 1 : 0);
// Lista de instituciones (para el dropdown del filtro)
const instituciones = useMemoUs(() => {
const set = new Set(items.map(u => u.institucion).filter(Boolean));
return Array.from(set).sort((a, b) => a.localeCompare(b, 'es', { sensitivity: 'base' }));
}, [items]);
const filtered = useMemoUs(() => {
const list = items.filter(u => {
if (q && !`${u.nombre} ${u.email} ${u.institucion}`.toLowerCase().includes(q.toLowerCase())) return false;
if (adv.rol !== 'todos' && u.rol !== adv.rol) return false;
if (adv.institucion.length && adv.institucion.indexOf(u.institucion) === -1) return false;
if (adv.estado !== 'todos' && window.cgrData.estadoUsuario(u) !== adv.estado) return false;
return true;
});
list.sort((a, b) => a.nombre.localeCompare(b.nombre, 'es', { sensitivity: 'base' }));
if (adv.orden === 'za') list.reverse();
return list;
}, [items, q, adv]);
const setAdvKey = (k, v) => setAdv(prev => ({ ...prev, [k]: v }));
const setAdvInst = (arr) => setAdv(prev => ({ ...prev, institucion: arr }));
const freshAdvUs = () => ({ rol: 'todos', institucion: [], estado: 'todos', orden: 'az' });
const resetAdv = () => setAdv(freshAdvUs());
const clearAll = () => { setQ(''); setAdv(freshAdvUs()); };
const handleToggleConfirm = () => {
if (!toggling) return;
const next = toggling.estado === 'desactivado' ? 'activo' : 'desactivado';
setItems(list => list.map(it => it.id === toggling.id ? { ...it, estado: next } : it));
setToggling(null);
};
const handleDeleteConfirm = () => {
if (!deleting) return;
setItems(list => list.filter(it => it.id !== deleting.id));
setDeleting(null);
};
const activeAdv = [];
if (adv.institucion.length) activeAdv.push({ key: 'institucion', group: 'Institución', label: adv.institucion.length === 1 ? adv.institucion[0] : `${adv.institucion.length} instituciones`, reset: () => setAdvInst([]) });
['rol', 'estado', 'orden'].forEach(k => {
if (adv[k] !== ADV_DEFAULT_US[k]) {
const group = ADV_GROUPS_US.find(g => g.key === k);
const opt = group.options.find(o => o.v === adv[k]);
activeAdv.push({ key: k, group: group.label, label: opt ? opt.l : adv[k], reset: () => setAdvKey(k, ADV_DEFAULT_US[k]) });
}
});
// Vista de formulario (crear / editar) — ocupa la misma área que el listado
if (view === 'form') {
return (
Administra las cuentas y roles de los funcionarios de la CGR y de las instituciones reportantes. Crea, edita o desactiva accesos; el historial de cada cuenta se conserva.
No hay usuarios que coincidan con la combinación actual de filtros. {(q || advCount > 0) && ( <>{' '}.> )}
| Usuario | Rol | Institución | Estado | Acciones |
|---|---|---|---|---|
|
{u.initials}
{u.nombre}
{u.email}
|
{u.institucion} | {estadoEf === 'activo' ? 'Activo' : estadoEf === 'pendiente' ? 'Pendiente' : 'Desactivado'} {instApagada && u.estado !== 'desactivado' && ( institución desactivada )} |
{esContacto ? (
|
{isActive ? ( <>{usuario.nombre} perderá el acceso a la plataforma de inmediato, pero se conserva todo el historial de sus acciones. Podrás reactivarlo cuando lo necesites.> ) : ( <>{usuario.nombre} recuperará el acceso a la plataforma con su rol actual.> )}
Se eliminará la cuenta de {usuario.nombre} de forma permanente. Esta acción no se puede deshacer. Si solo quieres suspender el acceso temporalmente, usa Desactivar en su lugar.