import React, { useEffect, useState } from 'react'; import { motion, AnimatePresence } from 'framer-motion'; import { Bell, CheckCircle, AlertTriangle, Info, X } from 'lucide-react'; import { useSocket } from '@/hooks/useSocket'; import { useTranslation } from 'react-i18next'; interface ToastMessage { id: string; title: string; content: string; type: 'success' | 'warning' | 'info' | 'error'; } export default function NotificationToast() { const { t } = useTranslation(); const [notifications, setNotifications] = useState([]); const socket = useSocket(); const addToast = (title: string, content: string, type: ToastMessage['type'] = 'info') => { const id = Math.random().toString(36).substring(7); setNotifications(prev => [...prev, { id, title, content, type }]); setTimeout(() => { removeToast(id); }, 5000); }; const removeToast = (id: string) => { setNotifications(prev => prev.filter(n => n.id !== id)); }; useEffect(() => { if (!socket) return; // 1. 监听支付成功 socket.on('payment_success', (data) => { addToast(t('notifications.payment_success'), data.message, 'success'); }); // 2. 监听熔断告警 (仅管理员) socket.on('admin:circuit_breaker_change', (data) => { const type = data.state === 'OPEN' ? 'error' : 'success'; const title = data.state === 'OPEN' ? t('notifications.circuit_breaker_title') : t('notifications.service_recovered'); addToast(title, t('notifications.circuit_breaker_msg', { name: data.name, state: data.state }), type); }); return () => { socket.off('payment_success'); socket.off('admin:circuit_breaker_change'); }; }, [socket]); return (
{notifications.map((n) => (
{n.type === 'success' ? : n.type === 'error' ? : n.type === 'warning' ? : }

{n.title}

{n.content}

))}
); }