cms.c2sgmbh/src/blocks/RelatedPostsBlock.ts
Martin Porwoll 2b097eefb3 feat: add comprehensive blogging and team features
Blogging Collections:
- Tags Collection with name, slug, description, color
- Authors Collection with avatar, bio, social media links

Posts Collection extended:
- Tags and Author relationships
- Co-Authors support
- Automatic reading time calculation
- Legacy author text field fallback

New Blogging Blocks:
- AuthorBioBlock: Display author info with various layouts
- RelatedPostsBlock: Show related articles (auto/manual/category/tag)
- ShareButtonsBlock: Social sharing (Facebook, Twitter, LinkedIn, etc.)
- TableOfContentsBlock: Auto-generated TOC from headings

Team Collection extended:
- Slug field for profile pages (auto-generated)
- Hierarchy fields (reportsTo, hierarchyLevel) for org charts
- vCard export flag

New Team API Endpoints:
- GET /api/team - List with search and filters
- GET /api/team/[slug]/vcard - vCard download (VCF)

New Team Blocks:
- TeamFilterBlock: Interactive team display with search/filter
- OrgChartBlock: Hierarchical organization chart visualization

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-13 21:49:13 +00:00

263 lines
6.5 KiB
TypeScript

import type { Block } from 'payload'
/**
* RelatedPostsBlock
*
* Zeigt verwandte Artikel an, basierend auf Kategorien, Tags
* oder manueller Auswahl.
*/
export const RelatedPostsBlock: Block = {
slug: 'related-posts-block',
labels: {
singular: 'Ähnliche Artikel',
plural: 'Ähnliche Artikel',
},
imageURL: '/assets/blocks/related-posts.png',
fields: [
{
name: 'title',
type: 'text',
label: 'Überschrift',
localized: true,
defaultValue: 'Das könnte Sie auch interessieren',
},
{
name: 'source',
type: 'select',
defaultValue: 'auto',
label: 'Artikel-Quelle',
options: [
{ label: 'Automatisch (Kategorien/Tags)', value: 'auto' },
{ label: 'Manuell auswählen', value: 'manual' },
{ label: 'Nach Kategorie', value: 'category' },
{ label: 'Nach Tag', value: 'tag' },
{ label: 'Neueste Artikel', value: 'latest' },
{ label: 'Beliebteste Artikel', value: 'popular' },
{ label: 'Vom gleichen Autor', value: 'author' },
],
},
{
name: 'posts',
type: 'relationship',
relationTo: 'posts',
hasMany: true,
label: 'Artikel',
admin: {
condition: (_, siblingData) => siblingData?.source === 'manual',
description: 'Wählen Sie die anzuzeigenden Artikel',
},
},
{
name: 'category',
type: 'relationship',
relationTo: 'categories',
label: 'Kategorie',
admin: {
condition: (_, siblingData) => siblingData?.source === 'category',
},
},
{
name: 'tag',
type: 'relationship',
relationTo: 'tags',
label: 'Tag',
admin: {
condition: (_, siblingData) => siblingData?.source === 'tag',
},
},
{
name: 'limit',
type: 'number',
defaultValue: 3,
min: 1,
max: 12,
label: 'Anzahl Artikel',
},
{
name: 'excludeCurrent',
type: 'checkbox',
defaultValue: true,
label: 'Aktuellen Artikel ausschließen',
admin: {
description: 'Den Artikel, auf dem dieser Block ist, nicht anzeigen',
},
},
// Layout
{
name: 'layout',
type: 'select',
defaultValue: 'grid',
label: 'Layout',
options: [
{ label: 'Grid', value: 'grid' },
{ label: 'Liste', value: 'list' },
{ label: 'Slider', value: 'slider' },
{ label: 'Kompakt', value: 'compact' },
{ label: 'Cards', value: 'cards' },
],
},
{
name: 'cols',
type: 'select',
defaultValue: '3',
label: 'Spalten',
options: [
{ label: '2 Spalten', value: '2' },
{ label: '3 Spalten', value: '3' },
{ label: '4 Spalten', value: '4' },
],
admin: {
condition: (_, siblingData) =>
siblingData?.layout === 'grid' || siblingData?.layout === 'cards',
},
},
// Anzuzeigende Elemente
{
name: 'show',
type: 'group',
label: 'Anzeigen',
fields: [
{
name: 'image',
type: 'checkbox',
defaultValue: true,
label: 'Beitragsbild',
},
{
name: 'date',
type: 'checkbox',
defaultValue: true,
label: 'Datum',
},
{
name: 'author',
type: 'checkbox',
defaultValue: false,
label: 'Autor',
},
{
name: 'category',
type: 'checkbox',
defaultValue: true,
label: 'Kategorie',
},
{
name: 'excerpt',
type: 'checkbox',
defaultValue: true,
label: 'Kurzfassung',
},
{
name: 'readingTime',
type: 'checkbox',
defaultValue: false,
label: 'Lesezeit',
},
{
name: 'tags',
type: 'checkbox',
defaultValue: false,
label: 'Tags',
},
],
},
// Styling
{
name: 'style',
type: 'group',
label: 'Darstellung',
fields: [
{
name: 'imgRatio',
type: 'select',
defaultValue: '16-9',
label: 'Bild-Verhältnis',
options: [
{ label: 'Quadratisch (1:1)', value: 'square' },
{ label: 'Querformat (4:3)', value: '4-3' },
{ label: 'Breit (16:9)', value: '16-9' },
{ label: 'Hochformat (3:4)', value: '3-4' },
],
},
{
name: 'rounded',
type: 'select',
defaultValue: 'md',
label: 'Ecken',
options: [
{ label: 'Keine', value: 'none' },
{ label: 'Klein', value: 'sm' },
{ label: 'Mittel', value: 'md' },
{ label: 'Groß', value: 'lg' },
],
},
{
name: 'shadow',
type: 'checkbox',
defaultValue: false,
label: 'Schatten',
},
{
name: 'hover',
type: 'select',
defaultValue: 'lift',
label: 'Hover-Effekt',
options: [
{ label: 'Keiner', value: 'none' },
{ label: 'Anheben', value: 'lift' },
{ label: 'Zoom', value: 'zoom' },
{ label: 'Overlay', value: 'overlay' },
],
},
{
name: 'bg',
type: 'select',
defaultValue: 'none',
label: 'Hintergrund',
options: [
{ label: 'Keiner', value: 'none' },
{ label: 'Hell', value: 'light' },
{ label: 'Dunkel', value: 'dark' },
],
},
{
name: 'gap',
type: 'select',
defaultValue: '24',
label: 'Abstand',
options: [
{ label: 'Klein (16px)', value: '16' },
{ label: 'Normal (24px)', value: '24' },
{ label: 'Groß (32px)', value: '32' },
],
},
],
},
// CTA
{
name: 'showAllLink',
type: 'checkbox',
defaultValue: false,
label: '"Alle anzeigen" Link',
},
{
name: 'allLinkText',
type: 'text',
label: 'Link-Text',
localized: true,
defaultValue: 'Alle Artikel anzeigen',
admin: {
condition: (_, siblingData) => siblingData?.showAllLink,
},
},
{
name: 'allLinkUrl',
type: 'text',
label: 'Link-URL',
admin: {
condition: (_, siblingData) => siblingData?.showAllLink,
description: 'z.B. /blog oder /news',
},
},
],
}