/* eslint-disable @typescript-eslint/no-explicit-any */ 'use client'; import { Bell, Check, Trash2, X } from 'lucide-react'; import { useEffect, useState } from 'react'; import { useRouter } from 'next/navigation'; import { Notification } from '@/lib/types'; interface NotificationPanelProps { isOpen: boolean; onClose: () => void; } export const NotificationPanel: React.FC = ({ isOpen, onClose, }) => { const router = useRouter(); const [notifications, setNotifications] = useState([]); const [loading, setLoading] = useState(false); // 加载通知 const loadNotifications = async () => { setLoading(true); try { const response = await fetch('/api/notifications'); if (response.ok) { const data = await response.json(); setNotifications(data.notifications || []); } } catch (error) { console.error('加载通知失败:', error); } finally { setLoading(false); } }; // 标记为已读 const markAsRead = async (notificationId: string) => { try { const response = await fetch('/api/notifications', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ action: 'mark_read', notificationId, }), }); if (response.ok) { setNotifications((prev) => prev.map((n) => n.id === notificationId ? { ...n, read: true } : n ) ); } } catch (error) { console.error('标记已读失败:', error); } }; // 删除通知 const deleteNotification = async (notificationId: string) => { try { const response = await fetch('/api/notifications', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ action: 'delete', notificationId, }), }); if (response.ok) { setNotifications((prev) => prev.filter((n) => n.id !== notificationId)); } } catch (error) { console.error('删除通知失败:', error); } }; // 清空所有通知 const clearAll = async () => { try { const response = await fetch('/api/notifications', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ action: 'clear_all', }), }); if (response.ok) { setNotifications([]); } } catch (error) { console.error('清空通知失败:', error); } }; // 处理通知点击 const handleNotificationClick = (notification: Notification) => { // 标记为已读 if (!notification.read) { markAsRead(notification.id); } // 根据通知类型跳转 if (notification.type === 'favorite_update' && notification.metadata) { const { source, id } = notification.metadata; router.push(`/play?source=${source}&id=${id}`); onClose(); } }; // 打开面板时加载通知 useEffect(() => { if (isOpen) { loadNotifications(); } }, [isOpen]); return ( <> {/* 背景遮罩 */}
{/* 通知面板 */}
{/* 标题栏 */}

通知中心

{notifications.length > 0 && ( {notifications.filter((n) => !n.read).length} 条未读 )}
{notifications.length > 0 && ( )}
{/* 通知列表 */}
{loading ? (
) : notifications.length === 0 ? (

暂无通知

) : (
{notifications.map((notification) => (
handleNotificationClick(notification)} > {/* 未读标识 */} {!notification.read && (
)} {/* 通知内容 */}

{notification.title}

{notification.message}

{new Date(notification.timestamp).toLocaleString('zh-CN')}

{/* 操作按钮 */}
{!notification.read && ( )}
))}
)}
); };