Skip to content

web UI: style Today/macros view #37

Closed

Description

@TSVRN9

What to build

Style src/routes/today/+page.svelte — the daily macro totals view and logged-entry list, plus the JSON/CSV export buttons. This is the other half of the core vertical slice from #36. Reuse #35's tokens.

Macro totals (calories, protein, carbs, fat) deserve real visual treatment — consider whether a simple stat/number display or something more visual (progress bars, etc.) fits this app's design direction better; use judgment, don't over-build (a clean stat row is probably enough, this is a lightweight tracker not a fitness-app dashboard).

Acceptance criteria

Blocked by

#35 (Tailwind + design tokens + shared layout)

Activity

  1. TSVRN9 commented on Aug 19, 2026

    @TSVRN9
    OwnerAuthor

    Landed via a rebase-and-retarget of PR #49 (previously stacked on the now-superseded
    ux/shell-components, whose #43 content merged separately as #53). Rebased #49's single commit
    (43fa9dd → d4a2be4) onto current main with git rebase --onto origin/main 86e5af0 ux/today-macros — clean, no conflicts, no faq/staff references (main also carries #51's removal of
    those features). PR now targets main: #49

    Acceptance criteria — verified live

    • Today/macros view fully restyled using web UI: install Tailwind CSS + design tokens + styled shared layout #35's tokens — audited every component class the page
      uses (.card, .page-title, .section-title, .stat/.stat-label/.stat-value, .btn +
      variants, .empty-state, .label-rule) against what actually landed in main's app.css via
      web UX: shared component layer, loading/error states, and nav hierarchy #53: exact match, no drift. Live-verified with a real dev server against real UMass Dining menu
      data (Hampshire, live /api/menu proxy) — browsed the menu, logged French Toast (127 cal, 5.3g
      protein, 20.4g carbs, 2.9g fat) and Fried Plantain, and confirmed the four-up stat panel, the
      per-macro "% of calories" split bar, sorted entry rows with per-entry cal/protein/time, and Remove
      • Undo all render and function correctly.
    • Export actions remain clearly visible/accessible — own titled section, two clearly-labelled
      buttons (Export JSON (all history), Export CSV (all history)), verified to actually produce a
      populated download (not just render) both manually and via a new Playwright spec that reads the
      downloaded blob's content.
    • npx playwright test passes unchanged — all 4 pre-existing specs plus the 7 shell specs from
      web UX: shared component layer, loading/error states, and nav hierarchy #53 pass unmodified (11/11 before any new work); full suite is 14/14 green with the 3 new specs
      added (see below).
    • pnpm --filter web check clean — 396 files, 0 errors, 0 warnings. pnpm --filter web build
      also succeeds.

    New test coverage: web/e2e/today.spec.ts

    The existing specs cover raw macro numbers but not the stat panel's %-share display, the
    chronological-sort fix, Remove/Undo, or that Export actually downloads real data. Added 3 new specs
    in a new file (didn't touch shell.spec.ts or the halls/menu specs owned by the parallel #48
    salvage).

    Red/green evidence — each spec's guarded behavior broken with a one-line mutation, run to
    observe the failure, then reverted to green:

    1. stat panel shows per-macro % of calories, and Remove + Undo restore the exact entry
      • share() forced to return 0: getByText('16% of calories') → element(s) not found
      • undoRemove() stops calling storage.addEntry(...): getByText('Nothing logged yet.')
        expected not-visible → unexpected value "visible"
    2. logged entries render chronologically, not in IndexedDB's own key order
      • Dropped the .sort(...) in refresh(): expected "Early Dish" first → received
        "Late Dish × 1 100 cal · 0.0g protein · logged 9:00 AM Remove"
    3. Export JSON and Export CSV download the full log, not just today's entries
      • exportJson/exportCsv export [] instead of await storage.getAllEntries(): expected
        downloaded JSON length 1 → received 0

    Each mutation reverted cleanly (git diff --stat empty afterward), full suite re-confirmed green
    (14/14) after every revert.

    Not touched

    web/src/routes/+page.svelte, web/src/routes/halls/[slug]/+page.svelte, and
    web/e2e/shell.spec.ts — those belong to PR #48's parallel rebase of the halls/menu screens (#36),
    being salvaged the same way on disjoint files.

    PR #49 is not merged — left for review.

  2. added a commit that references this issue on Aug 19, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    ready-for-agentFully specified, ready for an AFK agent

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions