Commit 1414569b by CaIon

feat(stat): enhance log stat cards with compact number formatting and improved layout

parent df013946
...@@ -18,8 +18,9 @@ For commercial licensing, please contact support@quantumnous.com ...@@ -18,8 +18,9 @@ For commercial licensing, please contact support@quantumnous.com
*/ */
import { useEffect, useState } from 'react' import { useEffect, useState } from 'react'
import { useAuthStore } from '@/stores/auth-store' import { useAuthStore } from '@/stores/auth-store'
import { formatNumber, formatQuota } from '@/lib/format' import { formatCompactNumber, formatNumber, formatQuota } from '@/lib/format'
import { computeTimeRange } from '@/lib/time' import { computeTimeRange } from '@/lib/time'
import { cn } from '@/lib/utils'
import { Skeleton } from '@/components/ui/skeleton' import { Skeleton } from '@/components/ui/skeleton'
import { getUserQuotaDates } from '@/features/dashboard/api' import { getUserQuotaDates } from '@/features/dashboard/api'
import { useModelStatCardsConfig } from '@/features/dashboard/hooks/use-dashboard-config' import { useModelStatCardsConfig } from '@/features/dashboard/hooks/use-dashboard-config'
...@@ -38,6 +39,21 @@ interface LogStatCardsProps { ...@@ -38,6 +39,21 @@ interface LogStatCardsProps {
onDataUpdate?: (data: QuotaDataItem[], loading: boolean) => void onDataUpdate?: (data: QuotaDataItem[], loading: boolean) => void
} }
const MAX_INLINE_STAT_CHARS = 9
function formatStatNumber(value: number) {
const fullValue = formatNumber(value)
const displayValue =
fullValue.length > MAX_INLINE_STAT_CHARS
? formatCompactNumber(value)
: fullValue
return {
displayValue,
fullValue,
}
}
export function LogStatCards(props: LogStatCardsProps) { export function LogStatCards(props: LogStatCardsProps) {
const statCardsConfig = useModelStatCardsConfig() const statCardsConfig = useModelStatCardsConfig()
const user = useAuthStore((state) => state.auth.user) const user = useAuthStore((state) => state.auth.user)
...@@ -100,27 +116,41 @@ export function LogStatCards(props: LogStatCardsProps) { ...@@ -100,27 +116,41 @@ export function LogStatCards(props: LogStatCardsProps) {
tpm: stats?.totalTokens ?? 0, tpm: stats?.totalTokens ?? 0,
} }
const items = statCardsConfig.map((config) => ({ const items = statCardsConfig.map((config) => {
title: config.title, const rawValue = config.getValue(adaptedStats, timeRangeMinutes)
value: const formatted =
config.key === 'quota' config.key === 'quota'
? formatQuota(config.getValue(adaptedStats, timeRangeMinutes)) ? {
: formatNumber(config.getValue(adaptedStats, timeRangeMinutes)), displayValue: formatQuota(rawValue),
desc: config.description, fullValue: formatQuota(rawValue),
icon: config.icon, }
})) : formatStatNumber(rawValue)
return {
title: config.title,
value: formatted.displayValue,
fullValue: formatted.fullValue,
desc: config.description,
icon: config.icon,
}
})
return ( return (
<div className='overflow-hidden rounded-lg border'> <div className='overflow-hidden rounded-lg border'>
<div className='divide-border/60 grid grid-cols-2 divide-x sm:grid-cols-3 lg:grid-cols-5'> <div className='divide-border/60 grid min-w-0 grid-cols-2 divide-x sm:grid-cols-3 lg:grid-cols-5'>
{items.map((it, idx) => { {items.map((it, idx) => {
const Icon = it.icon const Icon = it.icon
return ( return (
<div <div
key={it.title} key={it.title}
className={`px-3 py-2.5 sm:px-5 sm:py-4 ${idx === items.length - 1 && items.length % 2 !== 0 ? 'col-span-2 sm:col-span-1' : ''}`} className={cn(
'min-w-0 px-3 py-2.5 sm:px-5 sm:py-4',
idx === items.length - 1 &&
items.length % 2 !== 0 &&
'col-span-2 sm:col-span-1'
)}
> >
<div className='flex items-center gap-2'> <div className='flex min-w-0 items-center gap-2'>
<Icon className='text-muted-foreground/60 size-3.5 shrink-0' /> <Icon className='text-muted-foreground/60 size-3.5 shrink-0' />
<div className='text-muted-foreground truncate text-xs font-medium tracking-wider uppercase'> <div className='text-muted-foreground truncate text-xs font-medium tracking-wider uppercase'>
{it.title} {it.title}
...@@ -128,7 +158,7 @@ export function LogStatCards(props: LogStatCardsProps) { ...@@ -128,7 +158,7 @@ export function LogStatCards(props: LogStatCardsProps) {
</div> </div>
{loading ? ( {loading ? (
<div className='mt-2 space-y-1.5'> <div className='mt-2 flex flex-col gap-1.5'>
<Skeleton className='h-7 w-20' /> <Skeleton className='h-7 w-20' />
<Skeleton className='h-3.5 w-28' /> <Skeleton className='h-3.5 w-28' />
</div> </div>
...@@ -143,7 +173,10 @@ export function LogStatCards(props: LogStatCardsProps) { ...@@ -143,7 +173,10 @@ export function LogStatCards(props: LogStatCardsProps) {
</> </>
) : ( ) : (
<> <>
<div className='text-foreground mt-1.5 font-mono text-lg font-bold tracking-tight tabular-nums sm:mt-2 sm:text-2xl'> <div
className='text-foreground mt-1.5 max-w-full truncate font-mono text-lg font-bold tracking-tight tabular-nums sm:mt-2 sm:text-2xl'
title={it.fullValue}
>
{it.value} {it.value}
</div> </div>
<div className='text-muted-foreground/60 mt-1 hidden text-xs md:block'> <div className='text-muted-foreground/60 mt-1 hidden text-xs md:block'>
......
...@@ -45,8 +45,8 @@ function formatCompactLatency(ms: number): string { ...@@ -45,8 +45,8 @@ function formatCompactLatency(ms: number): string {
function formatCompactThroughput(tps: number): string { function formatCompactThroughput(tps: number): string {
if (!Number.isFinite(tps) || tps <= 0) return '—' if (!Number.isFinite(tps) || tps <= 0) return '—'
if (tps >= 1_000) return `${formatCompactNumber(tps / 1_000)}Ktps` if (tps >= 1_000) return `${formatCompactNumber(tps / 1_000)}Kt`
return `${formatCompactNumber(tps)}tps` return `${formatCompactNumber(tps)}t`
} }
export const ModelPerfBadge = memo(function ModelPerfBadge( export const ModelPerfBadge = memo(function ModelPerfBadge(
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment