diff --git a/app.db b/app.db index 43601a0..1e356fb 100644 Binary files a/app.db and b/app.db differ diff --git a/app.py b/app.py index eb8f2a0..7346dc4 100644 --- a/app.py +++ b/app.py @@ -324,7 +324,7 @@ def api_birthdate(): match request.method: case "POST": reqData = request.json - userUpdate = reqData["userUpdate"] + userUpdate = reqData.get("userUpdate", None) if userUpdate: logger.info("Обновлен пользователь") userId = userUpdate["userId"] @@ -338,7 +338,7 @@ def api_birthdate(): except Exception as e: logger.error(f"Ошибка при обновлении пользователя: {e}") return jsonify({"status": "error"}), 500 - scheduleSettings = reqData["scheduleSettings"] + scheduleSettings = reqData.get("scheduleSettings") if scheduleSettings: logger.info("Обновлены настройки расписания") try: @@ -554,13 +554,13 @@ def login(): protection = Protection.query.first() if not protection: protection = Protection() - protection.set_password(password) + protection.set_password(new_password) protection.generate_token() db.session.add(protection) db.session.commit() else: - protection.set_password(password) + protection.set_password(new_password) db.session.commit() return {"status": "ok"} @@ -595,5 +595,4 @@ def check_auth_cookie(): if __name__ == "__main__": init_app() - app.run(debug=True, host="0.0.0.0", port=80) - # app.run(host="0.0.0.0", port=80) + app.run(host="0.0.0.0", port=80) diff --git a/static/css/birthdate.css b/static/css/birthdate.css index eed018f..fa74d4f 100644 --- a/static/css/birthdate.css +++ b/static/css/birthdate.css @@ -27,7 +27,7 @@ /* Таблица сотрудников */ .table-responsive { - max-height: 800px; + max-height: 950px; overflow-y: auto; } @@ -77,22 +77,22 @@ } .status-enabled { - background-color: rgba(25, 135, 84, 0.1); + background-color: rgba(25, 135, 84, 0.5); color: #198754; } .status-disabled { - background-color: rgba(108, 117, 125, 0.1); + background-color: rgba(108, 117, 125, 0.2); color: #6c757d; } .status-data { - background-color: rgba(13, 110, 253, 0.1); + background-color: rgba(13, 110, 253, 0.5); color: #0d6efd; } .status-nodata { - background-color: rgba(220, 53, 69, 0.1); + background-color: rgba(220, 53, 69, 0.5); color: #dc3545; } diff --git a/static/js/birthdate.js b/static/js/birthdate.js index 3925f19..b8ec434 100644 --- a/static/js/birthdate.js +++ b/static/js/birthdate.js @@ -7,6 +7,8 @@ let schedulerFormChanged = false; let originalUserData = null; let originalSchedulerData = null; let pendingUserSwitch = null; +const monthNames = ['января', 'февраля', 'марта', 'апреля', 'мая', 'июня', 'июля', 'августа', 'сентября', 'октября', 'ноября', 'декабря']; + // Инициализация при загрузке страницы document.addEventListener('DOMContentLoaded', function () { @@ -18,6 +20,7 @@ document.addEventListener('DOMContentLoaded', function () { // Устанавливаем обработчики событий setupEventListeners(); + }); // Загрузка списка сотрудников @@ -28,6 +31,8 @@ async function loadUsersList() { if (data.status === 'ok') { usersData = data.users; + // Определение ближайшего дня рождения + findNearestBirthday(); renderUsersTable(); } else { showAlert('danger', 'Ошибка загрузки списка сотрудников'); @@ -39,6 +44,53 @@ async function loadUsersList() { } } +function findNearestBirthday() { + const today = new Date(); + today.setHours(0, 0, 0, 0); + + let nextBirthday = null; + let nextBirthdayUserData = null; + + for (const user of usersData) { + if (!user.enabled || !user.birthdate) continue; + + const birthdate = new Date(user.birthdate); + + // День рождения в текущем году + let candidate = new Date( + today.getFullYear(), + birthdate.getMonth(), + birthdate.getDate() + ); + + // Если уже прошёл — переносим на следующий год + if (candidate < today) { + candidate.setFullYear(today.getFullYear() + 1); + } + + if (!nextBirthday || candidate < nextBirthday) { + nextBirthday = candidate; + + const age = candidate.getFullYear() - birthdate.getFullYear(); + + nextBirthdayUserData = { + date: new Intl.DateTimeFormat('ru-RU', { month: 'long', day: 'numeric' }) + .format(new Date(user.birthdate)), + name: user.name, + age + }; + } + } + + const nextBirthdayElement = document.getElementById('nextBirthday'); + if (nextBirthdayUserData) { + nextBirthdayElement.textContent = `${nextBirthdayUserData.date} ${nextBirthdayUserData.name} исполнится ${nextBirthdayUserData.age} лет 🎉`; + } + + return nextBirthdayUserData; +} + + // Отображение таблицы сотрудников function renderUsersTable() { const tbody = document.getElementById('usersTableBody'); @@ -81,14 +133,11 @@ function renderUsersTable() { const birthdate = new Date(user.birthdate); const now = new Date(); const age = now.getFullYear() - birthdate.getFullYear(); - const month = birthdate.getMonth() + 1; - const day = birthdate.getDate(); const fullDate = birthdate.toLocaleDateString('ru-RU'); // Форматируем месяц и день (двузначные) - const monthNames = ['января', 'февраля', 'марта', 'апреля', 'мая', 'июня', 'июля', 'августа', 'сентября', 'октября', 'ноября', 'декабря']; - const monthStr = monthNames[month - 1]; - const dayStr = day.toString().padStart(2, '0'); + const dateText = new Intl.DateTimeFormat('ru-RU', { month: 'long', day: 'numeric' }) + .format(new Date(user.birthdate)); // Определяем пол const sexBadge = user.sex === 'male' ? @@ -121,7 +170,7 @@ function renderUsersTable() {
{{ data.schedulerStatus.next_run_time }}
+
Ссылка на публикацию в VK
+Создание и планирование публикаций в VK