bandsbender's picture
Upload 348 files
21a686e verified
raw
history blame
4.77 kB
"use client";
import React, { useState } from "react";
import { AnimatePresence, motion } from "motion/react";
import { IconChevronDown, IconChevronUp } from "@tabler/icons-react";
import { cn } from "@/lib/utils";
const FAQs = [
{
question: "What is the purpose of this website?",
answer:
"This website is a place to help you find the best products and services in the world.",
},
{
question: "How do I contact support?",
answer:
"You can contact support by email at support@example.com or by phone at 123-456-7890.",
},
{
question: "How do I find the best products?",
answer:
"You can find the best products by searching for them on the search page or by browsing the categories.",
},
{
question: "Can I return a product?",
answer:
"Yes, you can return a product within 30 days of purchase. Please refer to our return policy for more details.",
},
{
question: "Do you offer international shipping?",
answer:
"Yes, we offer international shipping to most countries. Shipping fees and delivery times may vary depending on the destination.",
},
{
question: "How can I track my order?",
answer:
"You can track your order by logging into your account and visiting the order history page. You will also receive a tracking number via email once your order has shipped.",
},
];
export function SimpleFaqsWithBackground() {
const [open, setOpen] = useState<string | null>(null);
return (
<div className="mx-auto grid w-full max-w-7xl gap-4 px-4 py-20 md:px-8 md:py-40">
<h2 className="text-center text-4xl font-medium tracking-tight text-neutral-600 md:text-5xl dark:text-neutral-50">
Frequently asked questions
</h2>
<p className="mx-auto max-w-lg text-center text-base text-neutral-600 dark:text-neutral-50">
We are here to help you with any questions you may have. If you
don&apos;t find what you need, please contact us at{" "}
<a
href="mailto:support@example.com"
className="text-blue-500 underline"
>
support@example.com
</a>
</p>
<div className="mx-auto mt-10 w-full max-w-3xl">
{FAQs.map((faq, index) => (
<FAQItem
key={index}
question={faq.question}
answer={faq.answer}
open={open}
setOpen={setOpen}
/>
))}
</div>
</div>
);
}
const FAQItem = ({
question,
answer,
setOpen,
open,
}: {
question: string;
answer: string;
open: string | null;
setOpen: (open: string | null) => void;
}) => {
const isOpen = open === question;
return (
<div
className="shadow-input mb-8 w-full cursor-pointer rounded-lg bg-white p-4 dark:bg-neutral-900"
onClick={() => {
if (isOpen) {
setOpen(null);
} else {
setOpen(question);
}
}}
>
<div className="flex items-start">
<div className="relative mr-4 mt-1 h-6 w-6 flex-shrink-0">
<IconChevronUp
className={cn(
"absolute inset-0 h-6 w-6 transform text-black transition-all duration-200 dark:text-white",
isOpen && "rotate-90 scale-0"
)}
/>
<IconChevronDown
className={cn(
"absolute inset-0 h-6 w-6 rotate-90 scale-0 transform text-black transition-all duration-200 dark:text-white",
isOpen && "rotate-0 scale-100"
)}
/>
</div>
<div>
<h3 className="text-lg font-medium text-neutral-700 dark:text-neutral-200">
{question}
</h3>
<AnimatePresence mode="wait">
{isOpen && (
<motion.div
initial={{ height: 0 }}
animate={{ height: "auto" }}
exit={{ height: 0 }}
transition={{ duration: 0.2, ease: "easeOut" }}
className="overflow-hidden text-neutral-500 dark:text-neutral-400"
>
{answer.split("").map((line, index) => (
<motion.span
initial={{ opacity: 0, filter: "blur(5px)" }}
animate={{ opacity: 1, filter: "blur(0px)" }}
exit={{ opacity: 0, filter: "blur(0px)" }}
transition={{
duration: 0.2,
ease: "easeOut",
delay: index * 0.005,
}}
key={index}
>
{line}
</motion.span>
))}
</motion.div>
)}
</AnimatePresence>
</div>
</div>
</div>
);
};