Spaces:
Paused
Paused
| 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 = '<div class="text-center py-3" style="color: var(--apple-gray-400); font-size: 13px;">Нет новых уведомлений</div>'; | |
| return; | |
| } | |
| let html = ''; | |
| data.forEach(n => { | |
| html += '<a href="' + n.link + '" class="dropdown-item border-bottom py-2" style="border-color: rgba(0,0,0,0.04) !important;">' + | |
| '<div class="d-flex" style="gap: 8px;">' + | |
| '<div>' + getNotifIcon(n.type) + '</div>' + | |
| '<div>' + | |
| '<div style="font-size: 13px;">' + n.message + '</div>' + | |
| '<small style="color: var(--apple-gray-400);">' + getTimeAgo(n.time_ago) + '</small>' + | |
| '</div></div></a>'; | |
| }); | |
| notifList.innerHTML = html; | |
| }) | |
| .catch(() => { | |
| notifList.innerHTML = '<div class="text-center py-3" style="color: var(--apple-gray-400); font-size: 13px;">Ошибка загрузки</div>'; | |
| }); | |
| } | |
| 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': '<i class="bi bi-check-circle-fill" style="color: var(--apple-green);"></i>', | |
| 'danger': '<i class="bi bi-exclamation-circle-fill" style="color: var(--apple-red);"></i>', | |
| 'warning': '<i class="bi bi-exclamation-triangle-fill" style="color: var(--apple-orange);"></i>', | |
| 'info': '<i class="bi bi-info-circle-fill" style="color: var(--apple-blue);"></i>', | |
| }; | |
| 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=/'; | |
| } | |