feat(usage): add last refresh timestamp in header

This commit is contained in:
Supra4E8C
2026-02-13 13:33:47 +08:00
parent 180a4ccab4
commit c4ca9be7b5
6 changed files with 22 additions and 3 deletions

View File

@@ -17,6 +17,7 @@ export interface UseUsageDataReturn {
usage: UsagePayload | null;
loading: boolean;
error: string;
lastRefreshedAt: Date | null;
modelPrices: Record<string, ModelPrice>;
setModelPrices: (prices: Record<string, ModelPrice>) => void;
loadUsage: () => Promise<void>;
@@ -38,6 +39,7 @@ export function useUsageData(): UseUsageDataReturn {
const [modelPrices, setModelPrices] = useState<Record<string, ModelPrice>>({});
const [exporting, setExporting] = useState(false);
const [importing, setImporting] = useState(false);
const [lastRefreshedAt, setLastRefreshedAt] = useState<Date | null>(null);
const importInputRef = useRef<HTMLInputElement | null>(null);
const loadUsage = useCallback(async () => {
@@ -47,6 +49,7 @@ export function useUsageData(): UseUsageDataReturn {
const data = await usageApi.getUsage();
const payload = (data?.usage ?? data) as unknown;
setUsage(payload && typeof payload === 'object' ? (payload as UsagePayload) : null);
setLastRefreshedAt(new Date());
} catch (err: unknown) {
const message = err instanceof Error ? err.message : t('usage_stats.loading_error');
setError(message);
@@ -140,6 +143,7 @@ export function useUsageData(): UseUsageDataReturn {
usage,
loading,
error,
lastRefreshedAt,
modelPrices,
setModelPrices: handleSetModelPrices,
loadUsage,

View File

@@ -817,7 +817,8 @@
"credential_name": "Credential",
"token_breakdown": "Token Type Breakdown",
"input_tokens": "Input Tokens",
"output_tokens": "Output Tokens"
"output_tokens": "Output Tokens",
"last_updated": "Updated"
},
"stats": {
"success": "Success",

View File

@@ -820,7 +820,8 @@
"credential_name": "Учётные данные",
"token_breakdown": "Распределение типов токенов",
"input_tokens": "Входные токены",
"output_tokens": "Выходные токены"
"output_tokens": "Выходные токены",
"last_updated": "Обновлено"
},
"stats": {
"success": "Успех",

View File

@@ -817,7 +817,8 @@
"credential_name": "凭证",
"token_breakdown": "Token 类型分布",
"input_tokens": "输入 Tokens",
"output_tokens": "输出 Tokens"
"output_tokens": "输出 Tokens",
"last_updated": "更新于"
},
"stats": {
"success": "成功",

View File

@@ -25,6 +25,12 @@
flex-wrap: wrap;
}
.lastRefreshed {
font-size: 11px;
color: var(--text-tertiary);
white-space: nowrap;
}
.timeRangeGroup {
display: inline-flex;
align-items: center;

View File

@@ -137,6 +137,7 @@ export function UsagePage() {
usage,
loading,
error,
lastRefreshedAt,
modelPrices,
setModelPrices,
loadUsage,
@@ -308,6 +309,11 @@ export function UsagePage() {
style={{ display: 'none' }}
onChange={handleImportChange}
/>
{lastRefreshedAt && (
<span className={styles.lastRefreshed}>
{t('usage_stats.last_updated')}: {lastRefreshedAt.toLocaleTimeString()}
</span>
)}
</div>
</div>