cms.c2sgmbh/src/migrations/20251213_160000_testimonials_slider_v2.ts
Martin Porwoll 8116180955 feat: enhance TestimonialsBlock with advanced slider options
Slider Settings:
- Animation types: slide, fade, cards, coverflow, none
- Configurable speed (300-800ms)
- Slides per view (1-3 or auto)
- Gap between slides

Navigation:
- Arrow controls with 5 styles and 4 positions
- Dots/pagination with 5 styles (dots, lines, numbers, progress, fraction)
- Touch swipe and keyboard navigation support

Display Options:
- Show/hide: rating, image, company, source, date
- Text truncation with configurable max length

Styling:
- 5 background options
- 4 card styles (shadow, border, flat, glass)
- 4 quote styles
- Image position and size controls
- Text alignment and spacing

Accessibility:
- ARIA labels (localized)
- Reduced motion preference support

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-13 20:37:35 +00:00

250 lines
13 KiB
TypeScript

import { MigrateUpArgs, MigrateDownArgs, sql } from '@payloadcms/db-postgres'
/**
* Migration: Testimonials Block Slider Enhancement
*
* Erweitert den TestimonialsBlock um:
* - Slider-Einstellungen (Animation, Geschwindigkeit, sichtbare Slides)
* - Navigation (Pfeile, Dots, Swipe, Keyboard)
* - Darstellungsoptionen (Hintergrund, Kartendesign, Zitate, Bilder)
* - Barrierefreiheit (ARIA Label, Reduced Motion)
*
* Da die Tabelle leer ist, wird sie komplett neu erstellt.
*/
export async function up({ db }: MigrateUpArgs): Promise<void> {
// Drop existing tables and enums (keine Daten vorhanden)
await db.execute(sql`
DROP TABLE IF EXISTS "pages_blocks_testimonials_block_selected_testimonials" CASCADE;
DROP TABLE IF EXISTS "pages_blocks_testimonials_block_locales" CASCADE;
DROP TABLE IF EXISTS "pages_blocks_testimonials_block" CASCADE;
DROP TYPE IF EXISTS "enum_pages_blocks_testimonials_block_layout";
DROP TYPE IF EXISTS "enum_pages_blocks_testimonials_block_columns";
DROP TYPE IF EXISTS "enum_pages_blocks_testimonials_block_display_mode";
DROP TYPE IF EXISTS "enum_pages_blocks_testimonials_block_background_color";
`)
// Create new enums
await db.execute(sql`
CREATE TYPE "enum_pages_blocks_testimonials_block_layout" AS ENUM('slider', 'grid', 'single', 'masonry', 'list');
CREATE TYPE "enum_pages_blocks_testimonials_block_columns" AS ENUM('2', '3', '4');
CREATE TYPE "enum_pages_blocks_testimonials_block_display_mode" AS ENUM('all', 'selected');
-- Slider settings
CREATE TYPE "enum_pages_blocks_testimonials_block_slider_effect" AS ENUM('slide', 'fade', 'cards', 'coverflow', 'none');
CREATE TYPE "enum_pages_blocks_testimonials_block_slider_speed" AS ENUM('300', '500', '800');
CREATE TYPE "enum_pages_blocks_testimonials_block_slider_per_view" AS ENUM('1', '2', '3', 'auto');
CREATE TYPE "enum_pages_blocks_testimonials_block_slider_gap" AS ENUM('0', '16', '24', '32', '48');
CREATE TYPE "enum_pages_blocks_testimonials_block_slider_delay" AS ENUM('3000', '4000', '5000', '6000', '8000', '10000');
-- Navigation
CREATE TYPE "enum_pages_blocks_testimonials_block_nav_arrow_style" AS ENUM('default', 'minimal', 'square', 'hover', 'outside');
CREATE TYPE "enum_pages_blocks_testimonials_block_nav_arrow_pos" AS ENUM('sides', 'bl', 'br', 'bc');
CREATE TYPE "enum_pages_blocks_testimonials_block_nav_dot_style" AS ENUM('dots', 'lines', 'numbers', 'progress', 'fraction');
CREATE TYPE "enum_pages_blocks_testimonials_block_nav_dot_pos" AS ENUM('bottom', 'bl', 'br');
-- Style
CREATE TYPE "enum_pages_blocks_testimonials_block_style_bg" AS ENUM('white', 'light', 'dark', 'accent', 'none');
CREATE TYPE "enum_pages_blocks_testimonials_block_style_card" AS ENUM('shadow', 'border', 'flat', 'glass');
CREATE TYPE "enum_pages_blocks_testimonials_block_style_quote" AS ENUM('icon', 'quotes', 'none', 'large');
CREATE TYPE "enum_pages_blocks_testimonials_block_style_img_pos" AS ENUM('top', 'left', 'bottom', 'bg');
CREATE TYPE "enum_pages_blocks_testimonials_block_style_img_size" AS ENUM('sm', 'md', 'lg', 'xl');
CREATE TYPE "enum_pages_blocks_testimonials_block_style_align" AS ENUM('left', 'center', 'right');
CREATE TYPE "enum_pages_blocks_testimonials_block_style_spacing" AS ENUM('sm', 'normal', 'lg');
`)
// Create main table
await db.execute(sql`
CREATE TABLE "pages_blocks_testimonials_block" (
"_order" integer NOT NULL,
"_parent_id" integer NOT NULL,
"_path" text NOT NULL,
"id" varchar PRIMARY KEY NOT NULL,
-- Basic settings
"layout" "enum_pages_blocks_testimonials_block_layout" DEFAULT 'slider',
"columns" "enum_pages_blocks_testimonials_block_columns" DEFAULT '3',
"display_mode" "enum_pages_blocks_testimonials_block_display_mode" DEFAULT 'all',
"limit" numeric DEFAULT 6,
-- Display options
"display_options_show_rating" boolean DEFAULT true,
"display_options_show_image" boolean DEFAULT true,
"display_options_show_company" boolean DEFAULT true,
"display_options_show_source" boolean DEFAULT false,
"display_options_show_date" boolean DEFAULT false,
"display_options_truncate_text" boolean DEFAULT false,
"display_options_max_length" numeric DEFAULT 200,
-- Slider settings
"slider_effect" "enum_pages_blocks_testimonials_block_slider_effect" DEFAULT 'slide',
"slider_speed" "enum_pages_blocks_testimonials_block_slider_speed" DEFAULT '500',
"slider_per_view" "enum_pages_blocks_testimonials_block_slider_per_view" DEFAULT '1',
"slider_gap" "enum_pages_blocks_testimonials_block_slider_gap" DEFAULT '24',
"slider_auto" boolean DEFAULT true,
"slider_delay" "enum_pages_blocks_testimonials_block_slider_delay" DEFAULT '5000',
"slider_hover_pause" boolean DEFAULT true,
"slider_loop" boolean DEFAULT true,
"slider_centered" boolean DEFAULT false,
-- Navigation
"nav_arrows" boolean DEFAULT true,
"nav_arrow_style" "enum_pages_blocks_testimonials_block_nav_arrow_style" DEFAULT 'default',
"nav_arrow_pos" "enum_pages_blocks_testimonials_block_nav_arrow_pos" DEFAULT 'sides',
"nav_dots" boolean DEFAULT true,
"nav_dot_style" "enum_pages_blocks_testimonials_block_nav_dot_style" DEFAULT 'dots',
"nav_dot_pos" "enum_pages_blocks_testimonials_block_nav_dot_pos" DEFAULT 'bottom',
"nav_swipe" boolean DEFAULT true,
"nav_keys" boolean DEFAULT true,
-- Style
"style_bg" "enum_pages_blocks_testimonials_block_style_bg" DEFAULT 'light',
"style_card" "enum_pages_blocks_testimonials_block_style_card" DEFAULT 'shadow',
"style_quote" "enum_pages_blocks_testimonials_block_style_quote" DEFAULT 'icon',
"style_img_pos" "enum_pages_blocks_testimonials_block_style_img_pos" DEFAULT 'top',
"style_img_size" "enum_pages_blocks_testimonials_block_style_img_size" DEFAULT 'md',
"style_align" "enum_pages_blocks_testimonials_block_style_align" DEFAULT 'center',
"style_spacing" "enum_pages_blocks_testimonials_block_style_spacing" DEFAULT 'normal',
-- Accessibility
"a11y_reduced_motion" boolean DEFAULT true,
"block_name" varchar
);
`)
// Create locales table
await db.execute(sql`
CREATE TABLE "pages_blocks_testimonials_block_locales" (
"title" varchar DEFAULT 'Das sagen unsere Kunden',
"subtitle" varchar,
"a11y_label" varchar DEFAULT 'Kundenstimmen',
"id" serial PRIMARY KEY NOT NULL,
"_locale" "_locales" NOT NULL,
"_parent_id" varchar NOT NULL
);
`)
// Create relationships table for selected testimonials
await db.execute(sql`
CREATE TABLE "pages_blocks_testimonials_block_selected_testimonials" (
"_order" integer NOT NULL,
"_parent_id" varchar NOT NULL,
"id" varchar PRIMARY KEY NOT NULL,
"testimonials_id" integer
);
`)
// Add foreign keys and indexes
await db.execute(sql`
ALTER TABLE "pages_blocks_testimonials_block"
ADD CONSTRAINT "pages_blocks_testimonials_block_parent_id_fk"
FOREIGN KEY ("_parent_id") REFERENCES "public"."pages"("id") ON DELETE cascade ON UPDATE no action;
ALTER TABLE "pages_blocks_testimonials_block_locales"
ADD CONSTRAINT "pages_blocks_testimonials_block_locales_parent_id_fk"
FOREIGN KEY ("_parent_id") REFERENCES "public"."pages_blocks_testimonials_block"("id") ON DELETE cascade ON UPDATE no action;
ALTER TABLE "pages_blocks_testimonials_block_selected_testimonials"
ADD CONSTRAINT "pages_blocks_testimonials_block_sel_test_parent_id_fk"
FOREIGN KEY ("_parent_id") REFERENCES "public"."pages_blocks_testimonials_block"("id") ON DELETE cascade ON UPDATE no action;
ALTER TABLE "pages_blocks_testimonials_block_selected_testimonials"
ADD CONSTRAINT "pages_blocks_testimonials_block_sel_test_testimonials_id_fk"
FOREIGN KEY ("testimonials_id") REFERENCES "public"."testimonials"("id") ON DELETE set null ON UPDATE no action;
CREATE INDEX "pages_blocks_testimonials_block_order_idx" ON "pages_blocks_testimonials_block" USING btree ("_order");
CREATE INDEX "pages_blocks_testimonials_block_parent_id_idx" ON "pages_blocks_testimonials_block" USING btree ("_parent_id");
CREATE INDEX "pages_blocks_testimonials_block_path_idx" ON "pages_blocks_testimonials_block" USING btree ("_path");
CREATE UNIQUE INDEX "pages_blocks_testimonials_block_locales_locale_parent_id_uniq"
ON "pages_blocks_testimonials_block_locales" USING btree ("_locale", "_parent_id");
CREATE INDEX "pages_blocks_testimonials_block_sel_test_order_idx"
ON "pages_blocks_testimonials_block_selected_testimonials" USING btree ("_order");
CREATE INDEX "pages_blocks_testimonials_block_sel_test_parent_id_idx"
ON "pages_blocks_testimonials_block_selected_testimonials" USING btree ("_parent_id");
`)
}
export async function down({ db }: MigrateDownArgs): Promise<void> {
// Drop new tables
await db.execute(sql`
DROP TABLE IF EXISTS "pages_blocks_testimonials_block_selected_testimonials" CASCADE;
DROP TABLE IF EXISTS "pages_blocks_testimonials_block_locales" CASCADE;
DROP TABLE IF EXISTS "pages_blocks_testimonials_block" CASCADE;
`)
// Drop new enums
await db.execute(sql`
DROP TYPE IF EXISTS "enum_pages_blocks_testimonials_block_layout";
DROP TYPE IF EXISTS "enum_pages_blocks_testimonials_block_columns";
DROP TYPE IF EXISTS "enum_pages_blocks_testimonials_block_display_mode";
DROP TYPE IF EXISTS "enum_pages_blocks_testimonials_block_slider_effect";
DROP TYPE IF EXISTS "enum_pages_blocks_testimonials_block_slider_speed";
DROP TYPE IF EXISTS "enum_pages_blocks_testimonials_block_slider_per_view";
DROP TYPE IF EXISTS "enum_pages_blocks_testimonials_block_slider_gap";
DROP TYPE IF EXISTS "enum_pages_blocks_testimonials_block_slider_delay";
DROP TYPE IF EXISTS "enum_pages_blocks_testimonials_block_nav_arrow_style";
DROP TYPE IF EXISTS "enum_pages_blocks_testimonials_block_nav_arrow_pos";
DROP TYPE IF EXISTS "enum_pages_blocks_testimonials_block_nav_dot_style";
DROP TYPE IF EXISTS "enum_pages_blocks_testimonials_block_nav_dot_pos";
DROP TYPE IF EXISTS "enum_pages_blocks_testimonials_block_style_bg";
DROP TYPE IF EXISTS "enum_pages_blocks_testimonials_block_style_card";
DROP TYPE IF EXISTS "enum_pages_blocks_testimonials_block_style_quote";
DROP TYPE IF EXISTS "enum_pages_blocks_testimonials_block_style_img_pos";
DROP TYPE IF EXISTS "enum_pages_blocks_testimonials_block_style_img_size";
DROP TYPE IF EXISTS "enum_pages_blocks_testimonials_block_style_align";
DROP TYPE IF EXISTS "enum_pages_blocks_testimonials_block_style_spacing";
`)
// Recreate original structure
await db.execute(sql`
CREATE TYPE "enum_pages_blocks_testimonials_block_layout" AS ENUM('slider', 'grid', 'single', 'masonry', 'list');
CREATE TYPE "enum_pages_blocks_testimonials_block_columns" AS ENUM('2', '3', '4');
CREATE TYPE "enum_pages_blocks_testimonials_block_display_mode" AS ENUM('all', 'selected');
CREATE TYPE "enum_pages_blocks_testimonials_block_background_color" AS ENUM('white', 'light', 'dark', 'accent');
CREATE TABLE "pages_blocks_testimonials_block" (
"_order" integer NOT NULL,
"_parent_id" integer NOT NULL,
"_path" text NOT NULL,
"id" varchar PRIMARY KEY NOT NULL,
"layout" "enum_pages_blocks_testimonials_block_layout" DEFAULT 'slider',
"columns" "enum_pages_blocks_testimonials_block_columns" DEFAULT '3',
"display_mode" "enum_pages_blocks_testimonials_block_display_mode" DEFAULT 'all',
"limit" numeric DEFAULT 6,
"show_rating" boolean DEFAULT true,
"show_image" boolean DEFAULT true,
"show_company" boolean DEFAULT true,
"show_source" boolean DEFAULT false,
"autoplay" boolean DEFAULT true,
"autoplay_speed" numeric DEFAULT 5000,
"background_color" "enum_pages_blocks_testimonials_block_background_color" DEFAULT 'light',
"block_name" varchar
);
CREATE TABLE "pages_blocks_testimonials_block_locales" (
"title" varchar DEFAULT 'Das sagen unsere Kunden',
"subtitle" varchar,
"id" serial PRIMARY KEY NOT NULL,
"_locale" "_locales" NOT NULL,
"_parent_id" varchar NOT NULL
);
ALTER TABLE "pages_blocks_testimonials_block"
ADD CONSTRAINT "pages_blocks_testimonials_block_parent_id_fk"
FOREIGN KEY ("_parent_id") REFERENCES "public"."pages"("id") ON DELETE cascade ON UPDATE no action;
ALTER TABLE "pages_blocks_testimonials_block_locales"
ADD CONSTRAINT "pages_blocks_testimonials_block_locales_parent_id_fk"
FOREIGN KEY ("_parent_id") REFERENCES "public"."pages_blocks_testimonials_block"("id") ON DELETE cascade ON UPDATE no action;
CREATE INDEX "pages_blocks_testimonials_block_order_idx" ON "pages_blocks_testimonials_block" USING btree ("_order");
CREATE INDEX "pages_blocks_testimonials_block_parent_id_idx" ON "pages_blocks_testimonials_block" USING btree ("_parent_id");
CREATE INDEX "pages_blocks_testimonials_block_path_idx" ON "pages_blocks_testimonials_block" USING btree ("_path");
CREATE UNIQUE INDEX "pages_blocks_testimonials_block_locales_locale_parent_id_uniq"
ON "pages_blocks_testimonials_block_locales" USING btree ("_locale", "_parent_id");
`)
}