'use client'; import { useEffect, useState, useCallback } from 'react'; import Link from 'next/link'; import { apiFetch } from '@/lib/auth'; import { Button } from '@/components/ui/button'; import { Skeleton } from '@/components/ui/skeleton'; interface Notification { id: number; type: 'like' | 'comment' | 'follow' | 'system'; title: string; content?: string; link?: string; relatedId?: number; isRead: boolean; createdAt: string; } function NotificationIcon({ type }: { type: string }) { const icons: Record = { like: '❤️', comment: '💬', follow: '👤', system: '🔔', }; return {icons[type] || '🔔'}; } export default function NotificationsPage() { const [notifications, setNotifications] = useState([]); const [unreadCount, setUnreadCount] = useState(0); const [loading, setLoading] = useState(true); const load = useCallback(async () => { try { const res = await apiFetch('/notifications'); if (res.ok) { const data = await res.json(); setNotifications(data.items || []); setUnreadCount(data.unread || 0); } } catch (e) { console.error(e) } setLoading(false); }, []); useEffect(() => { load(); }, [load]); async function markRead(id: number) { try { await apiFetch(`/notifications/${id}/read`, { method: 'PATCH' }); setNotifications(prev => prev.map(n => n.id === id ? { ...n, isRead: true } : n)); setUnreadCount(prev => Math.max(0, prev - 1)); } catch (e) { console.error(e) } } async function markAllRead() { try { await apiFetch('/notifications/read-all', { method: 'PATCH' }); setNotifications(prev => prev.map(n => ({ ...n, isRead: true }))); setUnreadCount(0); } catch (e) { console.error(e) } } if (loading) return (
); return (

通知

{unreadCount > 0 ? `你有 ${unreadCount} 条未读通知` : '暂无未读通知'}

{unreadCount > 0 && ( )}
{notifications.map(n => (
{n.link ? ( { if (!n.isRead) markRead(n.id); }} className="text-sm font-medium text-foreground hover:text-brand-600"> {n.title} ) : (

{n.title}

)} {n.content &&

{n.content}

}

{new Date(n.createdAt).toLocaleString('zh-CN')}

{!n.isRead && ( )}
))} {notifications.length === 0 && (

🔔

暂无通知

点赞、评论或关注你的人会出现在这里

)}
); }