"use client" import { Button } from "@/components/ui/button" import { Input } from "@/components/ui/input" import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table" import { CircleCheck, Edit, Trash2 } from "lucide-react" import { useOptimistic, useState } from "react" interface CrudProps { items: T[] columns: { key: keyof T label: string type?: "text" | "number" | "checkbox" defaultValue?: string editable?: boolean }[] onDelete: (id: string) => Promise onAdd: (data: Partial) => Promise onEdit?: (id: string, data: Partial) => Promise } export function CrudTable({ items, columns, onDelete, onAdd, onEdit }: CrudProps) { const [isAdding, setIsAdding] = useState(false) const [editingId, setEditingId] = useState(null) const [newItem, setNewItem] = useState>({}) const [editingItem, setEditingItem] = useState>({}) const [optimisticItems, addOptimisticItem] = useOptimistic(items, (state, newItem: T) => [...state, newItem]) const handleAdd = async () => { try { await onAdd(newItem) setIsAdding(false) setNewItem({}) } catch (error) { console.error("Failed to add item:", error) } } const handleEdit = async (id: string) => { if (!onEdit) return try { await onEdit(id, editingItem) setEditingId(null) setEditingItem({}) } catch (error) { console.error("Failed to edit item:", error) } } const startEditing = (item: T) => { setEditingId(item.code || item.id) setEditingItem(item) } const handleDelete = async (id: string) => { try { await onDelete(id) } catch (error) { console.error("Failed to delete item:", error) } } return (
{columns.map((column) => ( {column.label} ))} Actions {optimisticItems.map((item, index) => ( {columns.map((column) => ( {editingId === (item.code || item.id) && column.editable ? ( setEditingItem({ ...editingItem, [column.key]: column.type === "checkbox" ? e.target.checked : e.target.value, }) } /> ) : column.type === "checkbox" ? ( item[column.key] ? ( ) : ( "" ) ) : ( item[column.key] )} ))}
{editingId === (item.code || item.id) ? ( <> ) : ( <> {onEdit && ( )} {item.isDeletable && ( )} )}
))} {isAdding && ( {columns.map((column) => ( {column.editable && ( setNewItem({ ...newItem, [column.key]: column.type === "checkbox" ? e.target.checked : e.target.value, }) } /> )} ))}
)}
{!isAdding && }
) }