- Création des fichiers JSON dans public/data/ - Modification de tous les composants pour fetch depuis /data/*.json - PlaceList, FAQ, Lexique, Tides, SunTimes, Excursions, Notifications - Données complètes pour Fakarava (plages, restaurants, épiceries) - Fix docker-compose.build.yml (suppression volume node_modules)
81 lines
2.2 KiB
TypeScript
81 lines
2.2 KiB
TypeScript
"use client";
|
|
|
|
import { useEffect, useState, useMemo } from "react";
|
|
import {
|
|
Accordion,
|
|
AccordionItem,
|
|
AccordionTrigger,
|
|
AccordionContent,
|
|
} from "@/components/ui/accordion";
|
|
import { FAQItem } from "@/lib/types/infos";
|
|
|
|
export default function FAQAccordion() {
|
|
const [faqItems, setFaqItems] = useState<FAQItem[]>([]);
|
|
const [loading, setLoading] = useState(true);
|
|
|
|
useEffect(() => {
|
|
const fetchFAQ = async () => {
|
|
try {
|
|
const response = await fetch("/data/infos.json");
|
|
const data = await response.json();
|
|
setFaqItems(data.faq || []);
|
|
} catch (error) {
|
|
console.error("Erreur lors du chargement de la FAQ:", error);
|
|
} finally {
|
|
setLoading(false);
|
|
}
|
|
};
|
|
|
|
fetchFAQ();
|
|
}, []);
|
|
|
|
// Grouper les FAQ par catégorie
|
|
const faqByCategory = useMemo(() => {
|
|
const grouped: Record<string, FAQItem[]> = {};
|
|
faqItems.forEach((item) => {
|
|
const category = item.category || "Autres";
|
|
if (!grouped[category]) {
|
|
grouped[category] = [];
|
|
}
|
|
grouped[category].push(item);
|
|
});
|
|
return grouped;
|
|
}, [faqItems]);
|
|
|
|
if (loading) {
|
|
return (
|
|
<div className="flex items-center justify-center py-8">
|
|
<p className="text-gray-600">Chargement...</p>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<div className="space-y-6">
|
|
{Object.entries(faqByCategory).map(([category, items]) => (
|
|
<div key={category} className="space-y-3">
|
|
<h3 className="text-lg font-semibold text-primary flex items-center gap-2">
|
|
{items[0]?.icon && <span>{items[0].icon}</span>}
|
|
<span>{category}</span>
|
|
</h3>
|
|
<Accordion type="single" className="w-full">
|
|
{items.map((item) => (
|
|
<AccordionItem key={item.id} value={item.id}>
|
|
<AccordionTrigger className="text-left">
|
|
{item.question}
|
|
</AccordionTrigger>
|
|
<AccordionContent>
|
|
<p className="text-gray-700 leading-relaxed whitespace-pre-line">
|
|
{item.answer}
|
|
</p>
|
|
</AccordionContent>
|
|
</AccordionItem>
|
|
))}
|
|
</Accordion>
|
|
</div>
|
|
))}
|
|
</div>
|
|
);
|
|
}
|
|
|