92 lines
3.2 KiB
TypeScript
92 lines
3.2 KiB
TypeScript
"use client";
|
|
|
|
import { useState, useRef, useEffect } from "react";
|
|
import styles from "./ChannelFAQ.module.css";
|
|
import { MessageCircle, ChevronDown } from "lucide-react";
|
|
|
|
interface FAQItem {
|
|
question: string;
|
|
answer: string;
|
|
}
|
|
|
|
interface ChannelFAQProps {
|
|
faqs: FAQItem[];
|
|
channelTitle: string;
|
|
}
|
|
|
|
export default function ChannelFAQ({ faqs, channelTitle }: ChannelFAQProps) {
|
|
const [openIndex, setOpenIndex] = useState<number | null>(0); // First item open by default
|
|
|
|
const toggleFAQ = (index: number) => {
|
|
setOpenIndex(openIndex === index ? null : index);
|
|
};
|
|
|
|
return (
|
|
<section className={styles.section}>
|
|
<div className={styles.container}>
|
|
<div className={styles.grid}>
|
|
{/* Left Side: Static Content */}
|
|
<div className={styles.headerContent}>
|
|
<div className={styles.pill}>
|
|
<MessageCircle size={16} />
|
|
<span>Frequently Asked Questions</span>
|
|
</div>
|
|
<h2 className={styles.title}>
|
|
Frequently asked <span className={styles.highlight}>questions</span>
|
|
</h2>
|
|
<p className={styles.description}>
|
|
Got questions about how SocialBuddy works with {channelTitle}?
|
|
We've got answers. If you need more help, our support team is just a click away.
|
|
</p>
|
|
</div>
|
|
|
|
{/* Right Side: Accordion List */}
|
|
<div className={styles.accordionList}>
|
|
{faqs.map((faq, index) => (
|
|
<FAQItemCard
|
|
key={index}
|
|
item={faq}
|
|
isOpen={openIndex === index}
|
|
onClick={() => toggleFAQ(index)}
|
|
/>
|
|
))}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
);
|
|
}
|
|
|
|
// Sub-component for individual item to handle height animation cleanly
|
|
function FAQItemCard({ item, isOpen, onClick }: { item: FAQItem, isOpen: boolean, onClick: () => void }) {
|
|
const contentRef = useRef<HTMLDivElement>(null);
|
|
const [height, setHeight] = useState(0);
|
|
|
|
useEffect(() => {
|
|
if (isOpen && contentRef.current) {
|
|
setHeight(contentRef.current.scrollHeight);
|
|
} else {
|
|
setHeight(0);
|
|
}
|
|
}, [isOpen]);
|
|
|
|
return (
|
|
<div className={`${styles.card} ${isOpen ? styles.cardOpen : ''}`}>
|
|
<button className={styles.trigger} onClick={onClick} aria-expanded={isOpen}>
|
|
<span className={styles.question}>{item.question}</span>
|
|
<div className={styles.iconWrapper}>
|
|
<ChevronDown size={18} />
|
|
</div>
|
|
</button>
|
|
<div
|
|
className={styles.content}
|
|
style={{ height: `${height}px` }}
|
|
>
|
|
<div ref={contentRef} className={styles.contentInner}>
|
|
{item.answer}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|