diff --git a/src/components/admin/AdminFAQForm.tsx b/src/components/admin/AdminFAQForm.tsx new file mode 100644 index 0000000..b3bf09f --- /dev/null +++ b/src/components/admin/AdminFAQForm.tsx @@ -0,0 +1,133 @@ + +import { useState } from 'react'; +import { Button } from '@/components/ui/button'; +import { Input } from '@/components/ui/input'; +import { Textarea } from '@/components/ui/textarea'; +import { Label } from '@/components/ui/label'; +import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'; +import { useToast } from '@/hooks/use-toast'; +import { supabase } from '@/integrations/supabase/client'; + +interface FAQ { + id: string; + pergunta: string; + resposta: string; + imagem_url?: string; + ativo: boolean; + created_at: string; +} + +interface AdminFAQFormProps { + editingFaq: FAQ | null; + onSuccess: () => void; + onCancel: () => void; +} + +const AdminFAQForm = ({ editingFaq, onSuccess, onCancel }: AdminFAQFormProps) => { + const [formData, setFormData] = useState({ + pergunta: editingFaq?.pergunta || '', + resposta: editingFaq?.resposta || '', + imagem_url: editingFaq?.imagem_url || '', + ativo: editingFaq?.ativo ?? true + }); + const [loading, setLoading] = useState(false); + const { toast } = useToast(); + + const handleSubmit = async (e: React.FormEvent) => { + e.preventDefault(); + setLoading(true); + + try { + if (editingFaq) { + // Atualizar FAQ existente + const { error } = await supabase + .from('faqs') + .update(formData) + .eq('id', editingFaq.id); + + if (error) throw error; + toast({ title: "FAQ atualizado com sucesso!" }); + } else { + // Criar novo FAQ + const { error } = await supabase + .from('faqs') + .insert(formData); + + if (error) throw error; + toast({ title: "FAQ criado com sucesso!" }); + } + + // Reset form + setFormData({ pergunta: '', resposta: '', imagem_url: '', ativo: true }); + onSuccess(); + } catch (error) { + console.error('Erro ao salvar FAQ:', error); + toast({ + title: "Erro", + description: "Não foi possível salvar o FAQ.", + variant: "destructive" + }); + } finally { + setLoading(false); + } + }; + + return ( + + + {editingFaq ? 'Editar FAQ' : 'Criar Novo FAQ'} + + + + + Pergunta * + setFormData({ ...formData, pergunta: e.target.value })} + required + /> + + + + Resposta * + setFormData({ ...formData, resposta: e.target.value })} + rows={6} + required + /> + + + + URL da Imagem (opcional) + setFormData({ ...formData, imagem_url: e.target.value })} + placeholder="https://exemplo.com/imagem.jpg" + /> + + + + + {loading ? 'Salvando...' : editingFaq ? 'Atualizar' : 'Criar'} + + {editingFaq && ( + + Cancelar + + )} + + + + + ); +}; + +export default AdminFAQForm; diff --git a/src/components/admin/AdminFAQList.tsx b/src/components/admin/AdminFAQList.tsx new file mode 100644 index 0000000..f783203 --- /dev/null +++ b/src/components/admin/AdminFAQList.tsx @@ -0,0 +1,122 @@ + +import { Edit, Trash2, Eye, EyeOff } from 'lucide-react'; +import { Button } from '@/components/ui/button'; +import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'; +import { useToast } from '@/hooks/use-toast'; +import { supabase } from '@/integrations/supabase/client'; + +interface FAQ { + id: string; + pergunta: string; + resposta: string; + imagem_url?: string; + ativo: boolean; + created_at: string; +} + +interface AdminFAQListProps { + faqs: FAQ[]; + onEdit: (faq: FAQ) => void; + onUpdate: () => void; +} + +const AdminFAQList = ({ faqs, onEdit, onUpdate }: AdminFAQListProps) => { + const { toast } = useToast(); + + const handleDelete = async (id: string) => { + if (!confirm('Tem certeza que deseja excluir este FAQ?')) return; + + try { + const { error } = await supabase + .from('faqs') + .delete() + .eq('id', id); + + if (error) throw error; + toast({ title: "FAQ excluído com sucesso!" }); + onUpdate(); + } catch (error) { + console.error('Erro ao excluir FAQ:', error); + toast({ + title: "Erro", + description: "Não foi possível excluir o FAQ.", + variant: "destructive" + }); + } + }; + + const toggleStatus = async (faq: FAQ) => { + try { + const { error } = await supabase + .from('faqs') + .update({ ativo: !faq.ativo }) + .eq('id', faq.id); + + if (error) throw error; + toast({ title: `FAQ ${!faq.ativo ? 'ativado' : 'desativado'} com sucesso!` }); + onUpdate(); + } catch (error) { + console.error('Erro ao alterar status:', error); + toast({ + title: "Erro", + description: "Não foi possível alterar o status do FAQ.", + variant: "destructive" + }); + } + }; + + return ( + + + FAQs Cadastrados + + + + {faqs.map((faq) => ( + + + + {faq.pergunta} + + + Status: {faq.ativo ? 'Ativo' : 'Inativo'} + • + {new Date(faq.created_at).toLocaleDateString()} + + + + toggleStatus(faq)} + > + {faq.ativo ? : } + + onEdit(faq)} + > + + + handleDelete(faq.id)} + > + + + + + + ))} + + + + ); +}; + +export default AdminFAQList; diff --git a/src/pages/AdminFAQ.tsx b/src/pages/AdminFAQ.tsx index 15b399a..1bcc88d 100644 --- a/src/pages/AdminFAQ.tsx +++ b/src/pages/AdminFAQ.tsx @@ -1,13 +1,9 @@ import { useState, useEffect } from 'react'; -import { Plus, Edit, Trash2, Eye, EyeOff } from 'lucide-react'; -import { Button } from '@/components/ui/button'; -import { Input } from '@/components/ui/input'; -import { Textarea } from '@/components/ui/textarea'; -import { Label } from '@/components/ui/label'; -import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'; import { useToast } from '@/hooks/use-toast'; import { supabase } from '@/integrations/supabase/client'; +import AdminFAQForm from '@/components/admin/AdminFAQForm'; +import AdminFAQList from '@/components/admin/AdminFAQList'; interface FAQ { id: string; @@ -21,13 +17,6 @@ interface FAQ { const AdminFAQ = () => { const [faqs, setFaqs] = useState([]); const [editingFaq, setEditingFaq] = useState(null); - const [formData, setFormData] = useState({ - pergunta: '', - resposta: '', - imagem_url: '', - ativo: true - }); - const [loading, setLoading] = useState(false); const { toast } = useToast(); useEffect(() => { @@ -53,212 +42,30 @@ const AdminFAQ = () => { } }; - const handleSubmit = async (e: React.FormEvent) => { - e.preventDefault(); - setLoading(true); - - try { - if (editingFaq) { - // Atualizar FAQ existente - const { error } = await supabase - .from('faqs') - .update(formData) - .eq('id', editingFaq.id); - - if (error) throw error; - toast({ title: "FAQ atualizado com sucesso!" }); - } else { - // Criar novo FAQ - const { error } = await supabase - .from('faqs') - .insert(formData); - - if (error) throw error; - toast({ title: "FAQ criado com sucesso!" }); - } - - // Reset form - setFormData({ pergunta: '', resposta: '', imagem_url: '', ativo: true }); - setEditingFaq(null); - loadFAQs(); - } catch (error) { - console.error('Erro ao salvar FAQ:', error); - toast({ - title: "Erro", - description: "Não foi possível salvar o FAQ.", - variant: "destructive" - }); - } finally { - setLoading(false); - } + const handleFormSuccess = () => { + setEditingFaq(null); + loadFAQs(); }; - const handleEdit = (faq: FAQ) => { - setEditingFaq(faq); - setFormData({ - pergunta: faq.pergunta, - resposta: faq.resposta, - imagem_url: faq.imagem_url || '', - ativo: faq.ativo - }); - }; - - const handleDelete = async (id: string) => { - if (!confirm('Tem certeza que deseja excluir este FAQ?')) return; - - try { - const { error } = await supabase - .from('faqs') - .delete() - .eq('id', id); - - if (error) throw error; - toast({ title: "FAQ excluído com sucesso!" }); - loadFAQs(); - } catch (error) { - console.error('Erro ao excluir FAQ:', error); - toast({ - title: "Erro", - description: "Não foi possível excluir o FAQ.", - variant: "destructive" - }); - } - }; - - const toggleStatus = async (faq: FAQ) => { - try { - const { error } = await supabase - .from('faqs') - .update({ ativo: !faq.ativo }) - .eq('id', faq.id); - - if (error) throw error; - toast({ title: `FAQ ${!faq.ativo ? 'ativado' : 'desativado'} com sucesso!` }); - loadFAQs(); - } catch (error) { - console.error('Erro ao alterar status:', error); - toast({ - title: "Erro", - description: "Não foi possível alterar o status do FAQ.", - variant: "destructive" - }); - } + const handleCancelEdit = () => { + setEditingFaq(null); }; return ( Gerenciar FAQs - {/* Formulário */} - - - {editingFaq ? 'Editar FAQ' : 'Criar Novo FAQ'} - - - - - Pergunta * - setFormData({ ...formData, pergunta: e.target.value })} - required - /> - + - - Resposta * - setFormData({ ...formData, resposta: e.target.value })} - rows={6} - required - /> - - - - URL da Imagem (opcional) - setFormData({ ...formData, imagem_url: e.target.value })} - placeholder="https://exemplo.com/imagem.jpg" - /> - - - - - {loading ? 'Salvando...' : editingFaq ? 'Atualizar' : 'Criar'} - - {editingFaq && ( - { - setEditingFaq(null); - setFormData({ pergunta: '', resposta: '', imagem_url: '', ativo: true }); - }} - > - Cancelar - - )} - - - - - - {/* Lista de FAQs */} - - - FAQs Cadastrados - - - - {faqs.map((faq) => ( - - - - {faq.pergunta} - - - Status: {faq.ativo ? 'Ativo' : 'Inativo'} - • - {new Date(faq.created_at).toLocaleDateString()} - - - - toggleStatus(faq)} - > - {faq.ativo ? : } - - handleEdit(faq)} - > - - - handleDelete(faq.id)} - > - - - - - - ))} - - - + ); };