diff --git a/scripts/seed-sensualmoment.ts b/scripts/seed-sensualmoment.ts
index 6148b1e..02cbe4d 100644
--- a/scripts/seed-sensualmoment.ts
+++ b/scripts/seed-sensualmoment.ts
@@ -519,14 +519,6 @@ async function seed() {
type: 'paragraph',
text: 'Mit einfühlsamer Anleitung und einem Blick für das Besondere entstehen Bilder, die deine Stärke, Sinnlichkeit und Einzigartigkeit einfangen – authentisch und mit Respekt.',
},
- {
- type: 'paragraph',
- text: 'Kein Shooting gleicht dem anderen, denn keine Frau gleicht der anderen.',
- },
- {
- type: 'paragraph-italic',
- text: '— Dein Name',
- },
]),
},
{
@@ -603,6 +595,17 @@ async function seed() {
cardStyle: 'bordered',
},
},
+ {
+ blockType: 'posts-list-block',
+ title: 'Gedanken & Geschichten',
+ postType: 'blog',
+ layout: 'grid',
+ columns: '3',
+ limit: 3,
+ showExcerpt: true,
+ showDate: true,
+ showAuthor: false,
+ },
{
blockType: 'cta-block',
headline: 'Bereit für deinen Moment?',
@@ -617,6 +620,15 @@ async function seed() {
},
],
},
+ {
+ blockType: 'contact-form-block',
+ form: contactFormId,
+ headline: 'Bereit für deinen Moment?',
+ description:
+ 'Ich freue mich darauf, dich kennenzulernen und gemeinsam deinen ganz persönlichen Moment zu gestalten. Schreib mir oder ruf mich an – unverbindlich und vertraulich.',
+ successMessage: 'Vielen Dank!',
+ showContactInfo: true,
+ },
],
seo: {
metaTitle: 'Sensual Moment – Boudoir Photography · Dein Moment der Selbstliebe',
diff --git a/scripts/seed-zweitmeinung.ts b/scripts/seed-zweitmeinung.ts
index 2ec331b..17f17ab 100644
--- a/scripts/seed-zweitmeinung.ts
+++ b/scripts/seed-zweitmeinung.ts
@@ -1627,32 +1627,37 @@ async function seed() {
slug: 'impressum',
status: 'published',
layout: [
+ {
+ blockType: 'hero-block',
+ headline: 'Impressum',
+ alignment: 'center',
+ overlay: true,
+ },
{
blockType: 'text-block',
- width: 'medium',
+ width: 'narrow',
content: createRichTextComplex([
- { type: 'heading', tag: 'h1', text: 'Impressum' },
- { type: 'paragraph', text: 'complex care solutions GmbH' },
+ { type: 'paragraph-bold', text: 'complex care solutions GmbH' },
{ type: 'paragraph', text: 'Hans-Böckler-Str. 19' },
{ type: 'paragraph', text: '46236 Bottrop' },
- { type: 'heading', tag: 'h3', text: 'Handelsregister' },
+ { type: 'heading', tag: 'h2', text: 'Handelsregister' },
{ type: 'paragraph', text: 'Handelsregister: HRB 15753' },
{ type: 'paragraph', text: 'Registergericht: Gelsenkirchen' },
- { type: 'heading', tag: 'h3', text: 'Vertreten durch' },
+ { type: 'heading', tag: 'h2', text: 'Vertreten durch' },
{ type: 'paragraph', text: 'Martin Porwoll' },
- { type: 'heading', tag: 'h3', text: 'Kontakt' },
+ { type: 'heading', tag: 'h2', text: 'Kontakt' },
{ type: 'paragraph', text: 'Telefon: 0800 80 44 100' },
{ type: 'paragraph', text: 'Telefax: 0800 80 44 190' },
{ type: 'paragraph', text: 'E-Mail: kontakt@complexcaresolutions.de' },
- { type: 'heading', tag: 'h3', text: 'Umsatzsteuer-ID' },
+ { type: 'heading', tag: 'h2', text: 'Umsatzsteuer-ID' },
{ type: 'paragraph', text: 'Umsatzsteuer-Identifikationsnummer gemäß § 27 a Umsatzsteuergesetz: DE334815479' },
- { type: 'heading', tag: 'h3', text: 'Redaktionell verantwortlich' },
+ { type: 'heading', tag: 'h2', text: 'Redaktionell verantwortlich' },
{ type: 'paragraph', text: 'Martin Porwoll' },
{ type: 'paragraph', text: 'Hans-Böckler-Str. 19' },
{ type: 'paragraph', text: '46236 Bottrop' },
- { type: 'heading', tag: 'h3', text: 'EU-Streitschlichtung' },
+ { type: 'heading', tag: 'h2', text: 'EU-Streitschlichtung' },
{ type: 'paragraph', text: 'Die Europäische Kommission stellt eine Plattform zur Online-Streitbeilegung (OS) bereit: https://ec.europa.eu/consumers/odr/. Unsere E-Mail-Adresse finden Sie oben im Impressum.' },
- { type: 'heading', tag: 'h3', text: 'Verbraucherstreitbeilegung/Universalschlichtungsstelle' },
+ { type: 'heading', tag: 'h2', text: 'Verbraucherstreitbeilegung/Universalschlichtungsstelle' },
{ type: 'paragraph', text: 'Wir sind nicht bereit oder verpflichtet, an Streitbeilegungsverfahren vor einer Verbraucherschlichtungsstelle teilzunehmen.' },
]),
},
@@ -1670,11 +1675,16 @@ async function seed() {
status: 'published',
layout: [
{
- blockType: 'text-block',
- width: 'full',
- content: createRichText(
- 'Die Datenschutzerklärung wird über unseren externen Datenschutzbeauftragten alfright.eu bereitgestellt.',
- ),
+ blockType: 'hero-block',
+ headline: 'Datenschutzerklärung',
+ alignment: 'center',
+ overlay: true,
+ },
+ {
+ blockType: 'html-embed-block',
+ title: 'Alfright Datenschutzgenerator',
+ code: '',
+ maxWidth: 'full',
},
],
seo: {
diff --git a/src/blocks/HtmlEmbedBlock.ts b/src/blocks/HtmlEmbedBlock.ts
new file mode 100644
index 0000000..dde2211
--- /dev/null
+++ b/src/blocks/HtmlEmbedBlock.ts
@@ -0,0 +1,35 @@
+import type { Block } from 'payload'
+
+export const HtmlEmbedBlock: Block = {
+ slug: 'html-embed-block',
+ labels: { singular: 'HTML Embed', plural: 'HTML Embeds' },
+ fields: [
+ {
+ name: 'title',
+ type: 'text',
+ label: 'Titel (intern)',
+ admin: { description: 'Nur zur internen Identifikation im CMS' },
+ },
+ {
+ name: 'code',
+ type: 'code',
+ required: true,
+ label: 'HTML Code',
+ admin: {
+ language: 'html',
+ description: 'HTML/iframe Code der eingebettet werden soll',
+ },
+ },
+ {
+ name: 'maxWidth',
+ type: 'select',
+ defaultValue: 'full',
+ label: 'Maximale Breite',
+ options: [
+ { label: 'Schmal (620px)', value: 'narrow' },
+ { label: 'Mittel (900px)', value: 'medium' },
+ { label: 'Voll (1280px)', value: 'full' },
+ ],
+ },
+ ],
+}
diff --git a/src/blocks/index.ts b/src/blocks/index.ts
index 2f05b96..f075d1e 100644
--- a/src/blocks/index.ts
+++ b/src/blocks/index.ts
@@ -48,6 +48,9 @@ export { ComparisonBlock } from './ComparisonBlock'
// Tenant-specific Blocks
export { BeforeAfterBlock } from './BeforeAfterBlock'
+// Utility Blocks
+export { HtmlEmbedBlock } from './HtmlEmbedBlock'
+
// BlogWoman Blocks - ENABLED
export { FavoritesBlock } from './FavoritesBlock'
export { SeriesBlock } from './SeriesBlock'
diff --git a/src/collections/Pages.ts b/src/collections/Pages.ts
index 3869a35..038b1a7 100644
--- a/src/collections/Pages.ts
+++ b/src/collections/Pages.ts
@@ -43,6 +43,8 @@ import {
ComparisonBlock,
// Tenant-specific Blocks
BeforeAfterBlock,
+ // Utility Blocks
+ HtmlEmbedBlock,
// BlogWoman Blocks
FavoritesBlock,
SeriesBlock,
@@ -125,6 +127,8 @@ export const Pages: CollectionConfig = {
ComparisonBlock,
// Tenant-specific Blocks
BeforeAfterBlock,
+ // Utility Blocks
+ HtmlEmbedBlock,
// BlogWoman Blocks
FavoritesBlock,
SeriesBlock,
diff --git a/src/migrations/20260228_150000_add_html_embed_block.ts b/src/migrations/20260228_150000_add_html_embed_block.ts
new file mode 100644
index 0000000..c303ced
--- /dev/null
+++ b/src/migrations/20260228_150000_add_html_embed_block.ts
@@ -0,0 +1,36 @@
+import { MigrateUpArgs, MigrateDownArgs, sql } from '@payloadcms/db-postgres'
+
+export async function up({ db }: MigrateUpArgs): Promise {
+ await db.execute(sql`
+DO $$ BEGIN
+ CREATE TYPE "public"."enum_pages_blocks_html_embed_block_max_width" AS ENUM('narrow', 'medium', 'full');
+EXCEPTION
+ WHEN duplicate_object THEN null;
+END $$;
+
+CREATE TABLE IF NOT EXISTS "pages_blocks_html_embed_block" (
+ "_order" integer NOT NULL,
+ "_parent_id" integer NOT NULL,
+ "_path" text NOT NULL,
+ "id" varchar PRIMARY KEY NOT NULL,
+ "title" varchar,
+ "code" varchar NOT NULL,
+ "max_width" "enum_pages_blocks_html_embed_block_max_width" DEFAULT 'full',
+ "block_name" varchar
+);
+
+DO $$ BEGIN
+ ALTER TABLE "pages_blocks_html_embed_block" ADD CONSTRAINT "pages_blocks_html_embed_block_parent_id_fk" FOREIGN KEY ("_parent_id") REFERENCES "public"."pages"("id") ON DELETE cascade ON UPDATE no action;
+EXCEPTION
+ WHEN duplicate_object THEN null;
+END $$;
+
+CREATE INDEX IF NOT EXISTS "pages_blocks_html_embed_block_order_idx" ON "pages_blocks_html_embed_block" USING btree ("_order");
+CREATE INDEX IF NOT EXISTS "pages_blocks_html_embed_block_parent_id_idx" ON "pages_blocks_html_embed_block" USING btree ("_parent_id");
+CREATE INDEX IF NOT EXISTS "pages_blocks_html_embed_block_path_idx" ON "pages_blocks_html_embed_block" USING btree ("_path");
+ `)
+}
+
+export async function down({ db }: MigrateDownArgs): Promise {
+ // No-op: preserving data
+}
diff --git a/src/migrations/index.ts b/src/migrations/index.ts
index 9e91be6..e0ec4fc 100644
--- a/src/migrations/index.ts
+++ b/src/migrations/index.ts
@@ -38,6 +38,7 @@ import * as migration_20260116_120000_add_report_schedules from './20260116_1200
import * as migration_20260215_120000_add_monitoring_collections from './20260215_120000_add_monitoring_collections';
import * as migration_20260216_150000_add_card_grid_icon_fields from './20260216_150000_add_card_grid_icon_fields';
import * as migration_20260217_120000_add_tenant_to_forms from './20260217_120000_add_tenant_to_forms';
+import * as migration_20260228_150000_add_html_embed_block from './20260228_150000_add_html_embed_block';
export const migrations = [
{
@@ -240,4 +241,9 @@ export const migrations = [
down: migration_20260217_120000_add_tenant_to_forms.down,
name: '20260217_120000_add_tenant_to_forms'
},
+ {
+ up: migration_20260228_150000_add_html_embed_block.up,
+ down: migration_20260228_150000_add_html_embed_block.down,
+ name: '20260228_150000_add_html_embed_block'
+ },
];