From c168832a128a38ae2c4f87057bc28b1b56b60236 Mon Sep 17 00:00:00 2001 From: Martin Porwoll Date: Tue, 17 Feb 2026 16:12:59 +0000 Subject: [PATCH] feat: update types for multi-tenant forms + refactored ContactFormBlock - forms + form-submissions now have tenant field - ContactFormBlock: form relationship replaces recipientEmail - New fields: successMessage, showContactInfo Co-Authored-By: Claude Opus 4.6 --- src/payload-types.ts | 13193 +++++++++++++++++++++++++++++++++++ src/types/blocks.ts | 7 + src/types/payload-types.ts | 357 +- 3 files changed, 13393 insertions(+), 164 deletions(-) create mode 100644 src/payload-types.ts diff --git a/src/payload-types.ts b/src/payload-types.ts new file mode 100644 index 0000000..bdde704 --- /dev/null +++ b/src/payload-types.ts @@ -0,0 +1,13193 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * This file was automatically generated by Payload. + * DO NOT MODIFY IT BY HAND. Instead, modify your source Payload config, + * and re-run `payload generate:types` to regenerate this file. + */ + +/** + * Supported timezones in IANA format. + * + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "supportedTimezones". + */ +export type SupportedTimezones = + | 'Pacific/Midway' + | 'Pacific/Niue' + | 'Pacific/Honolulu' + | 'Pacific/Rarotonga' + | 'America/Anchorage' + | 'Pacific/Gambier' + | 'America/Los_Angeles' + | 'America/Tijuana' + | 'America/Denver' + | 'America/Phoenix' + | 'America/Chicago' + | 'America/Guatemala' + | 'America/New_York' + | 'America/Bogota' + | 'America/Caracas' + | 'America/Santiago' + | 'America/Buenos_Aires' + | 'America/Sao_Paulo' + | 'Atlantic/South_Georgia' + | 'Atlantic/Azores' + | 'Atlantic/Cape_Verde' + | 'Europe/London' + | 'Europe/Berlin' + | 'Africa/Lagos' + | 'Europe/Athens' + | 'Africa/Cairo' + | 'Europe/Moscow' + | 'Asia/Riyadh' + | 'Asia/Dubai' + | 'Asia/Baku' + | 'Asia/Karachi' + | 'Asia/Tashkent' + | 'Asia/Calcutta' + | 'Asia/Dhaka' + | 'Asia/Almaty' + | 'Asia/Jakarta' + | 'Asia/Bangkok' + | 'Asia/Shanghai' + | 'Asia/Singapore' + | 'Asia/Tokyo' + | 'Asia/Seoul' + | 'Australia/Brisbane' + | 'Australia/Sydney' + | 'Pacific/Guam' + | 'Pacific/Noumea' + | 'Pacific/Auckland' + | 'Pacific/Fiji'; + +export interface Config { + auth: { + users: UserAuthOperations; + }; + blocks: {}; + collections: { + users: User; + media: Media; + tenants: Tenant; + pages: Page; + posts: Post; + categories: Category; + 'social-links': SocialLink; + testimonials: Testimonial; + faqs: Faq; + team: Team; + 'service-categories': ServiceCategory; + services: Service; + 'newsletter-subscribers': NewsletterSubscriber; + 'portfolio-categories': PortfolioCategory; + portfolios: Portfolio; + 'video-categories': VideoCategory; + videos: Video; + 'product-categories': ProductCategory; + products: Product; + timelines: Timeline; + workflows: Workflow; + tags: Tag; + authors: Author; + locations: Location; + partners: Partner; + jobs: Job; + downloads: Download; + events: Event; + bookings: Booking; + certifications: Certification; + projects: Project; + favorites: Favorite; + series: Series; + 'youtube-channels': YoutubeChannel; + 'youtube-content': YoutubeContent; + 'yt-tasks': YtTask; + 'yt-notifications': YtNotification; + 'yt-batches': YtBatch; + 'yt-monthly-goals': YtMonthlyGoal; + 'yt-script-templates': YtScriptTemplate; + 'yt-checklist-templates': YtChecklistTemplate; + 'yt-series': YtSery; + 'social-platforms': SocialPlatform; + 'social-accounts': SocialAccount; + 'community-interactions': CommunityInteraction; + 'community-templates': CommunityTemplate; + 'community-rules': CommunityRule; + 'report-schedules': ReportSchedule; + 'cookie-configurations': CookieConfiguration; + 'cookie-inventory': CookieInventory; + 'consent-logs': ConsentLog; + 'privacy-policy-settings': PrivacyPolicySetting; + 'email-logs': EmailLog; + 'audit-logs': AuditLog; + 'monitoring-snapshots': MonitoringSnapshot; + 'monitoring-logs': MonitoringLog; + 'monitoring-alert-rules': MonitoringAlertRule; + 'monitoring-alert-history': MonitoringAlertHistory; + 'site-settings': SiteSetting; + navigations: Navigation; + forms: Form; + 'form-submissions': FormSubmission; + redirects: Redirect; + 'payload-kv': PayloadKv; + 'payload-locked-documents': PayloadLockedDocument; + 'payload-preferences': PayloadPreference; + 'payload-migrations': PayloadMigration; + }; + collectionsJoins: {}; + collectionsSelect: { + users: UsersSelect | UsersSelect; + media: MediaSelect | MediaSelect; + tenants: TenantsSelect | TenantsSelect; + pages: PagesSelect | PagesSelect; + posts: PostsSelect | PostsSelect; + categories: CategoriesSelect | CategoriesSelect; + 'social-links': SocialLinksSelect | SocialLinksSelect; + testimonials: TestimonialsSelect | TestimonialsSelect; + faqs: FaqsSelect | FaqsSelect; + team: TeamSelect | TeamSelect; + 'service-categories': ServiceCategoriesSelect | ServiceCategoriesSelect; + services: ServicesSelect | ServicesSelect; + 'newsletter-subscribers': NewsletterSubscribersSelect | NewsletterSubscribersSelect; + 'portfolio-categories': PortfolioCategoriesSelect | PortfolioCategoriesSelect; + portfolios: PortfoliosSelect | PortfoliosSelect; + 'video-categories': VideoCategoriesSelect | VideoCategoriesSelect; + videos: VideosSelect | VideosSelect; + 'product-categories': ProductCategoriesSelect | ProductCategoriesSelect; + products: ProductsSelect | ProductsSelect; + timelines: TimelinesSelect | TimelinesSelect; + workflows: WorkflowsSelect | WorkflowsSelect; + tags: TagsSelect | TagsSelect; + authors: AuthorsSelect | AuthorsSelect; + locations: LocationsSelect | LocationsSelect; + partners: PartnersSelect | PartnersSelect; + jobs: JobsSelect | JobsSelect; + downloads: DownloadsSelect | DownloadsSelect; + events: EventsSelect | EventsSelect; + bookings: BookingsSelect | BookingsSelect; + certifications: CertificationsSelect | CertificationsSelect; + projects: ProjectsSelect | ProjectsSelect; + favorites: FavoritesSelect | FavoritesSelect; + series: SeriesSelect | SeriesSelect; + 'youtube-channels': YoutubeChannelsSelect | YoutubeChannelsSelect; + 'youtube-content': YoutubeContentSelect | YoutubeContentSelect; + 'yt-tasks': YtTasksSelect | YtTasksSelect; + 'yt-notifications': YtNotificationsSelect | YtNotificationsSelect; + 'yt-batches': YtBatchesSelect | YtBatchesSelect; + 'yt-monthly-goals': YtMonthlyGoalsSelect | YtMonthlyGoalsSelect; + 'yt-script-templates': YtScriptTemplatesSelect | YtScriptTemplatesSelect; + 'yt-checklist-templates': YtChecklistTemplatesSelect | YtChecklistTemplatesSelect; + 'yt-series': YtSeriesSelect | YtSeriesSelect; + 'social-platforms': SocialPlatformsSelect | SocialPlatformsSelect; + 'social-accounts': SocialAccountsSelect | SocialAccountsSelect; + 'community-interactions': CommunityInteractionsSelect | CommunityInteractionsSelect; + 'community-templates': CommunityTemplatesSelect | CommunityTemplatesSelect; + 'community-rules': CommunityRulesSelect | CommunityRulesSelect; + 'report-schedules': ReportSchedulesSelect | ReportSchedulesSelect; + 'cookie-configurations': CookieConfigurationsSelect | CookieConfigurationsSelect; + 'cookie-inventory': CookieInventorySelect | CookieInventorySelect; + 'consent-logs': ConsentLogsSelect | ConsentLogsSelect; + 'privacy-policy-settings': PrivacyPolicySettingsSelect | PrivacyPolicySettingsSelect; + 'email-logs': EmailLogsSelect | EmailLogsSelect; + 'audit-logs': AuditLogsSelect | AuditLogsSelect; + 'monitoring-snapshots': MonitoringSnapshotsSelect | MonitoringSnapshotsSelect; + 'monitoring-logs': MonitoringLogsSelect | MonitoringLogsSelect; + 'monitoring-alert-rules': MonitoringAlertRulesSelect | MonitoringAlertRulesSelect; + 'monitoring-alert-history': MonitoringAlertHistorySelect | MonitoringAlertHistorySelect; + 'site-settings': SiteSettingsSelect | SiteSettingsSelect; + navigations: NavigationsSelect | NavigationsSelect; + forms: FormsSelect | FormsSelect; + 'form-submissions': FormSubmissionsSelect | FormSubmissionsSelect; + redirects: RedirectsSelect | RedirectsSelect; + 'payload-kv': PayloadKvSelect | PayloadKvSelect; + 'payload-locked-documents': PayloadLockedDocumentsSelect | PayloadLockedDocumentsSelect; + 'payload-preferences': PayloadPreferencesSelect | PayloadPreferencesSelect; + 'payload-migrations': PayloadMigrationsSelect | PayloadMigrationsSelect; + }; + db: { + defaultIDType: number; + }; + fallbackLocale: ('false' | 'none' | 'null') | false | null | ('de' | 'en') | ('de' | 'en')[]; + globals: { + 'seo-settings': SeoSetting; + }; + globalsSelect: { + 'seo-settings': SeoSettingsSelect | SeoSettingsSelect; + }; + locale: 'de' | 'en'; + user: User; + jobs: { + tasks: unknown; + workflows: unknown; + }; +} +export interface UserAuthOperations { + forgotPassword: { + email: string; + password: string; + }; + login: { + email: string; + password: string; + }; + registerFirstUser: { + email: string; + password: string; + }; + unlock: { + email: string; + password: string; + }; +} +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "users". + */ +export interface User { + id: number; + /** + * Super Admins haben Zugriff auf alle Tenants und können neue Tenants erstellen. + */ + isSuperAdmin?: boolean | null; + /** + * Rolle im YouTube Operations Hub + */ + youtubeRole?: ('none' | 'viewer' | 'editor' | 'producer' | 'creator' | 'manager') | null; + /** + * Zugewiesene YouTube-Kanäle + */ + youtubeChannels?: (number | YoutubeChannel)[] | null; + /** + * Zugriff auf Community Management Features + */ + communityRole?: ('none' | 'viewer' | 'moderator' | 'manager') | null; + tenants?: + | { + tenant: number | Tenant; + id?: string | null; + }[] + | null; + updatedAt: string; + createdAt: string; + email: string; + resetPasswordToken?: string | null; + resetPasswordExpiration?: string | null; + salt?: string | null; + hash?: string | null; + loginAttempts?: number | null; + lockUntil?: string | null; + sessions?: + | { + id: string; + createdAt?: string | null; + expiresAt: string; + }[] + | null; + password?: string | null; + collection: 'users'; +} +/** + * YouTube-Kanäle und ihre Konfiguration + * + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "youtube-channels". + */ +export interface YoutubeChannel { + id: number; + /** + * z.B. "BlogWoman by Caroline Porwoll" + */ + name: string; + /** + * Interner Kurzname (z.B. "blogwoman", "corporate-de") + */ + slug: string; + /** + * Die YouTube Channel ID (z.B. "UCxxxxxxxxxxxxx") + */ + youtubeChannelId: string; + /** + * z.B. "@blogwoman" oder "@zweitmeinu.ng" + */ + youtubeHandle?: string | null; + language: 'de' | 'en'; + category: 'lifestyle' | 'corporate' | 'b2b'; + status: 'active' | 'planned' | 'paused' | 'archived'; + /** + * Profil-Thumbnail URL von YouTube (automatisch befüllt) + */ + channelThumbnailUrl?: string | null; + branding?: { + /** + * z.B. #1278B3 + */ + primaryColor?: string | null; + secondaryColor?: string | null; + logo?: (number | null) | Media; + thumbnailTemplate?: (number | null) | Media; + }; + publishingSchedule?: { + defaultDays?: ('monday' | 'tuesday' | 'wednesday' | 'thursday' | 'friday' | 'saturday' | 'sunday')[] | null; + /** + * z.B. "12:00" + */ + defaultTime?: string | null; + shortsPerWeek?: number | null; + longformPerWeek?: number | null; + }; + /** + * Automatisch via YouTube API aktualisiert + */ + currentMetrics?: { + subscriberCount?: number | null; + totalViews?: number | null; + videoCount?: number | null; + lastSyncedAt?: string | null; + }; + updatedAt: string; + createdAt: string; +} +/** + * Bilder und Dokumente mit automatischer Optimierung + * + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "media". + */ +export interface Media { + id: number; + tenant?: (number | null) | Tenant; + /** + * Beschreibung für Screenreader und SEO (Pflichtfeld) + */ + alt: string; + /** + * Optionale Bildunterschrift für Darstellung unter dem Bild + */ + caption?: string | null; + /** + * Fotograf, Agentur oder Quelle + */ + credit?: string | null; + /** + * Schlagwörter für die Suche und Filterung + */ + tags?: string[] | null; + updatedAt: string; + createdAt: string; + url?: string | null; + thumbnailURL?: string | null; + filename?: string | null; + mimeType?: string | null; + filesize?: number | null; + width?: number | null; + height?: number | null; + focalX?: number | null; + focalY?: number | null; + sizes?: { + thumbnail?: { + url?: string | null; + width?: number | null; + height?: number | null; + mimeType?: string | null; + filesize?: number | null; + filename?: string | null; + }; + small?: { + url?: string | null; + width?: number | null; + height?: number | null; + mimeType?: string | null; + filesize?: number | null; + filename?: string | null; + }; + medium?: { + url?: string | null; + width?: number | null; + height?: number | null; + mimeType?: string | null; + filesize?: number | null; + filename?: string | null; + }; + large?: { + url?: string | null; + width?: number | null; + height?: number | null; + mimeType?: string | null; + filesize?: number | null; + filename?: string | null; + }; + xlarge?: { + url?: string | null; + width?: number | null; + height?: number | null; + mimeType?: string | null; + filesize?: number | null; + filename?: string | null; + }; + '2k'?: { + url?: string | null; + width?: number | null; + height?: number | null; + mimeType?: string | null; + filesize?: number | null; + filename?: string | null; + }; + og?: { + url?: string | null; + width?: number | null; + height?: number | null; + mimeType?: string | null; + filesize?: number | null; + filename?: string | null; + }; + medium_avif?: { + url?: string | null; + width?: number | null; + height?: number | null; + mimeType?: string | null; + filesize?: number | null; + filename?: string | null; + }; + large_avif?: { + url?: string | null; + width?: number | null; + height?: number | null; + mimeType?: string | null; + filesize?: number | null; + filename?: string | null; + }; + xlarge_avif?: { + url?: string | null; + width?: number | null; + height?: number | null; + mimeType?: string | null; + filesize?: number | null; + filename?: string | null; + }; + }; +} +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "tenants". + */ +export interface Tenant { + id: number; + name: string; + slug: string; + domains?: + | { + domain: string; + id?: string | null; + }[] + | null; + /** + * SMTP-Einstellungen für diesen Tenant. Leer = globale Einstellungen. + */ + email?: { + /** + * Tipp: Verwenden Sie eine E-Mail-Adresse der Domain, für die SPF/DKIM konfiguriert ist. + */ + fromAddress?: string | null; + fromName?: string | null; + replyTo?: string | null; + /** + * Aktivieren Sie diese Option, um einen eigenen SMTP-Server statt der globalen Einstellungen zu verwenden. + */ + useCustomSmtp?: boolean | null; + /** + * Hinweis: Stellen Sie sicher, dass SPF- und DKIM-Einträge für Ihre Domain konfiguriert sind, um eine optimale E-Mail-Zustellung zu gewährleisten. + */ + smtp?: { + /** + * Hostname ohne Protokoll (z.B. smtp.gmail.com) + */ + host?: string | null; + /** + * 587 (STARTTLS) oder 465 (SSL) + */ + port?: number | null; + /** + * Für Port 465 aktivieren + */ + secure?: boolean | null; + /** + * Meist die E-Mail-Adresse + */ + user?: string | null; + /** + * Leer lassen um bestehendes Passwort zu behalten + */ + pass?: string | null; + }; + }; + updatedAt: string; + createdAt: string; +} +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "pages". + */ +export interface Page { + id: number; + tenant?: (number | null) | Tenant; + title: string; + /** + * URL-Pfad (z.B. "ueber-uns" / "about-us") + */ + slug: string; + layout?: + | ( + | { + backgroundImage?: (number | null) | Media; + headline: string; + subline?: string | null; + alignment?: ('left' | 'center' | 'right') | null; + overlay?: boolean | null; + cta?: { + text?: string | null; + link?: string | null; + style?: ('primary' | 'secondary' | 'outline') | null; + }; + id?: string | null; + blockName?: string | null; + blockType: 'hero-block'; + } + | { + /** + * Mindestens 1 Slide erforderlich, maximal 10 Slides + */ + slides: { + /** + * Empfohlen: 1920x1080px oder größer + */ + backgroundImage: number | Media; + /** + * Optional: Alternatives Bild für mobile Geräte (Portrait-Format empfohlen) + */ + mobileBackgroundImage?: (number | null) | Media; + /** + * Hauptüberschrift des Slides + */ + headline: string; + /** + * Optionaler Untertitel oder kurze Beschreibung + */ + subline?: string | null; + textAlignment?: ('left' | 'center' | 'right') | null; + verticalPosition?: ('top' | 'center' | 'bottom') | null; + overlay?: { + enabled?: boolean | null; + color?: ('dark' | 'light' | 'primary' | 'gradient-bottom' | 'gradient-top') | null; + opacity?: ('20' | '30' | '40' | '50' | '60' | '70' | '80') | null; + }; + primaryCta?: { + enabled?: boolean | null; + text?: string | null; + /** + * URL oder interner Pfad (z.B. /kontakt) + */ + link?: string | null; + style?: ('primary' | 'secondary' | 'outline-white' | 'outline-dark') | null; + openInNewTab?: boolean | null; + }; + secondaryCta?: { + enabled?: boolean | null; + text?: string | null; + link?: string | null; + style?: ('primary' | 'secondary' | 'outline-white' | 'outline-dark' | 'text') | null; + openInNewTab?: boolean | null; + }; + textColor?: ('white' | 'dark' | 'primary') | null; + id?: string | null; + }[]; + settings?: { + /** + * Art des Übergangs zwischen den Slides + */ + animation?: ('fade' | 'slide' | 'zoom' | 'flip' | 'none') | null; + animationDuration?: ('300' | '500' | '800' | '1200') | null; + autoplay?: { + enabled?: boolean | null; + interval?: ('3000' | '4000' | '5000' | '6000' | '7000' | '8000' | '10000') | null; + /** + * Autoplay pausiert, wenn der Mauszeiger über dem Slider ist + */ + pauseOnHover?: boolean | null; + /** + * Autoplay pausiert nach manueller Navigation + */ + pauseOnInteraction?: boolean | null; + }; + /** + * Nach dem letzten Slide automatisch zum ersten springen + */ + loop?: boolean | null; + }; + navigation?: { + arrows?: { + enabled?: boolean | null; + style?: ('default' | 'minimal' | 'square' | 'hover-only') | null; + position?: ('sides' | 'bottom-left' | 'bottom-right' | 'bottom-center') | null; + hideOnMobile?: boolean | null; + }; + dots?: { + enabled?: boolean | null; + style?: ('dots' | 'lines' | 'numbers' | 'thumbnails' | 'progress') | null; + position?: ('bottom-center' | 'bottom-left' | 'bottom-right' | 'left' | 'right') | null; + color?: ('white' | 'dark' | 'primary') | null; + }; + /** + * Ermöglicht Wischen auf Touch-Geräten + */ + swipe?: boolean | null; + /** + * Navigation mit Pfeiltasten ermöglichen + */ + keyboard?: boolean | null; + }; + layout?: { + height?: ('viewport' | 'large' | 'medium' | 'small' | 'compact' | 'auto') | null; + mobileHeight?: ('same' | 'viewport' | 'large' | 'medium' | 'small' | 'compact') | null; + contentWidth?: ('container' | 'narrow' | 'wide' | 'full') | null; + /** + * Slider nimmt die volle Bildschirmbreite ein + */ + fullWidth?: boolean | null; + }; + accessibility?: { + /** + * Beschreibung für Screenreader + */ + ariaLabel?: string | null; + /** + * Autoplay deaktivieren, wenn der User "prefers-reduced-motion" aktiviert hat + */ + reducedMotion?: boolean | null; + }; + id?: string | null; + blockName?: string | null; + blockType: 'hero-slider-block'; + } + | { + /** + * Optionaler Titel über der Galerie + */ + title?: string | null; + description?: string | null; + /** + * Mindestens 1 Bild, maximal 50 Bilder + */ + images: { + image: number | Media; + caption?: string | null; + /** + * Alternativer Text für Barrierefreiheit (falls abweichend vom Media Alt) + */ + alt?: string | null; + /** + * Optionaler Link beim Klick (statt Lightbox) + */ + link?: string | null; + id?: string | null; + }[]; + layout?: ('slider' | 'grid' | 'masonry' | 'single' | 'thumbs' | 'filmstrip') | null; + grid?: { + cols?: ('2' | '3' | '4' | '5' | '6') | null; + gap?: ('0' | '8' | '16' | '24' | '32') | null; + aspectRatio?: ('square' | '4-3' | '16-9' | '3-4' | 'auto') | null; + }; + slider?: { + effect?: ('slide' | 'fade' | 'zoom' | 'flip' | 'coverflow' | 'cube') | null; + speed?: ('300' | '500' | '800') | null; + perView?: ('1' | '2' | '3' | '4' | 'auto') | null; + gap?: ('0' | '8' | '16' | '24') | null; + auto?: boolean | null; + delay?: ('3000' | '4000' | '5000' | '6000' | '8000') | null; + pauseHover?: boolean | null; + loop?: boolean | null; + centered?: boolean | null; + }; + nav?: { + arrows?: boolean | null; + arrowStyle?: ('default' | 'minimal' | 'square' | 'hover') | null; + dots?: boolean | null; + dotStyle?: ('dots' | 'lines' | 'numbers' | 'progress') | null; + counter?: boolean | null; + swipe?: boolean | null; + keys?: boolean | null; + }; + lightbox?: { + /** + * Bilder bei Klick in Vollansicht öffnen + */ + enabled?: boolean | null; + zoom?: boolean | null; + download?: boolean | null; + share?: boolean | null; + captions?: boolean | null; + thumbs?: boolean | null; + bg?: ('dark' | 'light' | 'blur') | null; + }; + style?: { + height?: ('auto' | '300' | '400' | '500' | '600' | 'full') | null; + imgFit?: ('cover' | 'contain' | 'fill') | null; + rounded?: ('none' | 'sm' | 'md' | 'lg' | 'full') | null; + shadow?: boolean | null; + border?: boolean | null; + hoverEffect?: ('none' | 'zoom' | 'brighten' | 'darken' | 'overlay') | null; + captionPos?: ('below' | 'overlay' | 'hover' | 'hidden') | null; + bg?: ('none' | 'white' | 'light' | 'dark') | null; + padding?: ('none' | 'sm' | 'md' | 'lg') | null; + }; + a11y?: { + label?: string | null; + reducedMotion?: boolean | null; + }; + id?: string | null; + blockName?: string | null; + blockType: 'image-slider-block'; + } + | { + content: { + root: { + type: string; + children: { + type: any; + version: number; + [k: string]: unknown; + }[]; + direction: ('ltr' | 'rtl') | null; + format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | ''; + indent: number; + version: number; + }; + [k: string]: unknown; + }; + width?: ('narrow' | 'medium' | 'full') | null; + id?: string | null; + blockName?: string | null; + blockType: 'text-block'; + } + | { + image: number | Media; + imagePosition?: ('left' | 'right') | null; + headline?: string | null; + content?: { + root: { + type: string; + children: { + type: any; + version: number; + [k: string]: unknown; + }[]; + direction: ('ltr' | 'rtl') | null; + format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | ''; + indent: number; + version: number; + }; + [k: string]: unknown; + } | null; + cta?: { + text?: string | null; + link?: string | null; + }; + id?: string | null; + blockName?: string | null; + blockType: 'image-text-block'; + } + | { + headline?: string | null; + cards?: + | { + mediaType?: ('none' | 'image' | 'icon') | null; + image?: (number | null) | Media; + /** + * Lucide Icon-Name (z.B. "heart", "star", "shield-check", "camera") + */ + icon?: string | null; + iconPosition?: ('top' | 'left') | null; + title: string; + description?: string | null; + link?: string | null; + linkText?: string | null; + id?: string | null; + }[] + | null; + columns?: ('2' | '3' | '4') | null; + id?: string | null; + blockName?: string | null; + blockType: 'card-grid-block'; + } + | { + quote: string; + author?: string | null; + role?: string | null; + image?: (number | null) | Media; + style?: ('simple' | 'highlighted' | 'with-image') | null; + id?: string | null; + blockName?: string | null; + blockType: 'quote-block'; + } + | { + headline: string; + description?: string | null; + buttons?: + | { + text: string; + link: string; + style?: ('primary' | 'secondary' | 'outline') | null; + id?: string | null; + }[] + | null; + backgroundColor?: ('dark' | 'light' | 'accent') | null; + id?: string | null; + blockName?: string | null; + blockType: 'cta-block'; + } + | { + /** + * Wählen Sie ein Formular aus der Formulare-Sammlung + */ + form: number | Form; + headline?: string | null; + description?: string | null; + successMessage?: string | null; + showContactInfo?: boolean | null; + showPhone?: boolean | null; + showAddress?: boolean | null; + showSocials?: boolean | null; + id?: string | null; + blockName?: string | null; + blockType: 'contact-form-block'; + } + | { + title?: string | null; + subtitle?: string | null; + layout?: ('vertical' | 'alternating' | 'horizontal') | null; + showConnector?: boolean | null; + markerStyle?: ('dot' | 'number' | 'icon' | 'date') | null; + items?: + | { + /** + * z.B. "2024", "Januar 2024", "15.03.2024" + */ + year?: string | null; + title: string; + description?: string | null; + /** + * Emoji oder Icon-Name + */ + icon?: string | null; + image?: (number | null) | Media; + link?: { + label?: string | null; + href?: string | null; + }; + id?: string | null; + }[] + | null; + backgroundColor?: ('white' | 'light' | 'dark') | null; + id?: string | null; + blockName?: string | null; + blockType: 'timeline-block'; + } + | { + style?: ('line' | 'space' | 'dots') | null; + spacing?: ('small' | 'medium' | 'large') | null; + id?: string | null; + blockName?: string | null; + blockType: 'divider-block'; + } + | { + /** + * Woher soll das Video eingebunden werden? + */ + sourceType: 'embed' | 'upload' | 'library' | 'external'; + /** + * Video aus der Video-Bibliothek auswählen + */ + videoFromLibrary?: (number | null) | Video; + /** + * YouTube, Vimeo oder externe Video-URL + */ + videoUrl?: string | null; + /** + * MP4, WebM oder andere Video-Dateien hochladen + */ + videoFile?: (number | null) | Media; + /** + * Eigenes Thumbnail (optional, bei YouTube wird automatisch eines verwendet) + */ + thumbnail?: (number | null) | Media; + /** + * Bildunterschrift unter dem Video + */ + caption?: string | null; + aspectRatio?: ('16:9' | '4:3' | '1:1' | '9:16' | '21:9') | null; + /** + * Breite des Video-Containers + */ + size?: ('full' | 'large' | 'medium' | 'small') | null; + alignment?: ('left' | 'center' | 'right') | null; + playback?: { + /** + * Video automatisch starten (erfordert meist Mute) + */ + autoplay?: boolean | null; + /** + * Video stumm abspielen + */ + muted?: boolean | null; + /** + * Video in Endlosschleife abspielen + */ + loop?: boolean | null; + /** + * Video-Controls anzeigen + */ + controls?: boolean | null; + /** + * Auf Mobile inline statt Vollbild abspielen + */ + playsinline?: boolean | null; + /** + * Video ab dieser Sekunde starten + */ + startTime?: number | null; + }; + embedOptions?: { + /** + * Am Ende ähnliche Videos von YouTube/Vimeo anzeigen + */ + showRelated?: boolean | null; + /** + * YouTube-nocookie.com verwenden (DSGVO-konformer) + */ + privacyMode?: boolean | null; + }; + style?: { + rounded?: ('none' | 'sm' | 'md' | 'lg' | 'xl') | null; + shadow?: ('none' | 'sm' | 'md' | 'lg' | 'xl') | null; + border?: boolean | null; + }; + id?: string | null; + blockName?: string | null; + blockType: 'video-block'; + } + | { + title?: string | null; + subtitle?: string | null; + postType: 'blog' | 'news' | 'press' | 'announcement' | 'all'; + layout?: ('grid' | 'list' | 'featured' | 'compact' | 'masonry') | null; + columns?: ('2' | '3' | '4') | null; + limit?: number | null; + showFeaturedOnly?: boolean | null; + /** + * Leer = alle Kategorien + */ + filterByCategory?: (number | Category)[] | null; + showExcerpt?: boolean | null; + showDate?: boolean | null; + showAuthor?: boolean | null; + showCategory?: boolean | null; + showPagination?: boolean | null; + showReadMore?: boolean | null; + readMoreLabel?: string | null; + readMoreLink?: string | null; + backgroundColor?: ('white' | 'light' | 'dark') | null; + id?: string | null; + blockName?: string | null; + blockType: 'posts-list-block'; + } + | { + title?: string | null; + subtitle?: string | null; + layout?: ('slider' | 'grid' | 'single' | 'masonry' | 'list') | null; + columns?: ('2' | '3' | '4') | null; + displayMode?: ('all' | 'selected') | null; + selectedTestimonials?: (number | Testimonial)[] | null; + limit?: number | 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'; + } + | { + title?: string | null; + subtitle?: string | null; + layout?: ('inline' | 'stacked' | 'with-image' | 'minimal' | 'card') | null; + image?: (number | null) | Media; + imagePosition?: ('left' | 'right') | null; + collectName?: boolean | null; + showInterests?: boolean | null; + availableInterests?: ('general' | 'blog' | 'products' | 'offers' | 'events')[] | null; + buttonText?: string | null; + placeholderEmail?: string | null; + successMessage?: string | null; + errorMessage?: string | null; + privacyText?: string | null; + privacyLink?: string | null; + /** + * Wird gespeichert um zu tracken, wo die Anmeldung erfolgte + */ + source?: string | null; + backgroundColor?: ('white' | 'light' | 'dark' | 'accent') | null; + id?: string | null; + blockName?: string | null; + blockType: 'newsletter-block'; + } + | { + title?: string | null; + subtitle?: string | null; + layout?: ('horizontal' | 'vertical' | 'alternating' | 'connected' | 'timeline') | null; + showNumbers?: boolean | null; + showIcons?: boolean | null; + steps?: + | { + title: string; + description?: string | null; + /** + * Emoji oder Icon-Name (z.B. "📞", "✓", "1") + */ + icon?: string | null; + image?: (number | null) | Media; + id?: string | null; + }[] + | null; + cta?: { + show?: boolean | null; + label?: string | null; + href?: string | null; + variant?: ('default' | 'ghost' | 'light') | null; + }; + backgroundColor?: ('white' | 'light' | 'dark') | null; + id?: string | null; + blockName?: string | null; + blockType: 'process-steps-block'; + } + | { + title?: string | null; + subtitle?: string | null; + sourceMode?: ('collection' | 'inline') | null; + displayMode?: ('all' | 'featured' | 'category' | 'selected') | null; + /** + * Zeigt nur FAQs mit dieser Kategorie + */ + category?: string | null; + selectedFAQs?: (number | Faq)[] | null; + limit?: number | null; + inlineFAQs?: + | { + question: string; + answer: { + root: { + type: string; + children: { + type: any; + version: number; + [k: string]: unknown; + }[]; + direction: ('ltr' | 'rtl') | null; + format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | ''; + indent: number; + version: number; + }; + [k: string]: unknown; + }; + /** + * Kurzfassung als reiner Text für SEO Structured Data + */ + answerPlainText?: string | null; + id?: string | null; + }[] + | null; + layout?: ('accordion' | 'grid' | 'list' | 'two-column') | null; + columns?: ('2' | '3') | null; + expandFirst?: boolean | null; + allowMultipleOpen?: boolean | null; + showCategory?: boolean | null; + showIcon?: boolean | null; + groupByCategory?: boolean | null; + /** + * Generiert SEO-optimiertes JSON-LD Structured Data + */ + enableSchemaOrg?: boolean | null; + backgroundColor?: ('white' | 'light' | 'dark' | 'accent') | null; + /** + * Zeigt einen "Frage nicht gefunden? Kontaktieren Sie uns" Button + */ + showContactCTA?: boolean | null; + contactCTAText?: string | null; + contactCTALink?: string | null; + contactCTAButtonText?: string | null; + id?: string | null; + blockName?: string | null; + blockType: 'faq-block'; + } + | { + title?: string | null; + subtitle?: string | null; + /** + * Optionaler Text vor der Team-Anzeige + */ + introduction?: { + root: { + type: string; + children: { + type: any; + version: number; + [k: string]: unknown; + }[]; + direction: ('ltr' | 'rtl') | null; + format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | ''; + indent: number; + version: number; + }; + [k: string]: unknown; + } | null; + displayMode?: ('all' | 'featured' | 'department' | 'selected') | null; + /** + * Zeigt nur Mitglieder dieser Abteilung + */ + department?: string | null; + selectedMembers?: (number | Team)[] | null; + limit?: number | null; + layout?: ('grid' | 'list' | 'slider' | 'compact' | 'detailed') | null; + columns?: ('2' | '3' | '4') | null; + showRole?: boolean | null; + showDepartment?: boolean | null; + showBio?: boolean | null; + /** + * Nur wenn beim Mitglied "Kontaktdaten öffentlich anzeigen" aktiviert ist + */ + showContact?: boolean | null; + showSocialLinks?: boolean | null; + showQualifications?: boolean | null; + showSpecializations?: boolean | null; + showLanguages?: boolean | null; + groupByDepartment?: boolean | null; + autoplay?: boolean | null; + autoplaySpeed?: number | null; + /** + * Klick auf Mitglied öffnet Modal/Lightbox mit allen Details + */ + enableDetailView?: boolean | null; + imageStyle?: ('circle' | 'rounded' | 'square') | null; + backgroundColor?: ('white' | 'light' | 'dark' | 'accent') | null; + showCTA?: boolean | null; + ctaText?: string | null; + ctaLink?: string | null; + id?: string | null; + blockName?: string | null; + blockType: 'team-block'; + } + | { + title?: string | null; + subtitle?: string | null; + /** + * Optionaler Text vor der Leistungsübersicht + */ + introduction?: { + root: { + type: string; + children: { + type: any; + version: number; + [k: string]: unknown; + }[]; + direction: ('ltr' | 'rtl') | null; + format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | ''; + indent: number; + version: number; + }; + [k: string]: unknown; + } | null; + displayMode?: ('all' | 'featured' | 'category' | 'selected') | null; + /** + * Zeigt nur Leistungen dieser Kategorie + */ + category?: (number | null) | ServiceCategory; + selectedServices?: (number | Service)[] | null; + limit?: number | null; + layout?: + | ('grid' | 'list' | 'tabs' | 'accordion' | 'featured-grid' | 'slider' | 'compact' | 'masonry') + | null; + columns?: ('2' | '3' | '4') | null; + /** + * Anzahl der hervorgehobenen Leistungen oben + */ + featuredCount?: number | null; + tabsStyle?: ('horizontal' | 'vertical' | 'pills') | null; + showAllTab?: boolean | null; + expandFirst?: boolean | null; + allowMultipleOpen?: boolean | null; + autoplay?: boolean | null; + autoplaySpeed?: number | null; + slidesPerView?: ('1' | '2' | '3' | '4') | null; + showImage?: boolean | null; + showIcon?: boolean | null; + showDescription?: boolean | null; + showCategory?: boolean | null; + showPricing?: boolean | null; + showFeatures?: boolean | null; + featuresLimit?: number | null; + showCTA?: boolean | null; + showNewBadge?: boolean | null; + /** + * Zeigt Kategorie-Überschriften zwischen den Leistungen + */ + groupByCategory?: boolean | null; + /** + * Karten/Einträge verlinken zur Leistungs-Detail-Seite + */ + linkToDetail?: boolean | null; + detailLinkText?: string | null; + /** + * z.B. "/leistungen" → "/leistungen/intensivpflege" + */ + servicesBasePath?: string | null; + cardStyle?: ('elevated' | 'bordered' | 'flat' | 'filled') | null; + backgroundColor?: ('white' | 'light' | 'dark' | 'accent') | null; + showSectionCTA?: boolean | null; + sectionCTAText?: string | null; + sectionCTALink?: string | null; + id?: string | null; + blockName?: string | null; + blockType: 'services-block'; + } + | { + /** + * Woher sollen die Autoren-Daten kommen? + */ + source?: ('post' | 'manual') | null; + /** + * Wählen Sie die anzuzeigenden Autoren + */ + authors?: (number | Author)[] | null; + /** + * Auch Co-Autoren des Artikels anzeigen + */ + showCoAuthors?: boolean | null; + layout?: ('card' | 'inline' | 'compact' | 'feature') | null; + show?: { + avatar?: boolean | null; + name?: boolean | null; + title?: boolean | null; + bio?: ('none' | 'short' | 'full') | null; + social?: boolean | null; + email?: boolean | null; + website?: boolean | null; + postCount?: boolean | null; + }; + style?: { + avatarSize?: ('sm' | 'md' | 'lg') | null; + avatarShape?: ('circle' | 'square' | 'rounded') | null; + bg?: ('none' | 'light' | 'dark' | 'accent') | null; + border?: boolean | null; + shadow?: boolean | null; + /** + * Linie zur Trennung vom Artikel-Inhalt + */ + divider?: boolean | null; + }; + /** + * z.B. "Über den Autor", "Geschrieben von" (optional) + */ + label?: string | null; + linkToProfile?: boolean | null; + id?: string | null; + blockName?: string | null; + blockType: 'author-bio-block'; + } + | { + title?: string | null; + source?: ('auto' | 'manual' | 'category' | 'tag' | 'latest' | 'popular' | 'author') | null; + /** + * Wählen Sie die anzuzeigenden Artikel + */ + posts?: (number | Post)[] | null; + category?: (number | null) | Category; + tag?: (number | null) | Tag; + limit?: number | null; + /** + * Den Artikel, auf dem dieser Block ist, nicht anzeigen + */ + excludeCurrent?: boolean | null; + layout?: ('grid' | 'list' | 'slider' | 'compact' | 'cards') | null; + cols?: ('2' | '3' | '4') | null; + show?: { + image?: boolean | null; + date?: boolean | null; + author?: boolean | null; + category?: boolean | null; + excerpt?: boolean | null; + readingTime?: boolean | null; + tags?: boolean | null; + }; + style?: { + imgRatio?: ('square' | '4-3' | '16-9' | '3-4') | null; + rounded?: ('none' | 'sm' | 'md' | 'lg') | null; + shadow?: boolean | null; + hover?: ('none' | 'lift' | 'zoom' | 'overlay') | null; + bg?: ('none' | 'light' | 'dark') | null; + gap?: ('16' | '24' | '32') | null; + }; + showAllLink?: boolean | null; + allLinkText?: string | null; + /** + * z.B. /blog oder /news + */ + allLinkUrl?: string | null; + id?: string | null; + blockName?: string | null; + blockType: 'related-posts-block'; + } + | { + /** + * z.B. "Teilen:", "Artikel teilen" (optional) + */ + label?: string | null; + platforms?: { + facebook?: boolean | null; + twitter?: boolean | null; + linkedin?: boolean | null; + xing?: boolean | null; + whatsapp?: boolean | null; + telegram?: boolean | null; + email?: boolean | null; + copy?: boolean | null; + print?: boolean | null; + pinterest?: boolean | null; + reddit?: boolean | null; + }; + layout?: ('horizontal' | 'vertical' | 'floating' | 'sticky') | null; + align?: ('left' | 'center' | 'right') | null; + floatSide?: ('left' | 'right') | null; + style?: { + variant?: ('filled' | 'outline' | 'icon' | 'minimal') | null; + size?: ('sm' | 'md' | 'lg') | null; + shape?: ('square' | 'rounded' | 'circle' | 'pill') | null; + colorScheme?: ('brand' | 'gray' | 'dark' | 'light' | 'accent') | null; + gap?: ('0' | '4' | '8' | '12') | null; + showLabel?: boolean | null; + /** + * Zeigt Anzahl der Shares (sofern verfügbar) + */ + showCount?: boolean | null; + }; + behavior?: { + /** + * Share-Dialoge in kleinem Popup statt neuem Tab + */ + openInPopup?: boolean | null; + /** + * Auf mobilen Geräten den System-Share-Dialog verwenden + */ + useNativeShare?: boolean | null; + /** + * Text der angezeigt wird nach dem Kopieren + */ + copyFeedback?: string | null; + }; + /** + * Überschreibt automatische Werte (optional) + */ + content?: { + /** + * Leer lassen für automatischen Seitentitel + */ + customTitle?: string | null; + /** + * Leer lassen für automatische Meta-Description + */ + customDescription?: string | null; + /** + * Komma-getrennt, ohne # (z.B. "blog,news,tech") + */ + hashtags?: string | null; + /** + * Twitter-Handle ohne @ (z.B. "c2sgmbh") + */ + via?: string | null; + }; + id?: string | null; + blockName?: string | null; + blockType: 'share-buttons-block'; + } + | { + title?: string | null; + /** + * Welche Überschriften-Ebenen einschließen? + */ + levels?: { + h2?: boolean | null; + h3?: boolean | null; + h4?: boolean | null; + h5?: boolean | null; + h6?: boolean | null; + }; + layout?: ('list' | 'numbered' | 'inline' | 'sidebar' | 'dropdown') | null; + sidebarPos?: ('left' | 'right') | null; + behavior?: { + smoothScroll?: boolean | null; + /** + * Markiert den aktuell sichtbaren Abschnitt + */ + highlightActive?: boolean | null; + /** + * Abstand zum oberen Rand nach dem Scrollen (für Fixed Headers) + */ + scrollOffset?: number | null; + /** + * User kann das Inhaltsverzeichnis ein-/ausklappen + */ + collapsible?: boolean | null; + startCollapsed?: boolean | null; + /** + * Fortschrittsbalken oder Prozent-Anzeige + */ + showProgress?: boolean | null; + progressStyle?: ('bar' | 'percent' | 'circle') | null; + }; + style?: { + bg?: ('none' | 'light' | 'dark' | 'accent') | null; + border?: boolean | null; + borderSide?: ('all' | 'left' | 'top') | null; + rounded?: ('none' | 'sm' | 'md' | 'lg') | null; + shadow?: boolean | null; + indent?: boolean | null; + /** + * Link-Symbol neben Einträgen + */ + showIcon?: boolean | null; + fontSize?: ('sm' | 'base' | 'lg') | null; + lineHeight?: ('tight' | 'normal' | 'relaxed') | null; + }; + /** + * Inhaltsverzeichnis nur anzeigen, wenn mindestens X Einträge + */ + minItems?: number | null; + /** + * Maximale Anzahl angezeigter Einträge (0 = unbegrenzt) + */ + maxItems?: number | null; + a11yLabel?: string | null; + id?: string | null; + blockName?: string | null; + blockType: 'toc-block'; + } + | { + title?: string | null; + subtitle?: string | null; + filters?: { + showSearch?: boolean | null; + searchPlaceholder?: string | null; + showDepartment?: boolean | null; + showSpecialization?: boolean | null; + showLanguage?: boolean | null; + showHierarchy?: boolean | null; + filterLayout?: ('horizontal' | 'sidebar' | 'dropdown' | 'tabs') | null; + filterStyle?: ('buttons' | 'select' | 'checkbox') | null; + showResultCount?: boolean | null; + showResetButton?: boolean | null; + }; + display?: { + layout?: ('grid' | 'list' | 'compact') | null; + columns?: ('2' | '3' | '4') | null; + initialLimit?: number | null; + loadMore?: ('button' | 'infinite' | 'pagination' | 'all') | null; + loadMoreText?: string | null; + }; + card?: { + showImage?: boolean | null; + imageStyle?: ('circle' | 'rounded' | 'square') | null; + showRole?: boolean | null; + showDepartment?: boolean | null; + showBio?: boolean | null; + showContact?: boolean | null; + showSocial?: boolean | null; + showSpecializations?: boolean | null; + showLanguages?: boolean | null; + showVCard?: boolean | null; + linkToProfile?: boolean | null; + /** + * z.B. "/team" ergibt "/team/max-mustermann" + */ + profileBasePath?: string | null; + /** + * Klick öffnet Modal statt Profilseite + */ + enableModal?: boolean | null; + }; + style?: { + bg?: ('none' | 'light' | 'dark') | null; + cardBg?: ('white' | 'transparent' | 'light') | null; + cardShadow?: boolean | null; + cardHover?: ('none' | 'lift' | 'shadow' | 'border') | null; + gap?: ('16' | '24' | '32') | null; + animation?: ('none' | 'fade' | 'slide' | 'scale') | null; + }; + emptyState?: { + title?: string | null; + message?: string | null; + showResetButton?: boolean | null; + }; + id?: string | null; + blockName?: string | null; + blockType: 'team-filter-block'; + } + | { + title?: string | null; + subtitle?: string | null; + source?: ('auto' | 'department' | 'manual') | null; + /** + * Oberstes Element (z.B. Geschäftsführer). Leer = automatisch ermitteln. + */ + rootMember?: (number | null) | Team; + /** + * Zeigt nur diese Abteilung + */ + department?: string | null; + selectedMembers?: (number | Team)[] | null; + /** + * Wie viele Hierarchie-Ebenen anzeigen + */ + maxDepth?: number | null; + layout?: ('tree' | 'tree-horizontal' | 'org' | 'radial' | 'layers') | null; + direction?: ('top' | 'bottom' | 'left' | 'right') | null; + node?: { + style?: ('card' | 'compact' | 'avatar' | 'text') | null; + showImage?: boolean | null; + imageSize?: ('sm' | 'md' | 'lg') | null; + imageShape?: ('circle' | 'rounded' | 'square') | null; + showName?: boolean | null; + showRole?: boolean | null; + showDepartment?: boolean | null; + showContact?: boolean | null; + clickAction?: ('none' | 'modal' | 'link' | 'expand') | null; + profileBasePath?: string | null; + }; + connectors?: { + style?: ('straight' | 'angular' | 'curved' | 'dashed') | null; + color?: ('gray' | 'dark' | 'accent' | 'gradient') | null; + thickness?: ('1' | '2' | '3') | null; + /** + * Animierte Linien beim Laden + */ + animated?: boolean | null; + }; + levels?: { + /** + * Verschiedene Farben pro Hierarchie-Ebene + */ + colorByLevel?: boolean | null; + /** + * Höhere Ebenen größer darstellen + */ + sizeByLevel?: boolean | null; + collapsible?: boolean | null; + /** + * Wie viele Ebenen anfangs sichtbar + */ + initiallyExpanded?: number | null; + }; + interaction?: { + zoomable?: boolean | null; + pannable?: boolean | null; + /** + * Kleine Übersichtskarte bei großen Organigrammen + */ + minimap?: boolean | null; + search?: boolean | null; + /** + * Bei Hover Pfad zur Wurzel hervorheben + */ + highlight?: boolean | null; + fullscreen?: boolean | null; + /** + * Als PNG oder PDF exportieren + */ + export?: boolean | null; + }; + style?: { + bg?: ('none' | 'light' | 'white' | 'dark' | 'gradient') | null; + nodeBg?: ('white' | 'light' | 'transparent' | 'accent') | null; + nodeShadow?: boolean | null; + nodeBorder?: boolean | null; + spacing?: ('sm' | 'md' | 'lg') | null; + minHeight?: ('auto' | '300' | '400' | '500' | '600' | 'full') | null; + }; + /** + * Erklärt Farben und Symbole + */ + showLegend?: boolean | null; + a11yLabel?: string | null; + id?: string | null; + blockName?: string | null; + blockType: 'org-chart-block'; + } + | { + title?: string | null; + subtitle?: string | null; + source?: ('all' | 'main' | 'type' | 'manual') | null; + locationType?: + | ('headquarters' | 'office' | 'branch' | 'warehouse' | 'showroom' | 'studio' | 'practice' | 'workshop') + | null; + selectedLocations?: (number | Location)[] | null; + layout?: ('map-list' | 'map-only' | 'list-only' | 'cards' | 'accordion' | 'tabs') | null; + mapPosition?: ('left' | 'right' | 'top' | 'bottom') | null; + columns?: ('1' | '2' | '3') | null; + map?: { + provider?: ('osm' | 'google' | 'mapbox') | null; + style?: ('default' | 'light' | 'dark' | 'satellite') | null; + height?: ('300' | '400' | '500' | '600') | null; + defaultZoom?: number | null; + /** + * Karte automatisch anpassen, um alle Standorte zu zeigen + */ + fitBounds?: boolean | null; + markerStyle?: ('pin' | 'dot' | 'icon' | 'custom') | null; + /** + * Hex-Farbe (z.B. #e11d48) + */ + markerColor?: string | null; + /** + * Nahe Marker zu Gruppen zusammenfassen + */ + clustering?: boolean | null; + controls?: { + zoom?: boolean | null; + fullscreen?: boolean | null; + scrollZoom?: boolean | null; + dragging?: boolean | null; + }; + }; + show?: { + image?: boolean | null; + type?: boolean | null; + address?: boolean | null; + phone?: boolean | null; + email?: boolean | null; + hours?: boolean | null; + directions?: boolean | null; + services?: boolean | null; + team?: boolean | null; + }; + actions?: { + showDirectionsLink?: boolean | null; + showCallButton?: boolean | null; + showEmailButton?: boolean | null; + showDetailLink?: boolean | null; + detailBasePath?: string | null; + }; + style?: { + bg?: ('none' | 'light' | 'dark') | null; + cardStyle?: ('simple' | 'bordered' | 'shadow' | 'filled') | null; + gap?: ('16' | '24' | '32') | null; + }; + id?: string | null; + blockName?: string | null; + blockType: 'locations-block'; + } + | { + /** + * z.B. "Unsere Partner", "Bekannt aus", "Zertifizierungen" + */ + title?: string | null; + subtitle?: string | null; + source?: ('collection' | 'manual') | null; + partnerType?: + | ( + | 'all' + | 'partner' + | 'client' + | 'reference' + | 'sponsor' + | 'certification' + | 'membership' + | 'award' + | 'supplier' + | 'technology' + )[] + | null; + /** + * Optional: Bestimmte Partner auswählen (sonst alle vom gewählten Typ) + */ + selectedPartners?: (number | Partner)[] | null; + featuredOnly?: boolean | null; + limit?: number | null; + logos?: + | { + logo: number | Media; + /** + * Für Alt-Text und Tooltip + */ + name?: string | null; + link?: string | null; + id?: string | null; + }[] + | null; + layout?: ('grid' | 'slider' | 'marquee' | 'inline' | 'masonry') | null; + columns?: ('3' | '4' | '5' | '6' | '8') | null; + slider?: { + perView?: ('3' | '4' | '5' | '6' | 'auto') | null; + autoplay?: boolean | null; + speed?: ('5000' | '3000' | '2000') | null; + pauseOnHover?: boolean | null; + showArrows?: boolean | null; + showDots?: boolean | null; + }; + logoStyle?: { + size?: ('sm' | 'md' | 'lg') | null; + maxHeight?: ('40' | '50' | '60' | '80' | '100') | null; + /** + * Logos in Graustufen anzeigen + */ + grayscale?: boolean | null; + colorOnHover?: boolean | null; + opacity?: ('50' | '70' | '100') | null; + hoverEffect?: ('none' | 'scale' | 'brighten' | 'shadow') | null; + }; + behavior?: { + linkToWebsite?: boolean | null; + openInNewTab?: boolean | null; + showTooltip?: boolean | null; + showName?: boolean | null; + }; + style?: { + bg?: ('none' | 'light' | 'white' | 'dark') | null; + logoBg?: ('none' | 'white' | 'light') | null; + logoPadding?: boolean | null; + gap?: ('16' | '24' | '32' | '48') | null; + alignment?: ('left' | 'center' | 'right') | null; + divider?: boolean | null; + }; + showCTA?: boolean | null; + ctaText?: string | null; + ctaLink?: string | null; + id?: string | null; + blockName?: string | null; + blockType: 'logo-grid-block'; + } + | { + title?: string | null; + subtitle?: string | null; + stats: { + /** + * z.B. "500+", "99%", "24/7", "10.000" + */ + value: string; + /** + * Für Zähl-Animation (z.B. 500 für "500+") + */ + numericValue?: number | null; + /** + * z.B. "€", "+" + */ + prefix?: string | null; + /** + * z.B. "+", "%", "k", "Mio." + */ + suffix?: string | null; + /** + * z.B. "Zufriedene Kunden", "Erfolgsquote" + */ + label: string; + /** + * Optionaler erklärender Text + */ + description?: string | null; + icon?: + | ( + | 'none' + | 'users' + | 'star' + | 'heart' + | 'check' + | 'trophy' + | 'chart' + | 'clock' + | 'calendar' + | 'globe' + | 'building' + | 'document' + | 'target' + | 'rocket' + | 'handshake' + ) + | null; + color?: ('default' | 'primary' | 'green' | 'blue' | 'orange' | 'red') | null; + id?: string | null; + }[]; + layout?: ('row' | 'grid' | 'cards' | 'column' | 'inline' | 'feature') | null; + columns?: ('2' | '3' | '4' | 'auto') | null; + alignment?: ('left' | 'center' | 'right') | null; + animation?: { + /** + * Zahlen hochzählen (benötigt numericValue) + */ + countUp?: boolean | null; + duration?: ('1000' | '2000' | '3000') | null; + trigger?: ('viewport' | 'immediate') | null; + /** + * Statistiken nacheinander einblenden + */ + stagger?: boolean | null; + }; + style?: { + bg?: ('none' | 'light' | 'dark' | 'primary' | 'gradient') | null; + bgImage?: (number | null) | Media; + bgOverlay?: ('none' | 'dark' | 'light' | 'primary') | null; + textColor?: ('auto' | 'dark' | 'light') | null; + valueSize?: ('base' | 'lg' | 'xl' | '2xl') | null; + valueWeight?: ('normal' | 'medium' | 'bold' | 'extrabold') | null; + showIcon?: boolean | null; + iconPosition?: ('top' | 'left' | 'inline') | null; + dividers?: boolean | null; + cardBorder?: boolean | null; + cardShadow?: boolean | null; + gap?: ('16' | '24' | '32' | '48') | null; + padding?: ('none' | 'sm' | 'md' | 'lg') | null; + }; + id?: string | null; + blockName?: string | null; + blockType: 'stats-block'; + } + | { + title?: string | null; + subtitle?: string | null; + introduction?: { + root: { + type: string; + children: { + type: any; + version: number; + [k: string]: unknown; + }[]; + direction: ('ltr' | 'rtl') | null; + format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | ''; + indent: number; + version: number; + }; + [k: string]: unknown; + } | null; + source?: ('all' | 'category' | 'department' | 'location' | 'featured' | 'manual') | null; + category?: + | ( + | 'care' + | 'medical' + | 'admin' + | 'it' + | 'marketing' + | 'sales' + | 'finance' + | 'hr' + | 'production' + | 'logistics' + ) + | null; + department?: string | null; + locationFilter?: (number | null) | Location; + selectedJobs?: (number | Job)[] | null; + limit?: number | null; + filters?: { + showSearch?: boolean | null; + showCategoryFilter?: boolean | null; + showTypeFilter?: boolean | null; + showLocationFilter?: boolean | null; + showWorkModelFilter?: boolean | null; + filterLayout?: ('horizontal' | 'sidebar' | 'dropdown') | null; + }; + layout?: ('list' | 'cards' | 'compact' | 'accordion') | null; + columns?: ('1' | '2' | '3') | null; + show?: { + image?: boolean | null; + department?: boolean | null; + type?: boolean | null; + location?: boolean | null; + workModel?: boolean | null; + salary?: boolean | null; + summary?: boolean | null; + deadline?: boolean | null; + publishDate?: boolean | null; + badges?: boolean | null; + }; + badges?: { + /** + * Wie viele Tage nach Veröffentlichung "Neu" anzeigen + */ + newDays?: number | null; + showUrgent?: boolean | null; + showFeatured?: boolean | null; + }; + pagination?: { + type?: ('button' | 'pagination' | 'infinite' | 'none') | null; + perPage?: number | null; + }; + style?: { + bg?: ('none' | 'light' | 'dark') | null; + cardStyle?: ('simple' | 'bordered' | 'shadow') | null; + hoverEffect?: ('none' | 'lift' | 'highlight') | null; + gap?: ('8' | '16' | '24') | null; + }; + emptyState?: { + title?: string | null; + message?: string | null; + showInitiativeLink?: boolean | null; + initiativeText?: string | null; + initiativeUrl?: string | null; + }; + showAllJobsLink?: boolean | null; + allJobsText?: string | null; + allJobsUrl?: string | null; + id?: string | null; + blockName?: string | null; + blockType: 'jobs-block'; + } + | { + title?: string | null; + subtitle?: string | null; + introduction?: { + root: { + type: string; + children: { + type: any; + version: number; + [k: string]: unknown; + }[]; + direction: ('ltr' | 'rtl') | null; + format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | ''; + indent: number; + version: number; + }; + [k: string]: unknown; + } | null; + source?: ('all' | 'category' | 'tags' | 'featured' | 'service' | 'product' | 'manual') | null; + category?: + | ( + | 'brochure' + | 'flyer' + | 'catalog' + | 'pricelist' + | 'form' + | 'manual' + | 'datasheet' + | 'certificate' + | 'press' + | 'whitepaper' + | 'presentation' + | 'legal' + ) + | null; + /** + * z.B. "produktinfo, 2024, neu" + */ + filterTags?: string | null; + relatedService?: (number | null) | Service; + relatedProduct?: (number | null) | Product; + selectedDownloads?: (number | Download)[] | null; + limit?: number | null; + filters?: { + showSearch?: boolean | null; + showCategoryFilter?: boolean | null; + showFileTypeFilter?: boolean | null; + filterLayout?: ('horizontal' | 'sidebar' | 'dropdown') | null; + }; + layout?: ('list' | 'cards' | 'compact' | 'table' | 'accordion') | null; + columns?: ('1' | '2' | '3' | '4') | null; + show?: { + thumbnail?: boolean | null; + description?: boolean | null; + fileSize?: boolean | null; + fileType?: boolean | null; + category?: boolean | null; + downloadCount?: boolean | null; + version?: boolean | null; + lastUpdated?: boolean | null; + }; + downloadBehavior?: { + /** + * Datei direkt herunterladen vs. Vorschau öffnen + */ + directDownload?: boolean | null; + trackDownloads?: boolean | null; + openInNewTab?: boolean | null; + }; + fileIcons?: { + showFileTypeIcon?: boolean | null; + iconStyle?: ('colored' | 'mono' | 'outline') | null; + }; + sortBy?: + | ('order' | 'title_asc' | 'title_desc' | 'date_desc' | 'date_asc' | 'downloads_desc' | 'size') + | null; + groupBy?: ('none' | 'category' | 'fileType') | null; + pagination?: { + type?: ('none' | 'button' | 'pagination') | null; + perPage?: number | null; + }; + style?: { + bg?: ('none' | 'light' | 'dark') | null; + cardStyle?: ('simple' | 'bordered' | 'shadow') | null; + hoverEffect?: ('none' | 'highlight' | 'lift') | null; + gap?: ('8' | '16' | '24') | null; + }; + emptyState?: { + title?: string | null; + message?: string | null; + }; + showAllDownloadsLink?: boolean | null; + allDownloadsText?: string | null; + allDownloadsUrl?: string | null; + id?: string | null; + blockName?: string | null; + blockType: 'downloads-block'; + } + | { + title?: string | null; + subtitle?: string | null; + source?: ('locations' | 'manual' | 'single') | null; + locationType?: + | ( + | 'all' + | 'headquarters' + | 'branch' + | 'office' + | 'warehouse' + | 'production' + | 'showroom' + | 'service' + | 'partner' + )[] + | null; + /** + * Optional: Bestimmte Standorte auswählen (sonst alle vom gewählten Typ) + */ + selectedLocations?: (number | Location)[] | null; + markers?: + | { + name: string; + address?: string | null; + lat: number; + lng: number; + markerType?: ('default' | 'main' | 'highlight' | 'custom') | null; + customIcon?: (number | null) | Media; + popupContent?: { + root: { + type: string; + children: { + type: any; + version: number; + [k: string]: unknown; + }[]; + direction: ('ltr' | 'rtl') | null; + format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | ''; + indent: number; + version: number; + }; + [k: string]: unknown; + } | null; + link?: string | null; + id?: string | null; + }[] + | null; + singleAddress?: { + name?: string | null; + street?: string | null; + zip?: string | null; + city?: string | null; + country?: string | null; + /** + * Optional - wird sonst per Geocoding ermittelt + */ + lat?: number | null; + lng?: number | null; + }; + provider?: ('osm' | 'google' | 'mapbox' | 'leaflet') | null; + mapStyle?: ('default' | 'light' | 'dark' | 'satellite' | 'hybrid' | 'terrain') | null; + mapSettings?: { + height?: ('300' | '400' | '500' | '600' | 'fullscreen') | null; + /** + * 1 = Welt, 20 = Gebäude-Details + */ + zoom?: number | null; + /** + * Zoom so anpassen, dass alle Marker sichtbar sind + */ + autoFit?: boolean | null; + /** + * Optional - wird automatisch berechnet wenn leer + */ + centerLat?: number | null; + centerLng?: number | null; + }; + interaction?: { + scrollZoom?: boolean | null; + dragging?: boolean | null; + zoomControl?: boolean | null; + fullscreenControl?: boolean | null; + /** + * User-Standort ermitteln + */ + locateControl?: boolean | null; + }; + markerStyle?: { + type?: ('pin' | 'dot' | 'icon' | 'custom') | null; + /** + * HEX-Farbcode, z.B. #3B82F6 + */ + color?: string | null; + size?: ('sm' | 'md' | 'lg') | null; + /** + * Nahe beieinander liegende Marker gruppieren + */ + clustering?: boolean | null; + clusterRadius?: number | null; + }; + popup?: { + show?: boolean | null; + trigger?: ('click' | 'hover') | null; + showAddress?: boolean | null; + showDirectionsLink?: boolean | null; + showPhone?: boolean | null; + showOpeningHours?: boolean | null; + showDetailLink?: boolean | null; + }; + sidebar?: { + show?: boolean | null; + position?: ('left' | 'right' | 'bottom') | null; + width?: ('250' | '300' | '400') | null; + searchable?: boolean | null; + clickToCenter?: boolean | null; + }; + style?: { + rounded?: boolean | null; + shadow?: boolean | null; + border?: boolean | null; + padding?: ('none' | 'sm' | 'md' | 'lg') | null; + }; + fallback?: { + showStaticImage?: boolean | null; + staticImage?: (number | null) | Media; + noJsMessage?: string | null; + }; + id?: string | null; + blockName?: string | null; + blockType: 'map-block'; + } + | { + title?: string | null; + subtitle?: string | null; + sourceMode?: ('collection' | 'selected') | null; + filterMode?: ('upcoming' | 'past' | 'all' | 'featured' | 'type' | 'category') | null; + eventType?: + | ( + | 'event' + | 'workshop' + | 'seminar' + | 'webinar' + | 'conference' + | 'tradeshow' + | 'networking' + | 'course' + | 'talk' + ) + | null; + category?: string | null; + selectedEvents?: (number | Event)[] | null; + limit?: number | null; + layout?: ('cards' | 'list' | 'compact' | 'timeline' | 'calendar' | 'agenda') | null; + columns?: ('2' | '3' | '4') | null; + showImage?: boolean | null; + showExcerpt?: boolean | null; + showDate?: boolean | null; + showTime?: boolean | null; + showLocation?: boolean | null; + showPrice?: boolean | null; + showEventType?: boolean | null; + showRegistrationButton?: boolean | null; + registrationButtonText?: string | null; + calendarOptions?: { + defaultView?: ('month' | 'week' | 'day') | null; + showNavigation?: boolean | null; + showViewToggle?: boolean | null; + }; + groupBy?: ('none' | 'month' | 'type' | 'category') | null; + sortOrder?: ('asc' | 'desc') | null; + showAllLink?: boolean | null; + allEventsLink?: string | null; + allEventsText?: string | null; + emptyMessage?: string | null; + backgroundColor?: ('white' | 'light' | 'dark' | 'accent') | null; + cardStyle?: ('elevated' | 'bordered' | 'flat') | null; + id?: string | null; + blockName?: string | null; + blockType: 'events'; + } + | { + title?: string | null; + subtitle?: string | null; + description?: string | null; + pricingType?: ('one-time' | 'monthly' | 'yearly' | 'toggle' | 'custom') | null; + currency?: string | null; + showCurrencyBefore?: boolean | null; + toggleOptions?: { + monthlyLabel?: string | null; + yearlyLabel?: string | null; + /** + * z.B. "2 Monate gratis" + */ + yearlyDiscount?: string | null; + defaultToYearly?: boolean | null; + }; + plans?: + | { + /** + * z.B. "Basic", "Pro", "Enterprise" + */ + name: string; + /** + * z.B. "Für Einsteiger" + */ + subtitle?: string | null; + description?: string | null; + price?: number | null; + priceMonthly?: number | null; + priceYearly?: number | null; + /** + * z.B. "/Monat", "/Nutzer" + */ + priceSuffix?: string | null; + /** + * Für Rabatt-Darstellung + */ + originalPrice?: number | null; + /** + * z.B. "zzgl. MwSt.", "Bei jährlicher Zahlung" + */ + priceNote?: string | null; + /** + * z.B. "Auf Anfrage", "Individuell" + */ + customPriceText?: string | null; + features?: + | { + text: string; + included?: boolean | null; + highlight?: boolean | null; + tooltip?: string | null; + id?: string | null; + }[] + | null; + ctaText?: string | null; + ctaLink?: string | null; + ctaStyle?: ('primary' | 'secondary' | 'outline') | null; + isPopular?: boolean | null; + popularLabel?: string | null; + isRecommended?: boolean | null; + recommendedLabel?: string | null; + accentColor?: ('default' | 'primary' | 'secondary' | 'green' | 'blue' | 'purple') | null; + icon?: (number | null) | Media; + id?: string | null; + }[] + | null; + showComparison?: boolean | null; + comparisonFeatures?: + | { + category?: string | null; + feature: string; + tooltip?: string | null; + values?: + | { + planIndex?: number | null; + /** + * ✓, ✗, oder Text wie "10 GB", "Unbegrenzt" + */ + value?: string | null; + id?: string | null; + }[] + | null; + id?: string | null; + }[] + | null; + layout?: ('cards' | 'table' | 'compact') | null; + alignment?: ('left' | 'center' | 'right') | null; + highlightPopular?: boolean | null; + guarantee?: { + show?: boolean | null; + text?: string | null; + icon?: ('shield' | 'check' | 'star' | 'lock') | null; + }; + showFAQ?: boolean | null; + faqTitle?: string | null; + faqItems?: + | { + question: string; + answer: { + root: { + type: string; + children: { + type: any; + version: number; + [k: string]: unknown; + }[]; + direction: ('ltr' | 'rtl') | null; + format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | ''; + indent: number; + version: number; + }; + [k: string]: unknown; + }; + id?: string | null; + }[] + | null; + backgroundColor?: ('white' | 'light' | 'dark' | 'gradient') | null; + cardStyle?: ('elevated' | 'bordered' | 'flat' | 'glass') | null; + id?: string | null; + blockName?: string | null; + blockType: 'pricing'; + } + | { + title?: string | null; + subtitle?: string | null; + tabs?: + | { + label: string; + icon?: + | ( + | 'none' + | 'info' + | 'star' + | 'heart' + | 'check' + | 'settings' + | 'user' + | 'document' + | 'image' + | 'video' + | 'code' + | 'chart' + | 'calendar' + | 'location' + | 'email' + | 'phone' + ) + | null; + /** + * Überschreibt das ausgewählte Icon + */ + customIcon?: (number | null) | Media; + /** + * z.B. "Neu", "3", "Beta" + */ + badge?: string | null; + contentType?: ('richtext' | 'image-text' | 'features' | 'code' | 'embed') | null; + content?: { + root: { + type: string; + children: { + type: any; + version: number; + [k: string]: unknown; + }[]; + direction: ('ltr' | 'rtl') | null; + format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | ''; + indent: number; + version: number; + }; + [k: string]: unknown; + } | null; + imgTxt?: { + img?: (number | null) | Media; + imgPos?: ('left' | 'right' | 'top') | null; + text?: { + root: { + type: string; + children: { + type: any; + version: number; + [k: string]: unknown; + }[]; + direction: ('ltr' | 'rtl') | null; + format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | ''; + indent: number; + version: number; + }; + [k: string]: unknown; + } | null; + }; + features?: + | { + title: string; + description?: string | null; + icon?: ('check' | 'star' | 'arrow' | 'dot' | 'number') | null; + id?: string | null; + }[] + | null; + code?: { + language?: + | ('javascript' | 'typescript' | 'html' | 'css' | 'json' | 'python' | 'bash' | 'sql') + | null; + code?: string | null; + showLineNumbers?: boolean | null; + }; + embed?: { + type?: ('youtube' | 'vimeo' | 'iframe') | null; + url?: string | null; + aspectRatio?: ('16:9' | '4:3' | '1:1') | null; + }; + id?: string | null; + }[] + | null; + tabStyle?: ('underline' | 'boxed' | 'pills' | 'buttons' | 'vertical') | null; + tabPosition?: ('top' | 'left' | 'right' | 'bottom') | null; + tabAlignment?: ('left' | 'center' | 'right' | 'stretch') | null; + /** + * 0 = erster Tab + */ + defaultTab?: number | null; + allowKeyboardNavigation?: boolean | null; + animated?: boolean | null; + /** + * Tab-Inhalte erst bei Aktivierung laden + */ + lazy?: boolean | null; + mobileStyle?: ('scroll' | 'dropdown' | 'accordion' | 'stacked') | null; + backgroundColor?: ('white' | 'light' | 'dark' | 'transparent') | null; + contentBackground?: ('white' | 'light' | 'transparent') | null; + showBorder?: boolean | null; + fullWidth?: boolean | null; + id?: string | null; + blockName?: string | null; + blockType: 'tabs'; + } + | { + title?: string | null; + subtitle?: string | null; + description?: string | null; + items?: + | { + title: string; + subtitle?: string | null; + icon?: + | ( + | 'none' + | 'info' + | 'question' + | 'star' + | 'check' + | 'warning' + | 'document' + | 'user' + | 'settings' + | 'code' + | 'lightbulb' + | 'lock' + ) + | null; + customIcon?: (number | null) | Media; + contentType?: ('richtext' | 'image-text' | 'list' | 'table' | 'code') | null; + content?: { + root: { + type: string; + children: { + type: any; + version: number; + [k: string]: unknown; + }[]; + direction: ('ltr' | 'rtl') | null; + format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | ''; + indent: number; + version: number; + }; + [k: string]: unknown; + } | null; + imgTxt?: { + img?: (number | null) | Media; + imgPos?: ('left' | 'right') | null; + text?: { + root: { + type: string; + children: { + type: any; + version: number; + [k: string]: unknown; + }[]; + direction: ('ltr' | 'rtl') | null; + format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | ''; + indent: number; + version: number; + }; + [k: string]: unknown; + } | null; + }; + listItems?: + | { + text: string; + icon?: ('check' | 'dot' | 'arrow' | 'star' | 'x') | null; + id?: string | null; + }[] + | null; + tableData?: { + headers?: + | { + text?: string | null; + id?: string | null; + }[] + | null; + rows?: + | { + cells?: + | { + text?: string | null; + id?: string | null; + }[] + | null; + id?: string | null; + }[] + | null; + }; + codeContent?: { + language?: ('javascript' | 'typescript' | 'html' | 'css' | 'json' | 'python' | 'bash') | null; + code?: string | null; + }; + /** + * z.B. "Neu", "Wichtig", "Pro" + */ + badge?: string | null; + badgeColor?: ('gray' | 'blue' | 'green' | 'yellow' | 'red' | 'purple') | null; + defaultOpen?: boolean | null; + disabled?: boolean | null; + id?: string | null; + }[] + | null; + behavior?: ('single' | 'multiple' | 'at-least-one') | null; + expandFirst?: boolean | null; + animated?: boolean | null; + style?: ('default' | 'bordered' | 'separated' | 'flush' | 'rounded') | null; + iconPosition?: ('left' | 'right') | null; + iconStyle?: ('chevron' | 'plus-minus' | 'arrow' | 'caret') | null; + layout?: ('full' | 'centered' | 'narrow' | 'two-column') | null; + titleSize?: ('small' | 'medium' | 'large') | null; + backgroundColor?: ('white' | 'light' | 'dark' | 'transparent') | null; + headerBackground?: ('white' | 'light' | 'transparent') | null; + /** + * Wenn aktiviert, wird FAQ Structured Data generiert + */ + enableSchemaOrg?: boolean | null; + id?: string | null; + blockName?: string | null; + blockType: 'accordion'; + } + | { + title?: string | null; + subtitle?: string | null; + description?: string | null; + comparisonType?: ('table' | 'cards' | 'before-after' | 'pros-cons' | 'feature-matrix') | null; + tbl?: { + columns?: + | { + name: string; + subtitle?: string | null; + image?: (number | null) | Media; + price?: string | null; + isHighlighted?: boolean | null; + /** + * z.B. "Empfohlen", "Bestseller" + */ + highlightLabel?: string | null; + ctaText?: string | null; + ctaLink?: string | null; + id?: string | null; + }[] + | null; + rows?: + | { + feature: string; + /** + * Für Gruppierung + */ + category?: string | null; + tooltip?: string | null; + values?: + | { + /** + * 0 = erste Spalte + */ + columnIndex?: number | null; + valueType?: ('text' | 'boolean' | 'partial' | 'na') | null; + textValue?: string | null; + booleanValue?: boolean | null; + /** + * z.B. "Eingeschränkt", "Mit Aufpreis" + */ + partialNote?: string | null; + id?: string | null; + }[] + | null; + id?: string | null; + }[] + | null; + }; + crd?: { + items?: + | { + title: string; + subtitle?: string | null; + image?: (number | null) | Media; + description?: { + root: { + type: string; + children: { + type: any; + version: number; + [k: string]: unknown; + }[]; + direction: ('ltr' | 'rtl') | null; + format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | ''; + indent: number; + version: number; + }; + [k: string]: unknown; + } | null; + features?: + | { + text: string; + included?: boolean | null; + id?: string | null; + }[] + | null; + price?: string | null; + ctaText?: string | null; + ctaLink?: string | null; + isHighlighted?: boolean | null; + accentColor?: ('default' | 'primary' | 'secondary' | 'green' | 'blue') | null; + id?: string | null; + }[] + | null; + }; + beforeAfter?: { + beforeLabel?: string | null; + afterLabel?: string | null; + items?: + | { + title?: string | null; + beforeImage?: (number | null) | Media; + afterImage?: (number | null) | Media; + beforeText?: string | null; + afterText?: string | null; + id?: string | null; + }[] + | null; + displayStyle?: ('slider' | 'side-by-side' | 'stacked' | 'flip') | null; + }; + prosCons?: { + prosLabel?: string | null; + consLabel?: string | null; + items?: + | { + title?: string | null; + image?: (number | null) | Media; + pros?: + | { + text: string; + id?: string | null; + }[] + | null; + cons?: + | { + text: string; + id?: string | null; + }[] + | null; + verdict?: string | null; + rating?: number | null; + id?: string | null; + }[] + | null; + }; + stickyHeader?: boolean | null; + showCategories?: boolean | null; + collapsibleCategories?: boolean | null; + showRowDividers?: boolean | null; + highlightDifferences?: boolean | null; + mobileView?: ('scroll' | 'stacked' | 'accordion' | 'dropdown') | null; + symbols?: { + checkSymbol?: string | null; + crossSymbol?: string | null; + partialSymbol?: string | null; + }; + backgroundColor?: ('white' | 'light' | 'dark') | null; + tableStyle?: ('bordered' | 'striped' | 'minimal' | 'cards') | null; + checkColor?: ('green' | 'primary' | 'blue') | null; + crossColor?: ('red' | 'gray' | 'transparent') | null; + id?: string | null; + blockName?: string | null; + blockType: 'comparison'; + } + | { + title?: string | null; + subtitle?: string | null; + description?: string | null; + comparisons: { + title?: string | null; + beforeImage: number | Media; + afterImage: number | Media; + beforeLabel?: string | null; + afterLabel?: string | null; + description?: string | null; + category?: + | ( + | 'wedding' + | 'portrait' + | 'retouch' + | 'colorgrade' + | 'restore' + | 'composing' + | 'architecture' + | 'product' + | 'other' + ) + | null; + /** + * Komma-getrennte Tags für Filterung + */ + tags?: string | null; + metadata?: { + client?: string | null; + date?: string | null; + /** + * z.B. Lightroom, Photoshop + */ + tools?: string | null; + duration?: string | null; + }; + showMetadata?: boolean | null; + id?: string | null; + }[]; + displayStyle?: ('slider' | 'hover' | 'toggle' | 'side-by-side' | 'fade') | null; + sliderOrientation?: ('horizontal' | 'vertical') | null; + /** + * 0 = links/oben, 100 = rechts/unten + */ + sliderStartPosition?: number | null; + layout?: ('single' | 'grid-2' | 'grid-3' | 'carousel' | 'masonry') | null; + aspectRatio?: ('original' | '16-9' | '4-3' | '3-2' | '1-1' | '2-3' | '9-16') | null; + sliderHandle?: { + style?: ('circle' | 'line' | 'arrows' | 'custom') | null; + color?: ('white' | 'black' | 'primary' | 'accent') | null; + size?: ('small' | 'medium' | 'large') | null; + showLine?: boolean | null; + }; + showLabels?: boolean | null; + labelPosition?: ('corners' | 'top' | 'bottom' | 'overlay') | null; + labelStyle?: ('badge' | 'text' | 'pill') | null; + showFilter?: boolean | null; + animation?: { + enableAnimation?: boolean | null; + autoPlay?: boolean | null; + autoPlaySpeed?: number | null; + scrollTrigger?: boolean | null; + }; + interactivity?: { + enableZoom?: boolean | null; + enableFullscreen?: boolean | null; + enableSwipe?: boolean | null; + enableKeyboard?: boolean | null; + }; + cta?: { + showCta?: boolean | null; + ctaText?: string | null; + ctaLink?: string | null; + ctaStyle?: ('primary' | 'secondary' | 'outline' | 'ghost') | null; + }; + backgroundColor?: ('transparent' | 'white' | 'light' | 'dark' | 'black') | null; + borderRadius?: ('none' | 'small' | 'medium' | 'large') | null; + shadow?: ('none' | 'small' | 'medium' | 'large') | null; + spacing?: ('none' | 'small' | 'medium' | 'large') | null; + id?: string | null; + blockName?: string | null; + blockType: 'before-after'; + } + | { + title?: string | null; + subtitle?: string | null; + /** + * Nur Favoriten dieser Kategorie anzeigen + */ + category?: ('all' | 'fashion' | 'beauty' | 'travel' | 'tech' | 'home') | null; + /** + * Nur als "Featured" markierte Favoriten anzeigen + */ + showFeaturedOnly?: boolean | null; + /** + * Maximale Anzahl der angezeigten Favoriten + */ + limit?: number | null; + layout?: ('grid' | 'list' | 'carousel') | null; + columns?: ('2' | '3' | '4') | null; + showPrice?: boolean | null; + showBadge?: boolean | null; + showDescription?: boolean | null; + showCategory?: boolean | null; + backgroundColor?: ('white' | 'ivory' | 'sand' | 'light' | 'dark') | null; + cta?: { + showCta?: boolean | null; + ctaText?: string | null; + ctaUrl?: string | null; + }; + id?: string | null; + blockName?: string | null; + blockType: 'favorites-block'; + } + | { + title?: string | null; + subtitle?: string | null; + layout?: ('grid' | 'list' | 'featured') | null; + columns?: ('2' | '3' | '4') | null; + showDescription?: boolean | null; + showLogo?: boolean | null; + showTagline?: boolean | null; + /** + * Serien-spezifische Farben für Akzente nutzen + */ + useBrandColors?: boolean | null; + /** + * Maximale Anzahl der angezeigten Serien + */ + limit?: number | null; + backgroundColor?: ('white' | 'ivory' | 'sand' | 'light' | 'dark') | null; + cta?: { + showCta?: boolean | null; + ctaText?: string | null; + ctaUrl?: string | null; + }; + id?: string | null; + blockName?: string | null; + blockType: 'series-block'; + } + | { + /** + * Die anzuzeigende Serie + */ + series: number | Series; + /** + * Cover-Bild mit Logo und Tagline + */ + showHero?: boolean | null; + showDescription?: boolean | null; + /** + * Serien-spezifische Farben für Akzente nutzen + */ + showBrandColors?: boolean | null; + /** + * Posts die mit dieser Serie verknüpft sind + */ + showRelatedPosts?: boolean | null; + relatedPostsLimit?: number | null; + relatedPostsTitle?: string | null; + /** + * Embed der YouTube-Playlist falls konfiguriert + */ + showYoutubePlaylist?: boolean | null; + layout?: ('full' | 'compact') | null; + hero?: { + height?: ('small' | 'medium' | 'large' | 'fullscreen') | null; + /** + * Dunkles Overlay für bessere Lesbarkeit + */ + overlay?: boolean | null; + textAlign?: ('left' | 'center' | 'right') | null; + }; + id?: string | null; + blockName?: string | null; + blockType: 'series-detail-block'; + } + | { + /** + * Optionaler Titel über dem Video + */ + title?: string | null; + videoSource: 'youtube' | 'vimeo' | 'custom'; + /** + * z.B. https://www.youtube.com/watch?v=VIDEO_ID oder https://youtu.be/VIDEO_ID + */ + youtubeUrl?: string | null; + /** + * z.B. https://vimeo.com/VIDEO_ID + */ + vimeoUrl?: string | null; + /** + * Direkte URL zu einer MP4, WebM oder anderen Video-Datei + */ + customUrl?: string | null; + /** + * Optional: Eigenes Vorschaubild. Bei YouTube wird automatisch das Thumbnail verwendet. + */ + thumbnail?: (number | null) | Media; + /** + * Optionaler Text unter dem Video + */ + caption?: string | null; + /** + * YouTube: Verwendet youtube-nocookie.com für besseren Datenschutz + */ + privacyMode?: boolean | null; + /** + * Video erst laden, wenn es im Viewport sichtbar ist + */ + lazyLoad?: boolean | null; + aspectRatio?: ('16:9' | '4:3' | '1:1' | '9:16') | null; + maxWidth?: ('full' | 'large' | 'medium' | 'small') | null; + playbackOptions?: { + /** + * Automatisch abspielen (erfordert Mute für die meisten Browser) + */ + autoplay?: boolean | null; + /** + * Video stumm abspielen + */ + muted?: boolean | null; + loop?: boolean | null; + showControls?: boolean | null; + /** + * Video ab dieser Sekunde starten + */ + startTime?: number | null; + }; + style?: { + alignment?: ('left' | 'center' | 'right') | null; + borderRadius?: ('none' | 'sm' | 'md' | 'lg') | null; + shadow?: boolean | null; + }; + id?: string | null; + blockName?: string | null; + blockType: 'video-embed-block'; + } + | { + title?: string | null; + subtitle?: string | null; + /** + * Wähle verschiedene Content-Typen aus + */ + items: { + itemType: 'post' | 'video' | 'series' | 'external'; + post?: (number | null) | Post; + video?: (number | null) | Video; + series?: (number | null) | Series; + externalTitle?: string | null; + externalUrl?: string | null; + externalImage?: (number | null) | Media; + externalDescription?: string | null; + /** + * Optionales Label (z.B. "NEU", "TRENDING", "MUSS-LESEN") + */ + customLabel?: string | null; + /** + * In featured-grid Layout größer darstellen + */ + featured?: boolean | null; + id?: string | null; + }[]; + layout?: ('grid' | 'carousel' | 'list' | 'featured-grid') | null; + columns?: ('2' | '3' | '4') | null; + showDates?: boolean | null; + /** + * Icon oder Label für Post/Video/Serie anzeigen + */ + showType?: boolean | null; + showDescription?: boolean | null; + showCustomLabels?: boolean | null; + backgroundColor?: ('white' | 'ivory' | 'sand' | 'light' | 'dark') | null; + card?: { + bg?: ('white' | 'transparent' | 'light') | null; + shadow?: boolean | null; + border?: boolean | null; + imgRatio?: ('16:9' | '4:3' | '1:1' | '3:2') | null; + hover?: ('none' | 'lift' | 'zoom' | 'shadow') | null; + }; + cta?: { + showCta?: boolean | null; + ctaText?: string | null; + ctaUrl?: string | null; + }; + id?: string | null; + blockName?: string | null; + blockType: 'featured-content-block'; + } + )[] + | null; + seo?: { + metaTitle?: string | null; + metaDescription?: string | null; + ogImage?: (number | null) | Media; + }; + status?: ('draft' | 'published') | null; + publishedAt?: string | null; + updatedAt: string; + createdAt: string; +} +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "forms". + */ +export interface Form { + id: number; + title: string; + fields?: + | ( + | { + name: string; + label?: string | null; + width?: number | null; + required?: boolean | null; + defaultValue?: boolean | null; + id?: string | null; + blockName?: string | null; + blockType: 'checkbox'; + } + | { + name: string; + label?: string | null; + width?: number | null; + required?: boolean | null; + id?: string | null; + blockName?: string | null; + blockType: 'email'; + } + | { + message?: { + root: { + type: string; + children: { + type: any; + version: number; + [k: string]: unknown; + }[]; + direction: ('ltr' | 'rtl') | null; + format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | ''; + indent: number; + version: number; + }; + [k: string]: unknown; + } | null; + id?: string | null; + blockName?: string | null; + blockType: 'message'; + } + | { + name: string; + label?: string | null; + width?: number | null; + defaultValue?: number | null; + required?: boolean | null; + id?: string | null; + blockName?: string | null; + blockType: 'number'; + } + | { + name: string; + label?: string | null; + width?: number | null; + defaultValue?: string | null; + placeholder?: string | null; + options?: + | { + label: string; + value: string; + id?: string | null; + }[] + | null; + required?: boolean | null; + id?: string | null; + blockName?: string | null; + blockType: 'select'; + } + | { + name: string; + label?: string | null; + width?: number | null; + defaultValue?: string | null; + required?: boolean | null; + id?: string | null; + blockName?: string | null; + blockType: 'text'; + } + | { + name: string; + label?: string | null; + width?: number | null; + defaultValue?: string | null; + required?: boolean | null; + id?: string | null; + blockName?: string | null; + blockType: 'textarea'; + } + )[] + | null; + submitButtonLabel?: string | null; + /** + * Choose whether to display an on-page message or redirect to a different page after they submit the form. + */ + confirmationType?: ('message' | 'redirect') | null; + confirmationMessage?: { + root: { + type: string; + children: { + type: any; + version: number; + [k: string]: unknown; + }[]; + direction: ('ltr' | 'rtl') | null; + format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | ''; + indent: number; + version: number; + }; + [k: string]: unknown; + } | null; + redirect?: { + type?: ('reference' | 'custom') | null; + reference?: { + relationTo: 'pages'; + value: number | Page; + } | null; + url?: string | null; + }; + /** + * Send custom emails when the form submits. Use comma separated lists to send the same email to multiple recipients. To reference a value from this form, wrap that field's name with double curly brackets, i.e. {{firstName}}. You can use a wildcard {{*}} to output all data and {{*:table}} to format it as an HTML table in the email. + */ + emails?: + | { + emailTo?: string | null; + cc?: string | null; + bcc?: string | null; + replyTo?: string | null; + emailFrom?: string | null; + subject: string; + /** + * Enter the message that should be sent in this email. + */ + message?: { + root: { + type: string; + children: { + type: any; + version: number; + [k: string]: unknown; + }[]; + direction: ('ltr' | 'rtl') | null; + format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | ''; + indent: number; + version: number; + }; + [k: string]: unknown; + } | null; + id?: string | null; + }[] + | null; + tenant: number | Tenant; + updatedAt: string; + createdAt: string; +} +/** + * Video-Bibliothek für YouTube/Vimeo Embeds und hochgeladene Videos + * + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "videos". + */ +export interface Video { + id: number; + tenant?: (number | null) | Tenant; + /** + * Titel des Videos + */ + title: string; + /** + * URL-freundlicher Name (z.B. "produkt-tutorial") + */ + slug: string; + /** + * Ausführliche Beschreibung des Videos + */ + description?: { + root: { + type: string; + children: { + type: any; + version: number; + [k: string]: unknown; + }[]; + direction: ('ltr' | 'rtl') | null; + format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | ''; + indent: number; + version: number; + }; + [k: string]: unknown; + } | null; + /** + * Kurzbeschreibung für Übersichten (max. 300 Zeichen) + */ + excerpt?: string | null; + /** + * Woher stammt das Video? + */ + source: 'youtube' | 'vimeo' | 'upload' | 'external'; + /** + * MP4, WebM oder andere Video-Dateien + */ + videoFile?: (number | null) | Media; + /** + * YouTube/Vimeo URL oder direkte Video-URL + */ + embedUrl?: string | null; + /** + * Wird automatisch aus der URL extrahiert + */ + videoId?: string | null; + /** + * Eigenes Thumbnail (bei YouTube wird automatisch eins verwendet falls leer) + */ + thumbnail?: (number | null) | Media; + /** + * Video-Dauer (z.B. "2:30" oder "1:02:30") + */ + duration?: string | null; + /** + * Automatisch berechnet + */ + durationSeconds?: number | null; + /** + * Primäre Video-Kategorie + */ + category?: (number | null) | VideoCategory; + /** + * Schlagwörter für bessere Auffindbarkeit + */ + tags?: (number | Tag)[] | null; + /** + * Art des Videos + */ + videoType?: + | ('tutorial' | 'product' | 'testimonial' | 'explainer' | 'webinar' | 'interview' | 'event' | 'trailer' | 'other') + | null; + playback?: { + /** + * Video automatisch starten (Browser blockieren oft ohne Mute) + */ + autoplay?: boolean | null; + /** + * Video stumm abspielen (erforderlich für Autoplay in Browsern) + */ + muted?: boolean | null; + /** + * Video in Endlosschleife abspielen + */ + loop?: boolean | null; + /** + * Video-Controls anzeigen + */ + controls?: boolean | null; + /** + * Video ab dieser Sekunde starten + */ + startTime?: number | null; + }; + /** + * Anzeigeverhältnis des Videos + */ + aspectRatio?: ('16:9' | '4:3' | '1:1' | '9:16' | '21:9') | null; + status?: ('draft' | 'published' | 'archived') | null; + /** + * Als Featured Video markieren + */ + isFeatured?: boolean | null; + publishedAt?: string | null; + /** + * Weitere Videos zu diesem Thema + */ + relatedVideos?: (number | Video)[] | null; + /** + * Blog-Beiträge zu diesem Video + */ + relatedPosts?: (number | Post)[] | null; + /** + * Vollständiges Transkript für SEO und Barrierefreiheit + */ + transcript?: { + root: { + type: string; + children: { + type: any; + version: number; + [k: string]: unknown; + }[]; + direction: ('ltr' | 'rtl') | null; + format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | ''; + indent: number; + version: number; + }; + [k: string]: unknown; + } | null; + seo?: { + /** + * SEO-Titel (falls abweichend vom Video-Titel) + */ + metaTitle?: string | null; + /** + * SEO-Beschreibung (max. 160 Zeichen) + */ + metaDescription?: string | null; + /** + * Bild für Social Media Shares (Fallback: Thumbnail) + */ + ogImage?: (number | null) | Media; + }; + updatedAt: string; + createdAt: string; +} +/** + * Kategorien für Video-Bibliothek (z.B. Tutorials, Produktvideos, Testimonials) + * + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "video-categories". + */ +export interface VideoCategory { + id: number; + tenant?: (number | null) | Tenant; + /** + * z.B. "Tutorials", "Produktvideos", "Webinare" + */ + name: string; + /** + * URL-freundlicher Name (z.B. "tutorials", "produktvideos") + */ + slug: string; + /** + * Kurzbeschreibung der Kategorie für SEO und Übersichten + */ + description?: string | null; + /** + * Icon-Name (z.B. Lucide Icon wie "play-circle", "video", "film") + */ + icon?: string | null; + /** + * Repräsentatives Bild für die Kategorieübersicht + */ + coverImage?: (number | null) | Media; + /** + * Niedrigere Zahlen erscheinen zuerst + */ + order?: number | null; + /** + * Inaktive Kategorien werden nicht angezeigt + */ + isActive?: boolean | null; + updatedAt: string; + createdAt: string; +} +/** + * Schlagwörter für Blog-Posts + * + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "tags". + */ +export interface Tag { + id: number; + tenant?: (number | null) | Tenant; + name: string; + /** + * URL-freundlicher Identifier (z.B. "javascript") + */ + slug: string; + /** + * Optionale Beschreibung für Tag-Archivseiten + */ + description?: string | null; + /** + * Optionale Farbe für Tag-Badge (z.B. "#3B82F6" oder "blue") + */ + color?: string | null; + updatedAt: string; + createdAt: string; +} +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "posts". + */ +export interface Post { + id: number; + tenant?: (number | null) | Tenant; + title: string; + /** + * URL-Pfad (z.B. "mein-beitrag" / "my-post") + */ + slug: string; + /** + * Art des Beitrags + */ + type: 'blog' | 'news' | 'press' | 'announcement'; + /** + * Auf Startseite/oben anzeigen + */ + isFeatured?: boolean | null; + /** + * Für Übersichten und SEO (max. 300 Zeichen). Wird automatisch aus Content generiert, falls leer. + */ + excerpt?: string | null; + featuredImage?: (number | null) | Media; + /** + * Optional: Video als Hero-Element für diesen Beitrag + */ + featuredVideo?: { + /** + * Video als primäres Medienelement verwenden + */ + enabled?: boolean | null; + /** + * Video statt Beitragsbild im Hero-Bereich anzeigen + */ + replaceImage?: boolean | null; + source?: ('library' | 'embed' | 'upload') | null; + /** + * Video aus der Video-Bibliothek auswählen + */ + video?: (number | null) | Video; + /** + * YouTube oder Vimeo URL + */ + embedUrl?: string | null; + /** + * MP4, WebM oder andere Video-Dateien + */ + uploadedVideo?: (number | null) | Media; + /** + * Video automatisch starten (erfordert Mute) + */ + autoplay?: boolean | null; + /** + * Video stumm abspielen (empfohlen für Autoplay) + */ + muted?: boolean | null; + /** + * Automatisch generierte Embed-URL mit Privacy-Mode + */ + processedEmbedUrl?: string | null; + /** + * Extrahierte Video-ID (z.B. YouTube Video-ID) + */ + extractedVideoId?: string | null; + /** + * Erkannte Plattform (youtube, vimeo, etc.) + */ + platform?: string | null; + /** + * Auto-generierte Thumbnail-URL + */ + thumbnailUrl?: string | null; + }; + content: { + root: { + type: string; + children: { + type: any; + version: number; + [k: string]: unknown; + }[]; + direction: ('ltr' | 'rtl') | null; + format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | ''; + indent: number; + version: number; + }; + [k: string]: unknown; + }; + categories?: (number | Category)[] | null; + /** + * Schlagwörter für bessere Auffindbarkeit + */ + tags?: (number | Tag)[] | null; + /** + * Hauptautor des Beitrags + */ + author?: (number | null) | Author; + /** + * Weitere beteiligte Autoren + */ + coAuthors?: (number | Author)[] | null; + /** + * Freitext-Autor für ältere Beiträge ohne Autoren-Eintrag + */ + authorLegacy?: string | null; + /** + * Wird automatisch berechnet + */ + readingTime?: number | null; + status?: ('draft' | 'published' | 'archived') | null; + publishedAt?: string | null; + seo?: { + metaTitle?: string | null; + metaDescription?: string | null; + ogImage?: (number | null) | Media; + }; + updatedAt: string; + createdAt: string; +} +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "categories". + */ +export interface Category { + id: number; + tenant?: (number | null) | Tenant; + name: string; + slug: string; + description?: string | null; + updatedAt: string; + createdAt: string; +} +/** + * Blog-Autoren und Gastautoren + * + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "authors". + */ +export interface Author { + id: number; + tenant?: (number | null) | Tenant; + /** + * Anzeigename des Autors + */ + name: string; + /** + * URL-freundlicher Identifier (z.B. "max-mustermann") + */ + slug: string; + /** + * Avatar/Profilbild (empfohlen: quadratisch, min. 200x200px) + */ + avatar?: (number | null) | Media; + /** + * Ausführliche Biografie für Autorenseite + */ + bio?: { + root: { + type: string; + children: { + type: any; + version: number; + [k: string]: unknown; + }[]; + direction: ('ltr' | 'rtl') | null; + format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | ''; + indent: number; + version: number; + }; + [k: string]: unknown; + } | null; + /** + * Ein bis zwei Sätze für Anzeige unter Artikeln + */ + bioShort?: string | null; + /** + * z.B. "Senior Editor", "Gastautor", "Chefredakteur" + */ + title?: string | null; + /** + * Öffentliche Kontakt-E-Mail (optional) + */ + email?: string | null; + /** + * Persönliche Website oder Blog + */ + website?: string | null; + social?: { + /** + * Twitter-Handle ohne @ (z.B. "maxmustermann") + */ + twitter?: string | null; + /** + * LinkedIn-Profil-URL oder Username + */ + linkedin?: string | null; + /** + * GitHub-Username + */ + github?: string | null; + /** + * Instagram-Handle ohne @ + */ + instagram?: string | null; + }; + /** + * Optional: Verknüpfung mit Team-Eintrag + */ + linkedTeam?: (number | null) | Team; + /** + * Optional: Verknüpfung mit Login-User + */ + linkedUser?: (number | null) | User; + /** + * Inaktive Autoren erscheinen nicht in Listen + */ + isActive?: boolean | null; + /** + * Markierung für Gastautoren + */ + isGuest?: boolean | null; + /** + * Für besondere Darstellung auf Autorenseite + */ + featured?: boolean | null; + updatedAt: string; + createdAt: string; +} +/** + * Team-Mitglieder und Mitarbeiter + * + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "team". + */ +export interface Team { + id: number; + tenant?: (number | null) | Tenant; + /** + * Vollständiger Name + */ + name: string; + /** + * URL-freundlicher Identifier (z.B. "max-mustermann") + */ + slug: string; + /** + * z.B. "Geschäftsführer", "Pflegedienstleitung", "Fotograf" + */ + role: string; + /** + * z.B. "Verwaltung", "Pflege", "Marketing" + */ + department?: string | null; + /** + * Portrait-Foto (empfohlen: quadratisch, min. 400x400px) + */ + image?: (number | null) | Media; + /** + * Kurze Beschreibung zur Person + */ + bio?: { + root: { + type: string; + children: { + type: any; + version: number; + [k: string]: unknown; + }[]; + direction: ('ltr' | 'rtl') | null; + format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | ''; + indent: number; + version: number; + }; + [k: string]: unknown; + } | null; + /** + * Ein-Satz-Beschreibung für kompakte Darstellung + */ + bioShort?: string | null; + /** + * Öffentliche Kontakt-E-Mail (optional) + */ + email?: string | null; + /** + * Öffentliche Telefonnummer (optional) + */ + phone?: string | null; + showContactInfo?: boolean | null; + socialLinks?: + | { + platform: 'linkedin' | 'xing' | 'twitter' | 'instagram' | 'facebook' | 'website' | 'github'; + url: string; + id?: string | null; + }[] + | null; + /** + * Ausbildungen, Zertifikate, Abschlüsse + */ + qualifications?: + | { + title: string; + year?: number | null; + institution?: string | null; + id?: string | null; + }[] + | null; + specializations?: + | { + title: string; + id?: string | null; + }[] + | null; + languages?: + | { + language: string; + level?: ('native' | 'fluent' | 'good' | 'basic') | null; + id?: string | null; + }[] + | null; + /** + * Optional: Verknüpfung mit Login-User (z.B. für Autoren-Zuordnung) + */ + linkedUser?: (number | null) | User; + /** + * Inaktive Mitglieder werden nicht angezeigt + */ + isActive?: boolean | null; + /** + * Für Startseiten-Anzeige oder besondere Hervorhebung + */ + isFeatured?: boolean | null; + /** + * Niedrigere Zahlen werden zuerst angezeigt + */ + order?: number | null; + /** + * Eintrittsdatum (optional) + */ + startDate?: string | null; + /** + * Direkter Vorgesetzter (für Organigramm) + */ + reportsTo?: (number | null) | Team; + /** + * Für Organigramm-Darstellung + */ + hierarchyLevel?: ('executive' | 'department_head' | 'team_lead' | 'employee' | 'trainee') | null; + /** + * Kontaktkarte zum Download anbieten + */ + allowVCard?: boolean | null; + updatedAt: string; + createdAt: string; +} +/** + * Kundenstimmen und Bewertungen + * + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "testimonials". + */ +export interface Testimonial { + id: number; + tenant?: (number | null) | Tenant; + /** + * Die Aussage des Kunden + */ + quote: string; + author: string; + /** + * z.B. "Patient", "Geschäftsführer", "Marketing Manager" + */ + role?: string | null; + company?: string | null; + /** + * Portrait-Foto (empfohlen: quadratisch, min. 200x200px) + */ + image?: (number | null) | Media; + /** + * Optional: Sterne-Bewertung + */ + rating?: number | null; + /** + * z.B. "Google Reviews", "Trustpilot", "Persönlich" + */ + source?: string | null; + /** + * URL zur Original-Bewertung (falls öffentlich) + */ + sourceUrl?: string | null; + date?: string | null; + /** + * Inaktive Testimonials werden nicht angezeigt + */ + isActive?: boolean | null; + /** + * Niedrigere Zahlen werden zuerst angezeigt + */ + order?: number | null; + updatedAt: string; + createdAt: string; +} +/** + * Häufig gestellte Fragen (FAQ) + * + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "faqs". + */ +export interface Faq { + id: number; + tenant?: (number | null) | Tenant; + /** + * Die Frage, die beantwortet wird + */ + question: string; + /** + * Die ausführliche Antwort auf die Frage + */ + answer: { + root: { + type: string; + children: { + type: any; + version: number; + [k: string]: unknown; + }[]; + direction: ('ltr' | 'rtl') | null; + format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | ''; + indent: number; + version: number; + }; + [k: string]: unknown; + }; + /** + * Kurzfassung der Antwort als reiner Text für Schema.org Structured Data. Falls leer, wird die Rich-Text-Antwort verwendet. + */ + answerPlainText?: string | null; + /** + * Optionale Kategorie zur Gruppierung (z.B. "Allgemein", "Preise", "Lieferung") + */ + category?: string | null; + /** + * Optionaler Icon-Name (z.B. "question-circle", "info") + */ + icon?: string | null; + /** + * Andere FAQs die thematisch zusammenhängen + */ + relatedFAQs?: (number | Faq)[] | null; + /** + * Inaktive FAQs werden nicht angezeigt + */ + isActive?: boolean | null; + /** + * Hervorgehobene FAQs werden prominent angezeigt + */ + isFeatured?: boolean | null; + /** + * Niedrigere Zahlen werden zuerst angezeigt + */ + order?: number | null; + updatedAt: string; + createdAt: string; +} +/** + * Kategorien für Leistungen/Services + * + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "service-categories". + */ +export interface ServiceCategory { + id: number; + tenant?: (number | null) | Tenant; + /** + * z.B. "Pflege", "Beratung", "Schulung" + */ + name: string; + /** + * URL-freundlicher Name (z.B. "pflege", "beratung") + */ + slug: string; + /** + * Kurze Beschreibung der Kategorie + */ + description?: string | null; + /** + * Icon-Name (z.B. "heart", "users", "book") + */ + icon?: string | null; + /** + * Optionales Kategorie-Bild + */ + image?: (number | null) | Media; + /** + * Akzentfarbe für die Kategorie (z.B. "#3B82F6") + */ + color?: string | null; + isActive?: boolean | null; + /** + * Niedrigere Zahlen werden zuerst angezeigt + */ + order?: number | null; + updatedAt: string; + createdAt: string; +} +/** + * Leistungen und Dienstleistungen + * + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "services". + */ +export interface Service { + id: number; + tenant?: (number | null) | Tenant; + /** + * Name der Leistung (z.B. "Intensivpflege", "Beratungsgespräch") + */ + title: string; + /** + * URL-Pfad für Detail-Seite (z.B. "intensivpflege") + */ + slug: string; + /** + * Optionaler Untertitel oder Slogan + */ + subtitle?: string | null; + /** + * Kurze Beschreibung für Übersichtsseiten (1-2 Sätze) + */ + shortDescription: string; + /** + * Detaillierte Beschreibung für die Detail-Seite + */ + description?: { + root: { + type: string; + children: { + type: any; + version: number; + [k: string]: unknown; + }[]; + direction: ('ltr' | 'rtl') | null; + format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | ''; + indent: number; + version: number; + }; + [k: string]: unknown; + } | null; + /** + * Icon-Name (z.B. "heart", "shield", "clock") + */ + icon?: string | null; + /** + * Alternativ: Icon als hochgeladenes Bild + */ + iconImage?: (number | null) | Media; + /** + * Bild für Karten und Header der Detail-Seite + */ + image?: (number | null) | Media; + /** + * Zusätzliche Bilder für die Detail-Seite + */ + gallery?: + | { + image: number | Media; + caption?: string | null; + id?: string | null; + }[] + | null; + /** + * Kategorie zur Gruppierung der Leistung + */ + category?: (number | null) | ServiceCategory; + /** + * Vorteile und Merkmale dieser Leistung + */ + features?: + | { + title: string; + description?: string | null; + /** + * Optionales Icon für das Merkmal + */ + icon?: string | null; + id?: string | null; + }[] + | null; + pricingType?: ('on-request' | 'fixed' | 'from' | 'range' | 'hourly' | 'monthly' | 'free') | null; + /** + * Preis in Euro + */ + price?: number | null; + /** + * Maximaler Preis bei Preisspanne + */ + priceMax?: number | null; + /** + * z.B. "pro Stunde", "pro Monat", "pro Behandlung" + */ + priceUnit?: string | null; + /** + * Zusätzliche Info (z.B. "zzgl. MwSt.", "inkl. Anfahrt") + */ + priceNote?: string | null; + /** + * Ausführliche Preisinformationen für Detail-Seite + */ + pricingDetails?: { + root: { + type: string; + children: { + type: any; + version: number; + [k: string]: unknown; + }[]; + direction: ('ltr' | 'rtl') | null; + format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | ''; + indent: number; + version: number; + }; + [k: string]: unknown; + } | null; + ctaText?: string | null; + /** + * Ziel-URL oder Pfad (z.B. "/kontakt", "#formular") + */ + ctaLink?: string | null; + ctaStyle?: ('primary' | 'secondary' | 'outline') | null; + secondaryCta?: { + enabled?: boolean | null; + text?: string | null; + link?: string | null; + }; + /** + * Andere Leistungen die thematisch passen + */ + relatedServices?: (number | Service)[] | null; + /** + * Ansprechpartner für diese Leistung + */ + teamMembers?: (number | Team)[] | null; + /** + * FAQs zu dieser Leistung + */ + faqs?: (number | Faq)[] | null; + detailSections?: + | { + title: string; + content: { + root: { + type: string; + children: { + type: any; + version: number; + [k: string]: unknown; + }[]; + direction: ('ltr' | 'rtl') | null; + format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | ''; + indent: number; + version: number; + }; + [k: string]: unknown; + }; + icon?: string | null; + id?: string | null; + }[] + | null; + /** + * Optionales Zitat zur Leistung + */ + testimonialQuote?: string | null; + testimonialAuthor?: string | null; + /** + * Titel für Suchmaschinen (falls anders als Titel) + */ + metaTitle?: string | null; + /** + * Beschreibung für Suchmaschinen + */ + metaDescription?: string | null; + ogImage?: (number | null) | Media; + /** + * Inaktive Leistungen werden nicht angezeigt + */ + isActive?: boolean | null; + /** + * Für Startseiten-Anzeige oder besondere Hervorhebung + */ + isFeatured?: boolean | null; + /** + * Zeigt "Neu"-Badge an + */ + isNew?: boolean | null; + /** + * Niedrigere Zahlen werden zuerst angezeigt + */ + order?: number | null; + updatedAt: string; + createdAt: string; +} +/** + * Firmenstandorte und Niederlassungen + * + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "locations". + */ +export interface Location { + id: number; + tenant?: (number | null) | Tenant; + /** + * z.B. "Hauptsitz München", "Filiale Hamburg" + */ + name: string; + /** + * URL-freundlicher Identifier + */ + slug: string; + type?: ('headquarters' | 'office' | 'branch' | 'warehouse' | 'showroom' | 'studio' | 'practice' | 'workshop') | null; + /** + * Optionale Beschreibung des Standorts + */ + description?: { + root: { + type: string; + children: { + type: any; + version: number; + [k: string]: unknown; + }[]; + direction: ('ltr' | 'rtl') | null; + format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | ''; + indent: number; + version: number; + }; + [k: string]: unknown; + } | null; + /** + * Foto des Gebäudes oder Standorts + */ + image?: (number | null) | Media; + address: { + street: string; + /** + * z.B. "Gebäude B, 3. Stock" + */ + additionalLine?: string | null; + zip: string; + city: string; + state?: string | null; + country?: string | null; + }; + /** + * Für Kartenanzeige + */ + geo?: { + /** + * z.B. 48.137154 + */ + lat?: number | null; + /** + * z.B. 11.576124 + */ + lng?: number | null; + zoom?: number | null; + }; + contact?: { + phone?: string | null; + fax?: string | null; + email?: string | null; + /** + * Falls abweichend von Hauptwebsite + */ + website?: string | null; + }; + hours?: { + /** + * z.B. "Mo-Fr: 9-18 Uhr, Sa: 10-14 Uhr" + */ + display?: string | null; + /** + * Detaillierte Öffnungszeiten pro Tag + */ + structured?: + | { + day: 'monday' | 'tuesday' | 'wednesday' | 'thursday' | 'friday' | 'saturday' | 'sunday'; + closed?: boolean | null; + /** + * z.B. "09:00" + */ + open?: string | null; + /** + * z.B. "18:00" + */ + close?: string | null; + break?: { + hasBreak?: boolean | null; + start?: string | null; + end?: string | null; + }; + id?: string | null; + }[] + | null; + /** + * z.B. "Termine nach Vereinbarung" + */ + note?: string | null; + }; + directions?: { + text?: { + root: { + type: string; + children: { + type: any; + version: number; + [k: string]: unknown; + }[]; + direction: ('ltr' | 'rtl') | null; + format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | ''; + indent: number; + version: number; + }; + [k: string]: unknown; + } | null; + parking?: string | null; + /** + * z.B. "U-Bahn U3 Haltestelle Münchner Freiheit" + */ + publicTransport?: string | null; + accessibility?: string | null; + }; + /** + * Welche Dienstleistungen werden hier angeboten? + */ + services?: (number | Service)[] | null; + /** + * Mitarbeiter an diesem Standort + */ + teamMembers?: (number | Team)[] | null; + /** + * Als primärer Standort markieren + */ + isMain?: boolean | null; + isActive?: boolean | null; + showInFooter?: boolean | null; + order?: number | null; + updatedAt: string; + createdAt: string; +} +/** + * Partner, Kunden, Referenzen und Zertifizierungen + * + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "partners". + */ +export interface Partner { + id: number; + tenant?: (number | null) | Tenant; + /** + * Firmen-/Partnername + */ + name: string; + slug: string; + type: + | 'partner' + | 'client' + | 'reference' + | 'sponsor' + | 'certification' + | 'membership' + | 'award' + | 'supplier' + | 'technology'; + /** + * Logo (empfohlen: SVG oder PNG mit transparentem Hintergrund) + */ + logo: number | Media; + /** + * Alternative Version für dunkle Hintergründe + */ + logoLight?: (number | null) | Media; + /** + * Kurze Beschreibung der Partnerschaft + */ + description?: string | null; + website?: string | null; + caseStudy?: { + quote?: string | null; + quotePerson?: string | null; + quoteRole?: string | null; + projectDescription?: { + root: { + type: string; + children: { + type: any; + version: number; + [k: string]: unknown; + }[]; + direction: ('ltr' | 'rtl') | null; + format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | ''; + indent: number; + version: number; + }; + [k: string]: unknown; + } | null; + results?: + | { + /** + * z.B. "+50%", "10.000+" + */ + metric: string; + /** + * z.B. "Umsatzsteigerung", "Neue Kunden" + */ + label: string; + id?: string | null; + }[] + | null; + }; + certification?: { + issuer?: string | null; + validFrom?: string | null; + validUntil?: string | null; + certNumber?: string | null; + document?: (number | null) | Media; + }; + /** + * z.B. "Technologie", "Finanzen", "Pflege" + */ + category?: string | null; + tags?: + | { + tag: string; + id?: string | null; + }[] + | null; + isFeatured?: boolean | null; + isActive?: boolean | null; + order?: number | null; + since?: string | null; + updatedAt: string; + createdAt: string; +} +/** + * Stellenanzeigen und Karriere + * + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "jobs". + */ +export interface Job { + id: number; + tenant?: (number | null) | Tenant; + /** + * z.B. "Pflegefachkraft (m/w/d)", "Senior Developer" + */ + title: string; + slug: string; + /** + * Interne Stellennummer + */ + reference?: string | null; + /** + * z.B. "Pflege", "IT", "Marketing" + */ + department?: string | null; + category?: + | ( + | 'care' + | 'medical' + | 'admin' + | 'it' + | 'marketing' + | 'sales' + | 'finance' + | 'hr' + | 'production' + | 'logistics' + | 'other' + ) + | null; + type: + | 'fulltime' + | 'parttime' + | 'minijob' + | 'working_student' + | 'internship' + | 'apprenticeship' + | 'dual_study' + | 'freelance' + | 'temporary'; + workModel?: ('onsite' | 'remote' | 'hybrid') | null; + experienceLevel?: ('entry' | 'experienced' | 'senior' | 'management') | null; + location?: { + locationRef?: (number | null) | Location; + /** + * Falls kein Standort aus Collection + */ + city?: string | null; + region?: string | null; + country?: string | null; + }; + /** + * Für Übersichten und SEO (max. 300 Zeichen) + */ + summary?: string | null; + description?: { + root: { + type: string; + children: { + type: any; + version: number; + [k: string]: unknown; + }[]; + direction: ('ltr' | 'rtl') | null; + format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | ''; + indent: number; + version: number; + }; + [k: string]: unknown; + } | null; + responsibilities?: { + root: { + type: string; + children: { + type: any; + version: number; + [k: string]: unknown; + }[]; + direction: ('ltr' | 'rtl') | null; + format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | ''; + indent: number; + version: number; + }; + [k: string]: unknown; + } | null; + requirements?: { + root: { + type: string; + children: { + type: any; + version: number; + [k: string]: unknown; + }[]; + direction: ('ltr' | 'rtl') | null; + format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | ''; + indent: number; + version: number; + }; + [k: string]: unknown; + } | null; + qualifications?: { + root: { + type: string; + children: { + type: any; + version: number; + [k: string]: unknown; + }[]; + direction: ('ltr' | 'rtl') | null; + format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | ''; + indent: number; + version: number; + }; + [k: string]: unknown; + } | null; + benefits?: { + root: { + type: string; + children: { + type: any; + version: number; + [k: string]: unknown; + }[]; + direction: ('ltr' | 'rtl') | null; + format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | ''; + indent: number; + version: number; + }; + [k: string]: unknown; + } | null; + /** + * Für visuelle Darstellung mit Icons + */ + benefitsList?: + | { + benefit: string; + icon?: + | ( + | 'money' + | 'vacation' + | 'home' + | 'education' + | 'health' + | 'team' + | 'flexible' + | 'transport' + | 'food' + | 'childcare' + | 'fitness' + | 'parking' + ) + | null; + id?: string | null; + }[] + | null; + salary?: { + show?: boolean | null; + type?: ('yearly' | 'monthly' | 'hourly') | null; + min?: number | null; + max?: number | null; + currency?: string | null; + /** + * z.B. "je nach Qualifikation" + */ + note?: string | null; + }; + application?: { + method?: ('email' | 'form' | 'external' | 'mail') | null; + email?: string | null; + formId?: (number | null) | Form; + externalUrl?: string | null; + contact?: (number | null) | Team; + deadline?: string | null; + }; + /** + * Bild für die Stellenanzeige + */ + image?: (number | null) | Media; + status: 'draft' | 'published' | 'filled' | 'archived'; + publishedAt?: string | null; + isFeatured?: boolean | null; + isUrgent?: boolean | null; + seo?: { + metaTitle?: string | null; + metaDescription?: string | null; + }; + updatedAt: string; + createdAt: string; +} +/** + * Produkte und Artikel + * + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "products". + */ +export interface Product { + id: number; + tenant?: (number | null) | Tenant; + title: string; + /** + * URL-freundlicher Name (z.B. "premium-widget") + */ + slug: string; + /** + * Eindeutige Artikelnummer für interne Verwaltung + */ + sku?: string | null; + /** + * Kurze Beschreibung für Produktlisten (max. 200 Zeichen) + */ + shortDescription?: string | null; + description?: { + root: { + type: string; + children: { + type: any; + version: number; + [k: string]: unknown; + }[]; + direction: ('ltr' | 'rtl') | null; + format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | ''; + indent: number; + version: number; + }; + [k: string]: unknown; + } | null; + /** + * Hauptkategorie des Produkts + */ + category?: (number | null) | ProductCategory; + /** + * Zusätzliche Schlagworte für Filterung + */ + tags?: + | { + tag: string; + id?: string | null; + }[] + | null; + featuredImage: number | Media; + /** + * Zusätzliche Produktbilder + */ + gallery?: + | { + image: number | Media; + caption?: string | null; + id?: string | null; + }[] + | null; + pricing?: { + /** + * Regulärer Preis in Euro + */ + price?: number | null; + /** + * Reduzierter Preis (optional) + */ + salePrice?: number | null; + currency?: ('EUR' | 'USD' | 'CHF') | null; + priceType?: ('fixed' | 'from' | 'on_request' | 'free') | null; + /** + * z.B. "zzgl. MwSt.", "pro Monat", "Einmalzahlung" + */ + priceNote?: string | null; + }; + /** + * Technische Daten und Spezifikationen + */ + details?: { + /** + * Technische Daten als Schlüssel-Wert-Paare + */ + specifications?: + | { + key: string; + value: string; + id?: string | null; + }[] + | null; + /** + * Wichtigste Produktvorteile + */ + features?: + | { + feature: string; + /** + * Optional: Lucide-Icon Name + */ + icon?: string | null; + id?: string | null; + }[] + | null; + }; + inventory?: { + stockStatus?: ('in_stock' | 'low_stock' | 'out_of_stock' | 'on_order' | 'preorder') | null; + /** + * Aktuelle Stückzahl (optional) + */ + stockQuantity?: number | null; + /** + * z.B. "1-3 Werktage", "Sofort lieferbar" + */ + deliveryTime?: string | null; + }; + /** + * Produktempfehlungen für Cross-Selling + */ + relatedProducts?: (number | Product)[] | null; + /** + * Produktdatenblätter, Anleitungen, etc. + */ + downloadFiles?: + | { + file: number | Media; + title?: string | null; + id?: string | null; + }[] + | null; + /** + * Handlungsaufforderung für das Produkt + */ + cta?: { + type?: ('contact' | 'quote' | 'cart' | 'external' | 'download') | null; + /** + * z.B. "Jetzt anfragen", "Kaufen", "Herunterladen" + */ + buttonText?: string | null; + /** + * URL für externen Shop oder Bestellseite + */ + externalUrl?: string | null; + }; + seo?: { + /** + * Überschreibt den Produktnamen für Suchmaschinen + */ + metaTitle?: string | null; + /** + * Kurze Beschreibung für Suchergebnisse (max. 160 Zeichen) + */ + metaDescription?: string | null; + /** + * Bild für Social Media Shares (1200x630px empfohlen) + */ + ogImage?: (number | null) | Media; + }; + status?: ('draft' | 'published' | 'archived') | null; + /** + * Auf Startseite oder in Highlights anzeigen + */ + isFeatured?: boolean | null; + /** + * "Neu"-Badge anzeigen + */ + isNew?: boolean | null; + /** + * Kleinere Zahlen erscheinen zuerst + */ + order?: number | null; + publishedAt?: string | null; + updatedAt: string; + createdAt: string; +} +/** + * Kategorien zur Gruppierung von Produkten + * + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "product-categories". + */ +export interface ProductCategory { + id: number; + tenant?: (number | null) | Tenant; + name: string; + /** + * URL-freundlicher Name (z.B. "elektronik", "software") + */ + slug: string; + /** + * Kurze Beschreibung der Kategorie + */ + description?: string | null; + image?: (number | null) | Media; + /** + * Icon-Name (z.B. Lucide-Icons: "package", "cpu", "code") + */ + icon?: string | null; + /** + * Optional: Für verschachtelte Kategorien + */ + parent?: (number | null) | ProductCategory; + /** + * Kleinere Zahlen erscheinen zuerst + */ + order?: number | null; + /** + * Inaktive Kategorien werden nicht angezeigt + */ + isActive?: boolean | null; + /** + * Suchmaschinenoptimierung für Kategorieseiten + */ + seo?: { + metaTitle?: string | null; + metaDescription?: string | null; + }; + updatedAt: string; + createdAt: string; +} +/** + * Downloadbare Dateien und Dokumente + * + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "downloads". + */ +export interface Download { + id: number; + tenant?: (number | null) | Tenant; + title: string; + slug: string; + description?: string | null; + file: number | Media; + /** + * Wird automatisch erkannt, kann überschrieben werden + */ + fileType?: ('pdf' | 'doc' | 'xls' | 'ppt' | 'image' | 'video' | 'audio' | 'archive' | 'other') | null; + /** + * z.B. "2.5 MB" - wird automatisch berechnet + */ + fileSize?: string | null; + category?: + | ( + | 'brochure' + | 'flyer' + | 'catalog' + | 'pricelist' + | 'form' + | 'manual' + | 'datasheet' + | 'certificate' + | 'press' + | 'whitepaper' + | 'presentation' + | 'legal' + | 'other' + ) + | null; + tags?: + | { + tag: string; + id?: string | null; + }[] + | null; + /** + * Optionales Thumbnail (sonst wird Standard-Icon verwendet) + */ + thumbnail?: (number | null) | Media; + relatedServices?: (number | Service)[] | null; + relatedProducts?: (number | Product)[] | null; + access?: { + requireLogin?: boolean | null; + /** + * User müssen Kontaktdaten eingeben + */ + requireForm?: boolean | null; + formFields?: ('name' | 'email' | 'company' | 'phone')[] | null; + }; + downloadCount?: number | null; + /** + * z.B. "2024-01", "v2.0" + */ + version?: string | null; + lastUpdated?: string | null; + isActive?: boolean | null; + isFeatured?: boolean | null; + order?: number | null; + updatedAt: string; + createdAt: string; +} +/** + * Veranstaltungen und Events + * + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "events". + */ +export interface Event { + id: number; + tenant?: (number | null) | Tenant; + title: string; + /** + * URL-Pfad für das Event + */ + slug: string; + subtitle?: string | null; + description?: { + root: { + type: string; + children: { + type: any; + version: number; + [k: string]: unknown; + }[]; + direction: ('ltr' | 'rtl') | null; + format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | ''; + indent: number; + version: number; + }; + [k: string]: unknown; + } | null; + /** + * Für Übersichtsseiten und SEO + */ + excerpt?: string | null; + eventType: + | 'event' + | 'workshop' + | 'seminar' + | 'webinar' + | 'conference' + | 'tradeshow' + | 'networking' + | 'course' + | 'talk' + | 'other'; + /** + * Freies Textfeld für Kategorisierung + */ + category?: string | null; + format: 'onsite' | 'online' | 'hybrid'; + startDate: string; + /** + * Leer lassen für eintägige Events + */ + endDate?: string | null; + isAllDay?: boolean | null; + /** + * z.B. Europe/Berlin, America/New_York + */ + timezone?: string | null; + isRecurring?: boolean | null; + recurrence?: { + frequency?: ('daily' | 'weekly' | 'monthly' | 'yearly') | null; + /** + * Alle X Tage/Wochen/Monate/Jahre + */ + interval?: number | null; + endRecurrence?: string | null; + /** + * z.B. "Jeden ersten Montag im Monat" + */ + description?: string | null; + }; + location?: { + /** + * Aus bestehenden Standorten wählen + */ + locationRef?: (number | null) | Location; + customLocation?: boolean | null; + venueName?: string | null; + street?: string | null; + zip?: string | null; + city?: string | null; + country?: string | null; + room?: string | null; + directions?: string | null; + }; + online?: { + platform?: ('zoom' | 'teams' | 'google-meet' | 'webex' | 'gotowebinar' | 'livestream' | 'other') | null; + /** + * Wird nur angemeldeten Teilnehmern angezeigt + */ + accessLink?: string | null; + /** + * z.B. Meeting-ID, Passwort + */ + accessInfo?: string | null; + }; + image?: (number | null) | Media; + gallery?: + | { + image: number | Media; + caption?: string | null; + id?: string | null; + }[] + | null; + registration?: { + required?: boolean | null; + method?: ('form' | 'email' | 'external' | 'phone') | null; + formId?: (number | null) | Form; + email?: string | null; + externalUrl?: string | null; + phone?: string | null; + deadline?: string | null; + /** + * 0 = unbegrenzt + */ + maxParticipants?: number | null; + currentParticipants?: number | null; + waitlistEnabled?: boolean | null; + }; + pricing?: { + isFree?: boolean | null; + prices?: + | { + /** + * z.B. "Standard", "Frühbucher", "Ermäßigt" + */ + name: string; + price: number; + currency?: string | null; + description?: string | null; + /** + * Für Frühbucher-Preise + */ + validUntil?: string | null; + id?: string | null; + }[] + | null; + /** + * z.B. "zzgl. MwSt.", "inkl. Verpflegung" + */ + priceNote?: string | null; + }; + speakers?: + | { + teamMember?: (number | null) | Team; + isExternal?: boolean | null; + name?: string | null; + title?: string | null; + company?: string | null; + photo?: (number | null) | Media; + bio?: string | null; + /** + * z.B. "Hauptredner", "Workshop-Leiter" + */ + role?: string | null; + id?: string | null; + }[] + | null; + agenda?: + | { + /** + * z.B. "09:00 - 10:30" + */ + time?: string | null; + title: string; + description?: string | null; + speaker?: string | null; + type?: ('talk' | 'workshop' | 'break' | 'networking' | 'panel' | 'qa') | null; + id?: string | null; + }[] + | null; + contact?: { + teamMember?: (number | null) | Team; + name?: string | null; + email?: string | null; + phone?: string | null; + }; + relatedServices?: (number | Service)[] | null; + relatedEvents?: (number | Event)[] | null; + seo?: { + metaTitle?: string | null; + metaDescription?: string | null; + ogImage?: (number | null) | Media; + }; + status: 'draft' | 'published' | 'soldout' | 'cancelled' | 'postponed' | 'past'; + isFeatured?: boolean | null; + publishedAt?: string | null; + updatedAt: string; + createdAt: string; +} +/** + * YouTube-Serien und Content-Reihen + * + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "series". + */ +export interface Series { + id: number; + tenant?: (number | null) | Tenant; + title: string; + /** + * URL-freundlicher Name (z.B. "grfi-series") + */ + slug: string; + /** + * Kurzer Slogan oder Untertitel (max. 150 Zeichen) + */ + tagline?: string | null; + /** + * Ausführliche Beschreibung der Serie + */ + description?: { + root: { + type: string; + children: { + type: any; + version: number; + [k: string]: unknown; + }[]; + direction: ('ltr' | 'rtl') | null; + format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | ''; + indent: number; + version: number; + }; + [k: string]: unknown; + } | null; + /** + * Serien-Logo (empfohlen: transparent PNG) + */ + logo?: (number | null) | Media; + /** + * Hauptbild für die Serie (16:9 empfohlen) + */ + coverImage?: (number | null) | Media; + /** + * Hex-Farbcode (z.B. #B08D57) + */ + brandColor?: string | null; + /** + * Sekundäre Farbe (z.B. #FFFFFF) + */ + accentColor?: string | null; + /** + * Die Playlist-ID aus YouTube (z.B. PLxxxxxx) + */ + youtubePlaylistId?: string | null; + /** + * Vollständiger Link zur YouTube-Playlist + */ + youtubePlaylistUrl?: string | null; + /** + * Niedrigere Zahlen werden zuerst angezeigt + */ + order?: number | null; + /** + * Inaktive Serien werden nicht angezeigt + */ + isActive: boolean; + updatedAt: string; + createdAt: string; +} +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "social-links". + */ +export interface SocialLink { + id: number; + tenant?: (number | null) | Tenant; + platform: 'facebook' | 'x' | 'instagram' | 'youtube' | 'linkedin' | 'xing'; + url: string; + isActive?: boolean | null; + updatedAt: string; + createdAt: string; +} +/** + * Newsletter-Abonnenten (DSGVO-konform) + * + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "newsletter-subscribers". + */ +export interface NewsletterSubscriber { + id: number; + tenant?: (number | null) | Tenant; + email: string; + firstName?: string | null; + lastName?: string | null; + status: 'pending' | 'confirmed' | 'unsubscribed' | 'bounced'; + interests?: ('general' | 'blog' | 'products' | 'offers' | 'events')[] | null; + /** + * z.B. "Footer", "Popup", "Blog-Artikel", "Kontakt-Seite" + */ + source?: string | null; + subscribedAt?: string | null; + confirmedAt?: string | null; + unsubscribedAt?: string | null; + confirmationToken?: string | null; + /** + * DSGVO-Nachweis der Anmeldung + */ + ipAddress?: string | null; + userAgent?: string | null; + updatedAt: string; + createdAt: string; +} +/** + * Kategorien für Portfolio-Galerien (z.B. Hochzeit, Portrait, Landschaft) + * + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "portfolio-categories". + */ +export interface PortfolioCategory { + id: number; + tenant?: (number | null) | Tenant; + /** + * z.B. "Hochzeitsfotografie", "Portraits", "Landschaften" + */ + name: string; + /** + * URL-freundlicher Name (z.B. "hochzeit", "portrait") + */ + slug: string; + /** + * Kurzbeschreibung der Kategorie für SEO und Übersichten + */ + description?: string | null; + /** + * Repräsentatives Bild für die Kategorieübersicht + */ + coverImage?: (number | null) | Media; + /** + * Niedrigere Zahlen erscheinen zuerst + */ + order?: number | null; + /** + * Inaktive Kategorien werden nicht angezeigt + */ + isActive?: boolean | null; + updatedAt: string; + createdAt: string; +} +/** + * Portfolio-Galerien mit Fotografien + * + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "portfolios". + */ +export interface Portfolio { + id: number; + tenant?: (number | null) | Tenant; + /** + * Name der Galerie / des Projekts + */ + title: string; + /** + * URL-freundlicher Name (z.B. "hochzeit-maria-thomas") + */ + slug: string; + /** + * Ausführliche Beschreibung des Projekts/Shootings + */ + description?: { + root: { + type: string; + children: { + type: any; + version: number; + [k: string]: unknown; + }[]; + direction: ('ltr' | 'rtl') | null; + format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | ''; + indent: number; + version: number; + }; + [k: string]: unknown; + } | null; + /** + * Kurze Beschreibung für Übersichten und SEO (max. 300 Zeichen) + */ + excerpt?: string | null; + /** + * Hauptkategorie dieser Galerie + */ + category: number | PortfolioCategory; + /** + * Zusätzliche Schlagwörter für Filterung (z.B. "outdoor", "studio", "schwarz-weiß") + */ + tags?: string[] | null; + /** + * Hauptbild für Übersichten und Vorschauen + */ + coverImage: number | Media; + /** + * Alle Bilder dieser Galerie + */ + images: { + image: number | Media; + /** + * Optionale Beschreibung für dieses Bild + */ + caption?: string | null; + /** + * Als Highlight-Bild markieren + */ + isHighlight?: boolean | null; + id?: string | null; + }[]; + /** + * Zusätzliche Informationen zum Shooting + */ + projectDetails?: { + /** + * Name des Kunden (optional, für Referenzen) + */ + client?: string | null; + /** + * Wo wurde das Shooting durchgeführt? + */ + location?: string | null; + shootingDate?: string | null; + /** + * Kamera, Objektive etc. (optional) + */ + equipment?: string[] | null; + }; + /** + * Veröffentlichungsstatus + */ + status: 'draft' | 'published' | 'archived'; + /** + * Auf der Startseite anzeigen + */ + isFeatured?: boolean | null; + /** + * Wann soll die Galerie veröffentlicht werden? + */ + publishedAt?: string | null; + /** + * Für manuelle Sortierung (niedrigere Zahlen zuerst) + */ + order?: number | null; + seo?: { + /** + * Überschreibt den Standardtitel für Suchmaschinen + */ + metaTitle?: string | null; + /** + * Beschreibung für Suchmaschinen (max. 160 Zeichen) + */ + metaDescription?: string | null; + /** + * Bild für Social Media Shares (verwendet Cover-Bild wenn leer) + */ + ogImage?: (number | null) | Media; + }; + updatedAt: string; + createdAt: string; +} +/** + * Chronologische Darstellungen für Unternehmensgeschichte, Meilensteine, etc. + * + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "timelines". + */ +export interface Timeline { + id: number; + tenant?: (number | null) | Tenant; + /** + * Interner Name zur Identifikation (z.B. "Unternehmensgeschichte") + */ + name: string; + /** + * URL-freundlicher Identifier (z.B. "company-history") + */ + slug: string; + /** + * Optionale Beschreibung der Timeline + */ + description?: string | null; + type: 'history' | 'milestones' | 'releases' | 'career' | 'events' | 'process'; + status: 'draft' | 'published' | 'archived'; + displayOptions?: { + layout?: ('vertical' | 'alternating' | 'horizontal' | 'compact') | null; + sortOrder?: ('desc' | 'asc') | null; + showConnector?: boolean | null; + showImages?: boolean | null; + groupByYear?: boolean | null; + markerStyle?: ('dot' | 'number' | 'icon' | 'date') | null; + colorScheme?: ('primary' | 'secondary' | 'neutral' | 'colorful') | null; + }; + /** + * Die einzelnen Einträge der Timeline + */ + events: { + dateType?: ('year' | 'monthYear' | 'fullDate' | 'range' | 'custom') | null; + year?: number | null; + month?: ('1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' | '10' | '11' | '12') | null; + day?: number | null; + endYear?: number | null; + endMonth?: ('1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' | '10' | '11' | '12') | null; + ongoing?: boolean | null; + /** + * z.B. "Frühjahr 2024", "Q1 2023", "1990er Jahre" + */ + customDate?: string | null; + title: string; + /** + * Optional: z.B. Rolle, Position, Ort + */ + subtitle?: string | null; + description?: { + root: { + type: string; + children: { + type: any; + version: number; + [k: string]: unknown; + }[]; + direction: ('ltr' | 'rtl') | null; + format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | ''; + indent: number; + version: number; + }; + [k: string]: unknown; + } | null; + /** + * Für kompakte Ansichten (max. 200 Zeichen empfohlen) + */ + shortDescription?: string | null; + image?: (number | null) | Media; + /** + * Zusätzliche Bilder für dieses Ereignis + */ + gallery?: + | { + image: number | Media; + caption?: string | null; + id?: string | null; + }[] + | null; + /** + * Zur Filterung und farblichen Unterscheidung + */ + category?: + | ('milestone' | 'founding' | 'product' | 'team' | 'award' | 'partnership' | 'expansion' | 'technology' | 'other') + | null; + /** + * Highlights werden visuell hervorgehoben + */ + importance?: ('highlight' | 'normal' | 'minor') | null; + /** + * Explizite Nummerierung (optional, sonst wird Reihenfolge verwendet) + */ + stepNumber?: number | null; + /** + * z.B. "2-3 Tage", "1 Woche", "30 Minuten" + */ + duration?: string | null; + /** + * Person oder Rolle (z.B. "HR-Team", "Projektleiter") + */ + responsible?: string | null; + /** + * Wer muss in diesem Schritt aktiv werden? + */ + actionRequired?: ('customer' | 'internal' | 'both' | 'automatic') | null; + /** + * Was wird in diesem Schritt erstellt oder benötigt? + */ + deliverables?: + | { + name: string; + type?: ('output' | 'input' | 'document') | null; + id?: string | null; + }[] + | null; + /** + * Emoji oder Lucide Icon-Name (z.B. "rocket", "award", "users") + */ + icon?: string | null; + /** + * Überschreibt die Kategorie-Farbe (z.B. "#FF5733" oder "blue") + */ + color?: string | null; + links?: + | { + label: string; + url: string; + type?: ('internal' | 'external' | 'download') | null; + id?: string | null; + }[] + | null; + /** + * Für spezielle Anwendungsfälle (z.B. Statistiken, Kennzahlen) + */ + metadata?: + | { + [k: string]: unknown; + } + | unknown[] + | string + | number + | boolean + | null; + id?: string | null; + }[]; + seo?: { + metaTitle?: string | null; + metaDescription?: string | null; + }; + updatedAt: string; + createdAt: string; +} +/** + * Komplexe Prozesse und Workflows mit Phasen, Abhängigkeiten und Status-Tracking + * + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "workflows". + */ +export interface Workflow { + id: number; + tenant?: (number | null) | Tenant; + /** + * Name des Workflows (z.B. "Projektablauf Webentwicklung") + */ + name: string; + /** + * URL-freundlicher Identifier + */ + slug: string; + /** + * Ausführliche Beschreibung des Workflows + */ + description?: { + root: { + type: string; + children: { + type: any; + version: number; + [k: string]: unknown; + }[]; + direction: ('ltr' | 'rtl') | null; + format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | ''; + indent: number; + version: number; + }; + [k: string]: unknown; + } | null; + /** + * Kurze Zusammenfassung für Übersichten + */ + shortDescription?: string | null; + type: 'project' | 'business' | 'approval' | 'onboarding' | 'support' | 'development' | 'marketing' | 'other'; + status: 'draft' | 'published' | 'archived'; + /** + * Optionales Bild für den Workflow + */ + image?: (number | null) | Media; + properties?: { + /** + * z.B. "4-6 Wochen", "3 Monate" + */ + estimatedDuration?: string | null; + complexity?: ('simple' | 'medium' | 'complex' | 'very_complex') | null; + /** + * Kann der Workflow wiederholt durchlaufen werden? + */ + isIterative?: boolean | null; + /** + * Können mehrere Phasen gleichzeitig aktiv sein? + */ + allowParallelPhases?: boolean | null; + }; + displayOptions?: { + layout?: ('vertical' | 'horizontal' | 'flowchart' | 'kanban' | 'gantt') | null; + showPhaseNumbers?: boolean | null; + showStepNumbers?: boolean | null; + showDurations?: boolean | null; + showResponsible?: boolean | null; + /** + * Zeigt Fortschrittsbalken basierend auf abgeschlossenen Schritten + */ + showProgress?: boolean | null; + colorScheme?: ('phase' | 'status' | 'priority' | 'brand') | null; + }; + /** + * Hauptabschnitte des Workflows + */ + phases: { + name: string; + description?: string | null; + /** + * Lucide Icon-Name (z.B. "rocket", "settings", "check-circle") + */ + icon?: string | null; + /** + * HEX-Farbe (z.B. "#3B82F6") oder Tailwind-Klasse + */ + color?: string | null; + /** + * z.B. "1 Woche", "2-3 Tage" + */ + estimatedDuration?: string | null; + /** + * Rolle oder Person (z.B. "Projektleiter", "Design-Team") + */ + responsible?: string | null; + /** + * Einzelne Schritte in dieser Phase + */ + steps: { + name: string; + description?: { + root: { + type: string; + children: { + type: any; + version: number; + [k: string]: unknown; + }[]; + direction: ('ltr' | 'rtl') | null; + format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | ''; + indent: number; + version: number; + }; + [k: string]: unknown; + } | null; + /** + * Für kompakte Ansichten + */ + shortDescription?: string | null; + stepType?: ('task' | 'decision' | 'milestone' | 'approval' | 'wait' | 'automatic') | null; + priority?: ('critical' | 'high' | 'normal' | 'low' | 'optional') | null; + /** + * z.B. "2 Stunden", "1 Tag" + */ + estimatedDuration?: string | null; + responsible?: string | null; + icon?: string | null; + /** + * Welche Schritte müssen vorher abgeschlossen sein? + */ + dependencies?: { + /** + * IDs oder Namen der Vorgänger-Schritte (komma-separiert). Leer = vorheriger Schritt + */ + dependsOnSteps?: string | null; + canRunParallel?: boolean | null; + /** + * Muss abgeschlossen sein, bevor der nächste Schritt beginnt + */ + isBlocking?: boolean | null; + }; + /** + * Für Entscheidungsschritte: Welche Wege gibt es? + */ + conditions?: + | { + /** + * z.B. "Wenn genehmigt", "Bei Budget > 10.000€" + */ + condition: string; + /** + * ID oder Name des nächsten Schritts + */ + nextStep?: string | null; + /** + * z.B. "green" für positiv, "red" für negativ + */ + color?: string | null; + id?: string | null; + }[] + | null; + /** + * To-Do-Punkte für diesen Schritt + */ + checklist?: + | { + item: string; + isRequired?: boolean | null; + id?: string | null; + }[] + | null; + resources?: + | { + name: string; + type?: ('document' | 'template' | 'link' | 'tool' | 'video') | null; + file?: (number | null) | Media; + url?: string | null; + description?: string | null; + id?: string | null; + }[] + | null; + /** + * Was wird in diesem Schritt produziert? + */ + outputs?: + | { + name: string; + description?: string | null; + id?: string | null; + }[] + | null; + /** + * Für spezielle Anwendungsfälle + */ + metadata?: + | { + [k: string]: unknown; + } + | unknown[] + | string + | number + | boolean + | null; + id?: string | null; + }[]; + /** + * Was wird am Ende dieser Phase abgeliefert? + */ + deliverables?: + | { + name: string; + description?: string | null; + id?: string | null; + }[] + | null; + id?: string | null; + }[]; + /** + * Ressourcen, die für den gesamten Workflow relevant sind + */ + globalResources?: + | { + name: string; + type?: ('document' | 'template' | 'checklist' | 'link' | 'tool') | null; + file?: (number | null) | Media; + url?: string | null; + description?: string | null; + id?: string | null; + }[] + | null; + seo?: { + metaTitle?: string | null; + metaDescription?: string | null; + }; + updatedAt: string; + createdAt: string; +} +/** + * Terminbuchungen für Fotoshootings + * + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "bookings". + */ +export interface Booking { + id: number; + tenant?: (number | null) | Tenant; + customerName: string; + customerEmail: string; + customerPhone?: string | null; + customerCompany?: string | null; + serviceType: + | 'wedding' + | 'portrait' + | 'business' + | 'event' + | 'product' + | 'family' + | 'newborn' + | 'maternity' + | 'realestate' + | 'other'; + /** + * Optional: Verknüpfung mit einem definierten Service + */ + service?: (number | null) | Service; + date: string; + /** + * z.B. 14:00 Uhr + */ + time?: string | null; + duration?: ('30' | '60' | '120' | '180' | '240' | '480' | 'custom') | null; + locationType?: ('studio' | 'outdoor' | 'customer' | 'event' | 'tbd') | null; + locationAddress?: string | null; + /** + * Wie viele Personen sollen fotografiert werden? + */ + participants?: number | null; + /** + * Besondere Wünsche, Ideen oder Anmerkungen + */ + message?: string | null; + /** + * Beispielbilder für gewünschten Stil + */ + referenceImages?: + | { + image?: (number | null) | Media; + note?: string | null; + id?: string | null; + }[] + | null; + status: 'pending' | 'review' | 'confirmed' | 'deposit' | 'completed' | 'cancelled' | 'noshow'; + priority?: ('high' | 'normal' | 'low') | null; + pricing?: { + /** + * In Euro + */ + estimatedPrice?: number | null; + finalPrice?: number | null; + depositAmount?: number | null; + depositPaid?: boolean | null; + fullyPaid?: boolean | null; + }; + /** + * Nur für interne Verwendung + */ + internalNotes?: + | { + note: string; + author?: (number | null) | User; + createdAt?: string | null; + id?: string | null; + }[] + | null; + contactHistory?: + | { + type: 'email_sent' | 'email_received' | 'call' | 'whatsapp' | 'inperson'; + summary: string; + date?: string | null; + id?: string | null; + }[] + | null; + assignedTo?: (number | null) | User; + source?: ('website' | 'phone' | 'email' | 'instagram' | 'facebook' | 'referral' | 'returning' | 'other') | null; + /** + * Kunde hat Datenschutzerklärung akzeptiert + */ + gdprConsent?: boolean | null; + updatedAt: string; + createdAt: string; +} +/** + * Zertifizierungen, Akkreditierungen und Qualitätssiegel + * + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "certifications". + */ +export interface Certification { + id: number; + tenant?: (number | null) | Tenant; + name: string; + /** + * URL-freundlicher Name + */ + slug: string; + description?: { + root: { + type: string; + children: { + type: any; + version: number; + [k: string]: unknown; + }[]; + direction: ('ltr' | 'rtl') | null; + format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | ''; + indent: number; + version: number; + }; + [k: string]: unknown; + } | null; + /** + * Für Übersichten und Meta-Beschreibungen + */ + shortDescription?: string | null; + type: 'iso' | 'din' | 'accreditation' | 'seal' | 'membership' | 'award' | 'license' | 'approval' | 'other'; + category?: + | ( + | 'quality' + | 'care' + | 'medical' + | 'hygiene' + | 'safety' + | 'privacy' + | 'environment' + | 'hr' + | 'it-security' + | 'accessibility' + | 'other' + ) + | null; + issuer: { + name: string; + logo?: (number | null) | Media; + website?: string | null; + country?: ('DE' | 'AT' | 'CH' | 'EU' | 'INT') | null; + }; + certNumber?: string | null; + issuedDate?: string | null; + validUntil?: string | null; + renewalCycle?: ('yearly' | '2years' | '3years' | '5years' | 'unlimited') | null; + logo?: (number | null) | Media; + /** + * Das offizielle Zertifikatsdokument + */ + certificate?: (number | null) | Media; + gallery?: + | { + document?: (number | null) | Media; + title?: string | null; + id?: string | null; + }[] + | null; + scope?: { + description?: string | null; + /** + * Für welche Standorte gilt die Zertifizierung? + */ + locations?: (number | Location)[] | null; + /** + * Für welche Leistungen gilt die Zertifizierung? + */ + services?: (number | Service)[] | null; + }; + requirements?: + | { + requirement: string; + description?: string | null; + id?: string | null; + }[] + | null; + benefits?: + | { + title: string; + description?: string | null; + icon?: ('check' | 'star' | 'shield' | 'heart' | 'lock' | 'search' | 'clock' | 'document') | null; + id?: string | null; + }[] + | null; + /** + * Historie der durchgeführten Audits + */ + audits?: + | { + date: string; + type?: ('initial' | 'surveillance' | 'recertification' | 'special') | null; + result?: ('passed' | 'conditional' | 'failed') | null; + notes?: string | null; + id?: string | null; + }[] + | null; + status: 'active' | 'pending' | 'renewal' | 'suspended' | 'expired' | 'withdrawn'; + visibility?: ('public' | 'request' | 'internal') | null; + /** + * Höhere Zahl = höhere Priorität in der Anzeige + */ + priority?: number | null; + showOnHomepage?: boolean | null; + seo?: { + metaTitle?: string | null; + metaDescription?: string | null; + }; + updatedAt: string; + createdAt: string; +} +/** + * Projekte, Spiele und kreative Arbeiten + * + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "projects". + */ +export interface Project { + id: number; + tenant?: (number | null) | Tenant; + title: string; + slug: string; + /** + * Kurze, prägnante Beschreibung (1 Zeile) + */ + tagline?: string | null; + description?: { + root: { + type: string; + children: { + type: any; + version: number; + [k: string]: unknown; + }[]; + direction: ('ltr' | 'rtl') | null; + format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | ''; + indent: number; + version: number; + }; + [k: string]: unknown; + } | null; + /** + * Für Übersichten und Social Media + */ + shortDescription?: string | null; + type: 'game' | 'demo' | 'mod' | 'tool' | 'assets' | 'prototype' | 'gamejam' | 'tutorial' | 'opensource' | 'other'; + genres?: + | ( + | 'action' + | 'adventure' + | 'rpg' + | 'strategy' + | 'simulation' + | 'puzzle' + | 'horror' + | 'shooter' + | 'platformer' + | 'racing' + | 'sports' + | 'fighting' + | 'music' + | 'visualnovel' + | 'survival' + | 'sandbox' + | 'towerdefense' + | 'roguelike' + | 'indie' + )[] + | null; + platforms?: + | ( + | 'windows' + | 'macos' + | 'linux' + | 'web' + | 'ios' + | 'android' + | 'playstation' + | 'xbox' + | 'switch' + | 'steamdeck' + | 'vr' + )[] + | null; + featuredImage: number | Media; + logo?: (number | null) | Media; + screenshots?: + | { + image: number | Media; + caption?: string | null; + id?: string | null; + }[] + | null; + videos?: + | { + type: 'trailer' | 'gameplay' | 'devlog' | 'tutorial' | 'other'; + title?: string | null; + /** + * YouTube, Vimeo oder direkter Link + */ + url: string; + thumbnail?: (number | null) | Media; + id?: string | null; + }[] + | null; + techStack?: { + engine?: + | ( + | 'unity' + | 'unreal' + | 'godot' + | 'gamemaker' + | 'rpgmaker' + | 'construct' + | 'custom' + | 'renpy' + | 'phaser' + | 'other' + ) + | null; + languages?: + | ('csharp' | 'cpp' | 'gdscript' | 'javascript' | 'typescript' | 'python' | 'lua' | 'rust' | 'blueprint')[] + | null; + /** + * z.B. Blender, Aseprite, FMOD + */ + tools?: string | null; + }; + requirements?: { + minimum?: { + os?: string | null; + cpu?: string | null; + ram?: string | null; + gpu?: string | null; + storage?: string | null; + }; + recommended?: { + os?: string | null; + cpu?: string | null; + ram?: string | null; + gpu?: string | null; + storage?: string | null; + }; + }; + releaseDate?: string | null; + links?: { + website?: string | null; + steam?: string | null; + itchio?: string | null; + epicGames?: string | null; + gog?: string | null; + playStore?: string | null; + appStore?: string | null; + github?: string | null; + discord?: string | null; + twitter?: string | null; + }; + downloads?: + | { + /** + * z.B. "Windows Build", "Demo v0.5" + */ + title: string; + platform?: ('windows' | 'macos' | 'linux' | 'universal') | null; + version?: string | null; + file?: (number | null) | Media; + externalUrl?: string | null; + size?: string | null; + id?: string | null; + }[] + | null; + features?: + | { + title: string; + description?: string | null; + icon?: (number | null) | Media; + id?: string | null; + }[] + | null; + team?: + | { + name: string; + role?: string | null; + link?: string | null; + avatar?: (number | null) | Media; + id?: string | null; + }[] + | null; + gameJam?: { + jamName?: string | null; + theme?: string | null; + /** + * z.B. "48 Stunden" + */ + duration?: string | null; + ranking?: string | null; + jamLink?: string | null; + }; + /** + * Verknüpfte Blog-Posts über dieses Projekt + */ + devlogs?: (number | Post)[] | null; + status: 'development' | 'earlyaccess' | 'released' | 'paused' | 'cancelled' | 'completed'; + visibility?: ('public' | 'draft' | 'unlisted' | 'private') | null; + featured?: boolean | null; + /** + * Höher = weiter oben + */ + sortOrder?: number | null; + seo?: { + metaTitle?: string | null; + metaDescription?: string | null; + ogImage?: (number | null) | Media; + }; + updatedAt: string; + createdAt: string; +} +/** + * Affiliate-Produkte und Favoriten + * + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "favorites". + */ +export interface Favorite { + id: number; + tenant?: (number | null) | Tenant; + title: string; + /** + * URL-freundlicher Name + */ + slug: string; + /** + * Kurze Produktbeschreibung (max. 300 Zeichen) + */ + description?: string | null; + category: 'fashion' | 'beauty' | 'travel' | 'tech' | 'home'; + /** + * z.B. "Taschen", "Hautpflege", "Laptops" + */ + subcategory?: string | null; + /** + * Aktueller Preis in Euro + */ + price?: number | null; + priceRange?: ('budget' | 'mid' | 'premium' | 'luxury') | null; + /** + * Vollständiger Affiliate-Link mit Tracking + */ + affiliateUrl: string; + affiliateNetwork?: ('amazon' | 'awin' | 'ltk' | 'direct' | 'other') | null; + /** + * Hauptbild des Produkts + */ + image: number | Media; + /** + * Optionales Label/Abzeichen + */ + badge?: ('investment-piece' | 'daily-driver' | 'grfi-approved' | 'new' | 'bestseller') | null; + /** + * In der Featured-Sektion anzeigen + */ + featured?: boolean | null; + /** + * Inaktive Favoriten werden nicht angezeigt + */ + isActive: boolean; + /** + * Niedrigere Zahlen werden zuerst angezeigt + */ + order?: number | null; + updatedAt: string; + createdAt: string; +} +/** + * Content-Pipeline für YouTube-Videos + * + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "youtube-content". + */ +export interface YoutubeContent { + id: number; + /** + * Max. 60 Zeichen für YouTube empfohlen + */ + title: string; + /** + * URL-freundlicher Name (wird automatisch generiert) + */ + slug: string; + channel: number | YoutubeChannel; + /** + * Content-Serie für dieses Video + */ + series?: (number | null) | YtSery; + format: 'short' | 'longform' | 'premiere'; + status: + | 'idea' + | 'script_draft' + | 'script_review' + | 'script_approved' + | 'shoot_scheduled' + | 'shot' + | 'rough_cut' + | 'fine_cut' + | 'final_review' + | 'approved' + | 'upload_scheduled' + | 'published' + | 'tracked' + | 'discarded'; + priority?: ('urgent' | 'high' | 'normal' | 'low') | null; + assignedTo?: (number | null) | User; + createdBy?: (number | null) | User; + productionBatch?: (number | null) | YtBatch; + description?: string | null; + /** + * Was sagt/zeigt der Creator in den ersten 3 Sekunden? + */ + hook?: string | null; + keyPoints?: + | { + point?: string | null; + id?: string | null; + }[] + | null; + callToAction?: string | null; + scriptUrl?: string | null; + scriptContent?: { + root: { + type: string; + children: { + type: any; + version: number; + [k: string]: unknown; + }[]; + direction: ('ltr' | 'rtl') | null; + format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | ''; + indent: number; + version: number; + }; + [k: string]: unknown; + } | null; + shootDate?: string | null; + editDeadline?: string | null; + reviewDeadline?: string | null; + scheduledPublishDate?: string | null; + actualPublishDate?: string | null; + productionWeek?: number | null; + calendarWeek?: number | null; + productionDate?: string | null; + targetDuration?: string | null; + bRollNotes?: string | null; + publishTime?: string | null; + thumbnailText?: string | null; + ctaType?: ('link_in_bio' | 'newsletter' | 'longform_link' | 'custom') | null; + ctaDetail?: string | null; + uploadChecklist?: + | { + step: string; + completed?: boolean | null; + completedAt?: string | null; + id?: string | null; + }[] + | null; + disclaimers?: + | { + type: 'medical' | 'legal' | 'affiliate' | 'sponsored'; + text?: string | null; + placement?: ('spoken' | 'overlay' | 'description' | 'all') | null; + id?: string | null; + }[] + | null; + thumbnail?: (number | null) | Media; + thumbnailAlt?: (number | null) | Media; + videoFile?: (number | null) | Media; + rawFootage?: + | { + file?: (number | null) | Media; + description?: string | null; + id?: string | null; + }[] + | null; + approvals?: { + scriptApproval?: { + approved?: boolean | null; + approvedBy?: (number | null) | User; + approvedAt?: string | null; + notes?: string | null; + }; + /** + * Nur für Corporate-Kanäle relevant + */ + medicalApproval?: { + required?: boolean | null; + approved?: boolean | null; + approvedBy?: (number | null) | User; + approvedAt?: string | null; + notes?: string | null; + }; + legalApproval?: { + approved?: boolean | null; + approvedBy?: (number | null) | User; + approvedAt?: string | null; + disclaimerIncluded?: boolean | null; + notes?: string | null; + }; + finalApproval?: { + approved?: boolean | null; + approvedBy?: (number | null) | User; + approvedAt?: string | null; + notes?: string | null; + }; + }; + youtube?: { + videoId?: string | null; + url?: string | null; + metadata?: { + youtubeTitle?: string | null; + youtubeDescription?: string | null; + tags?: + | { + tag?: string | null; + id?: string | null; + }[] + | null; + visibility?: ('public' | 'unlisted' | 'private') | null; + chapters?: string | null; + pinnedComment?: string | null; + }; + }; + /** + * Automatisch via YouTube API aktualisiert + */ + performance?: { + views?: number | null; + likes?: number | null; + comments?: number | null; + shares?: number | null; + watchTimeMinutes?: number | null; + avgViewDuration?: number | null; + avgViewPercentage?: number | null; + ctr?: number | null; + impressions?: number | null; + subscribersGained?: number | null; + lastSyncedAt?: string | null; + }; + /** + * Für ROI-Berechnung (manuell pflegen) + */ + costs?: { + estimatedProductionHours?: number | null; + estimatedProductionCost?: number | null; + /** + * AdSense + Sponsoring + Affiliate + */ + estimatedRevenue?: number | null; + }; + /** + * Nur für das Team sichtbar + */ + internalNotes?: { + root: { + type: string; + children: { + type: any; + version: number; + [k: string]: unknown; + }[]; + direction: ('ltr' | 'rtl') | null; + format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | ''; + indent: number; + version: number; + }; + [k: string]: unknown; + } | null; + updatedAt: string; + createdAt: string; +} +/** + * Content-Serien für YouTube-Kanäle + * + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "yt-series". + */ +export interface YtSery { + id: number; + name: string; + /** + * URL-freundlicher Name (eindeutig pro Kanal) + */ + slug: string; + channel: number | YoutubeChannel; + description?: string | null; + /** + * Serien-Logo (transparent PNG empfohlen) + */ + logo?: (number | null) | Media; + /** + * Hauptbild für die Serie (16:9 empfohlen) + */ + coverImage?: (number | null) | Media; + /** + * Hex-Farbcode + */ + brandColor?: string | null; + /** + * Sekundäre Farbe + */ + accentColor?: string | null; + /** + * Die Playlist-ID aus YouTube (z.B. PLxxxxxx) + */ + youtubePlaylistId?: string | null; + /** + * Vollständiger Link zur YouTube-Playlist + */ + youtubePlaylistUrl?: string | null; + format?: ('short' | 'longform' | 'mixed') | null; + publishingFrequency?: string | null; + /** + * Inaktive Serien werden nicht angezeigt + */ + isActive?: boolean | null; + /** + * Niedrigere Zahlen werden zuerst angezeigt + */ + order?: number | null; + updatedAt: string; + createdAt: string; +} +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "yt-batches". + */ +export interface YtBatch { + id: number; + name: string; + channel?: (number | null) | YoutubeChannel; + status?: ('planning' | 'production' | 'published') | null; + productionPeriodStart?: string | null; + productionPeriodEnd?: string | null; + targets?: { + shortsTarget?: number | null; + longformsTarget?: number | null; + totalTarget?: number | null; + bufferDays?: number | null; + }; + progress?: { + shortsCompleted?: number | null; + longformsCompleted?: number | null; + percentage?: number | null; + }; + team?: { + producer?: (number | null) | User; + editor?: (number | null) | User; + reviewer?: (number | null) | User; + }; + updatedAt: string; + createdAt: string; +} +/** + * Aufgaben für die Video-Produktion + * + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "yt-tasks". + */ +export interface YtTask { + id: number; + title: string; + description?: string | null; + video?: (number | null) | YoutubeContent; + /** + * Wird automatisch vom Video übernommen + */ + channel?: (number | null) | YoutubeChannel; + taskType: + | 'script_write' + | 'script_review' + | 'shoot_prep' + | 'shoot' + | 'edit' + | 'graphics' + | 'thumbnail' + | 'review' + | 'upload' + | 'track' + | 'comments' + | 'other'; + status: 'todo' | 'in_progress' | 'blocked' | 'waiting_review' | 'done' | 'cancelled'; + priority?: ('urgent' | 'high' | 'normal' | 'low') | null; + assignedTo: number | User; + dueDate?: string | null; + completedAt?: string | null; + completedBy?: (number | null) | User; + blockedReason?: string | null; + attachments?: + | { + file?: (number | null) | Media; + note?: string | null; + id?: string | null; + }[] + | null; + comments?: + | { + author?: (number | null) | User; + content?: string | null; + createdAt?: string | null; + id?: string | null; + }[] + | null; + updatedAt: string; + createdAt: string; +} +/** + * Benachrichtigungen für YouTube Operations + * + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "yt-notifications". + */ +export interface YtNotification { + id: number; + recipient: number | User; + type: + | 'task_assigned' + | 'task_due' + | 'task_overdue' + | 'approval_required' + | 'approved' + | 'rejected' + | 'video_published' + | 'comment' + | 'mention' + | 'token_expiring' + | 'token_expired' + | 'token_refresh_failed' + | 'token_refreshed' + | 'system'; + title: string; + message?: string | null; + /** + * Relativer Pfad zum relevanten Element + */ + link?: string | null; + relatedVideo?: (number | null) | YoutubeContent; + relatedTask?: (number | null) | YtTask; + /** + * Verknüpfter Social Account (für Token-Benachrichtigungen) + */ + relatedAccount?: (number | null) | SocialAccount; + read?: boolean | null; + readAt?: string | null; + emailSent?: boolean | null; + updatedAt: string; + createdAt: string; +} +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "social-accounts". + */ +export interface SocialAccount { + id: number; + platform: number | SocialPlatform; + /** + * Für Zuordnung zu Brand/Kanal + */ + linkedChannel?: (number | null) | YoutubeChannel; + displayName: string; + accountHandle?: string | null; + /** + * YouTube Channel ID, LinkedIn URN, etc. + */ + externalId?: string | null; + accountUrl?: string | null; + isActive?: boolean | null; + /** + * Sensible Daten – nur für Super-Admins sichtbar + */ + credentials?: { + /** + * OAuth Access Token + */ + accessToken?: string | null; + refreshToken?: string | null; + tokenExpiresAt?: string | null; + /** + * Für API-Key basierte Auth + */ + apiKey?: string | null; + }; + stats?: { + followers?: number | null; + totalPosts?: number | null; + lastSyncedAt?: string | null; + }; + syncSettings?: { + autoSyncEnabled?: boolean | null; + syncIntervalMinutes?: number | null; + syncComments?: boolean | null; + /** + * Nicht alle Plattformen unterstützen DM-API + */ + syncDMs?: boolean | null; + }; + updatedAt: string; + createdAt: string; +} +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "social-platforms". + */ +export interface SocialPlatform { + id: number; + name: string; + slug: string; + icon?: string | null; + color?: string | null; + isActive?: boolean | null; + apiStatus?: ('connected' | 'limited' | 'disconnected' | 'development') | null; + apiConfig?: { + apiType?: ('youtube_v3' | 'linkedin' | 'instagram_graph' | 'facebook_graph' | 'meta_graph' | 'custom') | null; + baseUrl?: string | null; + authType?: ('oauth2' | 'api_key' | 'bearer') | null; + /** + * Relativer API-Pfad für OAuth-Initiation (z.B. /api/youtube/auth) + */ + oauthEndpoint?: string | null; + scopes?: + | { + scope?: string | null; + id?: string | null; + }[] + | null; + /** + * Wie lange ist der Access Token gültig? (YouTube: unbegrenzt mit Refresh, Meta: 60 Tage) + */ + tokenValidityDays?: number | null; + }; + interactionTypes?: + | { + type: string; + label: string; + icon?: string | null; + canReply?: boolean | null; + id?: string | null; + }[] + | null; + rateLimits?: { + requestsPerMinute?: number | null; + requestsPerDay?: number | null; + /** + * YouTube: 10.000/Tag + */ + quotaUnitsPerDay?: number | null; + }; + updatedAt: string; + createdAt: string; +} +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "yt-monthly-goals". + */ +export interface YtMonthlyGoal { + id: number; + channel: number | YoutubeChannel; + month: string; + displayTitle?: string | null; + contentGoals?: { + longformsTarget?: number | null; + longformsCurrent?: number | null; + shortsTarget?: number | null; + shortsCurrent?: number | null; + }; + audienceGoals?: { + subscribersTarget?: number | null; + subscribersCurrent?: number | null; + viewsTarget?: number | null; + viewsCurrent?: number | null; + }; + engagementGoals?: { + avgCtrTarget?: string | null; + avgCtrCurrent?: string | null; + avgRetentionTarget?: string | null; + avgRetentionCurrent?: string | null; + }; + businessGoals?: { + newsletterSignupsTarget?: number | null; + newsletterSignupsCurrent?: number | null; + affiliateRevenueTarget?: number | null; + affiliateRevenueCurrent?: number | null; + }; + customGoals?: + | { + metric: string; + target: string; + current?: string | null; + status?: ('on_track' | 'at_risk' | 'achieved' | 'missed') | null; + id?: string | null; + }[] + | null; + notes?: string | null; + updatedAt: string; + createdAt: string; +} +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "yt-script-templates". + */ +export interface YtScriptTemplate { + id: number; + name: string; + channel: number | YoutubeChannel; + series: string; + format: 'short' | 'longform'; + description?: string | null; + updatedAt: string; + createdAt: string; +} +/** + * Reusable checklists for upload and production + * + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "yt-checklist-templates". + */ +export interface YtChecklistTemplate { + id: number; + name: string; + /** + * Optional: Channel-specific template + */ + channel?: (number | null) | YoutubeChannel; + type: 'upload' | 'production' | 'review' | 'post_publish'; + format?: ('all' | 'short' | 'longform') | null; + /** + * When to use this checklist + */ + description?: string | null; + items: { + order?: number | null; + task: string; + category?: ('metadata' | 'assets' | 'seo' | 'community' | 'legal' | 'other') | null; + details?: string | null; + isRequired?: boolean | null; + id?: string | null; + }[]; + /** + * Automatically used for new videos + */ + isDefault?: boolean | null; + isActive?: boolean | null; + updatedAt: string; + createdAt: string; +} +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "community-interactions". + */ +export interface CommunityInteraction { + id: number; + platform: number | SocialPlatform; + socialAccount: number | SocialAccount; + linkedContent?: (number | null) | YoutubeContent; + type: 'comment' | 'reply' | 'dm' | 'mention' | 'review' | 'question'; + /** + * YouTube Comment ID, etc. + */ + externalId: string; + parentInteraction?: (number | null) | CommunityInteraction; + author?: { + name?: string | null; + handle?: string | null; + profileUrl?: string | null; + avatarUrl?: string | null; + isVerified?: boolean | null; + isSubscriber?: boolean | null; + isMember?: boolean | null; + subscriberCount?: number | null; + }; + message: string; + /** + * Falls Plattform HTML liefert + */ + messageHtml?: string | null; + attachments?: + | { + type?: ('image' | 'video' | 'link' | 'sticker') | null; + url?: string | null; + id?: string | null; + }[] + | null; + publishedAt: string; + /** + * Automatisch via Claude API + */ + analysis?: { + sentiment?: ('positive' | 'neutral' | 'negative' | 'question' | 'gratitude' | 'frustration') | null; + sentimentScore?: number | null; + confidence?: number | null; + topics?: + | { + topic?: string | null; + id?: string | null; + }[] + | null; + language?: string | null; + suggestedTemplate?: (number | null) | CommunityTemplate; + suggestedReply?: string | null; + analyzedAt?: string | null; + }; + flags?: { + /** + * Erfordert ärztliche Review + */ + isMedicalQuestion?: boolean | null; + requiresEscalation?: boolean | null; + isSpam?: boolean | null; + /** + * >10k Follower + */ + isFromInfluencer?: boolean | null; + }; + status: 'new' | 'in_review' | 'waiting' | 'replied' | 'resolved' | 'archived' | 'spam'; + priority: 'urgent' | 'high' | 'normal' | 'low'; + assignedTo?: (number | null) | User; + responseDeadline?: string | null; + response?: { + text?: string | null; + usedTemplate?: (number | null) | CommunityTemplate; + sentAt?: string | null; + sentBy?: (number | null) | User; + externalReplyId?: string | null; + }; + /** + * Wird beim Sync aktualisiert + */ + engagement?: { + likes?: number | null; + replies?: number | null; + isHearted?: boolean | null; + isPinned?: boolean | null; + }; + /** + * Nur für Team sichtbar + */ + internalNotes?: string | null; + updatedAt: string; + createdAt: string; +} +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "community-templates". + */ +export interface CommunityTemplate { + id: number; + name: string; + category: + | 'thank_you' + | 'question_answer' + | 'redirect_hotline' + | 'medical_disclaimer' + | 'product_info' + | 'content_reference' + | 'follow_up' + | 'negative_feedback' + | 'spam_response' + | 'welcome'; + /** + * Leer = für alle Kanäle + */ + channel?: (number | null) | YoutubeChannel; + /** + * Leer = für alle Plattformen + */ + platforms?: (number | SocialPlatform)[] | null; + /** + * Variablen: {{author_name}}, {{video_title}}, {{channel_name}}, {{hotline_number}} + */ + template: string; + /** + * Dokumentation der Variablen in diesem Template + */ + variables?: + | { + variable: string; + description?: string | null; + defaultValue?: string | null; + id?: string | null; + }[] + | null; + /** + * Bei diesen Keywords wird das Template vorgeschlagen + */ + autoSuggestKeywords?: + | { + keyword: string; + id?: string | null; + }[] + | null; + /** + * Für medizinische Antworten + */ + requiresReview?: boolean | null; + isActive?: boolean | null; + usageCount?: number | null; + /** + * So sieht die Antwort mit ausgefüllten Variablen aus + */ + exampleOutput?: string | null; + updatedAt: string; + createdAt: string; +} +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "community-rules". + */ +export interface CommunityRule { + id: number; + name: string; + /** + * Niedrigere Zahl = höhere Priorität + */ + priority: number; + isActive?: boolean | null; + description?: string | null; + /** + * Leer = alle Kanäle + */ + channel?: (number | null) | YoutubeChannel; + /** + * Leer = alle Plattformen + */ + platforms?: (number | SocialPlatform)[] | null; + trigger: { + type: + | 'keyword' + | 'sentiment' + | 'question_detected' + | 'medical_detected' + | 'influencer' + | 'all_new' + | 'contains_link' + | 'contains_email'; + keywords?: + | { + keyword: string; + matchType?: ('contains' | 'exact' | 'regex') | null; + id?: string | null; + }[] + | null; + sentimentValues?: ('positive' | 'negative' | 'neutral' | 'question')[] | null; + influencerMinFollowers?: number | null; + }; + actions: { + action: + | 'set_priority' + | 'assign_to' + | 'set_flag' + | 'suggest_template' + | 'send_notification' + | 'flag_medical' + | 'escalate' + | 'mark_spam' + | 'set_deadline'; + /** + * Priority: urgent/high/normal/low, Deadline: Stunden + */ + value?: string | null; + targetUser?: (number | null) | User; + targetTemplate?: (number | null) | CommunityTemplate; + id?: string | null; + }[]; + stats?: { + timesTriggered?: number | null; + lastTriggeredAt?: string | null; + }; + updatedAt: string; + createdAt: string; +} +/** + * Automatische Community-Reports per E-Mail + * + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "report-schedules". + */ +export interface ReportSchedule { + id: number; + /** + * Interner Name für diesen Report-Zeitplan + */ + name: string; + /** + * Deaktivierte Reports werden nicht automatisch versendet + */ + enabled?: boolean | null; + frequency: 'daily' | 'weekly' | 'monthly'; + /** + * Für wöchentliche Reports + */ + dayOfWeek?: ('monday' | 'tuesday' | 'wednesday' | 'thursday' | 'friday' | 'saturday' | 'sunday') | null; + /** + * Für monatliche Reports (1-28) + */ + dayOfMonth?: number | null; + /** + * Format: HH:MM (24-Stunden) + */ + time: string; + timezone: 'Europe/Berlin' | 'Europe/London' | 'America/New_York' | 'America/Los_Angeles' | 'Asia/Tokyo' | 'UTC'; + /** + * Art der Daten im Report + */ + reportType: 'overview' | 'sentiment_analysis' | 'response_metrics' | 'content_performance' | 'full_report'; + /** + * Leer = alle aktiven Kanäle. Oder spezifische Kanäle auswählen. + */ + channels?: (number | SocialAccount)[] | null; + /** + * Wie viele Tage zurück sollen analysiert werden? + */ + periodDays?: number | null; + format: 'pdf' | 'excel' | 'html_email'; + recipients: { + email: string; + /** + * Optional + */ + name?: string | null; + id?: string | null; + }[]; + lastSentAt?: string | null; + nextScheduledAt?: string | null; + sendCount?: number | null; + lastError?: string | null; + updatedAt: string; + createdAt: string; +} +/** + * Cookie-Banner Konfiguration pro Tenant + * + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "cookie-configurations". + */ +export interface CookieConfiguration { + id: number; + /** + * Jeder Tenant kann nur eine Konfiguration haben + */ + tenant: number | Tenant; + /** + * Interner Titel zur Identifikation + */ + title: string; + /** + * Bei inhaltlichen Änderungen erhöhen → erzwingt erneuten Consent bei allen Nutzern + */ + revision: number; + /** + * Welche Kategorien sollen im Banner angezeigt werden? + */ + enabledCategories: ('necessary' | 'functional' | 'analytics' | 'marketing')[]; + translations?: { + de?: { + bannerTitle?: string | null; + bannerDescription?: string | null; + acceptAllButton?: string | null; + acceptNecessaryButton?: string | null; + settingsButton?: string | null; + saveButton?: string | null; + privacyPolicyUrl?: string | null; + categoryLabels?: { + necessary?: { + title?: string | null; + description?: string | null; + }; + functional?: { + title?: string | null; + description?: string | null; + }; + analytics?: { + title?: string | null; + description?: string | null; + }; + marketing?: { + title?: string | null; + description?: string | null; + }; + }; + }; + }; + styling?: { + position?: ('bottom' | 'top' | 'middle') | null; + theme?: ('dark' | 'light' | 'auto') | null; + }; + updatedAt: string; + createdAt: string; +} +/** + * Cookie-Dokumentation für die Datenschutzerklärung + * + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "cookie-inventory". + */ +export interface CookieInventory { + id: number; + tenant: number | Tenant; + /** + * Technischer Name des Cookies (z.B. "_ga") + */ + name: string; + /** + * Anbieter (z.B. "Google LLC") + */ + provider: string; + category: 'necessary' | 'functional' | 'analytics' | 'marketing'; + /** + * Speicherdauer (z.B. "2 Jahre") + */ + duration: string; + /** + * Verständliche Erklärung für Endnutzer + */ + description: string; + isActive?: boolean | null; + updatedAt: string; + createdAt: string; +} +/** + * WORM Audit-Trail für Cookie-Einwilligungen (unveränderbar) + * + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "consent-logs". + */ +export interface ConsentLog { + id: number; + /** + * Server-generierte eindeutige ID + */ + consentId: string; + /** + * Client-seitige Referenz (Cookie-UUID) für Traceability + */ + clientRef?: string | null; + tenant: number | Tenant; + /** + * Akzeptierte Kategorien zum Zeitpunkt der Einwilligung + */ + categories: + | { + [k: string]: unknown; + } + | unknown[] + | string + | number + | boolean + | null; + /** + * Version der Konfiguration zum Zeitpunkt der Zustimmung + */ + revision: number; + /** + * Browser/Device (für Forensik und Bot-Erkennung) + */ + userAgent?: string | null; + /** + * HMAC-Hash der IP (täglich rotierender, tenant-spezifischer Salt) + */ + anonymizedIp?: string | null; + /** + * Automatische Löschung nach 3 Jahren + */ + expiresAt: string; + updatedAt: string; + createdAt: string; +} +/** + * Externe Datenschutzerklärung Konfiguration (Alfright) + * + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "privacy-policy-settings". + */ +export interface PrivacyPolicySetting { + id: number; + /** + * Jeder Tenant kann nur eine Konfiguration haben + */ + tenant: number | Tenant; + /** + * Interner Titel zur Identifikation + */ + title: string; + /** + * Quelle der Datenschutzerklärung + */ + provider: 'alfright' | 'internal'; + /** + * Einstellungen für die Alfright Integration + */ + alfright?: { + /** + * Alfright Tenant-ID (aus dem iframe-Code) + */ + tenantId: string; + /** + * Alfright API-Key / Dokument-ID (aus dem iframe-Code, z.B. "9f315103c43245bcb0806dd56c2be757") + */ + apiKey: string; + /** + * Sprache der Datenschutzerklärung + */ + language: 'de-de' | 'de-at' | 'de-ch' | 'en-gb' | 'en-us'; + /** + * Höhe des iframes in Pixeln (empfohlen: 3000-5000) + */ + iframeHeight: number; + }; + /** + * Farben und Schriften an das Website-Design anpassen + */ + styling?: { + /** + * Farbe der Überschriften (Hex-Code, z.B. #ca8a04 für Gold) + */ + headerColor: string; + /** + * Schriftart der Überschriften + */ + headerFont: string; + /** + * Schriftgröße der Hauptüberschriften + */ + headerSize: string; + /** + * Schriftgröße der Unterüberschriften + */ + subheaderSize: string; + /** + * Textfarbe (Hex-Code, z.B. #f3f4f6 für hellen Text) + */ + fontColor: string; + /** + * Schriftart für Fließtext + */ + textFont: string; + /** + * Schriftgröße für Fließtext + */ + textSize: string; + /** + * Linkfarbe (Hex-Code) + */ + linkColor: string; + /** + * Hintergrundfarbe (Hex-Code, z.B. #111827 für Dark Theme) + */ + backgroundColor: string; + }; + /** + * Cookie-Tabelle aus CookieInventory unterhalb der Datenschutzerklärung anzeigen + */ + showCookieTable?: boolean | null; + /** + * Überschrift für die Cookie-Tabelle + */ + cookieTableTitle?: string | null; + /** + * Einleitungstext für die Cookie-Tabelle + */ + cookieTableDescription?: string | null; + seo?: { + /** + * Meta-Titel für die Seite + */ + metaTitle?: string | null; + /** + * Meta-Beschreibung für Suchmaschinen + */ + metaDescription?: string | null; + }; + updatedAt: string; + createdAt: string; +} +/** + * Protokoll aller gesendeten E-Mails + * + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "email-logs". + */ +export interface EmailLog { + id: number; + tenant: number | Tenant; + to: string; + from: string; + subject: string; + status: 'pending' | 'sent' | 'failed'; + /** + * SMTP Message-ID bei erfolgreichem Versand + */ + messageId?: string | null; + error?: string | null; + source: 'manual' | 'form' | 'system' | 'newsletter'; + /** + * Zusätzliche Kontextinformationen (z.B. Form-ID) + */ + metadata?: + | { + [k: string]: unknown; + } + | unknown[] + | string + | number + | boolean + | null; + updatedAt: string; + createdAt: string; +} +/** + * Protokoll wichtiger System-Aktionen + * + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "audit-logs". + */ +export interface AuditLog { + id: number; + action: + | 'login_success' + | 'login_failed' + | 'logout' + | 'password_changed' + | 'password_reset' + | 'create' + | 'update' + | 'delete' + | 'config_changed' + | 'email_failed' + | 'access_denied' + | 'rate_limit'; + severity: 'info' | 'warning' | 'error' | 'critical'; + entityType?: ('users' | 'tenants' | 'pages' | 'posts' | 'media' | 'forms' | 'email' | 'global' | 'system') | null; + /** + * ID des betroffenen Dokuments + */ + entityId?: string | null; + /** + * Benutzer, der die Aktion ausgeführt hat + */ + user?: (number | null) | User; + /** + * E-Mail zum Zeitpunkt der Aktion (für gelöschte User) + */ + userEmail?: string | null; + /** + * Betroffener Tenant (falls zutreffend) + */ + tenant?: (number | null) | Tenant; + ipAddress?: string | null; + userAgent?: string | null; + /** + * Detaillierte Beschreibung der Aktion + */ + description?: string | null; + /** + * Zustand vor der Änderung + */ + previousValue?: + | { + [k: string]: unknown; + } + | unknown[] + | string + | number + | boolean + | null; + /** + * Zustand nach der Änderung + */ + newValue?: + | { + [k: string]: unknown; + } + | unknown[] + | string + | number + | boolean + | null; + /** + * Weitere Kontextinformationen + */ + metadata?: + | { + [k: string]: unknown; + } + | unknown[] + | string + | number + | boolean + | null; + updatedAt: string; + createdAt: string; +} +/** + * Historische System-Metriken für Trend-Charts + * + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "monitoring-snapshots". + */ +export interface MonitoringSnapshot { + id: number; + timestamp: string; + /** + * System-Ressourcen (CPU, RAM, Disk) + */ + system?: { + cpuUsagePercent?: number | null; + memoryUsedMB?: number | null; + memoryTotalMB?: number | null; + memoryUsagePercent?: number | null; + diskUsedGB?: number | null; + diskTotalGB?: number | null; + diskUsagePercent?: number | null; + loadAvg1?: number | null; + loadAvg5?: number | null; + /** + * Uptime in Sekunden + */ + uptime?: number | null; + }; + /** + * Service-Status (PM2-Prozesse, Datenbank, Cache) + */ + services?: { + payload?: + | { + [k: string]: unknown; + } + | unknown[] + | string + | number + | boolean + | null; + queueWorker?: + | { + [k: string]: unknown; + } + | unknown[] + | string + | number + | boolean + | null; + postgresql?: + | { + [k: string]: unknown; + } + | unknown[] + | string + | number + | boolean + | null; + pgbouncer?: + | { + [k: string]: unknown; + } + | unknown[] + | string + | number + | boolean + | null; + redis?: + | { + [k: string]: unknown; + } + | unknown[] + | string + | number + | boolean + | null; + }; + /** + * Externe Services (SMTP, OAuth, Cron) + */ + external?: { + smtp?: + | { + [k: string]: unknown; + } + | unknown[] + | string + | number + | boolean + | null; + metaOAuth?: + | { + [k: string]: unknown; + } + | unknown[] + | string + | number + | boolean + | null; + youtubeOAuth?: + | { + [k: string]: unknown; + } + | unknown[] + | string + | number + | boolean + | null; + cronJobs?: + | { + [k: string]: unknown; + } + | unknown[] + | string + | number + | boolean + | null; + secrets?: + | { + [k: string]: unknown; + } + | unknown[] + | string + | number + | boolean + | null; + securityEvents?: + | { + [k: string]: unknown; + } + | unknown[] + | string + | number + | boolean + | null; + }; + /** + * Performance-Metriken + */ + performance?: { + avgResponseTimeMs?: number | null; + p95ResponseTimeMs?: number | null; + p99ResponseTimeMs?: number | null; + errorRate?: number | null; + requestsPerMinute?: number | null; + }; + updatedAt: string; + createdAt: string; +} +/** + * Structured Logs für Business-Events + * + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "monitoring-logs". + */ +export interface MonitoringLog { + id: number; + level: 'debug' | 'info' | 'warn' | 'error' | 'fatal'; + source: 'payload' | 'queue-worker' | 'cron' | 'email' | 'oauth' | 'sync' | 'security'; + message: string; + /** + * Strukturierte Metadaten + */ + context?: + | { + [k: string]: unknown; + } + | unknown[] + | string + | number + | boolean + | null; + /** + * Korrelations-ID + */ + requestId?: string | null; + userId?: (number | null) | User; + tenant?: (number | null) | Tenant; + /** + * Dauer in ms + */ + duration?: number | null; + updatedAt: string; + createdAt: string; +} +/** + * Konfigurierbare Alert-Regeln + * + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "monitoring-alert-rules". + */ +export interface MonitoringAlertRule { + id: number; + name: string; + /** + * z.B. system.cpuUsagePercent, services.redis.memoryUsedMB + */ + metric: string; + condition: 'gt' | 'lt' | 'eq' | 'gte' | 'lte'; + threshold: number; + severity: 'warning' | 'error' | 'critical'; + channels: ('email' | 'slack' | 'discord')[]; + recipients?: { + emails?: + | { + email: string; + id?: string | null; + }[] + | null; + slackWebhook?: string | null; + discordWebhook?: string | null; + }; + /** + * Minimaler Abstand zwischen gleichen Alerts + */ + cooldownMinutes?: number | null; + enabled?: boolean | null; + /** + * Optional: Tenant-spezifische Regel + */ + tenant?: (number | null) | Tenant; + updatedAt: string; + createdAt: string; +} +/** + * Alert-Log (WORM - Write Once) + * + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "monitoring-alert-history". + */ +export interface MonitoringAlertHistory { + id: number; + rule?: (number | null) | MonitoringAlertRule; + metric: string; + value: number; + threshold: number; + severity: 'warning' | 'error' | 'critical'; + message: string; + channelsSent?: ('email' | 'slack' | 'discord')[] | null; + resolvedAt?: string | null; + acknowledgedBy?: (number | null) | User; + updatedAt: string; + createdAt: string; +} +/** + * Allgemeine Website-Einstellungen pro Tenant + * + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "site-settings". + */ +export interface SiteSetting { + id: number; + tenant?: (number | null) | Tenant; + siteName: string; + siteTagline?: string | null; + logo?: (number | null) | Media; + favicon?: (number | null) | Media; + contact?: { + email?: string | null; + phone?: string | null; + fax?: string | null; + }; + address?: { + /** + * z.B. "Hans-Böckler-Str. 19" + */ + street?: string | null; + /** + * z.B. "Gebäude B, 3. Stock" + */ + additionalLine?: string | null; + zip?: string | null; + city?: string | null; + state?: string | null; + country?: string | null; + }; + /** + * Für Kartenanzeige (Google Maps, OpenStreetMap) + */ + geo?: { + /** + * z.B. 51.521732 + */ + lat?: number | null; + /** + * z.B. 6.928850 + */ + lng?: number | null; + /** + * 1 = Weltkarte, 20 = Straßenebene + */ + zoom?: number | null; + }; + footer?: { + copyrightText?: string | null; + showSocialLinks?: boolean | null; + }; + seo?: { + defaultMetaTitle?: string | null; + defaultMetaDescription?: string | null; + defaultOgImage?: (number | null) | Media; + }; + updatedAt: string; + createdAt: string; +} +/** + * Navigationsmenüs pro Tenant + * + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "navigations". + */ +export interface Navigation { + id: number; + tenant?: (number | null) | Tenant; + /** + * Interner Name zur Identifikation + */ + title: string; + mainMenu?: + | { + label: string; + type?: ('page' | 'custom' | 'submenu') | null; + page?: (number | null) | Page; + url?: string | null; + openInNewTab?: boolean | null; + submenu?: + | { + label: string; + linkType?: ('page' | 'custom') | null; + page?: (number | null) | Page; + url?: string | null; + id?: string | null; + }[] + | null; + id?: string | null; + }[] + | null; + footerMenu?: + | { + label: string; + linkType?: ('page' | 'custom') | null; + page?: (number | null) | Page; + url?: string | null; + id?: string | null; + }[] + | null; + updatedAt: string; + createdAt: string; +} +/** + * Eingegangene Formular-Einsendungen + * + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "form-submissions". + */ +export interface FormSubmission { + id: number; + form: number | Form; + submissionData?: + | { + field: string; + value: string; + id?: string | null; + }[] + | null; + updatedAt: string; + createdAt: string; +} +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "redirects". + */ +export interface Redirect { + id: number; + from: string; + to?: { + type?: ('reference' | 'custom') | null; + reference?: { + relationTo: 'pages'; + value: number | Page; + } | null; + url?: string | null; + }; + updatedAt: string; + createdAt: string; +} +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "payload-kv". + */ +export interface PayloadKv { + id: number; + key: string; + data: + | { + [k: string]: unknown; + } + | unknown[] + | string + | number + | boolean + | null; +} +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "payload-locked-documents". + */ +export interface PayloadLockedDocument { + id: number; + document?: + | ({ + relationTo: 'users'; + value: number | User; + } | null) + | ({ + relationTo: 'media'; + value: number | Media; + } | null) + | ({ + relationTo: 'tenants'; + value: number | Tenant; + } | null) + | ({ + relationTo: 'pages'; + value: number | Page; + } | null) + | ({ + relationTo: 'posts'; + value: number | Post; + } | null) + | ({ + relationTo: 'categories'; + value: number | Category; + } | null) + | ({ + relationTo: 'social-links'; + value: number | SocialLink; + } | null) + | ({ + relationTo: 'testimonials'; + value: number | Testimonial; + } | null) + | ({ + relationTo: 'faqs'; + value: number | Faq; + } | null) + | ({ + relationTo: 'team'; + value: number | Team; + } | null) + | ({ + relationTo: 'service-categories'; + value: number | ServiceCategory; + } | null) + | ({ + relationTo: 'services'; + value: number | Service; + } | null) + | ({ + relationTo: 'newsletter-subscribers'; + value: number | NewsletterSubscriber; + } | null) + | ({ + relationTo: 'portfolio-categories'; + value: number | PortfolioCategory; + } | null) + | ({ + relationTo: 'portfolios'; + value: number | Portfolio; + } | null) + | ({ + relationTo: 'video-categories'; + value: number | VideoCategory; + } | null) + | ({ + relationTo: 'videos'; + value: number | Video; + } | null) + | ({ + relationTo: 'product-categories'; + value: number | ProductCategory; + } | null) + | ({ + relationTo: 'products'; + value: number | Product; + } | null) + | ({ + relationTo: 'timelines'; + value: number | Timeline; + } | null) + | ({ + relationTo: 'workflows'; + value: number | Workflow; + } | null) + | ({ + relationTo: 'tags'; + value: number | Tag; + } | null) + | ({ + relationTo: 'authors'; + value: number | Author; + } | null) + | ({ + relationTo: 'locations'; + value: number | Location; + } | null) + | ({ + relationTo: 'partners'; + value: number | Partner; + } | null) + | ({ + relationTo: 'jobs'; + value: number | Job; + } | null) + | ({ + relationTo: 'downloads'; + value: number | Download; + } | null) + | ({ + relationTo: 'events'; + value: number | Event; + } | null) + | ({ + relationTo: 'bookings'; + value: number | Booking; + } | null) + | ({ + relationTo: 'certifications'; + value: number | Certification; + } | null) + | ({ + relationTo: 'projects'; + value: number | Project; + } | null) + | ({ + relationTo: 'favorites'; + value: number | Favorite; + } | null) + | ({ + relationTo: 'series'; + value: number | Series; + } | null) + | ({ + relationTo: 'youtube-channels'; + value: number | YoutubeChannel; + } | null) + | ({ + relationTo: 'youtube-content'; + value: number | YoutubeContent; + } | null) + | ({ + relationTo: 'yt-tasks'; + value: number | YtTask; + } | null) + | ({ + relationTo: 'yt-notifications'; + value: number | YtNotification; + } | null) + | ({ + relationTo: 'yt-batches'; + value: number | YtBatch; + } | null) + | ({ + relationTo: 'yt-monthly-goals'; + value: number | YtMonthlyGoal; + } | null) + | ({ + relationTo: 'yt-script-templates'; + value: number | YtScriptTemplate; + } | null) + | ({ + relationTo: 'yt-checklist-templates'; + value: number | YtChecklistTemplate; + } | null) + | ({ + relationTo: 'yt-series'; + value: number | YtSery; + } | null) + | ({ + relationTo: 'social-platforms'; + value: number | SocialPlatform; + } | null) + | ({ + relationTo: 'social-accounts'; + value: number | SocialAccount; + } | null) + | ({ + relationTo: 'community-interactions'; + value: number | CommunityInteraction; + } | null) + | ({ + relationTo: 'community-templates'; + value: number | CommunityTemplate; + } | null) + | ({ + relationTo: 'community-rules'; + value: number | CommunityRule; + } | null) + | ({ + relationTo: 'report-schedules'; + value: number | ReportSchedule; + } | null) + | ({ + relationTo: 'cookie-configurations'; + value: number | CookieConfiguration; + } | null) + | ({ + relationTo: 'cookie-inventory'; + value: number | CookieInventory; + } | null) + | ({ + relationTo: 'consent-logs'; + value: number | ConsentLog; + } | null) + | ({ + relationTo: 'privacy-policy-settings'; + value: number | PrivacyPolicySetting; + } | null) + | ({ + relationTo: 'email-logs'; + value: number | EmailLog; + } | null) + | ({ + relationTo: 'audit-logs'; + value: number | AuditLog; + } | null) + | ({ + relationTo: 'monitoring-snapshots'; + value: number | MonitoringSnapshot; + } | null) + | ({ + relationTo: 'monitoring-logs'; + value: number | MonitoringLog; + } | null) + | ({ + relationTo: 'monitoring-alert-rules'; + value: number | MonitoringAlertRule; + } | null) + | ({ + relationTo: 'monitoring-alert-history'; + value: number | MonitoringAlertHistory; + } | null) + | ({ + relationTo: 'site-settings'; + value: number | SiteSetting; + } | null) + | ({ + relationTo: 'navigations'; + value: number | Navigation; + } | null) + | ({ + relationTo: 'forms'; + value: number | Form; + } | null) + | ({ + relationTo: 'form-submissions'; + value: number | FormSubmission; + } | null) + | ({ + relationTo: 'redirects'; + value: number | Redirect; + } | null); + globalSlug?: string | null; + user: { + relationTo: 'users'; + value: number | User; + }; + updatedAt: string; + createdAt: string; +} +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "payload-preferences". + */ +export interface PayloadPreference { + id: number; + user: { + relationTo: 'users'; + value: number | User; + }; + key?: string | null; + value?: + | { + [k: string]: unknown; + } + | unknown[] + | string + | number + | boolean + | null; + updatedAt: string; + createdAt: string; +} +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "payload-migrations". + */ +export interface PayloadMigration { + id: number; + name?: string | null; + batch?: number | null; + updatedAt: string; + createdAt: string; +} +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "users_select". + */ +export interface UsersSelect { + isSuperAdmin?: T; + youtubeRole?: T; + youtubeChannels?: T; + communityRole?: T; + tenants?: + | T + | { + tenant?: T; + id?: T; + }; + updatedAt?: T; + createdAt?: T; + email?: T; + resetPasswordToken?: T; + resetPasswordExpiration?: T; + salt?: T; + hash?: T; + loginAttempts?: T; + lockUntil?: T; + sessions?: + | T + | { + id?: T; + createdAt?: T; + expiresAt?: T; + }; +} +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "media_select". + */ +export interface MediaSelect { + tenant?: T; + alt?: T; + caption?: T; + credit?: T; + tags?: T; + updatedAt?: T; + createdAt?: T; + url?: T; + thumbnailURL?: T; + filename?: T; + mimeType?: T; + filesize?: T; + width?: T; + height?: T; + focalX?: T; + focalY?: T; + sizes?: + | T + | { + thumbnail?: + | T + | { + url?: T; + width?: T; + height?: T; + mimeType?: T; + filesize?: T; + filename?: T; + }; + small?: + | T + | { + url?: T; + width?: T; + height?: T; + mimeType?: T; + filesize?: T; + filename?: T; + }; + medium?: + | T + | { + url?: T; + width?: T; + height?: T; + mimeType?: T; + filesize?: T; + filename?: T; + }; + large?: + | T + | { + url?: T; + width?: T; + height?: T; + mimeType?: T; + filesize?: T; + filename?: T; + }; + xlarge?: + | T + | { + url?: T; + width?: T; + height?: T; + mimeType?: T; + filesize?: T; + filename?: T; + }; + '2k'?: + | T + | { + url?: T; + width?: T; + height?: T; + mimeType?: T; + filesize?: T; + filename?: T; + }; + og?: + | T + | { + url?: T; + width?: T; + height?: T; + mimeType?: T; + filesize?: T; + filename?: T; + }; + medium_avif?: + | T + | { + url?: T; + width?: T; + height?: T; + mimeType?: T; + filesize?: T; + filename?: T; + }; + large_avif?: + | T + | { + url?: T; + width?: T; + height?: T; + mimeType?: T; + filesize?: T; + filename?: T; + }; + xlarge_avif?: + | T + | { + url?: T; + width?: T; + height?: T; + mimeType?: T; + filesize?: T; + filename?: T; + }; + }; +} +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "tenants_select". + */ +export interface TenantsSelect { + name?: T; + slug?: T; + domains?: + | T + | { + domain?: T; + id?: T; + }; + email?: + | T + | { + fromAddress?: T; + fromName?: T; + replyTo?: T; + useCustomSmtp?: T; + smtp?: + | T + | { + host?: T; + port?: T; + secure?: T; + user?: T; + pass?: T; + }; + }; + updatedAt?: T; + createdAt?: T; +} +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "pages_select". + */ +export interface PagesSelect { + tenant?: T; + title?: T; + slug?: T; + layout?: + | T + | { + 'hero-block'?: + | T + | { + backgroundImage?: T; + headline?: T; + subline?: T; + alignment?: T; + overlay?: T; + cta?: + | T + | { + text?: T; + link?: T; + style?: T; + }; + id?: T; + blockName?: T; + }; + 'hero-slider-block'?: + | T + | { + slides?: + | T + | { + backgroundImage?: T; + mobileBackgroundImage?: T; + headline?: T; + subline?: T; + textAlignment?: T; + verticalPosition?: T; + overlay?: + | T + | { + enabled?: T; + color?: T; + opacity?: T; + }; + primaryCta?: + | T + | { + enabled?: T; + text?: T; + link?: T; + style?: T; + openInNewTab?: T; + }; + secondaryCta?: + | T + | { + enabled?: T; + text?: T; + link?: T; + style?: T; + openInNewTab?: T; + }; + textColor?: T; + id?: T; + }; + settings?: + | T + | { + animation?: T; + animationDuration?: T; + autoplay?: + | T + | { + enabled?: T; + interval?: T; + pauseOnHover?: T; + pauseOnInteraction?: T; + }; + loop?: T; + }; + navigation?: + | T + | { + arrows?: + | T + | { + enabled?: T; + style?: T; + position?: T; + hideOnMobile?: T; + }; + dots?: + | T + | { + enabled?: T; + style?: T; + position?: T; + color?: T; + }; + swipe?: T; + keyboard?: T; + }; + layout?: + | T + | { + height?: T; + mobileHeight?: T; + contentWidth?: T; + fullWidth?: T; + }; + accessibility?: + | T + | { + ariaLabel?: T; + reducedMotion?: T; + }; + id?: T; + blockName?: T; + }; + 'image-slider-block'?: + | T + | { + title?: T; + description?: T; + images?: + | T + | { + image?: T; + caption?: T; + alt?: T; + link?: T; + id?: T; + }; + layout?: T; + grid?: + | T + | { + cols?: T; + gap?: T; + aspectRatio?: T; + }; + slider?: + | T + | { + effect?: T; + speed?: T; + perView?: T; + gap?: T; + auto?: T; + delay?: T; + pauseHover?: T; + loop?: T; + centered?: T; + }; + nav?: + | T + | { + arrows?: T; + arrowStyle?: T; + dots?: T; + dotStyle?: T; + counter?: T; + swipe?: T; + keys?: T; + }; + lightbox?: + | T + | { + enabled?: T; + zoom?: T; + download?: T; + share?: T; + captions?: T; + thumbs?: T; + bg?: T; + }; + style?: + | T + | { + height?: T; + imgFit?: T; + rounded?: T; + shadow?: T; + border?: T; + hoverEffect?: T; + captionPos?: T; + bg?: T; + padding?: T; + }; + a11y?: + | T + | { + label?: T; + reducedMotion?: T; + }; + id?: T; + blockName?: T; + }; + 'text-block'?: + | T + | { + content?: T; + width?: T; + id?: T; + blockName?: T; + }; + 'image-text-block'?: + | T + | { + image?: T; + imagePosition?: T; + headline?: T; + content?: T; + cta?: + | T + | { + text?: T; + link?: T; + }; + id?: T; + blockName?: T; + }; + 'card-grid-block'?: + | T + | { + headline?: T; + cards?: + | T + | { + mediaType?: T; + image?: T; + icon?: T; + iconPosition?: T; + title?: T; + description?: T; + link?: T; + linkText?: T; + id?: T; + }; + columns?: T; + id?: T; + blockName?: T; + }; + 'quote-block'?: + | T + | { + quote?: T; + author?: T; + role?: T; + image?: T; + style?: T; + id?: T; + blockName?: T; + }; + 'cta-block'?: + | T + | { + headline?: T; + description?: T; + buttons?: + | T + | { + text?: T; + link?: T; + style?: T; + id?: T; + }; + backgroundColor?: T; + id?: T; + blockName?: T; + }; + 'contact-form-block'?: + | T + | { + form?: T; + headline?: T; + description?: T; + successMessage?: T; + showContactInfo?: T; + showPhone?: T; + showAddress?: T; + showSocials?: T; + id?: T; + blockName?: T; + }; + 'timeline-block'?: + | T + | { + title?: T; + subtitle?: T; + layout?: T; + showConnector?: T; + markerStyle?: T; + items?: + | T + | { + year?: T; + title?: T; + description?: T; + icon?: T; + image?: T; + link?: + | T + | { + label?: T; + href?: T; + }; + id?: T; + }; + backgroundColor?: T; + id?: T; + blockName?: T; + }; + 'divider-block'?: + | T + | { + style?: T; + spacing?: T; + id?: T; + blockName?: T; + }; + 'video-block'?: + | T + | { + sourceType?: T; + videoFromLibrary?: T; + videoUrl?: T; + videoFile?: T; + thumbnail?: T; + caption?: T; + aspectRatio?: T; + size?: T; + alignment?: T; + playback?: + | T + | { + autoplay?: T; + muted?: T; + loop?: T; + controls?: T; + playsinline?: T; + startTime?: T; + }; + embedOptions?: + | T + | { + showRelated?: T; + privacyMode?: T; + }; + style?: + | T + | { + rounded?: T; + shadow?: T; + border?: T; + }; + id?: T; + blockName?: T; + }; + 'posts-list-block'?: + | T + | { + title?: T; + subtitle?: T; + postType?: T; + layout?: T; + columns?: T; + limit?: T; + showFeaturedOnly?: T; + filterByCategory?: T; + showExcerpt?: T; + showDate?: T; + showAuthor?: T; + showCategory?: T; + showPagination?: T; + showReadMore?: T; + readMoreLabel?: T; + readMoreLink?: T; + backgroundColor?: T; + id?: T; + blockName?: T; + }; + 'testimonials-block'?: + | T + | { + title?: T; + subtitle?: T; + layout?: T; + columns?: T; + displayMode?: T; + selectedTestimonials?: T; + limit?: 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; + }; + 'newsletter-block'?: + | T + | { + title?: T; + subtitle?: T; + layout?: T; + image?: T; + imagePosition?: T; + collectName?: T; + showInterests?: T; + availableInterests?: T; + buttonText?: T; + placeholderEmail?: T; + successMessage?: T; + errorMessage?: T; + privacyText?: T; + privacyLink?: T; + source?: T; + backgroundColor?: T; + id?: T; + blockName?: T; + }; + 'process-steps-block'?: + | T + | { + title?: T; + subtitle?: T; + layout?: T; + showNumbers?: T; + showIcons?: T; + steps?: + | T + | { + title?: T; + description?: T; + icon?: T; + image?: T; + id?: T; + }; + cta?: + | T + | { + show?: T; + label?: T; + href?: T; + variant?: T; + }; + backgroundColor?: T; + id?: T; + blockName?: T; + }; + 'faq-block'?: + | T + | { + title?: T; + subtitle?: T; + sourceMode?: T; + displayMode?: T; + category?: T; + selectedFAQs?: T; + limit?: T; + inlineFAQs?: + | T + | { + question?: T; + answer?: T; + answerPlainText?: T; + id?: T; + }; + layout?: T; + columns?: T; + expandFirst?: T; + allowMultipleOpen?: T; + showCategory?: T; + showIcon?: T; + groupByCategory?: T; + enableSchemaOrg?: T; + backgroundColor?: T; + showContactCTA?: T; + contactCTAText?: T; + contactCTALink?: T; + contactCTAButtonText?: T; + id?: T; + blockName?: T; + }; + 'team-block'?: + | T + | { + title?: T; + subtitle?: T; + introduction?: T; + displayMode?: T; + department?: T; + selectedMembers?: T; + limit?: T; + layout?: T; + columns?: T; + showRole?: T; + showDepartment?: T; + showBio?: T; + showContact?: T; + showSocialLinks?: T; + showQualifications?: T; + showSpecializations?: T; + showLanguages?: T; + groupByDepartment?: T; + autoplay?: T; + autoplaySpeed?: T; + enableDetailView?: T; + imageStyle?: T; + backgroundColor?: T; + showCTA?: T; + ctaText?: T; + ctaLink?: T; + id?: T; + blockName?: T; + }; + 'services-block'?: + | T + | { + title?: T; + subtitle?: T; + introduction?: T; + displayMode?: T; + category?: T; + selectedServices?: T; + limit?: T; + layout?: T; + columns?: T; + featuredCount?: T; + tabsStyle?: T; + showAllTab?: T; + expandFirst?: T; + allowMultipleOpen?: T; + autoplay?: T; + autoplaySpeed?: T; + slidesPerView?: T; + showImage?: T; + showIcon?: T; + showDescription?: T; + showCategory?: T; + showPricing?: T; + showFeatures?: T; + featuresLimit?: T; + showCTA?: T; + showNewBadge?: T; + groupByCategory?: T; + linkToDetail?: T; + detailLinkText?: T; + servicesBasePath?: T; + cardStyle?: T; + backgroundColor?: T; + showSectionCTA?: T; + sectionCTAText?: T; + sectionCTALink?: T; + id?: T; + blockName?: T; + }; + 'author-bio-block'?: + | T + | { + source?: T; + authors?: T; + showCoAuthors?: T; + layout?: T; + show?: + | T + | { + avatar?: T; + name?: T; + title?: T; + bio?: T; + social?: T; + email?: T; + website?: T; + postCount?: T; + }; + style?: + | T + | { + avatarSize?: T; + avatarShape?: T; + bg?: T; + border?: T; + shadow?: T; + divider?: T; + }; + label?: T; + linkToProfile?: T; + id?: T; + blockName?: T; + }; + 'related-posts-block'?: + | T + | { + title?: T; + source?: T; + posts?: T; + category?: T; + tag?: T; + limit?: T; + excludeCurrent?: T; + layout?: T; + cols?: T; + show?: + | T + | { + image?: T; + date?: T; + author?: T; + category?: T; + excerpt?: T; + readingTime?: T; + tags?: T; + }; + style?: + | T + | { + imgRatio?: T; + rounded?: T; + shadow?: T; + hover?: T; + bg?: T; + gap?: T; + }; + showAllLink?: T; + allLinkText?: T; + allLinkUrl?: T; + id?: T; + blockName?: T; + }; + 'share-buttons-block'?: + | T + | { + label?: T; + platforms?: + | T + | { + facebook?: T; + twitter?: T; + linkedin?: T; + xing?: T; + whatsapp?: T; + telegram?: T; + email?: T; + copy?: T; + print?: T; + pinterest?: T; + reddit?: T; + }; + layout?: T; + align?: T; + floatSide?: T; + style?: + | T + | { + variant?: T; + size?: T; + shape?: T; + colorScheme?: T; + gap?: T; + showLabel?: T; + showCount?: T; + }; + behavior?: + | T + | { + openInPopup?: T; + useNativeShare?: T; + copyFeedback?: T; + }; + content?: + | T + | { + customTitle?: T; + customDescription?: T; + hashtags?: T; + via?: T; + }; + id?: T; + blockName?: T; + }; + 'toc-block'?: + | T + | { + title?: T; + levels?: + | T + | { + h2?: T; + h3?: T; + h4?: T; + h5?: T; + h6?: T; + }; + layout?: T; + sidebarPos?: T; + behavior?: + | T + | { + smoothScroll?: T; + highlightActive?: T; + scrollOffset?: T; + collapsible?: T; + startCollapsed?: T; + showProgress?: T; + progressStyle?: T; + }; + style?: + | T + | { + bg?: T; + border?: T; + borderSide?: T; + rounded?: T; + shadow?: T; + indent?: T; + showIcon?: T; + fontSize?: T; + lineHeight?: T; + }; + minItems?: T; + maxItems?: T; + a11yLabel?: T; + id?: T; + blockName?: T; + }; + 'team-filter-block'?: + | T + | { + title?: T; + subtitle?: T; + filters?: + | T + | { + showSearch?: T; + searchPlaceholder?: T; + showDepartment?: T; + showSpecialization?: T; + showLanguage?: T; + showHierarchy?: T; + filterLayout?: T; + filterStyle?: T; + showResultCount?: T; + showResetButton?: T; + }; + display?: + | T + | { + layout?: T; + columns?: T; + initialLimit?: T; + loadMore?: T; + loadMoreText?: T; + }; + card?: + | T + | { + showImage?: T; + imageStyle?: T; + showRole?: T; + showDepartment?: T; + showBio?: T; + showContact?: T; + showSocial?: T; + showSpecializations?: T; + showLanguages?: T; + showVCard?: T; + linkToProfile?: T; + profileBasePath?: T; + enableModal?: T; + }; + style?: + | T + | { + bg?: T; + cardBg?: T; + cardShadow?: T; + cardHover?: T; + gap?: T; + animation?: T; + }; + emptyState?: + | T + | { + title?: T; + message?: T; + showResetButton?: T; + }; + id?: T; + blockName?: T; + }; + 'org-chart-block'?: + | T + | { + title?: T; + subtitle?: T; + source?: T; + rootMember?: T; + department?: T; + selectedMembers?: T; + maxDepth?: T; + layout?: T; + direction?: T; + node?: + | T + | { + style?: T; + showImage?: T; + imageSize?: T; + imageShape?: T; + showName?: T; + showRole?: T; + showDepartment?: T; + showContact?: T; + clickAction?: T; + profileBasePath?: T; + }; + connectors?: + | T + | { + style?: T; + color?: T; + thickness?: T; + animated?: T; + }; + levels?: + | T + | { + colorByLevel?: T; + sizeByLevel?: T; + collapsible?: T; + initiallyExpanded?: T; + }; + interaction?: + | T + | { + zoomable?: T; + pannable?: T; + minimap?: T; + search?: T; + highlight?: T; + fullscreen?: T; + export?: T; + }; + style?: + | T + | { + bg?: T; + nodeBg?: T; + nodeShadow?: T; + nodeBorder?: T; + spacing?: T; + minHeight?: T; + }; + showLegend?: T; + a11yLabel?: T; + id?: T; + blockName?: T; + }; + 'locations-block'?: + | T + | { + title?: T; + subtitle?: T; + source?: T; + locationType?: T; + selectedLocations?: T; + layout?: T; + mapPosition?: T; + columns?: T; + map?: + | T + | { + provider?: T; + style?: T; + height?: T; + defaultZoom?: T; + fitBounds?: T; + markerStyle?: T; + markerColor?: T; + clustering?: T; + controls?: + | T + | { + zoom?: T; + fullscreen?: T; + scrollZoom?: T; + dragging?: T; + }; + }; + show?: + | T + | { + image?: T; + type?: T; + address?: T; + phone?: T; + email?: T; + hours?: T; + directions?: T; + services?: T; + team?: T; + }; + actions?: + | T + | { + showDirectionsLink?: T; + showCallButton?: T; + showEmailButton?: T; + showDetailLink?: T; + detailBasePath?: T; + }; + style?: + | T + | { + bg?: T; + cardStyle?: T; + gap?: T; + }; + id?: T; + blockName?: T; + }; + 'logo-grid-block'?: + | T + | { + title?: T; + subtitle?: T; + source?: T; + partnerType?: T; + selectedPartners?: T; + featuredOnly?: T; + limit?: T; + logos?: + | T + | { + logo?: T; + name?: T; + link?: T; + id?: T; + }; + layout?: T; + columns?: T; + slider?: + | T + | { + perView?: T; + autoplay?: T; + speed?: T; + pauseOnHover?: T; + showArrows?: T; + showDots?: T; + }; + logoStyle?: + | T + | { + size?: T; + maxHeight?: T; + grayscale?: T; + colorOnHover?: T; + opacity?: T; + hoverEffect?: T; + }; + behavior?: + | T + | { + linkToWebsite?: T; + openInNewTab?: T; + showTooltip?: T; + showName?: T; + }; + style?: + | T + | { + bg?: T; + logoBg?: T; + logoPadding?: T; + gap?: T; + alignment?: T; + divider?: T; + }; + showCTA?: T; + ctaText?: T; + ctaLink?: T; + id?: T; + blockName?: T; + }; + 'stats-block'?: + | T + | { + title?: T; + subtitle?: T; + stats?: + | T + | { + value?: T; + numericValue?: T; + prefix?: T; + suffix?: T; + label?: T; + description?: T; + icon?: T; + color?: T; + id?: T; + }; + layout?: T; + columns?: T; + alignment?: T; + animation?: + | T + | { + countUp?: T; + duration?: T; + trigger?: T; + stagger?: T; + }; + style?: + | T + | { + bg?: T; + bgImage?: T; + bgOverlay?: T; + textColor?: T; + valueSize?: T; + valueWeight?: T; + showIcon?: T; + iconPosition?: T; + dividers?: T; + cardBorder?: T; + cardShadow?: T; + gap?: T; + padding?: T; + }; + id?: T; + blockName?: T; + }; + 'jobs-block'?: + | T + | { + title?: T; + subtitle?: T; + introduction?: T; + source?: T; + category?: T; + department?: T; + locationFilter?: T; + selectedJobs?: T; + limit?: T; + filters?: + | T + | { + showSearch?: T; + showCategoryFilter?: T; + showTypeFilter?: T; + showLocationFilter?: T; + showWorkModelFilter?: T; + filterLayout?: T; + }; + layout?: T; + columns?: T; + show?: + | T + | { + image?: T; + department?: T; + type?: T; + location?: T; + workModel?: T; + salary?: T; + summary?: T; + deadline?: T; + publishDate?: T; + badges?: T; + }; + badges?: + | T + | { + newDays?: T; + showUrgent?: T; + showFeatured?: T; + }; + pagination?: + | T + | { + type?: T; + perPage?: T; + }; + style?: + | T + | { + bg?: T; + cardStyle?: T; + hoverEffect?: T; + gap?: T; + }; + emptyState?: + | T + | { + title?: T; + message?: T; + showInitiativeLink?: T; + initiativeText?: T; + initiativeUrl?: T; + }; + showAllJobsLink?: T; + allJobsText?: T; + allJobsUrl?: T; + id?: T; + blockName?: T; + }; + 'downloads-block'?: + | T + | { + title?: T; + subtitle?: T; + introduction?: T; + source?: T; + category?: T; + filterTags?: T; + relatedService?: T; + relatedProduct?: T; + selectedDownloads?: T; + limit?: T; + filters?: + | T + | { + showSearch?: T; + showCategoryFilter?: T; + showFileTypeFilter?: T; + filterLayout?: T; + }; + layout?: T; + columns?: T; + show?: + | T + | { + thumbnail?: T; + description?: T; + fileSize?: T; + fileType?: T; + category?: T; + downloadCount?: T; + version?: T; + lastUpdated?: T; + }; + downloadBehavior?: + | T + | { + directDownload?: T; + trackDownloads?: T; + openInNewTab?: T; + }; + fileIcons?: + | T + | { + showFileTypeIcon?: T; + iconStyle?: T; + }; + sortBy?: T; + groupBy?: T; + pagination?: + | T + | { + type?: T; + perPage?: T; + }; + style?: + | T + | { + bg?: T; + cardStyle?: T; + hoverEffect?: T; + gap?: T; + }; + emptyState?: + | T + | { + title?: T; + message?: T; + }; + showAllDownloadsLink?: T; + allDownloadsText?: T; + allDownloadsUrl?: T; + id?: T; + blockName?: T; + }; + 'map-block'?: + | T + | { + title?: T; + subtitle?: T; + source?: T; + locationType?: T; + selectedLocations?: T; + markers?: + | T + | { + name?: T; + address?: T; + lat?: T; + lng?: T; + markerType?: T; + customIcon?: T; + popupContent?: T; + link?: T; + id?: T; + }; + singleAddress?: + | T + | { + name?: T; + street?: T; + zip?: T; + city?: T; + country?: T; + lat?: T; + lng?: T; + }; + provider?: T; + mapStyle?: T; + mapSettings?: + | T + | { + height?: T; + zoom?: T; + autoFit?: T; + centerLat?: T; + centerLng?: T; + }; + interaction?: + | T + | { + scrollZoom?: T; + dragging?: T; + zoomControl?: T; + fullscreenControl?: T; + locateControl?: T; + }; + markerStyle?: + | T + | { + type?: T; + color?: T; + size?: T; + clustering?: T; + clusterRadius?: T; + }; + popup?: + | T + | { + show?: T; + trigger?: T; + showAddress?: T; + showDirectionsLink?: T; + showPhone?: T; + showOpeningHours?: T; + showDetailLink?: T; + }; + sidebar?: + | T + | { + show?: T; + position?: T; + width?: T; + searchable?: T; + clickToCenter?: T; + }; + style?: + | T + | { + rounded?: T; + shadow?: T; + border?: T; + padding?: T; + }; + fallback?: + | T + | { + showStaticImage?: T; + staticImage?: T; + noJsMessage?: T; + }; + id?: T; + blockName?: T; + }; + events?: + | T + | { + title?: T; + subtitle?: T; + sourceMode?: T; + filterMode?: T; + eventType?: T; + category?: T; + selectedEvents?: T; + limit?: T; + layout?: T; + columns?: T; + showImage?: T; + showExcerpt?: T; + showDate?: T; + showTime?: T; + showLocation?: T; + showPrice?: T; + showEventType?: T; + showRegistrationButton?: T; + registrationButtonText?: T; + calendarOptions?: + | T + | { + defaultView?: T; + showNavigation?: T; + showViewToggle?: T; + }; + groupBy?: T; + sortOrder?: T; + showAllLink?: T; + allEventsLink?: T; + allEventsText?: T; + emptyMessage?: T; + backgroundColor?: T; + cardStyle?: T; + id?: T; + blockName?: T; + }; + pricing?: + | T + | { + title?: T; + subtitle?: T; + description?: T; + pricingType?: T; + currency?: T; + showCurrencyBefore?: T; + toggleOptions?: + | T + | { + monthlyLabel?: T; + yearlyLabel?: T; + yearlyDiscount?: T; + defaultToYearly?: T; + }; + plans?: + | T + | { + name?: T; + subtitle?: T; + description?: T; + price?: T; + priceMonthly?: T; + priceYearly?: T; + priceSuffix?: T; + originalPrice?: T; + priceNote?: T; + customPriceText?: T; + features?: + | T + | { + text?: T; + included?: T; + highlight?: T; + tooltip?: T; + id?: T; + }; + ctaText?: T; + ctaLink?: T; + ctaStyle?: T; + isPopular?: T; + popularLabel?: T; + isRecommended?: T; + recommendedLabel?: T; + accentColor?: T; + icon?: T; + id?: T; + }; + showComparison?: T; + comparisonFeatures?: + | T + | { + category?: T; + feature?: T; + tooltip?: T; + values?: + | T + | { + planIndex?: T; + value?: T; + id?: T; + }; + id?: T; + }; + layout?: T; + alignment?: T; + highlightPopular?: T; + guarantee?: + | T + | { + show?: T; + text?: T; + icon?: T; + }; + showFAQ?: T; + faqTitle?: T; + faqItems?: + | T + | { + question?: T; + answer?: T; + id?: T; + }; + backgroundColor?: T; + cardStyle?: T; + id?: T; + blockName?: T; + }; + tabs?: + | T + | { + title?: T; + subtitle?: T; + tabs?: + | T + | { + label?: T; + icon?: T; + customIcon?: T; + badge?: T; + contentType?: T; + content?: T; + imgTxt?: + | T + | { + img?: T; + imgPos?: T; + text?: T; + }; + features?: + | T + | { + title?: T; + description?: T; + icon?: T; + id?: T; + }; + code?: + | T + | { + language?: T; + code?: T; + showLineNumbers?: T; + }; + embed?: + | T + | { + type?: T; + url?: T; + aspectRatio?: T; + }; + id?: T; + }; + tabStyle?: T; + tabPosition?: T; + tabAlignment?: T; + defaultTab?: T; + allowKeyboardNavigation?: T; + animated?: T; + lazy?: T; + mobileStyle?: T; + backgroundColor?: T; + contentBackground?: T; + showBorder?: T; + fullWidth?: T; + id?: T; + blockName?: T; + }; + accordion?: + | T + | { + title?: T; + subtitle?: T; + description?: T; + items?: + | T + | { + title?: T; + subtitle?: T; + icon?: T; + customIcon?: T; + contentType?: T; + content?: T; + imgTxt?: + | T + | { + img?: T; + imgPos?: T; + text?: T; + }; + listItems?: + | T + | { + text?: T; + icon?: T; + id?: T; + }; + tableData?: + | T + | { + headers?: + | T + | { + text?: T; + id?: T; + }; + rows?: + | T + | { + cells?: + | T + | { + text?: T; + id?: T; + }; + id?: T; + }; + }; + codeContent?: + | T + | { + language?: T; + code?: T; + }; + badge?: T; + badgeColor?: T; + defaultOpen?: T; + disabled?: T; + id?: T; + }; + behavior?: T; + expandFirst?: T; + animated?: T; + style?: T; + iconPosition?: T; + iconStyle?: T; + layout?: T; + titleSize?: T; + backgroundColor?: T; + headerBackground?: T; + enableSchemaOrg?: T; + id?: T; + blockName?: T; + }; + comparison?: + | T + | { + title?: T; + subtitle?: T; + description?: T; + comparisonType?: T; + tbl?: + | T + | { + columns?: + | T + | { + name?: T; + subtitle?: T; + image?: T; + price?: T; + isHighlighted?: T; + highlightLabel?: T; + ctaText?: T; + ctaLink?: T; + id?: T; + }; + rows?: + | T + | { + feature?: T; + category?: T; + tooltip?: T; + values?: + | T + | { + columnIndex?: T; + valueType?: T; + textValue?: T; + booleanValue?: T; + partialNote?: T; + id?: T; + }; + id?: T; + }; + }; + crd?: + | T + | { + items?: + | T + | { + title?: T; + subtitle?: T; + image?: T; + description?: T; + features?: + | T + | { + text?: T; + included?: T; + id?: T; + }; + price?: T; + ctaText?: T; + ctaLink?: T; + isHighlighted?: T; + accentColor?: T; + id?: T; + }; + }; + beforeAfter?: + | T + | { + beforeLabel?: T; + afterLabel?: T; + items?: + | T + | { + title?: T; + beforeImage?: T; + afterImage?: T; + beforeText?: T; + afterText?: T; + id?: T; + }; + displayStyle?: T; + }; + prosCons?: + | T + | { + prosLabel?: T; + consLabel?: T; + items?: + | T + | { + title?: T; + image?: T; + pros?: + | T + | { + text?: T; + id?: T; + }; + cons?: + | T + | { + text?: T; + id?: T; + }; + verdict?: T; + rating?: T; + id?: T; + }; + }; + stickyHeader?: T; + showCategories?: T; + collapsibleCategories?: T; + showRowDividers?: T; + highlightDifferences?: T; + mobileView?: T; + symbols?: + | T + | { + checkSymbol?: T; + crossSymbol?: T; + partialSymbol?: T; + }; + backgroundColor?: T; + tableStyle?: T; + checkColor?: T; + crossColor?: T; + id?: T; + blockName?: T; + }; + 'before-after'?: + | T + | { + title?: T; + subtitle?: T; + description?: T; + comparisons?: + | T + | { + title?: T; + beforeImage?: T; + afterImage?: T; + beforeLabel?: T; + afterLabel?: T; + description?: T; + category?: T; + tags?: T; + metadata?: + | T + | { + client?: T; + date?: T; + tools?: T; + duration?: T; + }; + showMetadata?: T; + id?: T; + }; + displayStyle?: T; + sliderOrientation?: T; + sliderStartPosition?: T; + layout?: T; + aspectRatio?: T; + sliderHandle?: + | T + | { + style?: T; + color?: T; + size?: T; + showLine?: T; + }; + showLabels?: T; + labelPosition?: T; + labelStyle?: T; + showFilter?: T; + animation?: + | T + | { + enableAnimation?: T; + autoPlay?: T; + autoPlaySpeed?: T; + scrollTrigger?: T; + }; + interactivity?: + | T + | { + enableZoom?: T; + enableFullscreen?: T; + enableSwipe?: T; + enableKeyboard?: T; + }; + cta?: + | T + | { + showCta?: T; + ctaText?: T; + ctaLink?: T; + ctaStyle?: T; + }; + backgroundColor?: T; + borderRadius?: T; + shadow?: T; + spacing?: T; + id?: T; + blockName?: T; + }; + 'favorites-block'?: + | T + | { + title?: T; + subtitle?: T; + category?: T; + showFeaturedOnly?: T; + limit?: T; + layout?: T; + columns?: T; + showPrice?: T; + showBadge?: T; + showDescription?: T; + showCategory?: T; + backgroundColor?: T; + cta?: + | T + | { + showCta?: T; + ctaText?: T; + ctaUrl?: T; + }; + id?: T; + blockName?: T; + }; + 'series-block'?: + | T + | { + title?: T; + subtitle?: T; + layout?: T; + columns?: T; + showDescription?: T; + showLogo?: T; + showTagline?: T; + useBrandColors?: T; + limit?: T; + backgroundColor?: T; + cta?: + | T + | { + showCta?: T; + ctaText?: T; + ctaUrl?: T; + }; + id?: T; + blockName?: T; + }; + 'series-detail-block'?: + | T + | { + series?: T; + showHero?: T; + showDescription?: T; + showBrandColors?: T; + showRelatedPosts?: T; + relatedPostsLimit?: T; + relatedPostsTitle?: T; + showYoutubePlaylist?: T; + layout?: T; + hero?: + | T + | { + height?: T; + overlay?: T; + textAlign?: T; + }; + id?: T; + blockName?: T; + }; + 'video-embed-block'?: + | T + | { + title?: T; + videoSource?: T; + youtubeUrl?: T; + vimeoUrl?: T; + customUrl?: T; + thumbnail?: T; + caption?: T; + privacyMode?: T; + lazyLoad?: T; + aspectRatio?: T; + maxWidth?: T; + playbackOptions?: + | T + | { + autoplay?: T; + muted?: T; + loop?: T; + showControls?: T; + startTime?: T; + }; + style?: + | T + | { + alignment?: T; + borderRadius?: T; + shadow?: T; + }; + id?: T; + blockName?: T; + }; + 'featured-content-block'?: + | T + | { + title?: T; + subtitle?: T; + items?: + | T + | { + itemType?: T; + post?: T; + video?: T; + series?: T; + externalTitle?: T; + externalUrl?: T; + externalImage?: T; + externalDescription?: T; + customLabel?: T; + featured?: T; + id?: T; + }; + layout?: T; + columns?: T; + showDates?: T; + showType?: T; + showDescription?: T; + showCustomLabels?: T; + backgroundColor?: T; + card?: + | T + | { + bg?: T; + shadow?: T; + border?: T; + imgRatio?: T; + hover?: T; + }; + cta?: + | T + | { + showCta?: T; + ctaText?: T; + ctaUrl?: T; + }; + id?: T; + blockName?: T; + }; + }; + seo?: + | T + | { + metaTitle?: T; + metaDescription?: T; + ogImage?: T; + }; + status?: T; + publishedAt?: T; + updatedAt?: T; + createdAt?: T; +} +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "posts_select". + */ +export interface PostsSelect { + tenant?: T; + title?: T; + slug?: T; + type?: T; + isFeatured?: T; + excerpt?: T; + featuredImage?: T; + featuredVideo?: + | T + | { + enabled?: T; + replaceImage?: T; + source?: T; + video?: T; + embedUrl?: T; + uploadedVideo?: T; + autoplay?: T; + muted?: T; + processedEmbedUrl?: T; + extractedVideoId?: T; + platform?: T; + thumbnailUrl?: T; + }; + content?: T; + categories?: T; + tags?: T; + author?: T; + coAuthors?: T; + authorLegacy?: T; + readingTime?: T; + status?: T; + publishedAt?: T; + seo?: + | T + | { + metaTitle?: T; + metaDescription?: T; + ogImage?: T; + }; + updatedAt?: T; + createdAt?: T; +} +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "categories_select". + */ +export interface CategoriesSelect { + tenant?: T; + name?: T; + slug?: T; + description?: T; + updatedAt?: T; + createdAt?: T; +} +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "social-links_select". + */ +export interface SocialLinksSelect { + tenant?: T; + platform?: T; + url?: T; + isActive?: T; + updatedAt?: T; + createdAt?: T; +} +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "testimonials_select". + */ +export interface TestimonialsSelect { + tenant?: T; + quote?: T; + author?: T; + role?: T; + company?: T; + image?: T; + rating?: T; + source?: T; + sourceUrl?: T; + date?: T; + isActive?: T; + order?: T; + updatedAt?: T; + createdAt?: T; +} +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "faqs_select". + */ +export interface FaqsSelect { + tenant?: T; + question?: T; + answer?: T; + answerPlainText?: T; + category?: T; + icon?: T; + relatedFAQs?: T; + isActive?: T; + isFeatured?: T; + order?: T; + updatedAt?: T; + createdAt?: T; +} +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "team_select". + */ +export interface TeamSelect { + tenant?: T; + name?: T; + slug?: T; + role?: T; + department?: T; + image?: T; + bio?: T; + bioShort?: T; + email?: T; + phone?: T; + showContactInfo?: T; + socialLinks?: + | T + | { + platform?: T; + url?: T; + id?: T; + }; + qualifications?: + | T + | { + title?: T; + year?: T; + institution?: T; + id?: T; + }; + specializations?: + | T + | { + title?: T; + id?: T; + }; + languages?: + | T + | { + language?: T; + level?: T; + id?: T; + }; + linkedUser?: T; + isActive?: T; + isFeatured?: T; + order?: T; + startDate?: T; + reportsTo?: T; + hierarchyLevel?: T; + allowVCard?: T; + updatedAt?: T; + createdAt?: T; +} +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "service-categories_select". + */ +export interface ServiceCategoriesSelect { + tenant?: T; + name?: T; + slug?: T; + description?: T; + icon?: T; + image?: T; + color?: T; + isActive?: T; + order?: T; + updatedAt?: T; + createdAt?: T; +} +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "services_select". + */ +export interface ServicesSelect { + tenant?: T; + title?: T; + slug?: T; + subtitle?: T; + shortDescription?: T; + description?: T; + icon?: T; + iconImage?: T; + image?: T; + gallery?: + | T + | { + image?: T; + caption?: T; + id?: T; + }; + category?: T; + features?: + | T + | { + title?: T; + description?: T; + icon?: T; + id?: T; + }; + pricingType?: T; + price?: T; + priceMax?: T; + priceUnit?: T; + priceNote?: T; + pricingDetails?: T; + ctaText?: T; + ctaLink?: T; + ctaStyle?: T; + secondaryCta?: + | T + | { + enabled?: T; + text?: T; + link?: T; + }; + relatedServices?: T; + teamMembers?: T; + faqs?: T; + detailSections?: + | T + | { + title?: T; + content?: T; + icon?: T; + id?: T; + }; + testimonialQuote?: T; + testimonialAuthor?: T; + metaTitle?: T; + metaDescription?: T; + ogImage?: T; + isActive?: T; + isFeatured?: T; + isNew?: T; + order?: T; + updatedAt?: T; + createdAt?: T; +} +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "newsletter-subscribers_select". + */ +export interface NewsletterSubscribersSelect { + tenant?: T; + email?: T; + firstName?: T; + lastName?: T; + status?: T; + interests?: T; + source?: T; + subscribedAt?: T; + confirmedAt?: T; + unsubscribedAt?: T; + confirmationToken?: T; + ipAddress?: T; + userAgent?: T; + updatedAt?: T; + createdAt?: T; +} +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "portfolio-categories_select". + */ +export interface PortfolioCategoriesSelect { + tenant?: T; + name?: T; + slug?: T; + description?: T; + coverImage?: T; + order?: T; + isActive?: T; + updatedAt?: T; + createdAt?: T; +} +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "portfolios_select". + */ +export interface PortfoliosSelect { + tenant?: T; + title?: T; + slug?: T; + description?: T; + excerpt?: T; + category?: T; + tags?: T; + coverImage?: T; + images?: + | T + | { + image?: T; + caption?: T; + isHighlight?: T; + id?: T; + }; + projectDetails?: + | T + | { + client?: T; + location?: T; + shootingDate?: T; + equipment?: T; + }; + status?: T; + isFeatured?: T; + publishedAt?: T; + order?: T; + seo?: + | T + | { + metaTitle?: T; + metaDescription?: T; + ogImage?: T; + }; + updatedAt?: T; + createdAt?: T; +} +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "video-categories_select". + */ +export interface VideoCategoriesSelect { + tenant?: T; + name?: T; + slug?: T; + description?: T; + icon?: T; + coverImage?: T; + order?: T; + isActive?: T; + updatedAt?: T; + createdAt?: T; +} +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "videos_select". + */ +export interface VideosSelect { + tenant?: T; + title?: T; + slug?: T; + description?: T; + excerpt?: T; + source?: T; + videoFile?: T; + embedUrl?: T; + videoId?: T; + thumbnail?: T; + duration?: T; + durationSeconds?: T; + category?: T; + tags?: T; + videoType?: T; + playback?: + | T + | { + autoplay?: T; + muted?: T; + loop?: T; + controls?: T; + startTime?: T; + }; + aspectRatio?: T; + status?: T; + isFeatured?: T; + publishedAt?: T; + relatedVideos?: T; + relatedPosts?: T; + transcript?: T; + seo?: + | T + | { + metaTitle?: T; + metaDescription?: T; + ogImage?: T; + }; + updatedAt?: T; + createdAt?: T; +} +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "product-categories_select". + */ +export interface ProductCategoriesSelect { + tenant?: T; + name?: T; + slug?: T; + description?: T; + image?: T; + icon?: T; + parent?: T; + order?: T; + isActive?: T; + seo?: + | T + | { + metaTitle?: T; + metaDescription?: T; + }; + updatedAt?: T; + createdAt?: T; +} +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "products_select". + */ +export interface ProductsSelect { + tenant?: T; + title?: T; + slug?: T; + sku?: T; + shortDescription?: T; + description?: T; + category?: T; + tags?: + | T + | { + tag?: T; + id?: T; + }; + featuredImage?: T; + gallery?: + | T + | { + image?: T; + caption?: T; + id?: T; + }; + pricing?: + | T + | { + price?: T; + salePrice?: T; + currency?: T; + priceType?: T; + priceNote?: T; + }; + details?: + | T + | { + specifications?: + | T + | { + key?: T; + value?: T; + id?: T; + }; + features?: + | T + | { + feature?: T; + icon?: T; + id?: T; + }; + }; + inventory?: + | T + | { + stockStatus?: T; + stockQuantity?: T; + deliveryTime?: T; + }; + relatedProducts?: T; + downloadFiles?: + | T + | { + file?: T; + title?: T; + id?: T; + }; + cta?: + | T + | { + type?: T; + buttonText?: T; + externalUrl?: T; + }; + seo?: + | T + | { + metaTitle?: T; + metaDescription?: T; + ogImage?: T; + }; + status?: T; + isFeatured?: T; + isNew?: T; + order?: T; + publishedAt?: T; + updatedAt?: T; + createdAt?: T; +} +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "timelines_select". + */ +export interface TimelinesSelect { + tenant?: T; + name?: T; + slug?: T; + description?: T; + type?: T; + status?: T; + displayOptions?: + | T + | { + layout?: T; + sortOrder?: T; + showConnector?: T; + showImages?: T; + groupByYear?: T; + markerStyle?: T; + colorScheme?: T; + }; + events?: + | T + | { + dateType?: T; + year?: T; + month?: T; + day?: T; + endYear?: T; + endMonth?: T; + ongoing?: T; + customDate?: T; + title?: T; + subtitle?: T; + description?: T; + shortDescription?: T; + image?: T; + gallery?: + | T + | { + image?: T; + caption?: T; + id?: T; + }; + category?: T; + importance?: T; + stepNumber?: T; + duration?: T; + responsible?: T; + actionRequired?: T; + deliverables?: + | T + | { + name?: T; + type?: T; + id?: T; + }; + icon?: T; + color?: T; + links?: + | T + | { + label?: T; + url?: T; + type?: T; + id?: T; + }; + metadata?: T; + id?: T; + }; + seo?: + | T + | { + metaTitle?: T; + metaDescription?: T; + }; + updatedAt?: T; + createdAt?: T; +} +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "workflows_select". + */ +export interface WorkflowsSelect { + tenant?: T; + name?: T; + slug?: T; + description?: T; + shortDescription?: T; + type?: T; + status?: T; + image?: T; + properties?: + | T + | { + estimatedDuration?: T; + complexity?: T; + isIterative?: T; + allowParallelPhases?: T; + }; + displayOptions?: + | T + | { + layout?: T; + showPhaseNumbers?: T; + showStepNumbers?: T; + showDurations?: T; + showResponsible?: T; + showProgress?: T; + colorScheme?: T; + }; + phases?: + | T + | { + name?: T; + description?: T; + icon?: T; + color?: T; + estimatedDuration?: T; + responsible?: T; + steps?: + | T + | { + name?: T; + description?: T; + shortDescription?: T; + stepType?: T; + priority?: T; + estimatedDuration?: T; + responsible?: T; + icon?: T; + dependencies?: + | T + | { + dependsOnSteps?: T; + canRunParallel?: T; + isBlocking?: T; + }; + conditions?: + | T + | { + condition?: T; + nextStep?: T; + color?: T; + id?: T; + }; + checklist?: + | T + | { + item?: T; + isRequired?: T; + id?: T; + }; + resources?: + | T + | { + name?: T; + type?: T; + file?: T; + url?: T; + description?: T; + id?: T; + }; + outputs?: + | T + | { + name?: T; + description?: T; + id?: T; + }; + metadata?: T; + id?: T; + }; + deliverables?: + | T + | { + name?: T; + description?: T; + id?: T; + }; + id?: T; + }; + globalResources?: + | T + | { + name?: T; + type?: T; + file?: T; + url?: T; + description?: T; + id?: T; + }; + seo?: + | T + | { + metaTitle?: T; + metaDescription?: T; + }; + updatedAt?: T; + createdAt?: T; +} +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "tags_select". + */ +export interface TagsSelect { + tenant?: T; + name?: T; + slug?: T; + description?: T; + color?: T; + updatedAt?: T; + createdAt?: T; +} +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "authors_select". + */ +export interface AuthorsSelect { + tenant?: T; + name?: T; + slug?: T; + avatar?: T; + bio?: T; + bioShort?: T; + title?: T; + email?: T; + website?: T; + social?: + | T + | { + twitter?: T; + linkedin?: T; + github?: T; + instagram?: T; + }; + linkedTeam?: T; + linkedUser?: T; + isActive?: T; + isGuest?: T; + featured?: T; + updatedAt?: T; + createdAt?: T; +} +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "locations_select". + */ +export interface LocationsSelect { + tenant?: T; + name?: T; + slug?: T; + type?: T; + description?: T; + image?: T; + address?: + | T + | { + street?: T; + additionalLine?: T; + zip?: T; + city?: T; + state?: T; + country?: T; + }; + geo?: + | T + | { + lat?: T; + lng?: T; + zoom?: T; + }; + contact?: + | T + | { + phone?: T; + fax?: T; + email?: T; + website?: T; + }; + hours?: + | T + | { + display?: T; + structured?: + | T + | { + day?: T; + closed?: T; + open?: T; + close?: T; + break?: + | T + | { + hasBreak?: T; + start?: T; + end?: T; + }; + id?: T; + }; + note?: T; + }; + directions?: + | T + | { + text?: T; + parking?: T; + publicTransport?: T; + accessibility?: T; + }; + services?: T; + teamMembers?: T; + isMain?: T; + isActive?: T; + showInFooter?: T; + order?: T; + updatedAt?: T; + createdAt?: T; +} +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "partners_select". + */ +export interface PartnersSelect { + tenant?: T; + name?: T; + slug?: T; + type?: T; + logo?: T; + logoLight?: T; + description?: T; + website?: T; + caseStudy?: + | T + | { + quote?: T; + quotePerson?: T; + quoteRole?: T; + projectDescription?: T; + results?: + | T + | { + metric?: T; + label?: T; + id?: T; + }; + }; + certification?: + | T + | { + issuer?: T; + validFrom?: T; + validUntil?: T; + certNumber?: T; + document?: T; + }; + category?: T; + tags?: + | T + | { + tag?: T; + id?: T; + }; + isFeatured?: T; + isActive?: T; + order?: T; + since?: T; + updatedAt?: T; + createdAt?: T; +} +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "jobs_select". + */ +export interface JobsSelect { + tenant?: T; + title?: T; + slug?: T; + reference?: T; + department?: T; + category?: T; + type?: T; + workModel?: T; + experienceLevel?: T; + location?: + | T + | { + locationRef?: T; + city?: T; + region?: T; + country?: T; + }; + summary?: T; + description?: T; + responsibilities?: T; + requirements?: T; + qualifications?: T; + benefits?: T; + benefitsList?: + | T + | { + benefit?: T; + icon?: T; + id?: T; + }; + salary?: + | T + | { + show?: T; + type?: T; + min?: T; + max?: T; + currency?: T; + note?: T; + }; + application?: + | T + | { + method?: T; + email?: T; + formId?: T; + externalUrl?: T; + contact?: T; + deadline?: T; + }; + image?: T; + status?: T; + publishedAt?: T; + isFeatured?: T; + isUrgent?: T; + seo?: + | T + | { + metaTitle?: T; + metaDescription?: T; + }; + updatedAt?: T; + createdAt?: T; +} +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "downloads_select". + */ +export interface DownloadsSelect { + tenant?: T; + title?: T; + slug?: T; + description?: T; + file?: T; + fileType?: T; + fileSize?: T; + category?: T; + tags?: + | T + | { + tag?: T; + id?: T; + }; + thumbnail?: T; + relatedServices?: T; + relatedProducts?: T; + access?: + | T + | { + requireLogin?: T; + requireForm?: T; + formFields?: T; + }; + downloadCount?: T; + version?: T; + lastUpdated?: T; + isActive?: T; + isFeatured?: T; + order?: T; + updatedAt?: T; + createdAt?: T; +} +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "events_select". + */ +export interface EventsSelect { + tenant?: T; + title?: T; + slug?: T; + subtitle?: T; + description?: T; + excerpt?: T; + eventType?: T; + category?: T; + format?: T; + startDate?: T; + endDate?: T; + isAllDay?: T; + timezone?: T; + isRecurring?: T; + recurrence?: + | T + | { + frequency?: T; + interval?: T; + endRecurrence?: T; + description?: T; + }; + location?: + | T + | { + locationRef?: T; + customLocation?: T; + venueName?: T; + street?: T; + zip?: T; + city?: T; + country?: T; + room?: T; + directions?: T; + }; + online?: + | T + | { + platform?: T; + accessLink?: T; + accessInfo?: T; + }; + image?: T; + gallery?: + | T + | { + image?: T; + caption?: T; + id?: T; + }; + registration?: + | T + | { + required?: T; + method?: T; + formId?: T; + email?: T; + externalUrl?: T; + phone?: T; + deadline?: T; + maxParticipants?: T; + currentParticipants?: T; + waitlistEnabled?: T; + }; + pricing?: + | T + | { + isFree?: T; + prices?: + | T + | { + name?: T; + price?: T; + currency?: T; + description?: T; + validUntil?: T; + id?: T; + }; + priceNote?: T; + }; + speakers?: + | T + | { + teamMember?: T; + isExternal?: T; + name?: T; + title?: T; + company?: T; + photo?: T; + bio?: T; + role?: T; + id?: T; + }; + agenda?: + | T + | { + time?: T; + title?: T; + description?: T; + speaker?: T; + type?: T; + id?: T; + }; + contact?: + | T + | { + teamMember?: T; + name?: T; + email?: T; + phone?: T; + }; + relatedServices?: T; + relatedEvents?: T; + seo?: + | T + | { + metaTitle?: T; + metaDescription?: T; + ogImage?: T; + }; + status?: T; + isFeatured?: T; + publishedAt?: T; + updatedAt?: T; + createdAt?: T; +} +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "bookings_select". + */ +export interface BookingsSelect { + tenant?: T; + customerName?: T; + customerEmail?: T; + customerPhone?: T; + customerCompany?: T; + serviceType?: T; + service?: T; + date?: T; + time?: T; + duration?: T; + locationType?: T; + locationAddress?: T; + participants?: T; + message?: T; + referenceImages?: + | T + | { + image?: T; + note?: T; + id?: T; + }; + status?: T; + priority?: T; + pricing?: + | T + | { + estimatedPrice?: T; + finalPrice?: T; + depositAmount?: T; + depositPaid?: T; + fullyPaid?: T; + }; + internalNotes?: + | T + | { + note?: T; + author?: T; + createdAt?: T; + id?: T; + }; + contactHistory?: + | T + | { + type?: T; + summary?: T; + date?: T; + id?: T; + }; + assignedTo?: T; + source?: T; + gdprConsent?: T; + updatedAt?: T; + createdAt?: T; +} +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "certifications_select". + */ +export interface CertificationsSelect { + tenant?: T; + name?: T; + slug?: T; + description?: T; + shortDescription?: T; + type?: T; + category?: T; + issuer?: + | T + | { + name?: T; + logo?: T; + website?: T; + country?: T; + }; + certNumber?: T; + issuedDate?: T; + validUntil?: T; + renewalCycle?: T; + logo?: T; + certificate?: T; + gallery?: + | T + | { + document?: T; + title?: T; + id?: T; + }; + scope?: + | T + | { + description?: T; + locations?: T; + services?: T; + }; + requirements?: + | T + | { + requirement?: T; + description?: T; + id?: T; + }; + benefits?: + | T + | { + title?: T; + description?: T; + icon?: T; + id?: T; + }; + audits?: + | T + | { + date?: T; + type?: T; + result?: T; + notes?: T; + id?: T; + }; + status?: T; + visibility?: T; + priority?: T; + showOnHomepage?: T; + seo?: + | T + | { + metaTitle?: T; + metaDescription?: T; + }; + updatedAt?: T; + createdAt?: T; +} +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "projects_select". + */ +export interface ProjectsSelect { + tenant?: T; + title?: T; + slug?: T; + tagline?: T; + description?: T; + shortDescription?: T; + type?: T; + genres?: T; + platforms?: T; + featuredImage?: T; + logo?: T; + screenshots?: + | T + | { + image?: T; + caption?: T; + id?: T; + }; + videos?: + | T + | { + type?: T; + title?: T; + url?: T; + thumbnail?: T; + id?: T; + }; + techStack?: + | T + | { + engine?: T; + languages?: T; + tools?: T; + }; + requirements?: + | T + | { + minimum?: + | T + | { + os?: T; + cpu?: T; + ram?: T; + gpu?: T; + storage?: T; + }; + recommended?: + | T + | { + os?: T; + cpu?: T; + ram?: T; + gpu?: T; + storage?: T; + }; + }; + releaseDate?: T; + links?: + | T + | { + website?: T; + steam?: T; + itchio?: T; + epicGames?: T; + gog?: T; + playStore?: T; + appStore?: T; + github?: T; + discord?: T; + twitter?: T; + }; + downloads?: + | T + | { + title?: T; + platform?: T; + version?: T; + file?: T; + externalUrl?: T; + size?: T; + id?: T; + }; + features?: + | T + | { + title?: T; + description?: T; + icon?: T; + id?: T; + }; + team?: + | T + | { + name?: T; + role?: T; + link?: T; + avatar?: T; + id?: T; + }; + gameJam?: + | T + | { + jamName?: T; + theme?: T; + duration?: T; + ranking?: T; + jamLink?: T; + }; + devlogs?: T; + status?: T; + visibility?: T; + featured?: T; + sortOrder?: T; + seo?: + | T + | { + metaTitle?: T; + metaDescription?: T; + ogImage?: T; + }; + updatedAt?: T; + createdAt?: T; +} +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "favorites_select". + */ +export interface FavoritesSelect { + tenant?: T; + title?: T; + slug?: T; + description?: T; + category?: T; + subcategory?: T; + price?: T; + priceRange?: T; + affiliateUrl?: T; + affiliateNetwork?: T; + image?: T; + badge?: T; + featured?: T; + isActive?: T; + order?: T; + updatedAt?: T; + createdAt?: T; +} +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "series_select". + */ +export interface SeriesSelect { + tenant?: T; + title?: T; + slug?: T; + tagline?: T; + description?: T; + logo?: T; + coverImage?: T; + brandColor?: T; + accentColor?: T; + youtubePlaylistId?: T; + youtubePlaylistUrl?: T; + order?: T; + isActive?: T; + updatedAt?: T; + createdAt?: T; +} +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "youtube-channels_select". + */ +export interface YoutubeChannelsSelect { + name?: T; + slug?: T; + youtubeChannelId?: T; + youtubeHandle?: T; + language?: T; + category?: T; + status?: T; + channelThumbnailUrl?: T; + branding?: + | T + | { + primaryColor?: T; + secondaryColor?: T; + logo?: T; + thumbnailTemplate?: T; + }; + publishingSchedule?: + | T + | { + defaultDays?: T; + defaultTime?: T; + shortsPerWeek?: T; + longformPerWeek?: T; + }; + currentMetrics?: + | T + | { + subscriberCount?: T; + totalViews?: T; + videoCount?: T; + lastSyncedAt?: T; + }; + updatedAt?: T; + createdAt?: T; +} +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "youtube-content_select". + */ +export interface YoutubeContentSelect { + title?: T; + slug?: T; + channel?: T; + series?: T; + format?: T; + status?: T; + priority?: T; + assignedTo?: T; + createdBy?: T; + productionBatch?: T; + description?: T; + hook?: T; + keyPoints?: + | T + | { + point?: T; + id?: T; + }; + callToAction?: T; + scriptUrl?: T; + scriptContent?: T; + shootDate?: T; + editDeadline?: T; + reviewDeadline?: T; + scheduledPublishDate?: T; + actualPublishDate?: T; + productionWeek?: T; + calendarWeek?: T; + productionDate?: T; + targetDuration?: T; + bRollNotes?: T; + publishTime?: T; + thumbnailText?: T; + ctaType?: T; + ctaDetail?: T; + uploadChecklist?: + | T + | { + step?: T; + completed?: T; + completedAt?: T; + id?: T; + }; + disclaimers?: + | T + | { + type?: T; + text?: T; + placement?: T; + id?: T; + }; + thumbnail?: T; + thumbnailAlt?: T; + videoFile?: T; + rawFootage?: + | T + | { + file?: T; + description?: T; + id?: T; + }; + approvals?: + | T + | { + scriptApproval?: + | T + | { + approved?: T; + approvedBy?: T; + approvedAt?: T; + notes?: T; + }; + medicalApproval?: + | T + | { + required?: T; + approved?: T; + approvedBy?: T; + approvedAt?: T; + notes?: T; + }; + legalApproval?: + | T + | { + approved?: T; + approvedBy?: T; + approvedAt?: T; + disclaimerIncluded?: T; + notes?: T; + }; + finalApproval?: + | T + | { + approved?: T; + approvedBy?: T; + approvedAt?: T; + notes?: T; + }; + }; + youtube?: + | T + | { + videoId?: T; + url?: T; + metadata?: + | T + | { + youtubeTitle?: T; + youtubeDescription?: T; + tags?: + | T + | { + tag?: T; + id?: T; + }; + visibility?: T; + chapters?: T; + pinnedComment?: T; + }; + }; + performance?: + | T + | { + views?: T; + likes?: T; + comments?: T; + shares?: T; + watchTimeMinutes?: T; + avgViewDuration?: T; + avgViewPercentage?: T; + ctr?: T; + impressions?: T; + subscribersGained?: T; + lastSyncedAt?: T; + }; + costs?: + | T + | { + estimatedProductionHours?: T; + estimatedProductionCost?: T; + estimatedRevenue?: T; + }; + internalNotes?: T; + updatedAt?: T; + createdAt?: T; +} +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "yt-tasks_select". + */ +export interface YtTasksSelect { + title?: T; + description?: T; + video?: T; + channel?: T; + taskType?: T; + status?: T; + priority?: T; + assignedTo?: T; + dueDate?: T; + completedAt?: T; + completedBy?: T; + blockedReason?: T; + attachments?: + | T + | { + file?: T; + note?: T; + id?: T; + }; + comments?: + | T + | { + author?: T; + content?: T; + createdAt?: T; + id?: T; + }; + updatedAt?: T; + createdAt?: T; +} +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "yt-notifications_select". + */ +export interface YtNotificationsSelect { + recipient?: T; + type?: T; + title?: T; + message?: T; + link?: T; + relatedVideo?: T; + relatedTask?: T; + relatedAccount?: T; + read?: T; + readAt?: T; + emailSent?: T; + updatedAt?: T; + createdAt?: T; +} +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "yt-batches_select". + */ +export interface YtBatchesSelect { + name?: T; + channel?: T; + status?: T; + productionPeriodStart?: T; + productionPeriodEnd?: T; + targets?: + | T + | { + shortsTarget?: T; + longformsTarget?: T; + totalTarget?: T; + bufferDays?: T; + }; + progress?: + | T + | { + shortsCompleted?: T; + longformsCompleted?: T; + percentage?: T; + }; + team?: + | T + | { + producer?: T; + editor?: T; + reviewer?: T; + }; + updatedAt?: T; + createdAt?: T; +} +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "yt-monthly-goals_select". + */ +export interface YtMonthlyGoalsSelect { + channel?: T; + month?: T; + displayTitle?: T; + contentGoals?: + | T + | { + longformsTarget?: T; + longformsCurrent?: T; + shortsTarget?: T; + shortsCurrent?: T; + }; + audienceGoals?: + | T + | { + subscribersTarget?: T; + subscribersCurrent?: T; + viewsTarget?: T; + viewsCurrent?: T; + }; + engagementGoals?: + | T + | { + avgCtrTarget?: T; + avgCtrCurrent?: T; + avgRetentionTarget?: T; + avgRetentionCurrent?: T; + }; + businessGoals?: + | T + | { + newsletterSignupsTarget?: T; + newsletterSignupsCurrent?: T; + affiliateRevenueTarget?: T; + affiliateRevenueCurrent?: T; + }; + customGoals?: + | T + | { + metric?: T; + target?: T; + current?: T; + status?: T; + id?: T; + }; + notes?: T; + updatedAt?: T; + createdAt?: T; +} +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "yt-script-templates_select". + */ +export interface YtScriptTemplatesSelect { + name?: T; + channel?: T; + series?: T; + format?: T; + description?: T; + updatedAt?: T; + createdAt?: T; +} +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "yt-checklist-templates_select". + */ +export interface YtChecklistTemplatesSelect { + name?: T; + channel?: T; + type?: T; + format?: T; + description?: T; + items?: + | T + | { + order?: T; + task?: T; + category?: T; + details?: T; + isRequired?: T; + id?: T; + }; + isDefault?: T; + isActive?: T; + updatedAt?: T; + createdAt?: T; +} +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "yt-series_select". + */ +export interface YtSeriesSelect { + name?: T; + slug?: T; + channel?: T; + description?: T; + logo?: T; + coverImage?: T; + brandColor?: T; + accentColor?: T; + youtubePlaylistId?: T; + youtubePlaylistUrl?: T; + format?: T; + publishingFrequency?: T; + isActive?: T; + order?: T; + updatedAt?: T; + createdAt?: T; +} +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "social-platforms_select". + */ +export interface SocialPlatformsSelect { + name?: T; + slug?: T; + icon?: T; + color?: T; + isActive?: T; + apiStatus?: T; + apiConfig?: + | T + | { + apiType?: T; + baseUrl?: T; + authType?: T; + oauthEndpoint?: T; + scopes?: + | T + | { + scope?: T; + id?: T; + }; + tokenValidityDays?: T; + }; + interactionTypes?: + | T + | { + type?: T; + label?: T; + icon?: T; + canReply?: T; + id?: T; + }; + rateLimits?: + | T + | { + requestsPerMinute?: T; + requestsPerDay?: T; + quotaUnitsPerDay?: T; + }; + updatedAt?: T; + createdAt?: T; +} +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "social-accounts_select". + */ +export interface SocialAccountsSelect { + platform?: T; + linkedChannel?: T; + displayName?: T; + accountHandle?: T; + externalId?: T; + accountUrl?: T; + isActive?: T; + credentials?: + | T + | { + accessToken?: T; + refreshToken?: T; + tokenExpiresAt?: T; + apiKey?: T; + }; + stats?: + | T + | { + followers?: T; + totalPosts?: T; + lastSyncedAt?: T; + }; + syncSettings?: + | T + | { + autoSyncEnabled?: T; + syncIntervalMinutes?: T; + syncComments?: T; + syncDMs?: T; + }; + updatedAt?: T; + createdAt?: T; +} +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "community-interactions_select". + */ +export interface CommunityInteractionsSelect { + platform?: T; + socialAccount?: T; + linkedContent?: T; + type?: T; + externalId?: T; + parentInteraction?: T; + author?: + | T + | { + name?: T; + handle?: T; + profileUrl?: T; + avatarUrl?: T; + isVerified?: T; + isSubscriber?: T; + isMember?: T; + subscriberCount?: T; + }; + message?: T; + messageHtml?: T; + attachments?: + | T + | { + type?: T; + url?: T; + id?: T; + }; + publishedAt?: T; + analysis?: + | T + | { + sentiment?: T; + sentimentScore?: T; + confidence?: T; + topics?: + | T + | { + topic?: T; + id?: T; + }; + language?: T; + suggestedTemplate?: T; + suggestedReply?: T; + analyzedAt?: T; + }; + flags?: + | T + | { + isMedicalQuestion?: T; + requiresEscalation?: T; + isSpam?: T; + isFromInfluencer?: T; + }; + status?: T; + priority?: T; + assignedTo?: T; + responseDeadline?: T; + response?: + | T + | { + text?: T; + usedTemplate?: T; + sentAt?: T; + sentBy?: T; + externalReplyId?: T; + }; + engagement?: + | T + | { + likes?: T; + replies?: T; + isHearted?: T; + isPinned?: T; + }; + internalNotes?: T; + updatedAt?: T; + createdAt?: T; +} +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "community-templates_select". + */ +export interface CommunityTemplatesSelect { + name?: T; + category?: T; + channel?: T; + platforms?: T; + template?: T; + variables?: + | T + | { + variable?: T; + description?: T; + defaultValue?: T; + id?: T; + }; + autoSuggestKeywords?: + | T + | { + keyword?: T; + id?: T; + }; + requiresReview?: T; + isActive?: T; + usageCount?: T; + exampleOutput?: T; + updatedAt?: T; + createdAt?: T; +} +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "community-rules_select". + */ +export interface CommunityRulesSelect { + name?: T; + priority?: T; + isActive?: T; + description?: T; + channel?: T; + platforms?: T; + trigger?: + | T + | { + type?: T; + keywords?: + | T + | { + keyword?: T; + matchType?: T; + id?: T; + }; + sentimentValues?: T; + influencerMinFollowers?: T; + }; + actions?: + | T + | { + action?: T; + value?: T; + targetUser?: T; + targetTemplate?: T; + id?: T; + }; + stats?: + | T + | { + timesTriggered?: T; + lastTriggeredAt?: T; + }; + updatedAt?: T; + createdAt?: T; +} +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "report-schedules_select". + */ +export interface ReportSchedulesSelect { + name?: T; + enabled?: T; + frequency?: T; + dayOfWeek?: T; + dayOfMonth?: T; + time?: T; + timezone?: T; + reportType?: T; + channels?: T; + periodDays?: T; + format?: T; + recipients?: + | T + | { + email?: T; + name?: T; + id?: T; + }; + lastSentAt?: T; + nextScheduledAt?: T; + sendCount?: T; + lastError?: T; + updatedAt?: T; + createdAt?: T; +} +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "cookie-configurations_select". + */ +export interface CookieConfigurationsSelect { + tenant?: T; + title?: T; + revision?: T; + enabledCategories?: T; + translations?: + | T + | { + de?: + | T + | { + bannerTitle?: T; + bannerDescription?: T; + acceptAllButton?: T; + acceptNecessaryButton?: T; + settingsButton?: T; + saveButton?: T; + privacyPolicyUrl?: T; + categoryLabels?: + | T + | { + necessary?: + | T + | { + title?: T; + description?: T; + }; + functional?: + | T + | { + title?: T; + description?: T; + }; + analytics?: + | T + | { + title?: T; + description?: T; + }; + marketing?: + | T + | { + title?: T; + description?: T; + }; + }; + }; + }; + styling?: + | T + | { + position?: T; + theme?: T; + }; + updatedAt?: T; + createdAt?: T; +} +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "cookie-inventory_select". + */ +export interface CookieInventorySelect { + tenant?: T; + name?: T; + provider?: T; + category?: T; + duration?: T; + description?: T; + isActive?: T; + updatedAt?: T; + createdAt?: T; +} +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "consent-logs_select". + */ +export interface ConsentLogsSelect { + consentId?: T; + clientRef?: T; + tenant?: T; + categories?: T; + revision?: T; + userAgent?: T; + anonymizedIp?: T; + expiresAt?: T; + updatedAt?: T; + createdAt?: T; +} +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "privacy-policy-settings_select". + */ +export interface PrivacyPolicySettingsSelect { + tenant?: T; + title?: T; + provider?: T; + alfright?: + | T + | { + tenantId?: T; + apiKey?: T; + language?: T; + iframeHeight?: T; + }; + styling?: + | T + | { + headerColor?: T; + headerFont?: T; + headerSize?: T; + subheaderSize?: T; + fontColor?: T; + textFont?: T; + textSize?: T; + linkColor?: T; + backgroundColor?: T; + }; + showCookieTable?: T; + cookieTableTitle?: T; + cookieTableDescription?: T; + seo?: + | T + | { + metaTitle?: T; + metaDescription?: T; + }; + updatedAt?: T; + createdAt?: T; +} +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "email-logs_select". + */ +export interface EmailLogsSelect { + tenant?: T; + to?: T; + from?: T; + subject?: T; + status?: T; + messageId?: T; + error?: T; + source?: T; + metadata?: T; + updatedAt?: T; + createdAt?: T; +} +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "audit-logs_select". + */ +export interface AuditLogsSelect { + action?: T; + severity?: T; + entityType?: T; + entityId?: T; + user?: T; + userEmail?: T; + tenant?: T; + ipAddress?: T; + userAgent?: T; + description?: T; + previousValue?: T; + newValue?: T; + metadata?: T; + updatedAt?: T; + createdAt?: T; +} +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "monitoring-snapshots_select". + */ +export interface MonitoringSnapshotsSelect { + timestamp?: T; + system?: + | T + | { + cpuUsagePercent?: T; + memoryUsedMB?: T; + memoryTotalMB?: T; + memoryUsagePercent?: T; + diskUsedGB?: T; + diskTotalGB?: T; + diskUsagePercent?: T; + loadAvg1?: T; + loadAvg5?: T; + uptime?: T; + }; + services?: + | T + | { + payload?: T; + queueWorker?: T; + postgresql?: T; + pgbouncer?: T; + redis?: T; + }; + external?: + | T + | { + smtp?: T; + metaOAuth?: T; + youtubeOAuth?: T; + cronJobs?: T; + secrets?: T; + securityEvents?: T; + }; + performance?: + | T + | { + avgResponseTimeMs?: T; + p95ResponseTimeMs?: T; + p99ResponseTimeMs?: T; + errorRate?: T; + requestsPerMinute?: T; + }; + updatedAt?: T; + createdAt?: T; +} +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "monitoring-logs_select". + */ +export interface MonitoringLogsSelect { + level?: T; + source?: T; + message?: T; + context?: T; + requestId?: T; + userId?: T; + tenant?: T; + duration?: T; + updatedAt?: T; + createdAt?: T; +} +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "monitoring-alert-rules_select". + */ +export interface MonitoringAlertRulesSelect { + name?: T; + metric?: T; + condition?: T; + threshold?: T; + severity?: T; + channels?: T; + recipients?: + | T + | { + emails?: + | T + | { + email?: T; + id?: T; + }; + slackWebhook?: T; + discordWebhook?: T; + }; + cooldownMinutes?: T; + enabled?: T; + tenant?: T; + updatedAt?: T; + createdAt?: T; +} +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "monitoring-alert-history_select". + */ +export interface MonitoringAlertHistorySelect { + rule?: T; + metric?: T; + value?: T; + threshold?: T; + severity?: T; + message?: T; + channelsSent?: T; + resolvedAt?: T; + acknowledgedBy?: T; + updatedAt?: T; + createdAt?: T; +} +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "site-settings_select". + */ +export interface SiteSettingsSelect { + tenant?: T; + siteName?: T; + siteTagline?: T; + logo?: T; + favicon?: T; + contact?: + | T + | { + email?: T; + phone?: T; + fax?: T; + }; + address?: + | T + | { + street?: T; + additionalLine?: T; + zip?: T; + city?: T; + state?: T; + country?: T; + }; + geo?: + | T + | { + lat?: T; + lng?: T; + zoom?: T; + }; + footer?: + | T + | { + copyrightText?: T; + showSocialLinks?: T; + }; + seo?: + | T + | { + defaultMetaTitle?: T; + defaultMetaDescription?: T; + defaultOgImage?: T; + }; + updatedAt?: T; + createdAt?: T; +} +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "navigations_select". + */ +export interface NavigationsSelect { + tenant?: T; + title?: T; + mainMenu?: + | T + | { + label?: T; + type?: T; + page?: T; + url?: T; + openInNewTab?: T; + submenu?: + | T + | { + label?: T; + linkType?: T; + page?: T; + url?: T; + id?: T; + }; + id?: T; + }; + footerMenu?: + | T + | { + label?: T; + linkType?: T; + page?: T; + url?: T; + id?: T; + }; + updatedAt?: T; + createdAt?: T; +} +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "forms_select". + */ +export interface FormsSelect { + title?: T; + fields?: + | T + | { + checkbox?: + | T + | { + name?: T; + label?: T; + width?: T; + required?: T; + defaultValue?: T; + id?: T; + blockName?: T; + }; + email?: + | T + | { + name?: T; + label?: T; + width?: T; + required?: T; + id?: T; + blockName?: T; + }; + message?: + | T + | { + message?: T; + id?: T; + blockName?: T; + }; + number?: + | T + | { + name?: T; + label?: T; + width?: T; + defaultValue?: T; + required?: T; + id?: T; + blockName?: T; + }; + select?: + | T + | { + name?: T; + label?: T; + width?: T; + defaultValue?: T; + placeholder?: T; + options?: + | T + | { + label?: T; + value?: T; + id?: T; + }; + required?: T; + id?: T; + blockName?: T; + }; + text?: + | T + | { + name?: T; + label?: T; + width?: T; + defaultValue?: T; + required?: T; + id?: T; + blockName?: T; + }; + textarea?: + | T + | { + name?: T; + label?: T; + width?: T; + defaultValue?: T; + required?: T; + id?: T; + blockName?: T; + }; + }; + submitButtonLabel?: T; + confirmationType?: T; + confirmationMessage?: T; + redirect?: + | T + | { + type?: T; + reference?: T; + url?: T; + }; + emails?: + | T + | { + emailTo?: T; + cc?: T; + bcc?: T; + replyTo?: T; + emailFrom?: T; + subject?: T; + message?: T; + id?: T; + }; + tenant?: T; + updatedAt?: T; + createdAt?: T; +} +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "form-submissions_select". + */ +export interface FormSubmissionsSelect { + form?: T; + submissionData?: + | T + | { + field?: T; + value?: T; + id?: T; + }; + updatedAt?: T; + createdAt?: T; +} +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "redirects_select". + */ +export interface RedirectsSelect { + from?: T; + to?: + | T + | { + type?: T; + reference?: T; + url?: T; + }; + updatedAt?: T; + createdAt?: T; +} +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "payload-kv_select". + */ +export interface PayloadKvSelect { + key?: T; + data?: T; +} +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "payload-locked-documents_select". + */ +export interface PayloadLockedDocumentsSelect { + document?: T; + globalSlug?: T; + user?: T; + updatedAt?: T; + createdAt?: T; +} +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "payload-preferences_select". + */ +export interface PayloadPreferencesSelect { + user?: T; + key?: T; + value?: T; + updatedAt?: T; + createdAt?: T; +} +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "payload-migrations_select". + */ +export interface PayloadMigrationsSelect { + name?: T; + batch?: T; + updatedAt?: T; + createdAt?: T; +} +/** + * Globale SEO-Konfiguration und Schema.org Daten + * + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "seo-settings". + */ +export interface SeoSetting { + id: number; + metaDefaults?: { + /** + * Wird an jeden Seitentitel angehängt (z.B. "Startseite | Firmenname") + */ + titleSuffix?: string | null; + /** + * Wird verwendet, wenn keine spezifische Beschreibung gesetzt ist + */ + defaultDescription?: string | null; + /** + * Fallback-Bild für Social Media Shares (empfohlen: 1200x630px) + */ + defaultOgImage?: (number | null) | Media; + /** + * Globale Keywords (optional, geringe SEO-Relevanz) + */ + keywords?: string[] | null; + }; + /** + * Daten für das Organization Schema + */ + organization: { + name: string; + /** + * Vollständiger rechtlicher Firmenname (falls abweichend) + */ + legalName?: string | null; + description?: string | null; + /** + * Firmenlogo für Schema.org (min. 112x112px, empfohlen: 512x512px) + */ + logo?: (number | null) | Media; + foundingDate?: string | null; + }; + contact?: { + email?: string | null; + /** + * Im Format +49 123 456789 + */ + phone?: string | null; + fax?: string | null; + }; + address?: { + street?: string | null; + postalCode?: string | null; + city?: string | null; + region?: string | null; + country?: string | null; + /** + * ISO 3166-1 Alpha-2 Code + */ + countryCode?: string | null; + }; + /** + * Für Local Business Schema + */ + geo?: { + latitude?: number | null; + longitude?: number | null; + }; + /** + * URLs zu Social Media Profilen (für sameAs Schema) + */ + socialProfiles?: + | { + platform?: + | ('facebook' | 'instagram' | 'twitter' | 'linkedin' | 'youtube' | 'tiktok' | 'pinterest' | 'xing' | 'other') + | null; + url: string; + id?: string | null; + }[] + | null; + /** + * Zusätzliche Daten für lokale Unternehmen + */ + localBusiness?: { + enabled?: boolean | null; + type?: + | ( + | 'LocalBusiness' + | 'Physician' + | 'Dentist' + | 'Attorney' + | 'Restaurant' + | 'Hotel' + | 'Store' + | 'HealthClub' + | 'HairSalon' + | 'AutoRepair' + | 'RealEstateAgent' + | 'FinancialService' + | 'ProfessionalService' + | 'MedicalBusiness' + ) + | null; + priceRange?: ('€' | '€€' | '€€€' | '€€€€') | null; + /** + * Im Format "Mo-Fr 09:00-17:00" + */ + openingHours?: + | { + specification?: string | null; + id?: string | null; + }[] + | null; + }; + robots?: { + /** + * Wenn deaktiviert, wird die gesamte Website von Suchmaschinen ausgeschlossen + */ + allowIndexing?: boolean | null; + /** + * Pfade die nicht gecrawlt werden sollen (z.B. "/intern", "/preview") + */ + additionalDisallow?: string[] | null; + }; + /** + * Codes für Suchmaschinen-Verifizierung + */ + verification?: { + /** + * Meta-Tag Content (nur der Code, nicht das gesamte Tag) + */ + google?: string | null; + bing?: string | null; + yandex?: string | null; + }; + updatedAt?: string | null; + createdAt?: string | null; +} +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "seo-settings_select". + */ +export interface SeoSettingsSelect { + metaDefaults?: + | T + | { + titleSuffix?: T; + defaultDescription?: T; + defaultOgImage?: T; + keywords?: T; + }; + organization?: + | T + | { + name?: T; + legalName?: T; + description?: T; + logo?: T; + foundingDate?: T; + }; + contact?: + | T + | { + email?: T; + phone?: T; + fax?: T; + }; + address?: + | T + | { + street?: T; + postalCode?: T; + city?: T; + region?: T; + country?: T; + countryCode?: T; + }; + geo?: + | T + | { + latitude?: T; + longitude?: T; + }; + socialProfiles?: + | T + | { + platform?: T; + url?: T; + id?: T; + }; + localBusiness?: + | T + | { + enabled?: T; + type?: T; + priceRange?: T; + openingHours?: + | T + | { + specification?: T; + id?: T; + }; + }; + robots?: + | T + | { + allowIndexing?: T; + additionalDisallow?: T; + }; + verification?: + | T + | { + google?: T; + bing?: T; + yandex?: T; + }; + updatedAt?: T; + createdAt?: T; + globalType?: T; +} +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "auth". + */ +export interface Auth { + [k: string]: unknown; +} + + +declare module 'payload' { + export interface GeneratedTypes extends Config {} +} \ No newline at end of file diff --git a/src/types/blocks.ts b/src/types/blocks.ts index 55d3a24..fcd17bc 100644 --- a/src/types/blocks.ts +++ b/src/types/blocks.ts @@ -70,6 +70,13 @@ export const BLOCK_TYPES = [ 'series-detail-block', 'video-embed-block', 'featured-content-block', + 'checkbox', + 'email', + 'message', + 'number', + 'select', + 'text', + 'textarea', ] as const export type BlockType = typeof BLOCK_TYPES[number] diff --git a/src/types/payload-types.ts b/src/types/payload-types.ts index 6b64aac..b0918bb 100644 --- a/src/types/payload-types.ts +++ b/src/types/payload-types.ts @@ -850,9 +850,14 @@ export interface Page { blockType: 'cta-block'; } | { + /** + * Wählen Sie ein Formular aus der Formulare-Sammlung + */ + form: number | Form; headline?: string | null; description?: string | null; - recipientEmail?: string | null; + successMessage?: string | null; + showContactInfo?: boolean | null; showPhone?: boolean | null; showAddress?: boolean | null; showSocials?: boolean | null; @@ -3080,6 +3085,168 @@ export interface Page { updatedAt: string; createdAt: string; } +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "forms". + */ +export interface Form { + id: number; + title: string; + fields?: + | ( + | { + name: string; + label?: string | null; + width?: number | null; + required?: boolean | null; + defaultValue?: boolean | null; + id?: string | null; + blockName?: string | null; + blockType: 'checkbox'; + } + | { + name: string; + label?: string | null; + width?: number | null; + required?: boolean | null; + id?: string | null; + blockName?: string | null; + blockType: 'email'; + } + | { + message?: { + root: { + type: string; + children: { + type: any; + version: number; + [k: string]: unknown; + }[]; + direction: ('ltr' | 'rtl') | null; + format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | ''; + indent: number; + version: number; + }; + [k: string]: unknown; + } | null; + id?: string | null; + blockName?: string | null; + blockType: 'message'; + } + | { + name: string; + label?: string | null; + width?: number | null; + defaultValue?: number | null; + required?: boolean | null; + id?: string | null; + blockName?: string | null; + blockType: 'number'; + } + | { + name: string; + label?: string | null; + width?: number | null; + defaultValue?: string | null; + placeholder?: string | null; + options?: + | { + label: string; + value: string; + id?: string | null; + }[] + | null; + required?: boolean | null; + id?: string | null; + blockName?: string | null; + blockType: 'select'; + } + | { + name: string; + label?: string | null; + width?: number | null; + defaultValue?: string | null; + required?: boolean | null; + id?: string | null; + blockName?: string | null; + blockType: 'text'; + } + | { + name: string; + label?: string | null; + width?: number | null; + defaultValue?: string | null; + required?: boolean | null; + id?: string | null; + blockName?: string | null; + blockType: 'textarea'; + } + )[] + | null; + submitButtonLabel?: string | null; + /** + * Choose whether to display an on-page message or redirect to a different page after they submit the form. + */ + confirmationType?: ('message' | 'redirect') | null; + confirmationMessage?: { + root: { + type: string; + children: { + type: any; + version: number; + [k: string]: unknown; + }[]; + direction: ('ltr' | 'rtl') | null; + format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | ''; + indent: number; + version: number; + }; + [k: string]: unknown; + } | null; + redirect?: { + type?: ('reference' | 'custom') | null; + reference?: { + relationTo: 'pages'; + value: number | Page; + } | null; + url?: string | null; + }; + /** + * Send custom emails when the form submits. Use comma separated lists to send the same email to multiple recipients. To reference a value from this form, wrap that field's name with double curly brackets, i.e. {{firstName}}. You can use a wildcard {{*}} to output all data and {{*:table}} to format it as an HTML table in the email. + */ + emails?: + | { + emailTo?: string | null; + cc?: string | null; + bcc?: string | null; + replyTo?: string | null; + emailFrom?: string | null; + subject: string; + /** + * Enter the message that should be sent in this email. + */ + message?: { + root: { + type: string; + children: { + type: any; + version: number; + [k: string]: unknown; + }[]; + direction: ('ltr' | 'rtl') | null; + format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | ''; + indent: number; + version: number; + }; + [k: string]: unknown; + } | null; + id?: string | null; + }[] + | null; + tenant: number | Tenant; + updatedAt: string; + createdAt: string; +} /** * Video-Bibliothek für YouTube/Vimeo Embeds und hochgeladene Videos * @@ -4441,167 +4608,6 @@ export interface Job { updatedAt: string; createdAt: string; } -/** - * This interface was referenced by `Config`'s JSON-Schema - * via the `definition` "forms". - */ -export interface Form { - id: number; - title: string; - fields?: - | ( - | { - name: string; - label?: string | null; - width?: number | null; - required?: boolean | null; - defaultValue?: boolean | null; - id?: string | null; - blockName?: string | null; - blockType: 'checkbox'; - } - | { - name: string; - label?: string | null; - width?: number | null; - required?: boolean | null; - id?: string | null; - blockName?: string | null; - blockType: 'email'; - } - | { - message?: { - root: { - type: string; - children: { - type: any; - version: number; - [k: string]: unknown; - }[]; - direction: ('ltr' | 'rtl') | null; - format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | ''; - indent: number; - version: number; - }; - [k: string]: unknown; - } | null; - id?: string | null; - blockName?: string | null; - blockType: 'message'; - } - | { - name: string; - label?: string | null; - width?: number | null; - defaultValue?: number | null; - required?: boolean | null; - id?: string | null; - blockName?: string | null; - blockType: 'number'; - } - | { - name: string; - label?: string | null; - width?: number | null; - defaultValue?: string | null; - placeholder?: string | null; - options?: - | { - label: string; - value: string; - id?: string | null; - }[] - | null; - required?: boolean | null; - id?: string | null; - blockName?: string | null; - blockType: 'select'; - } - | { - name: string; - label?: string | null; - width?: number | null; - defaultValue?: string | null; - required?: boolean | null; - id?: string | null; - blockName?: string | null; - blockType: 'text'; - } - | { - name: string; - label?: string | null; - width?: number | null; - defaultValue?: string | null; - required?: boolean | null; - id?: string | null; - blockName?: string | null; - blockType: 'textarea'; - } - )[] - | null; - submitButtonLabel?: string | null; - /** - * Choose whether to display an on-page message or redirect to a different page after they submit the form. - */ - confirmationType?: ('message' | 'redirect') | null; - confirmationMessage?: { - root: { - type: string; - children: { - type: any; - version: number; - [k: string]: unknown; - }[]; - direction: ('ltr' | 'rtl') | null; - format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | ''; - indent: number; - version: number; - }; - [k: string]: unknown; - } | null; - redirect?: { - type?: ('reference' | 'custom') | null; - reference?: { - relationTo: 'pages'; - value: number | Page; - } | null; - url?: string | null; - }; - /** - * Send custom emails when the form submits. Use comma separated lists to send the same email to multiple recipients. To reference a value from this form, wrap that field's name with double curly brackets, i.e. {{firstName}}. You can use a wildcard {{*}} to output all data and {{*:table}} to format it as an HTML table in the email. - */ - emails?: - | { - emailTo?: string | null; - cc?: string | null; - bcc?: string | null; - replyTo?: string | null; - emailFrom?: string | null; - subject: string; - /** - * Enter the message that should be sent in this email. - */ - message?: { - root: { - type: string; - children: { - type: any; - version: number; - [k: string]: unknown; - }[]; - direction: ('ltr' | 'rtl') | null; - format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | ''; - indent: number; - version: number; - }; - [k: string]: unknown; - } | null; - id?: string | null; - }[] - | null; - updatedAt: string; - createdAt: string; -} /** * Produkte und Artikel * @@ -7563,6 +7569,24 @@ export interface MonitoringSnapshot { | number | boolean | null; + secrets?: + | { + [k: string]: unknown; + } + | unknown[] + | string + | number + | boolean + | null; + securityEvents?: + | { + [k: string]: unknown; + } + | unknown[] + | string + | number + | boolean + | null; }; /** * Performance-Metriken @@ -7586,7 +7610,7 @@ export interface MonitoringSnapshot { export interface MonitoringLog { id: number; level: 'debug' | 'info' | 'warn' | 'error' | 'fatal'; - source: 'payload' | 'queue-worker' | 'cron' | 'email' | 'oauth' | 'sync'; + source: 'payload' | 'queue-worker' | 'cron' | 'email' | 'oauth' | 'sync' | 'security'; message: string; /** * Strukturierte Metadaten @@ -8601,9 +8625,11 @@ export interface PagesSelect { 'contact-form-block'?: | T | { + form?: T; headline?: T; description?: T; - recipientEmail?: T; + successMessage?: T; + showContactInfo?: T; showPhone?: T; showAddress?: T; showSocials?: T; @@ -12584,6 +12610,8 @@ export interface MonitoringSnapshotsSelect { metaOAuth?: T; youtubeOAuth?: T; cronJobs?: T; + secrets?: T; + securityEvents?: T; }; performance?: | T @@ -12859,6 +12887,7 @@ export interface FormsSelect { message?: T; id?: T; }; + tenant?: T; updatedAt?: T; createdAt?: T; }