import React, { useState, useEffect } from "react"; import { Plus, Edit2, Trash2, X, Save, Search } from "lucide-react"; import { Button } from "../Button"; import { useAuth } from "../../contexts/AuthContext"; import { toast } from "react-hot-toast"; interface SimpleCrudProps { title: string; endpoint: string; columns?: { key: string; label: string }[]; transformData?: (data: any) => any[]; } const API_BASE_URL = import.meta.env.VITE_API_URL || "http://localhost:8080"; export const SimpleCrud: React.FC = ({ title, endpoint, columns = [{ key: "nome", label: "Nome" }], transformData }) => { const { token } = useAuth(); const [items, setItems] = useState([]); const [loading, setLoading] = useState(true); const [isModalOpen, setIsModalOpen] = useState(false); const [editingItem, setEditingItem] = useState(null); const [formData, setFormData] = useState({}); const [searchTerm, setSearchTerm] = useState(""); const fetchItems = async () => { try { setLoading(true); const res = await fetch(`${API_BASE_URL}${endpoint}`, { headers: { Authorization: `Bearer ${token}` } }); if (!res.ok) throw new Error("Falha ao carregar dados"); let data = await res.json(); // Handle different API response structures if needed if (data.data && Array.isArray(data.data)) data = data.data; // Standard ApiResponse structure if (transformData) data = transformData(data); setItems(Array.isArray(data) ? data : []); } catch (error) { console.error(error); toast.error("Erro ao carregar lista"); } finally { setLoading(false); } }; useEffect(() => { if (token) fetchItems(); }, [token, endpoint]); const handleDelete = async (id: string) => { if (!window.confirm("Tem certeza que deseja excluir?")) return; try { const res = await fetch(`${API_BASE_URL}${endpoint}/${id}`, { method: "DELETE", headers: { Authorization: `Bearer ${token}` } }); if (!res.ok) throw new Error("Erro ao excluir"); toast.success("Item excluído com sucesso"); fetchItems(); } catch (error) { toast.error("Erro ao excluir item"); } }; const handleSubmit = async (e: React.FormEvent) => { e.preventDefault(); try { const url = editingItem ? `${API_BASE_URL}${endpoint}/${editingItem.id}` : `${API_BASE_URL}${endpoint}`; const method = editingItem ? "PUT" : "POST"; const res = await fetch(url, { method, headers: { "Content-Type": "application/json", Authorization: `Bearer ${token}` }, body: JSON.stringify(formData) }); if (!res.ok) throw new Error("Erro ao salvar"); toast.success(editingItem ? "Atualizado com sucesso" : "Criado com sucesso"); setIsModalOpen(false); fetchItems(); } catch (error) { console.error(error); toast.error("Erro ao salvar dados"); } }; const openModal = (item?: any) => { setEditingItem(item || null); setFormData(item || {}); setIsModalOpen(true); }; const filteredItems = items.filter(item => columns.some(col => String(item[col.key] || "").toLowerCase().includes(searchTerm.toLowerCase()) ) ); return (

{title}

setSearchTerm(e.target.value)} />
{columns.map(col => ( ))} {loading ? ( ) : filteredItems.length === 0 ? ( ) : ( filteredItems.map((item) => ( {columns.map(col => ( ))} )) )}
{col.label} Ações
Carregando...
Nenhum item encontrado.
{item[col.key]}
{isModalOpen && (

{editingItem ? `Editar ${title}` : `Novo ${title}`}

{columns.map(col => (
setFormData({...formData, [col.key]: e.target.value})} required />
))}
)}
); };