feat(horas): nuevo módulo Reporte de Horas + icono reloj en headers

NUEVA APP /horas/
* public/horas/index.php — Bootstrap::inject del view
* public/horas/api.php — endpoint GET ?action=list que retorna:
  - entries: entradas detalladas con join a tramites_legales (link,
    título, cliente, departamento, estatus)
  - by_user: agregado por persona (solo socio/admin)
  - avail_users: dropdown de usuarios para filtrar (solo socio/admin)
  - total_hrs, is_socio, my_name
  Filtros: ?from=YYYY-MM-DD, ?to=YYYY-MM-DD, ?user=ID
* views/horas.html — UI con:
  - Header estandarizado (Portal, sync, user-chip, gear si socio, logout)
  - Toolbar de filtros: rango de fechas + dropdown usuario (solo socio)
    + atajos rápidos (Hoy / Semana / Mes / Año / Todo)
  - KPIs: Total horas, Entradas, Personas con horas (socio)
  - Tarjetas "Por persona" (solo socio), click filtra por ese usuario
  - Tabla detalle con link al trámite (?edit=CODIGO) + departamento +
    horas en h:mm + descripción

VISIBILIDAD
* Abogado/usuario ve solo sus horas (match por h.abogado = mi_name).
* Socio/admin ve todas las horas. Puede filtrar por persona.
* Admin oculto del dropdown de personas (queries excluyen role=admin).

ICONO DE RELOJ EN HEADERS
* Agregado .btn-clock (alias visual de .btn-gear) en:
  escrituras.html, tramites.html, calendario.html, admin.html,
  horas.html, public/index.php (landing).
* Posición: al lado del user-chip, antes del gear/logout.
* Visible para todos los autenticados (no restringido por rol).
This commit is contained in:
Soporte ZH Consultores
2026-06-05 00:56:10 +00:00
parent bbf91c7bec
commit 72c04ad594
8 changed files with 602 additions and 12 deletions
+6 -3
View File
@@ -33,9 +33,9 @@ header{background:var(--navy);border-bottom:3px solid var(--gold);padding:0 24px
.user-name{font-size:12px;color:rgba(255,255,255,0.85);max-width:160px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.btn-logout{font-size:11px;padding:4px 10px;border:1px solid rgba(255,255,255,0.20);border-radius:6px;background:transparent;color:rgba(255,255,255,0.70);cursor:pointer;font-family:'DM Sans',sans-serif;transition:all .15s;text-decoration:none;display:inline-block;line-height:1.6;}
.btn-logout:hover{background:rgba(255,255,255,0.10);color:#fff;border-color:rgba(255,255,255,0.30);}
.btn-gear{display:inline-flex;align-items:center;justify-content:center;width:34px;height:34px;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;cursor:pointer;font-family:'DM Sans',sans-serif;}
.btn-gear:hover{background:var(--gold);border-color:var(--gold);color:var(--navy);}
.btn-gear svg{width:16px;height:16px;}
.btn-gear,.btn-clock{display:inline-flex;align-items:center;justify-content:center;width:34px;height:34px;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;cursor:pointer;font-family:'DM Sans',sans-serif;}
.btn-gear:hover,.btn-clock:hover{background:var(--gold);border-color:var(--gold);color:var(--navy);}
.btn-gear svg,.btn-clock svg{width:16px;height:16px;}
.inv-stack{display:inline-flex;align-items:center;gap:3px;}
.inv-avatar{display:inline-flex;align-items:center;justify-content:center;width:22px;height:22px;border-radius:50%;background:var(--navy);color:#fff;font-size:9.5px;font-weight:700;border:1.5px solid #fff;cursor:default;font-family:'DM Sans',sans-serif;}
.inv-more{font-size:10px;color:var(--gray);margin-left:3px;}
@@ -161,6 +161,9 @@ tr.expanded>td{background:#fffdf5;}
<div class="user-avatar" id="user-avatar">?</div>
<span class="user-name" id="user-name">Cargando…</span>
</div>
<a class="btn-clock" href="/horas/" title="Reporte de horas">
<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="10"/><polyline points="12 6 12 12 16 14"/></svg>
</a>
<a class="btn-gear" href="/admin/" id="btn-gear" title="Panel de Control" style="display:none;">
<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>