Files
jiang13-bbs/frontend/app/admin/content/page.tsx

102 lines
3.3 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import type { Metadata } from "next";
import { cookies } from "next/headers";
import { authCookieHeader } from "@/lib/cookies";
import {
fetchAdminContentCounts,
fetchAdminContentPosts,
fetchAdminContentComments,
type AdminContentComment,
type AdminContentPost,
type AdminContentStatus,
} from "@/lib/api";
import { getMeCached, getPublicSettingsCached } from "@/lib/serverData";
import { canModerateAny, isSuperOrOwner, isOwner } from "@/lib/roles";
import Forbidden from "../Forbidden";
import ContentAdmin, { type ContentKind } from "./ContentAdmin";
export const metadata: Metadata = {
title: "内容管理",
};
const STATUSES: AdminContentStatus[] = ["live", "published", "pending", "rejected", "deleted"];
function parseStatus(v?: string): AdminContentStatus {
return v && STATUSES.includes(v as AdminContentStatus) ? (v as AdminContentStatus) : "live";
}
function parseKind(v?: string): ContentKind {
if (v === "comments") return "comments";
return "posts";
}
interface ContentPageProps {
searchParams: Promise<{ status?: string; kind?: string }>;
}
export default async function AdminContentPage({ searchParams }: ContentPageProps) {
const sp = await searchParams;
const initialStatus = parseStatus(sp.status);
const initialKind = parseKind(sp.kind);
const cookie = authCookieHeader(await cookies());
const me = await getMeCached(cookie || undefined);
if (!me.user || !canModerateAny(me.user)) {
return <Forbidden text="你所在的角色没有内容管理权限,或尚未被授权任何板块。" />;
}
let initialPosts: AdminContentPost[] = [];
let initialPostsTotal = 0;
let initialComments: AdminContentComment[] = [];
let initialCommentsTotal = 0;
let initError = "";
// PC 双栏同时展示:SSR 并行预取帖子与评论
const [postsSettled, commentsSettled, counts, settings] = await Promise.all([
fetchAdminContentPosts(1, initialStatus, cookie || undefined)
.then((res) => ({ ok: true as const, res }))
.catch((e) => ({
ok: false as const,
error: e instanceof Error ? e.message : "获取帖子失败",
})),
fetchAdminContentComments(1, initialStatus, cookie || undefined)
.then((res) => ({ ok: true as const, res }))
.catch((e) => ({
ok: false as const,
error: e instanceof Error ? e.message : "获取评论失败",
})),
fetchAdminContentCounts(cookie || undefined),
getPublicSettingsCached(),
]);
if (postsSettled.ok) {
initialPosts = postsSettled.res.posts;
initialPostsTotal = postsSettled.res.total;
} else {
initError = postsSettled.error;
}
if (commentsSettled.ok) {
initialComments = commentsSettled.res.comments;
initialCommentsTotal = commentsSettled.res.total;
} else if (!initError) {
initError = commentsSettled.error;
}
return (
<ContentAdmin
key={`${initialKind}-${initialStatus}`}
initialKind={initialKind}
initialStatus={initialStatus}
initialPosts={initialPosts}
initialPostsTotal={initialPostsTotal}
initialComments={initialComments}
initialCommentsTotal={initialCommentsTotal}
initialCounts={counts}
initError={initError}
canConfigureSettings={isSuperOrOwner(me.user.role)}
canPurge={isOwner(me.user.role)}
viewerRole={me.user.role}
initialSettings={settings}
/>
);
}