import React, { createContext, useContext, useState, useCallback } from 'react'; import { CheckCircleIcon, ExclamationTriangleIcon, } from '@heroicons/react/24/outline'; interface Toast { id: number; message: string | React.ReactNode; type: 'success' | 'error'; } interface ToastContextProps { showSuccessToast: (message: string | React.ReactNode) => void; showErrorToast: (message: string | React.ReactNode) => void; } const ToastContext = createContext(undefined); export const ToastProvider: React.FC<{ children: React.ReactNode }> = ({ children, }) => { const [toasts, setToasts] = useState([]); const removeToast = useCallback((id: number) => { setToasts((prev) => prev.filter((toast) => toast.id !== id)); }, []); const showSuccessToast = useCallback( (message: string | React.ReactNode) => { const id = Date.now() + Math.random(); const newToast: Toast = { id, message, type: 'success' }; setToasts((prev) => [...prev, newToast]); setTimeout(() => removeToast(id), 4000); }, [removeToast] ); const showErrorToast = useCallback( (message: string | React.ReactNode) => { const id = Date.now() + Math.random(); const newToast: Toast = { id, message, type: 'error' }; setToasts((prev) => [...prev, newToast]); setTimeout(() => removeToast(id), 4000); }, [removeToast] ); return ( {children}
{toasts.map((toast, index) => ( removeToast(toast.id)} style={{ transform: `translateY(${index * 4}px)` }} /> ))}
); }; export const useToast = () => { const context = useContext(ToastContext); if (context === undefined) { throw new Error('useToast must be used within a ToastProvider'); } return context; }; const ToastComponent: React.FC<{ message: string | React.ReactNode; type: 'success' | 'error'; onClose: () => void; style?: React.CSSProperties; }> = ({ message, type, onClose, style }) => { return (
{type === 'success' ? ( ) : ( )}
{message}
); };