// ══════════════════════════════════════════════════════════ // REDIL — Sistema de Gestión v5.1 // ══════════════════════════════════════════════════════════ var APP={user:null,mod:'',charts:{},hermanos:[],contactos:[],formUrl:'',formUrlPublic:'',config:{}}; const TIPO_REUNION=['Mixta (Reunión Regular)','Niños','Jóvenes','Mujeres','Profesionales']; const METODO_REPORTE=['Digital','Físico']; var SESSION_KEY='ir_sess_v51',SESSION_USER_KEY='ir_user_v51',SESSION_TIME_KEY='ir_time_v51'; var LOGO_KEY='ir_logo_v5',TOTALAPP_LOGO_KEY='ir_totalapp_logo_v5'; // ── DICCIONARIO DE TÍTULOS DE MÓDULOS ────────────────────── var TITLES = { dashboard: 'Dashboard General', reportes: 'Reporte de Grupos', reporteDigital: 'Reporte Digital', formulario: 'Formulario Externo', generador: 'Generador de Reportes', hermanos: 'Hermanos Líderes', cargaMasiva: 'Carga Masiva', supervisores: 'Supervisores de Sector', pastores: 'Pastores de Zona', ayudapastor: 'Ayuda de Pastor', seguimientos: 'Seguimientos', privilegios: 'Privilegios', diezmos: 'Control de Diezmos', gastos: 'Control de Gastos', inventario: 'Inventario', insumos: 'Insumos', envio: 'Centro de Envíos', contactos: 'Tabla de Contactos', usuarios: 'Usuarios', bitacora: 'Bitácora de Accesos', configuracion: 'Configuración', cronograma: 'Cronograma', bautizos: 'Bautizos en Agua' }; function saveSession(token,user,inactMin){[localStorage,sessionStorage].forEach(function(s){try{s.setItem(SESSION_KEY,token);s.setItem(SESSION_USER_KEY,JSON.stringify(user));s.setItem(SESSION_TIME_KEY,Date.now().toString());s.setItem('ir_inact_min',String(inactMin||60));}catch(e){}});} function getToken(){return localStorage.getItem(SESSION_KEY)||sessionStorage.getItem(SESSION_KEY);} function permisoEditar(){return APP.user&&APP.user.PuedeEditar!=='NO';} function clearSession(){var token=localStorage.getItem(SESSION_KEY)||sessionStorage.getItem(SESSION_KEY);if(token)try{call('destroySession',{token:token},function(){});}catch(e){}[SESSION_KEY,SESSION_USER_KEY,SESSION_TIME_KEY,'ir_inact_min'].forEach(function(k){try{localStorage.removeItem(k);sessionStorage.removeItem(k);}catch(e){}});} function getInactMin(){return parseInt(localStorage.getItem('ir_inact_min')||'60',10)||60;} function call(action,payload,cb){ payload=payload||{}; var token=localStorage.getItem(SESSION_KEY)||sessionStorage.getItem(SESSION_KEY); if(token && !payload.token) payload.token=token; try{ var url=window.location.origin+'/api/dispatch'; fetch(url,{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({action:action,payload:payload,token:token})}) .then(function(r){return r.json();}) .then(function(r){if(cb)cb(null,r);}) .catch(function(e){if(cb)cb(e,null);try{toast('Error: '+(e.message||e),'er');}catch(ex){}}); }catch(e){if(cb)cb(e,null);} } function g(id){var el=document.getElementById(id);return el?(el.value!==undefined?el.value:el.textContent):'';} function esc(s){return String(s||'').replace(/&/g,'&').replace(//g,'>').replace(/"/g,'"').replace(/'/g,''');} function num(v){return parseFloat(String(v).replace(/[^0-9.\-]/g,''))||0;} function fmtQ(v){return 'Q '+Number(v||0).toLocaleString('es-GT',{minimumFractionDigits:2,maximumFractionDigits:2});} function fmtD(s){if(!s)return'--';try{var d=new Date(s+'T12:00:00');return d.toLocaleDateString('es-GT');}catch(e){return s;}} function fmtF(s){if(!s)return'';try{var d=new Date(s+'T12:00:00');return d.toLocaleDateString('es-GT');}catch(e){return s;}} function today(){var d=new Date();return d.getFullYear()+'-'+String(d.getMonth()+1).padStart(2,'0')+'-'+String(d.getDate()).padStart(2,'0');} function todayStr(){return today();} function fom(){var d=new Date();return d.getFullYear()+'-'+String(d.getMonth()+1).padStart(2,'0')+'-01';} function fom30(){var d=new Date();d.setDate(d.getDate()-30);return d.getFullYear()+'-'+String(d.getMonth()+1).padStart(2,'0')+'-'+String(d.getDate()).padStart(2,'0');} function mesNombre(s){if(!s)return'';var m=['Enero','Febrero','Marzo','Abril','Mayo','Junio','Julio','Agosto','Septiembre','Octubre','Noviembre','Diciembre'];try{return m[new Date(s+'T12:00:00').getMonth()];}catch(e){return s;}} function exportXLS(data,name,file){ loading(true); call('exportExcel',{data:data,nombreHoja:name,nombreArchivo:file},function(_,res){ loading(false); if(res&&res.ok){ if(res.xlsx_base64){ try{ var bin=atob(res.xlsx_base64); var bytes=new Uint8Array(bin.length); for(var i=0;i*{box-sizing:border-box}body{font-family:Arial,Helvetica,sans-serif;margin:0;padding:20px;background:#f5f6fa;color:#222}' +'@page{size:letter landscape;margin:10mm}' +'.hdr{background:linear-gradient(135deg,#1a3a5c,#2563a8);color:#fff;padding:14px 18px;border-radius:8px;margin-bottom:14px;display:flex;justify-content:space-between;align-items:center;-webkit-print-color-adjust:exact;print-color-adjust:exact}' +'.hdr h1{margin:0;font-size:18px}.hdr .sub{font-size:11px;opacity:.85;margin-top:2px}' +'.hdr .badge{background:rgba(255,255,255,.2);padding:4px 12px;border-radius:99px;font-size:11px;font-weight:700}' +'table{width:100%;border-collapse:collapse;background:#fff;border-radius:8px;overflow:hidden;box-shadow:0 2px 8px rgba(0,0,0,.06)}' +'thead th{background:#1a3a5c;color:#fff;font-size:11px;text-transform:uppercase;letter-spacing:.3px;padding:8px 10px;text-align:left;-webkit-print-color-adjust:exact;print-color-adjust:exact}' +'tbody td{padding:7px 10px;font-size:11px;border-bottom:1px solid #eef0f5}' +'tbody tr:nth-child(even){background:#f8fafc}' +'tbody tr{page-break-inside:avoid}' +'.grp td{background:#e2e8f0;font-weight:800;font-size:11px;color:#1a3a5c;padding:7px 10px}' +'.ftr{margin-top:12px;font-size:10px;color:#888;text-align:center}' +'@media print{body{background:#fff;padding:0}.hdr{border-radius:0}table{box-shadow:none}}' +''; } // Cuerpo del reporte (encabezado + tabla + pie). Se reutiliza para imprimir y para PDF. function _tablaReporteCuerpo(titulo,columnas,filas,grupoPor){ var sysName=(APP.config&&APP.config.nombre)||'Iglesia Restauracion'; var hoy=new Date().toLocaleDateString('es-GT'); var grupos=[{titulo:'',filas:filas}]; if(grupoPor){ var map={}; filas.forEach(function(r){var k=r[grupoPor]||'Sin asignar';if(!map[k])map[k]=[];map[k].push(r);}); grupos=Object.keys(map).sort().map(function(k){return {titulo:k,filas:map[k]};}); } var thead=''+columnas.map(function(c){return ''+esc(c.label)+'';}).join('')+''; var body=''; grupos.forEach(function(g){ if(g.titulo){body+=''+esc(grupoPor)+': '+esc(g.titulo)+' ('+g.filas.length+')';} g.filas.forEach(function(r){ body+=''+columnas.map(function(c){var v=r[c.key];if(v===undefined||v===null)v='';return ''+esc(v)+'';}).join('')+''; }); }); return '

'+esc(titulo)+'

'+esc(sysName)+' · '+hoy+'
'+filas.length+' registros
' +''+thead+''+body+'
' +'
'+esc(sysName)+'
'; } function imprimirTabla(titulo,columnas,filas,grupoPor){ if(!filas||!filas.length){toast('No hay datos para imprimir','wa');return;} var w=window.open('','_blank','width=1000,height=700'); if(!w){toast('Activa ventanas emergentes','wa',5000);return;} w.document.write(''+esc(titulo)+'' +_tablaReporteEstilo()+'' +_tablaReporteCuerpo(titulo,columnas,filas,grupoPor) +'