turnero/recepcion: botón para generar nuevo turno desde recepción

Modal con select de prioridad (cargado desde BD) y campo opcional
de cédula/nombre. Llama a create_turno.php que ya maneja sesión,
duplicados, SSE y notificación WhatsApp.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Lizandro Guarnizo
2026-07-16 20:54:02 -05:00
co-authored by Claude Sonnet 4.6
parent 8917daf9be
commit 8b0bdc6b30
+91 -3
View File
@@ -116,6 +116,10 @@ try {
$desk = $desksRecepcion[0];
$deskId = (int)$desk['id'];
}
$prioridades = $pdo->query(
"SELECT codigo, nombre, color FROM turnero_prioridades WHERE activo=1 ORDER BY orden_peso"
)->fetchAll(PDO::FETCH_ASSOC);
} catch (\Throwable $e) {
$lugares = [];
$examenesAgrupados = [];
@@ -123,6 +127,7 @@ try {
$desk = null;
$lugarRecepcion = null;
$lugarMuestras = null;
$prioridades = [];
}
$deskNombre = $desk['nombre'] ?? null; // null = vista genérica
@@ -425,6 +430,42 @@ $SIDEBAR_ICON = 'fas fa-ticket-alt';
require_once __DIR__ . '/../../../shared/components/sidebar.php';
?>
<!-- Modal: Nuevo turno desde recepción -->
<div class="modal fade" id="modalNuevoTurno" tabindex="-1">
<div class="modal-dialog modal-dialog-centered modal-sm">
<div class="modal-content">
<div class="modal-header py-2">
<h6 class="modal-title fw-semibold"><i class="fas fa-plus-circle me-2 text-success"></i>Nuevo turno</h6>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<div class="mb-3">
<label class="form-label small fw-semibold">Prioridad</label>
<select id="mnt-prio" class="form-select form-select-sm">
<?php foreach ($prioridades as $p): ?>
<option value="<?= $p['codigo'] ?>" data-color="<?= htmlspecialchars($p['color']) ?>">
<?= $p['codigo'] ?> — <?= htmlspecialchars($p['nombre']) ?>
</option>
<?php endforeach; ?>
</select>
</div>
<div class="mb-1">
<label class="form-label small fw-semibold">Cédula / Nombre <span class="text-muted fw-normal">(opcional)</span></label>
<input type="text" id="mnt-doc" class="form-control form-control-sm"
placeholder="Número de documento o nombre" maxlength="150">
</div>
<div id="mnt-msg" class="small mt-2 d-none"></div>
</div>
<div class="modal-footer py-2">
<button type="button" class="btn btn-secondary btn-sm" data-bs-dismiss="modal">Cancelar</button>
<button type="button" class="btn btn-success btn-sm" id="mnt-btn-crear" onclick="crearNuevoTurno()">
<i class="fas fa-ticket-alt me-1"></i>Crear turno
</button>
</div>
</div>
</div>
</div>
<?php if (!$deskId && count($desksRecepcion) > 1): ?>
<!-- Modal selector de escritorio (se muestra si no hay desk_id en URL) -->
<div class="modal fade" id="modalDeskSelect" tabindex="-1" data-bs-backdrop="static" data-bs-keyboard="false">
@@ -485,9 +526,14 @@ 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 class="d-flex gap-2">
<button class="btn-llamar-cola" id="btn-llamar-cola" onclick="llamarSiguiente()">
<i class="fas fa-bell"></i>Llamar siguiente
</button>
<button class="btn btn-sm btn-outline-success" onclick="abrirModalNuevoTurno()" title="Crear nuevo turno">
<i class="fas fa-plus"></i>
</button>
</div>
</div>
<div class="cola-items" id="cola-items">
<div class="cola-vacia">
@@ -1242,6 +1288,48 @@ function renderCola(snap) {
}).join('');
}
// ── Nuevo turno desde recepción ───────────────────────────────
let _modalNuevoTurno;
function abrirModalNuevoTurno() {
if (!_modalNuevoTurno) _modalNuevoTurno = new bootstrap.Modal(document.getElementById('modalNuevoTurno'));
document.getElementById('mnt-doc').value = '';
document.getElementById('mnt-msg').className = 'small mt-2 d-none';
document.getElementById('mnt-btn-crear').disabled = false;
// Pre-fill doc si hay turno activo
const doc = turnoActivo?.paciente_nombre;
if (doc) document.getElementById('mnt-doc').value = doc;
_modalNuevoTurno.show();
}
async function crearNuevoTurno() {
const btn = document.getElementById('mnt-btn-crear');
const msg = document.getElementById('mnt-msg');
const prio = document.getElementById('mnt-prio').value;
const doc = document.getElementById('mnt-doc').value.trim();
btn.disabled = true;
msg.className = 'small mt-2 d-none';
try {
const r = await fetch(API + 'create_turno.php', {
method: 'POST',
headers: {'Content-Type':'application/json'},
body: JSON.stringify({ prioridad_codigo: prio, paciente_nombre: doc || undefined }),
});
const j = await r.json();
if (j.ok) {
msg.className = 'small mt-2 text-success';
msg.textContent = `Turno ${j.turno.codigo} creado`;
setTimeout(() => _modalNuevoTurno.hide(), 1200);
} else {
msg.className = 'small mt-2 text-danger';
msg.textContent = j.error || 'Error al crear turno';
btn.disabled = false;
}
} catch {
msg.className = 'small mt-2 text-danger';
msg.textContent = 'Error de conexión';
btn.disabled = false;
}
}
// ── Llamar siguiente ──────────────────────────────────────────
async function llamarSiguiente() {
const btn = document.getElementById('btn-llamar');