v3: интерактивный прототип платформы

This commit is contained in:
Dauren777 2026-06-04 09:42:30 +00:00
parent 5ad8ce91a4
commit ad4c3efc89

View File

@ -3,190 +3,412 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>ИИ-агент мониторинга производственной безопасностиАО «Самрук-Казына»</title>
<title>ИИ-агент мониторинга ПБАО «Самрук-Казына»</title>
<style>
:root{--ink:#0F1218;--cyan:#00E5FF;--cyan-50:#E8FCFF;--white:#fff;--gray-500:#5B6573;--gray-100:#F2F4F7;--gray-200:#E5E7EB;--green:#10B981;--red:#EF4444;--amber:#F59E0B}
:root{--ink:#0F1218;--cyan:#00E5FF;--cyan-50:#E8FCFF;--white:#fff;--gray-500:#5B6573;--gray-100:#F2F4F7;--gray-200:#E5E7EB;--gray-700:#374151;--green:#10B981;--red:#EF4444;--amber:#F59E0B;--blue:#3B82F6;--purple:#8B5CF6;--sidebar-w:260px;--topbar-h:60px}
*{box-sizing:border-box;margin:0;padding:0}
body{font:17px/1.6 -apple-system,BlinkMacSystemFont,"Segoe UI",Inter,system-ui,sans-serif;color:var(--ink);background:var(--white)}
body{font:14px/1.5 -apple-system,BlinkMacSystemFont,"Segoe UI",Inter,system-ui,sans-serif;color:var(--ink);background:var(--gray-100);display:flex;min-height:100vh}
a{color:var(--cyan);text-decoration:none}
.container{max-width:1140px;margin:0 auto;padding:80px 24px}
.hero{background:var(--ink);color:var(--white);text-align:center;padding:100px 0}
.hero h1{font-size:56px;font-weight:800;line-height:1.05;margin-bottom:24px}
.hero p{font-size:20px;color:#9aa3b2;max-width:650px;margin:0 auto 32px}
.hero .badge{display:inline-block;background:rgba(0,229,255,.1);color:var(--cyan);padding:6px 16px;border-radius:100px;font-size:14px;font-weight:600;margin-bottom:24px}
.btn{display:inline-block;background:var(--cyan);color:var(--ink);padding:16px 32px;border-radius:8px;font-weight:700;text-decoration:none;font-size:18px;transition:.2s}
.btn:hover{background:#1be5ff;transform:translateY(-1px)}
.btn-secondary{background:transparent;color:var(--ink);border:2px solid var(--ink)}
.btn-secondary:hover{background:var(--ink);color:var(--white);transform:none}
.section-title{font-size:36px;font-weight:700;text-align:center;margin-bottom:12px}
.section-subtitle{font-size:18px;color:var(--gray-500);text-align:center;max-width:650px;margin:0 auto 48px}
.cards{display:grid;grid-template-columns:repeat(auto-fit,minmax(320px,1fr));gap:24px}
.card{background:var(--white);border:1px solid var(--gray-200);border-radius:16px;padding:32px;transition:.2s}
.card:hover{border-color:var(--cyan);box-shadow:0 4px 24px rgba(0,229,255,.08)}
.card .icon{font-size:36px;margin-bottom:16px}
.card h3{font-size:20px;font-weight:700;margin-bottom:8px}
.card p{font-size:15px;color:var(--gray-500);line-height:1.6}
.stats{display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:24px;text-align:center}
.stat{background:var(--white);border:1px solid var(--gray-200);border-radius:16px;padding:40px 24px}
.stat .num{font-size:48px;font-weight:800;color:var(--cyan);line-height:1;margin-bottom:8px}
.stat .label{font-size:15px;color:var(--gray-500)}
.checklist{list-style:none;max-width:700px;margin:0 auto}
.checklist li{padding:12px 0;border-bottom:1px solid var(--gray-200);display:flex;align-items:center;gap:12px;font-size:16px}
.checklist li::before{content:"✔";color:var(--green);font-weight:700;font-size:18px}
.faq{max-width:750px;margin:0 auto}
.faq-item{background:var(--white);border:1px solid var(--gray-200);border-radius:12px;padding:24px 28px;margin-bottom:12px}
.faq-item h3{font-size:18px;font-weight:700;margin-bottom:6px}
.faq-item p{font-size:15px;color:var(--gray-500)}
.cta{background:var(--ink);color:var(--white);text-align:center}
.cta h2{font-size:36px;font-weight:700;margin-bottom:16px}
.cta p{font-size:18px;color:#9aa3b2;max-width:550px;margin:0 auto 32px}
.footer{text-align:center;padding:40px 24px;font-size:14px;color:var(--gray-500);border-top:1px solid var(--gray-200)}
@media (max-width:640px){
.hero h1{font-size:34px}
.hero{padding:60px 0}
.section-title{font-size:28px}
.container{padding:48px 20px}
.cards{grid-template-columns:1fr}
.stats{grid-template-columns:1fr 1fr}
.stat .num{font-size:32px}
/* SIDEBAR */
.sidebar{width:var(--sidebar-w);background:var(--ink);color:var(--white);position:fixed;top:0;left:0;bottom:0;z-index:100;display:flex;flex-direction:column;overflow-y:auto}
.sidebar .logo{padding:20px 24px;font-size:18px;font-weight:800;border-bottom:1px solid rgba(255,255,255,.1);line-height:1.3}
.sidebar .logo span{color:var(--cyan)}
.sidebar nav{padding:16px 0;flex:1}
.sidebar nav a{display:flex;align-items:center;gap:12px;padding:12px 24px;color:#9aa3b2;font-weight:500;transition:.15s;font-size:15px;cursor:pointer}
.sidebar nav a:hover,.sidebar nav a.active{color:var(--white);background:rgba(0,229,255,.08)}
.sidebar nav a.active{border-right:3px solid var(--cyan)}
.sidebar nav a .ico{font-size:18px;width:24px;text-align:center}
.sidebar .user{padding:20px 24px;border-top:1px solid rgba(255,255,255,.1);font-size:13px;color:#6b7280}
/* MAIN */
.main{margin-left:var(--sidebar-w);flex:1;padding:24px 32px;max-width:calc(100vw - var(--sidebar-w))}
/* PAGE */
.page{display:none}
.page.active{display:block}
.page h2{font-size:24px;font-weight:700;margin-bottom:20px}
/* STATS ROW */
.stats-row{display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:16px;margin-bottom:24px}
.stat-card{background:var(--white);border-radius:12px;padding:20px 24px;border:1px solid var(--gray-200)}
.stat-card .stat-label{font-size:13px;color:var(--gray-500);margin-bottom:4px}
.stat-card .stat-num{font-size:32px;font-weight:800;line-height:1}
.stat-card .stat-sub{font-size:13px;color:var(--gray-500);margin-top:4px}
.stat-card.red .stat-num{color:var(--red)}
.stat-card.green .stat-num{color:var(--green)}
.stat-card.amber .stat-num{color:var(--amber)}
.stat-card.blue .stat-num{color:var(--blue)}
/* GRID 2col */
.grid2{display:grid;grid-template-columns:1fr 1fr;gap:24px;margin-bottom:24px}
.grid3{display:grid;grid-template-columns:1fr 1fr 1fr;gap:24px;margin-bottom:24px}
/* PANEL */
.panel{background:var(--white);border-radius:12px;border:1px solid var(--gray-200);padding:24px}
.panel h3{font-size:17px;font-weight:700;margin-bottom:16px}
/* CHART STUB */
.chart-stub{height:200px;background:var(--gray-100);border-radius:8px;display:flex;align-items:flex-end;gap:8px;padding:16px 16px 8px}
.chart-stub .bar{flex:1;background:var(--cyan);border-radius:4px 4px 0 0;min-height:4px;transition:.3s}
.chart-stub .bar.danger{background:var(--red)}
.chart-stub .bar.warn{background:var(--amber)}
.chart-stub .bar.good{background:var(--green)}
.chart-stub .bar.blue{background:var(--blue)}
.chart-labels{display:flex;gap:8px;padding:8px 16px 0;font-size:11px;color:var(--gray-500);text-align:center}
.chart-labels span{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* RING */
.ring{position:relative;width:120px;height:120px;margin:0 auto 12px}
.ring svg{transform:rotate(-90deg)}
.ring .pct{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;font-size:28px;font-weight:800}
.ring-label{text-align:center;font-size:14px;color:var(--gray-500)}
/* TABLE */
table{width:100%;border-collapse:collapse}
th,td{padding:12px 16px;text-align:left;font-size:14px}
th{font-weight:600;color:var(--gray-500);font-size:12px;text-transform:uppercase;letter-spacing:.5px;border-bottom:2px solid var(--gray-200)}
td{border-bottom:1px solid var(--gray-200)}
tr:hover td{background:var(--cyan-50)}
/* BADGE */
.badge{display:inline-block;padding:4px 10px;border-radius:100px;font-size:12px;font-weight:600}
.badge.green{background:#D1FAE5;color:#065F46}
.badge.amber{background:#FEF3C7;color:#92400E}
.badge.red{background:#FEE2E2;color:#991B1B}
.badge.blue{background:#DBEAFE;color:#1E40AF}
.badge.gray{background:var(--gray-100);color:var(--gray-700)}
/* FILTERS */
.filters{display:flex;gap:12px;margin-bottom:20px;flex-wrap:wrap;align-items:center}
.filters select,.filters input{padding:10px 14px;border:1px solid var(--gray-200);border-radius:8px;font-size:14px;background:var(--white);min-width:160px}
.filters input{min-width:260px}
.filters .count{font-size:13px;color:var(--gray-500);margin-left:auto}
/* AI BADGE */
.ai-tag{display:inline-flex;align-items:center;gap:6px;background:var(--cyan-50);color:var(--ink);padding:4px 10px;border-radius:6px;font-size:12px;font-weight:600}
/* MODAL */
.modal-overlay{position:fixed;inset:0;background:rgba(0,0,0,.5);z-index:200;display:none;align-items:center;justify-content:center}
.modal-overlay.open{display:flex}
.modal{background:var(--white);border-radius:16px;max-width:800px;width:90vw;max-height:85vh;overflow-y:auto;padding:32px}
.modal h2{font-size:22px;margin-bottom:8px}
.modal .close{float:right;background:none;border:none;font-size:24px;cursor:pointer;line-height:1;color:var(--gray-500)}
.modal .meta{display:grid;grid-template-columns:1fr 1fr;gap:12px;margin:20px 0}
.modal .meta .field{font-size:13px;color:var(--gray-500)}
.modal .meta .field strong{display:block;font-size:15px;color:var(--ink);margin-top:2px}
.modal .docs{display:flex;gap:8px;flex-wrap:wrap;margin:12px 0}
.modal .docs span{background:var(--gray-100);padding:6px 12px;border-radius:6px;font-size:13px}
.modal .ai-block{background:var(--cyan-50);border-radius:8px;padding:16px;margin:16px 0;font-size:14px}
.modal .ai-block h4{font-size:14px;margin-bottom:6px;color:var(--ink)}
.modal .timeline{font-size:13px;color:var(--gray-500);line-height:2}
.modal .timeline strong{color:var(--ink)}
/* RATINGS */
.rating-bar{display:flex;align-items:center;gap:12px;padding:8px 0}
.rating-bar .name{width:180px;font-size:14px;font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.rating-bar .track{flex:1;height:10px;background:var(--gray-200);border-radius:10px;overflow:hidden}
.rating-bar .fill{height:100%;border-radius:10px;transition:.5s}
/* RESPONSIVE */
@media(max-width:900px){
.sidebar{width:60px}
.sidebar .logo,.sidebar nav a span,.sidebar .user{display:none}
.sidebar nav a{justify-content:center;padding:12px 0;font-size:20px}
.main{margin-left:60px;max-width:calc(100vw - 60px);padding:16px}
.grid2,.grid3{grid-template-columns:1fr}
.stats-row{grid-template-columns:1fr 1fr}
}
</style>
</head>
<body>
<section class="hero">
<div class="container">
<div class="badge">MVP • 2026</div>
<h1>ИИ-агент мониторинга производственной безопасности</h1>
<p>Единая цифровая платформа для автоматизации контроля исполнения Плана мероприятий, анализа эффективности и подготовки управленческих решений в Группе компаний АО «Самрук-Казына»</p>
<a class="btn" href="#cta">Запросить демо</a>
</div>
</section>
<!-- SIDEBAR -->
<aside class="sidebar">
<div class="logo"><span>ИИ-Агент</span><br>Самрук-Казына</div>
<nav>
<a class="active" data-page="dashboard"><span class="ico">📊</span> <span>Дашборд</span></a>
<a data-page="register"><span class="ico">📋</span> <span>Реестр мероприятий</span></a>
<a data-page="analytics"><span class="ico">📈</span> <span>Аналитика</span></a>
<a data-page="reports"><span class="ico">📑</span> <span>Отчёты</span></a>
<a data-page="risks"><span class="ico">⚠️</span> <span>Карта рисков</span></a>
</nav>
<div class="user">Инспектор ПБ • АО «Самрук-Казына»</div>
</aside>
<section id="features" class="section">
<div class="container">
<h2 class="section-title">Основные задачи системы</h2>
<p class="section-subtitle">Платформа закрывает полный цикл — от сбора данных до управленческой отчётности</p>
<div class="cards">
<div class="card">
<div class="icon">📥</div>
<h3>Централизованный сбор данных</h3>
<p>Сбор отчётной информации от филиалов и дочерних организаций через веб-интерфейс. Формирование единой базы данных исполнения Плана.</p>
<!-- MAIN CONTENT -->
<main class="main" id="mainContent"></main>
<!-- MODAL -->
<div class="modal-overlay" id="modalOverlay">
<div class="modal" id="modalContent"></div>
</div>
<script>
// ===== MOCK DATA =====
const branches = ['АО "КазТрансОйл"','АО "KEGOC"','АО "Казпочта"','АО "НК КТЖ"','АО "Казатомпром"','АО "Эйр Астана"','АО "QazaqGaz"','ТОО "Самрук-Энерго"']
const statuses = {done:'Исполнено',warn:'На контроле',late:'Просрочено',wait:'Не начато'}
const directions = ['Охрана труда','Пожарная безопасность','Промбезопасность','Экология','ГО и ЧС','Транспортная безопасность']
const events = [
{id:1, title:'Проведение внепланового инструктажа по охране труда', branch:branches[0], dir:directions[0], status:'done', progress:100, due:'15.02.2026', done:'12.02.2026', resp:'Ахметов К.Т.', docs:['Приказ №45','Журнал инструктажа','Фотоотчёт'], ai:'Все документы в наличии. Инструктаж проведён в срок. Замечаний нет.', history:['10.02 — Мероприятие создано','12.02 — Загружен журнал инструктажа','12.02 — Статус: Исполнено'] },
{id:2, title:'Замена средств пожаротушения на складе ГСМ', branch:branches[1], dir:directions[1], status:'warn', progress:65, due:'30.06.2026', done:'—', resp:'Сериков А.М.', docs:['Смета','Договор поставки'], ai:'Отсутствует акт выполненных работ. Рекомендуется ускорить монтаж. Срок под риском.', history:['05.03 — Мероприятие создано','20.04 — Загружен договор','01.06 — ИИ: риск срыва срока'] },
{id:3, title:'Аттестация сварщиков по промышленной безопасности', branch:branches[4], dir:directions[2], status:'late', progress:30, due:'01.04.2026', done:'—', resp:'Касымов Б.Е.', docs:[], ai:'Просрочка 64 дня. Подтверждающие документы отсутствуют. Эскалация руководителю.', history:['01.01 — Мероприятие создано','01.04 — Срок истёк','05.04 — Эскалация руководителю'] },
{id:4, title:'Экологический аудит очистных сооружений', branch:branches[6], dir:directions[3], status:'done', progress:100, due:'01.03.2026', done:'26.02.2026', resp:'Нурланов Д.С.', docs:['Акт аудита','Лабораторные пробы','Фото'], ai:'Аудит пройден. Лабораторные показатели в норме. Рекомендации выполнены.', history:['10.01 — Мероприятие создано','20.02 — Загружены пробы','26.02 — Статус: Исполнено'] },
{id:5, title:'Обучение персонала по ГО и ЧС', branch:branches[7], dir:directions[4], status:'warn', progress:45, due:'01.08.2026', done:'—', resp:'Тулегенов Е.А.', docs:['Программа обучения'], ai:'Утверждена программа. Не загружены списки групп. Рекомендуется начать обучение.', history:['01.04 — Мероприятие создано','15.05 — Утверждена программа','01.06 — ИИ: ожидается список групп'] },
{id:6, title:'Проверка состояния ж/д переездов', branch:branches[3], dir:directions[5], status:'done', progress:100, due:'10.05.2026', done:'05.05.2026', resp:'Искаков Р.Н.', docs:['Акт осмотра','Предписание','Фото'], ai:'Проверка проведена. Выявлено 3 замечания. Устранены в срок.', history:['01.04 — Мероприятие создано','28.04 — Акт осмотра','05.05 — Статус: Исполнено'] },
{id:7, title:'Монтаж системы оповещения на производстве', branch:branches[2], dir:directions[1], status:'wait', progress:0, due:'01.12.2026', done:'—', resp:'Сапаров А.Д.', docs:[], ai:'Мероприятие не начато. До срока 180 дней. Рекомендуется назначить поставщика.', history:['01.06 — Мероприятие создано'] },
{id:8, title:'Медицинский осмотр работников вредных производств', branch:branches[5], dir:directions[0], status:'done', progress:100, due:'01.04.2026', done:'28.03.2026', resp:'Алиева Г.С.', docs:['Приказ','Заключения врачей','Отчёт'], ai:'Осмотр пройден. 100% охват. Противопоказаний не выявлено.', history:['01.03 — Мероприятие создано','25.03 — Загружены заключения','28.03 — Статус: Исполнено'] },
{id:9, title:'Ремонт ограждения опасной зоны на участке №3', branch:branches[0], dir:directions[2], status:'late', progress:20, due:'15.03.2026', done:'—', resp:'Маратов Ж.К.', docs:[], ai:'Просрочено 81 день. Отсутствует проектная документация. Требуется вмешательство.', history:['15.01 — Мероприятие создано','15.03 — Срок истёк','20.03 — Эскалация'] },
{id:10, title:'Закуп СИЗ для полевых бригад', branch:branches[1], dir:directions[0], status:'warn', progress:80, due:'15.07.2026', done:'—', resp:'Омарова Д.Т.', docs:['Спецификация','Счёт-фактура'], ai:'СИЗ закуплены. Ожидается поставка. Рисков срыва нет.', history:['01.05 — Мероприятие создано','01.06 — Счёт оплачен'] },
{id:11, title:'Пересмотр плана ликвидации аварий', branch:branches[4], dir:directions[4], status:'warn', progress:50, due:'01.09.2026', done:'—', resp:'Касымов Б.Е.', docs:['Проект ПЛА'], ai:'Проект ПЛА на согласовании. Замечаний от проверяющих нет.', history:['01.04 — Мероприятие создано','20.05 — Проект загружен'] },
{id:12, title:'Проверка дымовых извещателей в админздании', branch:branches[7], dir:directions[1], status:'done', progress:100, due:'01.05.2026', done:'28.04.2026', resp:'Тулегенов Е.А.', docs:['Акт проверки','Сертификаты'], ai:'Все извещатели исправны. Сертификаты действительны.', history:['01.04 — Мероприятие создано','28.04 — Статус: Исполнено'] },
]
// ===== HELPERS =====
function pctBar(p){return `<div class="track"><div class="fill" style="width:${p}%;background:${p>=80?'var(--green)':p>=40?'var(--amber)':'var(--red)'}"></div></div> ${p}%`}
function sBadge(s){
const map={done:'green',warn:'amber',late:'red',wait:'gray'}
return `<span class="badge ${map[s]||'gray'}">${statuses[s]||s}</span>`
}
// ===== PAGES =====
function pageDashboard(){
let done=events.filter(e=>e.status==='done').length
let late=events.filter(e=>e.status==='late').length
let warn=events.filter(e=>e.status==='warn').length
let total=events.length
let donePct=Math.round(done/total*100)
return `
<div class="page active" id="page-dashboard">
<h2>Дашборд производственной безопасности</h2>
<div class="stats-row">
<div class="stat-card green"><div class="stat-label">Всего мероприятий</div><div class="stat-num">${total}</div></div>
<div class="stat-card green"><div class="stat-label">Исполнено</div><div class="stat-num">${done}</div><div class="stat-sub">${donePct}% от плана</div></div>
<div class="stat-card amber"><div class="stat-label">На контроле</div><div class="stat-num">${warn}</div></div>
<div class="stat-card red"><div class="stat-label">Просрочено</div><div class="stat-num">${late}</div></div>
<div class="stat-card blue"><div class="stat-label">Общий прогресс</div><div class="stat-num">${donePct}%</div></div>
</div>
<div class="card">
<div class="icon">📋</div>
<h3>Управление мероприятиями</h3>
<p>Электронный реестр мероприятий, назначение ответственных, контрольные сроки и мониторинг статусов в реальном времени.</p>
<div class="grid2">
<div class="panel">
<h3>Исполнение по направлениям</h3>
${directions.map(d=>{
let items=events.filter(e=>e.dir===d)
let pct=Math.round(items.filter(e=>e.status==='done').length/Math.max(1,items.length)*100)
return `<div class="rating-bar"><span class="name">${d}</span><div class="track"><div class="fill" style="width:${pct}%;background:var(--cyan)"></div></div><span style="font-size:13px;font-weight:700;width:40px;text-align:right">${pct}%</span></div>`
}).join('')}
</div>
<div class="panel">
<h3>Рейтинг организаций</h3>
${branches.slice(0,6).map(b=>{
let items=events.filter(e=>e.branch===b)
let pct=Math.round(items.filter(e=>e.status==='done').length/Math.max(1,items.length)*100)
return `<div class="rating-bar"><span class="name">${b.replace('АО ','').replace('ТОО ','')}</span><div class="track"><div class="fill" style="width:${pct}%;background:${pct>=70?'var(--green)':pct>=40?'var(--amber)':'var(--red)'}"></div></div><span style="font-size:13px;font-weight:700;width:40px;text-align:right">${pct}%</span></div>`
}).join('')}
</div>
</div>
<div class="card">
<div class="icon">📎</div>
<h3>Подтверждение исполнения</h3>
<p>Загрузка фото, актов, протоколов, приказов, презентаций, видео. Электронный архив с историей изменений и версионированием.</p>
<div class="panel">
<h3>Динамика исполнения по кварталам</h3>
<div class="chart-stub">
<div class="bar" style="height:40%"></div>
<div class="bar" style="height:55%"></div>
<div class="bar" style="height:70%"></div>
<div class="bar" style="height:${donePct}%"></div>
</div>
<div class="chart-labels"><span>Q1</span><span>Q2</span><span>Q3</span><span>Q4 (план)</span></div>
</div>
<div class="card">
<div class="icon">🆔</div>
<h3>Цифровой паспорт мероприятия</h3>
<p>Карточка с описанием, сроками, ответственным, статусом, % выполнения, историей, комментариями и выводами ИИ.</p>
</div>`
}
function pageRegister(filter='',statusFilter=''){
let list=events
if(filter) list=list.filter(e=>e.title.toLowerCase().includes(filter.toLowerCase())||e.branch.toLowerCase().includes(filter.toLowerCase()))
if(statusFilter) list=list.filter(e=>e.status===statusFilter)
return `
<div class="page active" id="page-register">
<h2>Реестр мероприятий</h2>
<div class="filters">
<input placeholder="Поиск по названию или организации..." oninput="refreshPage('register',this.value,document.getElementById('statusFilter')?.value||'')" id="searchInput">
<select onchange="refreshPage('register',document.getElementById('searchInput')?.value||'',this.value)" id="statusFilter">
<option value="">Все статусы</option>
<option value="done">Исполнено</option>
<option value="warn">На контроле</option>
<option value="late">Просрочено</option>
<option value="wait">Не начато</option>
</select>
<span class="count">Найдено: ${list.length}</span>
</div>
<div class="card">
<div class="icon">🤖</div>
<h3>Искусственный интеллект</h3>
<p>Анализ отчётов и материалов, проверка полноты, оценка достаточности подтверждения, выявление рисков и формирование рекомендаций.</p>
<div class="panel" style="overflow-x:auto">
<table>
<thead><tr><th></th><th>Мероприятие</th><th>Организация</th><th>Направление</th><th>Срок</th><th>Прогресс</th><th>Статус</th></tr></thead>
<tbody>${list.map(e=>`
<tr style="cursor:pointer" onclick="openEvent(${e.id})">
<td>${e.id}</td>
<td><strong>${e.title}</strong></td>
<td style="font-size:13px">${e.branch}</td>
<td style="font-size:13px">${e.dir}</td>
<td style="font-size:13px">${e.due}</td>
<td>${pctBar(e.progress)}</td>
<td>${sBadge(e.status)}</td>
</tr>`).join('')}</tbody>
</table>
</div>
<div class="card">
<div class="icon"></div>
<h3>Контроль дисциплины</h3>
<p>Мониторинг сроков, авто-напоминания исполнителям, эскалация просрочек руководителям, рейтинг организаций.</p>
</div>`
}
function pageAnalytics(){
let orgRatings=branches.map(b=>{
let items=events.filter(e=>e.branch===b)
let done=items.filter(e=>e.status==='done').length
let late=items.filter(e=>e.status==='late').length
return {name:b,done,late,total:items.length,pct:Math.round(done/Math.max(1,items.length)*100)}
}).sort((a,b)=>b.pct-a.pct)
return `
<div class="page active" id="page-analytics">
<h2>Аналитика</h2>
<div class="grid2">
<div class="panel">
<h3>Рейтинг организаций по исполнению</h3>
${orgRatings.map((r,i)=>`
<div class="rating-bar">
<span class="name">${i+1}. ${r.name}</span>
<div class="track"><div class="fill" style="width:${r.pct}%;background:${r.pct>=70?'var(--green)':r.pct>=40?'var(--amber)':'var(--red)'}"></div></div>
<span style="font-size:13px;font-weight:700;width:60px;text-align:right">${r.pct}% (${r.done}/${r.total})</span>
</div>`).join('')}
</div>
<div class="panel">
<h3>Просроченные мероприятия</h3>
${events.filter(e=>e.status==='late').map(e=>`
<div class="rating-bar">
<span class="name" style="font-size:13px">${e.title.slice(0,40)}...</span>
<span style="font-size:13px;color:var(--red);font-weight:700">${e.due}</span>
<span class="badge red">${e.branch.split('"')[1]||e.branch}</span>
</div>`).join('')||'<p style="color:var(--gray-500)">Просроченных мероприятий нет</p>'}
</div>
</div>
<div class="card">
<div class="icon">📊</div>
<h3>Аналитика и дашборды</h3>
<p>Процент исполнения по филиалам и направлениям, анализ просрочек и причин, карта рисков, динамика по периодам.</p>
<div class="grid3" style="margin-top:24px">
<div class="panel" style="text-align:center">
<h3>Всего мероприятий</h3>
<div style="font-size:48px;font-weight:800;color:var(--cyan)">${events.length}</div>
</div>
<div class="panel" style="text-align:center">
<h3>Документов загружено</h3>
<div style="font-size:48px;font-weight:800;color:var(--green)">${events.reduce((s,e)=>s+e.docs.length,0)}</div>
</div>
<div class="panel" style="text-align:center">
<h3>Средний % исполнения</h3>
<div style="font-size:48px;font-weight:800;color:var(--blue)">${Math.round(events.reduce((s,e)=>s+e.progress,0)/events.length)}%</div>
</div>
</div>
<div class="card">
<div class="icon">📑</div>
<h3>Формирование отчётности</h3>
<p>Автоматические ежемесячные, квартальные и годовые отчёты, аналитические справки, презентационные материалы.</p>
</div>`
}
function pageReports(){
return `
<div class="page active" id="page-reports">
<h2>Формирование отчётности</h2>
<div class="stats-row">
<div class="stat-card"><div class="stat-label">Ежемесячный отчёт</div><div class="stat-num" style="font-size:20px">За май 2026</div><div class="stat-sub"><span class="badge green">Сформирован</span></div></div>
<div class="stat-card"><div class="stat-label">Квартальный отчёт</div><div class="stat-num" style="font-size:20px">Q2 2026</div><div class="stat-sub"><span class="badge amber">В обработке</span></div></div>
<div class="stat-card"><div class="stat-label">Годовой отчёт</div><div class="stat-num" style="font-size:20px">2026</div><div class="stat-sub"><span class="badge gray">Ожидается</span></div></div>
</div>
<div class="card">
<div class="icon">🎯</div>
<h3>Управленческий помощник</h3>
<p>Проекты поручений, перечень проблемных мероприятий, системные нарушения, прогноз достижения целевых показателей.</p>
<div class="panel" style="margin-top:16px">
<h3>Все отчёты</h3>
<table>
<thead><tr><th>Тип отчёта</th><th>Период</th><th>Статус</th><th>Дата формирования</th><th>Формат</th></tr></thead>
<tbody>
<tr><td>Ежемесячный отчёт</td><td>Май 2026</td><td><span class="badge green">Готов</span></td><td>01.06.2026</td><td>PDF, Excel</td></tr>
<tr><td>Аналитическая справка</td><td>Май 2026</td><td><span class="badge green">Готов</span></td><td>02.06.2026</td><td>PDF, Word</td></tr>
<tr><td>Презентация для совещания</td><td>Июнь 2026</td><td><span class="badge amber">В работе</span></td><td></td><td>PPTX</td></tr>
<tr><td>Квартальный отчёт</td><td>Q2 2026</td><td><span class="badge amber">В работе</span></td><td></td><td>PDF, Excel</td></tr>
<tr><td>Рейтинг организаций</td><td>Июнь 2026</td><td><span class="badge green">Готов</span></td><td>04.06.2026</td><td>PDF</td></tr>
</tbody>
</table>
</div>
</div>`
}
function pageRisks(){
let risks=[
{event:'Замена средств пожаротушения на складе ГСМ', branch:branches[1], level:'medium', reason:'Отставание от графика на 15%'},
{event:'Аттестация сварщиков', branch:branches[4], level:'high', reason:'Просрочка 64 дня, отсутствуют документы'},
{event:'Ремонт ограждения опасной зоны', branch:branches[0], level:'high', reason:'Просрочка 81 день, нет проектной документации'},
{event:'Обучение персонала по ГО и ЧС', branch:branches[7], level:'low', reason:'Не загружены списки групп'},
{event:'Пересмотр плана ликвидации аварий', branch:branches[4], level:'low', reason:'План на согласовании, замечаний нет'},
]
return `
<div class="page active" id="page-risks">
<h2>Карта рисков</h2>
<div class="stats-row">
<div class="stat-card red"><div class="stat-label">Высокий риск</div><div class="stat-num">${risks.filter(r=>r.level==='high').length}</div></div>
<div class="stat-card amber"><div class="stat-label">Средний риск</div><div class="stat-num">${risks.filter(r=>r.level==='medium').length}</div></div>
<div class="stat-card blue"><div class="stat-label">Низкий риск</div><div class="stat-num">${risks.filter(r=>r.level==='low').length}</div></div>
</div>
<div class="panel">
<h3>Реестр рисков</h3>
<table>
<thead><tr><th>Мероприятие</th><th>Организация</th><th>Уровень риска</th><th>Причина</th></tr></thead>
<tbody>${risks.map(r=>`
<tr>
<td><strong>${r.event}</strong></td>
<td style="font-size:13px">${r.branch}</td>
<td>${r.level==='high'?'<span class="badge red">Высокий</span>':r.level==='medium'?'<span class="badge amber">Средний</span>':'<span class="badge blue">Низкий</span>'}</td>
<td style="font-size:13px">${r.reason}</td>
</tr>`).join('')}</tbody>
</table>
</div>
</div>`
}
function openEvent(id){
let e=events.find(x=>x.id===id)
if(!e) return
document.getElementById('modalContent').innerHTML=`
<button class="close" onclick="closeModal()">&times;</button>
<div class="ai-tag">🤖 Анализ ИИ</div>
<h2>${e.title}</h2>
<div class="meta">
<div class="field">Организация<strong>${e.branch}</strong></div>
<div class="field">Направление<strong>${e.dir}</strong></div>
<div class="field">Срок исполнения<strong>${e.due}</strong></div>
<div class="field">Дата исполнения<strong>${e.done}</strong></div>
<div class="field">Ответственный<strong>${e.resp}</strong></div>
<div class="field">Прогресс<strong>${pctBar(e.progress)}</strong></div>
<div class="field">Статус<strong>${sBadge(e.status)}</strong></div>
</div>
</div>
</section>
${e.docs.length?`<div style="font-weight:600;margin:8px 0 4px;font-size:14px">Подтверждающие материалы:</div><div class="docs">${e.docs.map(d=>`<span>📄 ${d}</span>`).join('')}</div>`:''}
<div class="ai-block"><h4>🤖 Выводы ИИ-агента</h4>${e.ai}</div>
<div style="font-weight:600;margin:8px 0 4px;font-size:14px">История изменений:</div>
<div class="timeline">${e.history.map(h=>`<div>${h}</div>`).join('')}</div>
`
document.getElementById('modalOverlay').classList.add('open')
}
<section class="section" style="background:var(--gray-100)">
<div class="container">
<h2 class="section-title">Ожидаемый эффект</h2>
<p class="section-subtitle">Ключевые показатели, на которые влияет внедрение платформы</p>
<div class="stats">
<div class="stat">
<div class="num">80%</div>
<div class="label">Сокращение ручного сбора отчётности</div>
</div>
<div class="stat">
<div class="num">100%</div>
<div class="label">Прозрачность контроля исполнения</div>
</div>
<div class="stat">
<div class="num">×3</div>
<div class="label">Скорость выявления рисков</div>
</div>
<div class="stat">
<div class="num">24/7</div>
<div class="label">Отчётность в реальном времени</div>
</div>
</div>
</div>
</section>
function closeModal(){ document.getElementById('modalOverlay').classList.remove('open') }
<section class="section">
<div class="container">
<h2 class="section-title">Интеграции</h2>
<p class="section-subtitle">Система встраивается в существующий ИТ-ландшафт</p>
<ul class="checklist">
<li>Корпоративная электронная почта (уведомления и напоминания)</li>
<li>Системы электронного документооборота (СЭД)</li>
<li>Корпоративные BI-платформы (экспорт данных)</li>
<li>Экспорт в Excel, Word, PDF</li>
<li>API для внешних систем и порталов</li>
</ul>
</div>
</section>
// NAVIGATION
function navTo(page, filter='', statusFilter=''){
document.querySelectorAll('.sidebar nav a').forEach(a=>a.classList.remove('active'))
document.querySelector(`[data-page="${page}"]`)?.classList.add('active')
let content
switch(page){
case 'dashboard': content=pageDashboard(); break
case 'register': content=pageRegister(filter,statusFilter); break
case 'analytics': content=pageAnalytics(); break
case 'reports': content=pageReports(); break
case 'risks': content=pageRisks(); break
default: content=pageDashboard()
}
document.getElementById('mainContent').innerHTML=content
}
<section class="section" style="background:var(--gray-100)">
<div class="container">
<h2 class="section-title">Часто задаваемые вопросы</h2>
<div class="faq">
<div class="faq-item">
<h3>Кто будет пользоваться системой?</h3>
<p>Ответственные работники филиалов и ДО, руководители направлений ПБ, проверяющие и топ-менеджмент АО «Самрук-Казына». Каждая роль имеет свой набор прав и интерфейс.</p>
</div>
<div class="faq-item">
<h3>Какие документы можно загружать?</h3>
<p>Фотографии, акты, протоколы, приказы, презентации, отчёты, видеоматериалы и любые иные подтверждающие документы в форматах PDF, DOCX, XLSX, PPTX, JPG, PNG, MP4.</p>
</div>
<div class="faq-item">
<h3>Как ИИ помогает в анализе?</h3>
<p>ИИ проверяет полноту отчётности, выявляет отсутствующие документы, оценивает достаточность подтверждения, прогнозирует риски нарушения сроков и формирует краткие аналитические справки.</p>
</div>
</div>
</div>
</section>
function refreshPage(page,filter,statusFilter){ navTo(page,filter,statusFilter) }
<section id="cta" class="cta">
<div class="container">
<h2>Готовы увидеть платформу в действии?</h2>
<p>Оставьте заявку — проведём демонстрацию системы и ответим на вопросы</p>
<a class="btn" href="mailto:info@samruk-ai.kz">Запросить демо</a>
</div>
</section>
document.querySelectorAll('.sidebar nav a').forEach(a=>{
a.addEventListener('click',e=>{
e.preventDefault()
navTo(a.dataset.page)
})
})
<footer class="footer">
© 2026 АО «Самрук-Казына» — Цифровая платформа производственной безопасности
</footer>
document.getElementById('modalOverlay').addEventListener('click',function(e){
if(e.target===this) closeModal()
})
document.addEventListener('keydown',e=>{if(e.key==='Escape') closeModal()})
// INIT
navTo('dashboard')
</script>
</body>
</html>