diff --git a/views/tramites.html b/views/tramites.html
index 367fd12..6b6dd17 100644
--- a/views/tramites.html
+++ b/views/tramites.html
@@ -438,9 +438,27 @@ function statusSlug(s){return (s||'').toLowerCase().replace(/\s+/g,'').replace(/
function statusBadge(s){return `${esc(s)}`;}
function yesnoBadge(v){return v?`${esc(v)}`:'—';}
+// Formatea decimal de horas como "h" o "h:mm" (bloques de 15 min).
+// Ej: 0.25 → "0:15", 1 → "1", 1.5 → "1:30", 2.75 → "2:45"
+function fmtHours(decimal){
+ const n = Math.round((parseFloat(decimal)||0) * 4) / 4; // snap a 15 min
+ const h = Math.floor(n);
+ const m = Math.round((n - h) * 60);
+ return m === 0 ? String(h) : `${h}:${String(m).padStart(2,'0')}`;
+}
function totalHours(r){
- if(!r.hours||!r.hours.length) return 0;
- return r.hours.reduce((s,h)=>s+(parseFloat(h.hrs)||0),0).toFixed(1);
+ if(!r.hours||!r.hours.length) return '0';
+ const total = r.hours.reduce((s,h)=>s+(parseFloat(h.hrs)||0),0);
+ return fmtHours(total);
+}
+// Opciones del dropdown de horas: bloques de 15 min de 0:15 a 12:00
+function hourBlockOptions(){
+ let out = '';
+ for (let q = 1; q <= 48; q++) {
+ const value = q * 0.25;
+ out += ``;
+ }
+ return out;
}
function venceAlert(fecha){
@@ -454,13 +472,13 @@ function venceAlert(fecha){
function buildRow(dept,r){
let cells='';
const invCell = `
${involucradosCell(r.involucrados)} | `;
- if(dept==='adm') cells=`${esc(r.institucion)||'—'} | ${esc(r.nombre)||'—'} | ${esc(r.cliente)||'—'} | ${esc(r.abogado)||'—'} | ${invCell}${statusBadge(r.estatus)} | ${esc(r.fechaSolicitud)||'—'} | ${totalHours(r)} h | `;
- if(dept==='corp') cells=`${esc(r.tipoDocumento)||'—'} | ${esc(r.nombre)||'—'} | ${esc(r.cliente)||'—'} | ${esc(r.abogado)||'—'} | ${invCell}${statusBadge(r.estatus)} | ${esc(r.fechaSolicitud)||'—'} | ${totalHours(r)} h | `;
- if(dept==='mig') cells=`${esc(r.tipoTramite)||'—'} | ${esc(r.cliente)||'—'} | ${esc(r.abogado)||'—'} | ${invCell}${yesnoBadge(r.docCompleta)} | ${yesnoBadge(r.permisoTrabajo)} | ${yesnoBadge(r.dependientes)} | ${statusBadge(r.estatus)} | ${esc(r.fechaSolicitud)||'—'} | ${fmtDateOnly(r.fechaVencimiento)||'—'}${venceAlert(r.fechaVencimiento)} | ${totalHours(r)} h | `;
+ if(dept==='adm') cells=`${esc(r.institucion)||'—'} | ${esc(r.nombre)||'—'} | ${esc(r.cliente)||'—'} | ${esc(r.abogado)||'—'} | ${invCell}${statusBadge(r.estatus)} | ${esc(r.fechaSolicitud)||'—'} | ${totalHours(r)} | `;
+ if(dept==='corp') cells=`${esc(r.tipoDocumento)||'—'} | ${esc(r.nombre)||'—'} | ${esc(r.cliente)||'—'} | ${esc(r.abogado)||'—'} | ${invCell}${statusBadge(r.estatus)} | ${esc(r.fechaSolicitud)||'—'} | ${totalHours(r)} | `;
+ if(dept==='mig') cells=`${esc(r.tipoTramite)||'—'} | ${esc(r.cliente)||'—'} | ${esc(r.abogado)||'—'} | ${invCell}${yesnoBadge(r.docCompleta)} | ${yesnoBadge(r.permisoTrabajo)} | ${yesnoBadge(r.dependientes)} | ${statusBadge(r.estatus)} | ${esc(r.fechaSolicitud)||'—'} | ${fmtDateOnly(r.fechaVencimiento)||'—'}${venceAlert(r.fechaVencimiento)} | ${totalHours(r)} | `;
if(dept==='lit'){
const esfera=r.esfera||'';
const inst=r.instancia||'';
- cells=`${esc(r.tipoProceso)||'—'} ${esc(r.juzgado)||'—'} · ${esc(r.circuito)||'—'} | ${esc(r.cliente)||'—'} | ${esc(r.abogado)||'—'} | ${invCell}${esfera?`${esfera}`:'—'} | ${inst?`${inst}`:'—'} | ${yesnoBadge(r.docCompleta)} | ${yesnoBadge(r.incidentes)} | ${yesnoBadge(r.amparo)} | ${statusBadge(r.estatus)} | ${esc(r.fechaSolicitud)||'—'} | ${fmtDateOnly(r.fechaTermino)||'—'}${venceAlert(r.fechaTermino)} | ${totalHours(r)} h | `;
+ cells=`${esc(r.tipoProceso)||'—'} ${esc(r.juzgado)||'—'} · ${esc(r.circuito)||'—'} | ${esc(r.cliente)||'—'} | ${esc(r.abogado)||'—'} | ${invCell}${esfera?`${esfera}`:'—'} | ${inst?`${inst}`:'—'} | ${yesnoBadge(r.docCompleta)} | ${yesnoBadge(r.incidentes)} | ${yesnoBadge(r.amparo)} | ${statusBadge(r.estatus)} | ${esc(r.fechaSolicitud)||'—'} | ${fmtDateOnly(r.fechaTermino)||'—'}${venceAlert(r.fechaTermino)} | ${totalHours(r)} | `;
}
const delBtn = CAN_DELETE ? `` : '';
const actions=` ${delBtn} | `;
@@ -495,7 +513,7 @@ function buildDetail(dept,r){
const obs=(r.obs||[]).map(o=>`${esc(o.texto)}
${esc(o.abogado)} · ${esc(o.fecha)}${o.autor_email?` · ${esc(o.autor_email.split('@')[0])}`:''}`).join('');
const lastUpd=r.obs&&r.obs.length?`Última actualización: ${esc(r.obs[r.obs.length-1].fecha)}
`:'';
- const hrs=(r.hours||[]).map(h=>`${esc(h.abogado)}${h.hrs} h · ${esc(h.fecha)}`).join('');
+ const hrs=(r.hours||[]).map(h=>`${esc(h.abogado)}${fmtHours(h.hrs)} · ${esc(h.fecha)}`).join('');
const totalH=totalHours(r);
const statusSel=`