Polish every product workflow across desktop and mobile
CI / verify (push) Successful in 3m32s

Reframe each screen around the decisions compute brokers make: sellable capacity, full-cost margin, pipeline movement, contract deadlines, evidence review, staged imports, and controlled agent access. Group the shell by operating domain, strengthen mobile navigation and sheets, add responsive record treatments, and make loading, error, empty, readiness, and retry states explicit.

The visual audit exposed sortable table targets and an unnamed file input only after exercising the rendered app, so this commit also pins those accessibility decisions at their actual interaction boundaries. Manrope is self-hosted as a single Latin variable subset to keep the stronger hierarchy without shipping unused font payloads.
This commit is contained in:
2026-08-13 05:34:23 -07:00
parent 1318c0b841
commit e12d27edd1
28 changed files with 672 additions and 522 deletions
+28 -15
View File
@@ -9,7 +9,7 @@ import { useQuery } from '@tanstack/react-query';
import { AlertTriangle, ArrowRight, Server, TrendingUp } from 'lucide-react';
import { Link } from 'react-router-dom';
import { compactNumber, get, money, percent, relativeTime } from '@/lib/api';
import { Badge, Card, CardContent, CardHeader, CardTitle, EmptyState, Skeleton, Stat } from '@/components/ui';
import { Badge, Button, Card, CardContent, CardHeader, CardTitle, EmptyState, Skeleton, Stat } from '@/components/ui';
import { usePageTitle } from '@/lib/title';
interface Dashboard {
@@ -46,7 +46,7 @@ interface Dashboard {
export function Overview() {
usePageTitle('Overview');
const { data, isLoading, error } = useQuery({
const { data, isLoading, error, refetch } = useQuery({
queryKey: ['dashboard'],
queryFn: () => get<Dashboard>('/api/dashboard'),
// The book does not change second to second, but it does change while
@@ -66,19 +66,25 @@ export function Overview() {
if (error || !data) {
return (
<EmptyState
title="Could not load the overview"
description={error instanceof Error ? error.message : 'Unknown error.'}
/>
<Card>
<CardContent className="flex flex-col items-center gap-4 pt-6">
<EmptyState
title="Could not load the overview"
description={error instanceof Error ? error.message : 'Unknown error.'}
/>
<Button variant="outline" onClick={() => void refetch()}>Try again</Button>
</CardContent>
</Card>
);
}
const m = data.margin;
const marginTone = m.grossMarginCents >= 0 ? 'positive' : 'danger';
const firstName = data.me.name.split(' ')[0];
const idleExposureCents = data.idleAlerts.reduce((sum, alert) => sum + alert.idleCostCents, 0);
return (
<div className="space-y-6">
<div className="space-y-5 pb-[calc(5.5rem+var(--safe-bottom))] md:pb-0">
<header>
<h1 className="text-xl font-semibold tracking-tight sm:text-2xl">
{greeting()}, {firstName}
@@ -90,7 +96,7 @@ export function Overview() {
</p>
</header>
<section className="grid gap-3 sm:grid-cols-2 xl:grid-cols-4">
<section className="grid grid-cols-2 gap-2 sm:gap-3 xl:grid-cols-4">
<Stat
label="Gross margin"
value={money(m.grossMarginCents)}
@@ -98,7 +104,7 @@ export function Overview() {
tone={marginTone}
/>
<Stat
label="Utilisation"
label="Sold ratio"
value={percent(m.utilisation, 1)}
hint={`${compactNumber(m.allocatedGpuHours)} of ${compactNumber(m.committedGpuHours)} GPU-hrs sold`}
tone={m.utilisation < 0.6 ? 'warning' : 'default'}
@@ -118,11 +124,17 @@ export function Overview() {
{data.idleAlerts.length > 0 ? (
<Card className="border-warning/30">
<CardHeader className="flex-row items-center gap-2 space-y-0">
<AlertTriangle className="h-4 w-4 shrink-0 text-warning" aria-hidden />
<CardTitle className="text-base">Capacity you are paying for and not selling</CardTitle>
<CardHeader className="flex-row items-start justify-between gap-3 space-y-0">
<div className="flex min-w-0 items-start gap-2">
<AlertTriangle className="mt-0.5 h-4 w-4 shrink-0 text-warning" aria-hidden />
<div>
<CardTitle className="text-base">Capacity you are paying for and not selling</CardTitle>
<p className="mt-1 text-xs text-muted">Prioritized by idle cost exposure.</p>
</div>
</div>
<Badge tone="warning" className="nums shrink-0">{money(idleExposureCents)}</Badge>
</CardHeader>
<CardContent className="space-y-3">
<CardContent className="space-y-2">
{data.idleAlerts.map((alert) => (
<div
key={alert.commitmentId}
@@ -131,7 +143,7 @@ export function Overview() {
<div className="min-w-0">
<p className="truncate font-medium">{alert.name}</p>
<p className="text-xs text-muted">
{alert.gpuCount}× {alert.gpuType} · {percent(alert.utilisation)} utilised
{alert.gpuCount}× {alert.gpuType} · {percent(alert.utilisation)} sold
{/*
A zero break-even means the block's cost is already
covered, so any further sale is upside. Printing
@@ -154,7 +166,8 @@ export function Overview() {
</span>
<Link
to="/capacity"
className="tap inline-flex items-center gap-1 text-sm font-medium text-accent-fg"
className="tap inline-flex min-h-11 items-center gap-1 rounded-lg px-3 text-sm font-medium text-accent-fg hover:bg-surface"
aria-label={`Match demand to ${alert.name}`}
>
Match
<ArrowRight className="h-3.5 w-3.5" aria-hidden />