v2: перестроил на ДС KT AI — классы kt-ai-*, токены var(--kt-ai-…), единый статус данных

This commit is contained in:
tore 2026-09-13 15:19:01 +00:00
parent 75947bbfeb
commit dd2c9ae9fd

View File

@ -9,27 +9,14 @@
<link rel="stylesheet" href="./design-system/kt-ai-components.css">
<link rel="stylesheet" href="./design-system/kt-ai-page.css">
<style>
body { min-height: 100vh; display: flex; flex-direction: column; margin: 0; }
.kt-ai-app-header { display: flex; align-items: center; gap: var(--kt-ai-space-4); padding: var(--kt-ai-space-3) 0; border-bottom: 1px solid var(--kt-ai-border); }
.kt-ai-app-title { font-size: var(--kt-ai-text-lg); font-weight: var(--kt-ai-weight-semibold); }
.kt-ai-filters-bar { display: flex; gap: var(--kt-ai-space-3); flex-wrap: wrap; align-items: center; margin-bottom: var(--kt-ai-space-5); }
.kt-ai-kpi-strip { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: var(--kt-ai-space-4); margin-bottom: var(--kt-ai-space-6); }
.kt-ai-kpi { background: var(--kt-ai-card-bg); border: 1px solid var(--kt-ai-card-border); border-radius: var(--kt-ai-radius-xl); padding: var(--kt-ai-space-4); }
.kt-ai-kpi .value { font-size: var(--kt-ai-text-2xl); font-weight: var(--kt-ai-weight-bold); font-family: var(--kt-ai-font-mono); color: var(--kt-ai-fg); }
.kt-ai-kpi .label { font-size: var(--kt-ai-text-sm); color: var(--kt-ai-fg-muted); margin-top: var(--kt-ai-space-1); }
.kt-ai-kpi .hint { font-size: var(--kt-ai-text-xs); color: var(--kt-ai-fg-faint); margin-top: var(--kt-ai-space-2); }
.kt-ai-chart-wrap { background: var(--kt-ai-card-bg); border: 1px solid var(--kt-ai-card-border); border-radius: var(--kt-ai-radius-xl); padding: var(--kt-ai-space-4); margin-bottom: var(--kt-ai-space-6); }
.kt-ai-chart { height: 200px; display: flex; align-items: flex-end; gap: 8px; }
.kt-ai-chart-bar { flex: 1; background: var(--kt-ai-chart-blue); border-radius: 2px 2px 0 0; position: relative; min-width: 20px; max-width: 28px; }
.kt-ai-chart-bar[data-kt-tip] { cursor: pointer; }
.kt-ai-chart-bar:hover { opacity: 0.85; }
.kt-ai-table-wrap { overflow-x: auto; margin-bottom: var(--kt-ai-space-6); }
.kt-ai-table { width: 100%; border-collapse: collapse; font-size: var(--kt-ai-text-sm); }
.kt-ai-table th { text-align: left; padding: var(--kt-ai-space-2) var(--kt-ai-space-3); border-bottom: 1px solid var(--kt-ai-border-strong); color: var(--kt-ai-fg-muted); font-weight: var(--kt-ai-weight-medium); }
.kt-ai-table td { padding: var(--kt-ai-space-2) var(--kt-ai-space-3); border-bottom: 1px solid var(--kt-ai-border); color: var(--kt-ai-fg); }
.kt-ai-table td.num { text-align: right; font-family: var(--kt-ai-font-mono); tabular-nums: lining; }
.kt-ai-insights { background: var(--kt-ai-bg-soft); border-radius: var(--kt-ai-radius-xl); padding: var(--kt-ai-space-4); margin-bottom: var(--kt-ai-space-6); }
.kt-ai-insights h3 { font-size: var(--kt-ai-text-base); font-weight: var(--kt-ai-weight-semibold); margin-bottom: var(--kt-ai-space-3); }
.kt-ai-insights h3 { font-size: var(--kt-ai-text-lg); font-weight: var(--kt-ai-weight-semibold); margin-bottom: var(--kt-ai-space-3); }
.kt-ai-insights p { font-size: var(--kt-ai-text-sm); color: var(--kt-ai-fg-muted); margin-bottom: var(--kt-ai-space-3); line-height: 1.5; }
.kt-ai-recommendations { margin-top: var(--kt-ai-space-4); }
.kt-ai-recommendations h4 { font-size: var(--kt-ai-text-sm); font-weight: var(--kt-ai-weight-semibold); margin-bottom: var(--kt-ai-space-2); }
@ -42,16 +29,18 @@ body { min-height: 100vh; display: flex; flex-direction: column; margin: 0; }
</head>
<body data-kt-data-mode="demo">
<header class="kt-ai-wrap">
<div class="kt-ai-app-header">
<img src="https://code.vibe42.kz/tore/aitu/kt-logo.svg" alt="Казахтелеком" height="28">
<span class="kt-ai-app-title">Бизнес-метрики</span>
<header class="kt-ai-pagehead">
<div class="kt-ai-wrap kt-ai-pagehead-in">
<div style="display:flex;align-items:center;gap:var(--kt-ai-space-3)">
<img src="https://code.vibe42.kz/tore/aitu/kt-logo.svg" alt="Казахтелеком" height="28">
<strong>Бизнес-метрики</strong>
</div>
<span class="kt-ai-spacer"></span>
<span class="kt-ai-chip" data-tone="orange">Демо-данные</span>
</div>
</header>
<main class="kt-ai-wrap" style="flex:1; padding-top: var(--kt-ai-space-5);">
<main class="kt-ai-wrap" style="padding-top:var(--kt-ai-space-5)">
<div class="kt-ai-filters-bar">
<div class="kt-ai-field">
@ -81,7 +70,7 @@ body { min-height: 100vh; display: flex; flex-direction: column; margin: 0; }
</div>
<div class="kt-ai-field">
<label>
<input type="checkbox" id="toggle-data" style="margin-right: var(--kt-ai-space-2)">
<input type="checkbox" id="toggle-data" style="margin-right:var(--kt-ai-space-2)">
Нет данных
</label>
</div>
@ -110,11 +99,11 @@ body { min-height: 100vh; display: flex; flex-direction: column; margin: 0; }
</div>
</div>
<div data-kt-region="chart" class="kt-ai-chart-wrap">
<div data-kt-region="chart" class="kt-ai-card" style="padding:var(--kt-ai-space-4);margin-bottom:var(--kt-ai-space-6)">
<div id="chart" class="kt-ai-chart"></div>
</div>
<div data-kt-region="table" class="kt-ai-table-wrap">
<div class="kt-ai-table-wrap" data-kt-region="table" style="margin-bottom:var(--kt-ai-space-6)">
<table class="kt-ai-table">
<thead>
<tr>
@ -133,7 +122,7 @@ body { min-height: 100vh; display: flex; flex-direction: column; margin: 0; }
<div data-kt-region="insights" class="kt-ai-insights">
<h3>Объяснение отклонений</h3>
<p id="insights-text">Загрузка...</p>
<div class="kt-ai-recommendations">
<div data-kt-region="recommendations" class="kt-ai-recommendations">
<h4>Рекомендации</h4>
<ul id="recommendations-list"></ul>
</div>
@ -262,18 +251,23 @@ function render(view) {
document.documentElement.dataset.ktDataState = view.status;
const emptyRegion = document.querySelector('[data-kt-region="empty"]');
const kpiRegion = document.querySelector('[data-kt-region="kpi"]');
const chartRegion = document.querySelector('[data-kt-region="chart"]');
const tableRegion = document.querySelector('[data-kt-region="table"]');
const insightsRegion = document.querySelector('[data-kt-region="insights"]');
if (view.status === "empty") {
emptyRegion.style.display = "block";
document.querySelector('[data-kt-region="kpi"]').style.display = "none";
document.querySelector('[data-kt-region="chart"]').style.display = "none";
document.querySelector('[data-kt-region="table"]').style.display = "none";
document.querySelector('[data-kt-region="insights"]').style.display = "none";
kpiRegion.style.display = "none";
chartRegion.parentElement.style.display = "none";
tableRegion.parentElement.style.display = "none";
insightsRegion.style.display = "none";
} else {
emptyRegion.style.display = "none";
document.querySelector('[data-kt-region="kpi"]').style.display = "grid";
document.querySelector('[data-kt-region="chart"]').style.display = "block";
document.querySelector('[data-kt-region="table"]').style.display = "block";
document.querySelector('[data-kt-region="insights"]').style.display = "block";
kpiRegion.style.display = "grid";
chartRegion.parentElement.style.display = "block";
tableRegion.parentElement.style.display = "block";
insightsRegion.style.display = "block";
document.getElementById("kpi-conversion").textContent = view.kpis.conversion || "—";
document.getElementById("kpi-satisfaction").textContent = view.kpis.satisfaction || "—";
@ -336,7 +330,6 @@ document.addEventListener("DOMContentLoaded", function() {
document.querySelectorAll('[data-kt-tip]').forEach(el => {
el.addEventListener("mouseenter", function() {
const tip = document.createElement("div");
tip.className = "kt-ai-chart-tip";
tip.textContent = this.getAttribute("data-kt-tip");
tip.style.position = "absolute";
tip.style.background = "var(--kt-ai-bg)";
@ -345,6 +338,7 @@ document.addEventListener("DOMContentLoaded", function() {
tip.style.borderRadius = "var(--kt-ai-radius-md)";
tip.style.fontSize = "var(--kt-ai-text-xs)";
tip.style.pointerEvents = "none";
tip.style.zIndex = "var(--kt-ai-z-tooltip)";
document.body.appendChild(tip);
const rect = this.getBoundingClientRect();
tip.style.left = (rect.left + rect.width/2 - tip.offsetWidth/2) + "px";