"use client"; import { useState } from "react"; import { useRouter } from "next/navigation"; import Link from "next/link"; import { Heart, MessageCircle, CheckCheck, Bell, CheckCircle2, XCircle } from "lucide-react"; import { apiMarkRead, apiMarkAllRead, type NotificationsResponse, type NotificationItem } from "@/lib/api"; /** * 通知列表交互层:数据由服务端 SSR 直出,这里只承担已读标记等客户端操作。 */ export default function NotificationsClient({ initialData }: { initialData: NotificationsResponse }) { const router = useRouter(); const [notifications, setNotifications] = useState(initialData.notifications || []); const handleClick = async (n: NotificationItem) => { if (!n.is_read) { apiMarkRead(n.id).catch(() => {}); setNotifications((list) => list.map((item) => (item.id === n.id ? { ...item, is_read: true } : item)) ); } router.push(`/post/${n.post_id}`); }; const handleMarkAll = async () => { await apiMarkAllRead(); setNotifications((list) => list.map((item) => ({ ...item, is_read: true }))); // 同步刷新 Header 未读红点(layout 重新取 unread_count) router.refresh(); }; const formatTime = (dateStr: string) => { const diff = Date.now() - new Date(dateStr).getTime(); const min = Math.floor(diff / 60000); if (min < 1) return "刚刚"; if (min < 60) return `${min} 分钟前`; const hour = Math.floor(min / 60); if (hour < 24) return `${hour} 小时前`; return `${Math.floor(hour / 24)} 天前`; }; const hasUnread = notifications.some((n) => !n.is_read); return ( <> {hasUnread && (
)} {notifications.length === 0 ? (

还没有通知

当有人评论或点赞你的帖子时,会在这里提醒你

) : (
{notifications.map((n, i) => { const approval = n.type === "approved" || n.type === "rejected"; const iconNode = n.type === "approved" ? : n.type === "rejected" ? : n.type === "like" ? : ; const iconColor = n.type === "approved" ? "var(--ok)" : n.type === "rejected" ? "var(--danger)" : n.type === "like" ? "var(--clay)" : "var(--accent)"; const iconBg = n.type === "approved" ? "var(--ok-soft)" : n.type === "rejected" ? "var(--danger-soft)" : n.type === "like" ? "var(--clay-soft)" : "var(--accent-soft)"; return ( ); })}
)} ); }