import { useMemo, useState } from 'react' import { formatNumber } from '../../lib/usage' import type { ApiSummaryItem } from '../../lib/types' import styles from '../../pages/usage/UsagePage.module.css' interface ApiOverviewCardProps { items: ApiSummaryItem[] } type SortKey = 'apiName' | 'totalRequests' | 'totalTokens' | 'totalCost' type SortDirection = 'asc' | 'desc' export function ApiOverviewCard({ items }: ApiOverviewCardProps) { const [expandedApis, setExpandedApis] = useState([]) 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 === 'apiName') { return direction * left.apiName.localeCompare(right.apiName) } return direction * (left[sortKey] - right[sortKey]) }) }, [items, sortDirection, sortKey]) function toggleExpand(apiName: string) { setExpandedApis((current) => current.includes(apiName) ? current.filter((item) => item !== apiName) : [...current, apiName], ) } function handleSort(key: SortKey) { if (sortKey === key) { setSortDirection((current) => (current === 'asc' ? 'desc' : 'asc')) return } setSortKey(key) setSortDirection(key === 'apiName' ? 'asc' : 'desc') } return (

API details

Requests, tokens, and estimated cost grouped by API provider.

{items.length} APIs
{sortedItems.map((item) => { const expanded = expandedApis.includes(item.apiName) return (
{expanded ? (
Model Requests Success / fail Tokens Cost
{item.models.map((model) => (
{model.modelName} {formatNumber(model.totalRequests)} {formatNumber(model.successCount)} / {formatNumber(model.failureCount)} {formatNumber(model.totalTokens)} ${formatNumber(model.totalCost)}
))}
) : null}
) })}
) }