forked from MergeFi/frontend
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathutils.ts
More file actions
72 lines (62 loc) · 2.43 KB
/
Copy pathutils.ts
File metadata and controls
72 lines (62 loc) · 2.43 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
import { clsx, type ClassValue } from "clsx";
import { twMerge } from "tailwind-merge";
export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs));
}
export function coerceDecimal(value: string | null | undefined, fallback = 0): number {
if (value == null) return fallback;
const n = Number(value);
if (!Number.isFinite(n)) return fallback;
return n;
}
export function coerceNonNegative(value: string | null | undefined, fallback = 0): number {
const n = coerceDecimal(value, fallback);
return n < 0 ? fallback : n;
}
export function coerceFraction(value: string | null | undefined, fallback = 0): number {
const n = coerceDecimal(value, fallback);
if (n < 0) return 0;
if (n > 1) return 1;
return n;
}
export function coercePercentage(value: string | null | undefined, fallback = 0): number {
const n = coerceDecimal(value, fallback);
if (n < 0) return 0;
if (n > 100) return 100;
return n;
}
export function formatCurrency(amount: number, asset: "USDC" | "XLM" = "USDC") {
if (!Number.isFinite(amount)) return `0 ${asset}`;
const abs = Math.abs(amount);
return `${abs.toLocaleString("en-US", { maximumFractionDigits: 2 })} ${asset}`;
}
export function formatPercent(value: number) {
if (!Number.isFinite(value)) return "0%";
return `${Math.round(value * 100)}%`;
}
export function daysUntil(dateIso: string) {
const diffMs = new Date(dateIso).getTime() - Date.now();
return Math.ceil(diffMs / (1000 * 60 * 60 * 24));
}
export function validateTeamSplits(splits: { percentage: number }[]): { valid: boolean; sum: number; message?: string } {
if (!splits || splits.length === 0) return { valid: true, sum: 0 };
const sum = splits.reduce((acc, s) => acc + (s.percentage ?? 0), 0);
const tolerance = 0.01; // 0.01% tolerance for floating point
const valid = Math.abs(sum - 100) <= tolerance;
return { valid, sum, message: valid ? undefined : `Team splits sum to ${sum.toFixed(2)}% (expected 100%)` };
}
export function validateTeamSplits(
splits: Array<{ percentage: string | number }>,
tolerance = 0.01
): { valid: boolean; sum: number; message?: string } {
const percentages = splits.map((s) =>
typeof s.percentage === "string" ? Number(s.percentage) : s.percentage
);
const sum = percentages.reduce((a, b) => a + b, 0);
const valid = Math.abs(sum - 100) <= tolerance;
return {
valid,
sum,
message: valid ? undefined : `Team splits sum to ${sum.toFixed(2)}% (expected 100%)`,
};
}