'use client'; import { useState, useEffect, useCallback } from 'react'; import { Box } from '@/ui/Box'; import { Text } from '@/ui/Text'; import { Icon } from '@/ui/Icon'; import { IconButton } from '@/ui/IconButton'; import type { Notification } from './notificationTypes'; import { Bell, AlertTriangle, Shield, Vote, Trophy, Users, Flag, X, ExternalLink, } from 'lucide-react'; interface ToastNotificationProps { notification: Notification; onDismiss: (notification: Notification) => void; onRead: (notification: Notification) => void; onNavigate?: (href: string) => void; autoHideDuration?: number; } 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: { bg: 'bg-red-500/10', border: 'border-red-500/30', text: 'text-red-400' }, protest_defense_requested: { bg: 'bg-warning-amber/10', border: 'border-warning-amber/30', text: 'text-warning-amber' }, protest_vote_required: { bg: 'bg-primary-blue/10', border: 'border-primary-blue/30', text: 'text-primary-blue' }, penalty_issued: { bg: 'bg-red-500/10', border: 'border-red-500/30', text: 'text-red-400' }, race_results_posted: { bg: 'bg-performance-green/10', border: 'border-performance-green/30', text: 'text-performance-green' }, league_invite: { bg: 'bg-primary-blue/10', border: 'border-primary-blue/30', text: 'text-primary-blue' }, race_reminder: { bg: 'bg-warning-amber/10', border: 'border-warning-amber/30', text: 'text-warning-amber' }, }; export function ToastNotification({ notification, onDismiss, onRead, onNavigate, autoHideDuration = 5000, }: ToastNotificationProps) { const [isVisible, setIsVisible] = useState(false); const [isExiting, setIsExiting] = useState(false); const handleDismiss = useCallback(() => { setIsExiting(true); setTimeout(() => { onDismiss(notification); }, 300); }, [notification, onDismiss]); useEffect(() => { // Animate in const showTimeout = setTimeout(() => setIsVisible(true), 10); // Auto-hide const hideTimeout = setTimeout(() => { handleDismiss(); }, autoHideDuration); return () => { clearTimeout(showTimeout); clearTimeout(hideTimeout); }; }, [autoHideDuration, handleDismiss]); const handleClick = () => { onRead(notification); if (notification.actionUrl && onNavigate) { onNavigate(notification.actionUrl); } handleDismiss(); }; const NotificationIcon = notificationIcons[notification.type] || Bell; const colors = notificationColors[notification.type] || { bg: 'bg-gray-500/10', border: 'border-gray-500/30', text: 'text-gray-400', }; return ( {/* Progress bar */} {/* Icon */} {/* Content */} {notification.title ?? 'Notification'} ) => { e.stopPropagation(); handleDismiss(); }} variant="ghost" size="sm" color="text-gray-400" /> {notification.message} {notification.actionUrl && ( View details )} ); }