mirror of
https://github.com/complexcaresolutions/cms.c2sgmbh.git
synced 2026-03-18 00:24:10 +00:00
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>
287 lines
7.1 KiB
TypeScript
287 lines
7.1 KiB
TypeScript
import type { Block } from 'payload'
|
|
|
|
/**
|
|
* TableOfContentsBlock
|
|
*
|
|
* Automatisches Inhaltsverzeichnis für lange Blog-Posts.
|
|
* Extrahiert Überschriften aus dem Content und erstellt Navigation.
|
|
*/
|
|
export const TableOfContentsBlock: Block = {
|
|
slug: 'toc-block',
|
|
labels: {
|
|
singular: 'Inhaltsverzeichnis',
|
|
plural: 'Inhaltsverzeichnisse',
|
|
},
|
|
imageURL: '/assets/blocks/table-of-contents.png',
|
|
fields: [
|
|
{
|
|
name: 'title',
|
|
type: 'text',
|
|
label: 'Überschrift',
|
|
localized: true,
|
|
defaultValue: 'Inhaltsverzeichnis',
|
|
},
|
|
// Überschriften-Level
|
|
{
|
|
name: 'levels',
|
|
type: 'group',
|
|
label: 'Überschriften-Level',
|
|
admin: {
|
|
description: 'Welche Überschriften-Ebenen einschließen?',
|
|
},
|
|
fields: [
|
|
{
|
|
name: 'h2',
|
|
type: 'checkbox',
|
|
defaultValue: true,
|
|
label: 'H2',
|
|
},
|
|
{
|
|
name: 'h3',
|
|
type: 'checkbox',
|
|
defaultValue: true,
|
|
label: 'H3',
|
|
},
|
|
{
|
|
name: 'h4',
|
|
type: 'checkbox',
|
|
defaultValue: false,
|
|
label: 'H4',
|
|
},
|
|
{
|
|
name: 'h5',
|
|
type: 'checkbox',
|
|
defaultValue: false,
|
|
label: 'H5',
|
|
},
|
|
{
|
|
name: 'h6',
|
|
type: 'checkbox',
|
|
defaultValue: false,
|
|
label: 'H6',
|
|
},
|
|
],
|
|
},
|
|
// Layout
|
|
{
|
|
name: 'layout',
|
|
type: 'select',
|
|
defaultValue: 'list',
|
|
label: 'Layout',
|
|
options: [
|
|
{ label: 'Liste', value: 'list' },
|
|
{ label: 'Nummeriert', value: 'numbered' },
|
|
{ label: 'Kompakt (Inline)', value: 'inline' },
|
|
{ label: 'Sidebar (Sticky)', value: 'sidebar' },
|
|
{ label: 'Dropdown/Akkordeon', value: 'dropdown' },
|
|
],
|
|
},
|
|
{
|
|
name: 'sidebarPos',
|
|
type: 'select',
|
|
defaultValue: 'right',
|
|
label: 'Sidebar-Position',
|
|
options: [
|
|
{ label: 'Links', value: 'left' },
|
|
{ label: 'Rechts', value: 'right' },
|
|
],
|
|
admin: {
|
|
condition: (_, siblingData) => siblingData?.layout === 'sidebar',
|
|
},
|
|
},
|
|
// Verhalten
|
|
{
|
|
name: 'behavior',
|
|
type: 'group',
|
|
label: 'Verhalten',
|
|
fields: [
|
|
{
|
|
name: 'smoothScroll',
|
|
type: 'checkbox',
|
|
defaultValue: true,
|
|
label: 'Sanftes Scrollen',
|
|
},
|
|
{
|
|
name: 'highlightActive',
|
|
type: 'checkbox',
|
|
defaultValue: true,
|
|
label: 'Aktiven Abschnitt markieren',
|
|
admin: {
|
|
description: 'Markiert den aktuell sichtbaren Abschnitt',
|
|
},
|
|
},
|
|
{
|
|
name: 'scrollOffset',
|
|
type: 'number',
|
|
defaultValue: 80,
|
|
label: 'Scroll-Offset (px)',
|
|
admin: {
|
|
description: 'Abstand zum oberen Rand nach dem Scrollen (für Fixed Headers)',
|
|
},
|
|
},
|
|
{
|
|
name: 'collapsible',
|
|
type: 'checkbox',
|
|
defaultValue: false,
|
|
label: 'Einklappbar',
|
|
admin: {
|
|
description: 'User kann das Inhaltsverzeichnis ein-/ausklappen',
|
|
},
|
|
},
|
|
{
|
|
name: 'startCollapsed',
|
|
type: 'checkbox',
|
|
defaultValue: false,
|
|
label: 'Anfangs eingeklappt',
|
|
admin: {
|
|
condition: (_, siblingData) => siblingData?.collapsible,
|
|
},
|
|
},
|
|
{
|
|
name: 'showProgress',
|
|
type: 'checkbox',
|
|
defaultValue: false,
|
|
label: 'Lesefortschritt anzeigen',
|
|
admin: {
|
|
description: 'Fortschrittsbalken oder Prozent-Anzeige',
|
|
},
|
|
},
|
|
{
|
|
name: 'progressStyle',
|
|
type: 'select',
|
|
defaultValue: 'bar',
|
|
label: 'Fortschritts-Stil',
|
|
options: [
|
|
{ label: 'Balken', value: 'bar' },
|
|
{ label: 'Prozent', value: 'percent' },
|
|
{ label: 'Kreis', value: 'circle' },
|
|
],
|
|
admin: {
|
|
condition: (_, siblingData) => siblingData?.showProgress,
|
|
},
|
|
},
|
|
],
|
|
},
|
|
// Styling
|
|
{
|
|
name: 'style',
|
|
type: 'group',
|
|
label: 'Darstellung',
|
|
fields: [
|
|
{
|
|
name: 'bg',
|
|
type: 'select',
|
|
defaultValue: 'light',
|
|
label: 'Hintergrund',
|
|
options: [
|
|
{ label: 'Keiner', value: 'none' },
|
|
{ label: 'Hell', value: 'light' },
|
|
{ label: 'Dunkel', value: 'dark' },
|
|
{ label: 'Akzent', value: 'accent' },
|
|
],
|
|
},
|
|
{
|
|
name: 'border',
|
|
type: 'checkbox',
|
|
defaultValue: true,
|
|
label: 'Rahmen',
|
|
},
|
|
{
|
|
name: 'borderSide',
|
|
type: 'select',
|
|
defaultValue: 'left',
|
|
label: 'Rahmen-Seite',
|
|
options: [
|
|
{ label: 'Alle', value: 'all' },
|
|
{ label: 'Links', value: 'left' },
|
|
{ label: 'Oben', value: 'top' },
|
|
],
|
|
admin: {
|
|
condition: (_, siblingData) => siblingData?.border,
|
|
},
|
|
},
|
|
{
|
|
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: 'indent',
|
|
type: 'checkbox',
|
|
defaultValue: true,
|
|
label: 'Sub-Überschriften einrücken',
|
|
},
|
|
{
|
|
name: 'showIcon',
|
|
type: 'checkbox',
|
|
defaultValue: false,
|
|
label: 'Icons anzeigen',
|
|
admin: {
|
|
description: 'Link-Symbol neben Einträgen',
|
|
},
|
|
},
|
|
{
|
|
name: 'fontSize',
|
|
type: 'select',
|
|
defaultValue: 'sm',
|
|
label: 'Schriftgröße',
|
|
options: [
|
|
{ label: 'Klein', value: 'sm' },
|
|
{ label: 'Normal', value: 'base' },
|
|
{ label: 'Groß', value: 'lg' },
|
|
],
|
|
},
|
|
{
|
|
name: 'lineHeight',
|
|
type: 'select',
|
|
defaultValue: 'relaxed',
|
|
label: 'Zeilenhöhe',
|
|
options: [
|
|
{ label: 'Eng', value: 'tight' },
|
|
{ label: 'Normal', value: 'normal' },
|
|
{ label: 'Locker', value: 'relaxed' },
|
|
],
|
|
},
|
|
],
|
|
},
|
|
// Limits
|
|
{
|
|
name: 'minItems',
|
|
type: 'number',
|
|
defaultValue: 3,
|
|
label: 'Mindestanzahl',
|
|
admin: {
|
|
description: 'Inhaltsverzeichnis nur anzeigen, wenn mindestens X Einträge',
|
|
},
|
|
},
|
|
{
|
|
name: 'maxItems',
|
|
type: 'number',
|
|
label: 'Maximalanzahl',
|
|
admin: {
|
|
description: 'Maximale Anzahl angezeigter Einträge (0 = unbegrenzt)',
|
|
},
|
|
},
|
|
// Accessibility
|
|
{
|
|
name: 'a11yLabel',
|
|
type: 'text',
|
|
label: 'ARIA Label',
|
|
localized: true,
|
|
defaultValue: 'Inhaltsverzeichnis',
|
|
},
|
|
],
|
|
}
|