refactor(web): Overview usage reuses WalletStatsCard (same as 模型与余额)
The wallet page already renders Current Balance / Total Usage / API Requests from /api/user/self. Reuse that exact component (WalletStatsCard) on the Overview instead of a hand-written block — DRY, identical numbers ($160.47 / $39.53 / 521 for the current user). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -3,32 +3,30 @@ import { useQuery } from '@tanstack/react-query'
|
||||
import { Link } from '@tanstack/react-router'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import {
|
||||
Activity,
|
||||
AlertTriangle,
|
||||
ArrowUpRight,
|
||||
Building2,
|
||||
CheckCircle2,
|
||||
CircleDashed,
|
||||
Coins,
|
||||
PlayCircle,
|
||||
Rocket,
|
||||
ScrollText,
|
||||
Wallet,
|
||||
} from 'lucide-react'
|
||||
import { api } from '@/lib/api'
|
||||
import { formatQuota } from '@/lib/format'
|
||||
import { cn } from '@/lib/utils'
|
||||
import { Button } from '@/components/ui/button'
|
||||
import {
|
||||
listAgentDeployments,
|
||||
type AgentDeployment,
|
||||
} from '@/features/agent-console/api'
|
||||
import { WalletStatsCard } from '@/features/wallet/components/wallet-stats-card'
|
||||
import type { UserWalletData } from '@/features/wallet/types'
|
||||
|
||||
// Current user's own lifetime usage (NOT the admin-global aggregate).
|
||||
type SelfUsage = { quota?: number; used_quota?: number; request_count?: number }
|
||||
async function getSelfUsage(): Promise<SelfUsage> {
|
||||
const res = await api.get<{ data?: SelfUsage }>('/api/user/self')
|
||||
return res.data?.data ?? {}
|
||||
// Current user's OWN balance/usage (NOT the admin-global aggregate) — same
|
||||
// source the 模型与余额 page uses.
|
||||
async function getSelfUsage(): Promise<UserWalletData> {
|
||||
const res = await api.get<{ data?: UserWalletData }>('/api/user/self')
|
||||
return res.data?.data ?? ({} as UserWalletData)
|
||||
}
|
||||
|
||||
type StatusKey = 'running' | 'success' | 'failed' | 'pending'
|
||||
@@ -162,7 +160,6 @@ export function CockpitView() {
|
||||
refetchInterval: 60_000,
|
||||
retry: false,
|
||||
})
|
||||
const self = selfQuery.data ?? {}
|
||||
|
||||
const stats = useMemo(() => {
|
||||
const list: AgentDeployment[] = deploymentsQuery.data ?? []
|
||||
@@ -238,29 +235,10 @@ export function CockpitView() {
|
||||
<p className='text-muted-foreground mb-2 text-[11px] font-semibold tracking-[0.16em] uppercase'>
|
||||
{t('Usage & cost')}
|
||||
</p>
|
||||
<div className='grid grid-cols-2 gap-3 lg:grid-cols-3'>
|
||||
<StatCard
|
||||
label={t('Used')}
|
||||
value={formatQuota(self.used_quota ?? 0)}
|
||||
hint={t('Your total spend so far')}
|
||||
icon={Coins}
|
||||
tone='primary'
|
||||
/>
|
||||
<StatCard
|
||||
label={t('Remaining quota')}
|
||||
value={formatQuota(self.quota ?? 0)}
|
||||
hint={t('Balance available')}
|
||||
icon={Wallet}
|
||||
tone='success'
|
||||
/>
|
||||
<StatCard
|
||||
label={t('Requests')}
|
||||
value={String(self.request_count ?? 0)}
|
||||
hint={t('Your total requests')}
|
||||
icon={Activity}
|
||||
tone='warn'
|
||||
/>
|
||||
</div>
|
||||
<WalletStatsCard
|
||||
user={selfQuery.data ?? null}
|
||||
loading={selfQuery.isLoading}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Tier 2: Stream */}
|
||||
|
||||
Reference in New Issue
Block a user