mirror of
https://github.com/complexcaresolutions/cms.c2sgmbh.git
synced 2026-03-17 19:44:12 +00:00
- Add migration for BlogWoman page blocks (favorites-block, series-block, series-detail-block, featured-content-block) with all required columns - Add seed scripts for BlogWoman tenant creation with full content: - 10 pages (Startseite, Über mich, Newsletter, etc.) - 7 blog posts - 9 series (GRFI, Investment-Piece, Pleasure P&L, etc.) - 4 categories, 10 tags, 1 author - Navigation, social links, cookie configuration - Add Konzept-KI guide for AI-assisted tenant creation - Add BlogWoman tenant prompt template Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1480 lines
49 KiB
TypeScript
1480 lines
49 KiB
TypeScript
/**
|
||
* BlogWoman Tenant Seed Script
|
||
*
|
||
* Creates the BlogWoman tenant and populates it with all content
|
||
* as specified in the Blogwoman-tenant-prompt.md
|
||
*
|
||
* Run with: npx tsx scripts/seed-blogwoman.ts
|
||
*/
|
||
|
||
import { getPayload } from 'payload'
|
||
import config from '../src/payload.config'
|
||
|
||
// Helper to create Lexical Rich Text content
|
||
function createRichText(content: string | string[]): object {
|
||
const paragraphs = Array.isArray(content) ? content : [content]
|
||
return {
|
||
root: {
|
||
type: 'root',
|
||
children: paragraphs.map((text) => ({
|
||
type: 'paragraph',
|
||
children: [{ type: 'text', text }],
|
||
})),
|
||
direction: 'ltr',
|
||
format: '',
|
||
indent: 0,
|
||
version: 1,
|
||
},
|
||
}
|
||
}
|
||
|
||
function createRichTextWithHeading(heading: string, paragraphs: string[]): object {
|
||
return {
|
||
root: {
|
||
type: 'root',
|
||
children: [
|
||
{
|
||
type: 'heading',
|
||
tag: 'h2',
|
||
children: [{ type: 'text', text: heading }],
|
||
},
|
||
...paragraphs.map((text) => ({
|
||
type: 'paragraph',
|
||
children: [{ type: 'text', text }],
|
||
})),
|
||
],
|
||
direction: 'ltr',
|
||
format: '',
|
||
indent: 0,
|
||
version: 1,
|
||
},
|
||
}
|
||
}
|
||
|
||
function createRichTextWithBullets(heading: string, intro: string, bullets: string[]): object {
|
||
return {
|
||
root: {
|
||
type: 'root',
|
||
children: [
|
||
{
|
||
type: 'heading',
|
||
tag: 'h2',
|
||
children: [{ type: 'text', text: heading }],
|
||
},
|
||
{
|
||
type: 'paragraph',
|
||
children: [{ type: 'text', text: intro }],
|
||
},
|
||
{
|
||
type: 'list',
|
||
listType: 'bullet',
|
||
children: bullets.map((b) => ({
|
||
type: 'listitem',
|
||
children: [{ type: 'text', text: b }],
|
||
})),
|
||
},
|
||
],
|
||
direction: 'ltr',
|
||
format: '',
|
||
indent: 0,
|
||
version: 1,
|
||
},
|
||
}
|
||
}
|
||
|
||
async function seed() {
|
||
console.log('🚀 Starting BlogWoman Tenant Seed...\n')
|
||
|
||
const payload = await getPayload({ config })
|
||
|
||
// ============================================
|
||
// 1. CREATE TENANT
|
||
// ============================================
|
||
console.log('--- 1. Creating Tenant ---')
|
||
|
||
let tenantId: number
|
||
|
||
const existingTenant = await payload.find({
|
||
collection: 'tenants',
|
||
where: { slug: { equals: 'blogwoman' } },
|
||
})
|
||
|
||
if (existingTenant.docs.length > 0) {
|
||
tenantId = existingTenant.docs[0].id as number
|
||
console.log(`✓ Tenant "blogwoman" already exists (ID: ${tenantId})`)
|
||
} else {
|
||
const tenant = await payload.create({
|
||
collection: 'tenants',
|
||
data: {
|
||
name: 'BlogWoman',
|
||
slug: 'blogwoman',
|
||
domains: [{ domain: 'blogwoman.de' }, { domain: 'www.blogwoman.de' }],
|
||
email: {
|
||
fromAddress: 'hello@blogwoman.de',
|
||
fromName: 'BlogWoman',
|
||
replyTo: 'caroline@blogwoman.de',
|
||
useCustomSmtp: false,
|
||
},
|
||
},
|
||
})
|
||
tenantId = tenant.id as number
|
||
console.log(`✓ Created tenant "BlogWoman" (ID: ${tenantId})`)
|
||
}
|
||
|
||
// ============================================
|
||
// 2. CREATE SITE-SETTINGS
|
||
// ============================================
|
||
console.log('\n--- 2. Creating Site Settings ---')
|
||
|
||
const existingSiteSettings = await payload.find({
|
||
collection: 'site-settings',
|
||
where: { tenant: { equals: tenantId } },
|
||
})
|
||
|
||
if (existingSiteSettings.docs.length > 0) {
|
||
await payload.update({
|
||
collection: 'site-settings',
|
||
id: existingSiteSettings.docs[0].id,
|
||
data: {
|
||
siteName: 'BlogWoman',
|
||
siteTagline: 'Für Frauen, die Karriere, Familie & Stil ernst nehmen.',
|
||
contact: {
|
||
email: 'hello@blogwoman.de',
|
||
},
|
||
footer: {
|
||
copyrightText: '© 2025 Complex Care Solutions GmbH',
|
||
showSocialLinks: true,
|
||
},
|
||
seo: {
|
||
defaultMetaTitle: 'BlogWoman – Karriere, Familie & Stil mit System',
|
||
defaultMetaDescription:
|
||
'Für Frauen, die Karriere, Familie und Stil ernst nehmen. Systeme statt Motivation. Von Dr. Caroline Porwoll.',
|
||
},
|
||
tenant: tenantId,
|
||
} as any,
|
||
})
|
||
console.log('✓ Updated Site Settings')
|
||
} else {
|
||
await payload.create({
|
||
collection: 'site-settings',
|
||
data: {
|
||
siteName: 'BlogWoman',
|
||
siteTagline: 'Für Frauen, die Karriere, Familie & Stil ernst nehmen.',
|
||
contact: {
|
||
email: 'hello@blogwoman.de',
|
||
},
|
||
footer: {
|
||
copyrightText: '© 2025 Complex Care Solutions GmbH',
|
||
showSocialLinks: true,
|
||
},
|
||
seo: {
|
||
defaultMetaTitle: 'BlogWoman – Karriere, Familie & Stil mit System',
|
||
defaultMetaDescription:
|
||
'Für Frauen, die Karriere, Familie und Stil ernst nehmen. Systeme statt Motivation. Von Dr. Caroline Porwoll.',
|
||
},
|
||
tenant: tenantId,
|
||
} as any,
|
||
})
|
||
console.log('✓ Created Site Settings')
|
||
}
|
||
|
||
// ============================================
|
||
// 3. CREATE CATEGORIES
|
||
// ============================================
|
||
console.log('\n--- 3. Creating Categories ---')
|
||
|
||
const categories = [
|
||
{
|
||
name: 'Stil & Wirkung',
|
||
slug: 'stil-wirkung',
|
||
description: 'GRFI, Investment-Pieces, Capsule Wardrobe, Business-Looks',
|
||
},
|
||
{
|
||
name: 'Systeme & Entscheidungen',
|
||
slug: 'systeme-entscheidungen',
|
||
description: 'Decision-Proof, Routinen, Delegation, Zeitmanagement',
|
||
},
|
||
{
|
||
name: 'Regeneration & Energie',
|
||
slug: 'regeneration-energie',
|
||
description: 'Reset-Routinen, Schlaf, Energie-Management, Selfcare',
|
||
},
|
||
{
|
||
name: 'Karriere x Familie',
|
||
slug: 'karriere-familie',
|
||
description: 'Backstage, Real Talk, Vereinbarkeit, Working Mom',
|
||
},
|
||
]
|
||
|
||
const categoryIds: Record<string, number> = {}
|
||
|
||
for (const cat of categories) {
|
||
const existing = await payload.find({
|
||
collection: 'categories',
|
||
where: {
|
||
and: [{ slug: { equals: cat.slug } }, { tenant: { equals: tenantId } }],
|
||
},
|
||
})
|
||
|
||
if (existing.docs.length > 0) {
|
||
categoryIds[cat.slug] = existing.docs[0].id as number
|
||
console.log(`- Category "${cat.name}" already exists`)
|
||
} else {
|
||
const created = await payload.create({
|
||
collection: 'categories',
|
||
data: {
|
||
...cat,
|
||
tenant: tenantId,
|
||
} as any,
|
||
})
|
||
categoryIds[cat.slug] = created.id as number
|
||
console.log(`✓ Created category: ${cat.name}`)
|
||
}
|
||
}
|
||
|
||
// ============================================
|
||
// 4. CREATE TAGS
|
||
// ============================================
|
||
console.log('\n--- 4. Creating Tags ---')
|
||
|
||
const tags = [
|
||
{ name: 'GRFI', slug: 'grfi', color: '#B08D57' },
|
||
{ name: 'Investment-Piece', slug: 'investment-piece', color: '#2B2520' },
|
||
{ name: 'Capsule-Wardrobe', slug: 'capsule-wardrobe', color: '#C6A47E' },
|
||
{ name: 'Morgenroutine', slug: 'morgenroutine', color: '#7BA08A' },
|
||
{ name: 'Zeitmanagement', slug: 'zeitmanagement', color: '#4A5568' },
|
||
{ name: 'Business-Outfit', slug: 'business-outfit', color: '#B08D57' },
|
||
{ name: 'Selfcare', slug: 'selfcare', color: '#D4A5A5' },
|
||
{ name: 'Working-Mom', slug: 'working-mom', color: '#6B1F2B' },
|
||
{ name: 'Entscheidungen', slug: 'entscheidungen', color: '#4A5568' },
|
||
{ name: 'Regeneration', slug: 'regeneration', color: '#7BA08A' },
|
||
]
|
||
|
||
const tagIds: Record<string, number> = {}
|
||
|
||
for (const tag of tags) {
|
||
const existing = await payload.find({
|
||
collection: 'tags',
|
||
where: {
|
||
and: [{ slug: { equals: tag.slug } }, { tenant: { equals: tenantId } }],
|
||
},
|
||
})
|
||
|
||
if (existing.docs.length > 0) {
|
||
tagIds[tag.slug] = existing.docs[0].id as number
|
||
console.log(`- Tag "${tag.name}" already exists`)
|
||
} else {
|
||
const created = await payload.create({
|
||
collection: 'tags',
|
||
data: {
|
||
...tag,
|
||
tenant: tenantId,
|
||
} as any,
|
||
})
|
||
tagIds[tag.slug] = created.id as number
|
||
console.log(`✓ Created tag: ${tag.name}`)
|
||
}
|
||
}
|
||
|
||
// ============================================
|
||
// 5. CREATE AUTHOR
|
||
// ============================================
|
||
console.log('\n--- 5. Creating Author ---')
|
||
|
||
let authorId: number
|
||
|
||
const existingAuthor = await payload.find({
|
||
collection: 'authors',
|
||
where: {
|
||
and: [{ slug: { equals: 'dr-caroline-porwoll' } }, { tenant: { equals: tenantId } }],
|
||
},
|
||
})
|
||
|
||
if (existingAuthor.docs.length > 0) {
|
||
authorId = existingAuthor.docs[0].id as number
|
||
console.log('- Author "Dr. Caroline Porwoll" already exists')
|
||
} else {
|
||
const author = await payload.create({
|
||
collection: 'authors',
|
||
data: {
|
||
name: 'Dr. Caroline Porwoll',
|
||
slug: 'dr-caroline-porwoll',
|
||
title: 'Gründerin & Host',
|
||
bioShort:
|
||
'Unternehmerin. Mutter. Systemdenkerin. Caroline ist promovierte Wirtschaftswissenschaftlerin, Geschäftsführerin der Complex Care Solutions GmbH und die Stimme hinter BlogWoman.',
|
||
bio: createRichText([
|
||
'Unternehmerin. Mutter. Systemdenkerin.',
|
||
'Caroline ist promovierte Wirtschaftswissenschaftlerin, Geschäftsführerin der Complex Care Solutions GmbH und die Stimme hinter BlogWoman.',
|
||
'Sie entwickelt Systeme, die Karriere und Familie verbinden – ohne Kompromisse bei beidem.',
|
||
]),
|
||
social: {
|
||
instagram: 'blogwoman.de',
|
||
},
|
||
website: 'https://youtube.com/@blogwoman',
|
||
isActive: true,
|
||
featured: true,
|
||
tenant: tenantId,
|
||
} as any,
|
||
})
|
||
authorId = author.id as number
|
||
console.log('✓ Created author: Dr. Caroline Porwoll')
|
||
}
|
||
|
||
// ============================================
|
||
// 6. CREATE SERIES
|
||
// ============================================
|
||
console.log('\n--- 6. Creating Series ---')
|
||
|
||
const seriesData = [
|
||
{
|
||
title: 'GRFI – Get Ready For Impact',
|
||
slug: 'grfi',
|
||
tagline: 'In 7-10 Minuten vom Alltag zur Präsenz.',
|
||
description: createRichText(
|
||
'In 7-10 Minuten vom Alltag zur Präsenz. Outfit. Grooming. Haltung. Mit System.'
|
||
),
|
||
brandColor: '#B08D57',
|
||
order: 1,
|
||
},
|
||
{
|
||
title: 'Investment-Piece',
|
||
slug: 'investment-piece',
|
||
tagline: '1 Teil, 3 Looks, 1 ehrliche Rechnung.',
|
||
description: createRichText(
|
||
'1 Teil, 3 Looks, 1 ehrliche Rechnung. Qualität über Quantität – mit CPW-Analyse.'
|
||
),
|
||
brandColor: '#2B2520',
|
||
order: 2,
|
||
},
|
||
{
|
||
title: 'Pleasure P&L',
|
||
slug: 'pleasure-pl',
|
||
tagline: 'Gönnen mit ROI.',
|
||
description: createRichText(
|
||
'Gönnen mit ROI. Die Gewinn-und-Verlust-Rechnung für Genuss-Momente.'
|
||
),
|
||
brandColor: '#6B1F2B',
|
||
order: 3,
|
||
},
|
||
{
|
||
title: 'Regeneration',
|
||
slug: 'regeneration',
|
||
tagline: '20-Minuten-Resets für Körper und Kopf.',
|
||
description: createRichText('20-Minuten-Resets für Körper und Kopf. Energie ist Strategie.'),
|
||
brandColor: '#7BA08A',
|
||
order: 4,
|
||
},
|
||
{
|
||
title: 'SPARK',
|
||
slug: 'spark',
|
||
tagline: 'Flamme zurückholen.',
|
||
description: createRichText('Flamme zurückholen. Für die Momente, wenn alles zu viel wird.'),
|
||
brandColor: '#D4A5A5',
|
||
order: 5,
|
||
},
|
||
{
|
||
title: 'Inner Circle',
|
||
slug: 'inner-circle',
|
||
tagline: 'Interviews mit inspirierenden Frauen.',
|
||
description: createRichText(
|
||
'Interviews mit Frauen, die Karriere, Familie und Stil leben.'
|
||
),
|
||
brandColor: '#C6A47E',
|
||
order: 6,
|
||
},
|
||
{
|
||
title: 'M2M – Meeting to Mama',
|
||
slug: 'm2m',
|
||
tagline: 'Der Übergang von Business zu Familie.',
|
||
description: createRichText(
|
||
'Der Übergang von Business zu Familie. Praktische Tipps für den Switch.'
|
||
),
|
||
brandColor: '#8B7355',
|
||
order: 7,
|
||
},
|
||
{
|
||
title: 'Decision-Proof',
|
||
slug: 'decision-proof',
|
||
tagline: 'Regeln schlagen Denken.',
|
||
description: createRichText(
|
||
'Regeln schlagen Denken. Systeme für bessere Entscheidungen mit weniger Aufwand.'
|
||
),
|
||
brandColor: '#4A5568',
|
||
order: 8,
|
||
},
|
||
{
|
||
title: 'Backstage',
|
||
slug: 'backstage',
|
||
tagline: 'Ein Tag, real.',
|
||
description: createRichText(
|
||
"Ein Tag, real. Keine Filter, keine Perfektion – so sieht's wirklich aus."
|
||
),
|
||
brandColor: '#718096',
|
||
order: 9,
|
||
},
|
||
]
|
||
|
||
const seriesIds: Record<string, number> = {}
|
||
|
||
for (const series of seriesData) {
|
||
const existing = await payload.find({
|
||
collection: 'series',
|
||
where: {
|
||
and: [{ slug: { equals: series.slug } }, { tenant: { equals: tenantId } }],
|
||
},
|
||
})
|
||
|
||
if (existing.docs.length > 0) {
|
||
seriesIds[series.slug] = existing.docs[0].id as number
|
||
console.log(`- Series "${series.title}" already exists`)
|
||
} else {
|
||
const created = await payload.create({
|
||
collection: 'series',
|
||
data: {
|
||
...series,
|
||
isActive: true,
|
||
tenant: tenantId,
|
||
} as any,
|
||
})
|
||
seriesIds[series.slug] = created.id as number
|
||
console.log(`✓ Created series: ${series.title}`)
|
||
}
|
||
}
|
||
|
||
// ============================================
|
||
// 7. CREATE FAVORITES
|
||
// ============================================
|
||
console.log('\n--- 7. Creating Favorites ---')
|
||
|
||
const favoritesData = [
|
||
{
|
||
title: 'Der Blazer, der alles mitmacht',
|
||
slug: 'blazer-klassiker',
|
||
description:
|
||
'Den Blazer trage ich seit 4 Jahren zu allem – Board, Office, Elternabend. Mein CPW liegt bei unter 5€.',
|
||
category: 'fashion',
|
||
badge: 'investment-piece',
|
||
price: 350,
|
||
priceRange: 'premium',
|
||
affiliateUrl: 'https://example.com/blazer',
|
||
order: 1,
|
||
},
|
||
{
|
||
title: 'Weiße Bluse (mein Klassiker)',
|
||
slug: 'weisse-bluse',
|
||
description: 'Besitze 3 Stück davon. Waschen, trocknen, fertig. Nie wieder Bügeln.',
|
||
category: 'fashion',
|
||
badge: 'daily-driver',
|
||
price: 120,
|
||
priceRange: 'mid',
|
||
affiliateUrl: 'https://example.com/bluse',
|
||
order: 2,
|
||
},
|
||
{
|
||
title: 'Die Tasche für alles',
|
||
slug: 'business-tasche',
|
||
description:
|
||
'Laptop, Wickelunterlage, Snacks – passt alles rein. Und sieht trotzdem aus wie eine Business-Tasche.',
|
||
category: 'fashion',
|
||
badge: 'grfi-approved',
|
||
price: 890,
|
||
priceRange: 'luxury',
|
||
affiliateUrl: 'https://example.com/tasche',
|
||
order: 3,
|
||
},
|
||
{
|
||
title: '2-Minuten Foundation',
|
||
slug: 'grfi-foundation',
|
||
description: 'Sieht nach 8 Stunden Schlaf aus, braucht aber nur 30 Sekunden.',
|
||
category: 'beauty',
|
||
badge: 'grfi-approved',
|
||
price: 45,
|
||
priceRange: 'mid',
|
||
affiliateUrl: 'https://example.com/foundation',
|
||
order: 1,
|
||
},
|
||
{
|
||
title: 'Power-Lippenstift',
|
||
slug: 'power-lippenstift',
|
||
description: 'Mein Geheim-Weapon für wichtige Termine. Verwandelt jedes Outfit.',
|
||
category: 'beauty',
|
||
badge: 'investment-piece',
|
||
price: 35,
|
||
priceRange: 'mid',
|
||
affiliateUrl: 'https://example.com/lippenstift',
|
||
order: 2,
|
||
},
|
||
{
|
||
title: 'Die Kalender-App, die alles zusammenführt',
|
||
slug: 'kalender-app',
|
||
description: 'Familie und Business in einem Kalender. Game-Changer.',
|
||
category: 'tech',
|
||
badge: 'daily-driver',
|
||
price: 0,
|
||
priceRange: 'budget',
|
||
affiliateUrl: 'https://example.com/kalender',
|
||
order: 1,
|
||
},
|
||
{
|
||
title: 'Meine Fokus-Zone',
|
||
slug: 'noise-cancelling-kopfhoerer',
|
||
description:
|
||
'Für Flüge, Home-Office mit Kindern im Haus, oder einfach 30 Minuten Ruhe.',
|
||
category: 'tech',
|
||
badge: 'investment-piece',
|
||
price: 380,
|
||
priceRange: 'premium',
|
||
affiliateUrl: 'https://example.com/kopfhoerer',
|
||
order: 2,
|
||
},
|
||
]
|
||
|
||
for (const fav of favoritesData) {
|
||
const existing = await payload.find({
|
||
collection: 'favorites',
|
||
where: {
|
||
and: [{ slug: { equals: fav.slug } }, { tenant: { equals: tenantId } }],
|
||
},
|
||
})
|
||
|
||
if (existing.docs.length > 0) {
|
||
console.log(`- Favorite "${fav.title}" already exists`)
|
||
} else {
|
||
await payload.create({
|
||
collection: 'favorites',
|
||
data: {
|
||
...fav,
|
||
isActive: true,
|
||
featured: fav.badge === 'investment-piece',
|
||
tenant: tenantId,
|
||
} as any,
|
||
})
|
||
console.log(`✓ Created favorite: ${fav.title}`)
|
||
}
|
||
}
|
||
|
||
// ============================================
|
||
// 8. CREATE PAGES
|
||
// ============================================
|
||
console.log('\n--- 8. Creating Pages ---')
|
||
|
||
const pages = [
|
||
// HOME PAGE
|
||
{
|
||
title: 'Startseite',
|
||
slug: 'home',
|
||
status: 'published',
|
||
hero: {
|
||
headline: 'BLOGWOMAN',
|
||
subline: 'Für Frauen, die Karriere, Familie & Stil ernst nehmen.',
|
||
},
|
||
layout: [
|
||
{
|
||
blockType: 'hero-block',
|
||
headline: 'BLOGWOMAN',
|
||
subline: 'Für Frauen, die Karriere, Familie & Stil ernst nehmen.',
|
||
alignment: 'center',
|
||
overlay: true,
|
||
overlayOpacity: 0.4,
|
||
cta: {
|
||
text: 'Newsletter',
|
||
link: '/newsletter',
|
||
style: 'primary',
|
||
},
|
||
},
|
||
{
|
||
blockType: 'image-text-block',
|
||
headline: 'Dr. Caroline Porwoll',
|
||
imagePosition: 'left',
|
||
content: createRichText([
|
||
'Unternehmerin. Mutter. Systemdenkerin.',
|
||
'Ich glaube nicht an Work-Life-Balance – ich glaube an Systeme, die beides möglich machen.',
|
||
]),
|
||
cta: {
|
||
text: 'Mehr erfahren →',
|
||
link: '/caroline',
|
||
},
|
||
},
|
||
{
|
||
blockType: 'posts-list-block',
|
||
headline: 'Aus dem Blog',
|
||
limit: 3,
|
||
showPagination: false,
|
||
},
|
||
{
|
||
blockType: 'newsletter-block',
|
||
headline: 'Der BlogWoman Brief',
|
||
description: 'Jeden Dienstag in deinem Postfach.',
|
||
buttonText: 'ANMELDEN',
|
||
privacyText: 'Kein Spam. Jederzeit abmelden.',
|
||
},
|
||
],
|
||
seo: {
|
||
metaTitle: 'BlogWoman – Karriere, Familie & Stil mit System',
|
||
metaDescription:
|
||
'Für Frauen, die Karriere, Familie und Stil ernst nehmen. Systeme statt Motivation. Von Dr. Caroline Porwoll.',
|
||
},
|
||
},
|
||
// ABOUT PAGE
|
||
{
|
||
title: 'Über mich',
|
||
slug: 'caroline',
|
||
status: 'published',
|
||
hero: {
|
||
headline: 'Dr. Caroline Porwoll',
|
||
subline: 'Unternehmerin. Mutter. Die Frau hinter BlogWoman.',
|
||
},
|
||
layout: [
|
||
{
|
||
blockType: 'hero-block',
|
||
headline: 'Dr. Caroline Porwoll',
|
||
subline: 'Unternehmerin. Mutter. Die Frau hinter BlogWoman.',
|
||
alignment: 'center',
|
||
overlay: true,
|
||
},
|
||
{
|
||
blockType: 'text-block',
|
||
width: 'medium',
|
||
content: createRichTextWithHeading('In 30 Sekunden:', [
|
||
'• Promovierte Wirtschaftswissenschaftlerin',
|
||
'• Gründerin & Geschäftsführerin der Complex Care Solutions GmbH',
|
||
'• Mutter',
|
||
'• 15+ Jahre Erfahrung in Unternehmensführung',
|
||
'• Entwicklerin von Systemen, die Karriere und Familie verbinden',
|
||
'',
|
||
'BlogWoman ist das, was ich mir selbst gewünscht hätte – als ich versuchte, alles unter einen Hut zu bekommen.',
|
||
]),
|
||
},
|
||
{
|
||
blockType: 'text-block',
|
||
width: 'medium',
|
||
content: createRichTextWithHeading('Es gab diesen Moment', [
|
||
'Ich stand vor dem Kleiderschrank, hatte ein wichtiges Board-Meeting in 45 Minuten, ein Kind mit Fieber zuhause, und absolut keine Ahnung, was ich anziehen sollte.',
|
||
'Nicht weil ich nichts hatte. Sondern weil ich kein System hatte.',
|
||
'In diesem Moment wurde mir klar: Ich brauche keine Motivation. Ich brauche keine Inspiration. Ich brauche Strukturen, die funktionieren – auch wenn ich nicht funktioniere.',
|
||
]),
|
||
},
|
||
{
|
||
blockType: 'text-block',
|
||
width: 'medium',
|
||
content: createRichTextWithHeading('Wofür ich stehe', [
|
||
'→ System schlägt Motivation – Willenskraft ist endlich. Gute Systeme nicht.',
|
||
'→ Investment statt Konsum – Ob Blazer oder Spa-Tag: Ich rechne den ROI.',
|
||
'→ Energie ist Strategie – Regeneration ist keine Belohnung. Sie ist die Voraussetzung.',
|
||
'→ Weniger, aber besser – Qualität über Quantität. In allem.',
|
||
'→ Ehrlichkeit über Perfektion – Ich zeige, was funktioniert – und was nicht.',
|
||
]),
|
||
},
|
||
{
|
||
blockType: 'text-block',
|
||
width: 'medium',
|
||
content: createRichTextWithHeading('Was du hier NICHT findest', [
|
||
'✗ Keine „Manifestiere dein bestes Selbst"-Sprüche',
|
||
'✗ Keine unrealistischen 5-Uhr-Morgenroutinen',
|
||
'✗ Keine Detox-Wunder oder Trend-Diäten',
|
||
'✗ Keine Fast-Fashion-Hauls',
|
||
'✗ Kein Mom-Shaming oder Karriere-Bashing',
|
||
'',
|
||
'Ich glaube daran, dass beides geht. Und ich zeige dir, wie.',
|
||
]),
|
||
},
|
||
{
|
||
blockType: 'cta-block',
|
||
headline: 'Lass uns verbunden bleiben',
|
||
backgroundColor: 'dark',
|
||
buttons: [
|
||
{ text: 'YouTube abonnieren', link: 'https://youtube.com/@blogwoman', style: 'primary' },
|
||
{ text: 'Newsletter anmelden', link: '/newsletter', style: 'secondary' },
|
||
],
|
||
},
|
||
],
|
||
seo: {
|
||
metaTitle: 'Über Caroline | BlogWoman',
|
||
metaDescription:
|
||
'Dr. Caroline Porwoll – Unternehmerin, Mutter, Gründerin von BlogWoman. Die Geschichte hinter den Systemen.',
|
||
},
|
||
},
|
||
// NEWSLETTER PAGE
|
||
{
|
||
title: 'Newsletter',
|
||
slug: 'newsletter',
|
||
status: 'published',
|
||
hero: {
|
||
headline: 'Der BlogWoman Brief',
|
||
subline: 'Performance & Pleasure für Karriere, Familie & Stil.',
|
||
},
|
||
layout: [
|
||
{
|
||
blockType: 'hero-block',
|
||
headline: 'Der BlogWoman Brief',
|
||
subline: 'Performance & Pleasure für Karriere, Familie & Stil. Jeden Dienstag direkt in dein Postfach.',
|
||
alignment: 'center',
|
||
},
|
||
{
|
||
blockType: 'newsletter-block',
|
||
headline: 'Jetzt anmelden',
|
||
description:
|
||
'☑ GRFI-Checkliste (PDF) ☑ 30-Teile Capsule Wardrobe Liste ☑ Pleasure P&L Template',
|
||
buttonText: 'ANMELDEN',
|
||
},
|
||
{
|
||
blockType: 'text-block',
|
||
width: 'medium',
|
||
content: createRichTextWithHeading('Jeden Dienstag in deinem Postfach:', [
|
||
'→ The Impact Move – 1 Mini-Tipp, sofort umsetzbar. Keine Theorie.',
|
||
'→ Video Recap – Was diese Woche auf YouTube lief – falls du\'s verpasst hast.',
|
||
'→ P&L Pick – 1 Produkt-Empfehlung mit meiner ehrlichen Rechnung.',
|
||
'→ Backstage Note – 3 Sätze aus meinem echten Leben. Kein Hochglanz.',
|
||
]),
|
||
},
|
||
{
|
||
blockType: 'text-block',
|
||
width: 'narrow',
|
||
content: createRichText([
|
||
'„Kein Spam. Kein Clickbait. Jederzeit abmelden."',
|
||
'Schon dabei: Frauen, die Karriere, Familie & Stil ernst nehmen.',
|
||
]),
|
||
},
|
||
],
|
||
seo: {
|
||
metaTitle: 'Der BlogWoman Brief | Newsletter',
|
||
metaDescription:
|
||
'Performance & Pleasure für Karriere, Familie & Stil. Jeden Dienstag direkt in dein Postfach. Plus: Kostenlose Downloads.',
|
||
},
|
||
},
|
||
// FAVORITEN PAGE
|
||
{
|
||
title: 'Favoriten',
|
||
slug: 'favoriten',
|
||
status: 'published',
|
||
hero: {
|
||
headline: 'Meine Favoriten & Tools',
|
||
subline: 'Die Dinge, die ich wirklich nutze – mit der Rechnung, warum.',
|
||
},
|
||
layout: [
|
||
{
|
||
blockType: 'hero-block',
|
||
headline: 'Meine Favoriten & Tools',
|
||
subline: 'Die Dinge, die ich wirklich nutze – mit der Rechnung, warum. Kuratiert, nicht gesponsert.',
|
||
alignment: 'center',
|
||
},
|
||
{
|
||
blockType: 'text-block',
|
||
width: 'narrow',
|
||
content: createRichText(
|
||
'Transparenz: Diese Seite enthält Affiliate-Links*. Für dich keine Mehrkosten. Mehr dazu: /transparenz'
|
||
),
|
||
},
|
||
{
|
||
blockType: 'favorites-block',
|
||
headline: 'Fashion',
|
||
category: 'fashion',
|
||
layout: 'grid',
|
||
},
|
||
{
|
||
blockType: 'favorites-block',
|
||
headline: 'Beauty',
|
||
category: 'beauty',
|
||
layout: 'grid',
|
||
},
|
||
{
|
||
blockType: 'favorites-block',
|
||
headline: 'Tech',
|
||
category: 'tech',
|
||
layout: 'grid',
|
||
},
|
||
],
|
||
seo: {
|
||
metaTitle: 'Meine Favoriten & Tools | BlogWoman',
|
||
metaDescription:
|
||
'Die Dinge, die ich wirklich nutze – mit der Rechnung, warum. Kuratiert, nicht gesponsert.',
|
||
},
|
||
},
|
||
// SERIEN PAGE
|
||
{
|
||
title: 'Serien',
|
||
slug: 'serien',
|
||
status: 'published',
|
||
hero: {
|
||
headline: 'Die BlogWoman Serien',
|
||
subline: 'Wiederkehrende Formate für wiederkehrende Herausforderungen.',
|
||
},
|
||
layout: [
|
||
{
|
||
blockType: 'hero-block',
|
||
headline: 'Die BlogWoman Serien',
|
||
subline:
|
||
'Wiederkehrende Formate für wiederkehrende Herausforderungen. Jede Serie löst ein konkretes Problem – mit System.',
|
||
alignment: 'center',
|
||
},
|
||
{
|
||
blockType: 'series-block',
|
||
headline: 'Alle Serien',
|
||
layout: 'grid',
|
||
showDescription: true,
|
||
},
|
||
],
|
||
seo: {
|
||
metaTitle: 'Die BlogWoman Serien | YouTube',
|
||
metaDescription:
|
||
'Wiederkehrende Formate für wiederkehrende Herausforderungen. GRFI, Investment-Piece, P&L und mehr.',
|
||
},
|
||
},
|
||
// BLOG PAGE
|
||
{
|
||
title: 'Blog',
|
||
slug: 'blog',
|
||
status: 'published',
|
||
hero: {
|
||
headline: 'Der BlogWoman Blog',
|
||
subline: 'Systeme für Karriere, Familie & Stil.',
|
||
},
|
||
layout: [
|
||
{
|
||
blockType: 'hero-block',
|
||
headline: 'Der BlogWoman Blog',
|
||
subline: 'Systeme für Karriere, Familie & Stil. Kein Fluff. Kein Clickbait. Nur das, was funktioniert.',
|
||
alignment: 'center',
|
||
},
|
||
{
|
||
blockType: 'posts-list-block',
|
||
headline: 'Alle Artikel',
|
||
limit: 12,
|
||
showPagination: true,
|
||
},
|
||
],
|
||
seo: {
|
||
metaTitle: 'Der BlogWoman Blog | Karriere, Familie & Stil',
|
||
metaDescription:
|
||
'Systeme für Karriere, Familie & Stil. Kein Fluff. Kein Clickbait. Nur das, was funktioniert.',
|
||
},
|
||
},
|
||
// KOOPERATIONEN PAGE
|
||
{
|
||
title: 'Kooperationen',
|
||
slug: 'kooperationen',
|
||
status: 'published',
|
||
hero: {
|
||
headline: 'Kooperationen mit BlogWoman',
|
||
subline: 'Für Marken, die Frauen mit Anspruch erreichen wollen.',
|
||
},
|
||
layout: [
|
||
{
|
||
blockType: 'hero-block',
|
||
headline: 'Kooperationen mit BlogWoman',
|
||
subline: 'Für Marken, die Frauen mit Anspruch erreichen wollen.',
|
||
alignment: 'center',
|
||
},
|
||
{
|
||
blockType: 'text-block',
|
||
width: 'medium',
|
||
content: createRichTextWithHeading('Wen Sie erreichen', [
|
||
'• Frauen 35-45, DACH',
|
||
'• Überdurchschnittliches Haushaltseinkommen',
|
||
'• Karriere + Familie',
|
||
'• Qualitätsorientiert, ROI-Denken',
|
||
'• Entscheiderinnen in Haushalt und Beruf',
|
||
]),
|
||
},
|
||
{
|
||
blockType: 'text-block',
|
||
width: 'medium',
|
||
content: createRichTextWithHeading('Zusammenarbeit', [
|
||
'→ Dedizierte Video-Integration (Longform)',
|
||
'→ Shorts-Serie (3-5 Videos)',
|
||
'→ Newsletter-Feature (P&L Pick)',
|
||
'→ Blog-Artikel (SEO-optimiert)',
|
||
'→ Affiliate-Partnerschaft (langfristig)',
|
||
]),
|
||
},
|
||
{
|
||
blockType: 'text-block',
|
||
width: 'medium',
|
||
content: createRichTextWithHeading('Passt gut', [
|
||
'Premium Fashion & Accessoires, Beauty & Skincare, Travel & Hospitality, Tech & Produktivität, Wellness & Selfcare, Home & Organisation',
|
||
]),
|
||
},
|
||
{
|
||
blockType: 'text-block',
|
||
width: 'medium',
|
||
content: createRichTextWithHeading('Passt nicht', [
|
||
'Fast Fashion, Detox/Wunder-Supplements, Alkohol/Glücksspiel/Nikotin, Krypto/High-Risk Finance',
|
||
]),
|
||
},
|
||
{
|
||
blockType: 'cta-block',
|
||
headline: 'Interesse?',
|
||
description: 'kooperationen@blogwoman.de – Ansprechpartnerin: Dr. Caroline Porwoll',
|
||
backgroundColor: 'dark',
|
||
buttons: [{ text: 'Kontakt aufnehmen', link: 'mailto:kooperationen@blogwoman.de', style: 'primary' }],
|
||
},
|
||
],
|
||
seo: {
|
||
metaTitle: 'Kooperationen | BlogWoman',
|
||
metaDescription:
|
||
'Für Marken, die Frauen mit Anspruch erreichen wollen. Media Kit und Kontakt.',
|
||
},
|
||
},
|
||
// TRANSPARENZ PAGE
|
||
{
|
||
title: 'Transparenz',
|
||
slug: 'transparenz',
|
||
status: 'published',
|
||
hero: {
|
||
headline: 'Transparenz & Affiliate-Offenlegung',
|
||
subline: 'Ehrlichkeit ist ein Kernwert von BlogWoman.',
|
||
},
|
||
layout: [
|
||
{
|
||
blockType: 'hero-block',
|
||
headline: 'Transparenz & Affiliate-Offenlegung',
|
||
subline: 'Ehrlichkeit ist ein Kernwert von BlogWoman.',
|
||
alignment: 'center',
|
||
},
|
||
{
|
||
blockType: 'text-block',
|
||
width: 'medium',
|
||
content: createRichTextWithHeading('AFFILIATE-LINKS', [
|
||
'Einige Links auf dieser Seite sind Affiliate-Links (*). Wenn du über diese Links kaufst, erhalte ich eine kleine Provision – für dich entstehen keine Mehrkosten.',
|
||
'Ich empfehle nur Produkte, die ich selbst nutze oder gründlich geprüft habe. Bezahlte Empfehlungen gibt es nicht.',
|
||
]),
|
||
},
|
||
{
|
||
blockType: 'text-block',
|
||
width: 'medium',
|
||
content: createRichTextWithHeading('SPONSORING', [
|
||
'Gesponserte Inhalte werden immer klar gekennzeichnet („Werbung" oder „In Kooperation mit").',
|
||
]),
|
||
},
|
||
{
|
||
blockType: 'text-block',
|
||
width: 'medium',
|
||
content: createRichTextWithHeading('WAS ICH NICHT EMPFEHLE', [
|
||
'• Fast Fashion',
|
||
'• Detox/Wunder-Produkte',
|
||
'• Alkohol, Glücksspiel, Nikotin',
|
||
'• Krypto/High-Risk-Investments',
|
||
'• Alles, was ich nicht selbst nutzen würde',
|
||
'',
|
||
'Fragen? hello@blogwoman.de',
|
||
]),
|
||
},
|
||
],
|
||
seo: {
|
||
metaTitle: 'Transparenz & Affiliate-Offenlegung | BlogWoman',
|
||
metaDescription:
|
||
'Ehrlichkeit ist ein Kernwert von BlogWoman. Hier findest du volle Transparenz zu Affiliate-Links und Sponsoring.',
|
||
},
|
||
},
|
||
// IMPRESSUM PAGE
|
||
{
|
||
title: 'Impressum',
|
||
slug: 'impressum',
|
||
status: 'published',
|
||
hero: {},
|
||
layout: [
|
||
{
|
||
blockType: 'text-block',
|
||
width: 'narrow',
|
||
content: {
|
||
root: {
|
||
type: 'root',
|
||
children: [
|
||
{ type: 'heading', tag: 'h1', children: [{ type: 'text', text: 'Impressum' }] },
|
||
{
|
||
type: 'paragraph',
|
||
children: [{ type: 'text', text: 'Angaben gemäß § 5 TMG / § 5 DDG', format: 1 }],
|
||
},
|
||
{
|
||
type: 'paragraph',
|
||
children: [
|
||
{
|
||
type: 'text',
|
||
text: 'Complex Care Solutions GmbH\n[Straße und Hausnummer]\n[PLZ] [Ort]\nDeutschland',
|
||
},
|
||
],
|
||
},
|
||
{
|
||
type: 'paragraph',
|
||
children: [{ type: 'text', text: 'Geschäftsführerin: Dr. Caroline Porwoll' }],
|
||
},
|
||
{ type: 'paragraph', children: [{ type: 'text', text: 'Kontakt', format: 1 }] },
|
||
{
|
||
type: 'paragraph',
|
||
children: [{ type: 'text', text: 'E-Mail: hello@blogwoman.de' }],
|
||
},
|
||
{ type: 'paragraph', children: [{ type: 'text', text: 'Registereintrag', format: 1 }] },
|
||
{
|
||
type: 'paragraph',
|
||
children: [
|
||
{
|
||
type: 'text',
|
||
text: 'Handelsregister: Amtsgericht [Ort]\nRegisternummer: HRB [Nummer]',
|
||
},
|
||
],
|
||
},
|
||
{ type: 'paragraph', children: [{ type: 'text', text: 'Umsatzsteuer-ID', format: 1 }] },
|
||
{ type: 'paragraph', children: [{ type: 'text', text: 'USt-IdNr.: DE[Nummer]' }] },
|
||
{
|
||
type: 'paragraph',
|
||
children: [
|
||
{
|
||
type: 'text',
|
||
text: 'Verantwortlich für den Inhalt nach § 55 Abs. 2 RStV:',
|
||
format: 1,
|
||
},
|
||
],
|
||
},
|
||
{
|
||
type: 'paragraph',
|
||
children: [{ type: 'text', text: 'Dr. Caroline Porwoll\n[Adresse]' }],
|
||
},
|
||
],
|
||
direction: 'ltr',
|
||
format: '',
|
||
indent: 0,
|
||
version: 1,
|
||
},
|
||
},
|
||
},
|
||
],
|
||
seo: {
|
||
metaTitle: 'Impressum | BlogWoman',
|
||
metaDescription: 'Impressum von BlogWoman – betrieben von Complex Care Solutions GmbH.',
|
||
},
|
||
},
|
||
// DATENSCHUTZ PAGE
|
||
{
|
||
title: 'Datenschutzerklärung',
|
||
slug: 'datenschutz',
|
||
status: 'published',
|
||
hero: {},
|
||
layout: [
|
||
{
|
||
blockType: 'text-block',
|
||
width: 'narrow',
|
||
content: {
|
||
root: {
|
||
type: 'root',
|
||
children: [
|
||
{
|
||
type: 'heading',
|
||
tag: 'h1',
|
||
children: [{ type: 'text', text: 'Datenschutzerklärung' }],
|
||
},
|
||
{
|
||
type: 'heading',
|
||
tag: 'h2',
|
||
children: [{ type: 'text', text: '1. Datenschutz auf einen Blick' }],
|
||
},
|
||
{ type: 'paragraph', children: [{ type: 'text', text: 'Allgemeine Hinweise', format: 1 }] },
|
||
{
|
||
type: 'paragraph',
|
||
children: [
|
||
{
|
||
type: 'text',
|
||
text: 'Die folgenden Hinweise geben einen einfachen Überblick darüber, was mit Ihren personenbezogenen Daten passiert, wenn Sie diese Website besuchen.',
|
||
},
|
||
],
|
||
},
|
||
{
|
||
type: 'heading',
|
||
tag: 'h2',
|
||
children: [{ type: 'text', text: '2. Verantwortliche Stelle' }],
|
||
},
|
||
{
|
||
type: 'paragraph',
|
||
children: [
|
||
{
|
||
type: 'text',
|
||
text: 'Complex Care Solutions GmbH\nGeschäftsführerin: Dr. Caroline Porwoll\nE-Mail: hello@blogwoman.de',
|
||
},
|
||
],
|
||
},
|
||
{
|
||
type: 'heading',
|
||
tag: 'h2',
|
||
children: [{ type: 'text', text: '3. Newsletter' }],
|
||
},
|
||
{
|
||
type: 'paragraph',
|
||
children: [
|
||
{
|
||
type: 'text',
|
||
text: 'Wenn Sie den auf der Website angebotenen Newsletter beziehen möchten, benötigen wir von Ihnen eine E-Mail-Adresse sowie Informationen, welche uns die Überprüfung gestatten, dass Sie der Inhaber der angegebenen E-Mail-Adresse sind.',
|
||
},
|
||
],
|
||
},
|
||
{
|
||
type: 'paragraph',
|
||
children: [
|
||
{
|
||
type: 'text',
|
||
text: '(Diese Datenschutzerklärung ist ein Platzhalter und muss durch eine vollständige, rechtskonforme Version ersetzt werden.)',
|
||
format: 2,
|
||
},
|
||
],
|
||
},
|
||
],
|
||
direction: 'ltr',
|
||
format: '',
|
||
indent: 0,
|
||
version: 1,
|
||
},
|
||
},
|
||
},
|
||
],
|
||
seo: {
|
||
metaTitle: 'Datenschutzerklärung | BlogWoman',
|
||
metaDescription: 'DSGVO-konforme Datenschutzerklärung von BlogWoman.',
|
||
},
|
||
},
|
||
]
|
||
|
||
const pageIds: Record<string, number> = {}
|
||
|
||
for (const page of pages) {
|
||
const existing = await payload.find({
|
||
collection: 'pages',
|
||
where: {
|
||
and: [{ slug: { equals: page.slug } }, { tenant: { equals: tenantId } }],
|
||
},
|
||
})
|
||
|
||
if (existing.docs.length > 0) {
|
||
pageIds[page.slug] = existing.docs[0].id as number
|
||
await payload.update({
|
||
collection: 'pages',
|
||
id: existing.docs[0].id,
|
||
data: {
|
||
...page,
|
||
tenant: tenantId,
|
||
} as any,
|
||
})
|
||
console.log(`✓ Updated page: ${page.title}`)
|
||
} else {
|
||
const created = await payload.create({
|
||
collection: 'pages',
|
||
data: {
|
||
...page,
|
||
tenant: tenantId,
|
||
} as any,
|
||
})
|
||
pageIds[page.slug] = created.id as number
|
||
console.log(`✓ Created page: ${page.title}`)
|
||
}
|
||
}
|
||
|
||
// ============================================
|
||
// 9. CREATE BLOG POSTS
|
||
// ============================================
|
||
console.log('\n--- 9. Creating Blog Posts ---')
|
||
|
||
const posts = [
|
||
{
|
||
title: 'Der komplette GRFI-Guide: In 7 Minuten boardroom-ready',
|
||
slug: 'grfi-guide',
|
||
type: 'blog',
|
||
isFeatured: true,
|
||
excerpt:
|
||
'Wie du in 7-10 Minuten vom Alltag zur Präsenz kommst. Mein komplettes System für Outfit, Grooming und Haltung.',
|
||
content: createRichTextWithBullets(
|
||
'GRFI – Get Ready For Impact',
|
||
'In 7-10 Minuten vom Alltag zur Präsenz. So funktioniert mein System:',
|
||
[
|
||
'Schritt 1: Outfit-Entscheidung in 60 Sekunden (mit Capsule Wardrobe)',
|
||
'Schritt 2: 2-Minuten-Grooming-Routine',
|
||
'Schritt 3: Haltung und Mindset-Reset',
|
||
'Schritt 4: Letzte Kontrolle und Go',
|
||
]
|
||
),
|
||
categories: [categoryIds['stil-wirkung']],
|
||
tags: [tagIds['grfi'], tagIds['business-outfit'], tagIds['morgenroutine']],
|
||
author: authorId,
|
||
status: 'published',
|
||
publishedAt: new Date().toISOString(),
|
||
},
|
||
{
|
||
title: 'Capsule Wardrobe für berufstätige Mütter: Mein System',
|
||
slug: 'capsule-wardrobe-berufstaetige-muetter',
|
||
type: 'blog',
|
||
isFeatured: false,
|
||
excerpt:
|
||
'30 Teile, unendliche Kombinationen. So baue ich eine Garderobe, die im Board und auf dem Spielplatz funktioniert.',
|
||
content: createRichText([
|
||
'Eine Capsule Wardrobe ist kein Verzicht – sie ist eine Befreiung.',
|
||
'Mit 30 sorgfältig ausgewählten Teilen habe ich unendliche Kombinationsmöglichkeiten. Jedes Teil passt zu mindestens 3 anderen.',
|
||
'Das Ergebnis: Weniger Entscheidungsmüdigkeit am Morgen, mehr Zeit für das, was wirklich zählt.',
|
||
]),
|
||
categories: [categoryIds['stil-wirkung']],
|
||
tags: [tagIds['capsule-wardrobe'], tagIds['investment-piece']],
|
||
author: authorId,
|
||
status: 'published',
|
||
publishedAt: new Date().toISOString(),
|
||
},
|
||
{
|
||
title: 'Cost-per-Wear erklärt: So rechnest du Investment-Pieces',
|
||
slug: 'cost-per-wear-erklaert',
|
||
type: 'blog',
|
||
isFeatured: false,
|
||
excerpt:
|
||
'Warum ein 400€-Blazer günstiger sein kann als einer für 60€. Die Mathematik hinter smarten Käufen.',
|
||
content: createRichText([
|
||
'Cost-per-Wear (CPW) = Kaufpreis ÷ Anzahl der Trageaktionen',
|
||
'Ein 400€-Blazer, den du 200x trägst = 2€ CPW',
|
||
'Ein 60€-Blazer, den du 10x trägst = 6€ CPW',
|
||
'Der teurere Blazer ist am Ende der günstigere. Das ist Investment-Denken.',
|
||
]),
|
||
categories: [categoryIds['stil-wirkung']],
|
||
tags: [tagIds['investment-piece'], tagIds['capsule-wardrobe']],
|
||
author: authorId,
|
||
status: 'published',
|
||
publishedAt: new Date().toISOString(),
|
||
},
|
||
{
|
||
title: 'Sunday Reset: 2 Stunden für eine stressfreie Woche',
|
||
slug: 'sunday-reset-routine',
|
||
type: 'blog',
|
||
isFeatured: false,
|
||
excerpt: 'Meine wöchentliche Reset-Routine, die mir unter der Woche Stunden spart.',
|
||
content: createRichTextWithBullets('Der Sunday Reset', 'So sieht meine Sonntagsroutine aus:', [
|
||
'Kalender-Review: Alle Termine der Woche durchgehen',
|
||
'Outfit-Planung: 5 Outfits für die Woche zusammenstellen',
|
||
'Meal-Prep: Basics für die Woche vorbereiten',
|
||
'Mental-Reset: 15 Minuten Journaling',
|
||
]),
|
||
categories: [categoryIds['systeme-entscheidungen']],
|
||
tags: [tagIds['zeitmanagement'], tagIds['morgenroutine']],
|
||
author: authorId,
|
||
status: 'published',
|
||
publishedAt: new Date().toISOString(),
|
||
},
|
||
{
|
||
title: '5 Regeln, die mir 5 Stunden pro Woche sparen',
|
||
slug: '5-regeln-zeitersparnis',
|
||
type: 'blog',
|
||
isFeatured: false,
|
||
excerpt: 'Keine Hacks. Keine Tricks. Nur Regeln, die funktionieren.',
|
||
content: createRichTextWithBullets(
|
||
'5 Regeln für mehr Zeit',
|
||
'Diese Regeln habe ich über Jahre entwickelt:',
|
||
[
|
||
'Regel 1: Keine Meetings ohne Agenda',
|
||
'Regel 2: E-Mails nur 2x täglich checken',
|
||
'Regel 3: Decision-Proof: Wenn X, dann Y',
|
||
'Regel 4: Batching: Gleiche Aufgaben bündeln',
|
||
'Regel 5: 2-Minuten-Regel: Sofort erledigen, wenn unter 2 Minuten',
|
||
]
|
||
),
|
||
categories: [categoryIds['systeme-entscheidungen']],
|
||
tags: [tagIds['zeitmanagement'], tagIds['entscheidungen']],
|
||
author: authorId,
|
||
status: 'published',
|
||
publishedAt: new Date().toISOString(),
|
||
},
|
||
{
|
||
title: 'Warum ich BlogWoman gestartet habe',
|
||
slug: 'warum-blogwoman',
|
||
type: 'blog',
|
||
isFeatured: true,
|
||
excerpt:
|
||
'Die Geschichte hinter BlogWoman. Was mich dazu gebracht hat, diesen Kanal zu starten.',
|
||
content: createRichText([
|
||
'Es gab diesen Moment vor dem Kleiderschrank. Board-Meeting in 45 Minuten, Kind mit Fieber, keine Ahnung was anziehen.',
|
||
'Nicht weil ich nichts hatte. Sondern weil ich kein System hatte.',
|
||
'In diesem Moment entstand die Idee für BlogWoman. Ein Ort für Frauen, die wie ich versuchen, Karriere und Familie unter einen Hut zu bekommen.',
|
||
'Nicht mit Motivation und Mindset-Sprüchen. Sondern mit Systemen, die funktionieren – auch an Tagen, an denen wir nicht funktionieren.',
|
||
]),
|
||
categories: [categoryIds['karriere-familie']],
|
||
tags: [tagIds['working-mom']],
|
||
author: authorId,
|
||
status: 'published',
|
||
publishedAt: new Date().toISOString(),
|
||
},
|
||
{
|
||
title: 'Meine 10 Investment-Pieces (mit CPW nach Jahren)',
|
||
slug: 'meine-investment-pieces',
|
||
type: 'blog',
|
||
isFeatured: false,
|
||
excerpt: 'Die Teile, die ich wirklich trage. Mit echten Zahlen nach Jahren der Nutzung.',
|
||
content: createRichText([
|
||
'Nach 15 Jahren habe ich gelernt: Weniger Teile, bessere Qualität, mehr Kombinationen.',
|
||
'Hier sind meine 10 Investment-Pieces mit echten Cost-per-Wear Zahlen nach Jahren der Nutzung.',
|
||
'Spoiler: Einige der "teuersten" Stücke haben den niedrigsten CPW.',
|
||
]),
|
||
categories: [categoryIds['stil-wirkung']],
|
||
tags: [tagIds['investment-piece'], tagIds['capsule-wardrobe']],
|
||
author: authorId,
|
||
status: 'published',
|
||
publishedAt: new Date().toISOString(),
|
||
},
|
||
]
|
||
|
||
for (const post of posts) {
|
||
const existing = await payload.find({
|
||
collection: 'posts',
|
||
where: {
|
||
and: [{ slug: { equals: post.slug } }, { tenant: { equals: tenantId } }],
|
||
},
|
||
})
|
||
|
||
if (existing.docs.length > 0) {
|
||
console.log(`- Post "${post.title}" already exists`)
|
||
} else {
|
||
await payload.create({
|
||
collection: 'posts',
|
||
data: {
|
||
...post,
|
||
tenant: tenantId,
|
||
} as any,
|
||
})
|
||
console.log(`✓ Created post: ${post.title}`)
|
||
}
|
||
}
|
||
|
||
// ============================================
|
||
// 10. CREATE NAVIGATION
|
||
// ============================================
|
||
console.log('\n--- 10. Creating Navigation ---')
|
||
|
||
const existingNav = await payload.find({
|
||
collection: 'navigations',
|
||
where: { tenant: { equals: tenantId } },
|
||
})
|
||
|
||
const navigationData = {
|
||
title: 'BlogWoman Navigation',
|
||
mainMenu: [
|
||
{ label: 'Über mich', type: 'custom', url: '/caroline' },
|
||
{ label: 'Blog', type: 'custom', url: '/blog' },
|
||
{
|
||
label: 'Serien',
|
||
type: 'submenu',
|
||
submenu: [
|
||
{ label: 'Alle Serien', linkType: 'custom', url: '/serien' },
|
||
{ label: 'GRFI', linkType: 'custom', url: '/serien/grfi' },
|
||
{ label: 'Investment-Piece', linkType: 'custom', url: '/serien/investment-piece' },
|
||
{ label: 'Pleasure P&L', linkType: 'custom', url: '/serien/pleasure-pl' },
|
||
{ label: 'Regeneration', linkType: 'custom', url: '/serien/regeneration' },
|
||
{ label: 'SPARK', linkType: 'custom', url: '/serien/spark' },
|
||
{ label: 'Inner Circle', linkType: 'custom', url: '/serien/inner-circle' },
|
||
],
|
||
},
|
||
{ label: 'Favoriten', type: 'custom', url: '/favoriten' },
|
||
{ label: 'Newsletter', type: 'custom', url: '/newsletter' },
|
||
],
|
||
footerMenu: [
|
||
{ label: 'Über mich', linkType: 'custom', url: '/caroline' },
|
||
{ label: 'Blog', linkType: 'custom', url: '/blog' },
|
||
{ label: 'Favoriten', linkType: 'custom', url: '/favoriten' },
|
||
{ label: 'Newsletter', linkType: 'custom', url: '/newsletter' },
|
||
{ label: 'Kooperationen', linkType: 'custom', url: '/kooperationen' },
|
||
{ label: 'Impressum', linkType: 'custom', url: '/impressum' },
|
||
{ label: 'Datenschutz', linkType: 'custom', url: '/datenschutz' },
|
||
{ label: 'Transparenz', linkType: 'custom', url: '/transparenz' },
|
||
],
|
||
tenant: tenantId,
|
||
}
|
||
|
||
if (existingNav.docs.length > 0) {
|
||
await payload.update({
|
||
collection: 'navigations',
|
||
id: existingNav.docs[0].id,
|
||
data: navigationData as any,
|
||
})
|
||
console.log('✓ Updated navigation')
|
||
} else {
|
||
await payload.create({
|
||
collection: 'navigations',
|
||
data: navigationData as any,
|
||
})
|
||
console.log('✓ Created navigation')
|
||
}
|
||
|
||
// ============================================
|
||
// 11. CREATE SOCIAL LINKS
|
||
// ============================================
|
||
console.log('\n--- 11. Creating Social Links ---')
|
||
|
||
const socialLinks = [
|
||
{ platform: 'youtube', url: 'https://youtube.com/@blogwoman', isActive: true },
|
||
{ platform: 'instagram', url: 'https://instagram.com/blogwoman.de', isActive: true },
|
||
]
|
||
|
||
for (const link of socialLinks) {
|
||
const existing = await payload.find({
|
||
collection: 'social-links',
|
||
where: {
|
||
and: [{ platform: { equals: link.platform } }, { tenant: { equals: tenantId } }],
|
||
},
|
||
})
|
||
|
||
if (existing.docs.length > 0) {
|
||
console.log(`- Social link "${link.platform}" already exists`)
|
||
} else {
|
||
await payload.create({
|
||
collection: 'social-links',
|
||
data: {
|
||
...link,
|
||
tenant: tenantId,
|
||
} as any,
|
||
})
|
||
console.log(`✓ Created social link: ${link.platform}`)
|
||
}
|
||
}
|
||
|
||
// ============================================
|
||
// 12. CREATE COOKIE CONFIGURATION
|
||
// ============================================
|
||
console.log('\n--- 12. Creating Cookie Configuration ---')
|
||
|
||
const existingCookieConfig = await payload.find({
|
||
collection: 'cookie-configurations',
|
||
where: { tenant: { equals: tenantId } },
|
||
})
|
||
|
||
if (existingCookieConfig.docs.length > 0) {
|
||
console.log('- Cookie configuration already exists')
|
||
} else {
|
||
await payload.create({
|
||
collection: 'cookie-configurations',
|
||
data: {
|
||
title: 'BlogWoman Cookie-Einstellungen',
|
||
bannerTitle: 'Wir respektieren deine Privatsphäre',
|
||
bannerDescription:
|
||
'BlogWoman verwendet Cookies, um dein Erlebnis zu verbessern. Du entscheidest, welche Cookies du erlaubst.',
|
||
acceptAllText: 'Alle akzeptieren',
|
||
acceptNecessaryText: 'Nur notwendige',
|
||
settingsText: 'Einstellungen',
|
||
tenant: tenantId,
|
||
} as any,
|
||
})
|
||
console.log('✓ Created cookie configuration')
|
||
}
|
||
|
||
// ============================================
|
||
// DONE
|
||
// ============================================
|
||
console.log('\n========================================')
|
||
console.log('✅ BlogWoman Tenant Seed completed!')
|
||
console.log('========================================')
|
||
console.log(`
|
||
Summary:
|
||
- Tenant ID: ${tenantId}
|
||
- Categories: ${Object.keys(categoryIds).length}
|
||
- Tags: ${Object.keys(tagIds).length}
|
||
- Series: ${Object.keys(seriesIds).length}
|
||
- Pages: ${Object.keys(pageIds).length}
|
||
- Posts: ${posts.length}
|
||
- Author: Dr. Caroline Porwoll
|
||
- Navigation: Configured
|
||
- Social Links: YouTube, Instagram
|
||
`)
|
||
|
||
process.exit(0)
|
||
}
|
||
|
||
seed().catch((error) => {
|
||
console.error('❌ Seed failed:', error)
|
||
process.exit(1)
|
||
})
|