Improve delete UX and prepaid credit time display.
Show minutes and local expiry for resource credits; add shared delete hook with row/card loading overlays, detail-page deleting modal, and disabled controls to prevent double-delete. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -18,3 +18,25 @@ export function parseMemoryToMi(mem: string): number {
|
||||
if (mem.endsWith('Ki')) return parseFloat(mem) / 1024;
|
||||
return parseFloat(mem);
|
||||
}
|
||||
|
||||
/** Human-readable time left (days, hours, minutes). */
|
||||
export function formatRemainingDurationMs(remainingMs: number): string {
|
||||
const ms = Math.max(0, remainingMs);
|
||||
const days = Math.floor(ms / 86400000);
|
||||
const hours = Math.floor((ms % 86400000) / 3600000);
|
||||
const minutes = Math.floor((ms % 3600000) / 60000);
|
||||
if (days > 0) return `${days}d ${hours}h ${minutes}m`;
|
||||
if (hours > 0) return `${hours}h ${minutes}m`;
|
||||
if (minutes > 0) return `${minutes}m`;
|
||||
return 'less than 1m';
|
||||
}
|
||||
|
||||
/** Expiry timestamp in the user's locale and timezone. */
|
||||
export function formatExpiresAtLocal(expiresAt: string | Date): string {
|
||||
const date = typeof expiresAt === 'string' ? new Date(expiresAt) : expiresAt;
|
||||
if (Number.isNaN(date.getTime())) return '—';
|
||||
return date.toLocaleString(undefined, {
|
||||
dateStyle: 'medium',
|
||||
timeStyle: 'short',
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user