Files
EasyCLIProxyAPI/src/components/useQuotaReset.ts
T
lzt404 a3f5d2e54e feat(quota): add Claude quota reset support
- Add reset counts and actions to auth file and quota pages
- Reuse the Codex confirmation flow with Claude eligibility and cooldown checks
- Preserve request IDs on retries to prevent duplicate credit consumption
- Add translations, regression tests, and layout checks
2026-10-05 00:45:17 +08:00

30 lines
1.5 KiB
TypeScript

import { useCallback } from 'react';
import { useI18n } from '../i18n';
import { hasPendingClaudeReset, resetQuotaWithConfirmation } from '../services/quotaActions';
import { fileName, formatQuotaTimestamp, providerForFile, type AuthFile, type QuotaState } from '../services/quotaService';
import type { ConfirmationOptions } from './ConfirmationDialog';
export function useQuotaReset(
askConfirmation: (options: ConfirmationOptions) => Promise<boolean>,
setError: (message: string) => void,
) {
const { locale, t } = useI18n();
return useCallback(async (file: AuthFile, quota: QuotaState) => {
setError('');
try {
await resetQuotaWithConfirmation(file, () => askConfirmation({
title: t('quota.reset'),
message: t(providerForFile(file) === 'claude' ? 'quota.claude.confirm' : 'quota.confirm.title', { name: fileName(file) }),
confirmText: t(hasPendingClaudeReset(file) ? 'quota.claude.retry' : 'quota.confirm.button'),
details: [
{ label: t('quota.resetCredits'), value: String(quota.resetCredits ?? '—') },
{ label: t('quota.earliestExpiry'), value: formatQuotaTimestamp(quota.resetCreditsEarliestExpiry, locale) },
],
warning: t(providerForFile(file) === 'claude' ? hasPendingClaudeReset(file) ? 'quota.claude.unknown' : 'quota.claude.warning' : 'quota.confirm.warning'),
}));
} catch (requestError) {
setError(requestError instanceof Error ? requestError.message : String(requestError));
}
}, [askConfirmation, locale, setError, t]);
}