forked from StellarSplit/StellarSplit
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathanalyticsDataProvider.ts
More file actions
107 lines (101 loc) · 3.45 KB
/
Copy pathanalyticsDataProvider.ts
File metadata and controls
107 lines (101 loc) · 3.45 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
import { apiClient } from "../utils/api-client";
import type {
SpendingTrend,
CategoryBreakdown,
TopPartner,
DebtBalance,
HeatmapCell,
TimeDistribution,
DateRange,
AnalyticsData,
} from "../types/analytics";
export type AnalyticsSource = "live" | "fixture";
export type AnalyticsMode = "hybrid" | "live-only" | "fixture-only";
export interface AnalyticsResult {
data: AnalyticsData;
source: AnalyticsSource;
}
const MOCK_SPENDING_TRENDS: SpendingTrend[] = [
{ period: "2025-09-01", totalSpent: 420, transactionCount: 8, avgTransactionAmount: 52.5 },
{ period: "2025-10-01", totalSpent: 580, transactionCount: 12, avgTransactionAmount: 48.33 },
{ period: "2025-11-01", totalSpent: 340, transactionCount: 6, avgTransactionAmount: 56.67 },
];
const MOCK_CATEGORY_BREAKDOWN: CategoryBreakdown[] = [
{ category: "Food & Dining", amount: 890 },
{ category: "Entertainment", amount: 420 },
{ category: "Transport", amount: 310 },
];
const MOCK_TOP_PARTNERS: TopPartner[] = [
{ partnerId: "u1", name: "Alice", totalAmount: 650, interactions: 14 },
{ partnerId: "u2", name: "Bob", totalAmount: 420, interactions: 9 },
];
const MOCK_DEBT_BALANCES: DebtBalance[] = [
{ userId: "u1", name: "Alice", amount: 45, direction: "owe" },
{ userId: "u2", name: "Bob", amount: 120.5, direction: "owed" },
];
const MOCK_HEATMAP: HeatmapCell[] = Array.from({ length: 30 }).map((_, i) => {
const d = new Date();
d.setDate(d.getDate() - (29 - i));
const count = i % 6;
return { date: d.toISOString().slice(0, 10), count, total: count * 22 };
});
const MOCK_TIME_DISTRIBUTION: TimeDistribution[] = [
{ label: "Mon", count: 12, amount: 340 },
{ label: "Tue", count: 8, amount: 210 },
{ label: "Wed", count: 15, amount: 480 },
];
function fixtureData(): AnalyticsData {
return {
spendingTrends: MOCK_SPENDING_TRENDS,
categoryBreakdown: MOCK_CATEGORY_BREAKDOWN,
topPartners: MOCK_TOP_PARTNERS,
debtBalances: MOCK_DEBT_BALANCES,
heatmapData: MOCK_HEATMAP,
timeDistribution: MOCK_TIME_DISTRIBUTION,
};
}
async function fetchLive(range?: DateRange): Promise<AnalyticsData> {
const params = {
...(range?.dateFrom && { dateFrom: range.dateFrom }),
...(range?.dateTo && { dateTo: range.dateTo }),
};
const [
spendingTrends,
categoryBreakdown,
topPartners,
debtBalances,
heatmapData,
timeDistribution,
] = await Promise.all([
apiClient.get<SpendingTrend[]>("/api/analytics/spending-trends", { params }),
apiClient.get<CategoryBreakdown[]>("/api/analytics/category-breakdown", { params }),
apiClient.get<TopPartner[]>("/api/analytics/top-partners", { params }),
Promise.resolve({ data: MOCK_DEBT_BALANCES }),
Promise.resolve({ data: MOCK_HEATMAP }),
Promise.resolve({ data: MOCK_TIME_DISTRIBUTION }),
]);
return {
spendingTrends: spendingTrends.data,
categoryBreakdown: categoryBreakdown.data,
topPartners: topPartners.data,
debtBalances: debtBalances.data,
heatmapData: heatmapData.data,
timeDistribution: timeDistribution.data,
};
}
export async function getAnalyticsData(
range?: DateRange,
mode: AnalyticsMode = "hybrid",
): Promise<AnalyticsResult> {
if (mode === "fixture-only") {
return { data: fixtureData(), source: "fixture" };
}
if (mode === "live-only") {
return { data: await fetchLive(range), source: "live" };
}
try {
return { data: await fetchLive(range), source: "live" };
} catch {
return { data: fixtureData(), source: "fixture" };
}
}