fix(admin): bug del activo + simplificar a Nombre Completo + gear en landing
BUG FIX
* admin.html: el filtro <select id="f-activo"> y el modal <input id="f-activo">
tenían el MISMO id. document.getElementById devolvía el select (primer en
DOM order) y la lectura .checked siempre era undefined → JSON enviaba el
valor stale del select. Renombré el filtro a `f-activo-filter`.
REFACTOR: drop apellido, usar Nombre Completo
* Migración 007: copia apellido→name para placeholders, migra
escrituras_tramites.abogado y tramites_legales.abogado a usar nombre
completo, DROP COLUMN apellido + índice.
* Lookups: abogadoApellidos() → abogadoNames() filtra socios+abogados
activos con name no vacío.
* Auth.php: drop método apellido(), agregado userName().
* tramites/api.php: visibilidad usa users.name = t.abogado.
* admin/api.php: drop apellido en create/update payloads.
* admin.html: drop columna y campo Apellido del table y form.
* Bootstrap envía window.DONNA.abogados con nombres completos.
LANDING (index.php)
* Gear icon en dash-header visible solo si Auth::isSocio() (chequeo
server-side, sin flash de JS).
CLEANUP
* Eliminado logging de debug en admin/api.php que se agregó para
diagnosticar el bug del activo.
PERMISOS (sin cambios — confirmación)
* Trámites Legales: solo socio/abogado pueden crear (canCreate() ya lo
enforza desde 2db8f23).
* Escrituras: cualquier rol autenticado puede crear (escrituras/api.php
nunca tuvo restricción).
This commit is contained in:
+10
-19
@@ -157,18 +157,18 @@ tr.is-me td { background:#FFFBEB; font-weight:500; }
|
||||
|
||||
<div class="intro">
|
||||
<h1>Usuarios y permisos</h1>
|
||||
<p>Administra la lista unificada de usuarios del sistema. El campo <b>Apellido</b> es lo que aparece en el dropdown "Abogado Solicitante" (solo si el rol es <b>Socio</b> o <b>Abogado</b>). Los emails que empiezan con <code>placeholder-</code> son los apellidos sembrados al inicio para que los dropdowns no salieran vacíos; reemplázalos con los emails reales conforme los abogados se logueen.</p>
|
||||
<p>Administra la lista unificada de usuarios del sistema. El campo <b>Nombre completo</b> es lo que aparece en el dropdown "Abogado Solicitante" (solo si el rol es <b>Socio</b> o <b>Abogado</b>). Los emails que empiezan con <code>placeholder-</code> son los nombres sembrados al inicio para que los dropdowns no salieran vacíos; reemplázalos con los emails reales conforme los abogados se logueen.</p>
|
||||
</div>
|
||||
|
||||
<div class="toolbar">
|
||||
<input type="search" id="search" placeholder="Buscar por email, nombre o apellido…">
|
||||
<input type="search" id="search" placeholder="Buscar por email o nombre…">
|
||||
<select id="f-role">
|
||||
<option value="">— Todos los roles —</option>
|
||||
<option value="socio">Socio</option>
|
||||
<option value="abogado">Abogado</option>
|
||||
<option value="usuario">Usuario</option>
|
||||
</select>
|
||||
<select id="f-activo">
|
||||
<select id="f-activo-filter">
|
||||
<option value="">— Activos e inactivos —</option>
|
||||
<option value="1">Solo activos</option>
|
||||
<option value="0">Solo inactivos</option>
|
||||
@@ -182,8 +182,7 @@ tr.is-me td { background:#FFFBEB; font-weight:500; }
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Email</th>
|
||||
<th>Nombre</th>
|
||||
<th>Apellido</th>
|
||||
<th>Nombre completo</th>
|
||||
<th>Rol</th>
|
||||
<th>Activo</th>
|
||||
<th>Orden</th>
|
||||
@@ -209,15 +208,11 @@ tr.is-me td { background:#FFFBEB; font-weight:500; }
|
||||
<input type="email" id="f-email" placeholder="usuario@aal-law.com">
|
||||
<div class="fg-hint" id="hint-email">El email debe coincidir exactamente con la cuenta de Mailcow que el usuario usa para entrar.</div>
|
||||
</div>
|
||||
<div class="fg">
|
||||
<label>Nombre completo</label>
|
||||
<input type="text" id="f-name" placeholder="Ej: Carlos Abrego">
|
||||
</div>
|
||||
<div class="fg-row">
|
||||
<div class="fg">
|
||||
<label>Apellido (dropdown)</label>
|
||||
<input type="text" id="f-apellido" placeholder="Ej: Abrego">
|
||||
<div class="fg-hint">Solo aparece en dropdowns si el rol es Socio o Abogado.</div>
|
||||
<label>Nombre completo</label>
|
||||
<input type="text" id="f-name" placeholder="Ej: Carlos Abrego">
|
||||
<div class="fg-hint">Aparece en el dropdown "Abogado Solicitante" si el rol es Socio o Abogado.</div>
|
||||
</div>
|
||||
<div class="fg">
|
||||
<label>Rol</label>
|
||||
@@ -310,12 +305,12 @@ async function loadUsers(){
|
||||
function visibleUsers(){
|
||||
const q = $('search').value.toLowerCase().trim();
|
||||
const fR = $('f-role').value;
|
||||
const fA = $('f-activo').value;
|
||||
const fA = $('f-activo-filter').value;
|
||||
return users.filter(u => {
|
||||
if (fR && u.role !== fR) return false;
|
||||
if (fA !== '' && String(u.activo) !== fA) return false;
|
||||
if (q) {
|
||||
const blob = ((u.email||'')+' '+(u.name||'')+' '+(u.apellido||'')).toLowerCase();
|
||||
const blob = ((u.email||'')+' '+(u.name||'')).toLowerCase();
|
||||
if (!blob.includes(q)) return false;
|
||||
}
|
||||
return true;
|
||||
@@ -338,7 +333,6 @@ function render(){
|
||||
return `<tr class="${rowCls}">
|
||||
<td><b>${esc(u.email)}</b>${isPlaceholder?' <span class="placeholder">(placeholder)</span>':''}${isMe?' <span style="color:var(--gold-d);font-size:10px;">(tú)</span>':''}</td>
|
||||
<td>${esc(u.name) || '<span class="placeholder">—</span>'}</td>
|
||||
<td>${esc(u.apellido) || '<span class="placeholder">—</span>'}</td>
|
||||
<td><span class="role-pill role-${u.role}">${ROLE_LABEL[u.role] || u.role}</span></td>
|
||||
<td><span class="activo-pill activo-${u.activo}">${u.activo ? 'Activo' : 'Inactivo'}</span></td>
|
||||
<td>${u.orden}</td>
|
||||
@@ -353,7 +347,6 @@ function openCreate(){
|
||||
$('modal-title').textContent = 'Nuevo usuario';
|
||||
$('f-email').value = ''; $('f-email').readOnly = false;
|
||||
$('f-name').value = '';
|
||||
$('f-apellido').value = '';
|
||||
$('f-role-edit').value = 'usuario';
|
||||
$('f-orden').value = '0';
|
||||
$('f-activo').checked = true;
|
||||
@@ -370,7 +363,6 @@ function openEdit(id){
|
||||
$('f-email').value = u.email;
|
||||
$('f-email').readOnly = false;
|
||||
$('f-name').value = u.name || '';
|
||||
$('f-apellido').value = u.apellido || '';
|
||||
$('f-role-edit').value = u.role;
|
||||
$('f-orden').value = u.orden;
|
||||
$('f-activo').checked = u.activo === 1;
|
||||
@@ -390,7 +382,6 @@ async function saveUser(){
|
||||
const payload = {
|
||||
email: $('f-email').value.trim().toLowerCase(),
|
||||
name: $('f-name').value.trim(),
|
||||
apellido: $('f-apellido').value.trim(),
|
||||
role: $('f-role-edit').value,
|
||||
orden: parseInt($('f-orden').value, 10) || 0,
|
||||
activo: $('f-activo').checked ? 1 : 0,
|
||||
@@ -423,7 +414,7 @@ async function saveUser(){
|
||||
document.addEventListener('keydown', e => {
|
||||
if (e.key === 'Escape') closeModal();
|
||||
});
|
||||
['search','f-role','f-activo'].forEach(id => {
|
||||
['search','f-role','f-activo-filter'].forEach(id => {
|
||||
$(id).addEventListener('input', render);
|
||||
$(id).addEventListener('change', render);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user