diff --git a/app.html b/app.html
index ee55509..75d5e2d 100644
--- a/app.html
+++ b/app.html
@@ -138,8 +138,8 @@ function rMS(){
var c=document.getElementById("msc");if(!c)return;
if(isA()){
var all=allU();var rows="",wc=0;
- for(var k in all){if(k==="admin")continue;wc++;var u=all[k];var q=getUserQuota(u);var p=gp(q.p);var d=getA().filter(function(a){return a.createdBy===k&&new Date(a.date)>=p.s}).length;var pct=Math.round(d/q.c*100);var st=d>q.c?"🔵 +"+(d-q.c):d>=q.c?"🟢 OK":"🔴 -"+(q.c-d);rows+="
| "+u.name+" | "+u.role+" | "+(u.branch||"—")+" | "+(u.region||"—")+" | "+q.l+" | "+d+"/"+q.c+" | "+st+" | "+p.l+" |
"}
- c.innerHTML=wc===0?"👥 График работников
Нет зарегистрированных работников. Зарегистрируйте их на странице входа.
":"👥 График всех работников
| ФИО | Должность | Филиал | Регион | Норма | Прогресс | Статус | Период |
"+rows+"
";
+ for(var k in all){if(k==="admin")continue;wc++;var u=all[k];var q=getUserQuota(u);var p=gp(q.p);var d=getA().filter(function(a){return a.createdBy===k&&new Date(a.date)>=p.s}).length;var pct=Math.round(d/q.c*100);var st=d>q.c?"🔵 +"+(d-q.c):d>=q.c?"🟢 OK":"🔴 -"+(q.c-d);rows+="| "+u.name+" | "+u.role+" | "+(u.branch||"—")+" | "+(u.region||"—")+" | "+q.l+" | "+d+"/"+q.c+" | "+st+" | "+p.l+" | |
"}
+ c.innerHTML=wc===0?"👥 График работников
Нет зарегистрированных работников. Зарегистрируйте их на странице входа.
":"👥 График всех работников
| ФИО | Должность | Филиал | Регион | Норма | Прогресс | Статус | Период | |
"+rows+"
";
return;
}
var q=getUserQuota(U);var p=gp(q.p);var d=getA().filter(function(a){return a.createdBy===U.login&&new Date(a.date)>=p.s}).length;var pct=Math.round(d/q.c*100);var over=d>q.c;var cl=over?"#00B4D8":d>=q.c?"#2D6A4F":d>=q.c/2?"#E76F51":"#E63946";
@@ -148,10 +148,16 @@ function rMS(){
function rDB(){
var c=document.getElementById("dbc");if(!c)return;
- var a=getA(),all=allU();var t=a.length,sf=a.filter(function(x){return x.overallSafe}).length,wd=a.filter(function(x){return !x.overallSafe}).length,tv=a.reduce(function(s,x){return s+(x.totalViolations||0)},0);
+ var a=getA(),all=allU();
+ // Date filter
+ var df=document.getElementById("df"),dt=document.getElementById("dt");
+ if(df&&df.value)a=a.filter(function(x){return x.date>=df.value});
+ if(dt&&dt.value)a=a.filter(function(x){return x.date<=dt.value});
+ var t=a.length,sf=a.filter(function(x){return x.overallSafe}).length,wd=a.filter(function(x){return !x.overallSafe}).length,tv=a.reduce(function(s,x){return s+(x.totalViolations||0)},0);
var ot=0,bh=0,ov=0;for(var k in all){if(k==="admin")continue;var u=all[k];var q=getUserQuota(u);if(!q.p)continue;var p=gp(q.p);var d=a.filter(function(x){return x.createdBy===k&&new Date(x.date)>=p.s}).length;if(d>q.c)ov++;else if(d>=q.c)ot++;else bh++}
var adb=isA()?"|
":"";
- c.innerHTML=adb+""+tv+"
Всего пунктов нарушений
"+(ot+ov)+"
Выполняют график
"+
+ c.innerHTML=adb+"спо
"+
+ ""+tv+"
Всего пунктов нарушений
"+(ot+ov)+"
Выполняют график
"+
"📂 Нарушения по категориям
📅 Динамика по датам
"+
"🔝 Топ-10 нарушений
";
setTimeout(function(){
@@ -204,6 +210,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}));rHS()}
+function delUser(login){if(!isA())return;if(!confirm("Удалить пользователя "+login+" и все его аудиты?"))return;var u=getU();delete u[login];saveU(u);var a=getA().filter(function(x){return x.createdBy!==login});saveA(a);fetch(SBU+"/rest/v1/users?login=eq."+encodeURIComponent(login),{method:"DELETE",headers:{"apikey":SBK,"Authorization":"Bearer "+SBK}}).catch(function(){});rMS();rHS();rDB()}
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="👥 Пользователи
| Логин | ФИО | Должность | Филиал | Регион | Город |
";for(var k in all){var u=all[k];h+="| "+k+(k==="admin"?" ⭐":"")+" | "+u.name+" | "+u.role+" | "+(u.branch||"—")+" | "+(u.region||"—")+" | "+(u.city||"—")+" |
"}h+="
";var w=window.open("","_blank","width=800,height=500");w.document.write("Пользователи"+h+"");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("Отчёт ПАБ📊 Сводный отчёт ПАБ
Сформирован: "+new Date().toLocaleString("ru")+" | Всего аудитов: "+t+"
📋 Аудиты
| № | Дата | Место | Наблюдатель | Статус | Нарушений |
"+a.map(function(x){return"| "+(x.number||"—")+" | "+x.date+" | "+x.location+" | "+x.observer+" | "+(x.overallSafe?"Безопасно":"Нарушения")+" | "+(x.totalViolations||0)+" |
"}).join("")+"
");w.document.close()}