import { useState, useEffect, useCallback } from 'react'; import { HelpCircle, Plus, Edit2, Trash2, X, GripVertical, ToggleLeft, ToggleRight } from 'lucide-react'; import { toast } from 'react-hot-toast'; import api from '../services/api'; import Spinner from '../components/ui/Spinner'; import ConfirmModal from '../components/ui/ConfirmModal'; import Button from '../components/ui/Button'; import Modal from '../components/ui/Modal'; interface FAQ { id: string; question: string; answer: string; order: number; isActive: boolean; createdAt: string; updatedAt: string; } export default function FAQManager() { const [faqs, setFaqs] = useState([]); const [isLoading, setIsLoading] = useState(true); const [isModalOpen, setIsModalOpen] = useState(false); const [editingFaq, setEditingFaq] = useState(null); const [deleteTargetId, setDeleteTargetId] = useState(null); const [isSaving, setIsSaving] = useState(false); const [formData, setFormData] = useState({ question: '', answer: '', order: 0, isActive: true, }); const fetchFaqs = useCallback(async () => { try { setIsLoading(true); const res = await api.get('/faq/admin'); const data = Array.isArray(res.data) ? res.data : (res.data?.data || []); setFaqs(data); } catch (err) { console.error('Failed to fetch FAQs:', err); toast.error('خطا در دریافت سوالات متداول'); } finally { setIsLoading(false); } }, []); useEffect(() => { fetchFaqs(); }, [fetchFaqs]); const openModal = (item: FAQ | null = null) => { if (item) { setEditingFaq(item); setFormData({ question: item.question, answer: item.answer, order: item.order, isActive: item.isActive, }); } else { setEditingFaq(null); setFormData({ question: '', answer: '', order: faqs.length, isActive: true, }); } setIsModalOpen(true); }; const handleSave = async (e: React.FormEvent) => { e.preventDefault(); if (!formData.question.trim() || !formData.answer.trim()) { toast.error('سوال و جواب اجباری هستند'); return; } try { setIsSaving(true); if (editingFaq) { await api.put(`/faq/${editingFaq.id}`, formData); toast.success('سوال با موفقیت بروزرسانی شد'); } else { await api.post('/faq', formData); toast.success('سوال جدید اضافه شد'); } setIsModalOpen(false); fetchFaqs(); } catch (err) { console.error('Failed to save FAQ:', err); toast.error('خطا در ذخیره سوال'); } finally { setIsSaving(false); } }; const toggleActive = async (item: FAQ) => { try { await api.put(`/faq/${item.id}`, { isActive: !item.isActive }); toast.success(item.isActive ? 'غیرفعال شد' : 'فعال شد'); fetchFaqs(); } catch { toast.error('خطا در تغییر وضعیت'); } }; const confirmDelete = async () => { if (!deleteTargetId) return; try { await api.delete(`/faq/${deleteTargetId}`); toast.success('سوال حذف شد'); fetchFaqs(); } catch { toast.error('خطا در حذف'); } finally { setDeleteTargetId(null); } }; return (

سوالات متداول (FAQ)

سوالات و پاسخ‌هایی که در صفحه اصلی سایت نمایش داده می‌شوند — با Schema.org FAQPage برای SEO

{/* Info Box */}
💡 نکته SEO: سوالات فعال به صورت خودکار با markup FAQPage در صفحه اصلی نمایش داده می‌شوند و در نتایج گوگل به عنوان Rich Snippet ظاهر می‌شوند.
{/* List */}
{isLoading ? (
) : faqs.length === 0 ? (

هیچ سوالی ثبت نشده است

) : ( faqs.map((faq) => (
ترتیب: {faq.order} {faq.isActive ? 'فعال' : 'غیرفعال'}

{faq.question}

{faq.answer}

)) )}
{/* Modal */} {isModalOpen && ( setIsModalOpen(false)} title={editingFaq ? 'ویرایش سوال متداول' : 'افزودن سوال جدید'} icon={HelpCircle} maxWidth="2xl" footer={
} >
setFormData({ ...formData, question: e.target.value })} placeholder="مثال: آیا محصولات کنینا برای سگ‌های حساس مناسب است؟" className="w-full px-4 py-2.5 rounded-xl border border-gray-200 focus:border-purple-500 outline-none text-sm" />