feat(turnero): tomas de muestras prolongadas con temporizador y progreso
- DB: ALTER TABLE turnero_consentimientos ADD siguiente_toma_at, toma_inicio_at; MODIFY estado para incluir 'en_progreso' - guardar_toma.php (nuevo): guarda firma parcial por campo_id, parsea el esquema para calcular siguiente_toma_at desde 'Minuto X' o hora fija, marca 'en_progreso' o 'firmado' según tomas restantes - get_consentimientos.php: expone siguiente_toma_at, es_toma_progresiva, tomas_total, tomas_firmadas, campos_firma_pro en cada consentimiento - lugar.php: estado en_progreso con badge X/Y, countdown en tiempo real, animación de alerta cuando el tiempo llega, botón 'Siguiente toma' que abre el modal embebido en modo toma_progresiva Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 4.6
parent
cf8d011f09
commit
ea1f0e30c9
@@ -48,6 +48,9 @@ $stmt = $pdo->prepare(
|
||||
tc.firmado_at,
|
||||
(tc.firma_profesional_svg IS NOT NULL) AS tiene_firma_profesional,
|
||||
tc.firmado_profesional_at,
|
||||
tc.siguiente_toma_at,
|
||||
tc.toma_inicio_at,
|
||||
tc.datos_respuestas,
|
||||
f.nombre AS formulario_nombre,
|
||||
f.esquema AS formulario_esquema
|
||||
FROM turnero_consentimientos tc
|
||||
@@ -66,14 +69,31 @@ foreach ($consentimientos as &$c) {
|
||||
$decoded = json_decode($esquema, true);
|
||||
$campos = is_array($decoded) ? $decoded : ($decoded['campos'] ?? []);
|
||||
}
|
||||
$tieneFirmaPro = !empty(array_filter($campos, fn($f) => ($f['tipo'] ?? '') === 'firma_profesional'));
|
||||
$tieneFirmaPac = !empty(array_filter($campos, fn($f) => ($f['tipo'] ?? '') === 'firma'));
|
||||
$camposFirmaPro = array_values(array_filter($campos, fn($f) => ($f['tipo'] ?? '') === 'firma_profesional'));
|
||||
$tieneFirmaPro = !empty($camposFirmaPro);
|
||||
$tieneFirmaPac = !empty(array_filter($campos, fn($f) => ($f['tipo'] ?? '') === 'firma'));
|
||||
|
||||
// Toma progresiva: más de 1 campo firma_profesional
|
||||
$esTomaProg = count($camposFirmaPro) > 1;
|
||||
$tomasTotal = count($camposFirmaPro);
|
||||
$tomasFirm = 0;
|
||||
if ($esTomaProg && $c['datos_respuestas']) {
|
||||
$dr = json_decode($c['datos_respuestas'], true) ?? [];
|
||||
foreach ($camposFirmaPro as $fp) {
|
||||
if (!empty($dr[$fp['id']]) && strlen($dr[$fp['id']]) > 10) $tomasFirm++;
|
||||
}
|
||||
}
|
||||
|
||||
$c['requiere_firma_profesional'] = $tieneFirmaPro;
|
||||
$c['requiere_firma_paciente'] = !($tieneFirmaPro && !$tieneFirmaPac);
|
||||
// Si el formulario está asignado al lugar destino → es de toma de muestras, no de recepción
|
||||
$c['origen_lugar_id'] = in_array((int)$c['formulario_id'], $fidsDeLugar, true)
|
||||
? $lugarDestinoId : null;
|
||||
unset($c['formulario_esquema']);
|
||||
$c['origen_lugar_id'] = in_array((int)$c['formulario_id'], $fidsDeLugar, true)
|
||||
? $lugarDestinoId : null;
|
||||
$c['es_toma_progresiva'] = $esTomaProg;
|
||||
$c['tomas_total'] = $tomasTotal;
|
||||
$c['tomas_firmadas'] = $tomasFirm;
|
||||
// Exponer campos firma_profesional (ids) para el frontend
|
||||
$c['campos_firma_pro'] = array_column($camposFirmaPro, 'id');
|
||||
unset($c['formulario_esquema'], $c['datos_respuestas']);
|
||||
}
|
||||
unset($c);
|
||||
|
||||
@@ -202,6 +222,9 @@ if ($incluirSolicitud) {
|
||||
tc.estado, tc.enviado_at, tc.firmado_at,
|
||||
(tc.firma_profesional_svg IS NOT NULL) AS tiene_firma_profesional,
|
||||
tc.firmado_profesional_at,
|
||||
tc.siguiente_toma_at,
|
||||
tc.toma_inicio_at,
|
||||
tc.datos_respuestas,
|
||||
f.nombre AS formulario_nombre,
|
||||
f.esquema AS formulario_esquema
|
||||
FROM turnero_consentimientos tc
|
||||
@@ -218,13 +241,26 @@ if ($incluirSolicitud) {
|
||||
$decoded = json_decode($esquema, true);
|
||||
$campos = is_array($decoded) ? $decoded : ($decoded['campos'] ?? []);
|
||||
}
|
||||
$tieneFirmaPro = !empty(array_filter($campos, fn($f) => ($f['tipo'] ?? '') === 'firma_profesional'));
|
||||
$tieneFirmaPac = !empty(array_filter($campos, fn($f) => ($f['tipo'] ?? '') === 'firma'));
|
||||
$camposFirmaPro = array_values(array_filter($campos, fn($f) => ($f['tipo'] ?? '') === 'firma_profesional'));
|
||||
$tieneFirmaPro = !empty($camposFirmaPro);
|
||||
$tieneFirmaPac = !empty(array_filter($campos, fn($f) => ($f['tipo'] ?? '') === 'firma'));
|
||||
$esTomaProg = count($camposFirmaPro) > 1;
|
||||
$tomasFirm = 0;
|
||||
if ($esTomaProg && $c['datos_respuestas']) {
|
||||
$dr = json_decode($c['datos_respuestas'], true) ?? [];
|
||||
foreach ($camposFirmaPro as $fp) {
|
||||
if (!empty($dr[$fp['id']]) && strlen($dr[$fp['id']]) > 10) $tomasFirm++;
|
||||
}
|
||||
}
|
||||
$c['requiere_firma_profesional'] = $tieneFirmaPro;
|
||||
$c['requiere_firma_paciente'] = !($tieneFirmaPro && !$tieneFirmaPac);
|
||||
$c['origen_lugar_id'] = in_array((int)$c['formulario_id'], $fidsDeLugar, true)
|
||||
? $lugarDestinoId : null;
|
||||
unset($c['formulario_esquema']);
|
||||
$c['origen_lugar_id'] = in_array((int)$c['formulario_id'], $fidsDeLugar, true)
|
||||
? $lugarDestinoId : null;
|
||||
$c['es_toma_progresiva'] = $esTomaProg;
|
||||
$c['tomas_total'] = count($camposFirmaPro);
|
||||
$c['tomas_firmadas'] = $tomasFirm;
|
||||
$c['campos_firma_pro'] = array_column($camposFirmaPro, 'id');
|
||||
unset($c['formulario_esquema'], $c['datos_respuestas']);
|
||||
}
|
||||
unset($c);
|
||||
$respuesta['consentimientos'] = $consentimientos;
|
||||
|
||||
@@ -0,0 +1,152 @@
|
||||
<?php
|
||||
/**
|
||||
* POST /modules/turnero/api/guardar_toma.php
|
||||
* Guarda una firma parcial en formularios de tomas prolongadas.
|
||||
* Calcula el próximo intervalo y actualiza estado + siguiente_toma_at.
|
||||
*
|
||||
* Body JSON:
|
||||
* turno_id int requerido
|
||||
* formulario_id int requerido
|
||||
* campo_id string requerido (id del campo firma_profesional firmado)
|
||||
* svg string requerido (data URI)
|
||||
* datos_respuestas object requerido (todos los valores actuales del form)
|
||||
*/
|
||||
require_once __DIR__ . '/_helpers.php';
|
||||
requireMethod('POST');
|
||||
requireTurnero();
|
||||
|
||||
$body = inputJson();
|
||||
$turnoId = (int)($body['turno_id'] ?? 0);
|
||||
$formularioId = (int)($body['formulario_id'] ?? 0);
|
||||
$campoId = trim($body['campo_id'] ?? '');
|
||||
$svg = $body['svg'] ?? '';
|
||||
$datosInput = is_array($body['datos_respuestas'] ?? null) ? $body['datos_respuestas'] : [];
|
||||
|
||||
if (!$turnoId) jsonError('turno_id requerido.');
|
||||
if (!$formularioId) jsonError('formulario_id requerido.');
|
||||
if (!$campoId) jsonError('campo_id requerido.');
|
||||
if (strlen($svg) < 100) jsonError('Firma requerida.');
|
||||
if (!preg_match('/^data:image\/(svg\+xml|png|jpeg|webp);base64,/i', $svg)) {
|
||||
jsonError('Formato de firma no válido.');
|
||||
}
|
||||
|
||||
$pdo = db();
|
||||
|
||||
// ── Cargar consentimiento y esquema ──────────────────────────
|
||||
$stmt = $pdo->prepare(
|
||||
"SELECT tc.id, tc.estado, tc.datos_respuestas, tc.toma_inicio_at, t.sesion_id,
|
||||
f.esquema
|
||||
FROM turnero_consentimientos tc
|
||||
JOIN turnero_turnos t ON t.id = tc.turno_id
|
||||
JOIN lab_formularios f ON f.id = tc.formulario_id
|
||||
WHERE tc.turno_id = ? AND tc.formulario_id = ?"
|
||||
);
|
||||
$stmt->execute([$turnoId, $formularioId]);
|
||||
$tc = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
if (!$tc) jsonError('Consentimiento no encontrado.', 404);
|
||||
|
||||
$esquema = json_decode($tc['esquema'] ?? '[]', true);
|
||||
if (!is_array($esquema)) $esquema = [];
|
||||
|
||||
// ── Merge datos_respuestas existentes + nuevos ───────────────
|
||||
$datosActuales = [];
|
||||
if ($tc['datos_respuestas']) {
|
||||
$d = json_decode($tc['datos_respuestas'], true);
|
||||
if (is_array($d)) $datosActuales = $d;
|
||||
}
|
||||
// Guardar svg en el campo firmado
|
||||
$datosInput[$campoId] = $svg;
|
||||
$datosMerge = array_merge($datosActuales, $datosInput);
|
||||
|
||||
// ── Analizar esquema: campos firma_profesional en orden ──────
|
||||
// Construir mapa: campo_id → minuto (o hora fija) leyendo el separador previo
|
||||
$firmasCampos = []; // [ [id, minutos|null, hora_fija|null], ... ] en orden
|
||||
$separadorLabel = null;
|
||||
|
||||
foreach ($esquema as $campo) {
|
||||
$tipo = $campo['tipo'] ?? '';
|
||||
if ($tipo === 'separador') {
|
||||
$separadorLabel = $campo['label'] ?? '';
|
||||
}
|
||||
if ($tipo === 'firma_profesional') {
|
||||
$minutos = null;
|
||||
$horaFija = null;
|
||||
if ($separadorLabel !== null) {
|
||||
// "Taukit · Minuto 10" → 10; "Toma · Minuto 60" → 60
|
||||
if (preg_match('/Minuto\s+(\d+)/i', $separadorLabel, $m)) {
|
||||
$minutos = (int)$m[1];
|
||||
}
|
||||
// "3:00 p.m." / "4:00 p.m." → hora fija
|
||||
elseif (preg_match('/(\d+):(\d+)\s*(a\.?m\.?|p\.?m\.?)/i', $separadorLabel, $m)) {
|
||||
$h = (int)$m[1];
|
||||
$min = (int)$m[2];
|
||||
$pm = strtolower(preg_replace('/[^apm]/i', '', $m[3])) === 'pm';
|
||||
if ($pm && $h < 12) $h += 12;
|
||||
$horaFija = sprintf('%02d:%02d:00', $h, $min);
|
||||
}
|
||||
}
|
||||
$firmasCampos[] = ['id' => $campo['id'], 'minutos' => $minutos, 'hora_fija' => $horaFija];
|
||||
}
|
||||
}
|
||||
|
||||
// ── Determinar estado y siguiente_toma_at ────────────────────
|
||||
$firmados = array_filter($firmasCampos, fn($f) => isset($datosMerge[$f['id']]) && strlen($datosMerge[$f['id']]) > 10);
|
||||
$pendientes = array_filter($firmasCampos, fn($f) => !isset($datosMerge[$f['id']]) || strlen($datosMerge[$f['id']]) <= 10);
|
||||
$pendientes = array_values($pendientes);
|
||||
|
||||
$todasFirmadas = empty($pendientes);
|
||||
$siguienteToma = null;
|
||||
$nuevoEstado = 'en_progreso';
|
||||
$tomaInicioAt = $tc['toma_inicio_at'];
|
||||
|
||||
if (empty($tc['toma_inicio_at'])) {
|
||||
$tomaInicioAt = date('Y-m-d H:i:s');
|
||||
}
|
||||
|
||||
if ($todasFirmadas) {
|
||||
$nuevoEstado = 'firmado';
|
||||
} else {
|
||||
// Calcular cuándo es la siguiente toma
|
||||
$next = $pendientes[0];
|
||||
if ($next['hora_fija'] !== null) {
|
||||
// Hora fija en el día actual
|
||||
$siguienteToma = date('Y-m-d') . ' ' . $next['hora_fija'];
|
||||
} elseif ($next['minutos'] !== null && $tomaInicioAt) {
|
||||
// Minuto relativo desde el inicio de la toma
|
||||
$siguienteToma = date('Y-m-d H:i:s', strtotime($tomaInicioAt) + $next['minutos'] * 60);
|
||||
}
|
||||
}
|
||||
|
||||
// ── Persistir ────────────────────────────────────────────────
|
||||
$pdo->prepare(
|
||||
"UPDATE turnero_consentimientos
|
||||
SET datos_respuestas = ?,
|
||||
estado = ?,
|
||||
siguiente_toma_at = ?,
|
||||
toma_inicio_at = COALESCE(toma_inicio_at, ?),
|
||||
firmado_at = IF(? = 'firmado', NOW(), firmado_at),
|
||||
firmado_profesional_at = IF(? = 'firmado', NOW(), firmado_profesional_at)
|
||||
WHERE turno_id = ? AND formulario_id = ?"
|
||||
)->execute([
|
||||
json_encode($datosMerge, JSON_UNESCAPED_UNICODE),
|
||||
$nuevoEstado,
|
||||
$siguienteToma,
|
||||
date('Y-m-d H:i:s'),
|
||||
$nuevoEstado,
|
||||
$nuevoEstado,
|
||||
$turnoId,
|
||||
$formularioId,
|
||||
]);
|
||||
|
||||
notificarSSE((int)$tc['sesion_id']);
|
||||
|
||||
$totalFirmas = count($firmasCampos);
|
||||
$firmadasCount = count($firmados) + ($todasFirmadas ? 0 : 1); // incluye la recién guardada
|
||||
|
||||
jsonOk([
|
||||
'estado' => $nuevoEstado,
|
||||
'siguiente_toma_at'=> $siguienteToma,
|
||||
'tomas_firmadas' => min($firmadasCount, $totalFirmas),
|
||||
'tomas_total' => $totalFirmas,
|
||||
'completado' => $todasFirmadas,
|
||||
], $todasFirmadas ? 'Formulario completado.' : 'Toma guardada. Próxima: ' . ($siguienteToma ?? 'pendiente'));
|
||||
@@ -265,11 +265,18 @@ try {
|
||||
padding: .5rem .7rem; border-radius: 10px; margin-bottom: .35rem;
|
||||
font-size: .84rem; border: 1px solid transparent; min-height: 46px;
|
||||
}
|
||||
.consent-row.firmado { background: #f0fdf4; color: #166534; border-color: #bbf7d0; }
|
||||
.consent-row.rechazado { background: #f8fafc; color: #64748b; border-color: #e2e8f0; }
|
||||
.consent-row.enviado { background: #eff6ff; color: #1e40af; border-color: #bfdbfe; }
|
||||
.consent-row.pendiente { background: #fffbeb; color: #92400e; border-color: #fde68a; }
|
||||
.consent-row.visto { background: #faf5ff; color: #6b21a8; border-color: #ddd6fe; }
|
||||
.consent-row.firmado { background: #f0fdf4; color: #166534; border-color: #bbf7d0; }
|
||||
.consent-row.rechazado { background: #f8fafc; color: #64748b; border-color: #e2e8f0; }
|
||||
.consent-row.enviado { background: #eff6ff; color: #1e40af; border-color: #bfdbfe; }
|
||||
.consent-row.pendiente { background: #fffbeb; color: #92400e; border-color: #fde68a; }
|
||||
.consent-row.visto { background: #faf5ff; color: #6b21a8; border-color: #ddd6fe; }
|
||||
.consent-row.en_progreso { background: #fff7ed; color: #9a3412; border-color: #fed7aa; }
|
||||
.consent-row.en_progreso.alerta { background: #fef2f2; color: #991b1b; border-color: #fca5a5;
|
||||
animation: parpadeo-alerta 1s infinite; }
|
||||
@keyframes parpadeo-alerta { 0%,100%{opacity:1} 50%{opacity:.6} }
|
||||
.toma-progreso { font-size:.67rem; background:#ea580c; color:#fff;
|
||||
border-radius:99px; padding:1px 7px; font-weight:700; white-space:nowrap; }
|
||||
.toma-countdown { font-size:.67rem; color:inherit; opacity:.75; white-space:nowrap; }
|
||||
.consent-row .nom-form { flex: 1; font-weight: 500; }
|
||||
.consent-row .c-badge { font-size: .67rem; padding: 1px 8px; border-radius: 99px;
|
||||
border: 1px solid currentColor; font-weight: 700; opacity: .85; }
|
||||
@@ -1090,17 +1097,46 @@ async function cargarFichaSolicitud(turnoId) {
|
||||
const CONSENT_IC = {
|
||||
firmado:'fa-check-circle', rechazado:'fa-ban',
|
||||
enviado:'fa-envelope', visto:'fa-eye', pendiente:'fa-clock',
|
||||
en_progreso:'fa-hourglass-half',
|
||||
};
|
||||
const CONSENT_LBL = {
|
||||
firmado:'Firmado', rechazado:'Rechazado', enviado:'Enviado', visto:'Visto', pendiente:'Pendiente',
|
||||
en_progreso:'En progreso',
|
||||
};
|
||||
|
||||
// ── Tomas progresivas: actualiza countdowns cada segundo ──────
|
||||
let _tomaTimers = {}; // consent_id → { siguiente_toma_at, es_alerta }
|
||||
setInterval(() => {
|
||||
const ahora = Date.now();
|
||||
for (const [cid, info] of Object.entries(_tomaTimers)) {
|
||||
const row = document.querySelector(`[data-consent-id="${cid}"]`);
|
||||
if (!row) continue;
|
||||
const cdEl = row.querySelector('.toma-countdown');
|
||||
if (!cdEl) continue;
|
||||
if (!info.siguiente_toma_at) { cdEl.textContent = ''; continue; }
|
||||
const diff = Math.floor((info.siguiente_toma_at - ahora) / 1000);
|
||||
if (diff <= 0) {
|
||||
cdEl.textContent = '¡Hora de toma!';
|
||||
row.classList.add('alerta');
|
||||
if (!info.alertado) {
|
||||
info.alertado = true;
|
||||
try { new Audio('data:audio/wav;base64,UklGRnoGAABXQVZFZm10IBAAAA...').play().catch(()=>{}); } catch(_) {}
|
||||
}
|
||||
} else {
|
||||
row.classList.remove('alerta');
|
||||
const m = Math.floor(diff / 60), s = diff % 60;
|
||||
cdEl.textContent = `próx. toma en ${m}:${String(s).padStart(2,'0')}`;
|
||||
}
|
||||
}
|
||||
}, 1000);
|
||||
|
||||
function renderConsentimientos(lista) {
|
||||
// Mostrar consentimientos de examen (origen null) + los de esta estación
|
||||
lista = lista.filter(c => !c.origen_lugar_id || c.origen_lugar_id == lugarId);
|
||||
tieneConsent = lista.length > 0;
|
||||
hayPendientes = lista.some(c => !['firmado','rechazado'].includes(c.estado));
|
||||
const pendCount = lista.filter(c => !['firmado','rechazado'].includes(c.estado)).length;
|
||||
// en_progreso bloquea finalizar pero no muestra aviso de "pendiente sin acción"
|
||||
const pendCount = lista.filter(c => ['pendiente','enviado','visto'].includes(c.estado)).length;
|
||||
|
||||
const listEl = document.getElementById('lista-consent');
|
||||
const sinEl = document.getElementById('sin-consent');
|
||||
@@ -1131,6 +1167,17 @@ function renderConsentimientos(lista) {
|
||||
banner.classList.toggle('d-none', !hayPendientes);
|
||||
if (btnFin) btnFin.disabled = hayPendientes;
|
||||
|
||||
// Actualizar mapa de timers para tomas progresivas
|
||||
_tomaTimers = {};
|
||||
lista.forEach(c => {
|
||||
if (c.es_toma_progresiva && c.estado === 'en_progreso') {
|
||||
_tomaTimers[c.id] = {
|
||||
siguiente_toma_at: c.siguiente_toma_at ? new Date(c.siguiente_toma_at).getTime() : null,
|
||||
alertado: false,
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
listEl.innerHTML = lista.map(c => {
|
||||
const ya = ['firmado','rechazado'].includes(c.estado);
|
||||
const ico = CONSENT_IC[c.estado] || 'fa-clock';
|
||||
@@ -1139,6 +1186,15 @@ function renderConsentimientos(lista) {
|
||||
const nomJs = JSON.stringify(c.formulario_nombre || 'Consentimiento');
|
||||
const idJs = parseInt(c.id) || 0;
|
||||
const tId = parseInt(c.turno_id) || (turnoActivo?.id) || 0;
|
||||
const fId = parseInt(c.formulario_id) || 0;
|
||||
|
||||
// Badge de progreso para tomas progresivas
|
||||
let progresoBadge = '';
|
||||
if (c.es_toma_progresiva && c.tomas_total > 0) {
|
||||
progresoBadge = `<span class="toma-progreso">${c.tomas_firmadas}/${c.tomas_total}</span>`;
|
||||
}
|
||||
const countdownEl = (c.es_toma_progresiva && c.estado === 'en_progreso')
|
||||
? `<span class="toma-countdown"></span>` : '';
|
||||
|
||||
// Botón ver
|
||||
const btnVer = (ya && c.token)
|
||||
@@ -1149,8 +1205,15 @@ function renderConsentimientos(lista) {
|
||||
|
||||
// Acción de firma según modo
|
||||
let btnAccion = '';
|
||||
if (!ya && c.token) {
|
||||
if (LUGAR_FORM_MODO === 'embebido') {
|
||||
const puedeFirmar = !ya || (c.es_toma_progresiva && c.estado === 'en_progreso');
|
||||
if (puedeFirmar && c.token) {
|
||||
if (c.es_toma_progresiva) {
|
||||
// Toma progresiva: siempre abre el modal embebido para firmar la siguiente toma
|
||||
btnAccion = `<button class="btn btn-primary" title="Registrar siguiente toma"
|
||||
onclick="abrirTomaProgresiva('${token}', ${tId}, ${fId})">
|
||||
<i class="fas fa-flask me-1"></i>Siguiente toma
|
||||
</button>`;
|
||||
} else if (LUGAR_FORM_MODO === 'embebido') {
|
||||
btnAccion = `<button class="btn btn-primary" title="Abrir formulario"
|
||||
onclick="abrirModalConsentimientoPorToken('${token}')">
|
||||
<i class="fas fa-pen me-1"></i>Firmar
|
||||
@@ -1170,6 +1233,8 @@ function renderConsentimientos(lista) {
|
||||
return `<div class="consent-row ${c.estado}" data-consent-id="${c.id}">
|
||||
<i class="fas ${ico}"></i>
|
||||
<span class="nom-form">${escHtml(c.formulario_nombre || 'Consentimiento')}</span>
|
||||
${progresoBadge}
|
||||
${countdownEl}
|
||||
<span class="c-badge">${label}</span>
|
||||
<div class="acciones-consent">${btnAccion}${btnVer}</div>
|
||||
</div>`;
|
||||
@@ -1234,6 +1299,22 @@ function abrirModalConsentimientoPorToken(token) {
|
||||
_abrirModalConToken(token);
|
||||
}
|
||||
|
||||
// ── Toma progresiva: abre el modal con modo especial ──────────
|
||||
function abrirTomaProgresiva(token, turnoId, formularioId) {
|
||||
const modal = document.getElementById('modal-consentimiento');
|
||||
const iframe = document.getElementById('modal-consent-iframe');
|
||||
const load = document.getElementById('modal-consent-loading');
|
||||
iframe.style.display = 'none';
|
||||
iframe.src = '';
|
||||
load.style.display = '';
|
||||
modal.style.display = 'flex';
|
||||
// Pasa modo=toma_progresiva para que el renderer solo muestre
|
||||
// los campos del siguiente tiempo pendiente y el botón de guardar parcial
|
||||
setTimeout(() => {
|
||||
iframe.src = `${BASE_WA}ver_formulario_enviado.php?token=${encodeURIComponent(token)}&embed=1&compact=1&modo=toma_progresiva`;
|
||||
}, 80);
|
||||
}
|
||||
|
||||
function cerrarModalConsentimiento() {
|
||||
const modal = document.getElementById('modal-consentimiento');
|
||||
const iframe = document.getElementById('modal-consent-iframe');
|
||||
|
||||
Reference in New Issue
Block a user