Initial commit: ANOUMA website with Payload CMS, WebRTC meetings, and booking system
- Next.js 16 App Router site with the ANOUMA design system - Payload CMS (PostgreSQL) for offers, events, posts and page content - WebRTC video-call system with custom signaling server - SMTP email reminders and booking-request notifications - Customer accounts, calendar-based availability, and booking workflow
This commit is contained in:
@@ -0,0 +1,92 @@
|
||||
/**
|
||||
* Minimal builders for Lexical's SerializedEditorState JSON — just enough to
|
||||
* seed richText fields from plain paragraph/heading strings (see lib/texte.ts).
|
||||
* Shape verified against node_modules/lexical's Serialized*Node types.
|
||||
*/
|
||||
|
||||
type TextNode = {
|
||||
type: "text";
|
||||
version: 1;
|
||||
text: string;
|
||||
format: 0;
|
||||
detail: 0;
|
||||
mode: "normal";
|
||||
style: "";
|
||||
};
|
||||
|
||||
type ParagraphNode = {
|
||||
type: "paragraph";
|
||||
version: 1;
|
||||
children: TextNode[];
|
||||
direction: "ltr";
|
||||
format: "";
|
||||
indent: 0;
|
||||
};
|
||||
|
||||
type HeadingNode = {
|
||||
type: "heading";
|
||||
tag: "h2" | "h3";
|
||||
version: 1;
|
||||
children: TextNode[];
|
||||
direction: "ltr";
|
||||
format: "";
|
||||
indent: 0;
|
||||
};
|
||||
|
||||
function textNode(text: string): TextNode {
|
||||
return { type: "text", version: 1, text, format: 0, detail: 0, mode: "normal", style: "" };
|
||||
}
|
||||
|
||||
function paragraphNode(text: string): ParagraphNode {
|
||||
return {
|
||||
type: "paragraph",
|
||||
version: 1,
|
||||
children: [textNode(text)],
|
||||
direction: "ltr",
|
||||
format: "",
|
||||
indent: 0,
|
||||
};
|
||||
}
|
||||
|
||||
function headingNode(text: string, tag: "h2" | "h3" = "h2"): HeadingNode {
|
||||
return {
|
||||
type: "heading",
|
||||
tag,
|
||||
version: 1,
|
||||
children: [textNode(text)],
|
||||
direction: "ltr",
|
||||
format: "",
|
||||
indent: 0,
|
||||
};
|
||||
}
|
||||
|
||||
function root(children: (ParagraphNode | HeadingNode)[]) {
|
||||
return {
|
||||
root: {
|
||||
type: "root",
|
||||
children,
|
||||
direction: "ltr" as const,
|
||||
format: "" as const,
|
||||
indent: 0,
|
||||
version: 1,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export function lexicalFromParagraphs(paragraphs: readonly string[]) {
|
||||
return root(paragraphs.map((p) => paragraphNode(p)));
|
||||
}
|
||||
|
||||
export function lexicalFromSections(
|
||||
intro: readonly string[],
|
||||
sections?: readonly { heading: string; paragraphs: readonly string[] }[],
|
||||
) {
|
||||
const children: (ParagraphNode | HeadingNode)[] = intro.map((p) => paragraphNode(p));
|
||||
if (sections) {
|
||||
for (const section of sections) {
|
||||
children.push(headingNode(section.heading));
|
||||
children.push(...section.paragraphs.map((p) => paragraphNode(p)));
|
||||
}
|
||||
}
|
||||
return root(children);
|
||||
}
|
||||
Reference in New Issue
Block a user