192 lines
11 KiB
HTML
192 lines
11 KiB
HTML
<!-- no-design-system: приложение с кастомной структурой (не лендинг) -->
|
||
<!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="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>
|
||
.kt-ai-btn { text-decoration: none; }
|
||
.app-shell { display:flex; min-height:100vh; background:var(--kt-ai-bg); }
|
||
.sidebar { width:280px; background:var(--kt-ai-bg-soft); border-right:1px solid var(--kt-ai-border); padding:var(--kt-ai-space-4); display:flex; flex-direction:column; position:fixed; height:100vh; overflow:auto; }
|
||
.main-content { margin-left:280px; flex:1; display:flex; flex-direction:column; }
|
||
.topbar { display:flex; align-items:center; gap:var(--kt-ai-space-4); padding:var(--kt-ai-space-4) var(--kt-ai-space-6); border-bottom:1px solid var(--kt-ai-border); position:sticky; top:0; background:var(--kt-ai-bg); z-index:10; }
|
||
.topbar-title { font-size:var(--kt-ai-text-lg); font-weight:var(--kt-ai-weight-semibold); margin:0; }
|
||
.kpi-strip { display:flex; gap:var(--kt-ai-space-6); padding:var(--kt-ai-space-4) var(--kt-ai-space-6); border-bottom:1px solid var(--kt-ai-border); }
|
||
.kpi { padding:var(--kt-ai-space-3) var(--kt-ai-space-4); background:var(--kt-ai-card-bg); border:1px solid var(--kt-ai-card-border); border-radius:var(--kt-ai-radius-lg); }
|
||
.kpi-value { font-size:var(--kt-ai-text-2xl); font-weight:var(--kt-ai-weight-bold); color:var(--kt-ai-fg); }
|
||
.kpi-label { font-size:var(--kt-ai-text-sm); color:var(--kt-ai-fg-muted); margin-top:var(--kt-ai-space-1); }
|
||
.toolbar { padding:var(--kt-ai-space-4) var(--kt-ai-space-6); display:flex; gap:var(--kt-ai-space-4); align-items:center; }
|
||
.table-wrap { flex:1; overflow:auto; padding:0 var(--kt-ai-space-6) var(--kt-ai-space-6); }
|
||
.appeals-table { width:100%; border-collapse:collapse; }
|
||
.appeals-table th, .appeals-table td { padding:var(--kt-ai-space-3) var(--kt-ai-space-4); text-align:left; border-bottom:1px solid var(--kt-ai-divider); }
|
||
.appeals-table th { font-weight:var(--kt-ai-weight-semibold); color:var(--kt-ai-fg-muted); font-size:var(--kt-ai-text-sm); position:sticky; top:0; background:var(--kt-ai-bg); }
|
||
.appeals-table tr:hover { background:var(--kt-ai-bg-soft); }
|
||
.status-pill { display:inline-block; padding:var(--kt-ai-space-1) var(--kt-ai-space-2); border-radius:var(--kt-ai-radius-full); font-size:var(--kt-ai-text-xs); font-weight:var(--kt-ai-weight-medium); }
|
||
.status-new { background:var(--kt-ai-bg-soft); color:var(--kt-ai-primary); }
|
||
.status-duplicate { background:var(--kt-ai-bg-soft); color:var(--kt-ai-fg-muted); }
|
||
.status-resolved { background:var(--kt-ai-bg-soft); color:var(--kt-ai-fg); }
|
||
.drawer-overlay { position:fixed; inset:0; background:rgba(0,0,0,0.5); z-index:100; display:none; }
|
||
.drawer-overlay.open { display:block; }
|
||
.drawer { position:fixed; right:0; top:0; bottom:0; width:480px; background:var(--kt-ai-bg); box-shadow:-4px 0 24px rgba(0,0,0,0.15); z-index:101; transform:translateX(100%); transition:transform 0.3s; display:flex; flex-direction:column; }
|
||
.drawer.open { transform:translateX(0); }
|
||
.drawer-header { display:flex; align-items:center; justify-content:space-between; padding:var(--kt-ai-space-4) var(--kt-ai-space-6); border-bottom:1px solid var(--kt-ai-border); }
|
||
.drawer-title { font-size:var(--kt-ai-text-lg); font-weight:var(--kt-ai-weight-semibold); margin:0; }
|
||
.drawer-content { flex:1; overflow:auto; padding:var(--kt-ai-space-6); }
|
||
.drawer-actions { padding:var(--kt-ai-space-4) var(--kt-ai-space-6); border-top:1px solid var(--kt-ai-border); display:flex; gap:var(--kt-ai-space-3); justify-content:flex-end; }
|
||
.field { margin-bottom:var(--kt-ai-space-4); }
|
||
.field label { display:block; font-size:var(--kt-ai-text-sm); font-weight:var(--kt-ai-weight-medium); color:var(--kt-ai-fg); margin-bottom:var(--kt-ai-space-2); }
|
||
.toast-container { position:fixed; bottom:var(--kt-ai-space-6); right:var(--kt-ai-space-6); display:flex; flex-direction:column; gap:var(--kt-ai-space-3); z-index:200; }
|
||
.toast { background:var(--kt-ai-fg); color:var(--kt-ai-bg); padding:var(--kt-ai-space-3) var(--kt-ai-space-4); border-radius:var(--kt-ai-radius-lg); font-size:var(--kt-ai-text-sm); min-width:280px; }
|
||
.search-input { width:100%; padding:var(--kt-ai-space-2) var(--kt-ai-space-3); border:1px solid var(--kt-ai-border); border-radius:var(--kt-ai-radius-md); background:var(--kt-ai-bg); color:var(--kt-ai-fg); font-size:var(--kt-ai-text-sm); }
|
||
.search-input:focus { outline:none; border-color:var(--kt-ai-primary); }
|
||
.empty-state { text-align:center; padding:var(--kt-ai-space-12); color:var(--kt-ai-fg-muted); }
|
||
.icon-btn { background:none; border:none; cursor:pointer; padding:var(--kt-ai-space-1); color:var(--kt-ai-fg-muted); }
|
||
.icon-btn:hover { color:var(--kt-ai-fg); }
|
||
</style>
|
||
</head>
|
||
<body>
|
||
|
||
<div class="app-shell">
|
||
<aside class="sidebar">
|
||
<div class="kt-ai-brand" style="margin-bottom:var(--kt-ai-space-6)">
|
||
<img src="design-system/brand/kt-ai-logo.png" alt="KT AI" height="20">
|
||
<span>Повторные обращения</span>
|
||
</div>
|
||
<nav>
|
||
<div class="kt-ai-nav-group">
|
||
<a class="kt-ai-nav-item is-active" href="#" data-filter="all">Все обращения</a>
|
||
<a class="kt-ai-nav-item" href="#" data-filter="new">Новые</a>
|
||
<a class="kt-ai-nav-item" href="#" data-filter="duplicate">Повторные</a>
|
||
<a class="kt-ai-nav-item" href="#" data-filter="resolved">Решённые</a>
|
||
</div>
|
||
</nav>
|
||
<div style="margin-top:auto">
|
||
<button class="kt-ai-btn" data-variant="primary" style="width:100%" id="newAppealBtn">
|
||
<svg class="kt-icon kt-icon-sm" aria-hidden="true"><use href="#plus"></use></svg>
|
||
Новое обращение
|
||
</button>
|
||
</div>
|
||
</aside>
|
||
|
||
<main class="main-content">
|
||
<header class="topbar">
|
||
<h1 class="topbar-title">Реестр обращений</h1>
|
||
<div style="flex:1; max-width:500px">
|
||
<input class="search-input" type="search" placeholder="Поиск по тексту, автору, дате…" id="searchInput">
|
||
</div>
|
||
<button class="kt-ai-btn" data-variant="ghost" id="themeToggle">
|
||
<svg class="kt-icon" aria-hidden="true"><use href="#sun"></use></svg>
|
||
</button>
|
||
</header>
|
||
|
||
<div class="kpi-strip">
|
||
<div class="kpi">
|
||
<div class="kpi-value" id="kpiTotal">0</div>
|
||
<div class="kpi-label">Всего обращений</div>
|
||
</div>
|
||
<div class="kpi">
|
||
<div class="kpi-value" id="kpiNew">0</div>
|
||
<div class="kpi-label">Новых</div>
|
||
</div>
|
||
<div class="kpi">
|
||
<div class="kpi-value" id="kpiDuplicate">0</div>
|
||
<div class="kpi-label">Повторных</div>
|
||
</div>
|
||
<div class="kpi">
|
||
<div class="kpi-value" id="kpiResolved">0</div>
|
||
<div class="kpi-label">Решённых</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="toolbar">
|
||
<div class="kt-ai-segmented">
|
||
<button class="kt-ai-segmented-item is-active" data-sort="date">По дате</button>
|
||
<button class="kt-ai-segmented-item" data-sort="author">По автору</button>
|
||
</div>
|
||
<select class="kt-ai-select" id="statusFilter">
|
||
<option value="">Все статусы</option>
|
||
<option value="new">Новое</option>
|
||
<option value="duplicate">Повторное</option>
|
||
<option value="resolved">Решено</option>
|
||
</select>
|
||
</div>
|
||
|
||
<div class="table-wrap">
|
||
<table class="appeals-table">
|
||
<thead>
|
||
<tr>
|
||
<th>Дата</th>
|
||
<th>Автор</th>
|
||
<th>Текст обращения</th>
|
||
<th>Статус</th>
|
||
<th>Действия</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody id="appealsTable"></tbody>
|
||
</table>
|
||
<div class="empty-state" id="emptyState" hidden>
|
||
<svg class="kt-icon kt-icon-lg" aria-hidden="true" style="margin-bottom:var(--kt-ai-space-4)"><use href="#inbox"></use></svg>
|
||
<p>Обращений пока нет</p>
|
||
<button class="kt-ai-btn" data-variant="primary" id="emptyNewBtn" style="margin-top:var(--kt-ai-space-4)">Добавить первое обращение</button>
|
||
</div>
|
||
</div>
|
||
</main>
|
||
</div>
|
||
|
||
<div class="drawer-overlay" id="drawerOverlay"></div>
|
||
<aside class="drawer" id="appealDrawer">
|
||
<header class="drawer-header">
|
||
<h2 class="drawer-title" id="drawerTitle">Новое обращение</h2>
|
||
<button class="kt-ai-btn" data-variant="ghost" id="closeDrawer">
|
||
<svg class="kt-icon" aria-hidden="true"><use href="#x"></use></svg>
|
||
</button>
|
||
</header>
|
||
<div class="drawer-content">
|
||
<form id="appealForm">
|
||
<input type="hidden" id="appealId">
|
||
<div class="field">
|
||
<label>Автор обращения</label>
|
||
<input class="kt-ai-input" id="authorInput" required placeholder="ФИО или название организации">
|
||
</div>
|
||
<div class="field">
|
||
<label>Контакты</label>
|
||
<input class="kt-ai-input" id="contactInput" placeholder="Телефон, email">
|
||
</div>
|
||
<div class="field">
|
||
<label>Текст обращения</label>
|
||
<textarea class="kt-ai-textarea" id="textInput" required rows="5" placeholder="Опишите суть обращения"></textarea>
|
||
</div>
|
||
<div class="field">
|
||
<label>Категория</label>
|
||
<select class="kt-ai-select" id="categoryInput">
|
||
<option value="">Не выбрано</option>
|
||
<option value="technical">Технический вопрос</option>
|
||
<option value="billing">Биллинг и оплата</option>
|
||
<option value="service">Качество услуги</option>
|
||
<option value="other">Другое</option>
|
||
</select>
|
||
</div>
|
||
<div class="field">
|
||
<label>Комментарий</label>
|
||
<textarea class="kt-ai-textarea" id="commentInput" rows="3" placeholder="Внутренний комментарий"></textarea>
|
||
</div>
|
||
</form>
|
||
</div>
|
||
<div class="drawer-actions">
|
||
<button class="kt-ai-btn" data-variant="ghost" id="cancelBtn">Отмена</button>
|
||
<button class="kt-ai-btn" data-variant="primary" id="saveBtn">Сохранить</button>
|
||
</div>
|
||
</aside>
|
||
|
||
<div class="toast-container" id="toastContainer"></div>
|
||
|
||
<script src="design-system/icons/kt-ai-icons.js"></script>
|
||
<script src="script.js"></script>
|
||
</body>
|
||
</html>
|