Skip to content

SPA: dashboard rework — capture-status tiles, 14-day sparkline, stock as a stacked bar #654

Closed

Description

@mforce

Part of the SPA look-and-feel pass (design review 2026-09-02). Sibling slices: numeric typesetting, elevation hierarchy, all-caps labels, table layout, empty states, visual identity. Do this one after the typesetting / elevation / caps slices so it inherits them.

Problem

The Dashboard (web/src/routes/Dashboard.tsx) is the landing screen and the weakest one — it is deliberately not among the README screenshots (#549). It is the default treatment: three identical stat cards (big number, small caps label) above three identical panels, each a small table. It answers "how many" but not the question a farm asks at 6 am: which houses have no entry yet, and is lay rate normal?

Proposal

┌ Today, Tue 2 Sep ─────────────────────────────────────────────┐
│ House A   327 ●    House B   — no entry    House C   298 ●    │  one tile per active flock;
│ ▁▂▃▅▆▅▆▇▆▇▇█▇▇  eggs, last 14 days      hen-day 101% (▲1.2)   │  "no entry" is the alarm state
├ Stock ─────────────────────────── ┬ Recent sales ─────────────┤
│ ████████▓▓▓▓▒▒▒░  4,956 available │ SO-66C1  Customer 3 16.20 │  stacked bar by grade,
│ Large 2,719 · Medium 1,480 · …    │ …                         │  reuses .meter
└───────────────────────────────────┴───────────────────────────┘
  • Capture status row replaces the Today panel table: one tile per active flock — name, today's eggs, status badge; a flock with no entry is visually the loudest thing on the screen and links straight to Daily entry for that flock.
  • 14-day eggs sparkline (inline SVG, no chart library) with the 7-day hen-day % and its delta vs the previous 7 days. One additional listDailyEntries range call; the hen-day maths already exists server-side for Reports — reuse the report endpoint if it is cheaper than recomputing client-side.
  • Stock as one stacked bar by grade (the .meter component already exists) with the per-grade figures as a caption, instead of a three-column table.
  • Recent sales: keep, as a compact list.
  • Stat cards: drop the row; the figures move into the tiles and the sparkline caption.
  • Panels degrade independently, as today.

Acceptance

  • A flock with no entry today is identifiable within one glance and one click from the dashboard.
  • Sparkline + hen-day delta render from real data; — (never a zero) when the fetch fails, matching the existing degrade-alone rule.
  • Stock bar sums to the available total and matches the Stock screen.
  • ReadOnly / Denied roles still see no sales panel (Security: ReadOnly role can read customer PII + sales financials via ungated /customers and /sales reads #127).
  • Light + night + four farm palettes; reduced motion respected (no animated bars).
  • Vitest tests for tile status, sparkline data mapping and stock bar proportions (frontend tests in the same PR).
  • Help page + specs/product/GLOSSARY.md updated if "hen-day %" or "capture status" appear as new dashboard concepts (owner directive 2026-07-17).
  • i18n en / es / tl inline.
  • Consider adding the dashboard to tools/simulation/ui/specs-screenshots/ once it is worth showing (docs: generated screenshots of the running SPA in the README #549 excluded it on purpose).

Siblings: #650 #651 #652 #653 #655 #656 #657

Activity

  1. mforce commented on Sep 2, 2026

    @mforce
    OwnerAuthor

    Shipped in #659, squashed onto main as 396ba233.

    Delivered: capture-status tiles (missing-entry flocks first, capped at 12 with an "N more flocks" link, each deep-linking to Daily entry for that flock and day); the 14-day sparkline with the production report's own hen-day % and its delta against the previous 7 days; stock as one stacked bar by grade whose total matches the Stock screen; recent sales as a compact list; the dead .stat* CSS removed; Help section, in-app glossary and specs/product/GLOSSARY.md term for "Capture status"; i18n en/es/tl inline; and the E2E smoke, canary and stock-summary-broken mutant pointed at the new DOM.

    Two additions beyond the original spec, both after review: a no-entry tile's dash is muted and shrunk with a Record today hover text, and such a tile now carries its own accessible name ({{flock}}: no entry yet, open today's entry) — previously a screen reader heard the same name whether or not a house had recorded, so the alarm state was visual only.

    Acceptance criterion 9 was amended, with the owner's agreement (2026-09-02). The capture spec ships; the image and the README embed do not. On the current fixture #627's ~100 catalog flocks never get an entry, so every visible tile is one of them and the two real houses sit behind the cap link, while the trend and stock panels fall below the capture viewport. #660 carries that work, and tools/simulation/ui/README.md now documents the related hazard: a capture taken after a smoke run photographs that run's leftovers.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions