document.addEventListener('DOMContentLoaded', function() { initTheme(); initNotifications(); }); function initTheme() { const savedTheme = getCookie('theme') || 'light'; document.documentElement.setAttribute('data-bs-theme', savedTheme); const toggle = document.getElementById('theme-toggle'); if (toggle) { toggle.addEventListener('click', function(e) { e.preventDefault(); const current = document.documentElement.getAttribute('data-bs-theme'); const next = current === 'dark' ? 'light' : 'dark'; document.documentElement.setAttribute('data-bs-theme', next); setCookie('theme', next, 365); const icon = this.querySelector('i'); const text = this.querySelector('span'); if (next === 'dark') { icon.className = 'bi bi-sun-fill me-2'; text.textContent = 'Светлая тема'; } else { icon.className = 'bi bi-moon-stars-fill me-2'; text.textContent = 'Тёмная тема'; } }); } } function initNotifications() { loadNotifications(); setInterval(loadNotificationCount, 30000); } function loadNotifications() { const notifList = document.getElementById('notif-list'); if (!notifList) return; fetch('/api/notifications/latest') .then(r => r.json()) .then(data => { if (data.length === 0) { notifList.innerHTML = '
Нет новых уведомлений
'; return; } let html = ''; data.forEach(n => { html += '' + '
' + '
' + getNotifIcon(n.type) + '
' + '
' + '
' + n.message + '
' + '' + getTimeAgo(n.time_ago) + '' + '
'; }); notifList.innerHTML = html; }) .catch(() => { notifList.innerHTML = '
Ошибка загрузки
'; }); } function loadNotificationCount() { fetch('/api/notifications/count') .then(r => r.json()) .then(data => { const badge = document.getElementById('notif-badge-top'); if (data.count > 0) { if (badge) { badge.textContent = data.count; badge.style.display = ''; } } else { if (badge) badge.style.display = 'none'; } }) .catch(() => {}); } function getNotifIcon(type) { const icons = { 'success': '', 'danger': '', 'warning': '', 'info': '', }; return icons[type] || icons.info; } function getTimeAgo(seconds) { if (!seconds) return 'только что'; const mins = Math.floor(seconds / 60); if (mins < 1) return 'только что'; if (mins < 60) return mins + ' мин. назад'; const hours = Math.floor(mins / 60); if (hours < 24) return hours + ' ч. назад'; const days = Math.floor(hours / 24); return days + ' дн. назад'; } function getCookie(name) { const match = document.cookie.match(new RegExp('(^| )' + name + '=([^;]+)')); return match ? decodeURIComponent(match[2]) : null; } function setCookie(name, value, days) { let expires = ''; if (days) { const d = new Date(); d.setTime(d.getTime() + days * 24 * 60 * 60 * 1000); expires = '; expires=' + d.toUTCString(); } document.cookie = name + '=' + encodeURIComponent(value) + expires + '; path=/'; }