diff --git a/app.html b/app.html index d71dee4..f90dffd 100644 --- a/app.html +++ b/app.html @@ -150,7 +150,7 @@ function printConfirm(){if(!lastSubmitted)return;var e=lastSubmitted;var w=windo function checkSA(){if(!U||isA()){document.getElementById("sa").classList.remove("sh","dg");return}var q=getUserQuota(U);if(!q.p)return;var p=gp(q.p);var done=getA().filter(function(a){return a.createdBy===U.login&&new Date(a.date)>=p.s}).length;var need=Math.max(0,q.c-done);var sa=document.getElementById("sa"),at=document.getElementById("sat");sa.classList.remove("sh","dg");if(need>0){at.textContent="⚠️ Отставание ("+p.l+"): "+done+" из "+q.c+". Осталось: "+need;sa.classList.add("sh");if(need>=q.c)sa.classList.add("dg")}} function sendScheduleReminder(){if(!U)return;var q=getUserQuota(U);var p=gp(q.p);var done=getA().filter(function(a){return a.createdBy===U.login&&new Date(a.date)>=p.s}).length;var need=Math.max(0,q.c-done);var to=U.email||"";if(!to||to.indexOf("@")<0){alert("Нет email");return}location.href="mailto:"+encodeURIComponent(to)+"?subject="+encodeURIComponent("График ПАБ — "+p.l)+"&body="+encodeURIComponent("График: "+q.l+"\nПериод: "+p.l+"\nВыполнено: "+done+" из "+q.c+(need>0?"\nОтставание: "+need:"\nГрафик выполнен!"))} -function rMS(){var c=document.getElementById("msc");if(!c)return;document.getElementById("sa").classList.remove("sh","dg");if(isA()){var all=allU();var rows="";for(var k in all){if(k==="admin")continue;var u=all[k];var q=getUserQuota({role:u.role,freq:u.freq||""});var p=gp(q.p);var done=getA().filter(function(a){return a.createdBy===k&&new Date(a.date)>=p.s}).length;var pct=Math.round(done/q.c*100);var cl=pct>=200?"#00B4D8":pct>=100?"#2D6A4F":pct>=50?"#E76F51":"#E63946";var st=pct>100?"🔵 Перевып. +"+(done-q.c):pct>=100?"🟢 Выполнен":"🔴 Отстаёт на "+(q.c-done);rows+=""+u.name+""+u.role+""+(u.branch||"—")+""+(u.region||"—")+""+(u.city||"—")+""+q.l+"
"+done+"/"+q.c+"
"+st+""+p.l+""}c.innerHTML="

👥 График всех работников

Вы админ — видите данные всех. Проводить ПАБ вам не нужно.
"+rows+"
ФИОДолжностьФилиалРегионГородНормаПрогрессСтатусПериод
";return}var q=getUserQuota(U);if(q.c===0)q={c:1,p:"month",l:"1 раз в месяц"};var p=gp(q.p);var done=getA().filter(function(a){return a.createdBy===U.login&&new Date(a.date)>=p.s}).length;var pct=Math.round(done/q.c*100);var over=pct>100;var cl=over?"#00B4D8":pct>=100?"#2D6A4F":pct>=50?"#E76F51":"#E63946";var barW=Math.min(pct,200);var need=Math.max(0,q.c-done);var extra=done-q.c;c.innerHTML="

📅 "+p.l+"

Минимум: "+q.l+" | "+U.role+"
Проведено: "+done+" (мин: "+q.c+")"+(over?" — ✅ перевыполнено на +"+extra+"!":done>=q.c?" — ✅ план выполнен!":" — осталось: "+need+"")+"
"+(need>0?"
":"")+"
👤 "+U.name+" — "+U.role+"
"+(U.branch||"—")+" | "+(U.dept||"—")+" | "+(U.region||"—")+" | "+(U.city||"—")+" | "+U.email+"
"+(done>0?"

📋 Проведённые:

"+getA().filter(function(a){return a.createdBy===U.login}).slice(0,10).map(function(a){return"
"+a.date+" — "+a.location+" — "+(a.overallSafe?"Безопасно":"Нарушений: "+a.totalViolations)+"
"}).join("")+"
":"")} +function rMS(){var c=document.getElementById("msc");if(!c)return;document.getElementById("sa").classList.remove("sh","dg");if(isA()){var all=allU();var rows="",wCount=0;for(var k in all){if(k==="admin")continue;wCount++;var u=all[k];var q=getUserQuota({role:u.role,freq:u.freq||""});var p=gp(q.p);var done=getA().filter(function(a){return a.createdBy===k&&new Date(a.date)>=p.s}).length;var pct=Math.round(done/q.c*100);var cl=pct>=200?"#00B4D8":pct>=100?"#2D6A4F":pct>=50?"#E76F51":"#E63946";var st=pct>100?"🔵 Перевып. +"+(done-q.c):pct>=100?"🟢 Выполнен":"🔴 Отстаёт на "+(q.c-done);rows+=""+u.name+""+u.role+""+(u.branch||"—")+""+(u.region||"—")+""+(u.city||"—")+""+q.l+"
"+done+"/"+q.c+"
"+st+""+p.l+""}var tbl=wCount>0?"
"+rows+"
ФИОДолжностьФилиалРегионГородНормаПрогрессСтатусПериод
":"
👥

Нет зарегистрированных работников.
Работники должны зарегистрироваться на странице входа.

";c.innerHTML="

👥 График всех работников

Вы админ — видите данные всех. Проводить ПАБ вам не нужно.
"+tbl+"
";return}var q=getUserQuota(U);if(q.c===0)q={c:1,p:"month",l:"1 раз в месяц"};var p=gp(q.p);var done=getA().filter(function(a){return a.createdBy===U.login&&new Date(a.date)>=p.s}).length;var pct=Math.round(done/q.c*100);var over=pct>100;var cl=over?"#00B4D8":pct>=100?"#2D6A4F":pct>=50?"#E76F51":"#E63946";var barW=Math.min(pct,200);var need=Math.max(0,q.c-done);var extra=done-q.c;c.innerHTML="

📅 "+p.l+"

Минимум: "+q.l+" | "+U.role+"
Проведено: "+done+" (мин: "+q.c+")"+(over?" — ✅ перевыполнено на +"+extra+"!":done>=q.c?" — ✅ план выполнен!":" — осталось: "+need+"")+"
"+(need>0?"
":"")+"
👤 "+U.name+" — "+U.role+"
"+(U.branch||"—")+" | "+(U.dept||"—")+" | "+(U.region||"—")+" | "+(U.city||"—")+" | "+U.email+"
"+(done>0?"

📋 Проведённые:

"+getA().filter(function(a){return a.createdBy===U.login}).slice(0,10).map(function(a){return"
"+a.date+" — "+a.location+" — "+(a.overallSafe?"Безопасно":"Нарушений: "+a.totalViolations)+"
"}).join("")+"
":"")} function rDB(){var c=document.getElementById("dbc");if(!c)return;var audits=getA();var all=allU();var total=audits.length,allSafe=audits.filter(function(a){return a.overallSafe}).length,wd=audits.filter(function(a){return !a.overallSafe}).length,tv=audits.reduce(function(s,a){return s+(a.totalViolations||0)},0);var ul=[];for(var k in all)if(k!=="admin")ul.push({login:k,role:all[k].role});var ot=0,bh=0,ov=0;ul.forEach(function(u){var q=getUserQuota(u);if(!q.p)return;var p=gp(q.p);var done=getA().filter(function(a){return a.createdBy===u.login&&new Date(a.date)>=p.s}).length;if(done>q.c)ov++;else if(done>=q.c)ot++;else bh++});var sp=total>0?(allSafe/total*100):50,dp=total>0?(wd/total*100):50;c.innerHTML=(isA()?"
|
":"")+"
Всего аудитов
"+total+"
Безопасно
"+allSafe+"
С нарушениями
"+wd+"
Нарушений
"+tv+"
Перевыполняют
"+ov+"
Выполняют
"+ot+"
Отстают
"+bh+"

🟢🔴 Соотношение

Безопасные: "+allSafe+"С нарушениями: "+wd+"

📂 По категориям

📅 По датам

🔝 Топ-10

";setTimeout(function(){for(var ck in charts)try{charts[ck].destroy()}catch(e){}charts={};var ctx1=document.getElementById("ch1");if(ctx1)charts.cat=new Chart(ctx1,{type:"bar",data:{labels:CATS.map(function(c){return c.title.split(". ")[1]}),datasets:[{label:"Нарушений",data:CATS.map(function(cat){return audits.reduce(function(s,a){var c=a.categories&&a.categories[cat.id];return s+(c?c.items.length:0)},0)}),backgroundColor:"#E63946",borderRadius:6}]},options:{responsive:true,plugins:{legend:{display:false}},scales:{y:{beginAtZero:true,ticks:{stepSize:1}}}}});var dates={};audits.forEach(function(a){if(!dates[a.date])dates[a.date]=0;dates[a.date]+=(a.totalViolations||0)});var sd=Object.keys(dates).sort();var ctx2=document.getElementById("ch2");if(ctx2)charts.tl=new Chart(ctx2,{type:"line",data:{labels:sd,datasets:[{label:"Нарушений",data:sd.map(function(d){return dates[d]}),borderColor:"#E63946",backgroundColor:"rgba(230,57,70,0.08)",fill:true,tension:0.3,pointRadius:5}]},options:{responsive:true,plugins:{legend:{display:false}},scales:{y:{beginAtZero:true,ticks:{stepSize:1}}}}});var ic={};audits.forEach(function(a){if(a.categories){Object.values(a.categories).forEach(function(cat){if(cat.items)cat.items.forEach(function(it){ic[it.item]=(ic[it.item]||0)+1})})}});var ti=Object.entries(ic).sort(function(a,b){return b[1]-a[1]}).slice(0,10);var ctx3=document.getElementById("ch3");if(ctx3)charts.top=new Chart(ctx3,{type:"bar",data:{labels:ti.map(function(i){return i[0].length>30?i[0].slice(0,30)+"...":i[0]}),datasets:[{label:"Раз",data:ti.map(function(i){return i[1]}),backgroundColor:["#E63946","#E76F51","#F4A261","#E9C46A","#2A9D8F","#264653","#00B4D8","#0077B6","#023E8A","#6C757D"],borderRadius:4}]},options:{indexAxis:"y",responsive:true,plugins:{legend:{display:false}},scales:{x:{beginAtZero:true,ticks:{stepSize:1}}}}})},300)}