diff --git a/ver_formulario_enviado.php b/ver_formulario_enviado.php index f60525b..5e937a3 100644 --- a/ver_formulario_enviado.php +++ b/ver_formulario_enviado.php @@ -31,6 +31,7 @@ if ($modoTurnero) { "SELECT tc.id, tc.turno_id, tc.formulario_id, tc.token, tc.estado, tc.enviado_at, tc.firmado_at, tc.ip_firma, tc.ua_firma, tc.firma_svg, tc.firma_profesional_svg, tc.firmado_profesional_at, tc.datos_respuestas, + tc.siguiente_toma_at, tc.toma_inicio_at, f.nombre AS form_nombre, f.categoria, f.descripcion AS form_descripcion, f.esquema, f.es_toma_progresiva, f.doc_encabezado, f.doc_subtitulo, f.doc_logo_base64, f.doc_color, f.doc_pie_pagina, p.nombre_completo AS paciente_nombre, @@ -321,6 +322,7 @@ if ($modoTurnero && $embebido && $_soloFirmaPro) { for ($i = 0, $n = count($_secs); $i < $n; $i++) { $_s = $_secs[$i]; $_nx = $_secs[$i + 1] ?? null; $_mpMap[$_s['firma']] = [ + 'label' => $_s['label'], 'hora_campo' => $_s['hora'], 'next_label' => $_nx ? $_nx['label'] : null, 'next_firma_id' => $_nx ? $_nx['firma'] : null, @@ -342,6 +344,15 @@ if (!empty($_mpMap)) { } } +// siguiente_toma_at para recuperar countdown si el modal fue cerrado y reabierto +$_mpSiguienteTomAt = null; +if ($modoTurnero && $embebido && !empty($_mpMap) && $_mpPrimeraPendiente !== null) { + $raw = $tcRow['siguiente_toma_at'] ?? null; + if ($raw && $raw > date('Y-m-d H:i:s')) { + $_mpSiguienteTomAt = $raw; + } +} + // Mapa id → label $labelMap = []; foreach ($esquema as $c) { @@ -880,9 +891,6 @@ function _addExamWizardHtml(string $cid): string { ($modoTurnero && $embebido && isUserLoggedIn()) ); if ($_mostrarCanvasPro): ?> - - - ; +window._muestrasMap = ; window._mpSavedFirmas = {}; +window._mpTomaData = {}; function _mpAutoFillHora(firmaId) { var entry = window._muestrasMap && window._muestrasMap[firmaId]; @@ -1529,6 +1538,19 @@ document.addEventListener('DOMContentLoaded', function() { }, 350); }); +window._fpwPreFirma = ; + +// Fix 1: recuperar countdown si el modal fue cerrado y reabierto mientras una toma estaba en curso +(function() { + var targetMs = new Date('').getTime(); + if (targetMs <= Date.now()) return; + var pendingId = ; + var entry = window._muestrasMap && window._muestrasMap[pendingId]; + document.addEventListener('DOMContentLoaded', function() { + _mpIniciarCountdown(targetMs, entry ? (entry.label || null) : null, pendingId); + }); +})(); + /* ── Firma del profesional: función compartida canvas/1-clic ────── */ function _guardarFirmaPro(widget, svg, msgEl) { const turnoId = widget.dataset.turno; @@ -1605,6 +1627,10 @@ function _guardarFirmaMP(widget, svg, msgEl, entry, campoId) { // Guardar con campoId directo (sin _svg) para que get_consentimientos lo cuente dr[campoId] = svg; (window._mpSavedFirmas = window._mpSavedFirmas||{})[campoId] = svg; + // Fix 5: cachear hora en el momento de guardar para el resumen final + (window._mpTomaData = window._mpTomaData||{})[campoId] = { + hora: entry.hora_campo ? (dr[entry.hora_campo] || '') : '' + }; var turnoId = parseInt(widget.dataset.turno, 10); var formularioId = parseInt(widget.dataset.formulario, 10); @@ -1644,11 +1670,11 @@ function _guardarFirmaMP(widget, svg, msgEl, entry, campoId) { _mpMostrarResumen(entry.exam_type || 'Examen'); setTimeout(function() { try { window.parent.postMessage({ type: 'turneroFirmado' }, '*'); } catch(e) {} - }, 2200); + }, 2000); } else if (data.siguiente_toma_at) { + // Fix 2: pasar timestamp exacto; evita el redondeo de Math.round var targetMs = new Date(data.siguiente_toma_at.replace(' ', 'T')).getTime(); - var minsLeft = Math.max(1, Math.round((targetMs - Date.now()) / 60000)); - _mpIniciarCountdown(minsLeft, entry.next_label, entry.next_firma_id); + _mpIniciarCountdown(targetMs, entry.next_label, entry.next_firma_id); } else if (!entry.is_last) { var nw = entry.next_firma_id ? document.getElementById('fpw-' + entry.next_firma_id) : null; if (!nw) nw = document.querySelector('.firma-pro-widget:not([style*="display:none"])'); @@ -1662,9 +1688,10 @@ function _guardarFirmaMP(widget, svg, msgEl, entry, campoId) { _mpAutoFillHora(nw.dataset.campo); } else { // Sin más firmas pendientes → cerrar + // Fix 4: unificar delay con el caso data.completado (ambos 2000ms) setTimeout(function() { try { window.parent.postMessage({ type: 'turneroFirmado' }, '*'); } catch(e) {} - }, 1200); + }, 2000); } } }) @@ -1688,8 +1715,9 @@ function _mpPlayBeep() { } catch(e) {} } -function _mpIniciarCountdown(minutos, nextLabel, nextFirmaId) { - var targetMs = Date.now() + minutos * 60000; +// Fix 2: acepta timestamp (ms > 1e10) o minutos (número pequeño) +function _mpIniciarCountdown(targetMsOrMins, nextLabel, nextFirmaId) { + var targetMs = targetMsOrMins > 1e10 ? targetMsOrMins : Date.now() + targetMsOrMins * 60000; var box = document.getElementById('mp-countdown'); if (!box) { box = document.createElement('div'); @@ -1747,24 +1775,14 @@ function _mpMostrarResumen(examType) { Object.keys(window._muestrasMap).forEach(function(fid) { var entry = window._muestrasMap[fid]; if (!entry || entry.exam_type !== examType) return; - var horaEl = entry.hora_campo ? document.querySelector('[name="' + entry.hora_campo + '"]') : null; - var horaVal = horaEl ? horaEl.value : ''; - // Buscar campo resultado adyacente (previo al firma widget) - var fpw = document.getElementById('fpw-' + fid); - var resVal = ''; - if (fpw) { - var prev = fpw.previousElementSibling; - while (prev) { - var inp = prev.querySelector && prev.querySelector('input[type="number"],input[type="text"]'); - if (inp) { resVal = inp.value; break; } - prev = prev.previousElementSibling; - } + // Fix 5: usar hora cacheada al momento de guardar; evita traversal DOM frágil + var cached = window._mpTomaData && window._mpTomaData[fid]; + var horaVal = (cached && cached.hora) || ''; + if (!horaVal && entry.hora_campo) { + var horaEl = document.querySelector('[name="' + entry.hora_campo + '"]'); + horaVal = horaEl ? horaEl.value : ''; } - // Separador label para esta firma - var secLabel = entry.next_label || ('Toma ' + fid); - // Si tiene next_label del ANTERIOR, buscamos la label de esta entrada en el DOM - var sepEl = document.querySelector('[data-campo-id]'); - rows.push({ hora: horaVal, resultado: resVal, firmado: !!(window._mpSavedFirmas && window._mpSavedFirmas[fid]) }); + rows.push({ hora: horaVal, firmado: !!(window._mpSavedFirmas && window._mpSavedFirmas[fid]) }); }); } var wrap = document.createElement('div'); @@ -1772,10 +1790,9 @@ function _mpMostrarResumen(examType) { wrap.className = 'alert alert-success mt-4'; var rowsHtml = rows.length ? '' - + '' + + '' + rows.map(function(r) { return '' - + '' + ''; }).join('') + '
HoraResultado
Hora
' + (r.hora || '—') + '' + (r.resultado || '—') + '
' : ''; wrap.innerHTML = '
'