mirror of
https://github.com/complexcaresolutions/cms.c2sgmbh.git
synced 2026-03-17 23:14:12 +00:00
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>
274 lines
6.3 KiB
TypeScript
274 lines
6.3 KiB
TypeScript
import type { CollectionConfig } from 'payload'
|
|
import { authenticatedOnly, tenantScopedPublicRead } from '../lib/tenantAccess'
|
|
|
|
/**
|
|
* Partners Collection
|
|
*
|
|
* Partner, Kunden, Zertifizierungen und Referenzen mit Logos.
|
|
* Vielseitig einsetzbar für Logo-Walls, Referenzen, Zertifikate.
|
|
*/
|
|
export const Partners: CollectionConfig = {
|
|
slug: 'partners',
|
|
labels: {
|
|
singular: 'Partner',
|
|
plural: 'Partner',
|
|
},
|
|
admin: {
|
|
useAsTitle: 'name',
|
|
group: 'Content',
|
|
defaultColumns: ['name', 'type', 'isFeatured', 'isActive', 'order'],
|
|
description: 'Partner, Kunden, Referenzen und Zertifizierungen',
|
|
},
|
|
access: {
|
|
read: tenantScopedPublicRead,
|
|
create: authenticatedOnly,
|
|
update: authenticatedOnly,
|
|
delete: authenticatedOnly,
|
|
},
|
|
fields: [
|
|
{
|
|
name: 'name',
|
|
type: 'text',
|
|
required: true,
|
|
label: 'Name',
|
|
admin: {
|
|
description: 'Firmen-/Partnername',
|
|
},
|
|
},
|
|
{
|
|
name: 'slug',
|
|
type: 'text',
|
|
required: true,
|
|
unique: true,
|
|
label: 'Slug',
|
|
},
|
|
{
|
|
name: 'type',
|
|
type: 'select',
|
|
required: true,
|
|
defaultValue: 'partner',
|
|
label: 'Typ',
|
|
options: [
|
|
{ label: 'Partner', value: 'partner' },
|
|
{ label: 'Kunde', value: 'client' },
|
|
{ label: 'Referenz', value: 'reference' },
|
|
{ label: 'Sponsor', value: 'sponsor' },
|
|
{ label: 'Zertifizierung', value: 'certification' },
|
|
{ label: 'Mitgliedschaft', value: 'membership' },
|
|
{ label: 'Auszeichnung', value: 'award' },
|
|
{ label: 'Lieferant', value: 'supplier' },
|
|
{ label: 'Technologie', value: 'technology' },
|
|
],
|
|
admin: {
|
|
position: 'sidebar',
|
|
},
|
|
},
|
|
{
|
|
name: 'logo',
|
|
type: 'upload',
|
|
relationTo: 'media',
|
|
required: true,
|
|
label: 'Logo',
|
|
admin: {
|
|
description: 'Logo (empfohlen: SVG oder PNG mit transparentem Hintergrund)',
|
|
},
|
|
},
|
|
{
|
|
name: 'logoLight',
|
|
type: 'upload',
|
|
relationTo: 'media',
|
|
label: 'Logo (Hell)',
|
|
admin: {
|
|
description: 'Alternative Version für dunkle Hintergründe',
|
|
},
|
|
},
|
|
{
|
|
name: 'description',
|
|
type: 'textarea',
|
|
label: 'Beschreibung',
|
|
localized: true,
|
|
admin: {
|
|
description: 'Kurze Beschreibung der Partnerschaft',
|
|
},
|
|
},
|
|
{
|
|
name: 'website',
|
|
type: 'text',
|
|
label: 'Website',
|
|
},
|
|
// Für Referenzen/Case Studies
|
|
{
|
|
name: 'caseStudy',
|
|
type: 'group',
|
|
label: 'Case Study / Referenz',
|
|
admin: {
|
|
condition: (_, siblingData) =>
|
|
siblingData?.type === 'client' || siblingData?.type === 'reference',
|
|
},
|
|
fields: [
|
|
{
|
|
name: 'quote',
|
|
type: 'textarea',
|
|
label: 'Zitat',
|
|
localized: true,
|
|
},
|
|
{
|
|
name: 'quotePerson',
|
|
type: 'text',
|
|
label: 'Zitatgeber',
|
|
},
|
|
{
|
|
name: 'quoteRole',
|
|
type: 'text',
|
|
label: 'Position',
|
|
},
|
|
{
|
|
name: 'projectDescription',
|
|
type: 'richText',
|
|
label: 'Projektbeschreibung',
|
|
localized: true,
|
|
},
|
|
{
|
|
name: 'results',
|
|
type: 'array',
|
|
label: 'Ergebnisse/Kennzahlen',
|
|
fields: [
|
|
{
|
|
name: 'metric',
|
|
type: 'text',
|
|
required: true,
|
|
label: 'Kennzahl',
|
|
admin: {
|
|
description: 'z.B. "+50%", "10.000+"',
|
|
},
|
|
},
|
|
{
|
|
name: 'label',
|
|
type: 'text',
|
|
required: true,
|
|
label: 'Beschreibung',
|
|
localized: true,
|
|
admin: {
|
|
description: 'z.B. "Umsatzsteigerung", "Neue Kunden"',
|
|
},
|
|
},
|
|
],
|
|
},
|
|
],
|
|
},
|
|
// Für Zertifizierungen
|
|
{
|
|
name: 'certification',
|
|
type: 'group',
|
|
label: 'Zertifizierungs-Details',
|
|
admin: {
|
|
condition: (_, siblingData) =>
|
|
siblingData?.type === 'certification' ||
|
|
siblingData?.type === 'membership' ||
|
|
siblingData?.type === 'award',
|
|
},
|
|
fields: [
|
|
{
|
|
name: 'issuer',
|
|
type: 'text',
|
|
label: 'Aussteller',
|
|
},
|
|
{
|
|
name: 'validFrom',
|
|
type: 'date',
|
|
label: 'Gültig ab',
|
|
},
|
|
{
|
|
name: 'validUntil',
|
|
type: 'date',
|
|
label: 'Gültig bis',
|
|
},
|
|
{
|
|
name: 'certNumber',
|
|
type: 'text',
|
|
label: 'Zertifikatsnummer',
|
|
},
|
|
{
|
|
name: 'document',
|
|
type: 'upload',
|
|
relationTo: 'media',
|
|
label: 'Zertifikat (PDF)',
|
|
},
|
|
],
|
|
},
|
|
// Kategorisierung
|
|
{
|
|
name: 'category',
|
|
type: 'text',
|
|
label: 'Kategorie',
|
|
admin: {
|
|
description: 'z.B. "Technologie", "Finanzen", "Pflege"',
|
|
},
|
|
},
|
|
{
|
|
name: 'tags',
|
|
type: 'array',
|
|
label: 'Tags',
|
|
fields: [
|
|
{
|
|
name: 'tag',
|
|
type: 'text',
|
|
required: true,
|
|
},
|
|
],
|
|
},
|
|
// Status
|
|
{
|
|
name: 'isFeatured',
|
|
type: 'checkbox',
|
|
defaultValue: false,
|
|
label: 'Hervorgehoben',
|
|
admin: {
|
|
position: 'sidebar',
|
|
},
|
|
},
|
|
{
|
|
name: 'isActive',
|
|
type: 'checkbox',
|
|
defaultValue: true,
|
|
label: 'Aktiv',
|
|
admin: {
|
|
position: 'sidebar',
|
|
},
|
|
},
|
|
{
|
|
name: 'order',
|
|
type: 'number',
|
|
defaultValue: 0,
|
|
label: 'Sortierung',
|
|
admin: {
|
|
position: 'sidebar',
|
|
},
|
|
},
|
|
{
|
|
name: 'since',
|
|
type: 'date',
|
|
label: 'Partner seit',
|
|
admin: {
|
|
position: 'sidebar',
|
|
},
|
|
},
|
|
],
|
|
hooks: {
|
|
beforeChange: [
|
|
({ data }) => {
|
|
if (data && !data.slug && data.name) {
|
|
data.slug = data.name
|
|
.toLowerCase()
|
|
.replace(/[äöüß]/g, (match: string) => {
|
|
const map: Record<string, string> = { ä: 'ae', ö: 'oe', ü: 'ue', ß: 'ss' }
|
|
return map[match] || match
|
|
})
|
|
.replace(/[^a-z0-9]+/g, '-')
|
|
.replace(/^-|-$/g, '')
|
|
}
|
|
return data
|
|
},
|
|
],
|
|
},
|
|
}
|