'use client'; import { AlertTriangle, Bell, CheckCheck, ExternalLink, Flag, Shield, Trophy, Users, Vote } from 'lucide-react'; import { useRouter } from 'next/navigation'; import { useEffect, useRef, useState } from 'react'; const notificationIcons: Record = { protest_filed: AlertTriangle, protest_defense_requested: Shield, protest_vote_required: Vote, penalty_issued: AlertTriangle, race_results_posted: Trophy, league_invite: Users, race_reminder: Flag, }; const notificationColors: Record = { protest_filed: 'text-red-400 bg-red-400/10', protest_defense_requested: 'text-warning-amber bg-warning-amber/10', protest_vote_required: 'text-primary-blue bg-primary-blue/10', penalty_issued: 'text-red-400 bg-red-400/10', race_results_posted: 'text-performance-green bg-performance-green/10', league_invite: 'text-primary-blue bg-primary-blue/10', race_reminder: 'text-warning-amber bg-warning-amber/10', }; import { useNotifications } from './NotificationProvider'; import type { Notification } from './NotificationProvider'; export default function NotificationCenter() { const [isOpen, setIsOpen] = useState(false); const panelRef = useRef(null); const router = useRouter(); const { notifications, unreadCount, markAsRead, markAllAsRead } = useNotifications(); // Close panel when clicking outside useEffect(() => { const handleClickOutside = (event: MouseEvent) => { if (panelRef.current && !panelRef.current.contains(event.target as Node)) { setIsOpen(false); } }; if (isOpen) { document.addEventListener('mousedown', handleClickOutside); } return () => { document.removeEventListener('mousedown', handleClickOutside); }; }, [isOpen]); const handleNotificationClick = (notification: Notification) => { markAsRead(notification.id); if (notification.actionUrl) { router.push(notification.actionUrl); setIsOpen(false); } }; const formatTime = (date: Date) => { const now = new Date(); const diff = now.getTime() - new Date(date).getTime(); const minutes = Math.floor(diff / (1000 * 60)); const hours = Math.floor(diff / (1000 * 60 * 60)); const days = Math.floor(diff / (1000 * 60 * 60 * 24)); if (minutes < 1) return 'Just now'; if (minutes < 60) return `${minutes}m ago`; if (hours < 24) return `${hours}h ago`; if (days < 7) return `${days}d ago`; return new Date(date).toLocaleDateString(); }; return (
{/* Bell button */} {/* Notification panel */} {isOpen && (
{/* Header */}
Notifications {unreadCount > 0 && ( {unreadCount} new )}
{unreadCount > 0 && ( )}
{/* Notifications list */}
{notifications.length === 0 ? (

No notifications yet

You'll be notified about protests, races, and more

) : (
{notifications.map((notification) => { const Icon = notificationIcons[notification.type] || Bell; const colorClass = notificationColors[notification.type] || 'text-gray-400 bg-gray-400/10'; return ( ); })}
)}
{/* Footer */} {notifications.length > 0 && (

Showing {notifications.length} notification{notifications.length !== 1 ? 's' : ''}

)}
)}
); }