'use client'; import { useState, useEffect } from 'react'; import { useLanguage } from '@/context/LanguageContext'; import { faqApi, FaqItemAdmin } from '@/lib/api'; import Card from '@/components/ui/Card'; import Button from '@/components/ui/Button'; import Input from '@/components/ui/Input'; import toast from 'react-hot-toast'; import clsx from 'clsx'; import { PlusIcon, PencilSquareIcon, TrashIcon, Bars3Icon, XMarkIcon, CheckIcon, ArrowLeftIcon, } from '@heroicons/react/24/outline'; type FormState = { id: string | null; question: string; questionEs: string; answer: string; answerEs: string; enabled: boolean; showOnHomepage: boolean }; const emptyForm: FormState = { id: null, question: '', questionEs: '', answer: '', answerEs: '', enabled: true, showOnHomepage: false, }; export default function AdminFaqPage() { const { locale } = useLanguage(); const [faqs, setFaqs] = useState([]); const [loading, setLoading] = useState(true); const [form, setForm] = useState(emptyForm); const [showForm, setShowForm] = useState(false); const [saving, setSaving] = useState(false); const [draggedId, setDraggedId] = useState(null); const [dragOverId, setDragOverId] = useState(null); useEffect(() => { loadFaqs(); }, []); const loadFaqs = async () => { try { setLoading(true); const res = await faqApi.getAdminList(); setFaqs(res.faqs); } catch (e) { console.error(e); toast.error(locale === 'es' ? 'Error al cargar FAQs' : 'Failed to load FAQs'); } finally { setLoading(false); } }; const handleCreate = () => { setForm(emptyForm); setShowForm(true); }; const handleEdit = (faq: FaqItemAdmin) => { setForm({ id: faq.id, question: faq.question, questionEs: faq.questionEs ?? '', answer: faq.answer, answerEs: faq.answerEs ?? '', enabled: faq.enabled, showOnHomepage: faq.showOnHomepage, }); setShowForm(true); }; const handleSave = async () => { if (!form.question.trim() || !form.answer.trim()) { toast.error(locale === 'es' ? 'Pregunta y respuesta (EN) son obligatorios' : 'Question and answer (EN) are required'); return; } try { setSaving(true); if (form.id) { await faqApi.update(form.id, { question: form.question.trim(), questionEs: form.questionEs.trim() || null, answer: form.answer.trim(), answerEs: form.answerEs.trim() || null, enabled: form.enabled, showOnHomepage: form.showOnHomepage, }); toast.success(locale === 'es' ? 'FAQ actualizado' : 'FAQ updated'); } else { await faqApi.create({ question: form.question.trim(), questionEs: form.questionEs.trim() || undefined, answer: form.answer.trim(), answerEs: form.answerEs.trim() || undefined, enabled: form.enabled, showOnHomepage: form.showOnHomepage, }); toast.success(locale === 'es' ? 'FAQ creado' : 'FAQ created'); } setForm(emptyForm); setShowForm(false); await loadFaqs(); } catch (e: any) { toast.error(e.message || (locale === 'es' ? 'Error al guardar' : 'Failed to save')); } finally { setSaving(false); } }; const handleDelete = async (id: string) => { if (!confirm(locale === 'es' ? '¿Eliminar esta pregunta?' : 'Delete this question?')) return; try { await faqApi.delete(id); toast.success(locale === 'es' ? 'FAQ eliminado' : 'FAQ deleted'); if (form.id === id) { setForm(emptyForm); setShowForm(false); } await loadFaqs(); } catch (e: any) { toast.error(e.message || (locale === 'es' ? 'Error al eliminar' : 'Failed to delete')); } }; const handleToggleEnabled = async (faq: FaqItemAdmin) => { try { await faqApi.update(faq.id, { enabled: !faq.enabled }); setFaqs(prev => prev.map(f => f.id === faq.id ? { ...f, enabled: !f.enabled } : f)); } catch (e: any) { toast.error(e.message || (locale === 'es' ? 'Error al actualizar' : 'Failed to update')); } }; const handleToggleShowOnHomepage = async (faq: FaqItemAdmin) => { try { await faqApi.update(faq.id, { showOnHomepage: !faq.showOnHomepage }); setFaqs(prev => prev.map(f => f.id === faq.id ? { ...f, showOnHomepage: !f.showOnHomepage } : f)); } catch (e: any) { toast.error(e.message || (locale === 'es' ? 'Error al actualizar' : 'Failed to update')); } }; const handleDragStart = (e: React.DragEvent, id: string) => { setDraggedId(id); e.dataTransfer.effectAllowed = 'move'; e.dataTransfer.setData('text/plain', id); }; const handleDragOver = (e: React.DragEvent, id: string) => { e.preventDefault(); e.dataTransfer.dropEffect = 'move'; setDragOverId(id); }; const handleDragLeave = () => { setDragOverId(null); }; const handleDrop = async (e: React.DragEvent, targetId: string) => { e.preventDefault(); setDragOverId(null); setDraggedId(null); const sourceId = e.dataTransfer.getData('text/plain'); if (!sourceId || sourceId === targetId) return; const idx = faqs.findIndex(f => f.id === sourceId); const targetIdx = faqs.findIndex(f => f.id === targetId); if (idx === -1 || targetIdx === -1) return; const newOrder = [...faqs]; const [removed] = newOrder.splice(idx, 1); newOrder.splice(targetIdx, 0, removed); const ids = newOrder.map(f => f.id); try { const res = await faqApi.reorder(ids); setFaqs(res.faqs); toast.success(locale === 'es' ? 'Orden actualizado' : 'Order updated'); } catch (err: any) { toast.error(err.message || (locale === 'es' ? 'Error al reordenar' : 'Failed to reorder')); } }; const handleDragEnd = () => { setDraggedId(null); setDragOverId(null); }; if (loading) { return (
); } return (

{locale === 'es' ? 'FAQ' : 'FAQ'}

{locale === 'es' ? 'Crear y editar preguntas frecuentes. Arrastra para cambiar el orden.' : 'Create and edit FAQ questions. Drag to change order.'}

{showForm && (

{form.id ? (locale === 'es' ? 'Editar pregunta' : 'Edit question') : (locale === 'es' ? 'Nueva pregunta' : 'New question')}

setForm(f => ({ ...f, question: e.target.value }))} placeholder="Question in English" />
setForm(f => ({ ...f, questionEs: e.target.value }))} placeholder="Pregunta en español" />