Website-V3/src/components/home/FAQ.jsx
2025-04-08 21:22:00 -04:00

205 lines
7 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import React, { useState } from "react";
import {
ChevronDown,
Search,
X,
CreditCard,
Gamepad,
HelpCircle,
} from "lucide-react";
const faqData = {
general: [
{
question: "How do I get started?",
answer:
"Simply choose your game server, select a plan, and your server will be instantly deployed. Our control panel makes setup easy and intuitive.",
},
{
question: "Do you offer 24/7 support?",
answer:
"Yes, our support team is available 24/7 through live chat, ticket system, and Discord. We typically respond within 5 minutes.",
},
{
question: "What locations do you offer?",
answer:
"Currently live in Phoenix, AZ, with new nodes planned for NYC, Germany, and beyond. Were building a global network focused on low-latency, high-uptime performance for gamers everywhere.",
},
],
billing: [
{
question: "What payment methods do you accept?",
answer:
"We accept all major credit cards and PayPal. All payments are processed securely.",
},
{
question: "Do you offer refunds?",
answer:
"Yes, we offer a 48-hour refund policy. Refunds are granted for valid reasons within this time frame. After 48 hours, refunds are no longer available. Please note that each client is eligible for one refund every six months.",
},
{
question: "Can I upgrade my plan anytime?",
answer:
"Yes, you can upgrade or your plan at any time. Changes take effect immediately and billing is prorated.",
},
],
gameServers: [
// {
// question: "How do I install mods?",
// answer:
// "Our control panel features one-click mod installation for popular modpacks. You can also manually upload mods through FTP.",
// },
{
question: "What's the minimum RAM recommended?",
answer:
"For Minecraft, we suggest 2GB for every 10 players. Other games vary.",
},
{
question: "Do you provide DDoS protection?",
answer:
"Yes, all servers include enterprise-grade DDoS protection up to 17Tbps at no extra cost.",
},
],
};
const tabs = [
{ id: "general", label: "General", icon: HelpCircle },
{ id: "billing", label: "Billing", icon: CreditCard },
{ id: "gameServers", label: "Game Servers", icon: Gamepad },
];
const FAQItem = ({ question, answer, isOpen, onToggle }) => {
return (
<div className="bg-slate-950 border border-gray-900 rounded-md">
<button
className="w-full py-5 px-5 flex items-center justify-between text-left focus:outline-none"
onClick={onToggle}
aria-expanded={isOpen}
>
<span className="text-lg font-medium text-white pr-8">{question}</span>
<ChevronDown
className={`w-5 h-5 text-gray-400 transition-transform duration-200 ${
isOpen ? "rotate-180" : ""
}`}
/>
</button>
<div
className={`overflow-hidden transition-all duration-200 ${
isOpen ? "max-h-96" : "max-h-0"
}`}
>
<div className="px-5 pb-5 text-gray-400">{answer}</div>
</div>
</div>
);
};
export const FAQ = () => {
const [activeTab, setActiveTab] = useState("general");
const [expandedQuestions, setExpandedQuestions] = useState([]);
const [searchQuery, setSearchQuery] = useState("");
const handleToggleQuestion = (id) => {
setExpandedQuestions((prev) =>
prev.includes(id) ? prev.filter((item) => item !== id) : [...prev, id]
);
};
const filteredQuestions = searchQuery
? faqData[activeTab].filter(
(item) =>
item.question.toLowerCase().includes(searchQuery.toLowerCase()) ||
item.answer.toLowerCase().includes(searchQuery.toLowerCase())
)
: faqData[activeTab];
return (
<section className="py-12 md:py-24 bg-slate-900">
<div className="container mx-auto px-4 max-w-screen-xl">
<div className="text-center max-w-2xl mx-auto mb-6">
<h2 className="text-3xl md:text-4xl font-bold text-white mb-4">
Frequently Asked Questions
</h2>
<p className="text-xl text-gray-300">
Find answers to common questions about our services
</p>
</div>
{/* Search Bar */}
<div className="max-w-3xl mx-auto mb-6">
<div className="bg-slate-950 rounded-md border border-gray-900">
<div className="relative">
<Search className="absolute left-4 top-1/2 -translate-y-1/2 w-5 h-5 text-gray-400" />
<input
type="text"
placeholder="Search questions..."
value={searchQuery}
onChange={(e) => setSearchQuery(e.target.value)}
className="w-full bg-transparent text-white pl-12 pr-12 py-3 rounded-md focus:outline-none"
/>
{searchQuery && (
<button
onClick={() => setSearchQuery("")}
className="absolute right-4 top-1/2 -translate-y-1/2"
>
<X className="w-5 h-5 text-gray-400 hover:text-blue-500 transition-colors duration-200" />
</button>
)}
</div>
</div>
</div>
{/* Tabs */}
<div className="max-w-5xl mx-auto">
<div className="flex justify-center mb-8">
<div className="inline-flex bg-slate-950 p-1 rounded-md border border-gray-900">
{tabs.map((tab) => {
const Icon = tab.icon;
return (
<button
key={tab.id}
onClick={() => setActiveTab(tab.id)}
className={`
flex items-center gap-2 px-6 py-2 rounded-md font-medium transition-all duration-200
${
activeTab === tab.id
? "bg-blue-600 text-white"
: "text-gray-400 hover:text-white"
}
`}
>
<Icon className="w-5 h-5" />
{tab.label}
</button>
);
})}
</div>
</div>
{/* FAQ Items */}
<div className="space-y-1 md:space-y-2">
{filteredQuestions.map((item, index) => (
<FAQItem
key={index}
question={item.question}
answer={item.answer}
isOpen={expandedQuestions.includes(`${activeTab}-${index}`)}
onToggle={() => handleToggleQuestion(`${activeTab}-${index}`)}
/>
))}
{filteredQuestions.length === 0 && (
<div className="bg-slate-950 p-5 rounded-md border border-gray-900 text-center">
<p className="text-gray-400">
No questions found matching your search.
</p>
</div>
)}
</div>
</div>
</div>
</section>
);
};
export default FAQ;