import { useState, useMemo } from 'react'; import { Plus, Search, Pencil, Trash2, TrendingUp, TrendingDown, ArrowLeftRight, ArrowRightFromLine, Banknote, } from 'lucide-react'; import api, { type Transaction } from '../api'; import TransactionModal from './TransactionModal'; import ConfirmDialog from './ConfirmDialog'; import { Button } from '@/components/ui/button'; import { Input } from '@/components/ui/input'; import { Card, CardContent } from '@/components/ui/card'; import { DataTable } from '@/components/ui/data-table'; import { getTransactionColumns } from '@/components/transactions/transaction-columns'; import { formatAmount } from '@/lib/format'; import { cn } from '@/lib/utils'; export interface TransactionListProps { transactions: Transaction[]; loading: boolean; source: 'CREDIT_CARD' | 'CASH' | 'TRANSFER'; search: string; onSearchChange: (value: string) => void; onRefresh: () => void; emptyIcon?: React.ReactNode; emptyMessage?: string; showCategory?: boolean; showSourceIcon?: boolean; addLabel?: string; onToggleDeferred?: (tx: Transaction) => void; } export default function TransactionList({ transactions, loading, source, search, onSearchChange, onRefresh, emptyIcon, emptyMessage = 'No transactions found', showCategory = true, showSourceIcon = false, addLabel = 'Add Transaction', onToggleDeferred, }: TransactionListProps) { const [modalOpen, setModalOpen] = useState(false); const [editing, setEditing] = useState(null); const [deleteId, setDeleteId] = useState(null); const [deleting, setDeleting] = useState(false); const handleEdit = (tx: Transaction) => { setEditing(tx); setModalOpen(true); }; const handleDelete = async () => { if (deleteId === null) return; setDeleting(true); try { await api.delete(`/transactions/${deleteId}`); setDeleteId(null); onRefresh(); } finally { setDeleting(false); } }; const columns = useMemo( () => getTransactionColumns({ showCategory, showSourceIcon, onEdit: handleEdit, onDelete: (id) => setDeleteId(id), onToggleDeferred }), [showCategory, showSourceIcon, onToggleDeferred], ); const empty = transactions.length === 0 && !loading; return ( <> {/* Search + Add */}
onSearchChange(e.target.value)} className="pl-10" placeholder="Search merchants..." />
{/* Mobile list */} {empty ? (
{emptyIcon || } {emptyMessage}
) : ( transactions.map((tx) => (
{tx.transaction_type === 'DEVOLUCION' ? ( ) : ( )}

{tx.merchant}

{showSourceIcon && ( tx.source === 'CASH' ? : tx.source === 'TRANSFER' ? : null )}

{new Date(tx.date).toLocaleDateString('en-US', { month: 'short', day: 'numeric' })} {showCategory && tx.category && ( {tx.category.name} )}

{tx.transaction_type === 'DEVOLUCION' ? '+' : '-'} {formatAmount(tx.amount, tx.currency)}
{onToggleDeferred && ( )}
)) )}
{/* Desktop table */} {/* Modals */} {modalOpen && ( setModalOpen(false)} onSaved={onRefresh} /> )} {deleteId !== null && ( setDeleteId(null)} loading={deleting} /> )} ); }