import { brandName } from "../lib/content" import type { FieldDef, ListFieldDef, SectionData, TemplateContent, TemplateDefinition } from "../lib/types" const clean = (value: string) => value.replace(/\*/g, "").replace(/\s*\n\s*/g, " · ").trim() type PageSection = { label: string; fields: (FieldDef | ListFieldDef)[]; data: SectionData | undefined; hidden: boolean } // Feste Sektionen der Vorlage und – im Baukasten – die Bausteine in ihrer Reihenfolge function pageSections(def: TemplateDefinition, content: TemplateContent): PageSection[] { const fixed = def.sections.map((section) => ({ label: section.label, fields: section.fields, data: content.data[section.key], hidden: content.hidden.includes(section.key), })) const library = new Map(def.builder?.library.map((block) => [block.type, block])) const blocks = content.blocks.flatMap((block) => { const definition = library.get(block.type) if (!definition) return [] const menu = typeof block.data.menu === "string" ? block.data.menu.trim() : "" return [{ label: menu || definition.label, fields: definition.fields, data: block.data, hidden: block.hidden }] }) return [...fixed, ...blocks] } export function businessName(def: TemplateDefinition, content: TemplateContent) { return brandName(content) ?? def.name } // Alles, was auf der Webseite steht, als Wissen für die KI – Bilder ausgenommen, ausgeblendete Sektionen auch export function buildKnowledge(def: TemplateDefinition, content: TemplateContent) { const parts = [`Betrieb: ${businessName(def, content)}`, `Branche: ${def.industry}`] for (const section of pageSections(def, content)) { const data = section.data if (!data || section.hidden) continue const lines: string[] = [] for (const field of section.fields) { const value = data[field.key] if (field.type === "list") { if (!Array.isArray(value)) continue const items = value .map((item) => field.fields .filter((sub) => sub.type !== "image" && item[sub.key]?.trim()) .map((sub) => `${sub.label}: ${clean(item[sub.key])}`) .join("; ") ) .filter(Boolean) if (items.length) lines.push(`${field.label}:\n${items.map((item) => `- ${item}`).join("\n")}`) } else if (field.type !== "image" && typeof value === "string" && value.trim()) { lines.push(`${field.label}: ${clean(value)}`) } } if (lines.length) parts.push(`\n## ${section.label}\n${lines.join("\n")}`) } if (content.ai.knowledge.trim()) parts.push(`\n## Zusatzwissen\n${content.ai.knowledge.trim()}`) return parts.join("\n") } // Bild-Links der Variante, z. B. für die Post-Vorschauen im Content-Generator export function collectImages(def: TemplateDefinition, content: TemplateContent) { const images: string[] = [] for (const section of pageSections(def, content)) { const data = section.data if (!data) continue for (const field of section.fields) { const value = data[field.key] if (field.type === "image" && typeof value === "string") images.push(value) if (field.type === "list" && Array.isArray(value)) { for (const sub of field.fields.filter((f) => f.type === "image")) { images.push(...value.map((item) => item[sub.key] ?? "")) } } } } return [...new Set(images.filter((src) => src.startsWith("http")))] }