97 lines
5.0 KiB
HTML
97 lines
5.0 KiB
HTML
<!doctype html>
|
|
<html lang="es">
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
<title>Ver acta — HBOX</title>
|
|
<script src="../js/tema.js"></script>
|
|
<link rel="stylesheet" href="acta.css">
|
|
<style>
|
|
.doc{background:var(--tarjeta);border:1px solid var(--linea);border-radius:12px;padding:18px}
|
|
.hdr{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:10px;margin-bottom:12px}
|
|
.hdr .c{background:var(--papel);border:1px solid var(--linea);border-radius:9px;padding:8px 10px}
|
|
.hdr .l{font-size:11px;color:var(--tinta2);text-transform:uppercase;letter-spacing:.05em}
|
|
.hdr .v{font-weight:700;font-size:15px}
|
|
.resu{font-weight:800}
|
|
.resu.OK{color:var(--ok)} .resu.FALLA{color:var(--falla)}
|
|
.sec{margin-top:14px} .sec h3{font-size:14px;margin:0 0 4px;color:var(--naranja)}
|
|
.row{display:flex;gap:10px;padding:5px 0;border-top:1px solid var(--linea);font-size:14px}
|
|
.row .a{flex:0 0 auto;font-weight:700}
|
|
.row .t{flex:1}
|
|
.si{color:var(--ok);font-weight:700} .no{color:var(--tinta2)}
|
|
@media print{.barra,.top .noprint,button{display:none} body{background:#fff}}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<div class="wrap">
|
|
<header class="top"><h1 id="titulo">Acta</h1><p id="sub">Cargando…</p></header>
|
|
<div style="display:flex;justify-content:space-between;margin:2px 0 10px">
|
|
<a class="volver" href="../tableros/actas/">← Estado de actas</a>
|
|
<a class="volver noprint" href="#" onclick="window.print();return false">Imprimir / PDF</a>
|
|
</div>
|
|
<div id="cont"></div>
|
|
</div>
|
|
<script>
|
|
const qs = new URLSearchParams(location.search);
|
|
const tipo = qs.get('tipo') || '';
|
|
const serie = qs.get('serie') || '';
|
|
const cont = document.getElementById('cont');
|
|
const TITULOS = { 'prueba-v5':'Acta de prueba V5', 'prueba-v4':'Acta de prueba V4', 'modulo-ard':'Acta de módulo ArduSimple', 'modulo-4g':'Acta de módulo 4G', 'integracion':'Acta de integración RTK + 4G', 'ensamble':'Acta de ensamble — unidad HBOX' };
|
|
const COMP = { einar:'EinarBoard', ard:'simpleRTK2B Pro (ArduSimple)', modem:'4G NTRIP Master' };
|
|
|
|
function esc(s){ const d=document.createElement('div'); d.textContent=s==null?'':String(s); return d.innerHTML; }
|
|
function fmt(iso){ return iso? iso.replace('T',' ').slice(0,16):''; }
|
|
|
|
function render(a){
|
|
document.getElementById('titulo').textContent = (TITULOS[tipo]||'Acta') + ' — ' + esc(a.serie);
|
|
document.getElementById('sub').textContent = 'Registro firmado · Helgen Technologies';
|
|
let h = '<div class="doc"><div class="hdr">'
|
|
+ '<div class="c"><div class="l">Serie</div><div class="v">'+esc(a.serie)+'</div></div>'
|
|
+ '<div class="c"><div class="l">Técnico</div><div class="v">'+esc(a.tecnico||'—')+'</div></div>'
|
|
+ '<div class="c"><div class="l">Resultado</div><div class="v resu '+esc(a.resultado)+'">'+esc(a.resultado||'—')+'</div></div>'
|
|
+ '<div class="c"><div class="l">Fecha</div><div class="v">'+esc(fmt(a._recibido))+'</div></div>'
|
|
+ '<div class="c"><div class="l">Usuario</div><div class="v">'+esc(a._usuario||'—')+'</div></div>'
|
|
+ '</div>';
|
|
if(a.componentes){
|
|
h += '<div class="hdr">' + Object.keys(a.componentes).map(k=>'<div class="c"><div class="l">'+esc(COMP[k]||k)+'</div><div class="v">'+esc(a.componentes[k])+'</div></div>').join('') + '</div>';
|
|
}
|
|
// agrupar respuestas por sección (prefijo sN_)
|
|
const R = a.respuestas || {};
|
|
const keys = Object.keys(R).sort((x,y)=>{
|
|
const px=x.match(/^s(\d+)_(\d+)/), py=y.match(/^s(\d+)_(\d+)/);
|
|
if(px&&py){ return (+px[1]-+py[1]) || (+px[2]-+py[2]); } return x<y?-1:1;
|
|
});
|
|
let curSec=-1;
|
|
keys.forEach(k=>{
|
|
const m=k.match(/^s(\d+)_/); const sec=m?+m[1]:0;
|
|
if(sec!==curSec){ if(curSec!==-1) h+='</div>'; h+='<div class="sec"><h3>Sección '+(sec+1)+'</h3>'; curSec=sec; }
|
|
const it=R[k]; const val=it.val;
|
|
let vista;
|
|
if(val===true) vista='<span class="si">Sí</span>';
|
|
else if(val===false) vista='<span class="no">— No marcado</span>';
|
|
else vista = val==='' ? '<span class="no">—</span>' : esc(val);
|
|
h+='<div class="row"><div class="t">'+ (it.lbl||k) +'</div><div class="a">'+vista+'</div></div>';
|
|
});
|
|
if(curSec!==-1) h+='</div>';
|
|
h += '<div class="sec"><div class="row"><div class="t">Conformidad del técnico</div><div class="a">'
|
|
+ (a.conforme?'<span class="si">Confirmado</span>':'<span class="no">—</span>') + '</div></div></div>';
|
|
h += '</div>';
|
|
cont.innerHTML = h;
|
|
}
|
|
|
|
async function cargar(){
|
|
if(!tipo || !serie){ cont.innerHTML='<div class="borrador">Falta indicar tipo y serie.</div>'; return; }
|
|
try{
|
|
const r = await fetch('/api/acta?tipo='+encodeURIComponent(tipo)+'&serie='+encodeURIComponent(serie));
|
|
const j = await r.json();
|
|
if(!j.ok) throw new Error(j.error||'error');
|
|
if(!j.exists){ cont.innerHTML='<div class="borrador">No hay un acta registrada para <b>'+esc(serie)+'</b> todavía.</div>';
|
|
document.getElementById('sub').textContent='Sin registro'; return; }
|
|
render(j.acta);
|
|
}catch(e){ cont.innerHTML='<div class="borrador">No se pudo cargar: '+esc(e.message)+'</div>'; }
|
|
}
|
|
cargar();
|
|
</script>
|
|
</body>
|
|
</html>
|