Откат до рабочей версии без Supabase

This commit is contained in:
Dauren777 2026-06-10 04:22:04 +00:00
parent cf4292ba9d
commit 280aaf6113
2 changed files with 11 additions and 60 deletions

View File

@ -4,7 +4,6 @@
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>ПАБ — Система</title>
<script src="https://cdn.jsdelivr.net/npm/@supabase/supabase-js@2/dist/umd/supabase.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.7/dist/chart.umd.min.js"></script>
<style>
*{box-sizing:border-box;margin:0;padding:0}
@ -87,52 +86,15 @@ td{padding:8px 12px;border-bottom:1px solid #F2F4F7}tr:hover td{background:#F2F4
</div>
<script>
var SB_URL="https://znexbjafkvyjffffbhlf.supabase.co";
var SB_KEY="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6InpuZXhiamFma3Z5amZmZmZiaGxmIiwicm9sZSI6InNlcnZpY2Vfcm9sZSIsImlhdCI6MTc4MDY0NDE4MiwiZXhwIjoyMDk2MjIwMTgyfQ.5pOYTkL5eCmpSHBY3EwKof6NVKt7tL4Fn8xUAKM8itE";
var SB=supabase.createClient(SB_URL,SB_KEY);
var U,editId,lastSubmitted;
var U,editId,lastSubmitted,vrc=6;
try{U=JSON.parse(sessionStorage.getItem("pab_user"));if(!U)location.href="index.html"}catch(e){location.href="index.html"}
document.getElementById("dn").textContent=U.login;
function isA(){return U&&U.login==="admin"}
// ===== DATA: Supabase REST API + localStorage =====
function getU(){return JSON.parse(localStorage.getItem("pab_users")||"{}")}
function saveU(d){localStorage.setItem("pab_users",JSON.stringify(d))}
function getU(){try{return JSON.parse(localStorage.getItem("pab_users")||"{}")}catch(e){return{}}}
function allU(){var r=getU();r.admin={pass:"admin",name:"Администратор",role:"Руководитель",email:"admin@telecom.kz",branch:"АО «Казахтелеком»",dept:"ЦА",region:"Центральный",oblast:"—",city:"г. Астана"};return r}
function getA(){return JSON.parse(localStorage.getItem("pab_audits")||"[]")}
function getA(){try{return JSON.parse(localStorage.getItem("pab_audits")||"[]")}catch(e){return[]}}
function saveA(d){localStorage.setItem("pab_audits",JSON.stringify(d))}
// Supabase REST API helpers
async function sbFetch(method,table,body){
try{
var url=SB_URL+"/rest/v1/"+table;
var headers={"apikey":SB_KEY,"Authorization":"Bearer "+SB_KEY,"Content-Type":"application/json","Prefer":"return=minimal"};
var opts={method:method,headers:headers};
if(method==="PATCH"||method==="POST"){headers["Prefer"]="resolution=merge-duplicates";opts.body=JSON.stringify(body)}
var r=await fetch(url,opts);
if(!r.ok){console.error("SB error:",r.status,await r.text())}else{console.log("SB OK:",method,table)}
return r;
}catch(e){console.error("SB fetch error:",e)}
}
async function sbUpsert(table,data){await sbFetch("POST",table,data)}
async function sbDeleteT(table,col,val){try{await fetch(SB_URL+"/rest/v1/"+table+"?"+col+"=eq."+encodeURIComponent(val),{method:"DELETE",headers:{"apikey":SB_KEY,"Authorization":"Bearer "+SB_KEY}})}catch(e){}}
// Sync
async function syncFromSB(){
try{
var lu=getU();for(var k in lu){await sbUpsert("users",{login:k,pass:lu[k].pass,name:lu[k].name,email:lu[k].email,role:lu[k].role,freq:lu[k].freq,branch:lu[k].branch,dept:lu[k].dept,region:lu[k].region,oblast:lu[k].oblast,city:lu[k].city})}
var la=getA();for(var i=0;i<la.length;i++){var a=la[i];await sbUpsert("audits",{id:a.id,number:a.number,date:a.date,location:a.location,region:a.region,work_type:a.workType,worker_count:a.workerCount,observer:a.observer,observer_role:a.observerRole,overall_safe:a.overallSafe,categories:a.categories,total_violations:a.totalViolations,dialogue:a.dialogue,docs:a.docs,created_by:a.createdBy,created_at:a.createdAt})}
var su=await fetch(SB_URL+"/rest/v1/users?select=*",{headers:{"apikey":SB_KEY,"Authorization":"Bearer "+SB_KEY}});if(su.ok){var suj=await su.json();var um={};suj.forEach(function(x){um[x.login]={pass:x.pass,name:x.name,email:x.email,role:x.role,freq:x.freq,branch:x.branch,dept:x.dept,region:x.region,oblast:x.oblast,city:x.city}});saveU(um)}
var sa=await fetch(SB_URL+"/rest/v1/audits?select=*&order=created_at.desc",{headers:{"apikey":SB_KEY,"Authorization":"Bearer "+SB_KEY}});if(sa.ok){var saj=await sa.json();var am=[];saj.forEach(function(x){am.push({id:x.id,number:x.number,date:x.date,location:x.location,region:x.region,workType:x.work_type,workerCount:x.worker_count,observer:x.observer,observerRole:x.observer_role,overallSafe:x.overall_safe,categories:x.categories,totalViolations:x.total_violations,dialogue:x.dialogue,docs:x.docs,createdBy:x.created_by,createdAt:x.created_at})});saveA(am)}
}catch(e){console.error("Sync error:",e)}
}
syncFromSB().then(function(){rHS()});
// ===== SYNC ON LOAD =====
syncFromSB().then(function(){rHS()});
// ===== QUOTA =====
function gq(role){return{c:1,p:"month",l:"1 раз в месяц"}}
function gq(role){var q={c:1,p:"month",l:"1 раз в месяц"};return q}
function getUserQuota(u){if(u.freq){var p=u.freq.split(",");if(p.length===2)return{c:parseInt(p[0]),p:p[1],l:parseInt(p[0])+" раз(а) в "+(p[1]==="month"?"месяц":p[1]==="quarter"?"квартал":"полгода")}}return gq(u.role)}
function gp(p){var n=new Date();if(p==="month")return{s:new Date(n.getFullYear(),n.getMonth(),1),l:n.toLocaleString("ru",{month:"long",year:"numeric"})};if(p==="quarter"){var q=Math.floor(n.getMonth()/3);return{s:new Date(n.getFullYear(),q*3,1),l:(q+1)+"-й квартал "+n.getFullYear()}}return{s:new Date(n.getFullYear(),n.getMonth()<6?0:6,1),l:(n.getMonth()<6?1:2)+"-е полугодие "+n.getFullYear()}}
@ -195,18 +157,13 @@ function rVL(){var c=document.getElementById("vlc");if(!c)return;var a=getA(),td
function rHS(){var a=getA(),tb=document.getElementById("hbd");if(!tb)return;tb.innerHTML=a.length===0?"<tr><td colspan=\"7\" style=\"text-align:center;padding:20px;color:#5B6573\">Нет записей</td></tr>":a.map(function(x){var ab=isA()?"<a style=\"color:#00B4D8;cursor:pointer;font-weight:600\" onclick=\"editA("+x.id+")\">✏️</a> <button class=\"btn bd\" style=\"padding:4px 8px;font-size:11px\" onclick=\"delA("+x.id+")\">🗑️</button>":"чтение";return"<tr><td>"+(x.number||"—")+"</td><td>"+x.date+"</td><td>"+x.location+"</td><td>"+x.observer+"</td><td><span class=\"badge "+(x.overallSafe?"bs":"bd2")+"\">"+(x.overallSafe?"Безопасно":"Нарушения")+"</span></td><td>"+(x.totalViolations||0)+"</td><td>"+ab+"</td></tr>"}).join("")}
async function uploadPhoto(file){var fn=Date.now()+"_"+file.name.replace(/[^a-zA-Z0-9._-]/g,"_");try{var r=await fetch(SB_URL+"/storage/v1/object/photos/"+fn,{method:"POST",headers:{"apikey":SB_KEY,"Authorization":"Bearer "+SB_KEY,"Content-Type":file.type},body:file});if(r.ok){return SB_URL+"/storage/v1/object/public/photos/"+fn}}catch(e){}return null}
async async function submitAudit(){
function submitAudit(){
if(editId&&!isA()){alert("Только администратор может редактировать");return}
var loc=document.getElementById("pl").value.trim();if(!loc){alert("Укажите место проведения");return}
// Upload photos
var pf=document.getElementById("pfiles");var photoUrls=[];if(pf&&pf.files.length>0){for(var i=0;i<pf.files.length;i++){var url=await uploadPhoto(pf.files[i]);if(url)photoUrls.push(url)}}
var cats={},tv=0;CATS.forEach(function(cat){var ch=[];cat.items.forEach(function(item,i){var cb=document.getElementById("cb-"+cat.id+"-"+i);if(cb&&cb.checked)ch.push({item:item})});cats[cat.id]={items:ch,allSafe:ch.length===0};tv+=ch.length});
var dl=[];if(document.getElementById("d0").checked)dl.push("Работник привёл примеры безопасных действий");if(document.getElementById("d1").checked)dl.push("Были обсуждены риски / проблемы");if(document.getElementById("d2").checked)dl.push("Определены корректирующие меры");if(document.getElementById("d3").checked)dl.push("Предложения работника зафиксированы");
var e={id:editId||Date.now(),number:document.getElementById("pn").value.trim(),date:document.getElementById("pd").value,location:loc,region:document.getElementById("pr").value,workType:document.getElementById("pw").value.trim(),workerCount:parseInt(document.getElementById("pc").value)||1,observer:document.getElementById("po").value.trim()||U.name,observerRole:document.getElementById("por").value.trim(),overallSafe:document.getElementById("os").classList.contains("sf"),categories:cats,totalViolations:tv,dialogue:dl,photos:photoUrls,createdBy:U.login,createdAt:new Date().toISOString()};
var audits=getA();if(editId){audits=audits.map(function(a){return a.id===editId?e:a});editId=null}else{audits.unshift(e)}saveA(audits);
sbUpsert("audits",{id:e.id,number:e.number,date:e.date,location:e.location,region:e.region,work_type:e.workType,worker_count:e.workerCount,observer:e.observer,observer_role:e.observerRole,overall_safe:e.overallSafe,categories:e.categories,total_violations:e.totalViolations,dialogue:e.dialogue,docs:e.docs,photos:e.photos,created_by:e.createdBy,created_at:e.createdAt}).then(function(r){console.log("Supabase save:",r.error||"OK")});lastSubmitted=e;
var e={id:editId||Date.now(),number:document.getElementById("pn").value.trim(),date:document.getElementById("pd").value,location:loc,region:document.getElementById("pr").value,workType:document.getElementById("pw").value.trim(),workerCount:parseInt(document.getElementById("pc").value)||1,observer:document.getElementById("po").value.trim()||U.name,observerRole:document.getElementById("por").value.trim(),overallSafe:document.getElementById("os").classList.contains("sf"),categories:cats,totalViolations:tv,dialogue:dl,createdBy:U.login,createdAt:new Date().toISOString()};
var audits=getA();if(editId){audits=audits.map(function(a){return a.id===editId?e:a});editId=null}else{audits.unshift(e)}saveA(audits);lastSubmitted=e;
document.getElementById("sd").innerHTML="<b>Бланк №"+(e.number||"—")+"</b> | "+e.date+" | "+(e.overallSafe?"БЕЗОПАСНО":"НАРУШЕНИЙ: "+e.totalViolations);document.getElementById("fs").style.display="block";setTimeout(function(){document.getElementById("fs").style.display="none"},20000);
resetF();
rVL();
@ -221,7 +178,7 @@ function resetF(){
function exportCSV(){var a=getA();if(a.length===0){alert("Нет данных");return}var all=allU(),h="Бланк №;Дата;Место;Наблюдатель;Должность;Филиал;Регион;Город;Статус;Нарушений",rs=a.map(function(x){var u=all[x.createdBy]||{};return(x.number||"")+";"+x.date+";"+x.location+";"+x.observer+";"+(x.observerRole||"")+";"+(u.branch||"")+";"+(u.region||"")+";"+(u.city||"")+";"+(x.overallSafe?"Безопасно":"Нарушения")+";"+(x.totalViolations||0)}),csv="\uFEFF"+h+"\n"+rs.join("\n"),bl=new Blob([csv],{type:"text/csv"}),ur=URL.createObjectURL(bl),dl=document.createElement("a");dl.href=ur;dl.download="pab.csv";dl.click();URL.revokeObjectURL(ur)}
function editA(id){if(!isA()){alert("Только админ");return}alert("Редактирование: аудит #"+id)}
function delA(id){if(!isA()){alert("Только админ");return}if(!confirm("Удалить?"))return;saveA(getA().filter(function(a){return a.id!==id}));sbDeleteT("audits","id",id);rHS()}
function delA(id){if(!isA()){alert("Только админ");return}if(!confirm("Удалить?"))return;saveA(getA().filter(function(a){return a.id!==id}));rHS()}
function downloadFullCSV(){var a=getA();if(a.length===0){alert("Нет данных");return}var all=allU(),h="Бланк №;Дата;Место;Наблюдатель;Филиал;Регион;Статус;Нарушений",rs=a.map(function(x){var u=all[x.createdBy]||{};return(x.number||"")+";"+x.date+";"+x.location+";"+x.observer+";"+(u.branch||"")+";"+(u.region||"")+";"+(x.overallSafe?"Безопасно":"Нарушения")+";"+(x.totalViolations||0)}),csv="\uFEFF"+h+"\n"+rs.join("\n"),bl=new Blob([csv],{type:"text/csv"}),ur=URL.createObjectURL(bl),dl=document.createElement("a");dl.href=ur;dl.download="pab-full.csv";dl.click();URL.revokeObjectURL(ur)}
function showAllUsers(){if(!isA())return;var all=allU(),h="<h2>👥 Пользователи</h2><table style=\"width:100%;border-collapse:collapse;font-size:13px\"><tr style=\"background:#0F1218;color:#fff\"><th>Логин</th><th>ФИО</th><th>Должность</th><th>Филиал</th><th>Регион</th><th>Город</th></tr>";for(var k in all){var u=all[k];h+="<tr><td>"+k+(k==="admin"?" ⭐":"")+"</td><td>"+u.name+"</td><td>"+u.role+"</td><td>"+(u.branch||"—")+"</td><td>"+(u.region||"—")+"</td><td>"+(u.city||"—")+"</td></tr>"}h+="</table>";var w=window.open("","_blank","width=800,height=500");w.document.write("<!DOCTYPE html><html><head><meta charset=\"utf-8\"><title>Пользователи</title><style>body{font:14px/1.5 Arial;max-width:800px;margin:20px auto;padding:20px}</style></head><body>"+h+"</body></html>");w.document.close()}
function downloadSummaryHTML(){var a=getA(),all=allU(),t=a.length;var w=window.open("","_blank","width=800,height=600");w.document.write("<!DOCTYPE html><html><head><meta charset=\"utf-8\"><title>Отчёт ПАБ</title><style>body{font:14px/1.5 Arial;max-width:900px;margin:20px auto;padding:20px}h1{font-size:22px}h2{font-size:16px;margin-top:20px}table{width:100%;border-collapse:collapse;font-size:12px}th{background:#0F1218;color:#fff;padding:8px}td{padding:6px 8px;border-bottom:1px solid #E2E6EB}@media print{button{display:none}}</style></head><body><button onclick=\"window.print()\" style=\"padding:8px 16px;margin-bottom:16px\">🖨️ Печать</button><h1>📊 Сводный отчёт ПАБ</h1><p>Сформирован: "+new Date().toLocaleString("ru")+" | Всего аудитов: "+t+"</p><h2>📋 Аудиты</h2><table><tr><th></th><th>Дата</th><th>Место</th><th>Наблюдатель</th><th>Статус</th><th>Нарушений</th></tr>"+a.map(function(x){return"<tr><td>"+(x.number||"—")+"</td><td>"+x.date+"</td><td>"+x.location+"</td><td>"+x.observer+"</td><td>"+(x.overallSafe?"Безопасно":"Нарушения")+"</td><td>"+(x.totalViolations||0)+"</td></tr>"}).join("")+"</table></body></html>");w.document.close()}

View File

@ -57,20 +57,14 @@ document.getElementById('lb').onclick=function(){
var u=document.getElementById('lu').value.trim().toLowerCase();
var p=document.getElementById('lp').value.trim();
if(u==='admin'&&p==='admin'){sessionStorage.setItem('pab_user',JSON.stringify({login:'admin',name:'Администратор',role:'Руководитель',freq:'0,month',email:'admin@telecom.kz',branch:'АО «Казахтелеком»',dept:'ЦА',region:'Центральный',oblast:'—',city:'г. Астана'}));location.href='app.html';return}
var users={};try{users=JSON.parse(localStorage.getItem('pab_users')||'{}')}catch(e){}
if(users[u]&&users[u].pass===p){sessionStorage.setItem('pab_user',JSON.stringify({login:u,name:users[u].name,role:users[u].role,freq:users[u].freq||'',email:users[u].email||'',branch:users[u].branch||'',dept:users[u].dept||'',region:users[u].region||'',oblast:users[u].oblast||'',city:users[u].city||''}));location.href='app.html';return}
// Проверяем через Supabase
var SBU="https://znexbjafkvyjffffbhlf.supabase.co",SBK="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6InpuZXhiamFma3Z5amZmZmZiaGxmIiwicm9sZSI6InNlcnZpY2Vfcm9sZSIsImlhdCI6MTc4MDY0NDE4MiwiZXhwIjoyMDk2MjIwMTgyfQ.5pOYTkL5eCmpSHBY3EwKof6NVKt7tL4Fn8xUAKM8itE";
fetch(SBU+"/rest/v1/users?login=eq."+encodeURIComponent(u),{headers:{"apikey":SBK,"Authorization":"Bearer "+SBK}}).then(function(r){return r.json()}).then(function(data){if(data.length>0&&data[0].pass===p){var ud=data[0];sessionStorage.setItem('pab_user',JSON.stringify({login:ud.login,name:ud.name,role:ud.role,freq:ud.freq||'',email:ud.email||'',branch:ud.branch||'',dept:ud.dept||'',region:ud.region||'',oblast:ud.oblast||'',city:ud.city||''}));location.href='app.html'}else{document.getElementById('lerr').style.display='block'}}).catch(function(){document.getElementById('lerr').style.display='block'});
var users={};try{users=JSON.parse(localStorage.getItem('pab_users')||'{}')}catch(e){}if(users[u]&&users[u].pass===p){sessionStorage.setItem('pab_user',JSON.stringify({login:u,name:users[u].name,role:users[u].role,freq:users[u].freq||'',email:users[u].email||'',branch:users[u].branch||'',dept:users[u].dept||'',region:users[u].region||'',oblast:users[u].oblast||'',city:users[u].city||''}));location.href='app.html';return}
document.getElementById('lerr').style.display='block'
};
document.getElementById('lp').onkeydown=function(e){if(e.key==='Enter')document.getElementById('lb').onclick()};
document.getElementById('rbb').onclick=function(){
var l=document.getElementById('rl').value.trim().toLowerCase(),p=document.getElementById('rp').value.trim(),n=document.getElementById('rn').value.trim(),em=document.getElementById('re').value.trim(),r=document.getElementById('rr').value,fr=document.getElementById('rf').value,br=document.getElementById('rb').value.trim(),dp=document.getElementById('rd').value.trim(),rg=document.getElementById('rg').value.trim(),ob=document.getElementById('ro').value.trim(),ct=document.getElementById('rc').value.trim();
var e=document.getElementById('rerr'),ok=document.getElementById('rok');ok.style.display='none';if(!l||l.length<2){e.textContent='Логин мин. 2 символа';e.style.display='block';return}if(!p||p.length<3){e.textContent='Пароль мин. 3 символа';e.style.display='block';return}if(!n){e.textContent='Укажите ФИО';e.style.display='block';return}if(!r){e.textContent='Выберите должность';e.style.display='block';return}if(!em||em.indexOf('@')<0){e.textContent='Укажите Email';e.style.display='block';return}if(!br){e.textContent='Укажите филиал';e.style.display='block';return}if(!rg){e.textContent='Укажите регион';e.style.display='block';return}if(!ct){e.textContent='Укажите город';e.style.display='block';return}if(!dp){e.textContent='Укажите подразделение';e.style.display='block';return}if(!fr){e.textContent='Укажите периодичность ПАБ';e.style.display='block';return}
var users={};try{users=JSON.parse(localStorage.getItem('pab_users')||'{}')}catch(e){}if(users[l]){e.textContent='Логин занят';e.style.display='block';return}e.style.display='none';users[l]={pass:p,name:n,email:em,role:r,freq:fr,branch:br,dept:dp,region:rg,oblast:ob,city:ct};localStorage.setItem('pab_users',JSON.stringify(users));ok.style.display='block';
// Отправка в Supabase
try{var SBU="https://znexbjafkvyjffffbhlf.supabase.co",SBK="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6InpuZXhiamFma3Z5amZmZmZiaGxmIiwicm9sZSI6InNlcnZpY2Vfcm9sZSIsImlhdCI6MTc4MDY0NDE4MiwiZXhwIjoyMDk2MjIwMTgyfQ.5pOYTkL5eCmpSHBY3EwKof6NVKt7tL4Fn8xUAKM8itE";fetch(SBU+"/rest/v1/users",{method:"POST",headers:{"apikey":SBK,"Authorization":"Bearer "+SBK,"Content-Type":"application/json","Prefer":"resolution=merge-duplicates"},body:JSON.stringify({login:l,pass:p,name:n,email:em,role:r,freq:fr,branch:br,dept:dp,region:rg,oblast:ob,city:ct})}).then(function(r){console.log("SB reg:",r.ok?"OK":r.status)})}catch(e){}
document.getElementById('lu').value=l;setTimeout(function(){ok.style.display='none';document.getElementById('tL').onclick()},2000)
var users={};try{users=JSON.parse(localStorage.getItem('pab_users')||'{}')}catch(e){}if(users[l]){e.textContent='Логин занят';e.style.display='block';return}e.style.display='none';users[l]={pass:p,name:n,email:em,role:r,freq:fr,branch:br,dept:dp,region:rg,oblast:ob,city:ct};localStorage.setItem('pab_users',JSON.stringify(users));ok.style.display='block';document.getElementById('lu').value=l;setTimeout(function(){ok.style.display='none';document.getElementById('tL').onclick()},2000)
};
</script>
</body>