/** * Seeds the CMS with the original ANOUMA content (the 7 offers from * texte.txt, plus starting text for every editable page). Safe to re-run — * offers are matched and updated by slug, globals are simply overwritten. * * Usage: npm run seed (requires DATABASE_URI + PAYLOAD_SECRET in .env) * * Deliberately does NOT create a Users document — the first admin account is * created through Payload's own "create first user" screen at /admin, so no * password is ever hardcoded here. */ import { getPayload } from "payload"; import config from "../payload.config"; import { prozessbegleitung, doula, erdenkinder, maedchenkreis, singenImKreis, singenFuerSchwangere, mamaBabySingkreis, ueberMich, } from "../lib/texte"; import { lexicalFromParagraphs, lexicalFromSections } from "./lexical"; async function seedOffers(payload: Awaited>) { const offers = [ { slug: "prozessbegleitung", title: "Prozessbegleitung", category: "prozessbegleitung" as const, order: 1, shortDescription: "Persönliche Begleitung in Lebensphasen, Veränderungen und inneren Prozessen.", description: lexicalFromSections(prozessbegleitung.intro, prozessbegleitung.sections), }, { slug: "doula-begleitung", title: "Doula-Begleitung", category: "doula-begleitung" as const, order: 2, shortDescription: "Begleitung vor, während und nach der Geburt.", description: lexicalFromSections(doula.intro, doula.sections), }, { slug: "erdenkinder", title: "Erdenkinder", category: "kindergruppen" as const, order: 3, shortDescription: "Naturverbunden. Kreativ. Frei. Für Kinder.", description: lexicalFromParagraphs(erdenkinder.paragraphs), }, { slug: "maedchenkreis", title: "Mädchenkreis", category: "kindergruppen" as const, order: 4, shortDescription: "Stärkung. Vertrauen. Gemeinschaft. Für Mädchen.", description: lexicalFromParagraphs(maedchenkreis.paragraphs), }, { slug: "singen-im-kreis", title: "Singen im Kreis", category: "singkreise" as const, order: 5, shortDescription: "Gemeinsam singen. Verbunden sein.", description: lexicalFromParagraphs(singenImKreis.paragraphs), }, { slug: "singen-fuer-schwangere", title: "Singen für Schwangere", category: "singkreise" as const, order: 6, shortDescription: "Lieder, die tragen. Für dich und dein Baby.", description: lexicalFromParagraphs(singenFuerSchwangere.paragraphs), }, { slug: "mama-baby-singkreis", title: "Singen für Mamas mit Baby", category: "singkreise" as const, order: 7, shortDescription: "Zeit für dich und dein Baby. Singen. Austauschen. Auftanken.", description: lexicalFromParagraphs(mamaBabySingkreis.paragraphs), }, { // A private, bookable single-session offer — not listed in the menu // or on /angebote (see `visibility`), reachable only via its direct // link or a booking Anna creates herself. Content reuses the // "Individuelle Begleitung" section of Prozessbegleitung, which is // exactly this kind of 1:1 session in the original texte.txt. slug: "einzelbegleitung", title: "Einzelbegleitung", category: "prozessbegleitung" as const, order: 8, visibility: "private" as const, bookable: true, price: "auf Anfrage", durationMinutes: 60, shortDescription: "Persönliche Einzelbegleitung — vor Ort oder online.", description: lexicalFromParagraphs(prozessbegleitung.sections[0].paragraphs), }, ]; for (const entry of offers) { const data = { visibility: "public" as const, ...entry }; const existing = await payload.find({ collection: "offers", where: { slug: { equals: data.slug } }, limit: 1, }); if (existing.docs[0]) { await payload.update({ collection: "offers", id: existing.docs[0].id, data, draft: false }); console.log(` ↺ Angebot aktualisiert: ${data.title}`); } else { await payload.create({ collection: "offers", data, draft: false }); console.log(` + Angebot angelegt: ${data.title}`); } } } async function seedGlobals(payload: Awaited>) { await payload.updateGlobal({ slug: "home", data: { heroEyebrow: "Prozessbegleitung · Doula · Gemeinschaft", heroTitle: "Willkommen bei Anouma", heroHighlight: ueberMich.closing.highlight, heroSupporting: ueberMich.closing.paragraph, aboutEyebrow: "Über mich", aboutTitle: "Mein Weg, meine Werte und was mich bewegt", aboutText: lexicalFromParagraphs(ueberMich.paragraphs.slice(0, 2)), valuesEyebrow: "Philosophie", valuesTitle: "Räume, in denen wir uns erinnern dürfen, wer wir sind", values: [ { title: "Vertrauen", quote: "Alles, was wir für unseren Weg brauchen, ist bereits in uns angelegt.", }, { title: "Verbindung", quote: "Räume für Verbindung — mit uns selbst, miteinander und mit der Natur.", }, { title: "Natur", quote: "Wir sind nicht nur in der Natur — wir sind ein Teil von ihr." }, ], ctaTitle: "Kennenlernen & Termine vereinbaren", ctaLead: "Ich freue mich, von dir zu hören — schreib mir oder buche direkt ein unverbindliches Kennenlerngespräch.", }, }); console.log(" ↺ Global „Startseite“ gesetzt"); await payload.updateGlobal({ slug: "about", data: { eyebrow: "Über mich", title: "Mein Weg, meine Werte und was mich bewegt", body: lexicalFromParagraphs(ueberMich.paragraphs), closingLead: ueberMich.closing.lead, closingHighlight: ueberMich.closing.highlight, closingParagraph: ueberMich.closing.paragraph, }, }); console.log(" ↺ Global „Über mich“ gesetzt"); await payload.updateGlobal({ slug: "angebote-intro", data: { title: "Angebote", lead: "Jeder Raum ist anders — und darf so genau das sein, was gerade gebraucht wird. Ein Überblick über meine Begleitung für Erwachsene, Kinder und Gemeinschaft.", }, }); console.log(" ↺ Global „Angebote (Einleitung)“ gesetzt"); await payload.updateGlobal({ slug: "aktuelles-intro", data: { eyebrow: "Aktuelles", title: "Neuigkeiten, Termine und Inspiration", lead: "Hier findest du künftig aktuelle Termine, Ankündigungen und Impulse rund um die Angebote von Anouma.", }, }); console.log(" ↺ Global „Aktuelles (Einleitung)“ gesetzt"); await payload.updateGlobal({ slug: "contact", data: { eyebrow: "Kontakt", title: "Ich freue mich, von dir zu hören", lead: "Ob Frage, Anliegen oder der Wunsch nach einem Kennenlerngespräch — schreib mir gerne.", // Placeholder contact details — replace with the real ones in the admin. email: "hallo@anouma.org", phone: "+49 000 00 00 00", region: "Platzhalter — Ort / Region", }, }); console.log(" ↺ Global „Kontakt“ gesetzt (mit Platzhalter-Kontaktdaten — bitte im Admin ersetzen)"); await payload.updateGlobal({ slug: "booking", data: { eyebrow: "Termin buchen", title: "Kennenlernen & Termine vereinbaren", lead: "Der erste Schritt ist oft der wichtigste. Melde dich gerne — unverbindlich und in deinem Tempo.", steps: [ { title: "Nachricht schreiben", text: "Schildere kurz dein Anliegen und welches Angebot dich interessiert — über das Formular unten oder direkt per E-Mail.", }, { title: "Kennenlernen", text: "In einem ersten, unverbindlichen Gespräch schauen wir gemeinsam, was du gerade brauchst und welcher Weg passt.", }, { title: "Termin vereinbaren", text: "Passt es für euch beide, vereinbaren wir gemeinsam die weiteren Termine.", }, ], formNote: "Aktuell öffnet dieses Formular dein E-Mail-Programm. Sobald ein Buchungstool (z. B. für Online-Terminvergabe) ausgewählt ist, kann es hier eingebunden werden.", }, }); console.log(" ↺ Global „Termin buchen“ gesetzt"); } async function run() { const payload = await getPayload({ config }); console.log("Angebote:"); await seedOffers(payload); console.log("Seiteninhalte:"); await seedGlobals(payload); console.log("\nFertig. Richte jetzt unter /admin den ersten Admin-Zugang ein (dort wird kein Passwort vorgegeben)."); process.exit(0); } run().catch((err) => { console.error(err); process.exit(1); });