Files
whatsapp/modules/turnero/views/kiosko.php
T
Lizandro GuarnizoandClaude Sonnet 4.6 f363631b32 Turnero: mejoras UI, historial detallado, kiosko scanner, firma por turno
- Kiosko: detector scanner (gap < 80ms), iconos 90px, fa-person-pregnant, ticket Arial
- Recepción: vincular_paciente.php para persistir paciente_id antes de firmar consentimiento
- Historial y dashboard: recepción desk, empleado recepción/muestras, exámenes y comentarios
- display_global: turno más pequeño, lugar-nombre más grande
- lab_pacientes: modal compacta con form-sm
- Configuración: icono embarazada fa-person-pregnant en prioridades
- ver_formulario_enviado: firma por campo (fix doble firma)
- docker-compose.local.yml: override BD producción para dev local

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-22 22:07:09 -05:00

614 lines
26 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
/**
* Kiosko de turnos — pantalla táctil pública
* Ruta: /modules/turnero/views/kiosko.php
* Sin login requerido. NUNCA expone datos de otros pacientes.
*/
require_once __DIR__ . '/../../../config/config.php';
// ── Configuración visual del laboratorio ──────────────────────
$_kioskoCfg = [];
try {
$_kpdo = Database::getInstance()->getConnection();
$_krows = $_kpdo->query(
"SELECT clave, valor FROM lab_config
WHERE clave IN ('empresa_nombre','doc_logo_base64','doc_color')"
)->fetchAll(PDO::FETCH_KEY_PAIR);
$_kioskoCfg = $_krows ?: [];
} catch (\Throwable $_) {}
$_kNombre = htmlspecialchars($_kioskoCfg['empresa_nombre'] ?? 'Laboratorio Clínico');
$_kLogo = $_kioskoCfg['doc_logo_base64'] ?? '';
$_kColor = preg_match('/^#[0-9a-fA-F]{3,8}$/', $_kioskoCfg['doc_color'] ?? '')
? $_kioskoCfg['doc_color'] : '#1565c0';
// ── Cargar prioridades activas desde BD ───────────────────────
$prioridades = [];
try {
$_pdo = Database::getInstance()->getConnection();
$stmt = $_pdo->query(
"SELECT id, codigo, nombre, color, icono, descripcion, orden_peso
FROM turnero_prioridades
WHERE activo = 1
ORDER BY orden_peso ASC"
);
$prioridades = $stmt->fetchAll(PDO::FETCH_ASSOC);
} catch (\Throwable $e) {
// Fallback con prioridades por defecto si la BD no está disponible
$prioridades = [
['codigo'=>'A','nombre'=>'Niños', 'color'=>'#ef4444','icono'=>'fas fa-child', 'descripcion'=>'Pacientes menores de edad'],
['codigo'=>'B','nombre'=>'Embarazadas', 'color'=>'#f97316','icono'=>'fas fa-heart', 'descripcion'=>'Mujeres en estado de embarazo'],
['codigo'=>'C','nombre'=>'Adulto mayor', 'color'=>'#eab308','icono'=>'fas fa-person-cane', 'descripcion'=>'Mayores de 60 años'],
['codigo'=>'D','nombre'=>'Discapacidad', 'color'=>'#8b5cf6','icono'=>'fas fa-wheelchair', 'descripcion'=>'Personas con discapacidad'],
['codigo'=>'E','nombre'=>'Paciente general', 'color'=>'#3b82f6','icono'=>'fas fa-user', 'descripcion'=>'Atención general'],
['codigo'=>'F','nombre'=>'Muestra pendiente','color'=>'#6b7280','icono'=>'fas fa-vial', 'descripcion'=>'Entrega de muestra tomada'],
];
}
// Iconos por defecto por código (si la BD no tiene el campo icono populado)
$iconosDefecto = [
'A' => 'fas fa-child',
'B' => 'fas fa-heart',
'C' => 'fas fa-person-cane',
'D' => 'fas fa-wheelchair',
'E' => 'fas fa-user',
'F' => 'fas fa-vial',
];
foreach ($prioridades as &$p) {
if (empty($p['icono'])) {
$p['icono'] = $iconosDefecto[$p['codigo']] ?? 'fas fa-ticket-alt';
}
}
unset($p);
?>
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
<title>Kiosko <?= $_kNombre ?></title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css" rel="stylesheet">
<style>
:root {
--brand: <?= $_kColor ?>;
--brand-dark: color-mix(in srgb, <?= $_kColor ?> 75%, #000);
--brand-light: color-mix(in srgb, <?= $_kColor ?> 10%, #fff);
--brand-mid: color-mix(in srgb, <?= $_kColor ?> 22%, #fff);
}
/* ── Reset fullscreen ── */
*, *::before, *::after { box-sizing: border-box; }
html, body {
margin: 0; padding: 0;
height: 100%; width: 100%;
overflow: hidden;
background: var(--brand-light);
color: #1e293b;
font-family: 'Segoe UI', system-ui, sans-serif;
touch-action: manipulation;
-webkit-tap-highlight-color: transparent;
}
/* ── Layout general ── */
.kiosko-wrap {
display: flex;
flex-direction: column;
height: 100vh;
overflow: hidden;
}
/* ── Header con logo ── */
.kiosko-topbar {
background: var(--brand);
padding: 14px 28px;
display: flex;
align-items: center;
gap: 14px;
flex-shrink: 0;
box-shadow: 0 2px 12px rgba(0,0,0,.18);
}
.kiosko-topbar .logo-img {
height: 48px;
max-width: 140px;
object-fit: contain;
background: #fff;
border-radius: 8px;
padding: 4px 6px;
}
.kiosko-topbar .logo-fallback {
width: 46px; height: 46px;
background: rgba(255,255,255,.2);
border-radius: 10px;
display: flex; align-items: center; justify-content: center;
color: #fff; font-size: 1.3rem;
}
.kiosko-topbar .lab-nombre {
color: #fff;
font-size: clamp(1.15rem, 2.8vw, 1.55rem);
font-weight: 700;
letter-spacing: -.3px;
flex: 1;
}
.kiosko-topbar .turno-badge {
background: rgba(255,255,255,.15);
border: 1.5px solid rgba(255,255,255,.3);
color: #fff;
border-radius: 8px;
padding: 4px 12px;
font-size: .95rem;
font-weight: 600;
}
.btn-fullscreen {
background: rgba(255,255,255,.15);
border: 1.5px solid rgba(255,255,255,.3);
color: #fff;
border-radius: 8px;
padding: 6px 10px;
font-size: 1.15rem;
cursor: pointer;
transition: background .15s;
flex-shrink: 0;
line-height: 1;
}
.btn-fullscreen:hover { background: rgba(255,255,255,.28); }
/* ── Pantalla / paso ── */
.screen {
flex: 1;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 2rem 1.5rem;
transition: opacity .3s ease, transform .3s ease;
overflow: hidden;
}
.screen.hidden { opacity: 0; pointer-events: none; transform: scale(.98); position: absolute; }
.screen.visible { opacity: 1; pointer-events: all; transform: scale(1); position: relative; }
/* ── Instrucción central ── */
.kiosko-titulo {
font-size: clamp(1.55rem, 3.8vw, 2.35rem);
font-weight: 700;
color: var(--brand-dark);
text-align: center;
margin-bottom: .4rem;
}
.kiosko-subtitulo {
font-size: clamp(1rem, 2.1vw, 1.2rem);
color: #64748b;
text-align: center;
margin-bottom: 2rem;
}
/* ── Grid de prioridades ── */
.prioridad-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 1rem;
width: 100%;
max-width: 860px;
}
.btn-prioridad {
border: 2px solid transparent;
border-radius: 18px;
padding: 1.6rem 1.2rem;
cursor: pointer;
display: flex; flex-direction: column;
align-items: center; justify-content: center;
gap: .5rem;
transition: transform .12s, box-shadow .12s, filter .12s;
font-weight: 600;
box-shadow: 0 2px 12px rgba(0,0,0,.10);
-webkit-user-select: none; user-select: none;
background: #fff;
}
.btn-prioridad:active { transform: scale(.95); filter: brightness(.93); }
.btn-prioridad:hover { transform: translateY(-2px); box-shadow: 0 6px 20px rgba(0,0,0,.13); }
.btn-prioridad .icon-wrap {
width: 90px; height: 90px;
border-radius: 16px;
display: flex; align-items: center; justify-content: center;
font-size: 3rem;
color: #fff;
margin-bottom: .2rem;
}
.btn-prioridad .letra { font-size: clamp(1.15rem, 2.8vw, 1.55rem); font-weight: 800; color: #1e293b; }
.btn-prioridad .nombre { font-size: clamp(.97rem, 2.1vw, 1.15rem); color: #334155; text-align: center; }
.btn-prioridad .desc { font-size: clamp(.83rem, 1.6vw, .95rem); color: #94a3b8; text-align: center; }
/* ── Formulario de datos ── */
.form-kiosko { width: 100%; max-width: 480px; }
.badge-prio-mini {
display: inline-flex; align-items: center; gap: 8px;
padding: .45rem 1.2rem; border-radius: 99px;
font-size: 1.15rem; font-weight: 700; color: #fff;
margin-bottom: 1.5rem;
}
.form-kiosko label { color: #475569; font-size: 1.1rem; margin-bottom: .35rem; font-weight: 500; }
.form-kiosko .form-control {
background: #fff;
border: 1.5px solid #e2e8f0;
color: #1e293b;
border-radius: 14px;
padding: .85rem 1.1rem;
font-size: 1.2rem;
box-shadow: 0 1px 4px rgba(0,0,0,.05);
transition: border-color .2s, box-shadow .2s;
}
.form-kiosko .form-control:focus {
border-color: var(--brand);
box-shadow: 0 0 0 3px color-mix(in srgb, var(--brand) 20%, transparent);
outline: none;
}
.form-kiosko .hint { color: #94a3b8; font-size: .97rem; margin-top: .35rem; }
.btn-kiosko-main {
border: none; border-radius: 14px;
padding: 1rem 2rem; font-size: 1.2rem; font-weight: 700;
cursor: pointer; color: #fff;
background: var(--brand);
box-shadow: 0 4px 16px color-mix(in srgb, var(--brand) 40%, transparent);
transition: transform .12s, box-shadow .12s, filter .12s;
width: 100%; margin-top: 1rem;
}
.btn-kiosko-main:active { transform: scale(.97); filter: brightness(.9); }
.btn-kiosko-back {
background: transparent;
border: 1.5px solid #e2e8f0;
color: #94a3b8; border-radius: 12px; padding: .7rem 1.5rem;
font-size: 1.07rem; cursor: pointer; margin-top: .6rem; width: 100%;
transition: background .12s, border-color .12s;
}
.btn-kiosko-back:hover { background: var(--brand-mid); border-color: var(--brand); color: var(--brand-dark); }
/* ── Print: ticket para impresora térmica SRP-B300 ── */
@media print {
@page { margin: 1mm 2mm; size: 80mm auto; }
body { background: #fff !important; font-family: Arial, Helvetica, sans-serif !important; -webkit-print-color-adjust: exact !important; print-color-adjust: exact !important; -webkit-font-smoothing: antialiased !important; }
.kiosko-topbar, .kiosko-footer, .spinner-overlay, .toast-error,
.btn-nuevo, #screen-prio, #screen-datos { display: none !important; }
#screen-ticket { display: block !important; opacity: 1 !important; position: static !important; }
.kiosko-wrap { height: auto !important; }
.screen { padding: 0 !important; min-height: 0 !important; }
.ticket-box {
width: 72mm !important; max-width: 72mm !important;
padding: 0 !important; margin: 0 auto !important;
box-shadow: none !important; border: none !important;
border-top: none !important; border-radius: 0 !important;
text-align: center !important;
}
.ticket-label { font-size: 10pt !important; font-weight: 600 !important; letter-spacing: 0.03em !important; margin-bottom: 0 !important; padding-top: 2pt !important; }
.ticket-codigo { font-size: 22pt !important; font-weight: 700 !important; letter-spacing: 0 !important; line-height: 1 !important; padding: 0 !important; }
.ticket-prio-badge { font-size: 10pt !important; font-weight: 600 !important; padding: 0 !important; margin: 0 !important; background: transparent !important; color: #000 !important; }
.ticket-pos { margin: 2pt 0 !important; padding: 0 !important; border-radius: 0 !important; background: transparent !important; }
.ticket-pos .lbl { font-size: 9pt !important; font-weight: 600 !important; letter-spacing: 0.03em !important; }
.ticket-pos .num { font-size: 12pt !important; font-weight: 700 !important; color: #000 !important; }
.ticket-instruc { font-size: 9pt !important; font-weight: 500 !important; margin: 2pt 0 !important; line-height: 1.3 !important; padding-bottom: 2pt !important; }
.ticket-codigo, .ticket-label, .ticket-prio-badge,
.ticket-pos, .ticket-pos .lbl, .ticket-pos .num,
.ticket-instruc { color: #000 !important; }
}
/* ── Ticket ── */
.ticket-box {
background: #fff;
border-radius: 24px;
padding: 2.5rem 3rem;
text-align: center;
box-shadow: 0 4px 30px rgba(0,0,0,.10);
max-width: 460px; width: 100%;
border-top: 6px solid var(--brand);
}
.ticket-label { color: #94a3b8; font-size: 1rem; text-transform: uppercase;
letter-spacing: .08em; margin-bottom: .3rem; }
.ticket-codigo {
font-size: clamp(4rem, 18vw, 9rem);
font-weight: 900; line-height: 1;
letter-spacing: -2px;
color: var(--brand);
}
.ticket-prio-badge {
display: inline-block; padding: .3rem 1.1rem;
border-radius: 99px; font-weight: 700; color: #fff;
font-size: 1.1rem; margin-top: .8rem;
}
.ticket-pos {
margin-top: 1.2rem;
background: var(--brand-light);
border-radius: 12px;
padding: .8rem;
}
.ticket-pos .lbl { font-size: .93rem; color: #64748b; text-transform: uppercase; letter-spacing: .06em; }
.ticket-pos .num { font-size: 1.95rem; font-weight: 800; color: var(--brand-dark); }
.ticket-instruc { margin-top: 1.4rem; color: #94a3b8; font-size: 1.03rem; line-height: 1.5; }
.btn-nuevo {
margin-top: 1.8rem; border: 2px solid var(--brand-mid);
border-radius: 12px; padding: .75rem 2rem;
font-size: 1.1rem; font-weight: 600; cursor: pointer;
color: var(--brand-dark); background: #fff;
transition: background .15s, border-color .15s;
}
.btn-nuevo:hover { background: var(--brand-light); border-color: var(--brand); }
/* ── Spinner ── */
.spinner-overlay {
position: fixed; inset: 0;
background: rgba(248,250,252,.8);
display: flex; align-items: center; justify-content: center;
z-index: 999; opacity: 0; pointer-events: none;
transition: opacity .2s;
}
.spinner-overlay.active { opacity: 1; pointer-events: all; }
.spinner {
width: 52px; height: 52px;
border: 4px solid var(--brand-mid);
border-top-color: var(--brand);
border-radius: 50%;
animation: spin .75s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }
/* ── Toast de error ── */
.toast-error {
position: fixed; bottom: 2rem; left: 50%; transform: translateX(-50%);
background: #ef4444; color: #fff; padding: .75rem 1.5rem;
border-radius: 12px; font-size: 1.07rem; font-weight: 600;
box-shadow: 0 4px 20px rgba(0,0,0,.2);
opacity: 0; pointer-events: none; transition: opacity .25s;
z-index: 1000; white-space: nowrap;
}
.toast-error.show { opacity: 1; }
/* ── Footer discreto ── */
.kiosko-footer {
text-align: center;
padding: 8px;
font-size: .85rem;
color: color-mix(in srgb, var(--brand) 55%, #fff);
background: var(--brand-mid);
flex-shrink: 0;
}
/* ── Responsive ── */
@media (min-height: 800px) {
.prioridad-grid { gap: 1.3rem; }
.btn-prioridad { padding: 1.9rem 1.4rem; }
}
@media (max-width: 480px) {
.kiosko-topbar { padding: 10px 16px; }
.ticket-box { padding: 1.8rem 1.5rem; }
}
</style>
</head>
<body>
<div class="kiosko-wrap">
<!-- ══ Top bar con logo ════════════════════════════════════════ -->
<header class="kiosko-topbar">
<?php if ($_kLogo): ?>
<img src="<?= htmlspecialchars($_kLogo) ?>" alt="Logo" class="logo-img">
<?php else: ?>
<div class="logo-fallback"><i class="fas fa-flask"></i></div>
<?php endif; ?>
<div class="lab-nombre"><?= $_kNombre ?></div>
<div class="turno-badge"><i class="fas fa-ticket-alt me-1"></i>Turnero</div>
<button class="btn-fullscreen" id="btn-fs" onclick="toggleFullscreen()" title="Pantalla completa">
<i class="fas fa-expand" id="fs-icon"></i>
</button>
</header>
<!-- ══ PASO 1: Selección de prioridad ══════════════════════════ -->
<div id="screen-prio" class="screen visible">
<div class="kiosko-titulo">Seleccione su tipo de atención</div>
<div class="kiosko-subtitulo">Toque la categoría que le corresponde para obtener su turno</div>
<div class="prioridad-grid">
<?php foreach ($prioridades as $prio): ?>
<button
class="btn-prioridad"
style="border-color:<?= htmlspecialchars($prio['color']) ?>22"
data-codigo="<?= htmlspecialchars($prio['codigo']) ?>"
data-nombre="<?= htmlspecialchars($prio['nombre']) ?>"
data-color="<?= htmlspecialchars($prio['color']) ?>"
onclick="seleccionarPrioridad(this)"
>
<div class="icon-wrap" style="background:<?= htmlspecialchars($prio['color']) ?>">
<i class="<?= htmlspecialchars($prio['icono']) ?>"></i>
</div>
<span class="letra" style="color:<?= htmlspecialchars($prio['color']) ?>"><?= htmlspecialchars($prio['codigo']) ?></span>
<span class="nombre"><?= htmlspecialchars($prio['nombre']) ?></span>
<?php if (!empty($prio['descripcion'])): ?>
<span class="desc"><?= htmlspecialchars($prio['descripcion']) ?></span>
<?php endif; ?>
</button>
<?php endforeach; ?>
</div>
</div>
<!-- ══ PASO 2: Datos del paciente ═══════════════════════════════ -->
<div id="screen-datos" class="screen hidden">
<div id="badge-prio" class="badge-prio-mini"></div>
<div class="kiosko-titulo">Ingrese su número de cédula</div>
<div class="kiosko-subtitulo">Le ayudará a identificar su turno correctamente</div>
<div class="form-kiosko">
<div class="mb-3">
<label for="inp-cedula">Número de cédula <span style="color:#ef4444">*</span></label>
<input type="text" id="inp-cedula" class="form-control"
placeholder="Ej: 1234567890" maxlength="20"
autocomplete="off" inputmode="numeric">
</div>
<div class="mb-3">
<label for="inp-cel">WhatsApp
<span style="color:#94a3b8;font-size:.82rem;font-weight:400"> (opcional)</span>
</label>
<input type="tel" id="inp-cel" class="form-control"
placeholder="Ej: 3001234567" maxlength="20"
autocomplete="off" inputmode="numeric">
<div class="hint"><i class="fas fa-bell me-1"></i>Para recibir notificaciones de su turno</div>
</div>
<button class="btn-kiosko-main" onclick="confirmarTurno()">
<i class="fas fa-ticket-alt me-2"></i>Obtener mi turno
</button>
<button class="btn-kiosko-back" onclick="volverPrioridades()">
<i class="fas fa-arrow-left me-1"></i>Cambiar tipo de atención
</button>
</div>
</div>
<!-- ══ PASO 3: Ticket asignado ══════════════════════════════════ -->
<div id="screen-ticket" class="screen hidden">
<div class="ticket-box">
<div class="ticket-label">Su número de turno es</div>
<div id="tick-codigo" class="ticket-codigo">—</div>
<div id="tick-prio-badge"></div>
<div class="ticket-pos">
<div class="lbl">Posición en cola</div>
<div class="num" id="tick-posicion">—</div>
</div>
<div class="ticket-instruc">
Por favor espere a ser llamado.<br>
Recuerde traer su documento de identidad y la orden médica.
</div>
</div>
<button class="btn-nuevo" onclick="seleccionarOtraPrioridad()">
<i class="fas fa-plus me-1"></i>Nuevo turno
</button>
</div>
<!-- ══ Footer ═════════════════════════════════════════════════ -->
<footer class="kiosko-footer"><?= $_kNombre ?> · Sistema de Turnos</footer>
</div><!-- /kiosko-wrap -->
<!-- ══ Spinner ════════════════════════════════════════════════ -->
<div class="spinner-overlay" id="spinner"><div class="spinner"></div></div>
<!-- ══ Toast de error ════════════════════════════════════════ -->
<div class="toast-error" id="toast-error"></div>
<script>
let prioCodigo = '';
let prioNombre = '';
let prioColor = '';
const API_URL = '<?= BASE_URL ?>modules/turnero/api/create_turno.php';
function mostrar(id) {
document.querySelectorAll('.screen').forEach(s => {
s.classList.toggle('visible', s.id === id);
s.classList.toggle('hidden', s.id !== id);
});
}
function seleccionarPrioridad(btn) {
prioCodigo = btn.dataset.codigo;
prioNombre = btn.dataset.nombre;
prioColor = btn.dataset.color;
const badge = document.getElementById('badge-prio');
badge.textContent = prioCodigo + ' — ' + prioNombre;
badge.style.background = prioColor;
mostrar('screen-datos');
const inpCedula = document.getElementById('inp-cedula');
inpCedula.focus();
inpCedula.value = '';
// Detector de scanner: auto-submit solo si los dígitos llegan rápido (< 80ms entre cada uno)
let _timerAutoSubmit = null;
let _lastKeyAt = 0;
inpCedula.addEventListener('input', () => {
clearTimeout(_timerAutoSubmit);
const now = Date.now();
const gap = now - _lastKeyAt;
_lastKeyAt = now;
const val = inpCedula.value.trim();
// Scanner envía dígitos en ráfaga; teclado humano siempre > 80ms entre teclas
if (/^\d{5,15}$/.test(val) && gap < 80) {
_timerAutoSubmit = setTimeout(() => confirmarTurno(), 300);
}
});
}
function volverPrioridades() { mostrar('screen-prio'); }
async function confirmarTurno() {
const cedula = document.getElementById('inp-cedula').value.trim();
const cel = document.getElementById('inp-cel').value.trim();
if (!cedula) { mostrarError('Por favor ingrese su número de cédula.'); return; }
if (!/^\d{5,15}$/.test(cedula)) { mostrarError('La cédula debe tener solo dígitos (mínimo 5).'); return; }
if (cel && !/^\+?\d{7,15}$/.test(cel.replace(/\s/g,''))) { mostrarError('Ingrese un número de WhatsApp válido.'); return; }
setSpinner(true);
try {
const res = await fetch(API_URL, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ prioridad_codigo: prioCodigo, paciente_nombre: cedula, paciente_cel: cel || null }),
});
const json = await res.json();
if (!json.ok) throw new Error(json.error ?? 'Error al crear turno');
mostrarTicket(json.turno ?? json.data?.turno);
} catch (err) {
mostrarError(err.message);
setSpinner(false);
}
}
function mostrarTicket(t) {
setSpinner(false);
document.getElementById('tick-codigo').textContent = t.codigo;
document.getElementById('tick-codigo').style.color = prioColor;
document.getElementById('tick-posicion').textContent = '#' + t.posicion_cola;
document.getElementById('tick-prio-badge').innerHTML =
`<span class="ticket-prio-badge" style="background:${prioColor}">${prioCodigo} — ${prioNombre}</span>`;
mostrar('screen-ticket');
// Imprimir automáticamente
setTimeout(() => window.print(), 300);
clearTimeout(window._timer);
window._timer = setTimeout(seleccionarOtraPrioridad, 5000);
}
function seleccionarOtraPrioridad() {
clearTimeout(window._timer);
document.getElementById('inp-cedula').value = '';
document.getElementById('inp-cel').value = '';
prioCodigo = prioNombre = prioColor = '';
mostrar('screen-prio');
}
function setSpinner(on) { document.getElementById('spinner').classList.toggle('active', on); }
function toggleFullscreen() {
if (!document.fullscreenElement) {
document.documentElement.requestFullscreen().catch(() => {});
} else {
document.exitFullscreen().catch(() => {});
}
}
document.addEventListener('fullscreenchange', () => {
const icon = document.getElementById('fs-icon');
if (document.fullscreenElement) {
icon.classList.replace('fa-expand', 'fa-compress');
} else {
icon.classList.replace('fa-compress', 'fa-expand');
}
});
function mostrarError(msg) {
const el = document.getElementById('toast-error');
el.textContent = msg;
el.classList.add('show');
setTimeout(() => el.classList.remove('show'), 4000);
}
</script>
</body>
</html>