import { deletePage, getPageById, updatePage } from "@cms/db" import { Button } from "@cms/ui/button" import Link from "next/link" import { redirect } from "next/navigation" import { AdminShell } from "@/components/admin-shell" import { requirePermissionForRoute } from "@/lib/route-guards" export const dynamic = "force-dynamic" type SearchParamsInput = Record type PageProps = { params: Promise<{ id: string }> searchParams: Promise } function readFirstValue(value: string | string[] | undefined): string | null { if (Array.isArray(value)) { return value[0] ?? null } return value ?? null } function readInputString(formData: FormData, field: string): string { const value = formData.get(field) return typeof value === "string" ? value.trim() : "" } function readNullableString(formData: FormData, field: string): string | null { const value = readInputString(formData, field) return value.length > 0 ? value : null } function redirectWithState(pageId: string, params: { notice?: string; error?: string }) { const query = new URLSearchParams() if (params.notice) { query.set("notice", params.notice) } if (params.error) { query.set("error", params.error) } const value = query.toString() redirect(value ? `/pages/${pageId}?${value}` : `/pages/${pageId}`) } export default async function PageEditorPage({ params, searchParams }: PageProps) { const role = await requirePermissionForRoute({ nextPath: "/pages", permission: "pages:read", scope: "team", }) const resolvedParams = await params const pageId = resolvedParams.id const [resolvedSearchParams, pageRecord] = await Promise.all([searchParams, getPageById(pageId)]) if (!pageRecord) { redirect("/pages?error=Page+not+found") } const page = pageRecord const notice = readFirstValue(resolvedSearchParams.notice) const error = readFirstValue(resolvedSearchParams.error) async function updatePageAction(formData: FormData) { "use server" await requirePermissionForRoute({ nextPath: "/pages", permission: "pages:write", scope: "team", }) try { await updatePage({ id: pageId, title: readInputString(formData, "title"), slug: readInputString(formData, "slug"), status: readInputString(formData, "status"), summary: readNullableString(formData, "summary"), content: readInputString(formData, "content"), seoTitle: readNullableString(formData, "seoTitle"), seoDescription: readNullableString(formData, "seoDescription"), }) } catch { redirectWithState(pageId, { error: "Failed to update page. Validate values and try again.", }) } redirectWithState(pageId, { notice: "Page updated.", }) } async function deletePageAction() { "use server" await requirePermissionForRoute({ nextPath: "/pages", permission: "pages:write", scope: "team", }) try { await deletePage(pageId) } catch { redirectWithState(pageId, { error: "Failed to delete page. Remove linked navigation references first.", }) } redirect("/pages?notice=Page+deleted") } return ( {notice ? (
{notice}
) : null} {error ? (
{error}
) : null}

{page.title}

ID: {page.id}

Back to pages