cms.c2sgmbh/src/blocks/LocationsBlock.ts
Martin Porwoll 9e5c741941 feat: add priority collections and advanced content blocks
New Collections:
- Events: Veranstaltungen mit Datum, Ort, Registrierung
- Jobs: Stellenangebote mit Standort und Bewerbungsfrist
- Locations: Standorte mit Adresse, Kontakt, Öffnungszeiten
- Partners: Partner/Kunden mit Logo und Beschreibung
- Downloads: Dateien mit Kategorisierung und Tracking

New Blocks:
- EventsBlock: Veranstaltungslisten mit Kalender-Ansicht
- JobsBlock: Stellenanzeigen mit Filterfunktion
- LocationsBlock: Standort-Karten und Listen
- PricingBlock: Preistabellen mit Feature-Vergleich
- TabsBlock: Tabbed Content mit verschiedenen Stilen
- AccordionBlock: FAQ/Accordion mit Animationen
- ComparisonBlock: Vergleichstabellen (Tabelle, Karten, Pro/Contra)
- StatsBlock: Statistiken mit Counter-Animation
- LogoGridBlock: Logo-Wolken und Partner-Galerien
- MapBlock: Interaktive Karten mit Markern
- DownloadsBlock: Download-Listen mit Kategorien

All collections support multi-tenant isolation and localization.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-14 00:58:30 +00:00

386 lines
9.8 KiB
TypeScript

