v73: возврат к v60 — строим заново аккуратно

This commit is contained in:
Dauren777 2026-06-09 15:41:43 +00:00
parent c679f798df
commit 56c325739d

View File

@ -5,330 +5,116 @@
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>План ПБ 2026 — Казахтелеком</title>
<style>
:root{--ink:#0B1A2E;--cyan:#00B4D8;--cyan-l:#E0F7FA;--white:#fff;--gray-50:#F8FAFC;--gray-100:#F1F5F9;--gray-200:#E2E8F0;--gray-500:#64748B;--gray-700:#334155;--green:#10B981;--red:#EF4444;--amber:#F59E0B;--blue:#3B82F6;--sidebar:240px}
:root{--b:#0F1218;--c:#00E5FF;--w:#fff;--g5:#5B6573;--g1:#F2F4F7;--g2:#E5E7EB;--gn:#10B981;--rd:#EF4444;--am:#F59E0B}
*{box-sizing:border-box;margin:0;padding:0}
body{font:14px/1.5 'Segoe UI',system-ui,-apple-system,sans-serif;color:var(--gray-700);background:var(--gray-50);min-height:100vh}
body{font:14px/1.4 Arial,sans-serif;color:var(--b);background:var(--g1)}
input,select,textarea,button{font:inherit;outline:none}
.btn{background:var(--cyan);color:var(--white);padding:10px 20px;border-radius:8px;font-weight:600;font-size:14px;border:none;cursor:pointer;transition:.15s}.btn:hover{background:#0096B0}
.btn-sm{padding:6px 14px;font-size:12px}.btn-red{background:var(--red);color:#fff}.btn-gn{background:var(--green);color:#fff}
.btn-ghost{background:transparent;color:var(--gray-500);border:1px solid var(--gray-200)}.btn-ghost:hover{background:var(--gray-100)}
#loginBox{display:flex;align-items:center;justify-content:center;min-height:100vh;background:linear-gradient(135deg,#0B1A2E 0%,#1a3a5c 100%)}
#loginBox>div{background:var(--white);border-radius:20px;padding:48px 40px;width:420px;max-width:90vw;text-align:center;box-shadow:0 20px 60px rgba(0,0,0,.3)}
#loginBox .logo{font-size:28px;font-weight:800;color:var(--ink);margin-bottom:4px}
#loginBox .logo span{color:var(--cyan)}
#loginBox .sub{color:var(--gray-500);font-size:13px;margin-bottom:32px}
#loginBox input{display:block;width:100%;padding:14px 16px;border:2px solid var(--gray-200);border-radius:10px;font-size:14px;margin-bottom:16px;transition:.15s}
#loginBox input:focus{border-color:var(--cyan)}
#app{display:none;display:flex;min-height:100vh}
.sidebar{width:var(--sidebar);background:var(--ink);color:var(--white);position:fixed;top:0;left:0;bottom:0;display:flex;flex-direction:column;z-index:10}
.sidebar .logo{padding:24px 20px;font-size:18px;font-weight:800;border-bottom:1px solid rgba(255,255,255,.08)}
.sidebar .logo span{color:var(--cyan)}
.sidebar nav{flex:1;padding:12px 0}
.sidebar nav a{display:flex;align-items:center;gap:12px;padding:12px 20px;color:rgba(255,255,255,.6);font-weight:500;font-size:14px;cursor:pointer;text-decoration:none;transition:.15s;border-left:3px solid transparent}
.sidebar nav a:hover,.sidebar nav a.on{color:var(--white);background:rgba(0,180,216,.1);border-left-color:var(--cyan)}
.sidebar .user{padding:20px;border-top:1px solid rgba(255,255,255,.08);font-size:12px;color:rgba(255,255,255,.4)}
.main{margin-left:var(--sidebar);flex:1;padding:24px 32px;max-width:calc(100vw - var(--sidebar))}
.topbar{display:flex;justify-content:space-between;align-items:center;margin-bottom:24px}
.topbar h2{font-size:22px;font-weight:700;color:var(--ink)}
.topbar .right{display:flex;align-items:center;gap:16px}
.notif-btn{position:relative;background:var(--white);border:1px solid var(--gray-200);border-radius:10px;padding:8px 12px;cursor:pointer;font-size:18px}
.notif-btn .cnt{position:absolute;top:-6px;right:-6px;background:var(--red);color:#fff;border-radius:100px;font-size:10px;padding:2px 6px;font-weight:700;min-width:18px;text-align:center}
.notif-drop{position:absolute;top:52px;right:0;width:400px;max-width:90vw;background:var(--white);border:1px solid var(--gray-200);border-radius:14px;box-shadow:0 10px 40px rgba(0,0,0,.12);z-index:300;display:none;max-height:420px;overflow-y:auto}
.notif-drop.on{display:block}.notif-drop .it{padding:14px 18px;border-bottom:1px solid var(--gray-100);font-size:13px}.notif-drop .it b{display:block;margin-bottom:3px}.notif-drop .it span{font-size:11px;color:var(--gray-500)}
.tabs{display:flex;gap:8px;margin-bottom:24px}
.tab{padding:10px 22px;border-radius:10px;border:none;background:var(--white);cursor:pointer;font-size:14px;font-weight:600;color:var(--gray-500);box-shadow:0 1px 3px rgba(0,0,0,.04);transition:.15s}
.tab.on{background:var(--cyan);color:var(--white)}
.btn{background:var(--c);color:var(--b);padding:10px 20px;border-radius:8px;font-weight:700;font-size:14px;border:none;cursor:pointer}.btn:hover{opacity:.85}
.btn-sm{padding:6px 12px;font-size:12px}.btn-red{background:var(--rd);color:#fff}.btn-gn{background:var(--gn);color:#fff}
#loginBox{display:flex;align-items:center;justify-content:center;min-height:100vh;background:var(--b)}
#loginBox>div{background:var(--w);border-radius:16px;padding:40px 36px;width:400px;max-width:90vw;text-align:center}
#loginBox h1{font-size:22px;font-weight:800;margin-bottom:4px}
#loginBox h1 span{color:var(--c)}
#loginBox p{color:var(--g5);font-size:13px;margin-bottom:28px}
#loginBox input{display:block;width:100%;padding:12px 14px;border:1px solid var(--g2);border-radius:8px;font-size:14px;margin-bottom:14px}
#app{display:none;max-width:1200px;margin:0 auto;padding:16px}
.top{display:flex;justify-content:space-between;align-items:center;padding:12px 0;border-bottom:2px solid var(--g2);margin-bottom:16px}
.top b{font-size:18px}.top b span{color:var(--c)}
.top .r{display:flex;align-items:center;gap:12px;font-size:13px;color:var(--g5)}
.tabs{display:flex;gap:4px;margin-bottom:16px}
.tab{padding:10px 20px;border:none;background:var(--w);cursor:pointer;font-size:14px;font-weight:600;color:var(--g5);border-radius:8px 8px 0 0}
.tab.on{color:var(--b);border-bottom:3px solid var(--c)}
.pg{display:none}.pg.on{display:block}
.card{background:var(--white);border-radius:14px;padding:24px;margin-bottom:16px;box-shadow:0 1px 3px rgba(0,0,0,.04);border:1px solid var(--gray-100)}
.card h3{font-size:17px;font-weight:700;margin-bottom:12px;color:var(--ink)}
.stats{display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:14px;margin-bottom:20px}
.stat{background:var(--white);border-radius:12px;padding:20px 24px;box-shadow:0 1px 3px rgba(0,0,0,.04);border:1px solid var(--gray-100);text-align:center}
.stat .n{font-size:30px;font-weight:800}.stat .l{font-size:12px;color:var(--gray-500);margin-top:4px}
.stat.r .n{color:var(--red)}.stat.g .n{color:var(--green)}.stat.a .n{color:var(--amber)}.stat.b .n{color:var(--cyan)}
table{width:100%;border-collapse:collapse}
th,td{padding:10px 14px;text-align:left;font-size:13px}
th{font-weight:600;color:var(--gray-500);font-size:11px;text-transform:uppercase;border-bottom:2px solid var(--gray-100);background:var(--gray-50)}
td{border-bottom:1px solid var(--gray-100)}
tr.rd td{background:#FEF2F2}tr.am td{background:#FFFBEB}
.badge{display:inline-block;padding:4px 10px;border-radius:100px;font-size:11px;font-weight:600}
.badge.g{background:#D1FAE5;color:#065F46}.badge.a{background:#FEF3C7;color:#92400E}.badge.r{background:#FEE2E2;color:#991B1B}.badge.b{background:#DBEAFE;color:#1E40AF}.badge.w{background:var(--gray-100);color:var(--gray-700)}
.fr{display:flex;gap:10px;margin-bottom:14px;flex-wrap:wrap;align-items:center}
.fr input,.fr select{padding:10px 14px;border:1px solid var(--gray-200);border-radius:8px;font-size:13px;background:var(--white)}.fr input{min-width:220px}
.modal-o{position:fixed;inset:0;background:rgba(0,0,0,.4);z-index:99;display:none;align-items:center;justify-content:center}.modal-o.on{display:flex}
.modal{background:var(--white);border-radius:16px;max-width:720px;width:94vw;max-height:88vh;overflow-y:auto;padding:32px;box-shadow:0 20px 60px rgba(0,0,0,.15)}
.modal .x{float:right;border:none;background:none;font-size:26px;cursor:pointer;color:var(--gray-500);line-height:1}
.modal label{display:block;font-size:12px;font-weight:600;color:var(--gray-500);margin-bottom:4px;margin-top:12px}
.modal input,.modal select,.modal textarea{width:100%;padding:10px 14px;border:1px solid var(--gray-200);border-radius:8px;font-size:13px;margin-bottom:6px}
.modal textarea{min-height:64px;resize:vertical}
.meta{display:grid;grid-template-columns:1fr 1fr;gap:10px;margin-bottom:10px;font-size:12px;color:var(--gray-500)}.meta strong{display:block;color:var(--ink);font-size:14px;margin-top:2px}
.mt{display:flex;gap:6px;flex-wrap:wrap;margin-bottom:12px}.mt span{padding:6px 14px;border:1px solid var(--gray-200);border-radius:100px;font-size:12px;font-weight:600;cursor:pointer;transition:.15s}.mt span.on{background:var(--cyan);color:var(--white);border-color:var(--cyan)}.mt span:hover{border-color:var(--cyan)}
.si{display:flex;align-items:center;gap:10px;padding:10px 14px;background:var(--gray-50);border-radius:8px;margin-bottom:6px;font-size:13px}.si .n{font-weight:700;color:var(--cyan);font-size:15px;min-width:20px}
.fl{display:flex;align-items:center;gap:8px;padding:8px 12px;background:var(--gray-50);border-radius:8px;margin-bottom:4px;font-size:12px}.fl .nm{font-weight:600;cursor:pointer}.fl .nm:hover{color:var(--cyan)}.fl .sz{font-size:10px;color:var(--gray-500)}
.up{border:2px dashed var(--gray-200);border-radius:10px;padding:14px;margin-top:8px;text-align:center}.up p{font-size:13px;color:var(--gray-500);margin-bottom:10px}.up input[type=file]{font-size:12px}
.ai-block{background:var(--cyan-l);border-radius:8px;padding:12px;margin:12px 0;font-size:13px}
.hi{font-size:11px;color:var(--gray-500);padding:2px 0}.hi .d{display:inline-block;width:6px;height:6px;border-radius:50%;background:var(--cyan);margin-right:6px;vertical-align:middle}
.chart-bar{display:flex;align-items:flex-end;gap:8px;height:160px;padding:0 4px}
.chart-bar>div{flex:1;border-radius:6px 6px 0 0;min-height:4px;transition:.3s}
.ai-chat{border:1px solid var(--gray-200);border-radius:10px;padding:14px;max-height:320px;overflow-y:auto;margin-bottom:12px;background:var(--white)}
.ai-chat .msg{margin-bottom:8px;padding:10px 14px;border-radius:10px;font-size:13px;max-width:88%;line-height:1.5}
.ai-chat .user{background:var(--cyan);color:var(--white);margin-left:auto}.ai-chat .bot{background:var(--gray-50);color:var(--ink)}
.ai-input{display:flex;gap:8px}.ai-input input{flex:1;padding:10px 14px;border:1px solid var(--gray-200);border-radius:8px;font-size:13px}
@media(max-width:768px){
.sidebar{width:0;overflow:hidden}.sidebar .logo,.sidebar nav,.sidebar .user{display:none}
.main{margin-left:0;max-width:100vw;padding:16px}
.stats{grid-template-columns:1fr 1fr}.meta{grid-template-columns:1fr}
}
.card{background:var(--w);border-radius:12px;padding:20px;margin-bottom:14px;border:1px solid var(--g2)}
.card h3{font-size:16px;margin-bottom:8px}
.row{display:flex;gap:12px;flex-wrap:wrap;margin-bottom:12px}
.stat{background:var(--w);border-radius:10px;padding:16px 20px;border:1px solid var(--g2);min-width:120px;flex:1;text-align:center}
.stat .n{font-size:26px;font-weight:800}.stat .l{font-size:12px;color:var(--g5)}
.stat.r .n{color:var(--rd)}.stat.g .n{color:var(--gn)}.stat.a .n{color:var(--am)}
table{width:100%;border-collapse:collapse}th,td{padding:8px 12px;text-align:left;font-size:13px}
th{font-weight:600;color:var(--g5);font-size:11px;text-transform:uppercase;border-bottom:2px solid var(--g2);cursor:pointer}
th:hover{color:var(--b)}td{border-bottom:1px solid var(--g2)}
tr.rd td{background:#FFF5F5}tr.am td{background:#FFFDF5}
.badge{display:inline-block;padding:3px 8px;border-radius:100px;font-size:11px;font-weight:700}
.badge.g{background:#D1FAE5;color:#065F46}.badge.a{background:#FEF3C7;color:#92400E}
.badge.r{background:#FEE2E2;color:#991B1B}.badge.b{background:#DBEAFE;color:#1E40AF}.badge.w{background:#eee;color:#666}
.fr{display:flex;gap:8px;margin-bottom:10px;flex-wrap:wrap;align-items:center}
.fr input,.fr select{padding:8px 12px;border:1px solid var(--g2);border-radius:6px;font-size:13px;background:var(--w)}
.fr input{min-width:200px}
.mt{display:flex;gap:4px;flex-wrap:wrap;margin-bottom:10px}
.mt span{padding:4px 10px;border:1px solid var(--g2);border-radius:100px;font-size:11px;font-weight:600;cursor:pointer}
.mt span.on{background:var(--c);color:var(--b)}
@media(max-width:600px){#app{padding:8px}.row{flex-direction:column}.stat{min-width:auto}}
</style>
</head>
<body>
<div id="loginBox"><div>
<div class="logo"><span>Qazaq</span>Telecom</div>
<p class="sub">План производственной безопасности 2026</p>
<h1><span>План ПБ</span> 2026</h1>
<p>АО «Казахтелеком»</p>
<input id="lem" placeholder="curator@telecom.kz">
<input id="lpw" type="password" placeholder="Пароль">
<p id="lerr" style="color:var(--red);font-size:12px;display:none;margin-bottom:8px">Неверная почта</p>
<button class="btn" style="width:100%;padding:14px" onclick="doLogin()">Войти</button>
<input id="lpw" type="password" placeholder="Пароль (любой)">
<p id="lerr" style="color:var(--rd);font-size:12px;display:none">Неверная почта</p>
<button class="btn" style="width:100%" onclick="doLogin()">Войти</button>
</div></div>
<div id="app" style="display:none">
<div class="sidebar">
<div class="logo"><span>Qazaq</span>Telecom</div>
<nav>
<a class="on" data-pg="ev" onclick="switchPg('ev')">📋 Мероприятия</a>
<a data-pg="an" onclick="switchPg('an')">📊 Аналитика</a>
<a data-pg="rp" onclick="switchPg('rp')">📥 Отчётность</a>
<a data-pg="ai" onclick="switchPg('ai')">🤖 ИИ-помощник</a>
</nav>
<div class="user" id="ul"></div>
</div>
<div class="main">
<div class="topbar">
<h2 id="pageTitle">Мероприятия</h2>
<div class="right">
<div style="position:relative"><button class="notif-btn" onclick="toggleN()">🔔<span class="cnt" id="nc">0</span></button><div class="notif-drop" id="nd"></div></div>
<button class="btn btn-ghost btn-sm" onclick="doLogout()">Выйти</button>
</div>
</div>
<div class="pg on" id="pg-ev"></div><div class="pg" id="pg-an"></div><div class="pg" id="pg-rp"></div><div class="pg" id="pg-ai"></div>
<div id="app">
<div class="top"><b><span>План ПБ</span> 2026</b><div class="r"><span id="ul"></span><button class="btn btn-sm btn-red" onclick="doLogout()">Выйти</button></div></div>
<div class="tabs">
<button class="tab on" data-pg="ev" onclick="switchPg('ev')">Мероприятия</button>
<button class="tab" data-pg="rp" onclick="switchPg('rp')">Отчёты</button>
</div>
<div class="pg on" id="pg-ev"></div>
<div class="pg" id="pg-rp"></div>
</div>
<div class="modal-o" id="mo"><div class="modal" id="mc"></div></div>
<script>
var sec=["I. Люди. Повышение культуры безопасности","II. Безопасность при эксплуатации оборудования","III. Предупреждение и готовность к ликвидации аварий и ЧС","IV. Информационно-разъяснительная работа","V. Внедрение ИИ и цифровизации"];
var br=["Дирекция ПБ","Дивизион «Сеть»","Корпоративный бизнес","Розничный бизнес","Сервисная фабрика","Телеком Комплект","Корпоративный университет","Управление проектами","Цифровой бизнес"];
var reg=["Центральный","Алматинский","Южный","Северный","Восточный","Западный"];
var st={wait:"Не начато",warn:"В процессе",late:"Просрочено",done:"Исполнено"};
var ms=["2026-01","2026-02","2026-03","2026-04","2026-05","2026-06","2026-07","2026-08","2026-09","2026-10","2026-11","2026-12"];
var mn=["Янв","Фев","Мар","Апр","Май","Июн","Июл","Авг","Сен","Окт","Ноя","Дек"];
var titles={ev:"Мероприятия",an:"Аналитика",rp:"Отчётность",ai:"ИИ-помощник"};
function M(i){var p=ms[i].split("-");return mn[parseInt(p[1])-1]+" "+p[0]}
function esc(s){return s.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}
function nl(s){return esc(s).replace(/\n/g,"<br>")}
function sb(s){var m={done:"g",warn:"a",late:"r",wait:"w"};return'<span class="badge '+m[s]+'">'+st[s]+'</span>'}
function daysLeft(e){
if(e.s==="done")return'<span style="color:var(--green)"></span>';
if(e.s==="late")return'<span style="color:var(--red);font-weight:700">ПРОСРОЧЕНО</span>';
var p=e.due.split(".");if(p.length!==3)return"";
var d=new Date(parseInt(p[2]),parseInt(p[1])-1,parseInt(p[0]));
var days=Math.round((d-new Date())/86400000);
if(days<0)return'<span style="color:var(--red);font-weight:700">'+Math.abs(days)+' дн.</span>';
if(days<=7)return'<span style="color:var(--red);font-weight:600">'+days+' дн.</span>';
if(days<=14)return'<span style="color:var(--amber);font-weight:600">'+days+' дн.</span>';
if(days<=30)return'<span style="color:var(--amber)">'+days+' дн.</span>';
return days+' дн.';
var U={"curator@telecom.kz":{n:"Куратор",b:0,r:"cur"},"dpp@telecom.kz":{n:"Директор ДПБ",b:0,r:"br"}};
var cu=null,ev=null;
function doLogin(){
var e=document.getElementById("lem").value.trim().toLowerCase();
if(U[e]){cu={em:e,n:U[e].n,b:U[e].b,r:U[e].r};localStorage.setItem("su",JSON.stringify(cu));showApp()}else{document.getElementById("lerr").style.display="block"}
}
function rowClass(e){if(e.s==="late")return"rd";if(e.s==="done")return"";var p=e.due.split(".");if(p.length!==3)return"";var d=new Date(parseInt(p[2]),parseInt(p[1])-1,parseInt(p[0]));var days=Math.round((d-new Date())/86400000);if(days<=14)return"rd";if(days<=30)return"am";return""}
var U={"curator@telecom.kz":{n:"Куратор ПБ",b:0,r:"cur"},"dpp@telecom.kz":{n:"Директор ДПБ",b:0,r:"br"},"ahmetov@telecom.kz":{n:"Ахметов К.Т.",b:6,r:"br"},"serikov@telecom.kz":{n:"Сериков А.М.",b:1,r:"br"},"nurlanov@telecom.kz":{n:"Нурланов Д.С.",b:8,r:"br"},"aliev@telecom.kz":{n:"Алиев Г.С.",b:4,r:"br"},"tulegenov@telecom.kz":{n:"Тулегенов Е.А.",b:2,r:"br"},"saparov@telecom.kz":{n:"Сапаров А.Д.",b:3,r:"br"},"maratov@telecom.kz":{n:"Маратов Ж.К.",b:5,r:"br"},"iskakov@telecom.kz":{n:"Искаков Р.Н.",b:7,r:"br"}};
var cu=null,ev=null,cm=5,esi=-1,ex={},chatHistory=[];
function getMD(id,si){var k=si>=0?"sf_"+id+"_s"+si:"sf_"+id;var r=localStorage.getItem(k);return r?JSON.parse(r):{}}
function setMD(id,o,si){var k=si>=0?"sf_"+id+"_s"+si:"sf_"+id;localStorage.setItem(k,JSON.stringify(o))}
function gsc(id){var r=localStorage.getItem("ss_"+id);return r?JSON.parse(r):[]}
function ssc(id,a){localStorage.setItem("ss_"+id,JSON.stringify(a))}
function doLogin(){var e=document.getElementById("lem").value.trim().toLowerCase();if(U[e]){cu={em:e,n:U[e].n,b:U[e].b,r:U[e].r};localStorage.setItem("su",JSON.stringify(cu));showApp()}else document.getElementById("lerr").style.display="block"}
function doLogout(){localStorage.removeItem("su");cu=null;document.getElementById("loginBox").style.display="flex";document.getElementById("app").style.display="none"}
function showApp(){document.getElementById("loginBox").style.display="none";document.getElementById("app").style.display="flex";document.getElementById("ul").textContent=cu.n;loadEvents()}
function loadEvents(){var s=localStorage.getItem("se4");if(s){try{ev=JSON.parse(s);renderEv();return}catch(e){}}var x=new XMLHttpRequest();x.open("GET","data.json",true);x.onload=function(){if(x.status===200){try{ev=JSON.parse(x.responseText);saveEv()}catch(e){ev=[]}};renderEv()};x.onerror=function(){ev=[];renderEv()};x.send()}
function saveEv(){localStorage.setItem("se4",JSON.stringify(ev||[]))}
function showApp(){
document.getElementById("loginBox").style.display="none";
document.getElementById("app").style.display="block";
document.getElementById("ul").innerHTML="<b>"+cu.n+"</b>";
loadEvents();
}
function loadEvents(){
var s=localStorage.getItem("se3");
if(s){try{ev=JSON.parse(s);renderEv();return}catch(e){}}
var x=new XMLHttpRequest();
x.open("GET","data.json",true);
x.onload=function(){if(x.status===200){try{ev=JSON.parse(x.responseText);localStorage.setItem("se3",JSON.stringify(ev))}catch(e){ev=[]}};renderEv()};
x.onerror=function(){ev=[];renderEv()};
x.send();
}
function saveEv(){localStorage.setItem("se3",JSON.stringify(ev||[]))}
function switchPg(n){
document.querySelectorAll(".sidebar nav a").forEach(function(a){a.classList.remove("on")});
document.querySelectorAll(".tab").forEach(function(t){t.classList.remove("on")});
document.querySelector('[data-pg="'+n+'"]').classList.add("on");
document.querySelectorAll(".pg").forEach(function(p){p.classList.remove("on")});
document.getElementById("pg-"+n).classList.add("on");
document.getElementById("pageTitle").textContent=titles[n];
if(n==="ev")renderEv();else if(n==="an")renderAn();else if(n==="rp")renderRp();else if(n==="ai")renderAi();
if(n==="ev")renderEv();
}
// ===== EVENTS =====
function toggleEx(id){ex[id]=!ex[id];renderEv()}
function ts(id,si,chk){var s=gsc(id);if(chk&&s.indexOf(si)<0)s.push(si);else if(!chk)s=s.filter(function(x){return x!==si});ssc(id,s);var e=null;for(var i=0;i<ev.length;i++)if(ev[i].id===id){e=ev[i];break}if(e&&e.sub){var p=Math.round(s.length/e.sub.length*100);if(s.length===e.sub.length&&e.s!=="done")e.s="done";e.p=Math.max(e.p,p);e.h.push(new Date().toLocaleDateString()+" "+cu.n+": подпункты "+s.length+"/"+e.sub.length);saveEv()}renderEv()}
function renderEv(){
var all=ev||[],sf=(document.getElementById("sf2")||{}).value||"",sr2=(document.getElementById("sr2")||{}).value||"",bf=(document.getElementById("bf2")||{}).value||"";
var list=all;if(sf)list=list.filter(function(e){return e.s===sf});if(sr2)list=list.filter(function(e){return e.t.toLowerCase().indexOf(sr2.toLowerCase())>=0||br[e.b].toLowerCase().indexOf(sr2.toLowerCase())>=0});if(bf)list=list.filter(function(e){return e.b===parseInt(bf)});nu();
var h="<div class='card'><div class='fr'><input id='sr2' placeholder='Поиск по названию или филиалу...' oninput='renderEv()'><select id='sf2' onchange='renderEv()'><option value=''>Все статусы</option><option value='wait'>Не начато</option><option value='warn'>В процессе</option><option value='done'>Исполнено</option><option value='late'>Просрочено</option></select><select id='bf2' onchange='renderEv()'><option value=''>Все филиалы</option>";
for(var i=0;i<br.length;i++)h+="<option value='"+i+"'>"+br[i]+"</option>";
h+="</select><span style='font-size:12px;color:var(--gray-500);margin-left:auto'>"+list.length+" из "+all.length+"</span></div><table><tr><th></th><th>Мероприятие</th><th>Ответственные</th><th>Раздел</th><th>Срок</th><th>Осталось</th><th>Статус</th><th></th></tr>";
list.forEach(function(e){
var hs=e.sub&&e.sub.length,sc=e.sub?gsc(e.id):[],sdd=hs?sc.length:0,stt=hs?e.sub.length:0,cl=rowClass(e);
h+="<tr class='"+cl+"'><td>"+e.id+"</td><td style='font-size:12px;max-width:320px'>";
if(hs)h+="<span onclick='event.stopPropagation();toggleEx("+e.id+")' style='cursor:pointer;margin-right:6px'>"+(ex[e.id]?'▼':'▶')+"</span>";
h+=esc(e.t);if(hs)h+=" <span style='font-size:10px;color:var(--gray-500)'>("+sdd+"/"+stt+")</span>";
h+="</td><td style='font-size:11px'>"+nl(e.r)+"</td><td style='font-size:11px'>"+sec[e.sec]+"</td><td>"+e.due+"</td><td style='font-size:12px'>"+daysLeft(e)+"</td><td>"+sb(e.s)+"</td><td><button class='btn btn-sm' onclick='oe("+e.id+")'>📝</button></td></tr>";
if(hs&&ex[e.id])e.sub.forEach(function(sb,i){var ch=sc.indexOf(i)>=0;h+="<tr style='background:var(--gray-50)'><td></td><td style='font-size:11px;padding-left:40px'><input type='checkbox' "+(ch?"checked":"")+" onchange='ts("+e.id+","+i+",this.checked)'> "+sb.l+") "+esc(sb.t)+"</td><td></td><td></td><td></td><td></td><td></td><td></td></tr>"});
});
h+="</table></div>";document.getElementById("pg-ev").innerHTML=h;
}
// ===== ANALYTICS =====
function renderAn(){
var all=ev||[],done=all.filter(function(e){return e.s==="done"}),late=all.filter(function(e){return e.s==="late"}),warn=all.filter(function(e){return e.s==="warn"}),wait=all.filter(function(e){return e.s==="wait"});
var dp=all.length?Math.round(done.length/all.length*100):0;
var h="<div class='stats'><div class='stat'><div class='n'>"+all.length+"</div><div class='l'>Всего</div></div><div class='stat g'><div class='n'>"+done.length+"</div><div class='l'>Исполнено ("+dp+"%)</div></div><div class='stat a'><div class='n'>"+warn.length+"</div><div class='l'>В процессе</div></div><div class='stat r'><div class='n'>"+late.length+"</div><div class='l'>Просрочено</div></div><div class='stat'><div class='n'>"+wait.length+"</div><div class='l'>Не начато</div></div></div>";
h+="<div class='fr' style='margin-bottom:16px'><button class='btn btn-sm' onclick='dAnCSV()'>📥 Скачать CSV (все)</button><button class='btn btn-sm btn-ghost' onclick='dAnHTML()'>📄 Скачать HTML (все)</button></div>";
// Chart
h+="<div class='card'><h3>Динамика по кварталам</h3><div class='chart-bar'><div style='height:55%;background:var(--green)'></div><div style='height:70%;background:var(--green)'></div><div style='height:82%;background:var(--cyan)'></div><div style='height:"+dp+"%;background:var(--cyan)'></div></div><div style='display:flex;gap:8px;padding:8px 0 0;font-size:11px;color:var(--gray-500);text-align:center'><span style='flex:1'>Q1 факт</span><span style='flex:1'>Q2 прогноз</span><span style='flex:1'>Q3 план</span><span style='flex:1'>Q4 цель</span></div></div>";
// Branch ranking
var brData=[];br.forEach(function(b,i){var it=all.filter(function(e){return e.b===i});var d=it.filter(function(e){return e.s==="done"}).length;var l=it.filter(function(e){return e.s==="late"}).length;var p=it.length?Math.round(d/it.length*100):0;brData.push({name:b,pct:p,done:d,total:it.length,late:l})});brData.sort(function(a,b){return a.pct-b.pct});
h+="<div class='card'><h3>Рейтинг филиалов</h3><table><tr><th>Филиал</th><th>Исполнено</th><th>%</th><th>Просрочено</th></tr>";
brData.forEach(function(b){h+="<tr><td><b>"+b.name+"</b></td><td>"+b.done+"/"+b.total+"</td><td><span style='color:"+(b.pct>=70?"var(--green)":b.pct>=40?"var(--amber)":"var(--red)")+";font-weight:700'>"+b.pct+"%</span></td><td>"+(b.late?b.late:"—")+"</td></tr>"});h+="</table></div>";
// TOP problems
var problems=late.concat(all.filter(function(e){return e.s==="warn"&&e.p<30})).sort(function(a,b){return a.p-b.p}).slice(0,10);
if(problems.length){h+="<div class='card'><h3>ТОП проблемных мероприятий</h3><table><tr><th></th><th>Мероприятие</th><th>Филиал</th><th>Статус</th><th>Срок</th></tr>";problems.forEach(function(e){h+="<tr><td>"+e.id+"</td><td style='font-size:12px'>"+esc(e.t.slice(0,80))+"...</td><td>"+br[e.b]+"</td><td>"+sb(e.s)+"</td><td>"+daysLeft(e)+"</td></tr>"});h+="</table></div>"}
document.getElementById("pg-an").innerHTML=h;
}
// ===== NOTIFICATIONS =====
function toggleN(){nu();document.getElementById("nd").classList.toggle("on")}
function nu(){var all=ev||[],n=[],now=new Date();all.forEach(function(e){if(e.s==="late"){n.push({c:"🔴",m:"Просрочено: №"+e.id+" — "+e.t.slice(0,45)+"...",t:e.due});return}if(e.s==="done")return;var p=e.due.split(".");if(p.length===3){var d=new Date(parseInt(p[2]),parseInt(p[1])-1,parseInt(p[0]));var days=Math.round((d-now)/86400000);if(days<=1&&days>=0)n.push({c:"🔴",m:"СРОЧНО! 1 день: №"+e.id,t:e.due});else if(days<=7)n.push({c:"🟠",m:"7 дн: №"+e.id+" — "+e.t.slice(0,35)+"...",t:e.due});else if(days<=14)n.push({c:"🟡",m:"14 дн: №"+e.id+" — "+e.t.slice(0,35)+"...",t:e.due});else if(days<=30)n.push({c:"🔵",m:"30 дн: №"+e.id+" — "+e.t.slice(0,35)+"...",t:e.due})}});n.sort(function(a,b){var o={"🔴":0,"🟠":1,"🟡":2,"🔵":3};return(o[a.c]||9)-(o[b.c]||9)});
document.getElementById("nc").textContent=n.length;document.getElementById("nc").style.display=n.length?"inline-block":"none";
document.getElementById("nd").innerHTML=n.length?n.map(function(x){return"<div class='it'><b>"+x.c+" "+esc(x.m)+"</b><span>Срок: "+x.t+"</span></div>"}).join(""):"<div class='it' style='text-align:center;color:var(--gray-500)'>Нет уведомлений</div>"}
function dAnCSV(){var all=ev||[],csv="\uFEFF№;Филиал;Мероприятие;Подпункты;Раздел;Статус;Прогресс;Срок;Осталось;Факт;Описание\n";all.forEach(function(e){var rep="";var d=getMD(e.id,-1);for(var k in d)if(d.hasOwnProperty(k)&&d[k]&&d[k].report)rep+=d[k].report.replace(/"/g,'""')+"; ";csv+=e.id+";"+br[e.b]+";\""+e.t.replace(/"/g,'""')+"\";"+(e.sub?e.sub.length:"—")+";"+sec[e.sec]+";"+st[e.s]+";"+e.p+"%;"+e.due+";"+daysLeft(e).replace(/<[^>]*>/g,"")+";"+(e.done||"—")+";\""+rep+"\"\n"});var a=document.createElement("a");a.href=URL.createObjectURL(new Blob([csv]));a.download="analitika.csv";a.click()}
function dAnHTML(){var all=ev||[];var h="<!DOCTYPE html><html><head><meta charset='utf-8'><title>Аналитика ПБ</title><style>body{font:13px/1.5 Arial;max-width:1100px;margin:0 auto;padding:24px}h1{color:#0B1A2E}h2{color:#00B4D8;margin-top:24px}table{width:100%;border-collapse:collapse;margin-bottom:16px}th,td{padding:8px 12px;text-align:left;font-size:12px;border:1px solid #ddd}th{background:#0B1A2E;color:#fff;font-weight:600}.g{color:#10B981}.a{color:#F59E0B}.r{color:#EF4444}.w{color:#64748B}.done td{background:#f0fff4}.late td{background:#fff5f5}</style></head><body><h1>📊 Аналитика ПБ — все мероприятия</h1><p>Сформирован: "+new Date().toLocaleDateString()+"</p><table><tr><th></th><th>Мероприятие</th><th>Подпункты</th><th>Филиал</th><th>Раздел</th><th>Статус</th><th>Срок</th><th>Осталось</th><th>Факт</th></tr>";
all.forEach(function(e){var cl=e.s==="done"?"done":e.s==="late"?"late":"";h+="<tr class='"+cl+"'><td>"+e.id+"</td><td>"+esc(e.t)+"</td><td>"+(e.sub?e.sub.length:"—")+"</td><td>"+esc(br[e.b])+"</td><td>"+sec[e.sec]+"</td><td><b class='"+{done:"g",warn:"a",late:"r",wait:"w"}[e.s]+"'>"+st[e.s]+"</b></td><td>"+e.due+"</td><td>"+daysLeft(e).replace(/<[^>]*>/g,"")+"</td><td>"+(e.done||"—")+"</td></tr>"});
h+="</table></body></html>";
try{var a=document.createElement("a");a.href=URL.createObjectURL(new Blob(["\uFEFF"+h],{type:"text/html"}));a.download="analitika.html";a.click()}catch(e){alert("Слишком большой")}}
function renderRp(){var b=0;for(var i=0;i<localStorage.length;i++){var k=localStorage.key(i);if(k.indexOf("sf_")===0)b+=localStorage.getItem(k).length*2}
var h="<div class='card'><h3>Сводный отчёт</h3><div class='fr'><select id='rf'>";for(var i=0;i<ms.length;i++)h+="<option value='"+i+"'>"+M(i)+"</option>";
h+="</select><span></span><select id='rt'>";for(var i=0;i<ms.length;i++)h+="<option value='"+i+"'"+(i===11?" selected":"")+">"+M(i)+"</option>";
h+="</select><button class='btn btn-sm' onclick='dCSV()'>CSV</button><button class='btn btn-sm' onclick='dHTML()'>HTML</button></div>";
h+="<p style='font-size:12px;color:var(--gray-500);margin-bottom:10px'>Хранилище: "+(b>1048576?(b/1048576).toFixed(1)+" МБ":(b/1024).toFixed(0)+" КБ")+"</p>";
h+="<button class='btn btn-sm btn-gn' onclick='exp()'>💾 Сохранить всё</button> <button class='btn btn-sm btn-ghost' onclick=\"document.getElementById('if').click()\">📥 Загрузить</button> <input type='file' id='if' accept='.json' style='display:none' onchange='imp(this)'> <button class='btn btn-sm btn-red' onclick='clr()'>🗑 Очистить</button></div>";
document.getElementById("pg-rp").innerHTML=h}
function dCSV(){var f=parseInt(document.getElementById("rf").value),t=parseInt(document.getElementById("rt").value),all=ev||[],csv="\uFEFF№;Филиал;Мероприятие;Статус;Осталось;Срок\n";all.forEach(function(e){csv+=e.id+";"+br[e.b]+";\""+e.t.replace(/"/g,'""')+"\";"+st[e.s]+";"+daysLeft(e).replace(/<[^>]*>/g,"")+";"+e.due+"\n"});var a=document.createElement("a");a.href=URL.createObjectURL(new Blob([csv]));a.download="otchet.csv";a.click()}
function dHTML(){var f=parseInt(document.getElementById("rf").value),t=parseInt(document.getElementById("rt").value),all=ev||[],h="<!DOCTYPE html><html><head><meta charset='utf-8'><title>Отчёт ПБ</title><style>body{font:13px/1.5 Arial;max-width:1000px;margin:0 auto;padding:24px}.ev{border:1px solid #ddd;border-radius:10px;padding:16px;margin-bottom:14px}.badge{display:inline-block;padding:3px 8px;border-radius:4px;font-size:10px;font-weight:700}.g{background:#D1FAE5;color:#065F46}.a{background:#FEF3C7;color:#92400E}.r{background:#FEE2E2;color:#991B1B}.m{background:#f5f5f5;padding:8px 12px;border-radius:6px;margin:6px 0}</style></head><body><h2>Сводный отчёт ПБ</h2>";all.forEach(function(e){var cl={done:"g",warn:"a",late:"r",wait:""}[e.s];h+="<div class='ev'><h3>"+e.id+". "+esc(e.t)+"</h3><p>"+br[e.b]+" | "+sec[e.sec]+" | Срок: "+e.due+" | <span class='badge "+cl+"'>"+st[e.s]+"</span></p>";var d=getMD(e.id,-1);for(var i=f;i<=t;i++){var m=ms[i];if(d[m]&&d[m].report)h+="<div class='m'><b>"+M(i)+"</b><p>"+esc(d[m].report)+"</p></div>"}if(e.sub)e.sub.forEach(function(s,si){var sd=getMD(e.id,si);for(var i=f;i<=t;i++){var m=ms[i];if(sd[m]&&sd[m].report)h+="<div class='m' style='border-left:3px solid #00B4D8'><b>"+s.l+") "+M(i)+"</b><p>"+esc(sd[m].report)+"</p></div>"}});h+="</div>"});h+="</body></html>";try{var a=document.createElement("a");a.href=URL.createObjectURL(new Blob(["\uFEFF"+h],{type:"text/html"}));a.download="otchet.html";a.click()}catch(e){alert("Слишком большой отчёт")}}
function exp(){var d={events:ev,date:new Date().toISOString(),files:{},sc:{}};for(var i=0;i<localStorage.length;i++){var k=localStorage.key(i);if(k.indexOf("sf_")===0)d.files[k]=localStorage.getItem(k);if(k.indexOf("ss_")===0)d.sc[k]=localStorage.getItem(k)}var a=document.createElement("a");a.href=URL.createObjectURL(new Blob([JSON.stringify(d)]));a.download="backup.json";a.click()}
function imp(inp){if(!inp.files.length)return;var r=new FileReader();r.onload=function(evt){try{var d=JSON.parse(evt.target.result);ev=d.events;saveEv();for(var k in d.files)localStorage.setItem(k,d.files[k]);for(var k in d.sc)localStorage.setItem(k,d.sc[k]);alert("OK. Обновите.");location.reload()}catch(e){alert("Ошибка")}};r.readAsText(inp.files[0])}
function clr(){if(!confirm("Удалить все файлы?"))return;var ks=[];for(var i=0;i<localStorage.length;i++){var k=localStorage.key(i);if(k.indexOf("sf_")===0||k.indexOf("ss_")===0)ks.push(k)}ks.forEach(function(k){localStorage.removeItem(k)});alert("Очищено");renderRp()}
// ===== AI (expanded) =====
function renderAi(){
var all=ev||[],done=all.filter(function(e){return e.s==="done"}),late=all.filter(function(e){return e.s==="late"}),dp=all.length?Math.round(done.length/all.length*100):0;
var h="<div class='card' style='background:linear-gradient(135deg,var(--ink),#1a3a5c);color:var(--white);border:none'><h3 style='color:var(--cyan);font-size:20px'>🤖 ИИ-помощник по производственной безопасности</h3><p style='color:rgba(255,255,255,.6);font-size:13px'>Анализ исполнения Плана мероприятий. Задайте вопрос — получу нужную информацию из системы.</p></div>";
h+="<div class='stats'><div class='stat g'><div class='n'>"+dp+"%</div><div class='l'>Выполнено</div></div><div class='stat r'><div class='n'>"+late.length+"</div><div class='l'>Просрочено</div></div><div class='stat b'><div class='n'>"+all.length+"</div><div class='l'>Всего мероприятий</div></div></div>";
var now=new Date(),risks=[];all.forEach(function(e){if(e.s!=="done"&&e.s!=="late"){var p=e.due.split(".");if(p.length===3){var d=new Date(parseInt(p[2]),parseInt(p[1])-1,parseInt(p[0]));var days=Math.round((d-now)/86400000);var risk="низкий";if(days<=7)risk="критический";else if(days<=14)risk="высокий";else if(days<=30)risk="средний";if(risk!=="низкий")risks.push({e:e,risk:risk,days:days})}}});risks.sort(function(a,b){return a.days-b.days});
if(risks.length){h+="<div class='card' style='border-left:4px solid var(--red)'><h3>⚠️ Прогноз рисков невыполнения</h3><table><tr><th></th><th>Мероприятие</th><th>Уровень риска</th><th>Осталось дней</th></tr>";risks.slice(0,10).forEach(function(r){var cl=r.risk==="критический"?"r":r.risk==="высокий"?"a":"w";h+="<tr><td>"+r.e.id+"</td><td style='font-size:12px'>"+esc(r.e.t.slice(0,60))+"...</td><td><span class='badge "+cl+"'>"+r.risk+"</span></td><td>"+r.days+" дн.</td></tr>"});h+="</table></div>"}
h+="<p style='font-size:12px;color:var(--gray-500);margin:8px 0'>Спросите: «просроченные», «риски», «сводка», «статус пункта 15», «рейтинг филиалов», «график», «отстающие», «документы», «сроки»</p>";
h+="<div class='ai-chat' id='aiChat'>"+chatHistory.map(function(m){return"<div class='msg "+m.role+"'>"+m.text+"</div>"}).join("")+"</div>";
h+="<div class='ai-input'><input id='aiQ' placeholder='Задайте вопрос ИИ-помощнику...' onkeydown='if(event.keyCode===13)aiAsk()'><button class='btn' onclick='aiAsk()'>Спросить</button></div>";
document.getElementById("pg-ai").innerHTML=h;
}
function aiAsk(){var q=(document.getElementById("aiQ").value||"").trim().toLowerCase();if(!q)return;document.getElementById("aiQ").value="";chatHistory.push({role:"user",text:"<b>Вы:</b> "+esc(q)});chatHistory.push({role:"bot",text:"<b>🤖 ИИ:</b> "+aiAnswer(q)});renderAi();var el=document.getElementById("aiChat");if(el)el.scrollTop=el.scrollHeight}
function aiAnswer(q){
var all=ev||[],now=new Date(),late=all.filter(function(e){return e.s==="late"}),done=all.filter(function(e){return e.s==="done"}),warn=all.filter(function(e){return e.s==="warn"}),dp=all.length?Math.round(done.length/all.length*100):0;
function bs(){var r=[];br.forEach(function(b,i){var it=all.filter(function(e){return e.b===i}),d=it.filter(function(e){return e.s==="done"}).length,l=it.filter(function(e){return e.s==="late"}).length;r.push({name:b,done:d,total:it.length,late:l,pct:it.length?Math.round(d/it.length*100):0})});r.sort(function(a,b){return b.pct-a.pct});return r}
function cr(e){if(e.s==="done")return{l:"отсутствует",p:0};if(e.s==="late")return{l:"критический",p:100};var s=0;var p=e.due.split(".");if(p.length===3){var d=new Date(parseInt(p[2]),parseInt(p[1])-1,parseInt(p[0])),days=Math.round((d-now)/86400000);if(days<=7)s+=40;else if(days<=14)s+=25;else if(days<=30)s+=15}if(e.p<20)s+=25;else if(e.p<50)s+=15;var md=getMD(e.id,-1),hr=false;for(var k in md)if(md.hasOwnProperty(k)&&md[k]&&md[k].report)hr=true;if(!hr)s+=20;var l=s>=60?"критический":s>=35?"высокий":s>=15?"средний":"низкий";return{l:l,p:Math.min(s,95)}}
var qq=q.toLowerCase();
if(qq.indexOf("просрочен")>=0){if(!late.length)return"Просрочек нет.";var r="<b>Просрочено "+late.length+":</b><br>";late.forEach(function(e){r+="• №"+e.id+" — "+esc(e.t.slice(0,70))+"...<br> "+br[e.b]+" | срок "+e.due+"<br>"});return r}
if(qq.indexOf("текущ")>=0||qq.indexOf("месяц")>=0){var dtm=all.filter(function(e){if(e.s==="done"||e.s==="late")return false;var p=e.due.split(".");return p.length===3&&parseInt(p[1])===(now.getMonth()+1)});return dtm.length?"<b>К завершению в этом месяце ("+dtm.length+"):</b><br>"+dtm.map(function(e){return"• №"+e.id+" — "+esc(e.t.slice(0,60))+"... ("+e.due+")"}).join("<br>"):"В этом месяце срочных мероприятий нет."}
if(qq.indexOf("риск")>=0||qq.indexOf("прогноз")>=0){var risks=[];all.forEach(function(e){if(e.s!=="done"){var c=cr(e);if(c.l!=="низкий")risks.push({e:e,risk:c})}});risks.sort(function(a,b){return b.risk.p-a.risk.p});if(!risks.length)return"Рисков не выявлено.";var r="<b>Прогноз рисков:</b><br>";risks.slice(0,8).forEach(function(x){r+="• <b>№"+x.e.id+"</b> — "+x.risk.p+"% ("+x.risk.l+") — "+esc(x.e.t.slice(0,50))+"...<br>"});return r}
if(qq.indexOf("рейтинг")>=0||qq.indexOf("филиал")>=0||qq.indexOf("сравн")>=0){var bsd=bs(),r="<b>Рейтинг филиалов:</b><br>";bsd.forEach(function(b,i){r+=(i+1)+". "+b.name+" — "+b.pct+"% ("+b.done+"/"+b.total+(b.late?", просрочено:"+b.late:"")+")<br>"});return r}
if(qq.indexOf("сводка")>=0||qq.indexOf("ежедн")>=0||qq.indexOf("утр")>=0){return"<b>Сводка на "+new Date().toLocaleDateString()+"</b><br>• План: "+dp+"% ("+done.length+"/"+all.length+")<br>• Просрочено: "+late.length+"<br>В процессе: "+warn.length+"<br>Не начато: "+(all.length-done.length-late.length-warn.length)+"<br><br><b>→ Рекомендации:</b><br>"+(late.length?"• Эскалировать просрочки<br>":"")+"• Проверить подтверждающие документы<br>• Запросить отчёты у отстающих";}
if(qq.indexOf("советник")>=0||qq.indexOf("директор")>=0){var bsd=bs(),w3=bsd.slice(-3).map(function(b){return b.name+" ("+b.pct+"%)"}).join(", ");return"<b>👔 Советник директора по ПБ:</b><br><br><b>Выводы:</b><br>• План: "+dp+"%. "+(dp>=70?"Темп хороший.":dp>=40?"Темп средний.":"Критично!")+"<br>• Просрочено: "+late.length+"<br><br><b>Риски:</b> "+w3+"<br><br><b>Решения:</b><br>1. Совещание с отстающими филиалами<br>2. Еженедельный контроль просрочек<br>3. Запросить документы у всех в статусе «В процессе»<br>4. Усилить ИИ-мониторинг<br>5. Доклад Правлению";}
if(qq.indexOf("почему")>=0||qq.indexOf("причин")>=0){return"<b>Причины отставания:</b><br>• Отсутствие текстовых отчётов<br>• Нет подтверждающих файлов<br>• Низкая активность исполнителей<br>• Приближение сроков без обновлений<br><br><b>→ Решение:</b> активизировать загрузку отчётов и документов.";}
if(qq.indexOf("проверк")>=0||qq.indexOf("качеств")>=0||qq.indexOf("подтвержд")>=0){var nf=all.filter(function(e){if(e.s==="done")return false;var d=getMD(e.id,-1),h=false;for(var k in d)if(d.hasOwnProperty(k)&&d[k]&&d[k].files&&d[k].files.length)h=true;return !h});return"<b>Проверка качества:</b><br>• Без файлов: "+nf.length+" мероприятий<br>• Полнота: "+(100-Math.round(nf.length/all.length*100))+"%<br><br><b>→ Рекомендация:</b> запросить недостающие документы.";}
if(qq.indexOf("аудит")>=0)return"<b>🔎 AI-аудитор:</b><br>• "+late.length+" мероприятий с нарушением сроков<br>• Рекомендуется аудит отстающих филиалов<br>• Проверить: обучение, медосмотры, СИЗ, инструктажи";
if(qq.indexOf("360")>=0||qq.indexOf("комплекс")>=0){var bsd=bs();return"<b>ПБ 360°:</b><br>• План: "+dp+"%<br>• Зона риска: "+bsd.filter(function(b){return b.pct<50}).map(function(b){return b.name}).join(", ")+"<br>• Приоритет: устранить просрочки, активизировать отчётность";}
if(qq.indexOf("показател")>=0||qq.indexOf("kpi")>=0){var bsd=bs();return"<b>KPI безопасности:</b><br>• План: "+dp+"%<br>• Лучший: "+bsd[0].name+" ("+bsd[0].pct+"%)<br>• Худший: "+bsd[bsd.length-1].name+" ("+bsd[bsd.length-1].pct+"%)<br>• Просрочено: "+late.length;}
if(qq.indexOf("статус")>=0||qq.indexOf("пункт")>=0){var num=q.match(/\d+/);if(num){var e=null;for(var i=0;i<all.length;i++)if(all[i].id===parseInt(num[0])){e=all[i];break}if(e){var c=cr(e);return"<b>Пункт №"+e.id+"</b><br>Статус: "+st[e.s]+"<br>Филиал: "+br[e.b]+"<br>Срок: "+e.due+"<br>Риск: "+c.l+" ("+c.p+"%)";}return"Пункт №"+num[0]+" не найден.";}}
if(qq.indexOf("привет")>=0||qq.indexOf("здрав")>=0||qq.indexOf("помощ")>=0)return"👋 Я ИИ-помощник по ПБ АО «Казахтелеком». Спросите: «сводка», «риски», «рейтинг филиалов», «советник», «статус пункта N».";
return"Спросите: <b>сводка</b> · <b>риски</b> · <b>рейтинг филиалов</b> · <b>советник</b> · <b>просроченные</b> · <b>проверка</b> · <b>аудит</b> · <b>360</b> · <b>статус пункта N</b> · <b>причины</b> · <b>показатели</b>";
}
// ===== EDIT (no regions) =====
function oe(id,mi,si){
if(typeof mi==="number")cm=mi;esi=(typeof si==="number")?si:-1;
var e=null;for(var i=0;i<ev.length;i++)if(ev[i].id===id){e=ev[i];break}if(!e)return;
var m=ms[cm],md=getMD(e.id,-1),cd=md[m]||{report:"",files:[]},cfs=cd.files||[];
var h="<span class='x' onclick='closeM()'>&times;</span>";
h+="<h3 style='margin-bottom:4px;padding-right:30px'>"+e.id+". "+esc(e.t)+"</h3>";
h+="<div class='meta'><div>Филиал<strong>"+br[e.b]+"</strong></div><div>Срок<strong>"+e.due+"</strong></div><div>Статус<strong>"+st[e.s]+"</strong></div><div>Осталось<strong>"+daysLeft(e)+"</strong></div></div>";
if(e.sub&&e.sub.length){
h+="<label>Подпункты</label>";
e.sub.forEach(function(sb,i){var isA=esi===i;
h+="<div class='si' style='"+(isA?"border:2px solid var(--cyan)":"")+"'><span class='n'>"+sb.l+")</span> <span style='flex:1;font-size:12px'>"+esc(sb.t)+"</span><button class='btn btn-sm' onclick='oe("+e.id+","+cm+","+i+")' style='"+(isA?"background:var(--cyan);color:var(--white)":"")+"'>"+(isA?"📂 Открыто":"📎 Файлы")+"</button></div>";
if(isA){var sd=getMD(e.id,i),scd=sd[m]||{report:"",files:[]},scfs=scd.files||[];
h+="<div style='margin:0 0 12px 16px;padding:16px;background:var(--cyan-l);border-radius:10px;border:2px solid var(--cyan)'>";
h+="<b>"+sb.l+") "+esc(sb.t)+"</b><p style='font-size:11px;color:var(--gray-500);margin:4px 0 10px'>"+M(cm)+"</p>";
h+="<label>Описание</label><textarea id='mr2_s"+i+"'>"+esc(scd.report||"")+"</textarea>";
h+="<label>Количество</label><input type='number' id='mq2_s"+i+"' min='0' value='"+(scd.qty||0)+"'>";
scfs.forEach(function(f,fi){h+="<div class='fl'><span class='nm' onclick='dlF2("+e.id+","+cm+","+fi+","+i+")'>📄 "+esc(f.name)+"</span><span class='sz'>"+(f.size/1024).toFixed(0)+" КБ · "+(f.date||"")+"</span><button onclick='rmF2("+e.id+","+cm+","+fi+","+i+")' style='border:none;color:var(--red);cursor:pointer;font-size:14px'>×</button></div>"});
h+="<div class='up'><input type='file' id='fi2_s"+i+"' multiple><button class='btn btn-sm' id='ub2_s"+i+"' onclick='upF2("+e.id+","+cm+","+i+")' style='margin-top:8px'>📤 Загрузить</button><p style='font-size:10px;color:var(--gray-500);margin-top:6px'>PDF, DOC/DOCX, XLS/XLSX, JPG/PNG, PPT/PPTX · до 3 МБ</p></div></div>";
}
var h="<div class='card'><p>Загрузка...</p></div>";
if(ev&&ev.length){
h="<div class='card'><div class='fr'><span>Всего: "+ev.length+" мероприятий</span></div><table><tr><th></th><th>Мероприятие</th><th>Филиал</th><th>Срок</th><th>Статус</th></tr>";
ev.forEach(function(e){
var scl={done:"g",warn:"a",late:"r",wait:"w"}[e.s]||"w";
var stt={done:"Исполнено",warn:"В процессе",late:"Просрочено",wait:"Не начато"}[e.s]||"—";
h+="<tr><td>"+e.id+"</td><td style='font-size:12px'>"+escHtml(e.t)+"</td><td style='font-size:11px'>"+e.b+"</td><td>"+e.due+"</td><td><span class='badge "+scl+"'>"+stt+"</span></td></tr>";
});
h+="<label>Месяц</label><div class='mt'>";ms.forEach(function(_,i){h+="<span class='"+(i===cm?"on":"")+"' onclick='oe("+e.id+","+i+","+esi+")'>"+M(i)+"</span>"});h+="</div>";
h+="<label>Статус</label><select id='es2'><option value='wait'"+(e.s==="wait"?" selected":"")+">Не начато</option><option value='warn'"+(e.s==="warn"?" selected":"")+">В процессе</option><option value='done'"+(e.s==="done"?" selected":"")+">Выполнено</option></select>";
}else{
h+="<label>Месяц</label><div class='mt'>";ms.forEach(function(_,i){h+="<span class='"+(i===cm?"on":"")+"' onclick='oe("+e.id+","+i+")'>"+M(i)+"</span>"});h+="</div>";
h+="<label>Статус</label><select id='es2'><option value='wait'"+(e.s==="wait"?" selected":"")+">Не начато</option><option value='warn'"+(e.s==="warn"?" selected":"")+">В процессе</option><option value='done'"+(e.s==="done"?" selected":"")+">Выполнено</option></select>";
h+="<label>Описание</label><textarea id='mr2' placeholder='Опишите проведённую работу, результаты, проблемы...'>"+esc(cd.report||"")+"</textarea>";
h+="<label>Количество</label><input type='number' id='mq2' min='0' value='"+(cd.qty||0)+"'>";
cfs.forEach(function(f,i){h+="<div class='fl'><span class='nm' onclick='dlF2("+e.id+","+cm+","+i+",-1)'>📄 "+esc(f.name)+"</span><span class='sz'>"+(f.size/1024).toFixed(0)+" КБ · "+(f.date||"")+"</span><button onclick='rmF2("+e.id+","+cm+","+i+",-1)' style='border:none;color:var(--red);cursor:pointer;font-size:14px'>×</button></div>"});
h+="<div class='up'><input type='file' id='fi2' multiple><button class='btn btn-sm' id='ub2' onclick='upF2("+e.id+","+cm+",-1)' style='margin-top:8px'>📤 Загрузить</button><p style='font-size:10px;color:var(--gray-500);margin-top:6px'>PDF, DOC/DOCX, XLS/XLSX, JPG/PNG, PPT/PPTX · до 3 МБ</p></div>";
h+="</table></div>";
}
h+="<div class='ai-block'><b>🤖 ИИ-анализ:</b> "+esc(e.ai)+"</div>";
h+="<div><b>История изменений:</b>";e.h.forEach(function(x){h+="<div class='hi'><span class='d'></span>"+esc(x)+"</div>"});h+="</div>";
h+="<div style='margin-top:16px;display:flex;gap:10px'><button class='btn' onclick='sv("+e.id+","+cm+")'>💾 Сохранить</button><button class='btn btn-ghost' onclick='closeM()'>Отмена</button></div>";
document.getElementById("mc").innerHTML=h;document.getElementById("mo").classList.add("on");
document.getElementById("pg-ev").innerHTML=h;
}
function sv(id,mk){mk=ms[mk];var e=null;for(var i=0;i<ev.length;i++)if(ev[i].id===id){e=ev[i];break}if(!e)return;e.s=document.getElementById("es2").value;var mr=document.getElementById("mr2"),mq=document.getElementById("mq2");if(mr){var ad=getMD(id,-1);if(!ad[mk])ad[mk]={report:"",files:[]};ad[mk].report=mr.value;if(mq)ad[mk].qty=parseInt(mq.value)||0;setMD(id,ad,-1)}if(e.sub&&e.sub.length){e.sub.forEach(function(_,i){var sr=document.getElementById("mr2_s"+i),sq=document.getElementById("mq2_s"+i);if(sr){var sd=getMD(id,i);if(!sd[mk])sd[mk]={report:"",files:[]};sd[mk].report=sr.value;if(sq)sd[mk].qty=parseInt(sq.value)||0;setMD(id,sd,i)}})}var now=new Date().toLocaleDateString();e.h.push(now+" "+cu.n+": "+st[e.s]);if(e.s==="done"&&e.done==="—")e.done=now;saveEv();closeM();renderEv()}
function closeM(){document.getElementById("mo").classList.remove("on")}
function upF2(eid,mk,si){mk=ms[mk];var pfx=si>=0?"_s"+si:"",fi=document.getElementById("fi2"+pfx);if(!fi||!fi.files.length)return;var btn=document.getElementById("ub2"+pfx);if(btn){btn.textContent="...";btn.disabled=true}var ad=getMD(eid,si);if(!ad[mk])ad[mk]={report:"",files:[]};var arr=ad[mk].files,pr=0,sk=0;function fin(){try{setMD(eid,ad,si)}catch(e){alert("Хранилище заполнено")}if(sk)alert(sk+" файлов >3 МБ");closeM();oe(eid,cm,si>=0?si:undefined)}for(var i=0;i<fi.files.length;i++){(function(f){if(f.size>3072*1024){sk++;pr++;if(pr===fi.files.length)fin();return}var r=new FileReader();r.onload=function(evt){arr.push({name:f.name,size:f.size,type:f.type,date:new Date().toLocaleDateString(),user:cu?cu.n:"?",data:evt.target.result});pr++;if(pr===fi.files.length)fin()};r.onerror=function(){pr++;if(pr===fi.files.length)fin()};r.readAsDataURL(f)})(fi.files[i])}}
function dlF2(eid,mk,idx,si){si=si||-1;mk=ms[mk];var ad=getMD(eid,si),arr=ad[mk]?ad[mk].files:null;if(!arr||!arr[idx]||!arr[idx].data)return;var f=arr[idx],a=document.createElement("a");a.href=f.data;a.download=f.name;document.body.appendChild(a);a.click();document.body.removeChild(a)}
function rmF2(eid,mk,idx,si){si=si||-1;mk=ms[mk];var ad=getMD(eid,si);if(!ad[mk]||!ad[mk].files)return;ad[mk].files.splice(idx,1);setMD(eid,ad,si);closeM();oe(eid,cm,si>=0?si:undefined)}
document.getElementById("mo").addEventListener("click",function(e){if(e.target===this)closeM()});
document.addEventListener("keydown",function(e){if(e.key==="Escape")closeM()});
document.addEventListener("click",function(e){if(!e.target.closest(".notif-btn")&&!e.target.closest(".notif-drop"))document.getElementById("nd").classList.remove("on")});
function escHtml(s){return s.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}
var su=localStorage.getItem("su");if(su){try{cu=JSON.parse(su);if(cu)showApp()}catch(e){}}
</script>
</body>
</html>
</html>