import { useState, useEffect, useCallback } from 'react'; import { Link } from 'react-router-dom'; import { useTranslation } from '../../i18n'; import { getNotifications, markAsRead, markAllAsRead, deleteNotification, deleteAllRead, requestPushPermission, type Notification } from '../../services/notificationService'; const NotificationsPage = () => { const [notifications, setNotifications] = useState([]); const [loading, setLoading] = useState(true); const [filter, setFilter] = useState<'all' | 'unread'>('all'); const [pushEnabled, setPushEnabled] = useState(false); const [pushPermission, setPushPermission] = useState('default'); const { locale } = useTranslation(); const isEn = locale === 'en'; const checkPushPermission = () => { if ('Notification' in window) { const permission = Notification.permission; setPushPermission(permission); setPushEnabled(permission === 'granted'); } }; const loadNotifications = useCallback(async () => { setLoading(true); try { const response = await getNotifications({ page: 1, limit: 50, unreadOnly: filter === 'unread' }); // Проверяем, что response имеет правильную структуру if (response && Array.isArray(response.notifications)) { setNotifications(response.notifications); } else { console.error('Неверный формат ответа от сервера:', response); setNotifications([]); } } catch (error) { console.error('Ошибка загрузки уведомлений:', error); setNotifications([]); } finally { setLoading(false); } }, [filter]); useEffect(() => { loadNotifications(); checkPushPermission(); }, [loadNotifications]); const handleMarkAsRead = async (id: number) => { try { await markAsRead(id); setNotifications((prev) => prev.map((n) => (n.id === id ? { ...n, isRead: true } : n)) ); } catch (error) { console.error('Ошибка пометки прочитанным:', error); } }; const handleMarkAllAsRead = async () => { try { await markAllAsRead(); setNotifications((prev) => prev.map((n) => ({ ...n, isRead: true }))); } catch (error) { console.error('Ошибка пометки всех прочитанными:', error); } }; const handleDelete = async (id: number) => { try { await deleteNotification(id); setNotifications((prev) => prev.filter((n) => n.id !== id)); } catch (error) { console.error('Ошибка удаления уведомления:', error); } }; const handleDeleteAllRead = async () => { if (!window.confirm(isEn ? 'Delete all read notifications?' : 'Удалить все прочитанные уведомления?')) return; try { await deleteAllRead(); setNotifications((prev) => prev.filter((n) => !n.isRead)); } catch (error) { console.error('Ошибка удаления прочитанных:', error); } }; const handleEnablePush = async () => { const success = await requestPushPermission(); if (success) { setPushEnabled(true); setPushPermission('granted'); alert(isEn ? 'Push notifications enabled!' : 'Push-уведомления успешно подключены!'); } else { alert(isEn ? 'Failed to enable push notifications. Check your browser permissions.' : 'Не удалось подключить Push-уведомления. Проверьте разрешения браузера.'); // Обновляем состояние на случай, если пользователь отклонил checkPushPermission(); } }; const formatDate = (dateString: string) => { const date = new Date(dateString); return date.toLocaleString(isEn ? 'en-US' : 'ru-RU', { day: 'numeric', month: 'long', year: 'numeric', hour: '2-digit', minute: '2-digit' }); }; const groupNotificationsByDate = (notifications: Notification[]) => { const now = new Date(); const today = new Date(now.getFullYear(), now.getMonth(), now.getDate()); const yesterday = new Date(today); yesterday.setDate(yesterday.getDate() - 1); const weekAgo = new Date(today); weekAgo.setDate(weekAgo.getDate() - 7); const todayLabel = isEn ? 'Today' : 'Сегодня'; const yesterdayLabel = isEn ? 'Yesterday' : 'Вчера'; const weekLabel = isEn ? 'Last 7 days' : 'За последние 7 дней'; const earlierLabel = isEn ? 'Earlier' : 'Ранее'; const groups: Record = { [todayLabel]: [], [yesterdayLabel]: [], [weekLabel]: [], [earlierLabel]: [] }; notifications.forEach((notification) => { const notifDate = new Date(notification.createdAt); const notifDay = new Date(notifDate.getFullYear(), notifDate.getMonth(), notifDate.getDate()); if (notifDay.getTime() === today.getTime()) { groups[todayLabel].push(notification); } else if (notifDay.getTime() === yesterday.getTime()) { groups[yesterdayLabel].push(notification); } else if (notifDate >= weekAgo) { groups[weekLabel].push(notification); } else { groups[earlierLabel].push(notification); } }); return groups; }; const unreadCount = notifications.filter((n) => !n.isRead).length; const groupedNotifications = groupNotificationsByDate(notifications); return (

{isEn ? 'Notifications' : 'Уведомления'}

{/* Панель действий */}
{/* Фильтры */}
{/* Действия */}
{unreadCount > 0 && ( )} {notifications.some((n) => n.isRead) && ( )}
{/* Push-уведомления */} {!pushEnabled && 'Notification' in window && pushPermission !== 'denied' && (

{isEn ? 'Enable Push Notifications' : 'Подключите Push-уведомления'}

{isEn ? 'Get instant notifications on your device for important events' : 'Получайте мгновенные уведомления на компьютер или телефон при важных событиях'}

)} {/* Уведомления заблокированы */} {pushPermission === 'denied' && (

Push-уведомления заблокированы

{isEn ? 'You have blocked notifications for this site. To enable them, allow notifications in your browser settings.' : 'Вы заблокировали уведомления для этого сайта. Чтобы включить их, разрешите уведомления в настройках браузера.'}

{isEn ? <>Chrome/Edge: Click the lock icon to the left of the address bar → Notifications → Allow
Firefox: Settings → Privacy & Security → Permissions → Notifications → Settings : <>Chrome/Edge: Нажмите на иконку замка слева от адресной строки → Уведомления → Разрешить
Firefox: Настройки → Приватность и защита → Разрешения → Уведомления → Настройки }

)}
{/* Список уведомлений */} {loading ? (
) : notifications.length === 0 ? (

{isEn ? 'No notifications' : 'Нет уведомлений'}

{filter === 'unread' ? (isEn ? 'All notifications are read' : 'Все уведомления прочитаны') : (isEn ? 'You have no notifications yet' : 'У вас пока нет уведомлений')}

) : (
{Object.entries(groupedNotifications).map(([groupName, groupNotifications]) => { if (groupNotifications.length === 0) return null; return (

{groupName}

{groupNotifications.map((notification) => (
{/* Цветовой индикатор */}
{/* Контент */}

{notification.title}

{notification.message}

{formatDate(notification.createdAt)}

{/* Действия */}
{!notification.isRead && ( )}
{/* Ссылка для перехода */} {notification.actionUrl && ( Перейти → )}
))}
); })}
)}
); }; export default NotificationsPage;