"use client"; import { useCallback, useEffect, useState } from "react"; import Link from "next/link"; import { ArrowLeft, ChevronLeft, ChevronRight, ExternalLink, FileText, Loader2, MessageCircle, MessagesSquare, } from "lucide-react"; import { apiAdminUserAuditComments, apiAdminUserAuditMessages, apiAdminUserAuditPosts, type AdminAuditCommentItem, type AdminAuditMessageItem, type AdminAuditPostItem, type AdminUserAuditProfile, } from "@/lib/api"; import { formatDate, formatRelative } from "@/lib/format"; import Avatar from "@/components/Avatar"; import RoleBadge from "@/components/RoleBadge"; type TabKey = "posts" | "comments" | "messages"; const TABS: { key: TabKey; label: string; icon: React.ReactNode }[] = [ { key: "posts", label: "帖子", icon: }, { key: "comments", label: "评论", icon: }, { key: "messages", label: "私信与群消息", icon: }, ]; const PAGE_SIZE = 20; function StatusChip({ status, deleted, recalled, }: { status?: string; deleted?: boolean; recalled?: boolean; }) { const chips: { label: string; color: string; soft: string }[] = []; if (deleted) chips.push({ label: "已删除", color: "var(--danger)", soft: "var(--danger-soft)" }); if (recalled) chips.push({ label: "已撤回", color: "var(--ink-3)", soft: "var(--tint)" }); if (status === "pending") chips.push({ label: "待审", color: "var(--gold)", soft: "var(--gold-soft)" }); if (status === "rejected") chips.push({ label: "已驳回", color: "var(--danger)", soft: "var(--danger-soft)" }); if (status === "published" && !deleted) { chips.push({ label: "已发布", color: "var(--ok)", soft: "var(--ok-soft)" }); } if (chips.length === 0 && !recalled) { chips.push({ label: "正常", color: "var(--ink-3)", soft: "var(--tint)" }); } return ( {chips.map((c) => ( {c.label} ))} ); } function Pager({ page, total, onChange, loading, }: { page: number; total: number; onChange: (p: number) => void; loading?: boolean; }) { const pages = Math.max(1, Math.ceil(total / PAGE_SIZE)); if (pages <= 1) return null; return (
{page} / {pages}
); } export default function UserAuditClient({ userId, initial, }: { userId: number; initial: AdminUserAuditProfile; }) { const [profile] = useState(initial); const [tab, setTab] = useState("posts"); const [page, setPage] = useState(1); const [loading, setLoading] = useState(false); const [error, setError] = useState(""); const [posts, setPosts] = useState([]); const [comments, setComments] = useState([]); const [messages, setMessages] = useState([]); const [total, setTotal] = useState(0); const u = profile.user; const load = useCallback( async (t: TabKey, p: number) => { setLoading(true); setError(""); try { if (t === "posts") { const res = await apiAdminUserAuditPosts(userId, p); setPosts(res.items || []); setTotal(res.total); } else if (t === "comments") { const res = await apiAdminUserAuditComments(userId, p); setComments(res.items || []); setTotal(res.total); } else { const res = await apiAdminUserAuditMessages(userId, p); setMessages(res.items || []); setTotal(res.total); } } catch (e) { setError(e instanceof Error ? e.message : "加载失败"); } finally { setLoading(false); } }, [userId] ); useEffect(() => { load(tab, page); }, [tab, page, load]); const switchTab = (t: TabKey) => { setTab(t); setPage(1); }; const tabCount = (t: TabKey) => { if (t === "posts") return profile.posts_total; if (t === "comments") return profile.comments_total; return profile.messages_total; }; return (
返回用户列表

{u.nickname}

{u.banned && ( 已封禁 )}

@{u.username}

注册于 {formatDate(u.created_at)} · 已发布帖 {profile.published_posts} / 评{" "} {profile.published_comments}

主页
{[ { label: "全部帖子", value: profile.posts_total }, { label: "全部评论", value: profile.comments_total }, { label: "全部消息", value: profile.messages_total }, ].map((c) => (

{c.value.toLocaleString("zh-CN")}

{c.label}

))}
{TABS.map((t) => { const active = tab === t.key; return ( ); })}
{error && (

{error}

)} {!error && loading && posts.length + comments.length + messages.length === 0 && (
)} {!error && !loading && total === 0 && (

该分类暂无内容

)} {tab === "posts" && posts.map((p) => (
{p.board_name && ( {p.board_name} )}
{p.deleted ? (

{p.title || "(无标题)"}

) : ( {p.title || "(无标题)"} )} {p.content && (

{p.content}

)}
{formatRelative(p.created_at)}
))} {tab === "comments" && comments.map((c) => (
{c.deleted ? ( 帖子 #{c.post_id} ) : ( 帖子 #{c.post_id} )}

{c.content || "(空)"}

{formatRelative(c.created_at)}
))} {tab === "messages" && messages.map((m) => (
{m.room_name} {m.room_type === "direct" ? " · 私聊" : m.room_type === "group" ? " · 群聊" : ""}

{m.content || "(空)"}

{formatRelative(m.created_at)}
))}
); }