feat: modo embebido de formulario por lugar (link vs iframe)

- Nueva columna turnero_lugares.formulario_modo (link|embebido)
- Config: radio en modal de edición para elegir el modo
- lugar.php: muestra iframe con ver_formulario_enviado al activar turno
- API get_consent_token.php: crea/obtiene token para turno+lugar

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Lizandro Guarnizo
2026-07-03 11:35:45 -05:00
co-authored by Claude Sonnet 4.6
parent daa9827d93
commit f8245b4d6f
5 changed files with 149 additions and 16 deletions
+60 -7
View File
@@ -23,13 +23,15 @@ try {
$lugares = [];
}
$lugarIdParam = isset($_GET['lugar_id']) ? (int)$_GET['lugar_id'] : 0;
$lugarIdParam = isset($_GET['lugar_id']) ? (int)$_GET['lugar_id'] : 0;
// Resolver nombre del lugar para el título
$lugarNombre = 'Estación de Servicio';
// Resolver nombre y modo del lugar para el título
$lugarNombre = 'Estación de Servicio';
$lugarFormModo = 'link'; // 'link' | 'embebido'
foreach ($lugares as $l) {
if ((int)$l['id'] === $lugarIdParam) {
$lugarNombre = $l['nombre'];
$lugarNombre = $l['nombre'];
$lugarFormModo = $l['formulario_modo'] ?? 'link';
break;
}
}
@@ -320,6 +322,18 @@ require_once __DIR__ . '/../../../shared/components/sidebar.php';
</div>
<!-- ── Sección: Consentimientos ── -->
<!-- ── Formulario embebido (modo=embebido) ── -->
<div class="ficha-sec d-none" id="sec-form-embebido">
<h6><i class="fas fa-file-alt me-1"></i>Formulario de consentimiento</h6>
<div id="form-embebido-loading" class="text-muted small py-2">
<i class="fas fa-spinner fa-spin me-1"></i>Cargando formulario...
</div>
<iframe id="form-embebido-iframe" src="" frameborder="0"
style="width:100%;min-height:520px;border-radius:8px;border:1px solid #e2e8f0;display:none"
onload="this.style.display='block';document.getElementById('form-embebido-loading').style.display='none'">
</iframe>
</div>
<div class="ficha-sec" id="sec-consent">
<h6><i class="fas fa-file-signature me-1"></i>Consentimientos informados</h6>
@@ -389,9 +403,10 @@ let hayPendientes = false;
let pollingColaId = null;
let pollingConsentId = null;
const API = '<?= BASE_URL ?>modules/turnero/api/';
const BASE_WA = '<?= BASE_URL ?>';
const LUGAR_NOMBRE = document.getElementById('lbl-lugar-titulo')?.textContent || '<?= addslashes($lugarNombre) ?>';
const API = '<?= BASE_URL ?>modules/turnero/api/';
const BASE_WA = '<?= BASE_URL ?>';
const LUGAR_NOMBRE = document.getElementById('lbl-lugar-titulo')?.textContent || '<?= addslashes($lugarNombre) ?>';
const LUGAR_FORM_MODO = '<?= $lugarFormModo ?>';
// ── Arranque ──────────────────────────────────────────────────
@@ -523,6 +538,9 @@ async function seleccionarSinLlamar(turnoId) {
await cargarFichaSolicitud(t.id);
clearInterval(pollingConsentId);
pollingConsentId = setInterval(() => actualizarConsentimientos(turnoActivo?.id), 5000);
if (LUGAR_FORM_MODO === 'embebido' && lugarId) {
cargarFormEmbebido(t.id);
}
mostrarFichaMobile();
}
@@ -596,6 +614,12 @@ async function abrirFicha(turno) {
// Iniciar polling de consentimientos
clearInterval(pollingConsentId);
pollingConsentId = setInterval(() => actualizarConsentimientos(turnoActivo?.id), 5000);
// Formulario embebido
if (LUGAR_FORM_MODO === 'embebido' && lugarId) {
cargarFormEmbebido(turno.id);
}
mostrarFichaMobile();
}
@@ -835,12 +859,41 @@ async function cambiarEstadoTurno(nuevoEstado) {
}
// ── Reset ─────────────────────────────────────────────────────
async function cargarFormEmbebido(turnoId) {
const sec = document.getElementById('sec-form-embebido');
const iframe = document.getElementById('form-embebido-iframe');
const load = document.getElementById('form-embebido-loading');
if (!sec || !iframe) return;
sec.classList.remove('d-none');
iframe.style.display = 'none';
load.style.display = '';
try {
const res = await fetch(`${API}get_consent_token.php?turno_id=${turnoId}&lugar_id=${lugarId}`);
const json = await res.json();
if (json.ok && json.token) {
iframe.src = `${BASE_WA}ver_formulario_enviado.php?token=${encodeURIComponent(json.token)}`;
} else {
load.innerHTML = '<span class="text-danger small"><i class="fas fa-exclamation-triangle me-1"></i>' + (json.error || 'No hay formulario configurado') + '</span>';
}
} catch (e) {
load.innerHTML = '<span class="text-danger small"><i class="fas fa-exclamation-triangle me-1"></i>Error al cargar formulario</span>';
}
}
function resetFicha() {
clearInterval(pollingConsentId);
turnoActivo = null;
tieneConsent = false;
hayPendientes = false;
// Limpiar iframe embebido
const iframe = document.getElementById('form-embebido-iframe');
const sec = document.getElementById('sec-form-embebido');
const load = document.getElementById('form-embebido-loading');
if (iframe) { iframe.src = ''; iframe.style.display = 'none'; }
if (sec) { sec.classList.add('d-none'); }
if (load) { load.style.display = ''; load.innerHTML = '<i class="fas fa-spinner fa-spin me-1"></i>Cargando formulario...'; }
document.getElementById('ficha-turno').classList.add('d-none');
document.getElementById('ficha-placeholder').classList.remove('d-none');
document.getElementById('badge-turno-activo').classList.add('d-none');