feat(turnero): buscador y paginación en tab de examenes
Filtrado en tiempo real + paginación client-side (15 por página). Categorías vacías se ocultan automáticamente al buscar. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 4.6
parent
18d50a3a16
commit
333e856f38
@@ -466,7 +466,13 @@ $tab = $_GET['tab'] ?? 'lugares';
|
||||
TAB 2 — EXÁMENES Y CONSENTIMIENTOS
|
||||
════════════════════════════════════════ -->
|
||||
<?php elseif ($tab === 'examenes'): ?>
|
||||
<p class="section-title">Tipos de examen y sus formularios de consentimiento</p>
|
||||
<div class="d-flex align-items-center gap-3 mb-3">
|
||||
<p class="section-title mb-0">Tipos de examen y sus formularios de consentimiento</p>
|
||||
<div class="ms-auto" style="min-width:220px">
|
||||
<input type="search" id="exam-buscar" class="form-control form-control-sm"
|
||||
placeholder="Buscar examen…" autocomplete="off">
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
// Agrupar por categoría
|
||||
$categorias = [];
|
||||
@@ -475,6 +481,7 @@ $tab = $_GET['tab'] ?? 'lugares';
|
||||
$categorias[$cat][] = $et;
|
||||
}
|
||||
?>
|
||||
<div id="exam-lista">
|
||||
<?php foreach ($categorias as $cat => $items): ?>
|
||||
<div class="mb-3">
|
||||
<div class="fw-semibold text-uppercase small text-secondary mb-1" style="font-size:.7rem;letter-spacing:.07em">
|
||||
@@ -513,6 +520,8 @@ $tab = $_GET['tab'] ?? 'lugares';
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div><!-- #exam-lista -->
|
||||
<div id="exam-pager"></div>
|
||||
<?php if (empty($examTipos)): ?>
|
||||
<p class="text-muted text-center py-3">No hay tipos de examen configurados</p>
|
||||
<?php endif; ?>
|
||||
@@ -1203,6 +1212,58 @@ async function eliminarExamen(id, nombre) {
|
||||
} catch (e) { toast('Error de conexión', 'error'); }
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────
|
||||
// BUSCADOR + PAGINADOR — Tab examenes
|
||||
// ─────────────────────────────────────────────────────────────
|
||||
(function () {
|
||||
const PAGE = 15;
|
||||
let page = 1, q = '';
|
||||
|
||||
function update() {
|
||||
const lista = document.getElementById('exam-lista');
|
||||
if (!lista) return;
|
||||
const rows = Array.from(lista.querySelectorAll('.item-row'));
|
||||
const term = q.toLowerCase();
|
||||
const matched = rows.filter(r => r.textContent.toLowerCase().includes(term));
|
||||
|
||||
rows.forEach(r => r.hidden = true);
|
||||
const start = (page - 1) * PAGE;
|
||||
matched.slice(start, start + PAGE).forEach(r => r.hidden = false);
|
||||
|
||||
// Ocultar categorías vacías
|
||||
lista.querySelectorAll('.mb-3').forEach(cat => {
|
||||
cat.hidden = Array.from(cat.querySelectorAll('.item-row')).every(r => r.hidden);
|
||||
});
|
||||
|
||||
renderPager(matched.length);
|
||||
}
|
||||
|
||||
function renderPager(total) {
|
||||
const el = document.getElementById('exam-pager');
|
||||
if (!el) return;
|
||||
const pages = Math.ceil(total / PAGE);
|
||||
if (pages <= 1) { el.innerHTML = total ? `<small class="text-muted">${total} resultado${total!==1?'s':''}</small>` : ''; return; }
|
||||
const prev = `<button class="btn btn-sm btn-outline-secondary" ${page===1?'disabled':''} onclick="examPag(${page-1})"><i class="fas fa-chevron-left"></i></button>`;
|
||||
const next = `<button class="btn btn-sm btn-outline-secondary" ${page===pages?'disabled':''} onclick="examPag(${page+1})"><i class="fas fa-chevron-right"></i></button>`;
|
||||
el.innerHTML = `<div class="d-flex align-items-center gap-2 mt-2">
|
||||
<small class="text-muted">${total} resultados</small>
|
||||
<div class="ms-auto d-flex align-items-center gap-1">
|
||||
${prev}
|
||||
<span class="small px-1">Página ${page} de ${pages}</span>
|
||||
${next}
|
||||
</div>
|
||||
</div>`;
|
||||
}
|
||||
|
||||
window.examPag = function (p) { page = p; update(); };
|
||||
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
const inp = document.getElementById('exam-buscar');
|
||||
if (inp) inp.addEventListener('input', () => { q = inp.value; page = 1; update(); });
|
||||
update();
|
||||
});
|
||||
})();
|
||||
|
||||
// ─────────────────────────────────────────────────────────────
|
||||
// TAB 3: PRIORIDADES
|
||||
// ─────────────────────────────────────────────────────────────
|
||||
|
||||
Reference in New Issue
Block a user