From 957e264a645f78e6f207f6c323781d1e1ffdaffe Mon Sep 17 00:00:00 2001 From: Lizandro Guarnizo <77708265+lizandrogd@users.noreply.github.com> Date: Tue, 21 Apr 2026 17:39:34 -0500 Subject: [PATCH] up --- modules/turnero/api/get_display_global.php | 130 +++++ modules/turnero/module.php | 3 +- modules/turnero/views/display.php | 29 +- modules/turnero/views/display_global.php | 551 +++++++++++++++++++++ 4 files changed, 702 insertions(+), 11 deletions(-) create mode 100644 modules/turnero/api/get_display_global.php create mode 100644 modules/turnero/views/display_global.php diff --git a/modules/turnero/api/get_display_global.php b/modules/turnero/api/get_display_global.php new file mode 100644 index 0000000..c5ff09c --- /dev/null +++ b/modules/turnero/api/get_display_global.php @@ -0,0 +1,130 @@ +prepare( + "SELECT t.id, + t.codigo, + t.numero, + t.estado, + t.paciente_nombre, + t.llamado_recepcion_at AS llamado_at, + t.atendido_recepcion_por, + p.codigo AS prioridad_codigo, + p.nombre AS prioridad_nombre, + p.color AS prioridad_color + FROM turnero_turnos t + JOIN turnero_prioridades p ON p.id = t.prioridad_id + WHERE t.sesion_id = ? + AND t.estado = 'en_recepcion' + ORDER BY t.llamado_recepcion_at DESC" +); +$stmtRec->execute([$sesionId]); +$activosRecepcion = $stmtRec->fetchAll(PDO::FETCH_ASSOC); + +// ── 2. Lugares activos con su turno en servicio ─────────────── +$stmtLugares = $pdo->query( + "SELECT id, nombre, sort_order + FROM turnero_lugares + WHERE activo = 1 + ORDER BY sort_order ASC" +); +$lugares = $stmtLugares->fetchAll(PDO::FETCH_ASSOC); + +$lugaresActivos = []; +foreach ($lugares as $lugar) { + $stmtActivo = $pdo->prepare( + "SELECT t.id, + t.codigo, + t.numero, + t.estado, + t.paciente_nombre, + t.llamado_lugar_at AS llamado_at, + p.codigo AS prioridad_codigo, + p.nombre AS prioridad_nombre, + p.color AS prioridad_color + FROM turnero_turnos t + JOIN turnero_prioridades p ON p.id = t.prioridad_id + WHERE t.sesion_id = ? + AND t.estado IN ('en_espera_lugar', 'en_servicio') + AND t.lugar_destino_id = ? + ORDER BY t.llamado_lugar_at DESC + LIMIT 1" + ); + $stmtActivo->execute([$sesionId, (int)$lugar['id']]); + $turnoActivo = $stmtActivo->fetch(PDO::FETCH_ASSOC) ?: null; + + $lugaresActivos[] = [ + 'lugar_id' => (int)$lugar['id'], + 'lugar_nombre'=> $lugar['nombre'], + 'sort_order' => (int)$lugar['sort_order'], + 'turno' => $turnoActivo, + ]; +} + +// ── 3. Cola en espera (pendientes por llamar) ───────────────── +$stmtCola = $pdo->prepare( + "SELECT t.id, + t.codigo, + t.numero, + t.estado, + t.paciente_nombre, + t.creado_at, + p.codigo AS prioridad_codigo, + p.nombre AS prioridad_nombre, + p.color AS prioridad_color, + p.orden_peso + FROM turnero_turnos t + JOIN turnero_prioridades p ON p.id = t.prioridad_id + WHERE t.sesion_id = ? + AND t.estado = 'espera' + ORDER BY p.orden_peso ASC, t.creado_at ASC" +); +$stmtCola->execute([$sesionId]); +$cola = $stmtCola->fetchAll(PDO::FETCH_ASSOC); + +// ── 4. Estadísticas ─────────────────────────────────────────── +$stmtStats = $pdo->prepare( + "SELECT + COUNT(*) AS total, + SUM(estado = 'espera') AS en_espera, + SUM(estado = 'en_recepcion') AS en_recepcion, + SUM(estado = 'en_espera_lugar') AS en_espera_lugar, + SUM(estado = 'en_servicio') AS en_servicio, + SUM(estado IN ('en_recepcion','en_espera_lugar', + 'en_servicio')) AS en_atencion, + SUM(estado = 'finalizado') AS finalizados, + SUM(estado IN ('ausente','cancelado')) AS no_atendidos, + SEC_TO_TIME( + AVG( + CASE WHEN fin_lugar_at IS NOT NULL AND creado_at IS NOT NULL + THEN TIMESTAMPDIFF(SECOND, creado_at, fin_lugar_at) + ELSE NULL END + ) + ) AS tiempo_promedio_atencion + FROM turnero_turnos + WHERE sesion_id = ?" +); +$stmtStats->execute([$sesionId]); +$stats = $stmtStats->fetch(PDO::FETCH_ASSOC); + +jsonOk([ + 'sesion_id' => $sesionId, + 'activos_recepcion'=> $activosRecepcion, // array — todos los en_recepcion + 'lugares' => $lugaresActivos, + 'cola' => $cola, + 'stats' => $stats, + 'timestamp' => date('c'), +]); diff --git a/modules/turnero/module.php b/modules/turnero/module.php index daea2cf..40d20a9 100644 --- a/modules/turnero/module.php +++ b/modules/turnero/module.php @@ -18,6 +18,7 @@ return [ ['name' => 'Recepción', 'icon' => 'fas fa-concierge-bell', 'route' => '/erp.php?m=turnero&v=recepcion'], ['name' => 'Configuración', 'icon' => 'fas fa-sliders-h', 'route' => '/erp.php?m=turnero&v=configuracion'], ['name' => 'Kiosko', 'icon' => 'fas fa-desktop', 'route' => '/erp.php?m=turnero&v=kiosko'], - ['name' => 'Pantalla TV', 'icon' => 'fas fa-tv', 'route' => '/erp.php?m=turnero&v=display'], + ['name' => 'Pantalla TV', 'icon' => 'fas fa-tv', 'route' => '/erp.php?m=turnero&v=display'], + ['name' => 'Pantalla TV Global', 'icon' => 'fas fa-th-large', 'route' => '/erp.php?m=turnero&v=display_global'], ], ]; diff --git a/modules/turnero/views/display.php b/modules/turnero/views/display.php index abbeb5c..54a4145 100644 --- a/modules/turnero/views/display.php +++ b/modules/turnero/views/display.php @@ -117,11 +117,13 @@ $_labColor = preg_match('/^#[0-9a-fA-F]{3,8}$/', $_dispCfg['doc_color'] ?? '') padding: 2rem; position: relative; overflow: hidden; background: #fff; + transition: background .5s; } /* Franja decorativa de color en el borde izquierdo */ .turno-activo::before { content: ''; position: absolute; left: 0; top: 0; bottom: 0; - width: 8px; background: var(--brand); + width: 10px; background: var(--prio-color, var(--brand)); + transition: background .5s; } .turno-activo .etiqueta { font-size: clamp(.8rem, 1.8vw, 1.1rem); @@ -133,7 +135,7 @@ $_labColor = preg_match('/^#[0-9a-fA-F]{3,8}$/', $_dispCfg['doc_color'] ?? '') font-size: clamp(5rem, 20vw, 15rem); font-weight: 900; line-height: 1; letter-spacing: -4px; - color: var(--brand); + color: var(--prio-color, var(--brand)); transition: color .4s; } .turno-activo .nombre-pac { @@ -147,6 +149,7 @@ $_labColor = preg_match('/^#[0-9a-fA-F]{3,8}$/', $_dispCfg['doc_color'] ?? '') font-size: clamp(.8rem, 1.6vw, 1.1rem); font-weight: 700; margin-top: 1rem; background: var(--brand-light); color: var(--brand-dark); + transition: background .4s, color .4s; } .turno-activo .sin-turno { font-size: clamp(1.2rem, 3vw, 2.2rem); @@ -164,7 +167,7 @@ $_labColor = preg_match('/^#[0-9a-fA-F]{3,8}$/', $_dispCfg['doc_color'] ?? '') } .ring-anim::before { content: ''; width: 35vmin; height: 35vmin; border-radius: 50%; - background: transparent; border: 5px solid var(--brand); opacity: 0; + background: transparent; border: 5px solid var(--prio-color, var(--brand)); opacity: 0; } .ring-anim.animar::before { animation: ping-ring .75s ease-out 1; } .turno-activo > *:not(.ring-anim) { position: relative; z-index: 1; } @@ -449,15 +452,21 @@ function renderSnapshot(snap) { lastCodigoActivo = activo.codigo; } - elCodigo.textContent = activo.codigo; - elCodigo.style.color = activo.prioridad_color - ? shadeColor(activo.prioridad_color, -30) - : 'var(--brand-dark)'; - elNombre.textContent = activo.paciente_nombre || ''; - elPrio.style.background = (activo.prioridad_color || '#1565c0') + '22'; - elPrio.style.color = activo.prioridad_color || '#1565c0'; + const prioColor = activo.prioridad_color || '#1565c0'; + const zona = document.getElementById('zona-activo'); + zona.style.setProperty('--prio-color', prioColor); + zona.style.background = prioColor + '12'; // fondo muy suave con color de prioridad + + elCodigo.textContent = activo.codigo; + elCodigo.style.color = ''; + elNombre.textContent = activo.paciente_nombre || ''; + elPrio.style.background = prioColor + '22'; + elPrio.style.color = prioColor; elPrio.innerHTML = ` ${activo.prioridad_codigo} — ${activo.prioridad_nombre}`; } else { + const zona = document.getElementById('zona-activo'); + zona.style.removeProperty('--prio-color'); + zona.style.background = '#fff'; elCodigo.textContent = '—'; elCodigo.style.color = '#cbd5e1'; elNombre.textContent = ''; diff --git a/modules/turnero/views/display_global.php b/modules/turnero/views/display_global.php new file mode 100644 index 0000000..1cc9671 --- /dev/null +++ b/modules/turnero/views/display_global.php @@ -0,0 +1,551 @@ +getConnection(); + $__rows = $__pdo->query( + "SELECT clave, valor FROM lab_config WHERE clave IN ('empresa_nombre','doc_logo_base64','doc_color')" + )->fetchAll(PDO::FETCH_KEY_PAIR); + $_dispCfg = $__rows ?: []; +} catch (\Throwable $_) {} +$_labNombre = htmlspecialchars($_dispCfg['empresa_nombre'] ?? 'Sistema de Turnos'); +$_labLogo = $_dispCfg['doc_logo_base64'] ?? ''; +$_labColor = preg_match('/^#[0-9a-fA-F]{3,8}$/', $_dispCfg['doc_color'] ?? '') ? $_dispCfg['doc_color'] : '#1565c0'; +?> + + +
+ + +