'use client'; import { useState, useEffect, useRef } from 'react'; import { useRouter } from 'next/navigation'; export interface Notification { id: string; type: 'critical_risk' | 'upcoming_audit' | 'expiring_document' | 'aircraft_status_change'; title: string; message: string; priority: 'low' | 'medium' | 'high' | 'critical'; createdAt: string; read: boolean; actionUrl?: string; } interface NotificationCenterProps { notifications: Notification[]; onMarkAsRead: (id: string) => void; onClose: () => void; } export default function NotificationCenter({ notifications, onMarkAsRead, onClose, }: NotificationCenterProps) { const router = useRouter(); const [unreadCount, setUnreadCount] = useState(0); const audioRef = useRef(null); useEffect(() => { const unread = notifications.filter(n => !n.read && n.priority === 'critical').length; setUnreadCount(unread); // Воспроизведение звука для критических уведомлений if (unread > 0 && audioRef.current) { audioRef.current.play().catch(() => { // Игнорируем ошибки автовоспроизведения }); } }, [notifications]); const getPriorityColor = (priority: string) => { switch (priority) { case 'critical': return '#f44336'; case 'high': return '#ff9800'; case 'medium': return '#2196f3'; case 'low': return '#4caf50'; default: return '#666'; } }; const getPriorityIcon = (priority: string) => { switch (priority) { case 'critical': return '🚨'; case 'high': return '⚠️'; case 'medium': return 'ℹ️'; case 'low': return '✅'; default: return '📌'; } }; const handleNotificationClick = (notification: Notification) => { if (!notification.read) { onMarkAsRead(notification.id); } if (notification.actionUrl) { router.push(notification.actionUrl); onClose(); } }; const criticalNotifications = notifications.filter(n => n.priority === 'critical'); const otherNotifications = notifications.filter(n => n.priority !== 'critical'); return ( <> {/* Скрытый audio элемент для звуковых сигналов */} {typeof window !== 'undefined' && ( )}
{/* Заголовок */}

Уведомления {unreadCount > 0 && ( {unreadCount} )}

{/* Список уведомлений */}
{notifications.length === 0 ? (
Нет уведомлений
) : ( <> {/* Критические уведомления */} {criticalNotifications.length > 0 && (
{criticalNotifications.map((notification) => (
handleNotificationClick(notification)} style={{ padding: '16px 20px', borderBottom: '1px solid #e0e0e0', cursor: 'pointer', backgroundColor: notification.read ? 'white' : '#fff3e0', borderLeft: `4px solid ${getPriorityColor(notification.priority)}`, transition: 'background-color 0.2s', }} onMouseEnter={(e) => { e.currentTarget.style.backgroundColor = '#f5f5f5'; }} onMouseLeave={(e) => { e.currentTarget.style.backgroundColor = notification.read ? 'white' : '#fff3e0'; }} >
{getPriorityIcon(notification.priority)}
{notification.title} {!notification.read && ( )}
{notification.message}
{new Date(notification.createdAt).toLocaleString('ru-RU')}
))}
)} {/* Остальные уведомления */} {otherNotifications.length > 0 && (
{otherNotifications.map((notification) => (
handleNotificationClick(notification)} style={{ padding: '16px 20px', borderBottom: '1px solid #e0e0e0', cursor: 'pointer', backgroundColor: notification.read ? 'white' : '#f9f9f9', borderLeft: `4px solid ${getPriorityColor(notification.priority)}`, transition: 'background-color 0.2s', }} onMouseEnter={(e) => { e.currentTarget.style.backgroundColor = '#f5f5f5'; }} onMouseLeave={(e) => { e.currentTarget.style.backgroundColor = notification.read ? 'white' : '#f9f9f9'; }} >
{getPriorityIcon(notification.priority)}
{notification.title} {!notification.read && ( )}
{notification.message}
{new Date(notification.createdAt).toLocaleString('ru-RU')}
))}
)} )}
); }