Skip to content

Commit 684d267

Browse files
committed
feat: better reset dates
1 parent d3162e7 commit 684d267

File tree

1 file changed

+36
-23
lines changed

1 file changed

+36
-23
lines changed

apps/dashboard/app/(main)/billing/utils/feature-usage.ts

Lines changed: 36 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,7 @@ export function calculateFeatureUsage(feature: CustomerFeature): FeatureUsage {
4040
} else if (reportedUsage > 0) {
4141
actualUsed = reportedUsage;
4242
} else if (reportedUsage < 0) {
43-
actualUsed = Math.max(
44-
0,
45-
includedUsage - balance + Math.abs(reportedUsage)
46-
);
43+
actualUsed = Math.max(0, includedUsage - balance + Math.abs(reportedUsage));
4744
} else {
4845
actualUsed = Math.max(0, includedUsage - balance);
4946
}
@@ -76,36 +73,52 @@ export function calculateAllFeatureUsage(
7673
}
7774

7875
export function formatCompactNumber(num: number): string {
79-
if (num >= 1_000_000_000_000) return `${(num / 1_000_000_000_000).toFixed(1)}T`;
76+
if (num >= 1_000_000_000_000)
77+
return `${(num / 1_000_000_000_000).toFixed(1)}T`;
8078
if (num >= 1_000_000_000) return `${(num / 1_000_000_000).toFixed(1)}B`;
8179
if (num >= 1_000_000) return `${(num / 1_000_000).toFixed(1)}M`;
82-
if (num >= 10_000) return `${(num / 1_000).toFixed(0)}K`;
80+
if (num >= 10_000) return `${(num / 1000).toFixed(0)}K`;
8381
return num.toLocaleString();
8482
}
8583

8684
const INTERVAL_LABELS: Record<string, string> = {
87-
day: "daily",
88-
month: "monthly",
89-
year: "yearly",
90-
lifetime: "never",
85+
day: "Daily",
86+
month: "Monthly",
87+
year: "Yearly",
88+
lifetime: "Lifetime",
9189
};
9290

9391
export function getResetText(feature: FeatureUsage): string {
94-
if (feature.interval === "lifetime") return "Never expires";
95-
if (!feature.resetAt) return "No reset scheduled";
92+
if (feature.interval === "lifetime") {
93+
return "Never expires";
94+
}
95+
if (!feature.resetAt) {
96+
return "No reset scheduled";
97+
}
9698

97-
const intervalLabel = feature.interval ? INTERVAL_LABELS[feature.interval] : null;
98-
const relativeText = feature.resetRelative;
99+
const resetDate = dayjs(feature.resetAt);
100+
const now = dayjs();
101+
const hoursUntil = resetDate.diff(now, "hour");
102+
const daysUntil = resetDate.diff(now, "day");
99103

100-
if (intervalLabel && relativeText) {
101-
return `Resets ${intervalLabel} · ${relativeText}`;
102-
}
103-
if (relativeText) {
104-
return `Resets ${relativeText}`;
104+
let resetString = "";
105+
106+
if (hoursUntil <= 0) {
107+
resetString = "Resets soon";
108+
} else if (hoursUntil < 24) {
109+
resetString = `Resets in ${hoursUntil}h`;
110+
} else if (daysUntil <= 1) {
111+
resetString = "Resets tomorrow";
112+
} else if (daysUntil < 14) {
113+
resetString = `Resets in ${daysUntil}d`;
114+
} else {
115+
resetString = `Resets on ${resetDate.format("MMM D")}`;
105116
}
106-
if (feature.resetDateFormatted) {
107-
return `Resets ${feature.resetDateFormatted}`;
117+
118+
if (feature.interval && INTERVAL_LABELS[feature.interval]) {
119+
const label = INTERVAL_LABELS[feature.interval];
120+
return `${label} limit · ${resetString}`;
108121
}
109-
return "No reset scheduled";
110-
}
111122

123+
return resetString;
124+
}

0 commit comments

Comments
 (0)