import config from "@payload-config";
import { headers as nextHeaders } from "next/headers";
import Link from "next/link";
import { getPayload } from "payload";
import { ArrowLeftIcon, BookOpenIcon } from "lucide-react";
import type { WikiPage as WikiPageDocument } from "@/payload-types";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import { Card, CardContent } from "@/components/ui/card";
import { LockdownBanner } from "@/components/frontend/wiki/LockdownBanner";
import { WikiContent } from "@/components/frontend/wiki/WikiContent";
import { WikiToolbar } from "@/components/frontend/wiki/WikiToolbar";
import { hasIntelligenceQualification } from "@/utils/access-control/hasIntelligenceQualification";
import { listTemplates, templateMap } from "@/lib/wiki/service";
import { prepareMarkdown } from "@/lib/wiki/prepare";
import { buildTemplateStyles } from "@/lib/wiki/templateCss";
export const metadata = {
title: "Wiki page: Polaris Task Force",
};
function relationName(relation: WikiPageDocument["lastEditor"]): string {
if (typeof relation === "object" && relation !== null) {
return (
relation.payloadDisplayName || relation.displayName || relation.username || "Unknown editor"
);
}
return typeof relation === "number" ? `User #${relation}` : "Unknown editor";
}
function formatDate(iso: string): string {
return new Intl.DateTimeFormat(undefined, {
dateStyle: "medium",
timeStyle: "short",
}).format(new Date(iso));
}
function MissingWikiPage({ slug }: { readonly slug: string }) {
return (
Page doesn't exist yet
This entry is not in the field guide. Start a page for this topic instead.
);
}
export default async function WikiDetailPage({
params,
searchParams,
}: {
readonly params: Promise<{ slug: string }>;
readonly searchParams: Promise<{ revision?: string }>;
}) {
const { slug } = await params;
const headers = await nextHeaders();
const payload = await getPayload({ config });
const { user } = await payload.auth({
headers,
canSetHeaders: false,
});
const pageResult = await payload.find({
collection: "wiki-pages",
where: { slug: { equals: slug } },
limit: 1,
depth: 1,
overrideAccess: true,
});
const page = pageResult.docs[0];
if (!page) {
return (
);
}
const [revisionNumber, templates, isModerator] = await Promise.all([
searchParams.then((sp) => {
const n = Number(sp.revision);
return Number.isInteger(n) && n >= 1 ? n : null;
}),
listTemplates(payload),
hasIntelligenceQualification(payload, user),
]);
const templateMapValue = templateMap(templates);
const templateHtmlMap: Record = {};
for (const template of templates) {
if (template.html && template.html.trim().length > 0) {
templateHtmlMap[template.name] = template.html;
}
}
if (revisionNumber !== null) {
const revisionResult = await payload.find({
collection: "wiki-revisions",
where: { page: { equals: page.id }, revisionNumber: { equals: revisionNumber } },
limit: 1,
depth: 0,
overrideAccess: true,
});
const revision = revisionResult.docs[0];
if (!revision) {
return (
Wiki
Revision not found
Revision {revisionNumber} of this page no longer exists.
);
}
const prepared = prepareMarkdown(revision.contentSnapshot, templateMapValue, templateHtmlMap);
const { css: templateCss, scopeClasses } = buildTemplateStyles(
revision.contentSnapshot,
templates,
);
return (
{templateCss && }
Wiki
You're viewing revision {revision.revisionNumber} (from{" "}
{formatDate(revision.createdAt)}).
{revision.titleSnapshot}
);
}
const prepared = prepareMarkdown(page.body, templateMapValue, templateHtmlMap);
const { css: templateCss, scopeClasses } = buildTemplateStyles(page.body, templates);
const lockdown = page.lockdown === true;
return (
{templateCss && }
Wiki
{page.title}
{page.category}
{(page.tags ?? []).map((tag) => (
{tag}
))}
Last edited by {relationName(page.lastEditor)}
{lockdown &&
}
);
}