116 lines
3.1 KiB
TypeScript
116 lines
3.1 KiB
TypeScript
import { PERMS } from "@/lib/permission-slugs";
|
|
import { resolveHousekeepingRouteTitle } from "../../../foundation/page/route-copy";
|
|
import type { HousekeepingPageInput } from "../../../route-handlers";
|
|
import { contentQuery } from "../queries/content-queries";
|
|
import { ContentCommandForm } from "./content-command-form";
|
|
import {
|
|
ContentPageFrame,
|
|
type ContentPageProps,
|
|
parseContentListInput,
|
|
} from "./content-page-frame";
|
|
|
|
export function ContentEditorialPage({
|
|
title,
|
|
context,
|
|
result,
|
|
routeId,
|
|
}: ContentPageProps) {
|
|
const canNews = context.has(PERMS.NEWS_EDIT);
|
|
const canPages = context.has(PERMS.PAGES_EDIT);
|
|
return (
|
|
<ContentPageFrame
|
|
title={title ?? "Editorial content"}
|
|
description="Manage articles, navigation, tags, and writable boxes."
|
|
result={result}
|
|
forms={
|
|
<div className="grid gap-3 lg:grid-cols-2">
|
|
{canNews && routeId?.includes("article") ? (
|
|
<ContentCommandForm
|
|
commandId="content.editorial.article.change"
|
|
buttonLabel="Save article"
|
|
input={{
|
|
action: routeId.endsWith("create") ? "create" : "update",
|
|
}}
|
|
fields={[
|
|
{ name: "id", label: "Article ID", type: "identifier" },
|
|
{
|
|
name: "title",
|
|
label: "Title",
|
|
type: "text",
|
|
required: true,
|
|
maxLength: 255,
|
|
},
|
|
{
|
|
name: "content",
|
|
label: "Body",
|
|
type: "textarea",
|
|
required: true,
|
|
maxLength: 100_000,
|
|
},
|
|
]}
|
|
/>
|
|
) : null}
|
|
{canPages && routeId === "content.editorial.tags" ? (
|
|
<ContentCommandForm
|
|
commandId="content.editorial.tag.change"
|
|
buttonLabel="Save tag"
|
|
input={{ action: "update" }}
|
|
fields={[
|
|
{ name: "id", label: "Tag ID", type: "identifier" },
|
|
{
|
|
name: "name",
|
|
label: "Name",
|
|
type: "text",
|
|
required: true,
|
|
maxLength: 100,
|
|
},
|
|
]}
|
|
/>
|
|
) : null}
|
|
{canPages && routeId === "content.editorial.writeable-boxes" ? (
|
|
<ContentCommandForm
|
|
commandId="content.editorial.writeable-box.change"
|
|
buttonLabel="Save box"
|
|
input={{ action: "update" }}
|
|
fields={[
|
|
{ name: "id", label: "Box ID", type: "identifier" },
|
|
{
|
|
name: "title",
|
|
label: "Title",
|
|
type: "text",
|
|
required: true,
|
|
maxLength: 255,
|
|
},
|
|
{
|
|
name: "content",
|
|
label: "Content",
|
|
type: "textarea",
|
|
maxLength: 20_000,
|
|
},
|
|
]}
|
|
/>
|
|
) : null}
|
|
</div>
|
|
}
|
|
/>
|
|
);
|
|
}
|
|
|
|
export async function renderContentEditorialPage(input: HousekeepingPageInput) {
|
|
const routeId = input.match.routeId as ContentPageProps["routeId"];
|
|
const title = resolveHousekeepingRouteTitle(input, "Editorial content");
|
|
const result = await contentQuery.run(input.context, {
|
|
routeId: routeId ?? "content.editorial.articles",
|
|
params: input.match.params,
|
|
list: parseContentListInput(input.searchParams ?? {}),
|
|
});
|
|
return (
|
|
<ContentEditorialPage
|
|
title={title}
|
|
context={input.context}
|
|
result={result}
|
|
routeId={routeId}
|
|
/>
|
|
);
|
|
}
|