This commit is contained in:
2025-12-23 01:12:10 +03:00
parent 69706d0cb7
commit 6ec4bd00e2
22 changed files with 1923 additions and 175 deletions
+267
View File
@@ -0,0 +1,267 @@
{% extends "base.html" %}
{% block title %}Дни рождения{% endblock %}
{% block styles %}
<link href="/static/css/birthdate.css" rel="stylesheet">
{% endblock %}
{% block content %}
<!-- Заголовок -->
<div class="d-flex justify-content-between align-items-center mb-4">
<div>
<h2 class="mb-1"><i class="bi bi-balloon-heart-fill text-pink me-2"></i>Дни рождения</h2>
<p class="text-muted mb-0">Управление поздравлениями сотрудников</p>
</div>
<div class="badge bg-pink fs-6 px-3 py-2">
<i class="bi bi-calendar-heart me-1"></i>Поздравления
</div>
</div>
<!-- Основной контент -->
<div class="row g-4 mb-3">
<!-- Левая колонка: Список сотрудников -->
<div class="col-lg-7">
<div class="card h-100">
<div class="card-header d-flex justify-content-between align-items-center">
<h5 class="mb-0"><i class="bi bi-people-fill me-2"></i>Сотрудники</h5>
<button type="button" class="btn btn-sm btn-outline-primary" onclick="refreshUsersList()">
<i class="bi bi-arrow-clockwise me-1"></i>Обновить список
</button>
</div>
<div class="card-body p-0">
<!-- Таблица сотрудников -->
<div class="table-responsive">
<table class="table table-hover mb-0" id="usersTable">
<thead class="table-light">
<tr>
<th width="120">Дата рождения</th>
<th>Имя</th>
<th>Короткое имя</th>
<th>Полная дата<br><small>(возраст)</small></th>
<th>Пол</th>
<th>Специальности</th>
<th width="100" class="text-center">Статус</th>
<th width="80" class="text-center">Данные</th>
</tr>
</thead>
<tbody id="usersTableBody">
<!-- Данные будут загружены через JS -->
<tr>
<td colspan="8" class="text-center py-5">
<div class="spinner-border text-primary" role="status">
<span class="visually-hidden">Загрузка...</span>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="card-footer">
<div class="row g-2">
<div class="col-md-6">
<button type="button" class="btn btn-sm btn-outline-success w-100" onclick="enableAllUsers()">
<i class="bi bi-check-circle me-1"></i>Включить всех
</button>
</div>
<div class="col-md-6">
<button type="button" class="btn btn-sm btn-outline-secondary w-100"
onclick="disableAllUsers()">
<i class="bi bi-x-circle me-1"></i>Отключить всех
</button>
</div>
</div>
</div>
</div>
</div>
<!-- Правая колонка: Данные сотрудника и планировщик -->
<div class="col-lg-5">
<!-- Данные выбранного сотрудника -->
<div class="card mb-4">
<div class="card-header">
<h5 class="mb-0">
<i class="bi bi-person-badge me-2"></i>
<span id="selectedUserName">Выберите сотрудника</span>
</h5>
</div>
<div class="card-body">
<form id="userForm">
<input type="hidden" id="userId">
<!-- Переключатель enabled -->
<div class="mb-4">
<div class="form-check form-switch d-flex align-items-center gap-2 p-0">
<input class="form-check-input m-0" type="checkbox" role="switch" id="user_enabled"
onchange="markUserChanged()">
<label class="form-check-label fw-semibold mb-0" for="user_enabled">
Включить поздравление для этого сотрудника
</label>
</div>
</div>
<!-- Ссылка на фото -->
<div class="mb-4">
<label class="form-label fw-semibold">
<i class="bi bi-image me-2"></i>Ссылка на фото для поздравления
</label>
<input type="url" class="form-control" id="photo_link"
placeholder="https://vk.com/groupname?z=photo-27937673_457248154"
oninput="markUserChanged()">
<div class="form-text">
Ссылка на изображение для поздравления. Должна быть доступна для всех. Лишние символы в
ссылке будут удалены автоматически.
</div>
</div>
<!-- Текст поздравления -->
<div class="mb-4">
<label class="form-label fw-semibold">
<i class="bi bi-chat-heart me-2"></i>Текст поздравления
</label>
<textarea class="form-control" id="congratulations" rows="5"
placeholder="Дорогой(ая) [Имя], поздравляем с днем рождения! 🎉"
oninput="markUserChanged()"></textarea>
<div class="form-text">
Не поддерживается никакая разметка. Только текст и эмоджи. Максимум 2000 символов.
</div>
</div>
<!-- Информация о посте -->
<div id="postInfo" style="display: none;">
<div class="alert alert-info">
<h6 class="alert-heading"><i class="bi bi-info-circle me-2"></i>Информация о посте</h6>
<div class="mb-2" id="postLinkContainer">
<!-- Ссылка на пост будет здесь -->
</div>
<div class="small" id="publishTime">
<!-- Время публикации будет здесь -->
</div>
</div>
</div>
<!-- Кнопка сохранения -->
<div class="d-flex gap-2 pt-3 border-top">
<button type="button" class="btn btn-outline-secondary" onclick="resetUserForm()">
<i class="bi bi-x-lg me-1"></i>Отмена
</button>
<button type="button" class="btn btn-primary" id="saveUserButton" onclick="saveUserData()"
disabled>
<i class="bi bi-save me-1"></i>Сохранить данные сотрудника
</button>
</div>
</form>
</div>
</div>
<!-- Настройки планировщика -->
<div class="card">
<div class="card-header d-flex justify-content-between align-items-center">
<h5 class="mb-0"><i class="bi bi-clock me-2"></i>Настройки планировщика</h5>
<span id="schedulerStatus" class="badge">
{% if data.schedulerStatus.scheduler %}
<span class="badge bg-success"><i class="bi bi-play-circle me-1"></i>Активен</span>
{% else %}
<span class="badge bg-secondary"><i class="bi bi-stop-circle me-1"></i>Неактивен</span>
{% endif %}
</span>
</div>
<div class="card-body">
<form id="schedulerForm">
<!-- Время запуска -->
<div class="row g-3 mb-3">
<div class="col-md-6">
<label class="form-label fw-semibold">Час запуска</label>
<input type="number" class="form-control" id="scheduler_hour" min="0" max="23"
placeholder="9"
value="{{ data.schedulerSettings.hour if data.schedulerSettings else 9 }}"
oninput="markSchedulerChanged()">
</div>
<div class="col-md-6">
<label class="form-label fw-semibold">Минута запуска</label>
<input type="number" class="form-control" id="scheduler_minute" min="0" max="59"
placeholder="0"
value="{{ data.schedulerSettings.minute if data.schedulerSettings else 0 }}"
oninput="markSchedulerChanged()">
</div>
</div>
<!-- Включение планировщика -->
<div class="mb-4">
<div class="form-check form-switch d-flex align-items-center gap-2 p-0">
<input class="form-check-input m-0" type="checkbox" role="switch" id="scheduler_enabled" {%
if data.schedulerSettings and data.schedulerSettings.enabled %}checked{% endif %}
onchange="markSchedulerChanged()">
<label class="form-check-label fw-semibold mb-0" for="scheduler_enabled">
Включить автоматическую публикацию
</label>
</div>
<div class="form-text">
Планировщик будет проверять дни рождения и публиковать поздравления ежедневно в
указанное время.
</div>
</div>
<!-- Информация о следующем запуске -->
{% if data.schedulerStatus.next_run_time %}
<div class="alert alert-success">
<div class="d-flex align-items-center">
<i class="bi bi-calendar-event fs-5 me-3"></i>
<div>
<h6 class="alert-heading mb-1">Следующий запуск</h6>
<p class="mb-0">{{ data.schedulerStatus.next_run_time }}</p>
</div>
</div>
</div>
{% endif %}
<!-- Кнопка сохранения -->
<div class="d-flex gap-2 pt-3 border-top">
<button type="button" class="btn btn-outline-secondary" onclick="resetSchedulerForm()">
<i class="bi bi-x-lg me-1"></i>Сбросить
</button>
<button type="button" class="btn btn-warning" id="saveSchedulerButton"
onclick="saveSchedulerSettings()" disabled>
<i class="bi bi-save me-1"></i>Сохранить настройки планировщика
</button>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
<!-- Модальное окно для подтверждения сохранения -->
<div class="modal fade" id="confirmModal" tabindex="-1" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title"><i class="bi bi-exclamation-triangle text-warning me-2"></i>Несохраненные
изменения</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<p>У вас есть несохраненные изменения для сотрудника <span id="modalUserName"
class="fw-semibold"></span>.</p>
<p>Вы хотите сохранить изменения перед переходом к другому сотруднику?</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal" onclick="cancelSwitchUser()">
<i class="bi bi-x-circle me-1"></i>Отмена
</button>
<button type="button" class="btn btn-outline-secondary" data-bs-dismiss="modal"
onclick="discardUserChanges()">
<i class="bi bi-trash me-1"></i>Не сохранять
</button>
<button type="button" class="btn btn-primary" data-bs-dismiss="modal" onclick="saveAndSwitchUser()">
<i class="bi bi-save me-1"></i>Сохранить и перейти
</button>
</div>
</div>
</div>
{% endblock %}
{% block scripts %}
<script src="/static/js/birthdate.js"></script>
{% endblock %}