spdniloy/anycoder-380d34cb
0
1import { Edit2, Trash2 } from 'lucide-react';2 3export default function TransactionList({4 transactions,5 type,6 onEdit,7 onDelete,8 emptyMessage,9}) {10 const formatCurrency = (amount) => {11 return new Intl.NumberFormat('en-US', {12 style: 'currency',13 currency: 'USD',14 minimumFractionDigits: 2,15 }).format(amount);16 };17 18 const formatDate = (dateStr) => {19 const date = new Date(dateStr);20 return new Intl.DateTimeFormat('en-US', {21 month: 'short',22 day: 'numeric',23 year: 'numeric',24 }).format(date);25 };26 27 const filtered = transactions.filter((t) => t.type === type);28 29 if (filtered.length === 0) {30 return (31 <div className="text-center py-12">32 <p className="text-neutral-400">{emptyMessage}</p>33 </div>34 );35 }36 37 return (38 <div className="overflow-hidden">39 <ul className="divide-y divide-neutral-100">40 {filtered.map((transaction) => (41 <li42 key={transaction.id}43 className="px-4 py-4 hover:bg-neutral-50 transition-colors duration-150 group"44 >45 <div className="flex items-center justify-between">46 <div className="flex-1 min-w-0">47 <div className="flex items-center gap-2">48 <span className="font-medium text-neutral-800 truncate">49 {transaction.category}50 </span>51 <span className={`text-xs px-2 py-0.5 rounded-full ${52 type === 'income'53 ? 'bg-income-light text-income-dark'54 : 'bg-expense-light text-expense-dark'55 }`}>56 {transaction.category}57 </span>58 </div>59 {transaction.description && (60 <p className="text-sm text-neutral-500 mt-1 truncate">61 {transaction.description}62 </p>63 )}64 <p className="text-xs text-neutral-400 mt-1">65 {formatDate(transaction.date)}66 </p>67 </div>68 <div className="flex items-center gap-3">69 <span className={`font-semibold ${70 type === 'income' ? 'text-income-dark' : 'text-expense-dark'71 }`}>72 {type === 'income' ? '+' : '-'}{formatCurrency(transaction.amount)}73 </span>74 <div className="flex items-center gap-1 opacity-0 group-hover:opacity-100 transition-opacity">75 <button76 onClick={() => onEdit(transaction)}77 className="p-2 text-neutral-400 hover:text-primary-600 rounded-lg hover:bg-primary-50 transition-colors"78 aria-label="Edit"79 >80 <Edit2 className="w-4 h-4" />81 </button>82 <button83 onClick={() => onDelete(transaction.id)}84 className="p-2 text-neutral-400 hover:text-expense-DEFAULT rounded-lg hover:bg-expense-light transition-colors"85 aria-label="Delete"86 >87 <Trash2 className="w-4 h-4" />88 </button>89 </div>90 </div>91 </div>92 </li>93 ))}94 </ul>95 </div>96 );97}