import type { Metadata } from "next"; import Link from "next/link"; import { cookies } from "next/headers"; import { UserPlus, LayoutGrid, ClipboardCheck, ChevronRight, MessageSquareText, FileText, Users, } from "lucide-react"; import { fetchOverview, fetchAdminPendingCounts, type PendingCounts, } from "@/lib/api"; import { authCookieHeader } from "@/lib/cookies"; import { getMeCached } from "@/lib/serverData"; import { canModerateAny, isSuperOrOwner } from "@/lib/roles"; import Avatar from "@/components/Avatar"; import { formatRelative } from "@/lib/format"; export const metadata: Metadata = { title: "管理仪表盘", }; const fmt = (n: number) => n.toLocaleString("zh-CN"); function greeting(hour: number) { if (hour < 6) return "凌晨好"; if (hour < 12) return "上午好"; if (hour < 14) return "中午好"; if (hour < 18) return "下午好"; return "晚上好"; } function PanelHead({ title, extra }: { title: string; extra?: string }) { return (
{title} {extra && ( {extra} )}
); } /** 待办工作区:待审帖子 / 评论数量,整块进入审核页 */ function PendingWorkPanel({ counts }: { counts: PendingCounts }) { const total = counts.posts + counts.comments; const idle = total === 0; return (

内容审核

{idle ? ( 暂无待审 ) : ( {fmt(total)} 项待处理 )}
); } export default async function AdminDashboardPage() { const cookie = authCookieHeader(await cookies()); const me = await getMeCached(cookie || undefined); const canMod = canModerateAny(me.user); const canUsers = isSuperOrOwner(me.user?.role); const [overview, pendingCounts] = await Promise.all([ fetchOverview(cookie).catch(() => null), canMod ? fetchAdminPendingCounts(cookie).catch(() => ({ posts: 0, comments: 0 })) : Promise.resolve(null), ]); const now = new Date(); const dateLabel = new Intl.DateTimeFormat("zh-CN", { year: "numeric", month: "long", day: "numeric", weekday: "long", }).format(now); const stats = overview?.stats; const boards = overview?.boards ?? []; const newUsers = overview?.new_users ?? []; const topBoards = [...boards].sort((a, b) => b.post_count - a.post_count).slice(0, 6); const maxBoardCount = Math.max(1, ...topBoards.map((b) => b.post_count)); return (

{greeting(now.getHours())},{me.user?.nickname}

{dateLabel} · 站点管理

{canMod && pendingCounts && }
{newUsers.length === 0 ? (

暂无成员数据

) : ( newUsers.slice(0, 6).map((u) => ( {u.nickname} @{u.username} )) )} {canUsers && (
{topBoards.length === 0 ? (

暂无板块数据

) : ( topBoards.map((b) => ( {b.name} {fmt(b.post_count)} )) )}
); }