151 lines
8.1 KiB
HTML
151 lines
8.1 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="ru" data-theme="auto">
|
||
<head>
|
||
<meta charset="utf-8">
|
||
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||
<title>Ревизия сервисных контрактов</title>
|
||
<link rel="icon" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><text y='.9em' font-size='90'>📋</text></svg>">
|
||
<link rel="stylesheet" href="design-system/kt-ai-fonts.css">
|
||
<link rel="stylesheet" href="design-system/kt-ai-tokens.css">
|
||
<link rel="stylesheet" href="design-system/kt-ai-components.css">
|
||
<link rel="stylesheet" href="design-system/kt-ai-page.css">
|
||
<style>
|
||
a.kt-ai-btn { text-decoration: none; }
|
||
.app { display: flex; min-height: 100vh; flex-direction: column; }
|
||
.app main { flex: 1; }
|
||
|
||
.kpi-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); gap: var(--kt-ai-space-4); margin-top: var(--kt-ai-space-7); }
|
||
.kpi { background: var(--kt-ai-card-bg); border: 1px solid var(--kt-ai-card-border); border-radius: var(--kt-ai-radius-2xl); padding: var(--kt-ai-space-6); }
|
||
.kpi .k { font-size: var(--kt-ai-text-sm); color: var(--kt-ai-fg-muted); }
|
||
.kpi .v { font-size: var(--kt-ai-text-2xl); font-weight: var(--kt-ai-weight-bold); margin-top: var(--kt-ai-space-2); }
|
||
.kpi .d { font-size: var(--kt-ai-text-sm); color: var(--kt-ai-fg-muted); margin-top: var(--kt-ai-space-1); }
|
||
.kpi.up .d { color: var(--kt-ai-danger); }
|
||
.kpi.down .d { color: var(--kt-ai-link); }
|
||
|
||
.panel { background: var(--kt-ai-card-bg); border: 1px solid var(--kt-ai-card-border); border-radius: var(--kt-ai-radius-2xl); padding: var(--kt-ai-space-6); }
|
||
|
||
.controls { display: flex; flex-wrap: wrap; gap: var(--kt-ai-space-3); align-items: center; margin-bottom: var(--kt-ai-space-5); }
|
||
.chips { display: flex; flex-wrap: wrap; gap: var(--kt-ai-space-2); }
|
||
|
||
.table-wrap { overflow-x: auto; border: 1px solid var(--kt-ai-border); border-radius: var(--kt-ai-radius-xl); }
|
||
table { width: 100%; border-collapse: collapse; font-size: var(--kt-ai-text-sm); min-width: 720px; }
|
||
th, td { text-align: left; padding: var(--kt-ai-space-3) var(--kt-ai-space-4); border-bottom: 1px solid var(--kt-ai-border); vertical-align: top; }
|
||
th { font-weight: var(--kt-ai-weight-semibold); color: var(--kt-ai-fg-muted); background: var(--kt-ai-bg-soft); white-space: nowrap; cursor: pointer; user-select: none; }
|
||
tbody tr:last-child td { border-bottom: none; }
|
||
.num { text-align: right; white-space: nowrap; }
|
||
|
||
.bar-cell { min-width: 180px; }
|
||
.bar-bg { background: var(--kt-ai-bg-soft); border-radius: 999px; height: 10px; width: 100%; overflow: hidden; }
|
||
.bar { height: 100%; border-radius: 999px; background: var(--kt-ai-primary); }
|
||
|
||
.cat-row { display: flex; flex-direction: column; gap: 4px; }
|
||
.cat-top { display: flex; justify-content: space-between; gap: var(--kt-ai-space-3); }
|
||
.cat-bar { height: 8px; border-radius: 999px; background: var(--kt-ai-bg-soft); overflow: hidden; }
|
||
|
||
.meta { font-size: var(--kt-ai-text-sm); color: var(--kt-ai-fg-muted); }
|
||
.muted { color: var(--kt-ai-fg-muted); }
|
||
.note { font-size: var(--kt-ai-text-sm); color: var(--kt-ai-fg-faint); margin-top: var(--kt-ai-space-4); line-height: 1.5; }
|
||
|
||
@media (max-width: 720px) {
|
||
.kpi .v { font-size: var(--kt-ai-text-xl); }
|
||
}
|
||
</style>
|
||
</head>
|
||
<body>
|
||
<div class="app">
|
||
<header class="kt-ai-pagehead">
|
||
<div class="kt-ai-wrap kt-ai-pagehead-in">
|
||
<strong>📋 Ревизия сервисных контрактов</strong>
|
||
<span class="kt-ai-spacer"></span>
|
||
<a class="kt-ai-btn" data-variant="ghost" href="#analytics">Аналитика</a>
|
||
<a class="kt-ai-btn" data-variant="ghost" href="#list">Реестр позиций</a>
|
||
</div>
|
||
</header>
|
||
|
||
<main>
|
||
<section class="kt-ai-hero" data-align="center">
|
||
<div class="kt-ai-wrap">
|
||
<h1>Автоматическая ревизия сервисных контрактов</h1>
|
||
<p class="kt-ai-hero-sub">Реестр конкретных позиций техподдержки, лицензий и сервисов компании за 2025 год и 6 месяцев 2026 года — с поиском, фильтрами и выгрузкой.</p>
|
||
<div class="kt-ai-hero-actions">
|
||
<a class="kt-ai-btn" data-variant="primary" data-size="lg" href="#analytics">Смотреть аналитику</a>
|
||
<a class="kt-ai-btn" data-size="lg" href="#list">Открыть реестр</a>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<section id="analytics" class="kt-ai-section" data-divider="true">
|
||
<div class="kt-ai-wrap">
|
||
<div class="kt-ai-section-head">
|
||
<h2>Ключевые показатели</h2>
|
||
<p>Фактические затраты по сервисным контрактам. Строка «6 мес. 2026» — за первое полугодие, поэтому прямое сравнение с полным 2025 годом некорректно.</p>
|
||
</div>
|
||
|
||
<div class="kpi-grid" id="kpis"></div>
|
||
|
||
<div class="kt-ai-grid" style="margin-top:var(--kt-ai-space-7)">
|
||
<article class="kt-ai-tile" data-span="full">
|
||
<h3>Структура затрат по категориям</h3>
|
||
<p>Доля техподдержки, лицензий, подписок, услуг и прочих расходов в общем итоге за два периода.</p>
|
||
<div id="cats" style="display:grid;grid-template-columns:repeat(auto-fit,minmax(260px,1fr));gap:var(--kt-ai-space-6);margin-top:var(--kt-ai-space-5)"></div>
|
||
</article>
|
||
<article class="kt-ai-tile" data-span="full">
|
||
<h3>Крупнейшие позиции 2025</h3>
|
||
<p>Топ-10 позиций по фактическим затратам за 2025 год — с чего начинать ревизию.</p>
|
||
<div id="top2025" style="margin-top:var(--kt-ai-space-5)"></div>
|
||
</article>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<section id="list" class="kt-ai-section" data-divider="true">
|
||
<div class="kt-ai-wrap">
|
||
<div class="kt-ai-section-head">
|
||
<h2>Реестр позиций</h2>
|
||
<p id="count" class="meta">Загрузка данных…</p>
|
||
</div>
|
||
|
||
<div class="controls">
|
||
<input id="q" class="kt-ai-input" type="search" placeholder="Поиск по позиции…" style="max-width:320px">
|
||
<button id="btnExport" class="kt-ai-btn" type="button">⬇ Выгрузить в Excel</button>
|
||
</div>
|
||
|
||
<div class="chips" id="catFilter" style="margin-bottom:var(--kt-ai-space-5)"></div>
|
||
|
||
<div class="kt-ai-grid" style="margin-top:var(--kt-ai-space-6)">
|
||
<article class="kt-ai-tile" data-span="full" style="padding:0;background:transparent;border:none">
|
||
<div class="table-wrap">
|
||
<table id="tbl">
|
||
<thead>
|
||
<tr>
|
||
<th data-k="name">Позиция</th>
|
||
<th data-k="cat">Категория</th>
|
||
<th class="num" data-k="f2025" data-num="1">2025, ₸</th>
|
||
<th class="num" data-k="f2026" data-num="1">6 мес 2026, ₸</th>
|
||
<th class="num" data-k="delta" data-num="1">Δ, ₸</th>
|
||
<th class="num" data-k="deltaP" data-num="2">Δ, %</th>
|
||
<th></th>
|
||
</tr>
|
||
</thead>
|
||
<tbody></tbody>
|
||
</table>
|
||
</div>
|
||
</article>
|
||
</div>
|
||
|
||
<p class="note">Источник: файл «Сервисные контракты.xlsx», лист «ОБ-Тех.поддержка». Значения «—» означают, что позиция отсутствует или не детализирована в соответствующем периоде. Сравнение периодов по Δ корректно только для позиций, присутствующих в обоих периодах.</p>
|
||
</div>
|
||
</section>
|
||
</main>
|
||
|
||
<footer class="kt-ai-wrap kt-ai-pagefoot">
|
||
<span>© 2026 Ревизия сервисных контрактов</span>
|
||
<span class="kt-ai-spacer"></span>
|
||
<span>По данным «Сервисные контракты.xlsx»</span>
|
||
</footer>
|
||
</div>
|
||
|
||
<script src="script.js"></script>
|
||
</body>
|
||
</html>
|