59 lines
2.1 KiB
TypeScript
59 lines
2.1 KiB
TypeScript
import Link from 'next/link'
|
|
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'
|
|
import { formatCents } from '@/lib/utils/currency'
|
|
import { ArrowRight } from 'lucide-react'
|
|
|
|
interface RecentTx {
|
|
id: string
|
|
date: string
|
|
description: string
|
|
amountCents: number
|
|
type: string
|
|
accountName: string
|
|
}
|
|
|
|
export function RecentTransactions({ transactions }: { transactions: RecentTx[] }) {
|
|
return (
|
|
<Card>
|
|
<CardHeader className="pb-2 flex flex-row items-center justify-between space-y-0">
|
|
<CardTitle className="text-sm font-medium text-muted-foreground">Recent Transactions</CardTitle>
|
|
<Link
|
|
href="/transactions"
|
|
className="flex items-center gap-1 text-xs text-muted-foreground hover:text-foreground transition-colors"
|
|
>
|
|
View all <ArrowRight className="h-3 w-3" />
|
|
</Link>
|
|
</CardHeader>
|
|
<CardContent>
|
|
{transactions.length === 0 ? (
|
|
<p className="text-sm text-muted-foreground py-4 text-center">No transactions yet.</p>
|
|
) : (
|
|
<div className="space-y-3">
|
|
{transactions.map((tx) => {
|
|
const date = new Date(tx.date)
|
|
const label = date.toLocaleDateString('en-US', { month: 'short', day: 'numeric' })
|
|
return (
|
|
<div key={tx.id} className="flex items-start justify-between gap-2">
|
|
<div className="min-w-0">
|
|
<p className="text-sm font-medium truncate">{tx.description}</p>
|
|
<p className="text-xs text-muted-foreground">
|
|
{label} · {tx.accountName}
|
|
</p>
|
|
</div>
|
|
<span
|
|
className={`text-sm font-medium tabular-nums shrink-0 ${
|
|
tx.type === 'CREDIT' ? 'text-green-600' : 'text-foreground'
|
|
}`}
|
|
>
|
|
{tx.type === 'CREDIT' ? '+' : '-'}{formatCents(tx.amountCents)}
|
|
</span>
|
|
</div>
|
|
)
|
|
})}
|
|
</div>
|
|
)}
|
|
</CardContent>
|
|
</Card>
|
|
)
|
|
}
|