import React, { createContext, useContext, useState, ReactNode } from 'react'; import Toast, { ToastType } from '../components/Toast'; interface ToastItem { id: string; type: ToastType; title?: string; message: string; duration?: number; } interface ToastContextType { showToast: (type: ToastType, message: string, title?: string, duration?: number) => void; showSuccess: (message: string, title?: string) => void; showError: (message: string, title?: string) => void; showWarning: (message: string, title?: string) => void; showInfo: (message: string, title?: string) => void; } const ToastContext = createContext(undefined); export const useToast = () => { const context = useContext(ToastContext); if (!context) { throw new Error('useToast must be used within a ToastProvider'); } return context; }; interface ToastProviderProps { children: ReactNode; } export const ToastProvider: React.FC = ({ children }) => { const [toasts, setToasts] = useState([]); const showToast = (type: ToastType, message: string, title?: string, duration?: number) => { const id = Date.now().toString(); const newToast: ToastItem = { id, type, message, title, duration }; setToasts(prev => { // 相同消息去重:如果已存在相同的消息(类型和内容相同),则先移除旧的 const filtered = prev.filter(t => t.message !== message || t.type !== type); return [...filtered, newToast]; }); }; const removeToast = (id: string) => { setToasts(prev => prev.filter(toast => toast.id !== id)); }; const showSuccess = (message: string, title?: string) => showToast('success', message, title); const showError = (message: string, title?: string) => showToast('error', message, title); const showWarning = (message: string, title?: string) => showToast('warning', message, title); const showInfo = (message: string, title?: string) => showToast('info', message, title); return ( {children}
{toasts.map((toast) => (
removeToast(toast.id)} />
))}
); };