feat(web): merge Usage route into Stats as tab (UC-3) #264

Closed
opened 2026-04-21 20:31:19 +00:00 by code-lead · 0 comments
Collaborator

As an operator, I want to see task stats and Pro-Max quota on the same page behind tabs, so that the two "how much have we spent" surfaces live together and the top nav drops one more entry.

Acceptance criteria

Tabbed layout

  • /app/stats renders a Base UI Tabs control with three panels: Tasks (today's /stats content), Quota (today's /usage content), Cost caps (new empty panel with a placeholder "Populated by issue #231" note — scaffolding only).
  • The active tab is encoded in the URL as ?tab=tasks|quota|caps; default tasks. validateSearch drops malformed values.
  • Tab triggers use rounded-pill and the accent token set per apps/web/CLAUDE.md. No raw hex.

Route + redirect

  • /app/usage route file is deleted; the router resolves the old path via a redirect to /app/stats?tab=quota (with any existing search params preserved). Today's usage window selector (week / day / all) stays owned by the Quota panel as local component state — no URL param migration needed.
  • The UsageRoute component's body is moved into a StatsQuotaPanel component that the Tasks-panel-is-today's-Stats code can import cleanly.

Nav

  • components/app-shell.tsx drops the Usage entry from both nav arrays. Stats label + to stay as-is.

Tests

  • Vitest: /stats defaults to the Tasks tab; ?tab=quota opens the Quota tab; malformed ?tab=xyz falls back to Tasks.
  • Vitest: switching tabs updates the URL via replace: true.
  • Playwright: existing /app/usage URL lands on /app/stats?tab=quota with the threshold banner visible.
  • Biome + typecheck pass.

Out of scope

  • Wiring real data into the Cost-caps panel. That's #231's job — this story just reserves the slot.
  • Merging any other numerical surfaces (Storage, Agents stats) — they stay where they are.
  • Changing the /stats or /usage server endpoints.

References

  • Spec: specs/ui-consolidation.md § UC-3 (Merge Usage into Stats as a tab)
  • Tracking: #259
  • apps/web/src/routes/usage.tsx (deleted; body moved to components/stats/quota-panel.tsx)
  • apps/web/src/routes/stats.tsx (extended)
  • apps/web/src/components/app-shell.tsx (nav prune)
  • Issue #231 (cost-caps panel placeholder reserves the slot)

Dependencies

  • Independent of UC-1 / UC-2. Can run in parallel with UC-2 if the operator wants to parallelise.
As an operator, I want to see task stats and Pro-Max quota on the same page behind tabs, so that the two "how much have we spent" surfaces live together and the top nav drops one more entry. ## Acceptance criteria ### Tabbed layout - [ ] `/app/stats` renders a Base UI `Tabs` control with three panels: **Tasks** (today's `/stats` content), **Quota** (today's `/usage` content), **Cost caps** (new empty panel with a placeholder "Populated by issue #231" note — scaffolding only). - [ ] The active tab is encoded in the URL as `?tab=tasks|quota|caps`; default `tasks`. `validateSearch` drops malformed values. - [ ] Tab triggers use `rounded-pill` and the accent token set per `apps/web/CLAUDE.md`. No raw hex. ### Route + redirect - [ ] `/app/usage` route file is deleted; the router resolves the old path via a redirect to `/app/stats?tab=quota` (with any existing search params preserved). Today's usage window selector (week / day / all) stays owned by the Quota panel as local component state — no URL param migration needed. - [ ] The `UsageRoute` component's body is moved into a `StatsQuotaPanel` component that the Tasks-panel-is-today's-Stats code can import cleanly. ### Nav - [ ] `components/app-shell.tsx` drops the `Usage` entry from both nav arrays. `Stats` label + `to` stay as-is. ### Tests - [ ] Vitest: `/stats` defaults to the Tasks tab; `?tab=quota` opens the Quota tab; malformed `?tab=xyz` falls back to Tasks. - [ ] Vitest: switching tabs updates the URL via `replace: true`. - [ ] Playwright: existing `/app/usage` URL lands on `/app/stats?tab=quota` with the threshold banner visible. - [ ] Biome + typecheck pass. ## Out of scope - Wiring real data into the Cost-caps panel. That's #231's job — this story just reserves the slot. - Merging any other numerical surfaces (Storage, Agents stats) — they stay where they are. - Changing the `/stats` or `/usage` server endpoints. ## References - Spec: `specs/ui-consolidation.md` § UC-3 (Merge Usage into Stats as a tab) - Tracking: #259 - `apps/web/src/routes/usage.tsx` (deleted; body moved to `components/stats/quota-panel.tsx`) - `apps/web/src/routes/stats.tsx` (extended) - `apps/web/src/components/app-shell.tsx` (nav prune) - Issue #231 (cost-caps panel placeholder reserves the slot) ## Dependencies - Independent of UC-1 / UC-2. Can run in parallel with UC-2 if the operator wants to parallelise.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
charles/claude-hooks#264
No description provided.