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:
+13
-15
@@ -41,27 +41,26 @@ try {
|
||||
if ($email === '') err('email requerido');
|
||||
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) err('email inválido');
|
||||
|
||||
$name = trim((string)($b['name'] ?? ''));
|
||||
$role = in_array(($b['role'] ?? ''), ROLES, true) ? $b['role'] : 'usuario';
|
||||
$apellido = trim((string)($b['apellido'] ?? ''));
|
||||
$activo = (int)($b['activo'] ?? 1) === 1 ? 1 : 0;
|
||||
$orden = (int)($b['orden'] ?? 0);
|
||||
$name = trim((string)($b['name'] ?? ''));
|
||||
$role = in_array(($b['role'] ?? ''), ROLES, true) ? $b['role'] : 'usuario';
|
||||
$activo = (int)($b['activo'] ?? 1) === 1 ? 1 : 0;
|
||||
$orden = (int)($b['orden'] ?? 0);
|
||||
|
||||
$exists = $pdo->prepare('SELECT id FROM users WHERE email = :e');
|
||||
$exists->execute([':e' => $email]);
|
||||
if ($exists->fetch()) err('Ya existe un usuario con ese email', 409);
|
||||
|
||||
$ins = $pdo->prepare(
|
||||
'INSERT INTO users (email, name, role, apellido, activo, orden, first_seen_at, last_login_at)
|
||||
VALUES (:email, :name, :role, :apellido, :activo, :orden, NULL, NULL)'
|
||||
'INSERT INTO users (email, name, role, activo, orden, first_seen_at, last_login_at)
|
||||
VALUES (:email, :name, :role, :activo, :orden, NULL, NULL)'
|
||||
);
|
||||
$ins->execute([
|
||||
':email' => $email, ':name' => $name, ':role' => $role,
|
||||
':apellido' => $apellido, ':activo' => $activo, ':orden' => $orden,
|
||||
':activo' => $activo, ':orden' => $orden,
|
||||
]);
|
||||
$id = (int)$pdo->lastInsertId();
|
||||
|
||||
$sel = $pdo->prepare('SELECT id, email, name, role, apellido, activo, orden, first_seen_at, last_login_at FROM users WHERE id = :id');
|
||||
$sel = $pdo->prepare('SELECT id, email, name, role, activo, orden, first_seen_at, last_login_at FROM users WHERE id = :id');
|
||||
$sel->execute([':id' => $id]);
|
||||
$row = $sel->fetch();
|
||||
$row['id'] = (int)$row['id'];
|
||||
@@ -97,22 +96,21 @@ try {
|
||||
if ($chk->fetch()) err('Otro usuario ya tiene ese email', 409);
|
||||
}
|
||||
|
||||
$name = trim((string)($b['name'] ?? ''));
|
||||
$apellido = trim((string)($b['apellido'] ?? ''));
|
||||
$orden = (int)($b['orden'] ?? 0);
|
||||
$name = trim((string)($b['name'] ?? ''));
|
||||
$orden = (int)($b['orden'] ?? 0);
|
||||
|
||||
$upd = $pdo->prepare(
|
||||
'UPDATE users SET email = :email, name = :name, role = :role,
|
||||
apellido = :apellido, activo = :activo, orden = :orden
|
||||
activo = :activo, orden = :orden
|
||||
WHERE id = :id'
|
||||
);
|
||||
$upd->execute([
|
||||
':email' => $newEmail, ':name' => $name, ':role' => $newRole,
|
||||
':apellido' => $apellido, ':activo' => $newActivo, ':orden' => $orden,
|
||||
':activo' => $newActivo, ':orden' => $orden,
|
||||
':id' => $id,
|
||||
]);
|
||||
|
||||
$sel = $pdo->prepare('SELECT id, email, name, role, apellido, activo, orden, first_seen_at, last_login_at FROM users WHERE id = :id');
|
||||
$sel = $pdo->prepare('SELECT id, email, name, role, activo, orden, first_seen_at, last_login_at FROM users WHERE id = :id');
|
||||
$sel->execute([':id' => $id]);
|
||||
$row = $sel->fetch();
|
||||
$row['id'] = (int)$row['id'];
|
||||
|
||||
+16
-6
@@ -106,6 +106,9 @@ a{color:inherit;text-decoration:none;}
|
||||
.user-email{font-size:10.5px;color:rgba(255,255,255,0.55);max-width:200px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
|
||||
.btn-logout{font-size:11px;padding:6px 12px;border:1px solid rgba(255,255,255,0.18);border-radius:18px;background:transparent;color:rgba(255,255,255,0.7);cursor:pointer;font-family:'DM Sans',sans-serif;transition:all .15s;}
|
||||
.btn-logout:hover{background:rgba(255,255,255,0.12);color:#fff;border-color:rgba(255,255,255,0.3);}
|
||||
.btn-gear{display:inline-flex;align-items:center;justify-content:center;width:36px;height:36px;border:1px solid rgba(255,255,255,0.18);border-radius:8px;color:rgba(255,255,255,0.85);transition:all .15s;text-decoration:none;font-family:'DM Sans',sans-serif;margin-right:8px;}
|
||||
.btn-gear:hover{background:var(--gold);border-color:var(--gold);color:var(--navy);}
|
||||
.btn-gear svg{width:16px;height:16px;}
|
||||
|
||||
.dash-main{max-width:1180px;margin:0 auto;padding:48px 32px 80px;}
|
||||
.dash-hero{margin-bottom:40px;}
|
||||
@@ -199,13 +202,20 @@ a{color:inherit;text-decoration:none;}
|
||||
<span class="brand-name" style="font-size:14px;color:rgba(255,255,255,0.7);">Portal interno</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="user-chip">
|
||||
<div class="user-avatar"><?= htmlspecialchars(initials($user['name'] ?: $user['email'])) ?></div>
|
||||
<div class="user-info">
|
||||
<span class="user-name"><?= htmlspecialchars($user['name'] ?: $user['email']) ?></span>
|
||||
<?php if ($user['name']): ?><span class="user-email"><?= htmlspecialchars($user['email']) ?></span><?php endif; ?>
|
||||
<div style="display:flex;align-items:center;">
|
||||
<?php if (Auth::isSocio()): ?>
|
||||
<a class="btn-gear" href="/admin/" title="Panel de Control">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="3"/><path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z"/></svg>
|
||||
</a>
|
||||
<?php endif; ?>
|
||||
<div class="user-chip">
|
||||
<div class="user-avatar"><?= htmlspecialchars(initials($user['name'] ?: $user['email'])) ?></div>
|
||||
<div class="user-info">
|
||||
<span class="user-name"><?= htmlspecialchars($user['name'] ?: $user['email']) ?></span>
|
||||
<?php if ($user['name']): ?><span class="user-email"><?= htmlspecialchars($user['email']) ?></span><?php endif; ?>
|
||||
</div>
|
||||
<a href="/auth/logout.php" class="btn-logout">Cerrar sesión</a>
|
||||
</div>
|
||||
<a href="/auth/logout.php" class="btn-logout">Cerrar sesión</a>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
|
||||
@@ -91,7 +91,7 @@ function hydrate(PDO $pdo, array $row): array {
|
||||
}, $hrs->fetchAll());
|
||||
|
||||
$inv = $pdo->prepare(
|
||||
'SELECT u.id, u.email, u.name, u.apellido
|
||||
'SELECT u.id, u.email, u.name
|
||||
FROM tramites_involucrados ti
|
||||
JOIN users u ON u.id = ti.user_id
|
||||
WHERE ti.tramite_id = :t
|
||||
@@ -109,7 +109,7 @@ function hydrate(PDO $pdo, array $row): array {
|
||||
/**
|
||||
* ¿El usuario actual puede ver/editar este trámite?
|
||||
* Socio → siempre
|
||||
* Resto → si es creador, o abogado solicitante (apellido), o involucrado
|
||||
* Resto → si es creador, o abogado solicitante (name), o involucrado
|
||||
*/
|
||||
function canView(PDO $pdo, int $tid): bool {
|
||||
if (Auth::isSocio()) return true;
|
||||
@@ -117,7 +117,7 @@ function canView(PDO $pdo, int $tid): bool {
|
||||
$uid = Auth::userId();
|
||||
$stmt = $pdo->prepare(
|
||||
"SELECT 1 FROM tramites_legales t
|
||||
LEFT JOIN users ua ON ua.apellido = t.abogado AND ua.activo = 1
|
||||
LEFT JOIN users ua ON ua.name = t.abogado AND ua.activo = 1
|
||||
LEFT JOIN tramites_involucrados ti ON ti.tramite_id = t.id AND ti.user_id = :uid
|
||||
WHERE t.id = :tid
|
||||
AND (t.creado_por = :email OR ua.id = :uid2 OR ti.user_id IS NOT NULL)
|
||||
@@ -153,7 +153,7 @@ try {
|
||||
} else {
|
||||
$stmt = $pdo->prepare(
|
||||
"SELECT DISTINCT t.* FROM tramites_legales t
|
||||
LEFT JOIN users ua ON ua.apellido = t.abogado AND ua.activo = 1
|
||||
LEFT JOIN users ua ON ua.name = t.abogado AND ua.activo = 1
|
||||
LEFT JOIN tramites_involucrados ti ON ti.tramite_id = t.id AND ti.user_id = :uid
|
||||
WHERE t.creado_por = :email
|
||||
OR ua.id = :uid2
|
||||
|
||||
Reference in New Issue
Block a user