PubliPrintMX
Pedidos y control de producción
'; try{const d=await window.claude.use("downloads");await d.save({filename:"orden-"+o.folio+".html",data:html});log("Descargó la orden #"+o.folio);toast("Archivo guardado: ábrelo y presiona Imprimir")} catch(e){toast("No se pudo descargar la orden")} } /* ===== Acceso contra el servidor (api.php) ===== */ let ME_USER=null,SETUP=false,NEEDKEY=false; function onLogin(r){ME_USER=r.user;SESS=r.user.usuario;api.csrf=r.csrf;adminLvl=r.user.rol==="admin";DB.setAuth(true); if(!$("#ver"))$("#conf").insertAdjacentHTML("beforeend",'

Versión '+esc(r.version||"")+' · servidor propio

')} window.onAuthLost=()=>{if(SESS){SESS="";ME_USER=null;ROLE=null;logged=false;myDay=null;$$("section").forEach(x=>x.classList.remove("on"));toast("Tu sesión terminó. Inicia sesión de nuevo.");route()}}; async function endSession(){ log("Cerró sesión");await logQ; try{await api("logout",{})}catch(e){} DB.setAuth(false);SESS="";ME_USER=null;ROLE=null;logged=false;myDay=null;USERS={}; $$("section").forEach(x=>x.classList.remove("on"));route(); } async function identify(){ db=await window.claude.use("db");window.DB=db; try{const r=await api("me");if(r.user){onLogin(r)}else{SETUP=!!r.setup;NEEDKEY=!!r.needkey}}catch(e){$("#lerr").textContent=e.message} db.collection("usuarios").onSnapshot(s=>{USERS={};s.docs.forEach(d=>USERS[d.id]=d.data());usersReady=true;route();if($("#users").classList.contains("on"))renderUsers()},()=>{}); route(); } function route(){ const u=SESS&&(USERS[SESS]||ME_USER),ok=u&&u.activo!==false&&ROLES[u.rol]; if(SESS&&ROLE&&!ok){endSession();return} ME=SESS;ROLE=ok?u.rol:null;MYNAME=ok?(u.nombre||SESS):""; $("#login").hidden=!!ROLE;$("#app").hidden=!ROLE; $("#lnl").hidden=!SETUP;$("#lkl").hidden=!(SETUP&&NEEDKEY);$("#lsetup").hidden=!SETUP; $("#lsetup").textContent="Primera configuración: crea la cuenta del administrador."; $("#lb").textContent=SETUP?"Crear administrador":"Iniciar sesión"; if(ROLE)applyRole(); } $("#lf2").addEventListener("submit",async e=>{ e.preventDefault();const err=m=>{$("#lerr").textContent=m};err(""); const u=$("#lu").value.trim().toLowerCase(),p=$("#lp").value; if(!/^[a-z0-9._-]{3,30}$/.test(u))return err("Usuario: de 3 a 30 caracteres (letras, números, punto, guion)."); if(SETUP&&p.length<8)return err("La contraseña debe tener al menos 8 caracteres."); $("#lb").disabled=true; try{const r=await api(SETUP?"setup":"login",{usuario:u,password:p,nombre:$("#ln").value.trim(),clave:$("#lkey").value,keep:$("#lk").checked}); SETUP=false;onLogin(r);$("#lp").value="";route()} catch(x){err(x.message||"No se pudo iniciar sesión.")} finally{$("#lb").disabled=false} }); $("#ulist").addEventListener("click",async e=>{ const t=e.target,{pw,rm}=t.dataset; try{ if(t.id==="nadd"){ const u=$("#nu").value.trim().toLowerCase(),pwd=$("#np").value; if(!/^[a-z0-9._-]{3,30}$/.test(u))return toast("Usuario no válido (3 a 30: letras, números, . - _)"); if(USERS[u])return toast("Ese usuario ya existe"); if(pwd.length<8)return toast("La contraseña debe tener al menos 8 caracteres"); const rol=$("#nr").value;await api("useradd",{usuario:u,nombre:$("#nn").value.trim(),rol,password:pwd}); log("Creó al usuario "+u+" ("+ROLES[rol]+")");toast("Usuario creado"); }else if(pw){ const n=await ask("Nueva contraseña temporal para @"+pw+" (mínimo 8 caracteres):",true);if(!n)return; if(n.length<8)return toast("La contraseña debe tener al menos 8 caracteres"); await api("setpw",{usuario:pw,nueva:n});log("Restableció la contraseña de "+pw);toast("Contraseña restablecida"); }else if(rm){ if(rm===ME)return toast("No puedes eliminar tu propia cuenta"); if(await ask("¿Eliminar al usuario @"+rm+"?")){await api("userdel",{usuario:rm});log("Eliminó al usuario "+rm)} } }catch(x){toast(x.message||"No se pudo guardar el cambio")} }); $("#pwf").addEventListener("submit",async e=>{ e.preventDefault();const m=$("#pm");m.textContent="";const n=$("#pn").value; if(n.length<8)return m.textContent="La nueva contraseña debe tener al menos 8 caracteres."; if(n!==$("#pr").value)return m.textContent="Las contraseñas no coinciden."; try{await api("setpw",{actual:$("#pa").value,nueva:n});e.target.reset();log("Cambió su contraseña");toast("Contraseña actualizada")} catch(x){m.textContent=x.message||"No se pudo actualizar la contraseña."} }); resetForm();init();