import React, { createContext, useCallback, useContext, useMemo, useState } from 'react'; type ToastTone = 'success' | 'error' | 'info'; interface ToastItem { id: number; message: string; tone: ToastTone; } interface ToastContextValue { showToast: (message: string, tone?: ToastTone) => void; success: (message: string) => void; error: (message: string) => void; info: (message: string) => void; } const ToastContext = createContext(null); export const ToastProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => { const [toasts, setToasts] = useState([]); const dismissToast = useCallback((id: number) => { setToasts((prev) => prev.filter((toast) => toast.id !== id)); }, []); const showToast = useCallback((message: string, tone: ToastTone = 'info') => { const id = Date.now() + Math.floor(Math.random() * 1000); setToasts((prev) => [...prev, { id, message, tone }]); window.setTimeout(() => { setToasts((prev) => prev.filter((toast) => toast.id !== id)); }, 5000); }, []); const value = useMemo(() => ({ showToast, success: (message) => showToast(message, 'success'), error: (message) => showToast(message, 'error'), info: (message) => showToast(message, 'info') }), [showToast]); return ( {children}
{toasts.map((toast) => (
{toast.message}
))}
); }; export const useToast = (): ToastContextValue => { const context = useContext(ToastContext); if (!context) { throw new Error('useToast must be used within a ToastProvider'); } return context; };