mirror of
https://github.com/complexcaresolutions/frontend.sensualmoment.de.git
synced 2026-03-17 15:03:54 +00:00
- Project foundation: Next.js 16, Tailwind v4, Google Fonts, payload-contracts - Shared components: Navigation (scroll effect), Footer (Deep Navy), Logo (wordmark), ScrollReveal - Homepage: Hero, AboutPreview, GalleryPreview, Testimonials, Packages, BlogPreview, Contact - Inner pages: ueber-mich, galerie, pakete, journal, journal/[slug], kontakt, faq, impressum, datenschutz, agb - CMS API client (src/lib/api.ts) with tenant-scoped fetch helpers - server.js for Plesk Passenger deployment - Color palette: Dark Wine, Blush, Bordeaux, Deep Navy, Creme, Espresso - Fonts: Playfair Display (headlines), Cormorant Garamond (body), Josefin Sans (UI) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
63 lines
1.9 KiB
TypeScript
63 lines
1.9 KiB
TypeScript
"use client"
|
|
|
|
import { useState } from "react"
|
|
|
|
interface FAQ {
|
|
question: string
|
|
answer: unknown
|
|
category?: string
|
|
}
|
|
|
|
interface FAQAccordionProps {
|
|
faqs: FAQ[]
|
|
}
|
|
|
|
function extractText(richText: unknown): string {
|
|
if (!richText || typeof richText !== "object") return ""
|
|
const root = (richText as { root?: { children?: unknown[] } }).root
|
|
if (!root?.children) return ""
|
|
|
|
function walk(nodes: unknown[]): string {
|
|
return nodes
|
|
.map((node) => {
|
|
const n = node as { type?: string; text?: string; children?: unknown[] }
|
|
if (n.type === "text" && n.text) return n.text
|
|
if (n.children) return walk(n.children)
|
|
return ""
|
|
})
|
|
.join("")
|
|
}
|
|
|
|
return walk(root.children)
|
|
}
|
|
|
|
export function FAQAccordion({ faqs }: FAQAccordionProps) {
|
|
const [openIndex, setOpenIndex] = useState<number | null>(null)
|
|
|
|
return (
|
|
<div className="space-y-3">
|
|
{faqs.map((faq, i) => (
|
|
<div key={i} className="border border-blush-border overflow-hidden">
|
|
<button
|
|
onClick={() => setOpenIndex(openIndex === i ? null : i)}
|
|
className="w-full flex items-center justify-between p-5 text-left hover:bg-blush-hover transition-colors"
|
|
>
|
|
<span className="font-cormorant text-[1.1rem] font-normal text-espresso pr-4">
|
|
{faq.question}
|
|
</span>
|
|
<span className={"font-playfair text-bordeaux text-xl transition-transform duration-300 shrink-0 " + (openIndex === i ? "rotate-45" : "")}>
|
|
+
|
|
</span>
|
|
</button>
|
|
<div
|
|
className={"overflow-hidden transition-all duration-300 " + (openIndex === i ? "max-h-96 opacity-100" : "max-h-0 opacity-0")}
|
|
>
|
|
<div className="px-5 pb-5 font-cormorant text-[1.05rem] font-light text-espresso/80 leading-[1.75]">
|
|
{extractText(faq.answer)}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
))}
|
|
</div>
|
|
)
|
|
}
|