import type { Block } from 'payload'
/**
* LocationsBlock
*
* Zeigt Firmenstandorte mit Karte, Adresse, Öffnungszeiten und Kontaktdaten.
* Unterstützt verschiedene Layouts und Kartenanbieter.
*/
export const LocationsBlock: Block = {
slug: 'locations-block',
labels: {
singular: 'Standorte',
plural: 'Standorte',
},
imageURL: '/assets/blocks/locations.png',
fields: [
{
name: 'title',
type: 'text',
label: 'Überschrift',
localized: true,
defaultValue: 'Unsere Standorte',
},
{
name: 'subtitle',
type: 'textarea',
label: 'Untertitel',
localized: true,
},
// Datenquelle
{
name: 'source',
type: 'select',
defaultValue: 'all',
label: 'Standorte',
options: [
{ label: 'Alle aktiven Standorte', value: 'all' },
{ label: 'Nur Hauptstandort', value: 'main' },
{ label: 'Nach Typ', value: 'type' },
{ label: 'Manuell auswählen', value: 'manual' },
],
},
{
name: 'locationType',
type: 'select',
label: 'Standort-Typ',
options: [
{ label: 'Hauptsitz', value: 'headquarters' },
{ label: 'Büro', value: 'office' },
{ label: 'Filiale', value: 'branch' },
{ label: 'Lager', value: 'warehouse' },
{ label: 'Showroom', value: 'showroom' },
{ label: 'Studio', value: 'studio' },
{ label: 'Praxis', value: 'practice' },
{ label: 'Werkstatt', value: 'workshop' },
],
admin: {
condition: (_, siblingData) => siblingData?.source === 'type',
},
},
{
name: 'selectedLocations',
type: 'relationship',
relationTo: 'locations',
hasMany: true,
label: 'Standorte auswählen',
admin: {
condition: (_, siblingData) => siblingData?.source === 'manual',
},
},
// Layout
{
name: 'layout',
type: 'select',
defaultValue: 'map-list',
label: 'Layout',
options: [
{ label: 'Karte + Liste', value: 'map-list' },
{ label: 'Nur Karte', value: 'map-only' },
{ label: 'Nur Liste', value: 'list-only' },
{ label: 'Karten-Grid', value: 'cards' },
{ label: 'Akkordeon', value: 'accordion' },
{ label: 'Tabs', value: 'tabs' },
],
},
{
name: 'mapPosition',
type: 'select',
defaultValue: 'left',
label: 'Karten-Position',
options: [
{ label: 'Links', value: 'left' },
{ label: 'Rechts', value: 'right' },
{ label: 'Oben', value: 'top' },
{ label: 'Unten', value: 'bottom' },
],
admin: {
condition: (_, siblingData) => siblingData?.layout === 'map-list',
},
},
{
name: 'columns',
type: 'select',
defaultValue: '2',
label: 'Spalten',
options: [
{ label: '1 Spalte', value: '1' },
{ label: '2 Spalten', value: '2' },
{ label: '3 Spalten', value: '3' },
],
admin: {
condition: (_, siblingData) => siblingData?.layout === 'cards',
},
},
// Karten-Einstellungen
{
name: 'map',
type: 'group',
label: 'Karten-Einstellungen',
admin: {
condition: (_, siblingData) =>
siblingData?.layout === 'map-list' || siblingData?.layout === 'map-only',
},
fields: [
{
name: 'provider',
type: 'select',
defaultValue: 'osm',
label: 'Kartenanbieter',
options: [
{ label: 'OpenStreetMap', value: 'osm' },
{ label: 'Google Maps', value: 'google' },
{ label: 'Mapbox', value: 'mapbox' },
],
},
{
name: 'style',
type: 'select',
defaultValue: 'default',
label: 'Kartenstil',
options: [
{ label: 'Standard', value: 'default' },
{ label: 'Hell', value: 'light' },
{ label: 'Dunkel', value: 'dark' },
{ label: 'Satellite', value: 'satellite' },
],
},
{
name: 'height',
type: 'select',
defaultValue: '400',
label: 'Höhe',
options: [
{ label: 'Klein (300px)', value: '300' },
{ label: 'Mittel (400px)', value: '400' },
{ label: 'Groß (500px)', value: '500' },
{ label: 'Sehr groß (600px)', value: '600' },
],
},
{
name: 'defaultZoom',
type: 'number',
defaultValue: 12,
min: 1,
max: 20,
label: 'Standard-Zoom',
},
{
name: 'fitBounds',
type: 'checkbox',
defaultValue: true,
label: 'Alle Marker zeigen',
admin: {
description: 'Karte automatisch anpassen, um alle Standorte zu zeigen',
},
},
{
name: 'markerStyle',
type: 'select',
defaultValue: 'pin',
label: 'Marker-Stil',
options: [
{ label: 'Pin', value: 'pin' },
{ label: 'Punkt', value: 'dot' },
{ label: 'Icon', value: 'icon' },
{ label: 'Custom', value: 'custom' },
],
},
{
name: 'markerColor',
type: 'text',
label: 'Marker-Farbe',
defaultValue: '#e11d48',
admin: {
description: 'Hex-Farbe (z.B. #e11d48)',
},
},
{
name: 'clustering',
type: 'checkbox',
defaultValue: true,
label: 'Marker clustern',
admin: {
description: 'Nahe Marker zu Gruppen zusammenfassen',
},
},
{
name: 'controls',
type: 'group',
label: 'Steuerung',
fields: [
{
name: 'zoom',
type: 'checkbox',
defaultValue: true,
label: 'Zoom-Buttons',
},
{
name: 'fullscreen',
type: 'checkbox',
defaultValue: true,
label: 'Vollbild-Button',
},
{
name: 'scrollZoom',
type: 'checkbox',
defaultValue: false,
label: 'Scroll-Zoom',
},
{
name: 'dragging',
type: 'checkbox',
defaultValue: true,
label: 'Verschiebbar',
},
],
},
],
},
// Anzuzeigende Informationen
{
name: 'show',
type: 'group',
label: 'Anzeigen',
fields: [
{
name: 'image',
type: 'checkbox',
defaultValue: true,
label: 'Bild',
},
{
name: 'type',
type: 'checkbox',
defaultValue: false,
label: 'Standort-Typ',
},
{
name: 'address',
type: 'checkbox',
defaultValue: true,
label: 'Adresse',
},
{
name: 'phone',
type: 'checkbox',
defaultValue: true,
label: 'Telefon',
},
{
name: 'email',
type: 'checkbox',
defaultValue: true,
label: 'E-Mail',
},
{
name: 'hours',
type: 'checkbox',
defaultValue: true,
label: 'Öffnungszeiten',
},
{
name: 'directions',
type: 'checkbox',
defaultValue: false,
label: 'Anfahrt',
},
{
name: 'services',
type: 'checkbox',
defaultValue: false,
label: 'Services',
},
{
name: 'team',
type: 'checkbox',
defaultValue: false,
label: 'Team-Mitglieder',
},
],
},
// Aktionen
{
name: 'actions',
type: 'group',
label: 'Aktionen',
fields: [
{
name: 'showDirectionsLink',
type: 'checkbox',
defaultValue: true,
label: '"Route planen" Link',
},
{
name: 'showCallButton',
type: 'checkbox',
defaultValue: true,
label: 'Anruf-Button (mobil)',
},
{
name: 'showEmailButton',
type: 'checkbox',
defaultValue: false,
label: 'E-Mail-Button',
},
{
name: 'showDetailLink',
type: 'checkbox',
defaultValue: false,
label: 'Link zur Detail-Seite',
},
{
name: 'detailBasePath',
type: 'text',
label: 'Detail-Basis-Pfad',
defaultValue: '/standorte',
admin: {
condition: (_, siblingData) => siblingData?.showDetailLink,
},
},
],
},
// Styling
{
name: 'style',
type: 'group',
label: 'Darstellung',
fields: [
{
name: 'bg',
type: 'select',
defaultValue: 'none',
label: 'Hintergrund',
options: [
{ label: 'Keiner', value: 'none' },
{ label: 'Hell', value: 'light' },
{ label: 'Dunkel', value: 'dark' },
],
},
{
name: 'cardStyle',
type: 'select',
defaultValue: 'bordered',
label: 'Karten-Stil',
options: [
{ label: 'Einfach', value: 'simple' },
{ label: 'Mit Rahmen', value: 'bordered' },
{ label: 'Mit Schatten', value: 'shadow' },
{ label: 'Gefüllt', value: 'filled' },
],
},
{
name: 'gap',
type: 'select',
defaultValue: '24',
label: 'Abstand',
options: [
{ label: 'Klein (16px)', value: '16' },
{ label: 'Normal (24px)', value: '24' },
{ label: 'Groß (32px)', value: '32' },
],
},
],
},
],
}