Files
openchamber/packages/ui/src/lib/quota/utils.ts
T

100 lines
3.4 KiB
TypeScript

import { formatMessage, useI18nStore } from '@/lib/i18n/store';
import { formatDateTimeForPreference, formatTimeForPreference } from '@/lib/timeFormat';
import type { TimeFormatPreference } from '@/stores/useUIStore';
const t = (key: Parameters<typeof formatMessage>[1]) => formatMessage(useI18nStore.getState().dictionary, key);
export const clampPercent = (value: number | null): number | null => {
if (typeof value !== 'number' || !Number.isFinite(value)) {
return null;
}
return Math.max(0, Math.min(100, Math.round(value)));
};
export const formatPercent = (value: number | null): string => {
if (typeof value !== 'number' || !Number.isFinite(value)) {
return '-';
}
return `${Math.round(value)}%`;
};
export const formatQuotaValueLabel = (
valueLabel: string | null | undefined,
percent: number | null,
): string => {
return valueLabel ?? formatPercent(percent);
};
export const formatQuotaResetLabel = (
resetAt: number | null,
fallback?: string | null,
timeFormatPreference: TimeFormatPreference = 'auto',
): string => {
if (!resetAt) {
return fallback ?? '';
}
try {
const resetDate = new Date(resetAt);
if (!Number.isFinite(resetDate.getTime())) {
return fallback ?? '';
}
const now = new Date();
const isToday = resetDate.toDateString() === now.toDateString();
if (isToday) {
return formatTimeForPreference(resetDate, timeFormatPreference, { fallback: fallback ?? '' });
}
return formatDateTimeForPreference(resetDate, timeFormatPreference, {
month: 'short',
day: 'numeric',
weekday: 'short',
hour: 'numeric',
minute: '2-digit',
});
} catch {
return fallback ?? '';
}
};
export const resolveUsageTone = (percent: number | null): 'safe' | 'warn' | 'critical' => {
if (percent === null) {
return 'safe';
}
if (percent >= 80) {
return 'critical';
}
if (percent >= 50) {
return 'warn';
}
return 'safe';
};
export const formatWindowLabel = (label: string): string => {
if (label === '5h') return t('quota.window.5h');
if (label === '7d') return t('quota.window.7d');
if (label === 'extra_usage') return t('quota.window.extraUsage');
if (label === 'weekly') return t('quota.window.weekly');
if (label === 'daily') return t('quota.window.daily');
if (label === 'monthly') return t('quota.window.monthly');
if (label === 'credits') return t('quota.window.credits');
if (label === 'credits_balance') return t('quota.window.creditsBalance');
if (label === 'monthly_credits') return t('quota.window.monthlyCredits');
if (label === 'purchased_credits') return t('quota.window.purchasedCredits');
if (label === 'free_credits') return t('quota.window.freeCredits');
if (label === 'billing_cycle') return t('quota.window.billingCycle');
if (label === 'plan_limit') return t('quota.window.planLimit');
if (label === 'auto') return t('quota.window.auto');
if (label === 'api') return t('quota.window.api');
if (label === 'plan_limit') return t('quota.window.planLimit');
if (label === 'on_demand') return t('quota.window.onDemand');
if (label === 'session') return t('quota.window.session');
if (label === 'premium') return t('quota.window.premium');
if (label === 'chat') return t('quota.window.chat');
if (label === 'completions') return t('quota.window.completions');
if (label === 'premium_interactions') return t('quota.window.premiumInteractions');
return label;
};