69 lines
2.5 KiB
TypeScript
69 lines
2.5 KiB
TypeScript
'use client'
|
|
import React, { useEffect, useRef, useState } from 'react'
|
|
import type { FDStatisticsBlock as Props } from '@/payload-types'
|
|
|
|
export const FDStatisticsBlockComponent: React.FC<Props> = ({
|
|
title,
|
|
stats = [],
|
|
sectionBackground = 'white',
|
|
numberColor = 'gradient',
|
|
}) => {
|
|
const [visible, setVisible] = useState(false)
|
|
const ref = useRef<HTMLDivElement>(null)
|
|
|
|
useEffect(() => {
|
|
const observer = new IntersectionObserver(
|
|
([entry]) => { if (entry.isIntersecting) setVisible(true) },
|
|
{ threshold: 0.3 },
|
|
)
|
|
if (ref.current) observer.observe(ref.current)
|
|
return () => observer.disconnect()
|
|
}, [])
|
|
|
|
const bgClass =
|
|
sectionBackground === 'navy' ? 'bg-fd-navy' :
|
|
sectionBackground === 'gray' ? 'bg-fd-surface-alt' : 'bg-white'
|
|
|
|
const titleClass = sectionBackground === 'navy' ? 'text-fd-yellow' : 'text-fd-navy'
|
|
const labelClass = sectionBackground === 'navy' ? 'text-white' : 'text-fd-navy'
|
|
|
|
const getNumberClass = () => {
|
|
if (numberColor === 'gradient') return 'bg-gradient-to-r from-fd-yellow to-fd-mint bg-clip-text text-transparent'
|
|
if (numberColor === 'yellow') return 'text-fd-yellow'
|
|
if (numberColor === 'mint') return 'text-fd-mint'
|
|
if (numberColor === 'white') return 'text-white'
|
|
return 'text-fd-navy'
|
|
}
|
|
|
|
return (
|
|
<section className={`w-full py-16 md:py-20 lg:py-[99px] ${bgClass}`} ref={ref}>
|
|
<div className="max-w-[1200px] mx-auto px-6 md:px-8 text-center">
|
|
{title && (
|
|
<h2 className={`font-joey-heavy text-fd-h1 mb-12 md:mb-16 ${titleClass}`}>
|
|
{title}
|
|
</h2>
|
|
)}
|
|
<div className="flex flex-wrap justify-center gap-8 md:gap-12 lg:gap-16">
|
|
{(stats ?? []).map((stat, i) => (
|
|
<div
|
|
key={i}
|
|
className={`flex flex-col items-center gap-2 transition-all duration-700 ${
|
|
visible ? 'opacity-100 translate-y-0' : 'opacity-0 translate-y-4'
|
|
}`}
|
|
style={{ transitionDelay: `${i * 120}ms` }}
|
|
>
|
|
{/* Intentionally oversized for visual impact — not mapped to fd-* token */}
|
|
<span className={`font-joey-heavy text-5xl md:text-7xl lg:text-[96px] leading-none ${getNumberClass()}`}>
|
|
{stat.number}
|
|
</span>
|
|
<span className={`font-joey text-fd-body max-w-[180px] ${labelClass}`}>
|
|
{stat.label}
|
|
</span>
|
|
</div>
|
|
))}
|
|
</div>
|
|
</div>
|
|
</section>
|
|
)
|
|
}
|