frontend.zweitmeinu.ng/src/components/blocks/CardGridBlock.tsx
CCS Admin 728de20157 feat: convert 5 static pages to CMS-driven blocks
Replace hardcoded motivation, so-funktionierts, ueber-uns, impressum,
and datenschutz pages with CMS-driven content via BlockRenderer.
Add block components: HeroBlock, TextBlock, CardGridBlock, CTABlock,
ProcessStepsBlock, QuoteBlock, HtmlEmbedBlock.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 15:44:23 +00:00

51 lines
1.7 KiB
TypeScript

import { Container } from "@/components/ui/Container"
import { getLucideIcon } from "@/lib/icon-map"
/* eslint-disable @typescript-eslint/no-explicit-any */
interface CardGridBlockProps {
block: any
}
const columnClasses: Record<string, string> = {
"2": "grid-cols-1 sm:grid-cols-2",
"3": "grid-cols-1 sm:grid-cols-2 lg:grid-cols-3",
"4": "grid-cols-1 sm:grid-cols-2 lg:grid-cols-4",
}
export function CardGridBlock({ block }: CardGridBlockProps) {
const cols = block.columns || "3"
const cards = block.cards || []
return (
<section className="py-16 bg-bg">
<Container>
{block.headline && (
<h2 className="text-2xl sm:text-3xl font-bold text-center text-navy mb-12">
{block.headline}
</h2>
)}
<div className={`grid ${columnClasses[cols] || columnClasses["3"]} gap-6`}>
{cards.map((card: any, i: number) => {
const Icon = card.mediaType === "icon" && card.icon
? getLucideIcon(card.icon)
: null
return (
<div key={card.id || i} className="bg-white rounded-xl p-6 text-center border border-border">
{Icon && (
<div className="inline-flex items-center justify-center w-12 h-12 rounded-xl bg-primary/10 text-primary mb-4">
<Icon className="h-6 w-6" />
</div>
)}
<h3 className="font-bold text-navy mb-2">{card.title}</h3>
{card.description && (
<p className="text-text-muted text-sm">{card.description}</p>
)}
</div>
)
})}
</div>
</Container>
</section>
)
}