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