"use client"; import { useState, useEffect, useCallback } from "react"; import { useSSE } from "@/lib/use-sse"; interface Toast { id: number; message: string; type: "info" | "warning" | "error"; } const ALERT_TYPES = ["container_unhealthy", "container_restarted", "drift_found"]; export function ToastProvider() { const events = useSSE("/api/activity", 5); const [toasts, setToasts] = useState([]); const [seen, setSeen] = useState(new Set()); const addToast = useCallback((message: string, type: Toast["type"]) => { const id = Date.now(); setToasts(prev => [...prev, { id, message, type }]); setTimeout(() => setToasts(prev => prev.filter(t => t.id !== id)), 5000); }, []); useEffect(() => { for (const event of events) { const key = `${event.type}-${event.timestamp}`; if (seen.has(key)) continue; if (ALERT_TYPES.includes(event.type)) { setSeen(prev => new Set(prev).add(key)); addToast(event.raw || `${event.type}: ${event.source}`, event.type.includes("unhealthy") ? "error" : "warning"); } } }, [events, seen, addToast]); if (toasts.length === 0) return null; const colors = { info: "border-blue-500/20 bg-blue-500/5 backdrop-blur-xl", warning: "border-amber-500/20 bg-amber-500/5 backdrop-blur-xl", error: "border-red-500/20 bg-red-500/5 backdrop-blur-xl", }; return (
{toasts.map(t => (

{t.message}

))}
); }