Круглый аватар слева от поля имени: миниатюра главного фото через thumbSrc, иначе инициалы. Клик по фото открывает imgModal с полным размером, клик по пустому — карточку профиля для загрузки. Аватар синхронизируется после загрузки, смены и удаления фото.
222 lines
12 KiB
HTML
222 lines
12 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="ru">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||
<title>Ученики — Админ-панель</title>
|
||
<link rel="stylesheet" href="admin.css">
|
||
</head>
|
||
<body data-page="students">
|
||
<div class="layout">
|
||
<div class="sidebar" id="sidebar"></div>
|
||
<div class="main">
|
||
<h2>Ученики</h2>
|
||
<div class="add-row">
|
||
<input type="text" id="newStudent" placeholder="Фамилия Имя" list="studentAddList">
|
||
<datalist id="studentAddList"></datalist>
|
||
<button type="button" id="addStudentBtn">Добавить</button>
|
||
<button class="btn-ghost" type="button" id="batchAddBtn">Пакетное добавление</button>
|
||
<button class="btn-ghost" type="button" id="batchAttachBtn">Прикрепить к группе</button>
|
||
</div>
|
||
<div style="display:flex;gap:8px;margin-bottom:16px;flex-wrap:wrap">
|
||
<input type="text" id="studentSearch" class="search-input" placeholder="Поиск по имени..." style="flex:1;min-width:200px;max-width:340px;padding:10px 14px;font-size:.9rem">
|
||
<select id="studentGroupFilter" class="search-input" style="padding:10px 14px"><option value="">Все группы</option></select>
|
||
<button class="btn-link" type="button" id="exportStudentsCsvBtn">Экспорт CSV</button>
|
||
<button class="btn-link" type="button" id="exportStudentsUrlsBtn">Экспорт URL</button>
|
||
</div>
|
||
<div class="list" id="studentList"></div>
|
||
<div class="pager" id="pager"></div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="modal-overlay" id="batchModal">
|
||
<div class="edit-modal" style="max-width:480px">
|
||
<h3>Пакетное добавление учеников</h3>
|
||
<form id="batchForm" class="settings-stack" style="gap:12px">
|
||
<div class="settings-row">
|
||
<div class="settings-field" style="flex:1">
|
||
<label>Имена — каждое с новой строки <span style="color:#ef4444">*</span></label>
|
||
<textarea id="batchText" class="settings-input" style="min-height:120px" required placeholder="Иванов Иван Петров Пётр Сидоров Сидор"></textarea>
|
||
</div>
|
||
</div>
|
||
<div class="settings-row">
|
||
<div class="settings-field" style="flex:1">
|
||
<label>Группа (необязательно)</label>
|
||
<select id="batchGroup" class="settings-input"><option value="">— без группы —</option></select>
|
||
</div>
|
||
</div>
|
||
<div class="card-foot" style="justify-content:flex-end;gap:8px">
|
||
<button type="button" class="btn-primary ghost" id="batchCancelBtn">Отмена</button>
|
||
<button type="submit" class="btn-primary">Добавить</button>
|
||
</div>
|
||
</form>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="modal-overlay" id="exportModal">
|
||
<div class="edit-modal" style="max-width:480px">
|
||
<h3>Экспорт отчёта: <span id="exportName" style="color:var(--accent)"></span></h3>
|
||
<form id="exportForm" class="settings-stack" style="gap:12px">
|
||
<div class="settings-row">
|
||
<div class="settings-field" style="flex:1">
|
||
<label>Период (необязательно)</label>
|
||
<div style="display:flex;gap:8px;flex-wrap:wrap">
|
||
<input type="date" id="exportDateFrom" class="settings-input" style="min-width:0;flex:1">
|
||
<input type="date" id="exportDateTo" class="settings-input" style="min-width:0;flex:1">
|
||
</div>
|
||
<span class="hint">Ограничить записи/фото/файлы датами</span>
|
||
</div>
|
||
</div>
|
||
<div class="settings-field full">
|
||
<label style="display:flex;align-items:center;gap:8px;cursor:pointer">
|
||
<input type="checkbox" id="expEntries" checked>
|
||
Записи занятий (текст)
|
||
</label>
|
||
</div>
|
||
<div class="settings-field full">
|
||
<label style="display:flex;align-items:center;gap:8px;cursor:pointer">
|
||
<input type="checkbox" id="expPhotos" checked>
|
||
Фотографии
|
||
</label>
|
||
</div>
|
||
<div class="settings-field full">
|
||
<label style="display:flex;align-items:center;gap:8px;cursor:pointer">
|
||
<input type="checkbox" id="expCaptions" checked>
|
||
Подписи к фотографиям
|
||
</label>
|
||
</div>
|
||
<div class="settings-field full">
|
||
<label style="display:flex;align-items:center;gap:8px;cursor:pointer">
|
||
<input type="checkbox" id="expFiles" checked>
|
||
Файлы
|
||
</label>
|
||
</div>
|
||
<div class="settings-field full">
|
||
<label style="display:flex;align-items:center;gap:8px;cursor:pointer">
|
||
<input type="checkbox" id="expDates" checked>
|
||
Показывать даты
|
||
</label>
|
||
</div>
|
||
<div class="card-foot" style="justify-content:flex-end;gap:8px">
|
||
<button type="button" class="btn-primary ghost" id="exportCancelBtn">Отмена</button>
|
||
<button type="submit" class="btn-primary">Скачать ZIP</button>
|
||
</div>
|
||
</form>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="modal-overlay" id="attachModal">
|
||
<div class="edit-modal" style="max-width:480px">
|
||
<h3>Прикрепить к группе</h3>
|
||
<form id="attachForm" class="settings-stack" style="gap:12px">
|
||
<div class="settings-row">
|
||
<div class="settings-field" style="flex:1">
|
||
<label>Группа <span style="color:#ef4444">*</span></label>
|
||
<select id="attachGroup" class="settings-input" required><option value="">— выберите группу —</option></select>
|
||
</div>
|
||
</div>
|
||
<div class="settings-row">
|
||
<div class="settings-field" style="flex:1">
|
||
<label>Ученики</label>
|
||
<input type="text" id="attachSearch" class="settings-input" placeholder="Поиск по имени..." style="margin-bottom:8px">
|
||
<div class="attach-list" id="attachList"></div>
|
||
</div>
|
||
</div>
|
||
<div class="card-foot" style="justify-content:flex-end;gap:8px">
|
||
<button type="button" class="btn-primary ghost" id="attachCancelBtn">Отмена</button>
|
||
<button type="submit" class="btn-primary">Прикрепить</button>
|
||
</div>
|
||
</form>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="modal-overlay" id="profileDataModal">
|
||
<div class="edit-modal" style="max-width:900px;width:96%;max-height:92dvh;overflow-y:auto">
|
||
<h3>Данные профиля: <span id="profileDataTitle" style="color:var(--accent)"></span></h3>
|
||
<form id="profileDataForm" style="display:grid;grid-template-columns:1fr 1fr;gap:12px 16px">
|
||
<div class="settings-field">
|
||
<label>Роль / направление</label>
|
||
<input type="text" id="pfRole" class="settings-input" placeholder="Например: Ученик направления «Frontend-разработка»">
|
||
</div>
|
||
<div class="settings-field">
|
||
<label>Статус</label>
|
||
<input type="text" id="pfStatus" class="settings-input" placeholder="Активно учится">
|
||
</div>
|
||
<div class="settings-field">
|
||
<label>Примечание к статусу</label>
|
||
<input type="text" id="pfStatusNote" class="settings-input" placeholder="учится с сентября 2022">
|
||
</div>
|
||
<div class="settings-field">
|
||
<label>Город</label>
|
||
<input type="text" id="pfCity" class="settings-input">
|
||
</div>
|
||
<div class="settings-field">
|
||
<label>Наставник</label>
|
||
<input type="text" id="pfMentor" class="settings-input">
|
||
</div>
|
||
<div class="settings-field">
|
||
<label>В академии с</label>
|
||
<input type="text" id="pfJoined" class="settings-input" placeholder="В академии с сентября 2022">
|
||
</div>
|
||
<div class="settings-field" style="grid-column:1/-1">
|
||
<label>О себе</label>
|
||
<textarea id="pfBio" class="settings-input" style="min-height:70px" placeholder="Короткий рассказ ученика о себе"></textarea>
|
||
</div>
|
||
<div class="settings-field">
|
||
<label>Цитата</label>
|
||
<input type="text" id="pfQuote" class="settings-input" placeholder="«Мой принцип: сначала понять, потом написать»">
|
||
</div>
|
||
<div class="settings-field">
|
||
<label>Теги (через запятую)</label>
|
||
<input type="text" id="pfTags" class="settings-input" placeholder="HTML, CSS, JavaScript">
|
||
</div>
|
||
<div class="settings-field">
|
||
<label>Контакты — строка: Иконка | Подпись | Ссылка</label>
|
||
<textarea id="pfContacts" class="settings-input" style="min-height:64px" placeholder="mail | maria@example.com | mailto:maria@example.com send | @nickname | https://t.me/nickname"></textarea>
|
||
<span class="hint">Иконки: mail, send, phone, github, globe, link, at-sign</span>
|
||
</div>
|
||
<div class="settings-field">
|
||
<label>Достижения — по одному в строке</label>
|
||
<textarea id="pfAchievements" class="settings-input" style="min-height:64px"></textarea>
|
||
</div>
|
||
<div class="settings-field">
|
||
<label>Навыки — строка: Группа | Навык | Уровень | %</label>
|
||
<textarea id="pfSkills" class="settings-input" style="min-height:64px" placeholder="Вёрстка | HTML5 · семантика | Изучен | 95"></textarea>
|
||
</div>
|
||
<div class="settings-field">
|
||
<label>Опыт работы — строка: Заголовок | Организация | Период | Дата | Бейдж | Описание | Теги (через запятую)</label>
|
||
<textarea id="pfExperience" class="settings-input" style="min-height:64px" placeholder="Хакатон Digital City | Академия | Март 2024 | 03.2024 | Хакатон | Прототип карты заявок, 2 место | Vue 3, Leaflet"></textarea>
|
||
</div>
|
||
<div class="settings-field">
|
||
<label>Прогресс по модулям — строка: Тема модуля | Прогресс % | Оценка | Преподаватель</label>
|
||
<textarea id="pfEducation" class="settings-input" style="min-height:64px" placeholder="JavaScript: основы языка | 100 | Оценка 4,7 | Игорь Дёмин"></textarea>
|
||
</div>
|
||
<div class="settings-field" style="grid-column:1/-1">
|
||
<label>Фотографии ученика</label>
|
||
<input type="hidden" id="pfPhoto">
|
||
<div class="pf-photos" id="pfPhotos"></div>
|
||
<div style="display:flex;gap:10px;align-items:center;flex-wrap:wrap;margin-top:6px">
|
||
<input type="file" id="pfPhotoFile" accept="image/*" hidden>
|
||
<button type="button" class="btn-primary ghost" id="pfPhotoUploadBtn">Загрузить фото</button>
|
||
<span class="hint">Клик по фото — сделать главным. Можно вставить из буфера обмена (Ctrl+V)</span>
|
||
</div>
|
||
</div>
|
||
<div style="grid-column:1/-1;display:flex;justify-content:flex-end;gap:8px">
|
||
<button type="button" class="btn-primary ghost" id="profileDataCancelBtn">Отмена</button>
|
||
<button type="submit" class="btn-primary">Сохранить</button>
|
||
</div>
|
||
</form>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="modal-overlay" id="imgModal">
|
||
<img id="imgModalSrc" alt="">
|
||
</div>
|
||
|
||
<div class="toast" id="toast"></div>
|
||
<script src="vendor/lucide.min.js"></script>
|
||
<script src="admin.js"></script>
|
||
<script src="vendor/jszip.min.js"></script>
|
||
<script src="js/students.js"></script>
|
||
</body>
|
||
</html> |