feat: filtros por fecha/paciente y paginación en tab Envíos de formularios
This commit is contained in:
+117
-8
@@ -118,6 +118,28 @@ $puedeEscribir = $esAdmin && hasModuleWrite('lab_formularios');
|
|||||||
|
|
||||||
<!-- ── ENVÍOS ─────────────────────────────────────────────── -->
|
<!-- ── ENVÍOS ─────────────────────────────────────────────── -->
|
||||||
<div id="panel-envios" style="display:none">
|
<div id="panel-envios" style="display:none">
|
||||||
|
<!-- Filtros -->
|
||||||
|
<div class="row g-2 mb-3 align-items-end">
|
||||||
|
<div class="col-sm-3">
|
||||||
|
<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-3">
|
||||||
|
<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">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-2">
|
||||||
|
<button class="btn btn-outline-secondary btn-sm w-100" onclick="envios.limpiarFiltros()">
|
||||||
|
<i class="fas fa-times me-1"></i>Limpiar
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="table-responsive">
|
<div class="table-responsive">
|
||||||
<table class="table table-hover align-middle small" id="tabla-envios">
|
<table class="table table-hover align-middle small" id="tabla-envios">
|
||||||
<thead class="table-light">
|
<thead class="table-light">
|
||||||
@@ -135,6 +157,14 @@ $puedeEscribir = $esAdmin && hasModuleWrite('lab_formularios');
|
|||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- Paginación -->
|
||||||
|
<div class="d-flex align-items-center justify-content-between mt-3 flex-wrap gap-2">
|
||||||
|
<small class="text-muted" id="env-pag-info"></small>
|
||||||
|
<nav>
|
||||||
|
<ul class="pagination pagination-sm mb-0" id="env-paginacion"></ul>
|
||||||
|
</nav>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
@@ -443,26 +473,71 @@ const ESTADO_ENV = {
|
|||||||
firmado: { cls:'badge-firmado', icon:'✍️' },
|
firmado: { cls:'badge-firmado', icon:'✍️' },
|
||||||
expirado: { cls:'badge-expirado', icon:'⏰' },
|
expirado: { cls:'badge-expirado', icon:'⏰' },
|
||||||
};
|
};
|
||||||
|
const POR_PAGINA = 15;
|
||||||
const envios = {
|
const envios = {
|
||||||
_data: [],
|
_data: [],
|
||||||
|
_filtrado: [],
|
||||||
|
_pagina: 1,
|
||||||
|
|
||||||
async cargar() {
|
async cargar() {
|
||||||
const r = await fetch('api/lab/get_formularios.php?envios=1');
|
const r = await fetch('api/lab/get_formularios.php?envios=1');
|
||||||
const d = await r.json();
|
const d = await r.json();
|
||||||
this._data = d.data || [];
|
this._data = d.data || [];
|
||||||
this._render();
|
this._pagina = 1;
|
||||||
|
this._aplicarFiltros();
|
||||||
},
|
},
|
||||||
_render() {
|
|
||||||
const tb = $('tbody-envios');
|
filtrar() {
|
||||||
|
this._pagina = 1;
|
||||||
|
this._aplicarFiltros();
|
||||||
|
},
|
||||||
|
|
||||||
|
limpiarFiltros() {
|
||||||
|
$('env-f-desde').value = '';
|
||||||
|
$('env-f-hasta').value = '';
|
||||||
|
$('env-f-paciente').value = '';
|
||||||
|
this.filtrar();
|
||||||
|
},
|
||||||
|
|
||||||
|
_aplicarFiltros() {
|
||||||
|
const desde = $('env-f-desde').value;
|
||||||
|
const hasta = $('env-f-hasta').value;
|
||||||
|
const paciente = $('env-f-paciente').value.trim().toLowerCase();
|
||||||
|
|
||||||
|
this._filtrado = this._data.filter(e => {
|
||||||
|
const fecha = (e.created_at || '').slice(0, 10);
|
||||||
|
if (desde && fecha < desde) return false;
|
||||||
|
if (hasta && fecha > hasta) return false;
|
||||||
|
if (paciente && !(e.paciente_nombre || '').toLowerCase().includes(paciente)) return false;
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
|
// badge de pendientes sobre el total sin filtrar
|
||||||
const badgePend = $('badge-envios');
|
const badgePend = $('badge-envios');
|
||||||
const pend = this._data.filter(e => e.estado==='pendiente').length;
|
const pend = this._data.filter(e => e.estado === 'pendiente').length;
|
||||||
if (pend) { badgePend.textContent = pend; badgePend.style.display = ''; }
|
if (pend) { badgePend.textContent = pend; badgePend.style.display = ''; }
|
||||||
else badgePend.style.display = 'none';
|
else badgePend.style.display = 'none';
|
||||||
|
|
||||||
if (!this._data.length) {
|
this._render();
|
||||||
tb.innerHTML = '<tr><td colspan="6" class="text-center text-muted py-4">Sin envíos aún</td></tr>';
|
},
|
||||||
|
|
||||||
|
_render() {
|
||||||
|
const tb = $('tbody-envios');
|
||||||
|
const total = this._filtrado.length;
|
||||||
|
|
||||||
|
if (!total) {
|
||||||
|
tb.innerHTML = '<tr><td colspan="6" class="text-center text-muted py-4">Sin envíos para los filtros seleccionados</td></tr>';
|
||||||
|
$('env-pag-info').textContent = '';
|
||||||
|
$('env-paginacion').innerHTML = '';
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
tb.innerHTML = this._data.map(e => {
|
|
||||||
|
const totalPag = Math.ceil(total / POR_PAGINA);
|
||||||
|
if (this._pagina > totalPag) this._pagina = totalPag;
|
||||||
|
const inicio = (this._pagina - 1) * POR_PAGINA;
|
||||||
|
const pagina = this._filtrado.slice(inicio, inicio + POR_PAGINA);
|
||||||
|
|
||||||
|
tb.innerHTML = pagina.map(e => {
|
||||||
const info = ESTADO_ENV[e.estado] || {};
|
const info = ESTADO_ENV[e.estado] || {};
|
||||||
return `<tr>
|
return `<tr>
|
||||||
<td><span class="fw-semibold">${esc(e.form_nombre)}</span>
|
<td><span class="fw-semibold">${esc(e.form_nombre)}</span>
|
||||||
@@ -487,7 +562,41 @@ const envios = {
|
|||||||
</td>
|
</td>
|
||||||
</tr>`;
|
</tr>`;
|
||||||
}).join('');
|
}).join('');
|
||||||
|
|
||||||
|
// Info
|
||||||
|
$('env-pag-info').textContent =
|
||||||
|
`Mostrando ${inicio + 1}–${Math.min(inicio + POR_PAGINA, total)} de ${total} envíos`;
|
||||||
|
|
||||||
|
// Paginación
|
||||||
|
const ul = $('env-paginacion');
|
||||||
|
ul.innerHTML = '';
|
||||||
|
const agregar = (label, pag, disabled, active) => {
|
||||||
|
const li = document.createElement('li');
|
||||||
|
li.className = `page-item${disabled?' disabled':''}${active?' active':''}`;
|
||||||
|
li.innerHTML = `<a class="page-link" href="#" onclick="event.preventDefault();${!disabled?`envios.irAPagina(${pag})`:''}">${label}</a>`;
|
||||||
|
ul.appendChild(li);
|
||||||
|
};
|
||||||
|
agregar('«', 1, this._pagina === 1, false);
|
||||||
|
agregar('‹', this._pagina-1, this._pagina === 1, false);
|
||||||
|
|
||||||
|
// páginas con ventana deslizante ±2
|
||||||
|
const rango = 2;
|
||||||
|
const pMin = Math.max(1, this._pagina - rango);
|
||||||
|
const pMax = Math.min(totalPag, this._pagina + rango);
|
||||||
|
if (pMin > 1) { agregar('1', 1, false, false); if (pMin > 2) agregar('…', null, true, false); }
|
||||||
|
for (let p = pMin; p <= pMax; p++) agregar(p, p, false, p === this._pagina);
|
||||||
|
if (pMax < totalPag) { if (pMax < totalPag-1) agregar('…', null, true, false); agregar(totalPag, totalPag, false, false); }
|
||||||
|
|
||||||
|
agregar('›', this._pagina+1, this._pagina === totalPag, false);
|
||||||
|
agregar('»', totalPag, this._pagina === totalPag, false);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
irAPagina(p) {
|
||||||
|
this._pagina = p;
|
||||||
|
this._render();
|
||||||
|
$('panel-envios').scrollIntoView({ behavior:'smooth', block:'start' });
|
||||||
|
},
|
||||||
|
|
||||||
copiarTokenLink(token) {
|
copiarTokenLink(token) {
|
||||||
const url = window.location.origin + window.location.pathname.replace(/\/[^/]+$/, '')
|
const url = window.location.origin + window.location.pathname.replace(/\/[^/]+$/, '')
|
||||||
+ `/form_cliente.php?t=${token}`;
|
+ `/form_cliente.php?t=${token}`;
|
||||||
|
|||||||
Reference in New Issue
Block a user