anycoder-380d34cb / components /TransactionList.js
spdniloy's picture
Upload components/TransactionList.js with huggingface_hub
fa9dbcb verified
Raw
History Blame Contribute Delete
3.35 kB
import { Edit2, Trash2 } from 'lucide-react';
export default function TransactionList({
transactions,
type,
onEdit,
onDelete,
emptyMessage,
}) {
const formatCurrency = (amount) => {
return new Intl.NumberFormat('en-US', {
style: 'currency',
currency: 'USD',
minimumFractionDigits: 2,
}).format(amount);
};
const formatDate = (dateStr) => {
const date = new Date(dateStr);
return new Intl.DateTimeFormat('en-US', {
month: 'short',
day: 'numeric',
year: 'numeric',
}).format(date);
};
const filtered = transactions.filter((t) => t.type === type);
if (filtered.length === 0) {
return (
<div className="text-center py-12">
<p className="text-neutral-400">{emptyMessage}</p>
</div>
);
}
return (
<div className="overflow-hidden">
<ul className="divide-y divide-neutral-100">
{filtered.map((transaction) => (
<li
key={transaction.id}
className="px-4 py-4 hover:bg-neutral-50 transition-colors duration-150 group"
>
<div className="flex items-center justify-between">
<div className="flex-1 min-w-0">
<div className="flex items-center gap-2">
<span className="font-medium text-neutral-800 truncate">
{transaction.category}
</span>
<span className={`text-xs px-2 py-0.5 rounded-full ${
type === 'income'
? 'bg-income-light text-income-dark'
: 'bg-expense-light text-expense-dark'
}`}>
{transaction.category}
</span>
</div>
{transaction.description && (
<p className="text-sm text-neutral-500 mt-1 truncate">
{transaction.description}
</p>
)}
<p className="text-xs text-neutral-400 mt-1">
{formatDate(transaction.date)}
</p>
</div>
<div className="flex items-center gap-3">
<span className={`font-semibold ${
type === 'income' ? 'text-income-dark' : 'text-expense-dark'
}`}>
{type === 'income' ? '+' : '-'}{formatCurrency(transaction.amount)}
</span>
<div className="flex items-center gap-1 opacity-0 group-hover:opacity-100 transition-opacity">
<button
onClick={() => onEdit(transaction)}
className="p-2 text-neutral-400 hover:text-primary-600 rounded-lg hover:bg-primary-50 transition-colors"
aria-label="Edit"
>
<Edit2 className="w-4 h-4" />
</button>
<button
onClick={() => onDelete(transaction.id)}
className="p-2 text-neutral-400 hover:text-expense-DEFAULT rounded-lg hover:bg-expense-light transition-colors"
aria-label="Delete"
>
<Trash2 className="w-4 h-4" />
</button>
</div>
</div>
</div>
</li>
))}
</ul>
</div>
);
}