wwwfiberdirekt/src/blocks/FDCardGridBlock/Component.tsx

171 lines
5.8 KiB
TypeScript

import React from 'react'
import type { FDCardGridBlock as FDCardGridBlockProps } from '@/payload-types'
const cardStyleMap: Record<
string,
{ bg: string; headingText: string; bodyText: string; linkText: string; border: string }
> = {
navy: {
bg: 'bg-fd-navy dark:bg-white/10',
headingText: 'text-fd-yellow',
bodyText: 'text-white',
linkText: 'text-fd-yellow hover:text-fd-yellow/80',
border: '',
},
gray: {
bg: 'bg-fd-gray-light dark:bg-white/10',
headingText: 'text-fd-navy dark:text-fd-yellow',
bodyText: 'text-fd-navy dark:text-white',
linkText: 'text-fd-navy hover:text-fd-navy/70 dark:text-fd-yellow dark:hover:text-fd-yellow/80',
border: '',
},
yellow: {
bg: 'bg-fd-yellow',
headingText: 'text-fd-navy',
bodyText: 'text-fd-navy',
linkText: 'text-fd-navy hover:text-fd-navy/70',
border: '',
},
green: {
/* Priority #9: Was bg-[#4ADE80] (Tailwind default) — now uses brand mint */
bg: 'bg-fd-mint',
headingText: 'text-fd-navy',
bodyText: 'text-fd-navy',
linkText: 'text-fd-navy hover:text-fd-navy/70',
border: '',
},
outlined: {
bg: 'bg-white dark:bg-white/10',
headingText: 'text-fd-navy dark:text-fd-yellow',
bodyText: 'text-fd-navy dark:text-white',
linkText: 'text-fd-navy/70 hover:text-fd-navy dark:text-fd-yellow/80 dark:hover:text-fd-yellow',
border: 'border-5 border-gray-200 dark:border-white/10 shadow-fd-card',
},
}
const sectionBgMap: Record<string, string> = {
white: 'bg-white dark:bg-fd-navy',
navy: 'bg-fd-navy',
gray: 'bg-fd-gray-light dark:bg-fd-navy',
}
const layoutGridMap: Record<string, string> = {
'1-2': 'min-[820px]:grid-cols-[1fr_2fr]',
'2-1': 'min-[820px]:grid-cols-[2fr_1fr]',
'1-1-1': 'min-[820px]:grid-cols-3',
'1-1': 'min-[820px]:grid-cols-2',
}
const styleClassMap: Record<string, string> = {
normal: '',
bold: 'font-joey-bold',
italic: 'italic',
boldItalic: 'font-joey-bold italic',
}
/* Priority #5: Responsive radius constant */
const cardRadius = 'rounded-[32px] md:rounded-[50px] lg:rounded-[70px]'
export const FDCardGridBlockComponent: React.FC<FDCardGridBlockProps> = ({
layout = '1-1-1',
cardStyle = 'outlined',
cards,
sectionBackground = 'white',
anchorId,
}) => {
const style = cardStyleMap[cardStyle] || cardStyleMap.outlined
const sectionBg = sectionBgMap[sectionBackground || 'white']
const gridCols = layoutGridMap[layout] || layoutGridMap['1-1-1']
return (
<section id={anchorId || undefined} className={`w-full py-16 md:py-20 lg:py-[99px] ${sectionBg}`}>
<div className="max-w-[1200px] mx-auto px-6 md:px-8">
<div className={`grid grid-cols-1 ${gridCols} gap-4 md:gap-6`}>
{cards?.map((card, index) => {
const mode = card.displayMode || 'content'
let cardContent: React.ReactNode
if (mode === 'centeredHeading') {
cardContent = (
<div
className={`${style.bg} ${style.border} ${cardRadius} px-8 md:px-14 py-14 md:py-20 flex items-center justify-center min-h-[280px] md:min-h-[360px]`}
>
<span
className={`font-joey-heavy text-fd-display leading-tight text-center ${style.headingText}`}
>
{card.heading}
</span>
</div>
)
} else if (mode === 'centeredBody') {
cardContent = (
<div
className={`${style.bg} ${style.border} ${cardRadius} px-8 md:px-14 py-14 md:py-20 flex items-center justify-center min-h-[280px] md:min-h-[360px]`}
>
<p
className={`font-joey text-fd-body-lg text-center ${style.bodyText}`}
>
{card.centeredBodyText}
</p>
</div>
)
} else {
cardContent = (
<div
className={`${style.bg} ${style.border} ${cardRadius} px-6 md:px-10 lg:px-14 py-8 md:py-12 lg:py-14 flex flex-col gap-1 h-full`}
>
{card.heading && (
<h3
className={`font-joey-heavy text-fd-h2 mb-2 ${style.headingText}`}
>
{card.heading}
</h3>
)}
{card.contentLines?.map((line, lineIndex) => {
const textStyle = styleClassMap[line.style || 'normal'] || ''
const baseClass = `font-joey text-fd-body-lg ${style.bodyText} ${textStyle}`
if (line.link) {
return (
<a
key={lineIndex}
href={line.link}
className={`${baseClass} ${style.linkText} underline underline-offset-2 transition-colors`}
>
{line.text}
</a>
)
}
return (
<p key={lineIndex} className={baseClass}>
{line.text}
</p>
)
})}
</div>
)
}
if (card.cardLink) {
return (
<a
key={index}
href={card.cardLink}
className="block hover:shadow-fd-card-hover hover:-translate-y-1 transition-all duration-200"
aria-label={card.heading || undefined}
>
{cardContent}
</a>
)
}
return <div key={index}>{cardContent}</div>
})}
</div>
</div>
</section>
)
}