"use client" import { type PageBlock, type PageBlocks, parsePageBlocks, serializePageBlocks } from "@cms/content" import { useMemo, useState } from "react" type PageBlockEditorProps = { name: string initialContent: string label?: string } function randomId(prefix: string): string { return `${prefix}-${Math.random().toString(36).slice(2, 10)}` } function normalizeInitialBlocks(initialContent: string): PageBlocks { if (!initialContent.trim()) { return [ { id: randomId("rich"), type: "rich_text", body: "", }, ] } try { return parsePageBlocks(initialContent) } catch { return [ { id: randomId("rich"), type: "rich_text", body: initialContent, }, ] } } function updateBlock(blocks: PageBlocks, blockId: string, next: Partial): PageBlocks { return blocks.map((block) => block.id === blockId ? ({ ...block, ...next } as PageBlock) : block, ) } export function PageBlockEditor({ name, initialContent, label = "Page Blocks", }: PageBlockEditorProps) { const [blocks, setBlocks] = useState(() => normalizeInitialBlocks(initialContent)) const serialized = useMemo(() => serializePageBlocks(blocks), [blocks]) function addBlock(type: PageBlock["type"]) { if (type === "hero") { setBlocks((prev) => [ ...prev, { id: randomId("hero"), type, heading: "Hero heading", subheading: null, ctaHref: null, ctaLabel: null, }, ]) return } if (type === "rich_text") { setBlocks((prev) => [...prev, { id: randomId("rich"), type, body: "" }]) return } if (type === "gallery") { setBlocks((prev) => [...prev, { id: randomId("gallery"), type, title: null, imageIds: [] }]) return } if (type === "cta") { setBlocks((prev) => [ ...prev, { id: randomId("cta"), type, label: "Open", href: "/", variant: "primary" }, ]) return } if (type === "form") { setBlocks((prev) => [ ...prev, { id: randomId("form"), type, formKey: "contact", title: null, description: null }, ]) return } setBlocks((prev) => [ ...prev, { id: randomId("price"), type: "price_cards", title: null, cards: [] }, ]) } return (
{label}
{blocks.map((block, index) => (
#{index + 1} {block.type}
{block.type === "hero" ? (
setBlocks((prev) => updateBlock(prev, block.id, { heading: event.target.value }), ) } placeholder="Heading" className="rounded border border-neutral-300 px-2 py-1 text-sm" /> setBlocks((prev) => updateBlock(prev, block.id, { subheading: event.target.value || null }), ) } placeholder="Subheading" className="rounded border border-neutral-300 px-2 py-1 text-sm" />
) : null} {block.type === "rich_text" ? (