81 lines
3.1 KiB
TypeScript
81 lines
3.1 KiB
TypeScript
'use client'
|
|
import React, { useState } from 'react'
|
|
import { motion, AnimatePresence } from 'framer-motion'
|
|
import { ChevronDown } from 'lucide-react'
|
|
import type { Page } from '../../payload-types'
|
|
|
|
type Props = Extract<NonNullable<Page['layout']>[0], { blockType: 'faqTeaser' }>
|
|
|
|
export const FAQTeaserBlock: React.FC<Props> = ({ title, questions, ctaText, ctaUrl }) => {
|
|
const [openIndex, setOpenIndex] = useState<number | null>(0)
|
|
|
|
const toggleQuestion = (index: number) => {
|
|
setOpenIndex(openIndex === index ? null : index)
|
|
}
|
|
|
|
return (
|
|
<section className="py-20 md:py-32" id="faq">
|
|
<div className="container-premium max-w-4xl">
|
|
<div className="mb-12 md:mb-16 text-center">
|
|
<h2 className="font-heading text-3xl sm:text-4xl md:text-5xl font-extrabold text-foreground tracking-tight text-balance">
|
|
{title}
|
|
</h2>
|
|
</div>
|
|
|
|
<div className="space-y-4">
|
|
{questions?.map((q: NonNullable<Props['questions']>[0], index: number) => {
|
|
const isOpen = openIndex === index
|
|
|
|
return (
|
|
<div
|
|
key={q.id || index}
|
|
className="bg-background border border-border overflow-hidden shadow-sm hover:shadow-md transition-shadow"
|
|
>
|
|
<button
|
|
onClick={() => toggleQuestion(index)}
|
|
className="w-full flex items-center justify-between p-6 text-left hover:bg-card/50 transition-colors focus:outline-none"
|
|
aria-expanded={isOpen}
|
|
>
|
|
<h3 className="font-heading text-lg sm:text-xl font-bold text-foreground pr-8">
|
|
{q.question}
|
|
</h3>
|
|
<div className="w-8 h-8 rounded-full bg-accent/10 flex items-center justify-center shrink-0">
|
|
<ChevronDown
|
|
className={`w-5 h-5 text-accent transition-transform duration-300 ${isOpen ? 'rotate-180' : ''}`}
|
|
/>
|
|
</div>
|
|
</button>
|
|
<AnimatePresence initial={false}>
|
|
{isOpen && (
|
|
<motion.div
|
|
initial={{ height: 0, opacity: 0 }}
|
|
animate={{ height: 'auto', opacity: 1 }}
|
|
exit={{ height: 0, opacity: 0 }}
|
|
transition={{ duration: 0.3, ease: 'easeInOut' }}
|
|
>
|
|
<div className="p-6 pt-0 text-foreground/75 leading-relaxed border-t border-border/10">
|
|
{q.answer}
|
|
</div>
|
|
</motion.div>
|
|
)}
|
|
</AnimatePresence>
|
|
</div>
|
|
)
|
|
})}
|
|
</div>
|
|
|
|
{ctaText && ctaUrl && (
|
|
<div className="mt-12 text-center">
|
|
<a
|
|
href={ctaUrl}
|
|
className="inline-flex items-center justify-center h-14 px-8 text-base sm:text-lg font-bold text-background bg-accent rounded-[6px] hover:bg-accent-hover transition-colors"
|
|
>
|
|
{ctaText}
|
|
</a>
|
|
</div>
|
|
)}
|
|
</div>
|
|
</section>
|
|
)
|
|
}
|