106 lines
4.1 KiB
TypeScript
106 lines
4.1 KiB
TypeScript
import React from 'react'
|
|
import type { FDLocationsGridBlock as Props, Media } from '@/payload-types'
|
|
|
|
export const FDLocationsGridBlockComponent: React.FC<Props> = ({
|
|
heading,
|
|
description,
|
|
ctaText,
|
|
ctaLink = '/kontakt',
|
|
cards = [],
|
|
hoverColor = 'navy',
|
|
sectionBackground = 'white',
|
|
}) => {
|
|
const bgClass =
|
|
sectionBackground === 'navy' ? 'bg-fd-navy' :
|
|
sectionBackground === 'gray' ? 'bg-fd-gray-light dark:bg-fd-navy' :
|
|
'bg-white dark:bg-fd-navy'
|
|
|
|
const titleClass = sectionBackground === 'navy'
|
|
? 'text-fd-yellow'
|
|
: 'text-fd-navy dark:text-fd-yellow'
|
|
|
|
const bodyClass = sectionBackground === 'navy'
|
|
? 'text-white'
|
|
: 'text-fd-navy dark:text-white'
|
|
|
|
const hoverBgClass =
|
|
hoverColor === 'yellow' ? 'bg-fd-yellow' :
|
|
hoverColor === 'mint' ? 'bg-fd-mint' : 'bg-fd-navy'
|
|
|
|
const hoverTextClass =
|
|
hoverColor === 'yellow' ? 'text-fd-navy' :
|
|
hoverColor === 'mint' ? 'text-fd-navy' : 'text-white'
|
|
|
|
return (
|
|
<section className={`w-full py-16 md:py-20 lg:py-[99px] ${bgClass}`}>
|
|
<div className="max-w-[1200px] mx-auto px-6 md:px-8">
|
|
|
|
{(heading || description || ctaText) && (
|
|
<div className="flex flex-col lg:flex-row lg:items-start lg:justify-between gap-6 mb-12 md:mb-16">
|
|
{heading && (
|
|
<h2 className={`font-joey-medium text-fd-h1 ${titleClass} lg:max-w-[380px]`}>
|
|
{heading}
|
|
</h2>
|
|
)}
|
|
<div className="flex flex-col gap-4 lg:max-w-[560px]">
|
|
{description && (
|
|
<p className={`font-joey text-fd-body-lg ${bodyClass}`}>{description}</p>
|
|
)}
|
|
{ctaText && (
|
|
<a href={ctaLink || '#'} className="self-start fd-btn-primary">
|
|
{ctaText} →
|
|
</a>
|
|
)}
|
|
</div>
|
|
</div>
|
|
)}
|
|
|
|
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4 md:gap-6">
|
|
{(cards ?? []).map((card, i) => {
|
|
const media = card.image as Media | undefined
|
|
const isLink = Boolean(card.link)
|
|
const className = `group relative overflow-hidden rounded-[30px] md:rounded-[50px] aspect-[4/3] block ${isLink ? 'cursor-pointer' : ''}`
|
|
|
|
const inner = (
|
|
<>
|
|
{media?.url && (
|
|
<img
|
|
src={media.url}
|
|
alt={(media as any).alt || card.locationName}
|
|
className="absolute inset-0 w-full h-full object-cover transition-transform duration-500 group-hover:scale-105"
|
|
/>
|
|
)}
|
|
<div className="absolute inset-0 bg-gradient-to-t from-black/70 via-black/20 to-transparent transition-opacity duration-300 group-hover:opacity-0" />
|
|
<div className="absolute bottom-0 left-0 px-7 md:px-8 pb-8 md:pb-10 transition-opacity duration-300 group-hover:opacity-0">
|
|
<span className="font-joey-bold text-white text-fd-h3">{card.locationName}</span>
|
|
</div>
|
|
<div className={`absolute inset-0 ${hoverBgClass} flex flex-col justify-end px-7 md:px-8 pb-10 md:pb-12 pt-6 opacity-0 group-hover:opacity-100 transition-opacity duration-300`}>
|
|
<span className={`font-joey-bold text-fd-h2 ${hoverTextClass} mb-1`}>
|
|
{card.locationName}
|
|
</span>
|
|
{card.address && (
|
|
<span className={`font-joey text-fd-body ${hoverTextClass} opacity-80`}>
|
|
{card.address}
|
|
</span>
|
|
)}
|
|
{card.link && (
|
|
<span className={`mt-3 font-joey-bold text-fd-small ${hoverTextClass}`}>
|
|
→ Se mer
|
|
</span>
|
|
)}
|
|
</div>
|
|
</>
|
|
)
|
|
|
|
return isLink ? (
|
|
<a key={i} href={card.link!} className={className}>{inner}</a>
|
|
) : (
|
|
<div key={i} className={className}>{inner}</div>
|
|
)
|
|
})}
|
|
</div>
|
|
</div>
|
|
</section>
|
|
)
|
|
}
|