diff --git a/index.html b/index.html index 07f36ce..1e420fd 100644 --- a/index.html +++ b/index.html @@ -238,6 +238,7 @@ body{font:15px/1.5 -apple-system,BlinkMacSystemFont,"Segoe UI",Inter,system-ui,s Новый аудит Мой график Дашборд + Нарушения История
@@ -324,6 +325,10 @@ body{font:15px/1.5 -apple-system,BlinkMacSystemFont,"Segoe UI",Inter,system-ui,s + | + + +
@@ -332,6 +337,10 @@ body{font:15px/1.5 -apple-system,BlinkMacSystemFont,"Segoe UI",Inter,system-ui,s + с + + по +
Всего аудитов
0
@@ -356,6 +365,28 @@ body{font:15px/1.5 -apple-system,BlinkMacSystemFont,"Segoe UI",Inter,system-ui,s
+ +
+ +
+
Всего несоответствий
0
+
Устранено
0
+
Просрочено
0
+
В работе
0
+
+
+ + +
+
+ + + +
НесоответствиеАудит (дата)ИсполнительВидМерыОтветственныйСрокЗавершениеСтатус
+
+ +
+
@@ -701,6 +732,7 @@ function switchPanel(name,el){ if(name==='dashboard')renderDashboard(); if(name==='history')renderHistory(); if(name==='mySchedule')renderMySchedule(); + if(name==='violations')renderViolations(); } // ========== DASHBOARD ========== @@ -742,6 +774,12 @@ function renderDashboard(){ return true; }); + // Date range filter + const df=document.getElementById('dfDateFrom')?.value; + const dt=document.getElementById('dfDateTo')?.value; + if(df)audits=audits.filter(a=>a.date>=df); + if(dt)audits=audits.filter(a=>a.date<=dt); + const total=audits.length; const allSafe=audits.filter(a=>a.overallSafe).length; const withDanger=audits.filter(a=>!a.overallSafe).length; @@ -857,7 +895,8 @@ function exportCSV(){ // ========== ADMIN DOWNLOADS ========== function downloadFullCSV(){ - const audits=getAudits();if(audits.length===0){alert('Нет данных');return} + const {audits,all}=getDashboardFilters(); + if(audits.length===0){alert('Нет данных');return} const all=getAllUsers(); const header='Бланк №;Дата;Время;Место;Тип работы;Наблюдатель;Должность;Руководитель;Филиал;Подразделение;Регион;Область;Город;Статус;Нарушений;Категории с нарушениями'; const rows=audits.map(a=>{ @@ -869,7 +908,8 @@ function downloadFullCSV(){ } function downloadWorkerReport(){ - const all=getAllUsers();const audits=getAudits();const userList=Object.entries(all).filter(([l])=>l!=='admin'); + const {audits}=getDashboardFilters(); + const all=getAllUsers();const userList=Object.entries(all).filter(([l])=>l!=='admin'); if(userList.length===0){alert('Нет зарегистрированных работников');return} const header='Логин;ФИО;Должность;Филиал;Подразделение;Регион;Область;Город;Email;График;Период;Выполнено;Нужно;Статус'; const rows=userList.map(([login,u])=>{ @@ -883,7 +923,8 @@ function downloadWorkerReport(){ } function downloadSummaryHTML(){ - const audits=getAudits();const all=getAllUsers();const userList=Object.entries(all).filter(([l])=>l!=='admin'); + const {audits}=getDashboardFilters(); + const all=getAllUsers();const userList=Object.entries(all).filter(([l])=>l!=='admin'); const total=audits.length;const allSafe=audits.filter(a=>a.overallSafe).length; const withDanger=audits.filter(a=>!a.overallSafe).length;const totalVio=audits.reduce((s,a)=>s+(a.totalViolations||0),0); @@ -944,6 +985,112 @@ tr:hover td{background:#F2F4F7} `; const w=window.open('','_blank','width=1000,height=800');w.document.write(html);w.document.close(); } + +// ========== VIOLATIONS TRACKING ========== +function renderViolations(){ + const all=getAllUsers();let audits=getAudits(); + const df=document.getElementById('dfDateFrom')?.value,dt=document.getElementById('dfDateTo')?.value; + if(df)audits=audits.filter(a=>a.date>=df); + if(dt)audits=audits.filter(a=>a.date<=dt); + const fStatus=document.getElementById('vfStatus')?.value||'all'; + const fType=document.getElementById('vfType')?.value||'all'; + + // Collect all violations from all audits + const today=new Date().toISOString().split('T')[0]; + let allVios=[]; + audits.forEach(a=>{ + if(!a.violations)return; + const u=all[a.createdBy]||{}; + a.violations.forEach((v,i)=>{ + const dueDate=v.date||''; + const done=v.done&&v.done.trim(); + let status='pending'; + if(done)status='done'; + else if(dueDate&&dueDatev.status==='done').length; + const overdueCount=allVios.filter(v=>v.status==='overdue').length; + const pendingCount=allVios.filter(v=>v.status==='pending').length; + document.getElementById('vTotal').textContent=total; + document.getElementById('vDone').textContent=doneCount; + document.getElementById('vOverdue').textContent=overdueCount; + document.getElementById('vPending').textContent=pendingCount; + + // Filter + if(fStatus!=='all')allVios=allVios.filter(v=>v.status===fStatus); + if(fType!=='all')allVios=allVios.filter(v=>v.type===fType); + + const tbody=document.getElementById('violationsBody'),nd=document.getElementById('vioNoData'); + if(allVios.length===0){tbody.innerHTML='';nd.style.display='block';return} + nd.style.display='none'; + tbody.innerHTML=allVios.map((v,i)=>{ + const sc=v.status==='done'?'badge-safe':v.status==='overdue'?'badge-danger':'badge-warn'; + const sl=v.status==='done'?'Устранено':v.status==='overdue'?'Просрочено':'В работе'; + return ` + ${i+1}${v.nc} + ${v.auditDate} (№${v.auditNumber})${v.executor}${v.type} + ${v.measure||'—'} + ${v.responsible}${v.date||'—'}${v.done||'—'} + ${sl} + `; + }).join(''); +} + +// ========== ADMIN DATA MANAGEMENT ========== +function clearAllAudits(){ + if(!isAdmin())return; + if(!confirm('ВНИМАНИЕ! Это удалит ВСЕ аудиты безвозвратно. Продолжить?'))return; + if(!confirm('Точно удалить все данные?'))return; + localStorage.removeItem('safetyAudits'); + alert('Все аудиты удалены.'); + renderDashboard();renderHistory();renderViolations(); +} + +function clearAuditsByDate(){ + if(!isAdmin())return; + const from=prompt('Удалить аудиты С даты (ГГГГ-ММ-ДД):',''); + if(!from)return; + const to=prompt('Удалить аудиты ПО дату (ГГГГ-ММ-ДД, или оставьте пустым):',''); + let audits=getAudits(); + const before=audits.length; + audits=audits.filter(a=>{if(a.dateto)return true;return false}); + if(before===audits.length){alert('Нет аудитов за указанный период.');return} + if(!confirm('Удалить '+ (before-audits.length) +' аудитов за период '+from+(to?' — '+to:'')+'?'))return; + saveAudits(audits); + alert('Удалено '+(before-audits.length)+' аудитов.'); + renderDashboard();renderHistory();renderViolations(); +} + +function showAllUsers(){ + if(!isAdmin())return; + const all=getAllUsers(); + const userList=Object.entries(all); + let html=`

👥 Зарегистрированные пользователи (${userList.length})

`; + userList.forEach(([login,u])=>{ + const q=getQuota(u.role); + html+=``; + }); + html+='
ЛогинФИОДолжностьФилиалПодразделениеРегионОбластьГородEmailГрафик
${login}${login==='admin'?' ⭐':''}${u.name}${u.role}${u.branch||'—'}${u.dept||'—'}${u.region||'—'}${u.oblast||'—'}${u.city||'—'}${u.email||'—'}${q.label}
'; + const w=window.open('','_blank','width=1000,height=600'); + w.document.write(`Пользователи ПАБ${html}

⭐ — предустановленный администратор

`); + w.document.close(); +} + +// ========== DOWNLOADS WITH DATE RANGE ========== +function getDashboardFilters(){ + const all=getAllUsers(); + let audits=getAudits(); + const fr=document.getElementById('dfRegion')?.value||'all',fo=document.getElementById('dfOblast')?.value||'all',fb=document.getElementById('dfBranch')?.value||'all',fd=document.getElementById('dfDept')?.value||'all',fc=document.getElementById('dfCity')?.value||'all'; + const df=document.getElementById('dfDateFrom')?.value,dt=document.getElementById('dfDateTo')?.value; + audits=audits.filter(a=>{const u=all[a.createdBy];if(!u)return true;if(fr!=='all'&&u.region!==fr)return false;if(fo!=='all'&&u.oblast!==fo)return false;if(fb!=='all'&&u.branch!==fb)return false;if(fd!=='all'&&u.dept!==fd)return false;if(fc!=='all'&&u.city!==fc)return false;return true}); + if(df)audits=audits.filter(a=>a.date>=df);if(dt)audits=audits.filter(a=>a.date<=dt); + return {audits,all}; +}