forked from StellarSplit/StellarSplit
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathSplitTimeline.tsx
More file actions
70 lines (64 loc) · 2.36 KB
/
Copy pathSplitTimeline.tsx
File metadata and controls
70 lines (64 loc) · 2.36 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
import { formatDate, formatCurrency } from "../../utils/format";
import type { HistorySplit } from "../../pages/SplitHistoryPage";
import { SplitCard } from "./SplitCard";
interface SplitTimelineProps {
splits: HistorySplit[];
}
export function SplitTimeline({ splits }: SplitTimelineProps) {
// Group by month-year for headers
const groups = splits.reduce<Record<string, HistorySplit[]>>((acc, s) => {
const d = new Date(s.date);
const key = `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, "0")}`;
(acc[key] ||= []).push(s);
return acc;
}, {});
const orderedKeys = Object.keys(groups).sort((a, b) => (a > b ? -1 : 1));
return (
<div className="relative">
<div className="absolute left-4 sm:left-6 top-0 bottom-0 w-px bg-gray-200 dark:bg-gray-700" />
<div className="space-y-8">
{orderedKeys.map((k) => (
<div key={k}>
<div className="flex items-center gap-3 mb-4">
<div className="w-2 h-2 rounded-full bg-purple-600" />
<h3 className="text-sm font-semibold text-gray-700 dark:text-gray-300">
{formatMonthKey(k)}
</h3>
</div>
<div className="space-y-4">
{groups[k].map((s) => (
<TimelineRow key={s.id} split={s} />
))}
</div>
</div>
))}
</div>
</div>
);
}
function TimelineRow({ split }: { split: HistorySplit }) {
return (
<div className="relative flex items-start gap-4">
<div className="relative">
<div className="w-8 h-8 rounded-full bg-white dark:bg-gray-900 border border-gray-300 dark:border-gray-700 flex items-center justify-center">
<span className="w-2.5 h-2.5 rounded-full bg-purple-600" />
</div>
</div>
<div className="flex-1">
<SplitCard
title={split.title}
subtitle={formatDate(split.date)}
amountLabel={formatCurrency(split.totalAmount, split.currency)}
status={split.status}
role={split.role}
participants={split.participants.map((p) => p.name)}
/>
</div>
</div>
);
}
function formatMonthKey(key: string): string {
const [year, month] = key.split("-").map((n) => Number(n));
const d = new Date(year, month - 1, 1);
return d.toLocaleDateString(undefined, { month: "long", year: "numeric" });
}