frontend.porwoll.de/src/components/blocks/index.tsx
CCS Admin 2e8d34d917 feat: apply Definity Template design system
- Tailwind v4 theme config with Definity colors (accent #2CAADF, dark #111)
- Montserrat + Open Sans font setup via next/font/google
- UI components: Button (6 variants), Container, SectionHeader
- Navigation with transparent-to-solid scroll behavior
- Footer with social links, widgets, copyright bar
- Block components: Hero, Text, CardGrid, Quote, ImageText, CTA,
  ContactForm, Timeline, Divider
- Typography system with prose styles for rich text
- Animation library with framer-motion variants
- Page transitions via template.tsx
- cn() utility (clsx + tailwind-merge)
- Updated API layer with getSocialLinks

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 11:06:05 +00:00

71 lines
2.1 KiB
TypeScript

/**
* Block Renderer for porwoll.de
*
* Maps CMS block types to Definity Template components.
* Uses @c2s/payload-contracts Block type for type safety.
*/
import type { Block } from '@c2s/payload-contracts/types'
// Definity Design System Blocks
import { HeroBlock } from './HeroBlock'
import { TextBlock } from './TextBlock'
import { ImageTextBlock } from './ImageTextBlock'
import { CardGridBlock } from './CardGridBlock'
import { CTABlock } from './CTABlock'
import { DividerBlock } from './DividerBlock'
import { QuoteBlock } from './QuoteBlock'
import { ContactFormBlock } from './ContactFormBlock'
import { TimelineBlock } from './TimelineBlock'
// Block component registry
const blockComponents: Record<string, React.ComponentType<{ block: Record<string, unknown> }>> = {
'hero-block': HeroBlock,
'text-block': TextBlock,
'image-text-block': ImageTextBlock,
'card-grid-block': CardGridBlock,
'cta-block': CTABlock,
'divider-block': DividerBlock,
'quote-block': QuoteBlock,
'contact-form-block': ContactFormBlock,
'timeline-block': TimelineBlock,
}
// Placeholder for blocks not yet implemented
function PlaceholderBlock({ block }: { block: Record<string, unknown> }) {
if (process.env.NODE_ENV === 'development') {
return (
<div className="py-ws-s bg-light-bg border border-dashed border-light">
<div className="max-w-[1200px] mx-auto px-4 text-center">
<p className="font-heading text-[0.85em] tracking-[2px] uppercase text-gray-light">
Block: {block.blockType as string}
</p>
</div>
</div>
)
}
return null
}
interface BlockRendererProps {
blocks: Block[]
}
export function BlockRenderer({ blocks }: BlockRendererProps) {
if (!blocks || blocks.length === 0) return null
return (
<>
{blocks.map((block, index) => {
const blockType = block.blockType
const Component = blockComponents[blockType] || PlaceholderBlock
return (
<Component
key={block.id || `block-${index}`}
block={block as unknown as Record<string, unknown>}
/>
)
})}
</>
)
}