Дашборд B2C на дизайн-системе KT AI

This commit is contained in:
tore 2026-09-04 07:09:12 +00:00
parent e6045c99ac
commit ab0000701c

View File

@ -1,155 +1,185 @@
<!doctype html>
<html lang="ru">
<html lang="ru" data-theme="light">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Топ услуг B2C по регионам</title>
<link rel="stylesheet" href="./design-system/variables.css">
<link rel="stylesheet" href="./design-system/typography.css">
<link rel="stylesheet" href="./design-system/components.css">
<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>
:root {
--kt-blue: #0096D7;
--kt-dark: #1a1a2e;
--kt-gray: #f5f5f7;
--kt-border: #e0e0e5;
}
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
background: var(--kt-gray);
color: var(--kt-dark);
line-height: 1.5;
}
.container { max-width: 1400px; margin: 0 auto; padding: 0 24px; }
/* Header */
.header {
background: white;
border-bottom: 1px solid var(--kt-border);
.dashboard-header {
background: var(--kt-ai-card-bg);
border-bottom: 1px solid var(--kt-ai-border);
padding: 20px 0;
position: sticky;
top: 0;
z-index: 100;
}
.header-content {
.dashboard-header-in {
display: flex;
align-items: center;
gap: 16px;
}
.header img { height: 48px; }
.header h1 { font-size: 24px; font-weight: 600; color: var(--kt-dark); }
.period { font-size: 14px; color: #666; margin-top: 4px; }
.dashboard-header img { height: 48px; }
.dashboard-header h1 {
font-size: var(--kt-ai-text-xl);
font-weight: var(--kt-ai-weight-semibold);
color: var(--kt-ai-fg);
margin: 0;
}
.period {
font-size: var(--kt-ai-text-sm);
color: var(--kt-ai-fg-muted);
margin-top: 4px;
}
/* Summary Cards */
.summary { padding: 32px 0; }
.summary-section { padding: 32px 0; }
.summary-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
gap: 20px;
gap: var(--kt-ai-space-5);
}
.card {
background: white;
border-radius: 12px;
padding: 24px;
box-shadow: 0 2px 8px rgba(0,0,0,0.06);
border: 1px solid var(--kt-border);
.summary-card {
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);
}
.card-label {
font-size: var(--kt-ai-text-sm);
color: var(--kt-ai-fg-muted);
margin-bottom: var(--kt-ai-space-2);
}
.card-value {
font-size: var(--kt-ai-text-4xl);
font-weight: var(--kt-ai-weight-bold);
color: var(--kt-ai-primary);
}
.card-sub {
font-size: var(--kt-ai-text-xs);
color: var(--kt-ai-fg-faint);
margin-top: var(--kt-ai-space-2);
}
.card-label { font-size: 14px; color: #666; margin-bottom: 8px; }
.card-value { font-size: 32px; font-weight: 700; color: var(--kt-blue); }
.card-sub { font-size: 13px; color: #888; margin-top: 8px; }
/* Charts */
.charts { padding: 0 0 32px; }
.charts-section { padding: 0 0 32px; }
.charts-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(500px, 1fr));
gap: 24px;
gap: var(--kt-ai-space-6);
}
.chart-card {
background: white;
border-radius: 12px;
padding: 24px;
box-shadow: 0 2px 8px rgba(0,0,0,0.06);
border: 1px solid var(--kt-border);
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);
}
.chart-title {
font-size: var(--kt-ai-text-lg);
font-weight: var(--kt-ai-weight-semibold);
margin-bottom: var(--kt-ai-space-5);
color: var(--kt-ai-fg);
}
.chart-title { font-size: 18px; font-weight: 600; margin-bottom: 20px; }
.chart-container { position: relative; height: 300px; }
canvas { width: 100% !important; height: 100% !important; }
/* Filters */
.filters { padding: 0 0 24px; }
.filters-section { padding: 0 0 var(--kt-ai-space-6); }
.filter-bar {
background: white;
border-radius: 12px;
padding: 20px 24px;
box-shadow: 0 2px 8px rgba(0,0,0,0.06);
border: 1px solid var(--kt-border);
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-5) var(--kt-ai-space-6);
display: flex;
gap: 16px;
gap: var(--kt-ai-space-4);
align-items: center;
flex-wrap: wrap;
}
.filter-label { font-size: 14px; font-weight: 500; }
.filter-label {
font-size: var(--kt-ai-text-sm);
font-weight: var(--kt-ai-weight-medium);
color: var(--kt-ai-fg);
}
.filter-select {
padding: 10px 16px;
border: 1px solid var(--kt-border);
border-radius: 8px;
font-size: 14px;
background: white;
border: 1px solid var(--kt-ai-border);
border-radius: var(--kt-ai-radius-lg);
font-size: var(--kt-ai-text-sm);
background: var(--kt-ai-card-bg);
color: var(--kt-ai-fg);
cursor: pointer;
min-width: 200px;
}
.filter-select:focus { outline: 2px solid var(--kt-blue); border-color: var(--kt-blue); }
.chips { display: flex; gap: 8px; flex-wrap: wrap; }
.filter-select:focus {
outline: 2px solid var(--kt-ai-primary);
border-color: var(--kt-ai-primary);
}
.chips { display: flex; gap: var(--kt-ai-space-2); flex-wrap: wrap; }
.chip {
padding: 8px 16px;
border-radius: 20px;
font-size: 13px;
background: var(--kt-gray);
border: 1px solid var(--kt-border);
border-radius: var(--kt-ai-radius-full);
font-size: var(--kt-ai-text-xs);
background: var(--kt-ai-bg-soft);
border: 1px solid var(--kt-ai-border);
cursor: pointer;
transition: all 0.2s;
color: var(--kt-ai-fg);
}
.chip:hover { background: var(--kt-ai-border); }
.chip.active {
background: var(--kt-ai-primary);
color: white;
border-color: var(--kt-ai-primary);
}
.chip:hover { background: #e8e8ed; }
.chip.active { background: var(--kt-blue); color: white; border-color: var(--kt-blue); }
/* Table */
.table-section { padding: 0 0 40px; }
.table-section { padding: 0 0 var(--kt-ai-space-10); }
.table-card {
background: white;
border-radius: 12px;
box-shadow: 0 2px 8px rgba(0,0,0,0.06);
border: 1px solid var(--kt-border);
background: var(--kt-ai-card-bg);
border: 1px solid var(--kt-ai-card-border);
border-radius: var(--kt-ai-radius-2xl);
overflow: hidden;
}
.table-header {
padding: 20px 24px;
border-bottom: 1px solid var(--kt-border);
padding: var(--kt-ai-space-5) var(--kt-ai-space-6);
border-bottom: 1px solid var(--kt-ai-border);
display: flex;
justify-content: space-between;
align-items: center;
}
.table-title { font-size: 18px; font-weight: 600; }
.table-title {
font-size: var(--kt-ai-text-lg);
font-weight: var(--kt-ai-weight-semibold);
color: var(--kt-ai-fg);
}
.table-container { overflow-x: auto; }
table { width: 100%; border-collapse: collapse; }
th, td { padding: 14px 20px; text-align: left; border-bottom: 1px solid var(--kt-border); }
th { background: var(--kt-gray); font-weight: 600; font-size: 13px; color: #666; text-transform: uppercase; letter-spacing: 0.5px; }
th, td {
padding: 14px 20px;
text-align: left;
border-bottom: 1px solid var(--kt-ai-border);
}
th {
background: var(--kt-ai-bg-soft);
font-weight: var(--kt-ai-weight-semibold);
font-size: var(--kt-ai-text-xs);
color: var(--kt-ai-fg-muted);
text-transform: uppercase;
letter-spacing: 0.5px;
}
tr { transition: background 0.2s; cursor: pointer; }
tr:hover { background: #f8f9fc; }
tr:hover { background: var(--kt-ai-bg-soft); }
tr.selected { background: rgba(0, 150, 215, 0.08); }
.num { color: #999; font-size: 13px; }
.amount { font-weight: 600; color: var(--kt-dark); }
.num { color: var(--kt-ai-fg-faint); font-size: var(--kt-ai-text-xs); }
.amount { font-weight: var(--kt-ai-weight-semibold); color: var(--kt-ai-fg); }
.region-tag {
display: inline-block;
padding: 4px 10px;
border-radius: 6px;
font-size: 12px;
background: var(--kt-gray);
color: var(--kt-dark);
border-radius: var(--kt-ai-radius-lg);
font-size: var(--kt-ai-text-xs);
background: var(--kt-ai-bg-soft);
color: var(--kt-ai-fg);
}
/* Modal */
.modal-overlay {
display: none;
position: fixed;
@ -161,47 +191,57 @@
}
.modal-overlay.on { display: flex; }
.modal {
background: white;
border-radius: 16px;
padding: 32px;
background: var(--kt-ai-card-bg);
border-radius: var(--kt-ai-radius-3xl);
padding: var(--kt-ai-space-8);
max-width: 600px;
width: 90%;
max-height: 80vh;
overflow-y: auto;
border: 1px solid var(--kt-ai-card-border);
}
.modal-title {
font-size: var(--kt-ai-text-2xl);
font-weight: var(--kt-ai-weight-semibold);
margin-bottom: var(--kt-ai-space-4);
color: var(--kt-ai-fg);
}
.modal-row {
display: flex;
justify-content: space-between;
padding: var(--kt-ai-space-3) 0;
border-bottom: 1px solid var(--kt-ai-border);
}
.modal-title { font-size: 22px; font-weight: 600; margin-bottom: 16px; }
.modal-row { display: flex; justify-content: space-between; padding: 12px 0; border-bottom: 1px solid var(--kt-border); }
.modal-row:last-child { border-bottom: none; }
.modal-label { color: #666; }
.modal-value { font-weight: 600; }
.modal-label { color: var(--kt-ai-fg-muted); }
.modal-value { font-weight: var(--kt-ai-weight-semibold); color: var(--kt-ai-fg); }
.close-btn {
margin-top: 20px;
margin-top: var(--kt-ai-space-5);
padding: 12px 24px;
background: var(--kt-blue);
background: var(--kt-ai-primary);
color: white;
border: none;
border-radius: 8px;
font-size: 14px;
border-radius: var(--kt-ai-radius-lg);
font-size: var(--kt-ai-text-sm);
cursor: pointer;
width: 100%;
}
.close-btn:hover { opacity: 0.9; }
/* Responsive */
@media (max-width: 768px) {
.header h1 { font-size: 18px; }
.dashboard-header h1 { font-size: var(--kt-ai-text-lg); }
.summary-grid { grid-template-columns: 1fr; }
.charts-grid { grid-template-columns: 1fr; }
.filter-bar { flex-direction: column; align-items: stretch; }
.filter-select { width: 100%; }
th, td { padding: 10px 12px; font-size: 13px; }
th, td { padding: 10px 12px; font-size: var(--kt-ai-text-xs); }
}
</style>
</head>
<body>
<header class="header">
<div class="container">
<div class="header-content">
<header class="dashboard-header">
<div class="kt-ai-wrap">
<div class="dashboard-header-in">
<img src="./kt-logo.svg" alt="Казахтелеком" height="48">
<div>
<h1>Топ услуг B2C по регионам</h1>
@ -211,25 +251,25 @@
</div>
</header>
<main class="container">
<section class="summary">
<main class="kt-ai-wrap">
<section class="summary-section">
<div class="summary-grid">
<div class="card">
<div class="summary-card">
<div class="card-label">Всего покупок</div>
<div class="card-value" id="totalPurchases">0</div>
<div class="card-sub">за июль 2026</div>
</div>
<div class="card">
<div class="summary-card">
<div class="card-label">Всего регионов</div>
<div class="card-value" id="totalRegions">0</div>
<div class="card-sub">в выборке</div>
</div>
<div class="card">
<div class="summary-card">
<div class="card-label">Услуга-лидер</div>
<div class="card-value" id="topService" style="font-size: 20px;">-</div>
<div class="card-value" id="topService" style="font-size: var(--kt-ai-text-xl);">-</div>
<div class="card-sub">по количеству</div>
</div>
<div class="card">
<div class="summary-card">
<div class="card-label">Регион-лидер</div>
<div class="card-value" id="topRegion">-</div>
<div class="card-sub">по покупкам</div>
@ -237,7 +277,7 @@
</div>
</section>
<section class="charts">
<section class="charts-section">
<div class="charts-grid">
<div class="chart-card">
<div class="chart-title">Топ-10 регионов по покупкам</div>
@ -254,7 +294,7 @@
</div>
</section>
<section class="filters">
<section class="filters-section">
<div class="filter-bar">
<div class="filter-label">Фильтр по региону:</div>
<select class="filter-select" id="regionFilter">