fix(ui): show Claude reset time for quota display (not earliest)

- add getClaudeResetTime to match getMinClaudeQuota logic

- weekly Claude resets now show absolute date (01/27, 12:07)

- daily Gemini resets no longer overshadow Claude weekly limits
This commit is contained in:
kaitranntt
2026-01-25 16:38:54 -05:00
parent 6021c10ddc
commit 9516e71f17
3 changed files with 50 additions and 11 deletions
@@ -6,7 +6,7 @@ import {
cn,
sortModelsByPriority,
formatResetTime,
getEarliestResetTime,
getClaudeResetTime,
getMinClaudeQuota,
} from '@/lib/utils';
import { PRIVACY_BLUR_CLASS } from '@/contexts/privacy-context';
@@ -226,7 +226,7 @@ export function AccountCard({
</div>
))}
{(() => {
const resetTime = getEarliestResetTime(quota?.models || []);
const resetTime = getClaudeResetTime(quota?.models || []);
return resetTime ? (
<div className="flex items-center gap-1.5 mt-2 pt-2 border-t border-border/50">
<Clock className="w-3 h-3 text-blue-400" />
@@ -33,7 +33,7 @@ import {
cn,
sortModelsByPriority,
formatResetTime,
getEarliestResetTime,
getClaudeResetTime,
getMinClaudeQuota,
} from '@/lib/utils';
import { PRIVACY_BLUR_CLASS } from '@/contexts/privacy-context';
@@ -121,7 +121,7 @@ export function AccountItem({
// Get earliest reset time
const nextReset =
quota?.success && quota.models.length > 0 ? getEarliestResetTime(quota.models) : null;
quota?.success && quota.models.length > 0 ? getClaudeResetTime(quota.models) : null;
return (
<div
+46 -7
View File
@@ -81,7 +81,7 @@ export function sortModelsByPriority<T extends { name: string; displayName?: str
}
/**
* Format reset time as relative time (e.g., "in 2h 30m")
* Format reset time - relative for <24h, absolute date for >=24h (weekly limits)
*/
export function formatResetTime(resetTime: string | null): string | null {
if (!resetTime) return null;
@@ -92,8 +92,19 @@ export function formatResetTime(resetTime: string | null): string | null {
if (diff <= 0) return 'soon';
const hours = Math.floor(diff / (1000 * 60 * 60));
const minutes = Math.floor((diff % (1000 * 60 * 60)) / (1000 * 60));
// Weekly/long resets: show absolute date (e.g., "01/27, 12:07")
if (hours >= 24) {
return reset.toLocaleDateString(undefined, {
month: '2-digit',
day: '2-digit',
hour: '2-digit',
minute: '2-digit',
});
}
// Daily resets: show relative time
const minutes = Math.floor((diff % (1000 * 60 * 60)) / (1000 * 60));
if (hours > 0) return `in ${hours}h ${minutes}m`;
return `in ${minutes}m`;
} catch {
@@ -117,6 +128,16 @@ export function getEarliestResetTime<T extends { resetTime: string | null }>(
);
}
/**
* Filter to get Claude models from a model array
*/
function filterClaudeModels<T extends { name: string; displayName?: string }>(models: T[]): T[] {
return models.filter((m) => {
const name = (m.displayName || m.name || '').toLowerCase();
return name.includes('claude');
});
}
/**
* Calculate the minimum quota percentage from Claude models (primary usage).
* Falls back to minimum of all models if no Claude models exist.
@@ -127,11 +148,7 @@ export function getMinClaudeQuota<
>(models: T[]): number | null {
if (models.length === 0) return null;
const claudeModels = models.filter((m) => {
const name = (m.displayName || m.name || '').toLowerCase();
return name.includes('claude');
});
const claudeModels = filterClaudeModels(models);
const targetModels = claudeModels.length > 0 ? claudeModels : models;
const percentages = targetModels
.map((m) => m.percentage)
@@ -140,3 +157,25 @@ export function getMinClaudeQuota<
if (percentages.length === 0) return null;
return Math.min(...percentages);
}
/**
* Get reset time for Claude models (matches getMinClaudeQuota logic).
* Shows when the Claude quota will reset, not just earliest across all models.
*/
export function getClaudeResetTime<
T extends { name: string; displayName?: string; resetTime: string | null },
>(models: T[]): string | null {
if (models.length === 0) return null;
const claudeModels = filterClaudeModels(models);
const targetModels = claudeModels.length > 0 ? claudeModels : models;
return targetModels.reduce(
(earliest, m) => {
if (!m.resetTime) return earliest;
if (!earliest) return m.resetTime;
return new Date(m.resetTime) < new Date(earliest) ? m.resetTime : earliest;
},
null as string | null
);
}