From d0bb21000b7372ae723f04de510ccaa11366c103 Mon Sep 17 00:00:00 2001 From: MarvekG Date: Fri, 5 Jun 2026 14:35:01 +0000 Subject: [PATCH] feat(quota): add card refresh actions --- src/components/quota/QuotaCard.tsx | 23 ++++++++++++++++++++++- src/i18n/locales/en.json | 2 ++ src/i18n/locales/zh-CN.json | 2 ++ src/i18n/locales/zh-TW.json | 2 ++ src/pages/QuotaPage.module.scss | 18 ++++++++++++++++++ 5 files changed, 46 insertions(+), 1 deletion(-) diff --git a/src/components/quota/QuotaCard.tsx b/src/components/quota/QuotaCard.tsx index df68fe0..aa1d300 100644 --- a/src/components/quota/QuotaCard.tsx +++ b/src/components/quota/QuotaCard.tsx @@ -5,6 +5,8 @@ import { useTranslation } from 'react-i18next'; import type { ReactElement, ReactNode } from 'react'; import type { TFunction } from 'i18next'; +import { Button } from '@/components/ui/Button'; +import { IconRefreshCw } from '@/components/ui/icons'; import type { AuthFileItem, ResolvedTheme, ThemeColors } from '@/types'; import { TYPE_COLORS } from '@/utils/quota'; import styles from '@/pages/QuotaPage.module.scss'; @@ -89,6 +91,7 @@ export function QuotaCard({ resolvedTheme === 'dark' && typeColorSet.dark ? typeColorSet.dark : typeColorSet.light; const quotaStatus = quota?.status ?? 'idle'; + const quotaLoading = quotaStatus === 'loading'; const quotaErrorMessage = resolveQuotaErrorMessage( t, quota?.errorStatus, @@ -121,7 +124,7 @@ export function QuotaCard({
- {quotaStatus === 'loading' ? ( + {quotaLoading ? (
{t(`${i18nPrefix}.loading`)}
) : quotaStatus === 'idle' ? ( onRefresh ? ( @@ -148,6 +151,24 @@ export function QuotaCard({
{t(idleMessageKey)}
)}
+ + {onRefresh && ( +
+ +
+ )} ); } diff --git a/src/i18n/locales/en.json b/src/i18n/locales/en.json index dab3664..777eb23 100644 --- a/src/i18n/locales/en.json +++ b/src/i18n/locales/en.json @@ -368,6 +368,8 @@ "prefix_proxy_invalid_json": "This auth file is not a JSON object, so fields cannot be edited.", "prefix_proxy_html_challenge": "Downloaded content is an HTML challenge page, not an auth JSON object. Re-authenticate or replace this auth file before editing fields.", "prefix_proxy_saved_success": "Updated auth file \"{{name}}\" successfully", + "quota_refresh_single": "Refresh quota", + "quota_refresh_hint": "Refresh quota only for this credential", "quota_refresh_success": "Quota refreshed for \"{{name}}\"", "quota_refresh_failed": "Failed to refresh quota for \"{{name}}\": {{message}}" }, diff --git a/src/i18n/locales/zh-CN.json b/src/i18n/locales/zh-CN.json index 9f36295..e671bf4 100644 --- a/src/i18n/locales/zh-CN.json +++ b/src/i18n/locales/zh-CN.json @@ -368,6 +368,8 @@ "prefix_proxy_invalid_json": "该认证文件不是 JSON 对象,无法编辑字段。", "prefix_proxy_html_challenge": "下载到的是 HTML 验证页面,不是认证 JSON 对象。请重新认证或替换该认证文件后再编辑字段。", "prefix_proxy_saved_success": "已更新认证文件 \"{{name}}\"", + "quota_refresh_single": "刷新额度", + "quota_refresh_hint": "仅刷新该认证文件的额度", "quota_refresh_success": "已刷新 \"{{name}}\" 的额度", "quota_refresh_failed": "刷新 \"{{name}}\" 的额度失败:{{message}}" }, diff --git a/src/i18n/locales/zh-TW.json b/src/i18n/locales/zh-TW.json index d2e166b..e75d1a9 100644 --- a/src/i18n/locales/zh-TW.json +++ b/src/i18n/locales/zh-TW.json @@ -368,6 +368,8 @@ "prefix_proxy_invalid_json": "該驗證檔案不是 JSON 物件,無法編輯欄位。", "prefix_proxy_html_challenge": "下載到的是 HTML 驗證頁面,不是驗證 JSON 物件。請重新驗證或替換該驗證檔案後再編輯欄位。", "prefix_proxy_saved_success": "已更新驗證檔案「{{name}}」", + "quota_refresh_single": "重新整理配額", + "quota_refresh_hint": "僅重新整理該驗證檔案的配額", "quota_refresh_success": "已重新整理「{{name}}」的配額", "quota_refresh_failed": "重新整理「{{name}}」的配額失敗:{{message}}" }, diff --git a/src/pages/QuotaPage.module.scss b/src/pages/QuotaPage.module.scss index 2ba5ad4..fda1ad9 100644 --- a/src/pages/QuotaPage.module.scss +++ b/src/pages/QuotaPage.module.scss @@ -392,6 +392,24 @@ } } +.quotaCardActions { + display: flex; + justify-content: flex-end; + padding-top: $spacing-xs; +} + +.quotaRefreshButton:global(.btn.btn-sm) { + border-radius: 999px; + padding-inline: 12px; + + > span { + display: inline-flex; + align-items: center; + gap: 6px; + white-space: nowrap; + } +} + .quotaError { font-size: 12px; color: var(--danger-color);