forked from Creditra/Creditra-Frontend
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathRecentTransactionsRail.tsx
More file actions
108 lines (101 loc) · 4.33 KB
/
Copy pathRecentTransactionsRail.tsx
File metadata and controls
108 lines (101 loc) · 4.33 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
import { Link } from 'react-router-dom';
import { Skeleton } from './Skeleton';
import { COLOR, fmt } from '../utils/tokens';
import type { Transaction, TransactionType } from '../types/creditLine';
import './RecentTransactionsRail.css';
type RichTransaction = Transaction & { lineName: string; lineId: string };
interface RecentTransactionsRailProps {
transactions: RichTransaction[];
loading?: boolean;
}
const relativeTime = (iso: string): string => {
const diff = Date.now() - new Date(iso).getTime();
const mins = Math.floor(diff / 60000);
if (mins < 60) return `${mins}m ago`;
const hrs = Math.floor(mins / 60);
if (hrs < 24) return `${hrs}h ago`;
const days = Math.floor(hrs / 24);
if (days < 30) return `${days}d ago`;
return new Date(iso).toLocaleDateString('en-US', { month: 'short', day: 'numeric', year: 'numeric' });
};
const TX_ICON: Record<TransactionType, string> = {
Draw: '\u2197',
Repay: '\u2199',
Fee: '\uD83D\uDCCB',
Interest: '\uD83D\uDCC8',
StatusChange: '\uD83D\uDD04',
};
const TX_COLOR: Record<TransactionType, string> = {
Draw: COLOR.danger,
Repay: COLOR.success,
Fee: COLOR.muted,
Interest: COLOR.warning,
StatusChange: COLOR.muted,
};
const fmtAmount = (type: TransactionType, amount: number) =>
`${type === 'Repay' ? '+' : '-'}${fmt(amount)}`;
export function RecentTransactionsRail({ transactions, loading = false }: RecentTransactionsRailProps) {
return (
<div className="recent-transactions-rail" role="region" aria-label="Recent transactions">
{loading ? (
<>
<div className="activity-item">
<Skeleton className="activity-icon" style={{ borderRadius: '6px' }} />
<div className="activity-content" style={{ display: 'flex', flexDirection: 'column', gap: '0.4rem' }}>
<Skeleton style={{ width: '120px', height: '14px', borderRadius: '2px' }} />
<Skeleton style={{ width: '180px', height: '10px', borderRadius: '2px' }} />
</div>
<Skeleton style={{ width: '60px', height: '14px', marginLeft: 'auto', borderRadius: '2px' }} />
</div>
<div className="activity-item">
<Skeleton className="activity-icon" style={{ borderRadius: '6px' }} />
<div className="activity-content" style={{ display: 'flex', flexDirection: 'column', gap: '0.4rem' }}>
<Skeleton style={{ width: '100px', height: '14px', borderRadius: '2px' }} />
<Skeleton style={{ width: '150px', height: '10px', borderRadius: '2px' }} />
</div>
<Skeleton style={{ width: '50px', height: '14px', marginLeft: 'auto', borderRadius: '2px' }} />
</div>
<div className="activity-item">
<Skeleton className="activity-icon" style={{ borderRadius: '6px' }} />
<div className="activity-content" style={{ display: 'flex', flexDirection: 'column', gap: '0.4rem' }}>
<Skeleton style={{ width: '140px', height: '14px', borderRadius: '2px' }} />
<Skeleton style={{ width: '160px', height: '10px', borderRadius: '2px' }} />
</div>
<Skeleton style={{ width: '70px', height: '14px', marginLeft: 'auto', borderRadius: '2px' }} />
</div>
</>
) : transactions.length === 0 ? (
<p className="rtr-empty" role="status">
No transactions yet
</p>
) : (
<>
{transactions.map((tx, i) => (
<div key={`${tx.id}-${i}`} className="activity-item">
<div
className="activity-icon"
style={{
background: `${TX_COLOR[tx.type]}15`,
color: TX_COLOR[tx.type],
}}
aria-hidden="true"
>
{TX_ICON[tx.type]}
</div>
<div className="activity-content">
<div className="activity-title">{tx.note || tx.type}</div>
<div className="activity-sub">{tx.lineName} · {relativeTime(tx.date)}</div>
</div>
<div className="activity-amount" style={{ color: TX_COLOR[tx.type] }}>
{fmtAmount(tx.type, tx.amount)}
</div>
</div>
))}
<Link to="/transactions" className="rtr-view-all">
View all transactions →
</Link>
</>
)}
</div>
);
}