173 lines
9.6 KiB
HTML
173 lines
9.6 KiB
HTML
<!DOCTYPE html>
|
||
<!-- Дизайн: Стандартный дизайн. Сохраняй все пять CSS; подробности в design.md. -->
|
||
<html lang="ru" data-theme="light">
|
||
<head>
|
||
<meta charset="utf-8">
|
||
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||
<title>Розничные продажи — дашборд по городам</title>
|
||
<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">
|
||
<link rel="stylesheet" href="design-system/vibe-theme.css">
|
||
<style>
|
||
.kt-ai-screen { display: none; padding: var(--kt-ai-space-6); max-width: 1180px; margin: 0 auto; width: 100%; }
|
||
.kt-ai-screen.is-active { display: block; }
|
||
.screen-head { display: flex; align-items: baseline; gap: var(--kt-ai-space-4); flex-wrap: wrap; margin-bottom: var(--kt-ai-space-3); }
|
||
.screen-title { font-size: var(--kt-ai-text-2xl); font-weight: var(--kt-ai-weight-semibold); letter-spacing: -.02em; }
|
||
.screen-sub { font-size: var(--kt-ai-text-sm); color: var(--kt-ai-fg-muted); }
|
||
.dash-legend { display: flex; gap: var(--kt-ai-space-5); flex-wrap: wrap; margin-bottom: var(--kt-ai-space-5); }
|
||
.dash-legend span { display: inline-flex; align-items: center; gap: var(--kt-ai-space-2); font-size: var(--kt-ai-text-xs); color: var(--kt-ai-fg-muted); }
|
||
.dash-legend i { width: 10px; height: 10px; border-radius: 3px; display: inline-block; }
|
||
.legend-ok i { background: var(--kt-ai-chart-blue); }
|
||
.legend-down i { background: var(--kt-ai-chart-salmon); }
|
||
.main-grid { display: grid; grid-template-columns: minmax(0, 1.15fr) minmax(0, .85fr); gap: var(--kt-ai-space-6); align-items: start; }
|
||
.hbar-chart { display: flex; flex-direction: column; gap: var(--kt-ai-space-3); }
|
||
.hbar-row { display: grid; grid-template-columns: 92px minmax(0, 1fr) 76px; align-items: center; gap: var(--kt-ai-space-3); cursor: pointer; padding: 2px var(--kt-ai-space-2); margin: 0; border: none; background: none; text-align: left; border-radius: var(--kt-ai-radius-md); font: inherit; color: inherit; }
|
||
.hbar-row:hover { background: var(--kt-ai-bg-hover); }
|
||
.hbar-name { font-size: var(--kt-ai-text-sm); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
||
.hbar-track { background: var(--kt-ai-bg-soft); border: 1px solid var(--kt-ai-border); border-radius: 3px; height: 20px; overflow: hidden; }
|
||
.hbar-fill { display: block; height: 100%; border-radius: 2px; background: var(--kt-ai-chart-blue); }
|
||
.hbar-val { font-size: var(--kt-ai-text-sm); font-variant-numeric: tabular-nums; text-align: right; color: var(--kt-ai-fg); }
|
||
.toplist { display: flex; flex-direction: column; }
|
||
.toplist-item { display: flex; align-items: center; gap: var(--kt-ai-space-3); padding: var(--kt-ai-space-3) 0; border-bottom: 1px solid var(--kt-ai-divider); }
|
||
.toplist-item:last-child { border-bottom: none; }
|
||
.toplist-rank { width: 22px; height: 22px; border-radius: 50%; background: var(--kt-ai-bg-soft); border: 1px solid var(--kt-ai-border); display: inline-flex; align-items: center; justify-content: center; font-size: var(--kt-ai-text-2xs); color: var(--kt-ai-fg-muted); flex: none; }
|
||
.toplist-city { font-size: var(--kt-ai-text-sm); flex: 1; }
|
||
.toplist-val { font-size: var(--kt-ai-text-sm); font-variant-numeric: tabular-nums; }
|
||
.delta { display: inline-flex; align-items: center; gap: 3px; font-variant-numeric: tabular-nums; white-space: nowrap; }
|
||
.delta svg { width: 13px; height: 13px; }
|
||
.delta[data-dir="up"] { color: var(--kt-ai-status-ok-fg); }
|
||
.delta[data-dir="down"] { color: var(--kt-ai-status-risk-fg); }
|
||
.city-kpis { display: grid; grid-template-columns: repeat(auto-fit, minmax(170px, 1fr)); gap: var(--kt-ai-space-6); padding: var(--kt-ai-space-6) 0; }
|
||
.city-kpis .kt-ai-kpi .value { font-size: var(--kt-ai-text-xl); }
|
||
.city-grid { display: grid; grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); gap: var(--kt-ai-space-6); align-items: start; }
|
||
.back-row { display: flex; align-items: center; gap: var(--kt-ai-space-3); margin-bottom: var(--kt-ai-space-4); }
|
||
.mini-stat { }
|
||
.mini-stat .label { font-size: var(--kt-ai-text-2xs); color: var(--kt-ai-fg-muted); margin-bottom: 2px; }
|
||
.mini-stat .value { font-size: var(--kt-ai-text-lg); font-weight: var(--kt-ai-weight-semibold); font-variant-numeric: tabular-nums; }
|
||
@media (max-width: 760px) {
|
||
.kt-ai-screen { padding: var(--kt-ai-space-4); }
|
||
.main-grid, .city-grid { grid-template-columns: 1fr; }
|
||
.hbar-row { grid-template-columns: 74px minmax(0, 1fr) 68px; }
|
||
.city-kpis { gap: var(--kt-ai-space-4); }
|
||
}
|
||
</style>
|
||
</head>
|
||
<body class="kt-ai-app">
|
||
|
||
<header class="kt-ai-pagehead">
|
||
<div class="kt-ai-wrap kt-ai-pagehead-in" style="display:flex;align-items:center;gap:var(--kt-ai-space-4)">
|
||
<img src="https://code.vibe42.kz/tore/aitu/kt-logo.svg" alt="Казахтелеком" height="28" style="flex:none">
|
||
<strong style="font-size:var(--kt-ai-text-md)">Розничные продажи</strong>
|
||
<span class="kt-ai-spacer"></span>
|
||
<span class="kt-ai-meta">Февраль 2026</span>
|
||
</div>
|
||
</header>
|
||
|
||
<!-- Главный экран: города -->
|
||
<section id="screen-main" class="kt-ai-screen is-active">
|
||
<div class="screen-head">
|
||
<h1 class="screen-title">Города</h1>
|
||
<span class="screen-sub" id="mainSub">—</span>
|
||
</div>
|
||
|
||
<div class="kt-ai-kpi-strip" id="kpiMain" data-cards="true"></div>
|
||
|
||
<div class="kt-ai-table-toolbar" style="padding-bottom:var(--kt-ai-space-2)">
|
||
<div style="display:flex;align-items:center;gap:8px;max-width:240px">
|
||
<svg class="kt-icon" style="width:15px;height:15px;color:var(--kt-ai-fg-faint);flex:none"><use href="#search"></use></svg>
|
||
<input id="citySearch" class="kt-ai-input" placeholder="Найти город…">
|
||
</div>
|
||
<div class="kt-ai-select-wrap" style="max-width:240px">
|
||
<select id="dirSelect" class="kt-ai-select">
|
||
<option value="">Все направления</option>
|
||
</select>
|
||
</div>
|
||
<div id="dirChips"></div>
|
||
</div>
|
||
|
||
<div class="main-grid" style="margin-top:var(--kt-ai-space-4)">
|
||
<section class="kt-ai-chart-card" style="margin-bottom:0">
|
||
<div class="cc-head"><div><div class="cc-title">Выручка по городам</div><div class="kt-ai-meta">млн ₸ · февраль 2026</div></div></div>
|
||
<div class="dash-legend">
|
||
<span class="legend-ok"><i></i>рост к январю</span>
|
||
<span class="legend-down"><i></i>снижение к январю</span>
|
||
</div>
|
||
<div id="cityBars" class="hbar-chart"></div>
|
||
</section>
|
||
<section class="kt-ai-chart-card" style="margin-bottom:0">
|
||
<div class="cc-head"><div><div class="cc-title">Лидеры февраля</div><div class="kt-ai-meta">по выручке</div></div></div>
|
||
<div id="cityTop" class="toplist"></div>
|
||
</section>
|
||
</div>
|
||
|
||
<div class="kt-ai-table-wrap" data-framed="true" style="margin-top:var(--kt-ai-space-6)">
|
||
<div class="kt-ai-table-toolbar">
|
||
<strong style="font-size:var(--kt-ai-text-md)">Все города</strong>
|
||
<span class="kt-ai-meta" id="tableCount">—</span>
|
||
</div>
|
||
<table class="kt-ai-table">
|
||
<thead>
|
||
<tr>
|
||
<th>Город</th>
|
||
<th>Направление</th>
|
||
<th class="num">Магазины</th>
|
||
<th class="num">Трафик</th>
|
||
<th class="num">Выручка, млн ₸</th>
|
||
<th class="num">Средний чек</th>
|
||
<th class="num">Динамика</th>
|
||
<th>Статус</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody id="cityTbody"></tbody>
|
||
</table>
|
||
<div class="kt-ai-empty" id="cityEmpty" hidden>
|
||
<div class="title">Городы не найдены</div>
|
||
<div>Измените фильтр направления или текст поиска.</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- Экран города -->
|
||
<section id="screen-city" class="kt-ai-screen">
|
||
<div class="back-row">
|
||
<button class="kt-ai-btn" data-variant="ghost" data-size="sm" id="backBtn" type="button">
|
||
<svg class="kt-icon" style="width:15px;height:15px"><use href="#chevronLeft"></use></svg>
|
||
К городам
|
||
</button>
|
||
</div>
|
||
<div class="screen-head">
|
||
<h1 class="screen-title" id="cityTitle">—</h1>
|
||
<span class="screen-sub" id="cityMeta">—</span>
|
||
</div>
|
||
|
||
<div class="kt-ai-kpi-strip city-kpis" id="kpiCity" data-cards="true"></div>
|
||
|
||
<div class="city-grid">
|
||
<section class="kt-ai-chart-card" style="margin-bottom:0">
|
||
<div class="cc-head"><div><div class="cc-title" id="trendTitle">Динамика выручки</div><div class="kt-ai-meta">млн ₸ · 6 месяцев</div></div></div>
|
||
<div id="cityTrend" class="hbar-chart"></div>
|
||
</section>
|
||
<section class="kt-ai-chart-card" style="margin-bottom:0">
|
||
<div class="cc-head"><div><div class="cc-title">Каналы продаж</div><div class="kt-ai-meta">выручка, млн ₸</div></div></div>
|
||
<div id="cityChannels" class="hbar-chart"></div>
|
||
<div class="mini-stat" style="margin-top:var(--kt-ai-space-5)">
|
||
<div class="label">Доля розницы в выручке города</div>
|
||
<div class="value" id="cityShare">—</div>
|
||
</div>
|
||
</section>
|
||
</div>
|
||
|
||
<section class="kt-ai-conclusion" style="margin-top:var(--kt-ai-space-6)">
|
||
<div class="title">Итог месяца</div>
|
||
<p class="text" id="citySummary">—</p>
|
||
</section>
|
||
</section>
|
||
|
||
<script src="design-system/icons/kt-ai-icons.js"></script>
|
||
<script src="design-system/kt-ai-chart-tip.js" defer></script>
|
||
<script src="script.js" defer></script>
|
||
</body>
|
||
</html>
|