import { useMemo, useState } from 'react' import { formatNumber } from '../../lib/usage' import type { ModelSummaryItem } from '../../lib/types' import styles from '../../pages/usage/UsagePage.module.css' interface ModelDetailsCardProps { items: ModelSummaryItem[] } type SortKey = 'modelName' | 'totalRequests' | 'totalTokens' | 'averageLatencyMs' | 'successRate' | 'totalCost' type SortDirection = 'asc' | 'desc' export function ModelDetailsCard({ items }: ModelDetailsCardProps) { const [sortKey, setSortKey] = useState('totalRequests') const [sortDirection, setSortDirection] = useState('desc') const sortedItems = useMemo(() => { const direction = sortDirection === 'asc' ? 1 : -1 return [...items].sort((left, right) => { if (sortKey === 'modelName') { return direction * left.modelName.localeCompare(right.modelName) } return direction * (left[sortKey] - right[sortKey]) }) }, [items, sortDirection, sortKey]) function handleSort(key: SortKey) { if (sortKey === key) { setSortDirection((current) => (current === 'asc' ? 'desc' : 'asc')) return } setSortKey(key) setSortDirection(key === 'modelName' ? 'asc' : 'desc') } return (

Model stats

Sortable model-level requests, latency, success rate, and cost.

{items.length} rows
{sortedItems.map((item) => (
{item.modelName} {item.apiName} {formatNumber(item.totalRequests)} {formatNumber(item.totalTokens)} {formatNumber(item.averageLatencyMs)} ms = 95 ? styles.statusSuccess : item.successRate >= 80 ? styles.statusNeutral : styles.statusFailed}> {item.successRate.toFixed(1)}% ${formatNumber(item.totalCost)}
))}
) }