ty-produktovyy-dizayner-i-se/index.html

534 lines
16 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="ru" data-theme="light">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>HR Candidate Matcher</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="icon" href="design-system/brand/kt-ai-logo.png">
<style>
a.kt-ai-btn { text-decoration: none; }
:root {
--hm-bg: var(--kt-ai-bg);
--hm-surface: var(--kt-ai-card-bg);
--hm-fg: var(--kt-ai-fg);
--hm-fg-muted: var(--kt-ai-fg-muted);
--hm-accent: var(--kt-ai-primary);
--hm-border: var(--kt-ai-border);
--hm-success: var(--kt-ai-primary);
--hm-warning: var(--kt-ai-fg-muted);
--hm-error: var(--kt-ai-danger);
}
.hm-container {
max-width: 1200px;
margin: 0 auto;
padding: var(--kt-ai-space-8);
}
.hm-header {
display: flex;
align-items: center;
gap: var(--kt-ai-space-4);
margin-bottom: var(--kt-ai-space-8);
padding: var(--kt-ai-space-4) 0;
border-bottom: 1px solid var(--kt-ai-border);
}
.hm-title {
font-size: var(--kt-ai-text-xl);
font-weight: var(--kt-ai-weight-semibold);
}
.hm-nav {
display: flex;
gap: var(--kt-ai-space-2);
margin-left: auto;
}
.hm-nav-btn {
padding: var(--kt-ai-space-2) var(--kt-ai-space-3);
border-radius: var(--kt-ai-radius-md);
background: transparent;
border: 1px solid transparent;
color: var(--kt-ai-fg-muted);
cursor: pointer;
font-size: var(--kt-ai-text-sm);
transition: all 0.15s ease;
}
.hm-nav-btn:hover {
background: var(--kt-ai-card-bg);
color: var(--kt-ai-fg);
}
.hm-nav-btn.active {
background: var(--kt-ai-primary);
color: white;
}
.hm-screen {
display: none;
}
.hm-screen.active {
display: block;
}
.hm-card {
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-6);
margin-bottom: var(--kt-ai-space-6);
}
.hm-grid-2 {
display: grid;
grid-template-columns: 1fr 1fr;
gap: var(--kt-ai-space-6);
}
.hm-label {
display: block;
font-size: var(--kt-ai-text-sm);
font-weight: var(--kt-ai-weight-medium);
margin-bottom: var(--kt-ai-space-2);
}
.hm-textarea {
width: 100%;
min-height: 280px;
padding: var(--kt-ai-space-3);
border: 1px solid var(--kt-ai-border);
border-radius: var(--kt-ai-radius-md);
font-family: var(--kt-ai-font-mono);
font-size: var(--kt-ai-text-sm);
line-height: 1.6;
resize: vertical;
background: var(--kt-ai-bg-soft);
color: var(--kt-ai-fg);
}
.hm-textarea:focus {
outline: 2px solid var(--kt-ai-primary);
border-color: transparent;
}
.hm-hint {
font-size: var(--kt-ai-text-xs);
color: var(--kt-ai-fg-muted);
margin-top: var(--kt-ai-space-2);
display: flex;
align-items: center;
gap: var(--kt-ai-space-1);
}
.hm-actions {
display: flex;
gap: var(--kt-ai-space-3);
margin-top: var(--kt-ai-space-6);
}
.hm-criteria-list {
display: flex;
flex-direction: column;
gap: var(--kt-ai-space-3);
}
.hm-criterion {
display: grid;
grid-template-columns: 2fr 1fr 80px 40px;
gap: var(--kt-ai-space-3);
align-items: center;
padding: var(--kt-ai-space-3);
background: var(--kt-ai-bg-soft);
border-radius: var(--kt-ai-radius-md);
border: 1px solid var(--kt-ai-border);
}
.hm-criterion input[type="text"],
.hm-criterion select,
.hm-criterion input[type="number"] {
width: 100%;
padding: var(--kt-ai-space-2);
border: 1px solid var(--kt-ai-border);
border-radius: var(--kt-ai-radius-md);
background: var(--kt-ai-card-bg);
color: var(--kt-ai-fg);
font-size: var(--kt-ai-text-sm);
}
.hm-criterion input[type="number"] {
text-align: center;
}
.hm-criterion button {
width: 32px;
height: 32px;
border: none;
background: transparent;
color: var(--kt-ai-fg-muted);
cursor: pointer;
border-radius: var(--kt-ai-radius-md);
display: flex;
align-items: center;
justify-content: center;
}
.hm-criterion button:hover {
background: var(--kt-ai-danger);
color: white;
}
.hm-synonyms {
grid-column: 1 / -1;
display: flex;
gap: var(--kt-ai-space-2);
align-items: center;
}
.hm-synonyms input {
flex: 1;
padding: var(--kt-ai-space-2);
border: 1px dashed var(--kt-ai-border);
border-radius: var(--kt-ai-radius-md);
background: var(--kt-ai-card-bg);
color: var(--kt-ai-fg);
font-size: var(--kt-ai-text-xs);
}
.hm-table-wrapper {
overflow-x: auto;
border: 1px solid var(--kt-ai-border);
border-radius: var(--kt-ai-radius-xl);
background: var(--kt-ai-card-bg);
}
.hm-table {
width: 100%;
border-collapse: collapse;
font-size: var(--kt-ai-text-sm);
}
.hm-table th {
text-align: left;
padding: var(--kt-ai-space-3) var(--kt-ai-space-4);
background: var(--kt-ai-bg-soft);
border-bottom: 2px solid var(--kt-ai-border);
font-weight: var(--kt-ai-weight-semibold);
white-space: nowrap;
}
.hm-table td {
padding: var(--kt-ai-space-3) var(--kt-ai-space-4);
border-bottom: 1px solid var(--kt-ai-border);
vertical-align: top;
}
.hm-table tr:last-child td {
border-bottom: none;
}
.hm-quote {
font-family: var(--kt-ai-font-mono);
font-size: var(--kt-ai-text-xs);
background: var(--kt-ai-bg-soft);
padding: var(--kt-ai-space-2);
border-radius: var(--kt-ai-radius-md);
border-left: 3px solid var(--kt-ai-primary);
max-width: 400px;
white-space: pre-wrap;
word-break: break-word;
}
.hm-status {
display: inline-flex;
align-items: center;
gap: var(--kt-ai-space-1);
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);
white-space: nowrap;
}
.hm-status-confirmed {
background: var(--kt-ai-bg-soft);
color: var(--kt-ai-primary);
}
.hm-status-clarify {
background: var(--kt-ai-bg-soft);
color: var(--kt-ai-fg-muted);
}
.hm-status-notfound {
background: var(--kt-ai-bg-soft);
color: var(--kt-ai-fg-muted);
}
.hm-coverage-bar {
height: 8px;
background: var(--kt-ai-border);
border-radius: var(--kt-ai-radius-full);
overflow: hidden;
margin-top: var(--kt-ai-space-4);
}
.hm-coverage-fill {
height: 100%;
background: var(--kt-ai-primary);
transition: width 0.3s ease;
}
.hm-coverage-text {
text-align: center;
font-size: var(--kt-ai-text-sm);
color: var(--kt-ai-fg-muted);
margin-top: var(--kt-ai-space-2);
}
.hm-questions-list {
display: flex;
flex-direction: column;
gap: var(--kt-ai-space-4);
}
.hm-question-card {
background: var(--kt-ai-bg-soft);
border: 1px solid var(--kt-ai-border);
border-radius: var(--kt-ai-radius-md);
padding: var(--kt-ai-space-4);
}
.hm-question-criterion {
font-size: var(--kt-ai-text-sm);
font-weight: var(--kt-ai-weight-semibold);
margin-bottom: var(--kt-ai-space-2);
}
.hm-question-text {
font-size: var(--kt-ai-text-sm);
color: var(--kt-ai-fg-muted);
line-height: 1.6;
}
.hm-copy-area {
background: var(--kt-ai-card-bg);
border: 1px solid var(--kt-ai-border);
border-radius: var(--kt-ai-radius-md);
padding: var(--kt-ai-space-4);
font-family: var(--kt-ai-font-mono);
font-size: var(--kt-ai-text-sm);
white-space: pre-wrap;
max-height: 300px;
overflow-y: auto;
margin-top: var(--kt-ai-space-4);
}
.hm-empty {
text-align: center;
padding: var(--kt-ai-space-12) var(--kt-ai-space-6);
color: var(--kt-ai-fg-muted);
}
.hm-empty-icon {
width: 64px;
height: 64px;
margin: 0 auto var(--kt-ai-space-4);
color: var(--kt-ai-border);
}
.hm-brand img {
height: 20px;
}
@media (max-width: 768px) {
.hm-grid-2 {
grid-template-columns: 1fr;
}
.hm-criterion {
grid-template-columns: 1fr;
gap: var(--kt-ai-space-2);
}
.hm-header {
flex-wrap: wrap;
}
.hm-nav {
margin-left: 0;
width: 100%;
overflow-x: auto;
}
.hm-container {
padding: var(--kt-ai-space-4);
}
}
</style>
</head>
<body>
<div class="hm-container">
<header class="hm-header">
<a class="kt-ai-brand" href="#">
<img src="design-system/brand/kazakhtelecom-logo.png" alt="Казахтелеком" height="20">
</a>
<span class="hm-title">HR Candidate Matcher</span>
<nav class="hm-nav" id="hmNav">
<button class="hm-nav-btn" data-screen="input">Ввод</button>
<button class="hm-nav-btn" data-screen="criteria">Критерии</button>
<button class="hm-nav-btn" data-screen="match">Сопоставление</button>
<button class="hm-nav-btn" data-screen="interview">Интервью</button>
</nav>
</header>
<main>
<!-- ЭКРАН ВВОДА -->
<section id="screen-input" class="hm-screen active">
<div class="hm-card">
<h1 style="margin-bottom: var(--kt-ai-space-2)">Сопоставление резюме и вакансии</h1>
<p style="color: var(--kt-ai-fg-muted); margin-bottom: var(--kt-ai-space-6)">
Вставьте текст вакансии и резюме — система извлечёт требования и покажет степень соответствия.
</p>
<div class="hm-grid-2">
<div>
<label class="hm-label" for="vacancyText">Текст вакансии</label>
<textarea id="vacancyText" class="hm-textarea" placeholder="Требования, обязанности, условия..."></textarea>
</div>
<div>
<label class="hm-label" for="resumeText">Текст резюме (обезличенное)</label>
<textarea id="resumeText" class="hm-textarea" placeholder="Опыт, навыки, образование..."></textarea>
<div class="hm-hint">
<svg class="kt-icon kt-icon-sm" aria-hidden="true"><use href="#lock"></use></svg>
Данные не покидают браузер и не сохраняются без вашего согласия
</div>
</div>
</div>
<div class="hm-actions">
<button class="kt-ai-btn" data-variant="primary" id="btnExtract">
<svg class="kt-icon kt-icon-sm" style="margin-right: var(--kt-ai-space-2)"><use href="#sparkles"></use></svg>
Извлечь требования
</button>
<button class="kt-ai-btn" id="btnLoadExample">Попробовать пример</button>
<button class="kt-ai-btn" data-variant="ghost" id="btnClearAll" style="margin-left: auto">
<svg class="kt-icon kt-icon-sm" style="margin-right: var(--kt-ai-space-2)"><use href="#trash"></use></svg>
Очистить всё
</button>
</div>
</div>
</section>
<!-- ЭКРАН КРИТЕРИЕВ -->
<section id="screen-criteria" class="hm-screen">
<div class="hm-card">
<h1 style="margin-bottom: var(--kt-ai-space-2)">Критерии оценки</h1>
<p style="color: var(--kt-ai-fg-muted); margin-bottom: var(--kt-ai-space-6)">
Отредактируйте требования: укажите обязательность, вес (1–5) и синонимы для поиска.
</p>
<div id="criteriaList" class="hm-criteria-list"></div>
<div class="hm-actions">
<button class="kt-ai-btn" id="btnAddCriterion">
<svg class="kt-icon kt-icon-sm" style="margin-right: var(--kt-ai-space-2)"><use href="#plus"></use></svg>
Добавить критерий
</button>
<button class="kt-ai-btn" data-variant="primary" id="btnApplyCriteria" style="margin-left: auto">
Применить и перейти к сопоставлению
</button>
</div>
</div>
</section>
<!-- ЭКРАН СОПОСТАВЛЕНИЯ -->
<section id="screen-match" class="hm-screen">
<div class="hm-card">
<h1 style="margin-bottom: var(--kt-ai-space-2)">Сопоставление требований</h1>
<p style="color: var(--kt-ai-fg-muted); margin-bottom: var(--kt-ai-space-6)">
Система нашла соответствия в резюме для каждого требования.
</p>
<div id="matchResults">
<div class="hm-table-wrapper">
<table class="hm-table">
<thead>
<tr>
<th style="width: 25%">Требование</th>
<th style="width: 15%">Тип</th>
<th style="width: 15%">Вес</th>
<th style="width: 30%">Найдено в резюме</th>
<th style="width: 15%">Статус</th>
</tr>
</thead>
<tbody id="matchTableBody"></tbody>
</table>
</div>
<div class="hm-coverage-bar">
<div class="hm-coverage-fill" id="coverageFill" style="width: 0%"></div>
</div>
<div class="hm-coverage-text" id="coverageText">Покрытие требований: 0%</div>
</div>
<div id="matchEmpty" class="hm-empty" style="display: none">
<svg class="hm-empty-icon" aria-hidden="true"><use href="#search"></use></svg>
<h3>Ничего не найдено</h3>
<p>Попробуйте изменить критерии или добавить синонимы</p>
</div>
<div class="hm-actions">
<button class="kt-ai-btn" id="btnBackToCriteria">Назад к критериям</button>
<button class="kt-ai-btn" data-variant="primary" id="btnGenerateQuestions" style="margin-left: auto">
<svg class="kt-icon kt-icon-sm" style="margin-right: var(--kt-ai-space-2)"><use href="#sparkles"></use></svg>
Сгенерировать вопросы
</button>
</div>
</div>
</section>
<!-- ЭКРАН ИНТЕРВЬЮ -->
<section id="screen-interview" class="hm-screen">
<div class="hm-card">
<h1 style="margin-bottom: var(--kt-ai-space-2)">Вопросы для интервью</h1>
<p style="color: var(--kt-ai-fg-muted); margin-bottom: var(--kt-ai-space-6)">
Вопросы по требованиям, которые требуют уточнения на собеседовании.
</p>
<div id="questionsList" class="hm-questions-list"></div>
<div class="hm-actions">
<button class="kt-ai-btn" id="btnBackToMatch">Назад к сопоставлению</button>
<button class="kt-ai-btn" id="btnCopyQuestions">
<svg class="kt-icon kt-icon-sm" style="margin-right: var(--kt-ai-space-2)"><use href="#copy"></use></svg>
Копировать вопросы
</button>
<button class="kt-ai-btn" data-variant="primary" id="btnExport" style="margin-left: auto">
<svg class="kt-icon kt-icon-sm" style="margin-right: var(--kt-ai-space-2)"><use href="#download"></use></svg>
Экспорт сводки
</button>
</div>
</div>
</section>
</main>
</div>
<script src="design-system/icons/kt-ai-icons.js"></script>
<script src="aiAdapter.js"></script>
<script src="storage.js"></script>
<script src="matcher.js"></script>
<script src="ui.js"></script>
<script src="app.js"></script>
</body>
</html>