Update lab_formularios.php

This commit is contained in:
Lizandro Guarnizo
2026-04-07 15:02:13 -05:00
parent 61728b6ee2
commit 58f420e7ce
+70 -50
View File
@@ -34,6 +34,12 @@ $puedeEscribir = $esAdmin && hasModuleWrite('lab_formularios');
.badge-completado { background:#0d6efd; }
.badge-firmado { background:#198754; }
.badge-expirado { background:#dc3545; }
/* ── Animación toast ────────────────────────────── */
@keyframes fadeInUp {
from { opacity:0; transform:translateY(12px); }
to { opacity:1; transform:translateY(0); }
}
</style>
</head>
<body>
@@ -118,53 +124,58 @@ $puedeEscribir = $esAdmin && hasModuleWrite('lab_formularios');
<!-- ── ENVÍOS ─────────────────────────────────────────────── -->
<div id="panel-envios" style="display:none">
<!-- Filtros fila 1 -->
<div class="row g-2 mb-2 align-items-end">
<div class="col-sm-2">
<label class="form-label small mb-1">Desde</label>
<input type="date" id="env-f-desde" class="form-control form-control-sm" oninput="envios.filtrar()">
</div>
<div class="col-sm-2">
<label class="form-label small mb-1">Hasta</label>
<input type="date" id="env-f-hasta" class="form-control form-control-sm" oninput="envios.filtrar()">
</div>
<div class="col-sm-4">
<label class="form-label small mb-1">Formulario</label>
<select id="env-f-formulario" class="form-select form-select-sm" onchange="envios.filtrar()">
<option value="">Todos los formularios</option>
</select>
</div>
<div class="col-sm-2">
<label class="form-label small mb-1">Estado</label>
<select id="env-f-estado" class="form-select form-select-sm" onchange="envios.filtrar()">
<option value="">Todos los estados</option>
<option value="pendiente">🕐 Pendiente</option>
<option value="completado">✅ Completado</option>
<option value="firmado">✍️ Firmado</option>
<option value="expirado">⏰ Expirado</option>
</select>
</div>
</div>
<!-- Filtros fila 2 -->
<div class="row g-2 mb-3 align-items-end">
<div class="col-sm-4">
<label class="form-label small mb-1">Paciente</label>
<input type="text" id="env-f-paciente" class="form-control form-control-sm"
placeholder="Buscar paciente…" oninput="envios.filtrar()">
</div>
<div class="col-sm-auto ms-auto">
<button class="btn btn-success btn-sm" onclick="envios.exportarExcel()">
<i class="fas fa-file-excel me-1"></i>Exportar Excel
</button>
</div>
<div class="col-sm-auto">
<button class="btn btn-outline-secondary btn-sm" onclick="envios.limpiarFiltros()">
<i class="fas fa-times me-1"></i>Limpiar
</button>
<!-- Filtros en una sola fila compacta -->
<div class="card border-0 bg-light mb-3 px-3 py-2">
<div class="row g-2 align-items-end">
<div class="col-6 col-sm-2">
<label class="form-label form-label-sm mb-1 text-muted">Desde</label>
<input type="date" id="env-f-desde" class="form-control form-control-sm" oninput="envios.filtrar()">
</div>
<div class="col-6 col-sm-2">
<label class="form-label form-label-sm mb-1 text-muted">Hasta</label>
<input type="date" id="env-f-hasta" class="form-control form-control-sm" oninput="envios.filtrar()">
</div>
<div class="col-12 col-sm-3">
<label class="form-label form-label-sm mb-1 text-muted">Formulario</label>
<select id="env-f-formulario" class="form-select form-select-sm" onchange="envios.filtrar()">
<option value="">Todos los formularios</option>
</select>
</div>
<div class="col-6 col-sm-2">
<label class="form-label form-label-sm mb-1 text-muted">Estado</label>
<select id="env-f-estado" class="form-select form-select-sm" onchange="envios.filtrar()">
<option value="">Todos</option>
<option value="pendiente">🕐 Pendiente</option>
<option value="completado">✅ Completado</option>
<option value="firmado">✍️ Firmado</option>
<option value="expirado">⏰ Expirado</option>
</select>
</div>
<div class="col-6 col-sm-3">
<label class="form-label form-label-sm mb-1 text-muted">Paciente</label>
<input type="text" id="env-f-paciente" class="form-control form-control-sm"
placeholder="Buscar…" oninput="envios.filtrar()">
</div>
<div class="col-12 col-sm-auto ms-sm-auto d-flex gap-2">
<button class="btn btn-success btn-sm" onclick="envios.exportarExcel()" title="Exportar a Excel">
<i class="fas fa-file-excel me-1"></i><span class="d-none d-md-inline">Excel</span>
</button>
<button class="btn btn-outline-secondary btn-sm" onclick="envios.limpiarFiltros()" title="Limpiar filtros">
<i class="fas fa-times"></i>
</button>
</div>
</div>
</div>
<div class="table-responsive">
<!-- Spinner de carga -->
<div id="env-spinner" class="text-center py-5" style="display:none">
<div class="spinner-border text-primary" role="status" style="width:2rem;height:2rem">
<span class="visually-hidden">Cargando…</span>
</div>
<p class="text-muted small mt-2 mb-0">Cargando envíos…</p>
</div>
<div class="table-responsive" id="env-tabla-wrap">
<table class="table table-hover align-middle small" id="tabla-envios">
<thead class="table-light">
<tr>
@@ -504,12 +515,21 @@ const envios = {
_pagina: 1,
async cargar() {
// Mostrar spinner, ocultar tabla
const spinner = $('env-spinner');
const tabla = $('env-tabla-wrap');
if (spinner) spinner.style.display = '';
if (tabla) tabla.style.display = 'none';
const r = await fetch('api/lab/get_formularios.php?envios=1');
const d = await r.json();
this._data = d.data || [];
this._pagina = 1;
this._poblarSelectFormulario();
this._aplicarFiltros();
if (spinner) spinner.style.display = 'none';
if (tabla) tabla.style.display = '';
},
filtrar() {
@@ -644,7 +664,7 @@ const envios = {
a.click();
document.body.removeChild(a);
URL.revokeObjectURL(url);
showToast('✅ Exportando ' + rows.length + ' envíos…');
showToast('✅ Excel descargado — ' + rows.length + ' registro(s)', 'success', 4000);
},
_render() {
@@ -1042,13 +1062,13 @@ function renderCampoPreview(c, valores) {
// ══════════════════════════════════════════════════════════════════════
// HELPERS UI
// ══════════════════════════════════════════════════════════════════════
function showToast(msg) {
function showToast(msg, tipo = 'success', ms = 3000) {
const t = document.createElement('div');
t.className = 'alert alert-success position-fixed bottom-0 end-0 m-3 shadow py-2 px-3';
t.style.zIndex = '9999';
t.textContent = msg;
t.className = `alert alert-${tipo} d-flex align-items-center gap-2 position-fixed bottom-0 end-0 m-3 shadow-sm py-2 px-3`;
t.style.cssText = 'z-index:9999;min-width:220px;max-width:360px;font-size:.875rem;border-radius:8px;animation:fadeInUp .2s ease';
t.innerHTML = `<span style="flex:1">${esc(msg)}</span><button type="button" class="btn-close btn-close-sm ms-2" style="font-size:.65rem" onclick="this.closest('.alert').remove()"></button>`;
document.body.appendChild(t);
setTimeout(() => t.remove(), 3000);
setTimeout(() => t && t.remove(), ms);
}
document.addEventListener('keydown', e => {