/* eslint-disable react-hooks/set-state-in-effect */ // Toast Notification System - Slide-in notifications from top-right "use client"; import { useEffect, useState, useCallback, useSyncExternalStore } from "react"; import { createPortal } from "react-dom"; import { subscribeToToasts, type Toast, } from "./toast-store"; interface ToastNotificationProps { toast: Toast; onDismiss: (id: string) => void; } function ToastItem({ toast, onDismiss }: ToastNotificationProps) { const [progress, setProgress] = useState(100); const [isExiting, setIsExiting] = useState(false); const duration = toast.duration ?? 5000; useEffect(() => { const startTime = Date.now(); const interval = setInterval(() => { const elapsed = Date.now() - startTime; const remaining = Math.max(0, 100 - (elapsed / duration) * 100); setProgress(remaining); if (remaining === 0) { clearInterval(interval); setIsExiting(true); setTimeout(() => onDismiss(toast.id), 300); } }, 50); return () => clearInterval(interval); }, [toast.id, duration, onDismiss]); const handleDismiss = () => { setIsExiting(true); setTimeout(() => onDismiss(toast.id), 300); }; const icons = { success: ( ), error: ( ), warning: ( ), info: ( ), }[toast.type]; const bgColors = { success: "bg-green-50 border-green-200", error: "bg-red-50 border-red-200", warning: "bg-amber-50 border-amber-200", info: "bg-blue-50 border-blue-200", }[toast.type]; return (
{toast.title}
{toast.message && ({toast.message}
)} {/* Progress bar */}