This repository has been archived on 2026-11-14. You can view files and clone it, but cannot push or open issues or pull requests.
sultan/index.html
sultan 32378c342c Restrict delete to Абделазиз, move done tasks to archive
- The delete button is now director-only via CSS + JS guard.
- The main tasks table only shows active tasks (not done).
- A collapsible "Архив" section lists completed tasks (employees
  see their own; Абделазиз sees everyone's). Each archived row
  has "↺ Вернуть" and progress access; delete is director-only.
- Department charts are now director-only too.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-25 09:27:54 +05:00

343 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">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta http-equiv="Cache-Control" content="no-store, no-cache, must-revalidate" />
<meta http-equiv="Pragma" content="no-cache" />
<meta http-equiv="Expires" content="0" />
<title>ДВГО — Помощник руководителя</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/flatpickr@4.6.13/dist/flatpickr.min.css">
<link rel="stylesheet" href="styles.css?v=36" />
</head>
<body>
<header class="topbar">
<div class="topbar-left">
<div class="menu-host">
<button id="menuBtn" class="menu-btn" aria-label="Открыть меню" aria-haspopup="true" aria-expanded="false">
<span></span><span></span><span></span>
</button>
<div id="menuPanel" class="menu-panel" role="menu" hidden>
<a href="#/home" class="menu-item" data-view="home" role="menuitem">
<span class="menu-icon">🏠</span>
<span class="menu-text">
<span class="menu-title">Главная</span>
<span class="menu-sub">Время, погода, новости отрасли</span>
</span>
</a>
<a href="#/create" class="menu-item director-only" data-view="create" role="menuitem">
<span class="menu-icon">+</span>
<span class="menu-text">
<span class="menu-title">Создать поручение</span>
<span class="menu-sub">Форма ввода нового поручения</span>
</span>
</a>
<a href="#/analytics" class="menu-item" data-view="analytics" role="menuitem">
<span class="menu-icon">📊</span>
<span class="menu-text">
<span class="menu-title">Аналитика</span>
<span class="menu-sub">Сводка, фильтры, графики</span>
</span>
</a>
</div>
</div>
<a href="#/home" class="brand" id="brandHome" title="На главную">
<img src="icon.jpg" alt="" class="logo" />
<span class="brand-mark">
<span class="brand-mark-primary">GR</span>
<span class="brand-mark-divider" aria-hidden="true"></span>
<span class="brand-mark-secondary">Department</span>
</span>
</a>
</div>
<div class="who">
<div id="userChip" class="user-chip" hidden>
<button id="profileBtn" class="user-chip-main" type="button" title="Профиль">
<span class="user-chip-avatar" id="userChipAvatar">—</span>
<span class="user-chip-text">
<span class="user-chip-name" id="userChipName">—</span>
<span class="user-chip-role" id="userChipRole">—</span>
</span>
</button>
<button id="logoutBtn" class="btn btn-ghost" type="button" title="Выйти">Выйти</button>
</div>
<button id="resetDemo" class="btn btn-ghost" title="Очистить данные и пересоздать демо">↺ Сброс демо</button>
</div>
</header>
<!-- Промежуточные результаты -->
<div id="progressModal" class="modal" hidden>
<div class="modal-backdrop" id="progressBackdrop"></div>
<div class="modal-card modal-wide" role="dialog" aria-modal="true" aria-labelledby="progressTaskTitle">
<button id="progressClose" class="modal-close" type="button" aria-label="Закрыть">×</button>
<h2 id="progressTaskTitle" class="modal-title">—</h2>
<div id="progressTaskMeta" class="progress-task-meta">—</div>
<h3 class="modal-sub">История</h3>
<ul id="progressList" class="progress-list">
<li class="progress-empty">Промежуточных результатов пока нет.</li>
</ul>
<h3 class="modal-sub">Добавить результат</h3>
<form id="progressForm" class="progress-form">
<textarea id="progressInput" rows="3" placeholder="Что сделано? Что осталось? Риски, блокеры..." required></textarea>
<button type="submit" class="btn btn-primary">+ Добавить</button>
</form>
<p id="progressLocked" class="hint" hidden>Только исполнитель или Абделазиз может добавлять записи.</p>
</div>
</div>
<!-- Профиль / смена пароля -->
<div id="profileModal" class="modal" hidden>
<div class="modal-backdrop" id="profileBackdrop"></div>
<div class="modal-card" role="dialog" aria-modal="true" aria-labelledby="profileTitle">
<button id="profileClose" class="modal-close" type="button" aria-label="Закрыть">×</button>
<h2 id="profileTitle" class="modal-title">Личный кабинет</h2>
<div class="profile-head">
<div class="profile-name" id="profileName">—</div>
<div class="profile-role" id="profileRole">—</div>
</div>
<h3 class="modal-sub">Смена пароля</h3>
<form id="profileForm" class="login-form">
<label>Текущий пароль
<input id="pwdCurrent" type="password" autocomplete="current-password" required />
</label>
<label>Новый пароль
<input id="pwdNew" type="password" autocomplete="new-password" minlength="4" required />
</label>
<label>Подтвердите новый
<input id="pwdConfirm" type="password" autocomplete="new-password" minlength="4" required />
</label>
<div id="profileError" class="login-error" hidden></div>
<div id="profileSuccess" class="login-success" hidden>Пароль обновлён.</div>
<button type="submit" class="btn btn-primary">Сохранить</button>
</form>
</div>
</div>
<!-- Логин -->
<div id="loginOverlay" class="login-overlay" hidden>
<div class="login-card">
<div class="login-brand">
<img src="icon.jpg" alt="" class="login-logo" />
<div>
<div class="login-title">GR Department</div>
<div class="login-sub">Помощник руководителя · ДВГО</div>
</div>
</div>
<h1 class="login-h1">Вход</h1>
<form id="loginForm" class="login-form">
<label>Сотрудник
<select id="loginUser" required></select>
</label>
<label id="loginPwdLabel" hidden>Пароль
<input id="loginPwd" type="password" autocomplete="current-password" placeholder="Введите пароль" />
</label>
<div id="loginError" class="login-error" hidden>Неверный пароль.</div>
<button type="submit" class="btn btn-primary">Войти</button>
<p class="login-hint">Если забыли пароль — попросите Абделазиза сбросить через личный кабинет.</p>
</form>
</div>
</div>
<main>
<!-- Главная -->
<div id="view-home" class="view">
<div class="home-grid">
<section class="card home-clock">
<div class="lbl">Сегодня</div>
<div class="clock-date" id="clockDate">—</div>
<div class="clock-time" id="clockTime">—</div>
<div class="clock-tz">Время в Астане · UTC+5</div>
</section>
<section class="card home-weather">
<div class="lbl">Погода · Астана</div>
<div id="weatherBox" class="weather-box">
<div class="weather-loading">Загружаем данные…</div>
</div>
</section>
</div>
<div class="home-row2">
<section class="card home-calendar">
<div class="cal-head">
<h2>Календарь</h2>
<div class="cal-nav">
<button class="cal-btn" id="calPrev" type="button" aria-label="Предыдущий месяц">‹</button>
<span class="cal-title" id="calTitle">—</span>
<button class="cal-btn" id="calNext" type="button" aria-label="Следующий месяц">›</button>
</div>
</div>
<div class="cal-weekdays" aria-hidden="true">
<span>Пн</span><span>Вт</span><span>Ср</span><span>Чт</span><span>Пт</span><span>Сб</span><span>Вс</span>
</div>
<div class="cal-grid" id="calGrid"></div>
<p class="hint cal-hint">Точки — задачи с дедлайнами. Нажмите день, чтобы перейти в аналитику.</p>
</section>
<section class="card home-tasks">
<div class="tasks-head">
<h2>Ближайшие задачи</h2>
<a href="#/analytics" class="tasks-all">Все →</a>
</div>
<ul id="upcomingList" class="upcoming-list">
<li class="upcoming-empty">Загружаем…</li>
</ul>
</section>
</div>
<section class="card">
<div class="news-header">
<h2>Новости отрасли</h2>
<button id="refreshNews" class="btn btn-ghost" title="Обновить">↻ Обновить</button>
</div>
<ul id="newsList" class="news-list">
<li class="news-loading">Загружаем заголовки…</li>
</ul>
<p class="hint" id="newsSource">—</p>
</section>
</div>
<!-- Создать поручение -->
<div id="view-create" class="view" hidden>
<section class="card">
<h2>Новое поручение</h2>
<form id="taskForm" class="grid">
<label>Заголовок<input type="text" name="title" required placeholder="Подготовить позицию по проекту НПА" /></label>
<label>Дедлайн<input type="date" name="deadline" required /></label>
<label>Исполнитель<select name="assignee" required></select></label>
<label>Направление<select name="direction"></select></label>
<label class="full">Описание<textarea name="description" rows="3" placeholder="Краткая суть, контекст, ожидаемый результат"></textarea></label>
<div class="actions full">
<button type="submit" class="btn btn-primary">+ Создать поручение</button>
<span class="hint">Приоритет назначится автоматически. Можно изменить вручную в аналитике.</span>
</div>
</form>
</section>
</div>
<!-- Аналитика -->
<div id="view-analytics" class="view" hidden>
<section class="card director-only">
<h2>Сводка по департаменту</h2>
<div class="kpis">
<div class="kpi"><div class="kpi-num" id="kpiActive">0</div><div class="kpi-lbl">Активных задач</div></div>
<div class="kpi"><div class="kpi-num" id="kpiOverdue">0</div><div class="kpi-lbl">Просрочено</div></div>
<div class="kpi"><div class="kpi-num" id="kpiSoon">0</div><div class="kpi-lbl">Дедлайн ≤ 3 дн</div></div>
<div class="kpi"><div class="kpi-num" id="kpiDone">0</div><div class="kpi-lbl">Выполнено</div></div>
</div>
</section>
<section class="card director-only">
<h2>Загрузка по сотрудникам</h2>
<div class="load" id="loadByAssignee"></div>
<p class="hint">Нажмите на сотрудника, чтобы отфильтровать таблицу.</p>
</section>
<section class="card">
<h2 class="director-only">Все поручения</h2>
<h2 class="employee-only">Мои поручения</h2>
<div class="filters">
<select id="fAssignee" class="director-only"><option value="">Все исполнители</option></select>
<select id="fStatus">
<option value="">Все статусы</option>
<option value="new">Новая</option>
<option value="in_progress">В работе</option>
<option value="overdue">Просрочена</option>
</select>
<select id="fDirection"><option value="">Все направления</option></select>
<select id="fPriority">
<option value="">Все приоритеты</option>
<option value="high">Высокий</option>
<option value="medium">Средний</option>
<option value="low">Низкий</option>
</select>
<button id="clearFilters" class="btn btn-ghost">Сбросить фильтры</button>
</div>
<table id="tasksTable">
<thead>
<tr>
<th>Заголовок</th>
<th>Исполнитель</th>
<th>Направление</th>
<th>Дедлайн</th>
<th>Приоритет</th>
<th>Статус</th>
<th>Действия</th>
</tr>
</thead>
<tbody id="tasksBody"></tbody>
</table>
<p id="emptyHint" class="hint" hidden>Нет поручений по текущим фильтрам.</p>
</section>
<section class="card">
<div class="archive-head">
<h2>Архив <span class="archive-count" id="archiveCount">0</span></h2>
<button id="archiveToggle" class="btn btn-ghost" type="button" aria-expanded="false">Показать</button>
</div>
<div id="archiveBox" hidden>
<table id="archiveTable">
<thead>
<tr>
<th>Заголовок</th>
<th>Исполнитель</th>
<th>Направление</th>
<th>Дедлайн</th>
<th>Завершено</th>
<th>Действия</th>
</tr>
</thead>
<tbody id="archiveBody"></tbody>
</table>
<p id="archiveEmpty" class="hint" hidden>Архив пуст.</p>
</div>
</section>
<section class="card director-only">
<h2>Задачи по сотрудникам (по статусу)</h2>
<div class="chart-wrap"><canvas id="chartStatus"></canvas></div>
</section>
<section class="card director-only">
<h2>Задачи по сотрудникам (по приоритету)</h2>
<div class="chart-wrap"><canvas id="chartPriority"></canvas></div>
</section>
<div class="charts-row director-only">
<section class="card">
<h2>Распределение по дедлайнам</h2>
<div class="chart-wrap small"><canvas id="chartDeadlines"></canvas></div>
</section>
<section class="card">
<h2>Задачи по направлениям</h2>
<div class="chart-wrap small"><canvas id="chartDirections"></canvas></div>
</section>
</div>
<section class="card">
<h2>Поступление задач в ближайшие 14 дней</h2>
<div class="chart-wrap"><canvas id="chartTimeline"></canvas></div>
</section>
</div>
</main>
<div id="toast" class="toast" role="status" aria-live="polite" hidden></div>
<script src="https://cdn.jsdelivr.net/npm/flatpickr@4.6.13/dist/flatpickr.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/flatpickr@4.6.13/dist/l10n/ru.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.1/dist/chart.umd.min.js"></script>
<script src="app.js?v=33"></script>
</body>
</html>