mirror of
https://github.com/tiennm99/ccs.git
synced 2026-07-16 04:18:05 +00:00
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:
@@ -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
@@ -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
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user