frontend.sensualmoment.de/src/app/faq/FAQAccordion.tsx
CCS Admin f4e610e81e feat: complete frontend scaffold with all pages and components
- 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>
2026-02-27 12:57:57 +00:00

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>
)
}