feat(templates): persist independent guide applications
This commit is contained in:
@@ -9,8 +9,11 @@ import {
|
||||
savePageDraft,
|
||||
} from "@/lib/content/mutations";
|
||||
import { dataSourceSnapshotSchema } from "@/lib/content/data-source";
|
||||
import { slugSchema } from "@/lib/content/lifecycle";
|
||||
import type { DataSourceSnapshot, PageSnapshot } from "@/lib/content/types";
|
||||
import { requireAdmin } from "@/lib/auth/server";
|
||||
import { builtInTemplates } from "@/lib/templates";
|
||||
import { persistTemplateApplication } from "@/lib/templates/persist";
|
||||
|
||||
const serializedBlockSchema = z.strictObject({
|
||||
id: z.string().uuid(),
|
||||
@@ -132,3 +135,56 @@ export async function createEditorRevision(
|
||||
const id = await createNamedRevision(parsed.data, safeLabel.data, admin.user.id);
|
||||
return id ? { status: "saved", id } : { status: "error" };
|
||||
}
|
||||
|
||||
const templateApplicationSchema = z.strictObject({
|
||||
templateSlug: z.string().min(1).max(120),
|
||||
characterSlug: slugSchema,
|
||||
nameTh: z.string().trim().min(1).max(160),
|
||||
nameEn: z.string().trim().max(160).optional(),
|
||||
description: z.string().trim().max(2_000).optional(),
|
||||
});
|
||||
|
||||
export async function applyEditorTemplate(input: unknown): Promise<
|
||||
| { status: "created"; location: string }
|
||||
| { status: "validation-error"; issues: string[] }
|
||||
| { status: "error"; message: string }
|
||||
> {
|
||||
const admin = await requireAdmin();
|
||||
const parsed = templateApplicationSchema.safeParse(input);
|
||||
if (!parsed.success) {
|
||||
return {
|
||||
status: "validation-error",
|
||||
issues: parsed.error.issues.map((issue) => issue.message),
|
||||
};
|
||||
}
|
||||
const template = builtInTemplates.find(
|
||||
(candidate) => candidate.slug === parsed.data.templateSlug,
|
||||
);
|
||||
if (!template) {
|
||||
return { status: "validation-error", issues: ["ไม่พบเทมเพลต"] };
|
||||
}
|
||||
if (process.env.BUZZ_DEMO_MODE === "true") {
|
||||
return { status: "created", location: "/admin/astra/info" };
|
||||
}
|
||||
try {
|
||||
const applied = await persistTemplateApplication(
|
||||
template,
|
||||
{
|
||||
slug: parsed.data.characterSlug,
|
||||
nameTh: parsed.data.nameTh,
|
||||
nameEn: parsed.data.nameEn,
|
||||
description: parsed.data.description,
|
||||
},
|
||||
admin.user.id,
|
||||
);
|
||||
return {
|
||||
status: "created",
|
||||
location: `/admin/${applied.characterSlug}/${applied.firstPageSlug}`,
|
||||
};
|
||||
} catch (cause) {
|
||||
return {
|
||||
status: "error",
|
||||
message: cause instanceof Error ? cause.message : "สร้างคู่มือไม่สำเร็จ",
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
import { redirect } from "next/navigation";
|
||||
import { connection } from "next/server";
|
||||
|
||||
import { AdminSidebar } from "@/components/admin/admin-sidebar";
|
||||
import { TemplateGallery } from "@/components/admin/template-gallery";
|
||||
import { SidebarInset, SidebarProvider, SidebarTrigger } from "@/components/ui/sidebar";
|
||||
import { getAdminSession } from "@/lib/auth/server";
|
||||
import { loadAdminNavigation } from "@/lib/content/loaders";
|
||||
import { builtInTemplates } from "@/lib/templates";
|
||||
|
||||
export default async function TemplatesPage() {
|
||||
await connection();
|
||||
if (!(await getAdminSession())) redirect("/admin/login");
|
||||
const navigation = await loadAdminNavigation();
|
||||
|
||||
return (
|
||||
<SidebarProvider>
|
||||
<AdminSidebar navigation={navigation} />
|
||||
<SidebarInset>
|
||||
<header className="flex min-h-14 items-center gap-3 border-b px-4">
|
||||
<SidebarTrigger />
|
||||
<div>
|
||||
<h1 className="font-heading font-semibold">เทมเพลตคู่มือ</h1>
|
||||
<p className="text-xs text-muted-foreground">โครงสร้างเริ่มต้นที่คัดมาจากรูปแบบคู่มือทั้งห้า</p>
|
||||
</div>
|
||||
</header>
|
||||
<main className="mx-auto w-full max-w-6xl p-4 sm:p-6 lg:p-8">
|
||||
<TemplateGallery templates={builtInTemplates} />
|
||||
</main>
|
||||
</SidebarInset>
|
||||
</SidebarProvider>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user