import { useEffect, useRef } from 'react'; import { X, CheckCircle, AlertTriangle, AlertCircle, Info, Bell, Trash2 } from 'lucide-react'; import { useGameStore, type GameNotification } from '@/store'; import { formatDuration } from '@ai-tycoon/shared'; const ICON_MAP = { success: { icon: CheckCircle, color: 'text-success' }, warning: { icon: AlertTriangle, color: 'text-warning' }, danger: { icon: AlertCircle, color: 'text-danger' }, info: { icon: Info, color: 'text-accent-light' }, } as const; export function NotificationPanel({ onClose }: { onClose: () => void }) { const notifications = useGameStore((s) => s.notifications); const markAllRead = useGameStore((s) => s.markAllNotificationsRead); const removeNotification = useGameStore((s) => s.removeNotification); const clearAll = useGameStore((s) => s.clearAllNotifications); const currentTick = useGameStore((s) => s.meta.tickCount); const panelRef = useRef(null); useEffect(() => { markAllRead(); }, [markAllRead]); useEffect(() => { const handler = (e: MouseEvent) => { if (panelRef.current && !panelRef.current.contains(e.target as Node)) { onClose(); } }; const keyHandler = (e: KeyboardEvent) => { if (e.key === 'Escape') onClose(); }; document.addEventListener('mousedown', handler); document.addEventListener('keydown', keyHandler); return () => { document.removeEventListener('mousedown', handler); document.removeEventListener('keydown', keyHandler); }; }, [onClose]); return (

Notifications

{notifications.length > 0 && ( )}
{notifications.length === 0 ? (

No notifications yet

) : ( notifications.map((n: GameNotification) => { const { icon: Icon, color } = ICON_MAP[n.type] ?? ICON_MAP.info; const ticksAgo = currentTick - n.tick; return (
{n.title}
{n.message}
{formatDuration(ticksAgo)} ago
); }) )}
); }