import { createContext, useContext, useState, useCallback, useEffect, ReactNode } from 'react' import { useNavigate } from 'react-router-dom' import { AlertTriangle, AlertCircle, Info, X } from 'lucide-react' import type { Alert } from '@/lib/api' interface Toast { id: string alert: Alert dismissedAt?: number } interface ToastContextValue { addToast: (alert: Alert) => void } const ToastContext = createContext(null) export function useToast() { const context = useContext(ToastContext) if (!context) { throw new Error('useToast must be used within a ToastProvider') } return context } function getSeverityStyles(severity: string) { switch (severity?.toLowerCase()) { case 'critical': case 'emergency': return { bg: 'bg-red-500/10', border: 'border-red-500', icon: AlertCircle, iconColor: 'text-red-500', } case 'warning': return { bg: 'bg-amber-500/10', border: 'border-amber-500', icon: AlertTriangle, iconColor: 'text-amber-500', } default: return { bg: 'bg-blue-500/10', border: 'border-blue-500', icon: Info, iconColor: 'text-blue-500', } } } function ToastItem({ toast, onDismiss, onNavigate, }: { toast: Toast onDismiss: () => void onNavigate: () => void }) { const styles = getSeverityStyles(toast.alert.severity) const Icon = styles.icon // Auto-dismiss after 8 seconds useEffect(() => { const timer = setTimeout(onDismiss, 8000) return () => clearTimeout(timer) }, [onDismiss]) return (
{/* Severity bar */}
{toast.alert.type.replace(/_/g, ' ').replace(/\b\w/g, l => l.toUpperCase())}
{toast.alert.message}
) } export function ToastProvider({ children }: { children: ReactNode }) { const [toasts, setToasts] = useState([]) const navigate = useNavigate() const addToast = useCallback((alert: Alert) => { const id = `${Date.now()}-${Math.random().toString(36).substr(2, 9)}` setToasts((prev) => [...prev, { id, alert }]) }, []) const dismissToast = useCallback((id: string) => { setToasts((prev) => prev.filter((t) => t.id !== id)) }, []) const handleNavigate = useCallback(() => { navigate('/alerts') }, [navigate]) return ( {children} {/* Toast container - fixed bottom right */}
{toasts.map((toast) => (
dismissToast(toast.id)} onNavigate={handleNavigate} />
))}
) }