70 lines
2.7 KiB
TypeScript
70 lines
2.7 KiB
TypeScript
'use client'
|
|
import React, { useState, useEffect } from 'react'
|
|
import type { Page } from '../../payload-types'
|
|
|
|
type Props = Extract<NonNullable<Page['layout']>[0], { blockType: 'testimonials' }>
|
|
|
|
export const TestimonialsBlock: React.FC<Props> = ({ title, testimonials }) => {
|
|
const [currentIndex, setCurrentIndex] = useState(0)
|
|
|
|
useEffect(() => {
|
|
if (!testimonials || testimonials.length <= 1) return
|
|
|
|
const timer = setInterval(() => {
|
|
setCurrentIndex((prev) => (prev + 1) % testimonials.length)
|
|
}, 7000)
|
|
|
|
return () => clearInterval(timer)
|
|
}, [testimonials])
|
|
|
|
if (!testimonials || testimonials.length === 0) return null
|
|
|
|
return (
|
|
<section className="py-24 md:py-40 bg-background border-y border-border overflow-hidden">
|
|
<div className="container-premium max-w-4xl mx-auto text-center relative">
|
|
<h2 className="font-mono text-sm md:text-base font-bold text-accent tracking-widest uppercase mb-12">
|
|
// {title}
|
|
</h2>
|
|
|
|
<div className="relative min-h-[300px] sm:min-h-[240px] flex items-center justify-center">
|
|
{testimonials.map((t: NonNullable<Props['testimonials']>[0], index: number) => (
|
|
<div
|
|
key={t.id || index}
|
|
className={`absolute inset-0 flex flex-col items-center justify-center transition-opacity duration-1000 ease-in-out ${
|
|
index === currentIndex ? 'opacity-100 z-10' : 'opacity-0 z-0 pointer-events-none'
|
|
}`}
|
|
>
|
|
<p className="font-heading text-3xl sm:text-4xl md:text-5xl font-extrabold text-foreground leading-[1.2] mb-10 text-balance tracking-tight">
|
|
"{t.quote}"
|
|
</p>
|
|
|
|
<div className="flex items-center gap-4">
|
|
<div className="w-12 h-px bg-accent/40" />
|
|
<p className="font-heading font-bold text-lg sm:text-xl text-foreground/80 uppercase tracking-wide">
|
|
{t.author}
|
|
</p>
|
|
<div className="w-12 h-px bg-accent/40" />
|
|
</div>
|
|
</div>
|
|
))}
|
|
</div>
|
|
|
|
{testimonials.length > 1 && (
|
|
<div className="flex items-center justify-center gap-3 mt-12">
|
|
{testimonials.map((_, index) => (
|
|
<button
|
|
key={index}
|
|
onClick={() => setCurrentIndex(index)}
|
|
className={`w-2 h-2 transition-all ${
|
|
index === currentIndex ? 'bg-accent w-8' : 'bg-border hover:bg-foreground/30'
|
|
}`}
|
|
aria-label={`Pokaż opinię ${index + 1}`}
|
|
/>
|
|
))}
|
|
</div>
|
|
)}
|
|
</div>
|
|
</section>
|
|
)
|
|
}
|