feat(turnero): UI/UX tablet improvements for recepcion and lugar views
- recepcion: wider queue column (370px), breakpoint at 680px so portrait tablets get 2-column layout; prominent "Llamar siguiente" button in queue column header; searchable exam filter; touch-friendly action bar with large primary/secondary button rows; larger touch targets for cards, checkboxes and consent items - lugar: wider queue column (340px), breakpoint at 680px; larger action buttons (.8rem padding, 1rem font) and secondary buttons; consistent mobile breakpoint Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 4.6
parent
b55c7c1a19
commit
5af985581c
@@ -45,11 +45,11 @@ $adminNombre = $_SESSION['admin_user']['full_name'] ?? $_SESSION['admin_user']['
|
||||
/* ── Layout ─────────────────────────────────────────────── */
|
||||
.lugar-layout {
|
||||
display: grid;
|
||||
grid-template-columns: 290px 1fr;
|
||||
grid-template-columns: 340px 1fr;
|
||||
height: calc(100vh - 52px);
|
||||
overflow: hidden;
|
||||
}
|
||||
@media (max-width: 860px) {
|
||||
@media (max-width: 680px) {
|
||||
.lugar-layout { grid-template-columns: 1fr; position: relative; overflow: hidden; }
|
||||
.lugar-cola { transition: transform .22s ease; }
|
||||
.lugar-cola.mobile-oculta { transform: translateX(-100%); position: absolute; inset: 0; pointer-events: none; }
|
||||
@@ -173,7 +173,7 @@ $adminNombre = $_SESSION['admin_user']['full_name'] ?? $_SESSION['admin_user']['
|
||||
border-bottom: 1px solid #e2e8f0; flex-shrink: 0;
|
||||
position: sticky; top: 0; z-index: 20;
|
||||
}
|
||||
@media (max-width: 860px) {
|
||||
@media (max-width: 680px) {
|
||||
.ficha-mobile-topbar { display: flex; }
|
||||
}
|
||||
.ficha-mobile-topbar .btn-back {
|
||||
@@ -273,8 +273,8 @@ $adminNombre = $_SESSION['admin_user']['full_name'] ?? $_SESSION['admin_user']['
|
||||
.accion-consent-warn i { color: #f59e0b; flex-shrink: 0; }
|
||||
.accion-primary-row { margin-bottom: .45rem; }
|
||||
.btn-accion-primary {
|
||||
width: 100%; padding: .7rem; border: none; border-radius: 11px;
|
||||
font-size: .97rem; font-weight: 700; cursor: pointer;
|
||||
width: 100%; padding: .8rem; border: none; border-radius: 11px;
|
||||
font-size: 1rem; font-weight: 700; cursor: pointer;
|
||||
display: flex; align-items: center; justify-content: center; gap: .45rem;
|
||||
transition: background .15s, transform .1s, opacity .15s;
|
||||
}
|
||||
@@ -289,8 +289,8 @@ $adminNombre = $_SESSION['admin_user']['full_name'] ?? $_SESSION['admin_user']['
|
||||
}
|
||||
.btn-accion-sec {
|
||||
flex: 1; min-width: 80px;
|
||||
padding: .45rem .5rem; border-radius: 9px;
|
||||
font-size: .8rem; font-weight: 600; cursor: pointer;
|
||||
padding: .55rem .5rem; border-radius: 9px;
|
||||
font-size: .82rem; font-weight: 600; cursor: pointer;
|
||||
display: flex; align-items: center; justify-content: center; gap: .35rem;
|
||||
border: 1.5px solid; background: transparent; transition: background .12s;
|
||||
}
|
||||
@@ -921,11 +921,15 @@ async function cargarFichaSolicitud(turnoId) {
|
||||
const pac = json.paciente;
|
||||
_solicitudActiva = sol || null;
|
||||
|
||||
// Número de orden
|
||||
// Número de orden (F-... azul, D-... verde)
|
||||
const ordenEl = document.getElementById('ficha-orden');
|
||||
const ordenValEl = document.getElementById('ficha-orden-val');
|
||||
if (sol && sol.numero_orden) {
|
||||
ordenValEl.textContent = sol.numero_orden;
|
||||
const isDom = sol.numero_orden.startsWith('D-');
|
||||
ordenEl.style.background = isDom ? '#f0fdf4' : '#eff6ff';
|
||||
ordenEl.style.color = isDom ? '#15803d' : '#1d4ed8';
|
||||
ordenEl.style.borderColor = isDom ? '#86efac' : '#bfdbfe';
|
||||
ordenEl.classList.remove('d-none');
|
||||
} else {
|
||||
ordenEl.classList.add('d-none');
|
||||
@@ -1271,7 +1275,7 @@ function resetFicha() {
|
||||
}
|
||||
|
||||
// ── Mobile ────────────────────────────────────────────────────
|
||||
function esMobile() { return window.innerWidth <= 860; }
|
||||
function esMobile() { return window.innerWidth <= 680; }
|
||||
|
||||
function mostrarFichaMobile() {
|
||||
if (!esMobile()) return;
|
||||
|
||||
@@ -83,11 +83,11 @@ $adminNombre = $_SESSION['admin_user']['full_name'] ?? $_SESSION['admin_user']['
|
||||
/* ── Layout de dos columnas ── */
|
||||
.rec-layout {
|
||||
display: grid;
|
||||
grid-template-columns: 320px 1fr;
|
||||
grid-template-columns: 370px 1fr;
|
||||
height: calc(100vh - 56px);
|
||||
overflow: hidden;
|
||||
}
|
||||
@media (max-width: 900px) {
|
||||
@media (max-width: 680px) {
|
||||
.rec-layout { grid-template-columns: 1fr; position: relative; overflow: hidden; }
|
||||
.rec-cola { transition: transform .2s ease; }
|
||||
.rec-cola.mobile-oculta { transform: translateX(-100%); position: absolute; inset: 0; pointer-events: none; }
|
||||
@@ -95,6 +95,8 @@ $adminNombre = $_SESSION['admin_user']['full_name'] ?? $_SESSION['admin_user']['
|
||||
.rec-ficha.mobile-visible { transform: translateX(0); }
|
||||
.btn-volver-cola { display: inline-flex !important; align-items: center; gap: 6px; }
|
||||
}
|
||||
/* En pantalla 2 columnas el botón de topbar queda oculto (hay uno en la cola) */
|
||||
@media (min-width: 681px) { #btn-llamar { display: none !important; } }
|
||||
|
||||
/* ── Columna cola ── */
|
||||
.rec-cola {
|
||||
@@ -266,6 +268,51 @@ $adminNombre = $_SESSION['admin_user']['full_name'] ?? $_SESSION['admin_user']['
|
||||
.timeline-codigo { font-size: .82rem; font-weight: 700; }
|
||||
.timeline-lugar { font-size: .73rem; color: #64748b; }
|
||||
.timeline-eb { font-size: .62rem; padding: 1px 7px; border-radius: 99px; font-weight: 700; display: inline-block; margin-top: 2px; }
|
||||
|
||||
/* ── Botón "Llamar siguiente" en columna de cola ── */
|
||||
.btn-llamar-cola {
|
||||
width: 100%; padding: .65rem 1rem; border: none; border-radius: 10px;
|
||||
background: #2563eb; color: #fff; font-weight: 700; font-size: .92rem;
|
||||
cursor: pointer; display: flex; align-items: center; justify-content: center; gap: .5rem;
|
||||
transition: background .15s, transform .1s; margin-top: .5rem;
|
||||
}
|
||||
.btn-llamar-cola:hover { background: #1d4ed8; }
|
||||
.btn-llamar-cola:active { transform: scale(.98); }
|
||||
.btn-llamar-cola:disabled { background: #94a3b8; cursor: not-allowed; }
|
||||
|
||||
/* ── Barra de acciones: botones primarios/secundarios touch-friendly ── */
|
||||
.accion-primary-row { margin-bottom: .5rem; }
|
||||
.btn-accion-primary {
|
||||
width: 100%; padding: .8rem 1rem; border: none; border-radius: 11px;
|
||||
font-size: .97rem; font-weight: 700; cursor: pointer;
|
||||
display: flex; align-items: center; justify-content: center; gap: .45rem;
|
||||
transition: background .15s, transform .1s, opacity .15s;
|
||||
}
|
||||
.btn-accion-primary:active { transform: scale(.98); }
|
||||
.btn-accion-primary:disabled { opacity: .55; cursor: not-allowed; }
|
||||
.btn-accion-primary.verde { background: #16a34a; color: #fff; }
|
||||
.btn-accion-primary.verde:hover { background: #15803d; }
|
||||
.btn-accion-primary.azul { background: #2563eb; color: #fff; }
|
||||
.btn-accion-primary.azul:hover { background: #1d4ed8; }
|
||||
.accion-secondary-row { display: flex; gap: .4rem; flex-wrap: wrap; }
|
||||
.btn-accion-sec {
|
||||
flex: 1; min-width: 80px; padding: .55rem .5rem; border-radius: 9px;
|
||||
font-size: .8rem; font-weight: 600; cursor: pointer;
|
||||
display: flex; align-items: center; justify-content: center; gap: .35rem;
|
||||
border: 1.5px solid; background: transparent; transition: background .12s;
|
||||
}
|
||||
.btn-accion-sec.warning { color: #92400e; border-color: #fcd34d; }
|
||||
.btn-accion-sec.warning:hover { background: #fffbeb; }
|
||||
.btn-accion-sec.info { color: #1e40af; border-color: #93c5fd; }
|
||||
.btn-accion-sec.info:hover { background: #eff6ff; }
|
||||
.btn-accion-sec.danger { color: #991b1b; border-color: #fca5a5; }
|
||||
.btn-accion-sec.danger:hover { background: #fef2f2; }
|
||||
|
||||
/* ── Mejoras de touch target (tablet) ── */
|
||||
.exam-check-item { min-height: 40px; }
|
||||
.consent-item { min-height: 46px; }
|
||||
.pac-resultado { min-height: 50px; }
|
||||
.cola-card { min-height: 62px; padding: .7rem 1rem .7rem .85rem; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
@@ -340,6 +387,9 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
</span>
|
||||
<span class="badge bg-primary rounded-pill" id="badge-count">0</span>
|
||||
</div>
|
||||
<button class="btn-llamar-cola" id="btn-llamar-cola" onclick="llamarSiguiente()">
|
||||
<i class="fas fa-bell"></i>Llamar siguiente
|
||||
</button>
|
||||
</div>
|
||||
<div class="cola-items" id="cola-items">
|
||||
<div class="cola-vacia">
|
||||
@@ -511,6 +561,17 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
<i class="fas fa-vial me-1"></i>Solo entrega de muestras
|
||||
</label>
|
||||
</div>
|
||||
<div class="input-group input-group-sm mb-2">
|
||||
<span class="input-group-text text-muted" style="background:#f8fafc"><i class="fas fa-search"></i></span>
|
||||
<input type="text" id="inp-filtrar-exam" class="form-control"
|
||||
placeholder="Filtrar exámenes…" autocomplete="off"
|
||||
oninput="filtrarExamenes(this.value)">
|
||||
<button class="btn btn-outline-secondary" type="button"
|
||||
onclick="document.getElementById('inp-filtrar-exam').value='';filtrarExamenes('')"
|
||||
title="Limpiar filtro">
|
||||
<i class="fas fa-times"></i>
|
||||
</button>
|
||||
</div>
|
||||
<div id="lista-examenes">
|
||||
<?php foreach ($examenesAgrupados as $cat => $items): ?>
|
||||
<div class="exam-group-title"><?= htmlspecialchars($cat) ?></div>
|
||||
@@ -586,21 +647,25 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
|
||||
<!-- ── Acciones ── -->
|
||||
<div class="ficha-acciones">
|
||||
<button class="btn btn-success" id="btn-guardar" onclick="guardarSolicitud()">
|
||||
<i class="fas fa-save me-1"></i>Guardar solicitud
|
||||
</button>
|
||||
<button class="btn btn-primary d-none" id="btn-pasar-lugar" onclick="pasarALugar()">
|
||||
<i class="fas fa-arrow-right me-1"></i>Pasar a lugar
|
||||
</button>
|
||||
<button class="btn btn-warning d-none" id="btn-enviar-consent" onclick="enviarConsentimientos()">
|
||||
<i class="fas fa-paper-plane me-1"></i>Enviar consentimientos
|
||||
</button>
|
||||
<button class="btn btn-outline-secondary" id="btn-soltar" onclick="soltarTurno()" title="Liberar turno para que otro escritorio lo llame">
|
||||
<i class="fas fa-undo-alt me-1"></i>Soltar
|
||||
</button>
|
||||
<button class="btn btn-secondary ms-auto" onclick="marcarAusente()">
|
||||
<i class="fas fa-user-slash me-1"></i>Ausente
|
||||
</button>
|
||||
<div class="accion-primary-row">
|
||||
<button class="btn-accion-primary verde" id="btn-guardar" onclick="guardarSolicitud()">
|
||||
<i class="fas fa-save"></i>Guardar solicitud
|
||||
</button>
|
||||
<button class="btn-accion-primary azul d-none" id="btn-pasar-lugar" onclick="pasarALugar()">
|
||||
<i class="fas fa-arrow-right"></i>Pasar a lugar
|
||||
</button>
|
||||
</div>
|
||||
<div class="accion-secondary-row">
|
||||
<button class="btn-accion-sec warning d-none" id="btn-enviar-consent" onclick="enviarConsentimientos()">
|
||||
<i class="fas fa-paper-plane"></i>Consentimientos
|
||||
</button>
|
||||
<button class="btn-accion-sec info" id="btn-soltar" onclick="soltarTurno()" title="Liberar turno para que otro escritorio lo llame">
|
||||
<i class="fas fa-undo-alt"></i>Soltar
|
||||
</button>
|
||||
<button class="btn-accion-sec danger" onclick="marcarAusente()">
|
||||
<i class="fas fa-user-slash"></i>Ausente
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div><!-- /ficha-turno -->
|
||||
</div><!-- /rec-ficha -->
|
||||
@@ -917,8 +982,10 @@ function renderCola(snap) {
|
||||
|
||||
// ── Llamar siguiente ──────────────────────────────────────────
|
||||
async function llamarSiguiente() {
|
||||
const btn = document.getElementById('btn-llamar');
|
||||
btn.disabled = true;
|
||||
const btn = document.getElementById('btn-llamar');
|
||||
const btn2 = document.getElementById('btn-llamar-cola');
|
||||
if (btn) btn.disabled = true;
|
||||
if (btn2) btn2.disabled = true;
|
||||
mostrarToast('Consultando siguiente turno…', 'info', 1500);
|
||||
try {
|
||||
const res = await fetch(API + 'llamar_turno.php', {
|
||||
@@ -941,7 +1008,8 @@ async function llamarSiguiente() {
|
||||
} catch (err) {
|
||||
mostrarError(err.message);
|
||||
} finally {
|
||||
btn.disabled = false;
|
||||
if (btn) btn.disabled = false;
|
||||
if (btn2) btn2.disabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1014,7 +1082,7 @@ async function cargarConsecutivo() {
|
||||
if (!inp) return;
|
||||
inp.value = '…';
|
||||
try {
|
||||
const r = await fetch(API + 'get_consecutivo.php');
|
||||
const r = await fetch(API + 'get_consecutivo.php?tipo=F');
|
||||
const d = await r.json();
|
||||
if (d.ok) inp.value = d.consecutivo;
|
||||
} catch(_) { inp.value = ''; }
|
||||
@@ -1764,12 +1832,30 @@ function resetCheckboxes() {
|
||||
document.getElementById('chk-solo-muestras').checked = false;
|
||||
document.querySelectorAll('.exam-chk').forEach(c => { c.checked = false; c.disabled = false; });
|
||||
document.getElementById('lista-examenes').style.opacity = '';
|
||||
const fi = document.getElementById('inp-filtrar-exam');
|
||||
if (fi) { fi.value = ''; filtrarExamenes(''); }
|
||||
document.getElementById('sel-pago').value = '';
|
||||
document.getElementById('inp-total').value = '';
|
||||
document.getElementById('inp-obs').value = '';
|
||||
resetPagoCombinado();
|
||||
resetMedico();
|
||||
}
|
||||
|
||||
function filtrarExamenes(q) {
|
||||
const query = q.toLowerCase().trim();
|
||||
document.querySelectorAll('#lista-examenes .exam-check-item').forEach(item => {
|
||||
item.style.display = (!query || item.textContent.toLowerCase().includes(query)) ? '' : 'none';
|
||||
});
|
||||
document.querySelectorAll('#lista-examenes .exam-group-title').forEach(title => {
|
||||
let next = title.nextElementSibling;
|
||||
let anyVisible = false;
|
||||
while (next && !next.classList.contains('exam-group-title')) {
|
||||
if (next.style.display !== 'none') anyVisible = true;
|
||||
next = next.nextElementSibling;
|
||||
}
|
||||
title.style.display = anyVisible ? '' : 'none';
|
||||
});
|
||||
}
|
||||
function toggleTodosExamenes(val) {
|
||||
document.querySelectorAll('.exam-chk').forEach(c => c.checked = val);
|
||||
}
|
||||
@@ -1790,7 +1876,7 @@ function resetPlaceholder() {
|
||||
volverACola();
|
||||
}
|
||||
|
||||
function esMobile() { return window.innerWidth <= 900; }
|
||||
function esMobile() { return window.innerWidth <= 680; }
|
||||
function mostrarFichaMobile() {
|
||||
if (!esMobile()) return;
|
||||
document.getElementById('rec-ficha').classList.add('mobile-visible');
|
||||
|
||||
Reference in New Issue
Block a user