|
|
|
|
@@ -32,7 +32,7 @@ function TimeAgo({ timestamp }) {
|
|
|
|
|
|
|
|
|
|
function RecentRequests({ requests = [] }) {
|
|
|
|
|
return (
|
|
|
|
|
<Card className="flex flex-col overflow-hidden" padding="sm" style={{ height: 480 }}>
|
|
|
|
|
<Card className="flex min-w-0 flex-col overflow-hidden" padding="sm" style={{ height: 480 }}>
|
|
|
|
|
{/* Header */}
|
|
|
|
|
<div className="px-1 py-2 border-b border-border shrink-0">
|
|
|
|
|
<span className="text-xs font-semibold text-text-muted uppercase tracking-wide">Recent Requests</span>
|
|
|
|
|
@@ -42,7 +42,7 @@ function RecentRequests({ requests = [] }) {
|
|
|
|
|
<div className="flex-1 flex items-center justify-center text-text-muted text-sm">No requests yet.</div>
|
|
|
|
|
) : (
|
|
|
|
|
<div className="flex-1 overflow-y-auto">
|
|
|
|
|
<table className="w-full text-xs border-collapse">
|
|
|
|
|
<table className="w-full min-w-[420px] border-collapse text-xs">
|
|
|
|
|
<thead className="sticky top-0 bg-bg z-10">
|
|
|
|
|
<tr className="border-b border-border">
|
|
|
|
|
<th className="py-1.5 text-left font-semibold text-text-muted w-2"></th>
|
|
|
|
|
@@ -397,16 +397,16 @@ export default function UsageStats() {
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<div className="flex flex-col gap-6">
|
|
|
|
|
<div className="flex min-w-0 flex-col gap-6">
|
|
|
|
|
{/* Period selector */}
|
|
|
|
|
<div className="flex items-center gap-2 self-end">
|
|
|
|
|
<div className="flex items-center gap-1 bg-bg-subtle rounded-lg p-1 border border-border">
|
|
|
|
|
<div className="flex w-full items-center gap-2 sm:w-auto sm:self-end">
|
|
|
|
|
<div className="grid flex-1 grid-cols-4 items-center gap-1 rounded-lg border border-border bg-bg-subtle p-1 sm:flex sm:flex-none">
|
|
|
|
|
{PERIODS.map((p) => (
|
|
|
|
|
<button
|
|
|
|
|
key={p.value}
|
|
|
|
|
onClick={() => setPeriod(p.value)}
|
|
|
|
|
disabled={fetching}
|
|
|
|
|
className={`px-3 py-1 rounded-md text-sm font-medium transition-colors ${period === p.value ? "bg-primary text-white shadow-sm" : "text-text-muted hover:text-text hover:bg-bg-hover"}`}
|
|
|
|
|
className={`rounded-md px-3 py-1 text-sm font-medium transition-colors ${period === p.value ? "bg-primary text-white shadow-sm" : "text-text-muted hover:bg-bg-hover hover:text-text"}`}
|
|
|
|
|
>
|
|
|
|
|
{p.label}
|
|
|
|
|
</button>
|
|
|
|
|
@@ -422,7 +422,7 @@ export default function UsageStats() {
|
|
|
|
|
|
|
|
|
|
{/* Provider topology + Recent Requests */}
|
|
|
|
|
{loading ? spinner : (
|
|
|
|
|
<div className="grid grid-cols-1 lg:grid-cols-[2fr_1fr] gap-2 items-stretch">
|
|
|
|
|
<div className="grid min-w-0 grid-cols-1 items-stretch gap-2 lg:grid-cols-[minmax(0,2fr)_minmax(280px,1fr)]">
|
|
|
|
|
<ProviderTopology
|
|
|
|
|
providers={providers}
|
|
|
|
|
activeRequests={stats.activeRequests || []}
|
|
|
|
|
@@ -438,17 +438,17 @@ export default function UsageStats() {
|
|
|
|
|
|
|
|
|
|
{/* Table with dropdown selector */}
|
|
|
|
|
<div className="flex flex-col gap-3">
|
|
|
|
|
<div className="flex items-center justify-between">
|
|
|
|
|
<div className="flex flex-col gap-2 sm:flex-row sm:items-center sm:justify-between">
|
|
|
|
|
<select
|
|
|
|
|
value={tableView}
|
|
|
|
|
onChange={(e) => setTableView(e.target.value)}
|
|
|
|
|
className="px-3 py-1.5 rounded-lg border border-border bg-bg-subtle text-sm font-medium text-text focus:outline-none focus:ring-2 focus:ring-primary/50"
|
|
|
|
|
className="w-full rounded-lg border border-border bg-bg-subtle px-3 py-1.5 text-sm font-medium text-text focus:outline-none focus:ring-2 focus:ring-primary/50 sm:w-auto"
|
|
|
|
|
>
|
|
|
|
|
{TABLE_OPTIONS.map((opt) => (
|
|
|
|
|
<option key={opt.value} value={opt.value}>{opt.label}</option>
|
|
|
|
|
))}
|
|
|
|
|
</select>
|
|
|
|
|
<div className="flex items-center gap-1 bg-bg-subtle rounded-lg p-1 border border-border">
|
|
|
|
|
<div className="grid grid-cols-2 items-center gap-1 rounded-lg border border-border bg-bg-subtle p-1 sm:flex">
|
|
|
|
|
<button
|
|
|
|
|
onClick={() => setViewMode("costs")}
|
|
|
|
|
className={`px-3 py-1 rounded-md text-sm font-medium transition-colors ${viewMode === "costs" ? "bg-primary text-white shadow-sm" : "text-text-muted hover:text-text hover:bg-bg-hover"}`}
|
|
|
|
|
|