171 lines
5.8 KiB
TypeScript
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>
|
|
)
|
|
}
|