mirror of
https://github.com/complexcaresolutions/cms.c2sgmbh.git
synced 2026-03-17 22:04:10 +00:00
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>
This commit is contained in:
parent
4f6280e09e
commit
8116180955
3 changed files with 753 additions and 62 deletions
|
|
@ -2,7 +2,11 @@ import type { Block } from 'payload'
|
|||
|
||||
/**
|
||||
* Testimonials Block
|
||||
* Zeigt Kundenstimmen aus der Testimonials Collection
|
||||
*
|
||||
* Zeigt Kundenstimmen aus der Testimonials Collection mit:
|
||||
* - Verschiedenen Layouts (Slider, Grid, Masonry, Liste)
|
||||
* - Erweiterten Slider-Optionen (Animation, Navigation, Autoplay)
|
||||
* - Flexiblen Anzeigeoptionen
|
||||
*/
|
||||
export const TestimonialsBlock: Block = {
|
||||
slug: 'testimonials-block',
|
||||
|
|
@ -11,6 +15,7 @@ export const TestimonialsBlock: Block = {
|
|||
plural: 'Testimonials',
|
||||
},
|
||||
fields: [
|
||||
// Überschrift & Untertitel
|
||||
{
|
||||
name: 'title',
|
||||
type: 'text',
|
||||
|
|
@ -24,6 +29,8 @@ export const TestimonialsBlock: Block = {
|
|||
label: 'Untertitel',
|
||||
localized: true,
|
||||
},
|
||||
|
||||
// Layout-Auswahl
|
||||
{
|
||||
name: 'layout',
|
||||
type: 'select',
|
||||
|
|
@ -48,10 +55,12 @@ export const TestimonialsBlock: Block = {
|
|||
{ label: '4 Spalten', value: '4' },
|
||||
],
|
||||
admin: {
|
||||
condition: (data, siblingData) =>
|
||||
condition: (_, siblingData) =>
|
||||
siblingData?.layout === 'grid' || siblingData?.layout === 'masonry',
|
||||
},
|
||||
},
|
||||
|
||||
// Testimonial-Auswahl
|
||||
{
|
||||
name: 'displayMode',
|
||||
type: 'select',
|
||||
|
|
@ -70,7 +79,7 @@ export const TestimonialsBlock: Block = {
|
|||
hasMany: true,
|
||||
label: 'Testimonials auswählen',
|
||||
admin: {
|
||||
condition: (data, siblingData) => siblingData?.displayMode === 'selected',
|
||||
condition: (_, siblingData) => siblingData?.displayMode === 'selected',
|
||||
},
|
||||
},
|
||||
{
|
||||
|
|
@ -81,64 +90,402 @@ export const TestimonialsBlock: Block = {
|
|||
max: 20,
|
||||
label: 'Maximale Anzahl',
|
||||
admin: {
|
||||
condition: (data, siblingData) => siblingData?.displayMode === 'all',
|
||||
condition: (_, siblingData) => siblingData?.displayMode === 'all',
|
||||
},
|
||||
},
|
||||
|
||||
// Anzeige-Optionen
|
||||
{
|
||||
name: 'showRating',
|
||||
type: 'checkbox',
|
||||
defaultValue: true,
|
||||
label: 'Sterne-Bewertung anzeigen',
|
||||
name: 'displayOptions',
|
||||
type: 'group',
|
||||
label: 'Anzeige-Optionen',
|
||||
fields: [
|
||||
{
|
||||
name: 'showRating',
|
||||
type: 'checkbox',
|
||||
defaultValue: true,
|
||||
label: 'Sterne-Bewertung anzeigen',
|
||||
},
|
||||
{
|
||||
name: 'showImage',
|
||||
type: 'checkbox',
|
||||
defaultValue: true,
|
||||
label: 'Foto anzeigen',
|
||||
},
|
||||
{
|
||||
name: 'showCompany',
|
||||
type: 'checkbox',
|
||||
defaultValue: true,
|
||||
label: 'Unternehmen anzeigen',
|
||||
},
|
||||
{
|
||||
name: 'showSource',
|
||||
type: 'checkbox',
|
||||
defaultValue: false,
|
||||
label: 'Quelle anzeigen',
|
||||
},
|
||||
{
|
||||
name: 'showDate',
|
||||
type: 'checkbox',
|
||||
defaultValue: false,
|
||||
label: 'Datum anzeigen',
|
||||
},
|
||||
{
|
||||
name: 'truncateText',
|
||||
type: 'checkbox',
|
||||
defaultValue: false,
|
||||
label: 'Text kürzen',
|
||||
admin: {
|
||||
description: 'Lange Testimonials werden abgeschnitten mit "Mehr lesen"',
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'maxLength',
|
||||
type: 'number',
|
||||
defaultValue: 200,
|
||||
min: 100,
|
||||
max: 500,
|
||||
label: 'Max. Zeichenanzahl',
|
||||
admin: {
|
||||
condition: (_, siblingData) => siblingData?.truncateText,
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
// Slider-Einstellungen (nur bei layout=slider)
|
||||
{
|
||||
name: 'showImage',
|
||||
type: 'checkbox',
|
||||
defaultValue: true,
|
||||
label: 'Foto anzeigen',
|
||||
},
|
||||
{
|
||||
name: 'showCompany',
|
||||
type: 'checkbox',
|
||||
defaultValue: true,
|
||||
label: 'Unternehmen anzeigen',
|
||||
},
|
||||
{
|
||||
name: 'showSource',
|
||||
type: 'checkbox',
|
||||
defaultValue: false,
|
||||
label: 'Quelle anzeigen',
|
||||
},
|
||||
{
|
||||
name: 'autoplay',
|
||||
type: 'checkbox',
|
||||
defaultValue: true,
|
||||
label: 'Automatisch wechseln',
|
||||
name: 'slider',
|
||||
type: 'group',
|
||||
label: 'Slider-Einstellungen',
|
||||
admin: {
|
||||
condition: (data, siblingData) => siblingData?.layout === 'slider',
|
||||
condition: (_, siblingData) => siblingData?.layout === 'slider',
|
||||
},
|
||||
fields: [
|
||||
// Animation
|
||||
{
|
||||
name: 'effect',
|
||||
type: 'select',
|
||||
defaultValue: 'slide',
|
||||
label: 'Animationstyp',
|
||||
options: [
|
||||
{ label: 'Schieben (Slide)', value: 'slide' },
|
||||
{ label: 'Überblenden (Fade)', value: 'fade' },
|
||||
{ label: 'Karten (Cards)', value: 'cards' },
|
||||
{ label: 'Coverflow', value: 'coverflow' },
|
||||
{ label: 'Keine Animation', value: 'none' },
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'speed',
|
||||
type: 'select',
|
||||
defaultValue: '500',
|
||||
label: 'Animationsdauer',
|
||||
options: [
|
||||
{ label: 'Schnell (300ms)', value: '300' },
|
||||
{ label: 'Normal (500ms)', value: '500' },
|
||||
{ label: 'Langsam (800ms)', value: '800' },
|
||||
],
|
||||
},
|
||||
// Anzahl sichtbarer Slides
|
||||
{
|
||||
name: 'perView',
|
||||
type: 'select',
|
||||
defaultValue: '1',
|
||||
label: 'Sichtbare Testimonials',
|
||||
options: [
|
||||
{ label: '1 (Vollbild)', value: '1' },
|
||||
{ label: '2', value: '2' },
|
||||
{ label: '3', value: '3' },
|
||||
{ label: 'Auto (responsive)', value: 'auto' },
|
||||
],
|
||||
admin: {
|
||||
description: 'Anzahl gleichzeitig sichtbarer Testimonials',
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'gap',
|
||||
type: 'select',
|
||||
defaultValue: '24',
|
||||
label: 'Abstand zwischen Slides',
|
||||
options: [
|
||||
{ label: 'Kein Abstand', value: '0' },
|
||||
{ label: 'Klein (16px)', value: '16' },
|
||||
{ label: 'Normal (24px)', value: '24' },
|
||||
{ label: 'Groß (32px)', value: '32' },
|
||||
{ label: 'Sehr groß (48px)', value: '48' },
|
||||
],
|
||||
},
|
||||
// Autoplay
|
||||
{
|
||||
name: 'auto',
|
||||
type: 'checkbox',
|
||||
defaultValue: true,
|
||||
label: 'Autoplay aktivieren',
|
||||
},
|
||||
{
|
||||
name: 'delay',
|
||||
type: 'select',
|
||||
defaultValue: '5000',
|
||||
label: 'Intervall',
|
||||
options: [
|
||||
{ label: '3 Sekunden', value: '3000' },
|
||||
{ label: '4 Sekunden', value: '4000' },
|
||||
{ label: '5 Sekunden', value: '5000' },
|
||||
{ label: '6 Sekunden', value: '6000' },
|
||||
{ label: '8 Sekunden', value: '8000' },
|
||||
{ label: '10 Sekunden', value: '10000' },
|
||||
],
|
||||
admin: {
|
||||
condition: (_, siblingData) => siblingData?.auto,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'hoverPause',
|
||||
type: 'checkbox',
|
||||
defaultValue: true,
|
||||
label: 'Bei Hover pausieren',
|
||||
admin: {
|
||||
condition: (_, siblingData) => siblingData?.auto,
|
||||
},
|
||||
},
|
||||
// Loop
|
||||
{
|
||||
name: 'loop',
|
||||
type: 'checkbox',
|
||||
defaultValue: true,
|
||||
label: 'Endlosschleife',
|
||||
},
|
||||
// Zentrierung
|
||||
{
|
||||
name: 'centered',
|
||||
type: 'checkbox',
|
||||
defaultValue: false,
|
||||
label: 'Aktiven Slide zentrieren',
|
||||
admin: {
|
||||
description: 'Der aktive Slide wird in der Mitte angezeigt',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
// Navigation
|
||||
{
|
||||
name: 'autoplaySpeed',
|
||||
type: 'number',
|
||||
defaultValue: 5000,
|
||||
min: 2000,
|
||||
max: 15000,
|
||||
label: 'Wechselintervall (ms)',
|
||||
name: 'nav',
|
||||
type: 'group',
|
||||
label: 'Navigation',
|
||||
admin: {
|
||||
condition: (data, siblingData) =>
|
||||
siblingData?.layout === 'slider' && siblingData?.autoplay,
|
||||
condition: (_, siblingData) => siblingData?.layout === 'slider',
|
||||
},
|
||||
fields: [
|
||||
// Pfeile
|
||||
{
|
||||
name: 'arrows',
|
||||
type: 'checkbox',
|
||||
defaultValue: true,
|
||||
label: 'Pfeile anzeigen',
|
||||
},
|
||||
{
|
||||
name: 'arrowStyle',
|
||||
type: 'select',
|
||||
defaultValue: 'default',
|
||||
label: 'Pfeil-Stil',
|
||||
options: [
|
||||
{ label: 'Standard (Kreis)', value: 'default' },
|
||||
{ label: 'Minimal', value: 'minimal' },
|
||||
{ label: 'Eckig', value: 'square' },
|
||||
{ label: 'Nur bei Hover', value: 'hover' },
|
||||
{ label: 'Außerhalb', value: 'outside' },
|
||||
],
|
||||
admin: {
|
||||
condition: (_, siblingData) => siblingData?.arrows,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'arrowPos',
|
||||
type: 'select',
|
||||
defaultValue: 'sides',
|
||||
label: 'Pfeil-Position',
|
||||
options: [
|
||||
{ label: 'Seitlich', value: 'sides' },
|
||||
{ label: 'Unten links', value: 'bl' },
|
||||
{ label: 'Unten rechts', value: 'br' },
|
||||
{ label: 'Unten zentriert', value: 'bc' },
|
||||
],
|
||||
admin: {
|
||||
condition: (_, siblingData) => siblingData?.arrows,
|
||||
},
|
||||
},
|
||||
// Dots/Pagination
|
||||
{
|
||||
name: 'dots',
|
||||
type: 'checkbox',
|
||||
defaultValue: true,
|
||||
label: 'Punkte anzeigen',
|
||||
},
|
||||
{
|
||||
name: 'dotStyle',
|
||||
type: 'select',
|
||||
defaultValue: 'dots',
|
||||
label: 'Punkte-Stil',
|
||||
options: [
|
||||
{ label: 'Punkte (rund)', value: 'dots' },
|
||||
{ label: 'Striche', value: 'lines' },
|
||||
{ label: 'Nummern', value: 'numbers' },
|
||||
{ label: 'Fortschritt', value: 'progress' },
|
||||
{ label: 'Fraktion (1/5)', value: 'fraction' },
|
||||
],
|
||||
admin: {
|
||||
condition: (_, siblingData) => siblingData?.dots,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'dotPos',
|
||||
type: 'select',
|
||||
defaultValue: 'bottom',
|
||||
label: 'Punkte-Position',
|
||||
options: [
|
||||
{ label: 'Unten', value: 'bottom' },
|
||||
{ label: 'Unten links', value: 'bl' },
|
||||
{ label: 'Unten rechts', value: 'br' },
|
||||
],
|
||||
admin: {
|
||||
condition: (_, siblingData) => siblingData?.dots,
|
||||
},
|
||||
},
|
||||
// Touch & Keyboard
|
||||
{
|
||||
name: 'swipe',
|
||||
type: 'checkbox',
|
||||
defaultValue: true,
|
||||
label: 'Touch-Swipe aktivieren',
|
||||
},
|
||||
{
|
||||
name: 'keys',
|
||||
type: 'checkbox',
|
||||
defaultValue: true,
|
||||
label: 'Tastaturnavigation',
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
// Darstellung
|
||||
{
|
||||
name: 'backgroundColor',
|
||||
type: 'select',
|
||||
defaultValue: 'light',
|
||||
label: 'Hintergrund',
|
||||
options: [
|
||||
{ label: 'Weiß', value: 'white' },
|
||||
{ label: 'Hell (Grau)', value: 'light' },
|
||||
{ label: 'Dunkel', value: 'dark' },
|
||||
{ label: 'Akzentfarbe', value: 'accent' },
|
||||
name: 'style',
|
||||
type: 'group',
|
||||
label: 'Darstellung',
|
||||
fields: [
|
||||
{
|
||||
name: 'bg',
|
||||
type: 'select',
|
||||
defaultValue: 'light',
|
||||
label: 'Hintergrund',
|
||||
options: [
|
||||
{ label: 'Weiß', value: 'white' },
|
||||
{ label: 'Hell (Grau)', value: 'light' },
|
||||
{ label: 'Dunkel', value: 'dark' },
|
||||
{ label: 'Akzentfarbe', value: 'accent' },
|
||||
{ label: 'Transparent', value: 'none' },
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'card',
|
||||
type: 'select',
|
||||
defaultValue: 'shadow',
|
||||
label: 'Karten-Stil',
|
||||
options: [
|
||||
{ label: 'Karte mit Schatten', value: 'shadow' },
|
||||
{ label: 'Karte mit Rahmen', value: 'border' },
|
||||
{ label: 'Flach (kein Rand)', value: 'flat' },
|
||||
{ label: 'Glassmorphism', value: 'glass' },
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'quote',
|
||||
type: 'select',
|
||||
defaultValue: 'icon',
|
||||
label: 'Zitat-Stil',
|
||||
options: [
|
||||
{ label: 'Mit Icon', value: 'icon' },
|
||||
{ label: 'Anführungszeichen', value: 'quotes' },
|
||||
{ label: 'Ohne', value: 'none' },
|
||||
{ label: 'Groß', value: 'large' },
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'imgPos',
|
||||
type: 'select',
|
||||
defaultValue: 'top',
|
||||
label: 'Bild-Position',
|
||||
options: [
|
||||
{ label: 'Oben', value: 'top' },
|
||||
{ label: 'Links', value: 'left' },
|
||||
{ label: 'Unten', value: 'bottom' },
|
||||
{ label: 'Hintergrund', value: 'bg' },
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'imgSize',
|
||||
type: 'select',
|
||||
defaultValue: 'md',
|
||||
label: 'Bild-Größe',
|
||||
options: [
|
||||
{ label: 'Klein (48px)', value: 'sm' },
|
||||
{ label: 'Mittel (64px)', value: 'md' },
|
||||
{ label: 'Groß (80px)', value: 'lg' },
|
||||
{ label: 'Sehr groß (96px)', value: 'xl' },
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'align',
|
||||
type: 'select',
|
||||
defaultValue: 'center',
|
||||
label: 'Text-Ausrichtung',
|
||||
options: [
|
||||
{ label: 'Links', value: 'left' },
|
||||
{ label: 'Zentriert', value: 'center' },
|
||||
{ label: 'Rechts', value: 'right' },
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'spacing',
|
||||
type: 'select',
|
||||
defaultValue: 'normal',
|
||||
label: 'Innenabstand',
|
||||
options: [
|
||||
{ label: 'Kompakt', value: 'sm' },
|
||||
{ label: 'Normal', value: 'normal' },
|
||||
{ label: 'Großzügig', value: 'lg' },
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
// Accessibility (nur für Slider)
|
||||
{
|
||||
name: 'a11y',
|
||||
type: 'group',
|
||||
label: 'Barrierefreiheit',
|
||||
admin: {
|
||||
condition: (_, siblingData) => siblingData?.layout === 'slider',
|
||||
},
|
||||
fields: [
|
||||
{
|
||||
name: 'label',
|
||||
type: 'text',
|
||||
defaultValue: 'Kundenstimmen',
|
||||
label: 'ARIA Label',
|
||||
localized: true,
|
||||
},
|
||||
{
|
||||
name: 'reducedMotion',
|
||||
type: 'checkbox',
|
||||
defaultValue: true,
|
||||
label: 'Reduzierte Bewegung respektieren',
|
||||
admin: {
|
||||
description: 'Autoplay deaktivieren bei "prefers-reduced-motion"',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
|
|
|
|||
250
src/migrations/20251213_160000_testimonials_slider_v2.ts
Normal file
250
src/migrations/20251213_160000_testimonials_slider_v2.ts
Normal file
|
|
@ -0,0 +1,250 @@
|
|||
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");
|
||||
`)
|
||||
}
|
||||
|
|
@ -720,13 +720,61 @@ export interface Page {
|
|||
displayMode?: ('all' | 'selected') | null;
|
||||
selectedTestimonials?: (number | Testimonial)[] | null;
|
||||
limit?: number | null;
|
||||
showRating?: boolean | null;
|
||||
showImage?: boolean | null;
|
||||
showCompany?: boolean | null;
|
||||
showSource?: boolean | null;
|
||||
autoplay?: boolean | null;
|
||||
autoplaySpeed?: number | null;
|
||||
backgroundColor?: ('white' | 'light' | 'dark' | 'accent') | null;
|
||||
displayOptions?: {
|
||||
showRating?: boolean | null;
|
||||
showImage?: boolean | null;
|
||||
showCompany?: boolean | null;
|
||||
showSource?: boolean | null;
|
||||
showDate?: boolean | null;
|
||||
/**
|
||||
* Lange Testimonials werden abgeschnitten mit "Mehr lesen"
|
||||
*/
|
||||
truncateText?: boolean | null;
|
||||
maxLength?: number | null;
|
||||
};
|
||||
slider?: {
|
||||
effect?: ('slide' | 'fade' | 'cards' | 'coverflow' | 'none') | null;
|
||||
speed?: ('300' | '500' | '800') | null;
|
||||
/**
|
||||
* Anzahl gleichzeitig sichtbarer Testimonials
|
||||
*/
|
||||
perView?: ('1' | '2' | '3' | 'auto') | null;
|
||||
gap?: ('0' | '16' | '24' | '32' | '48') | null;
|
||||
auto?: boolean | null;
|
||||
delay?: ('3000' | '4000' | '5000' | '6000' | '8000' | '10000') | null;
|
||||
hoverPause?: boolean | null;
|
||||
loop?: boolean | null;
|
||||
/**
|
||||
* Der aktive Slide wird in der Mitte angezeigt
|
||||
*/
|
||||
centered?: boolean | null;
|
||||
};
|
||||
nav?: {
|
||||
arrows?: boolean | null;
|
||||
arrowStyle?: ('default' | 'minimal' | 'square' | 'hover' | 'outside') | null;
|
||||
arrowPos?: ('sides' | 'bl' | 'br' | 'bc') | null;
|
||||
dots?: boolean | null;
|
||||
dotStyle?: ('dots' | 'lines' | 'numbers' | 'progress' | 'fraction') | null;
|
||||
dotPos?: ('bottom' | 'bl' | 'br') | null;
|
||||
swipe?: boolean | null;
|
||||
keys?: boolean | null;
|
||||
};
|
||||
style?: {
|
||||
bg?: ('white' | 'light' | 'dark' | 'accent' | 'none') | null;
|
||||
card?: ('shadow' | 'border' | 'flat' | 'glass') | null;
|
||||
quote?: ('icon' | 'quotes' | 'none' | 'large') | null;
|
||||
imgPos?: ('top' | 'left' | 'bottom' | 'bg') | null;
|
||||
imgSize?: ('sm' | 'md' | 'lg' | 'xl') | null;
|
||||
align?: ('left' | 'center' | 'right') | null;
|
||||
spacing?: ('sm' | 'normal' | 'lg') | null;
|
||||
};
|
||||
a11y?: {
|
||||
label?: string | null;
|
||||
/**
|
||||
* Autoplay deaktivieren bei "prefers-reduced-motion"
|
||||
*/
|
||||
reducedMotion?: boolean | null;
|
||||
};
|
||||
id?: string | null;
|
||||
blockName?: string | null;
|
||||
blockType: 'testimonials-block';
|
||||
|
|
@ -3531,13 +3579,59 @@ export interface PagesSelect<T extends boolean = true> {
|
|||
displayMode?: T;
|
||||
selectedTestimonials?: T;
|
||||
limit?: T;
|
||||
showRating?: T;
|
||||
showImage?: T;
|
||||
showCompany?: T;
|
||||
showSource?: T;
|
||||
autoplay?: T;
|
||||
autoplaySpeed?: T;
|
||||
backgroundColor?: T;
|
||||
displayOptions?:
|
||||
| T
|
||||
| {
|
||||
showRating?: T;
|
||||
showImage?: T;
|
||||
showCompany?: T;
|
||||
showSource?: T;
|
||||
showDate?: T;
|
||||
truncateText?: T;
|
||||
maxLength?: T;
|
||||
};
|
||||
slider?:
|
||||
| T
|
||||
| {
|
||||
effect?: T;
|
||||
speed?: T;
|
||||
perView?: T;
|
||||
gap?: T;
|
||||
auto?: T;
|
||||
delay?: T;
|
||||
hoverPause?: T;
|
||||
loop?: T;
|
||||
centered?: T;
|
||||
};
|
||||
nav?:
|
||||
| T
|
||||
| {
|
||||
arrows?: T;
|
||||
arrowStyle?: T;
|
||||
arrowPos?: T;
|
||||
dots?: T;
|
||||
dotStyle?: T;
|
||||
dotPos?: T;
|
||||
swipe?: T;
|
||||
keys?: T;
|
||||
};
|
||||
style?:
|
||||
| T
|
||||
| {
|
||||
bg?: T;
|
||||
card?: T;
|
||||
quote?: T;
|
||||
imgPos?: T;
|
||||
imgSize?: T;
|
||||
align?: T;
|
||||
spacing?: T;
|
||||
};
|
||||
a11y?:
|
||||
| T
|
||||
| {
|
||||
label?: T;
|
||||
reducedMotion?: T;
|
||||
};
|
||||
id?: T;
|
||||
blockName?: T;
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in a new issue