feat: players page redesign — deltas, KPI tiles, sparklines, expanded row #9

Merged
shcizo merged 27 commits from feat/shared-visual-layer-topbar-4 into main 2026-05-21 16:14:01 +02:00

27 Commits

Author SHA1 Message Date
Samuel Enocsson 15adddc2f1 re-swap table after refresh for consistent in-place updates
Release Please / release-please (push) Failing after 44s
Release Please / docker (push) Has been skipped
2026-05-21 16:11:32 +02:00
Samuel Enocsson b6c674e4c7 wire refresh button to update both rating and prediction 2026-05-21 16:04:15 +02:00
Samuel Enocsson a7562e9b47 fallback to monthlyHistory for lastMonthRating 2026-05-21 15:58:48 +02:00
Samuel Enocsson 4b145094bf render flat delta pill for null values per design spec 2026-05-21 15:51:17 +02:00
Samuel Enocsson 96ae7d7dac fix CSS for rating row 2026-05-21 15:33:21 +02:00
Samuel Enocsson 9feb5c2c43 fix: remove sticky thead — overlapped table toolbar (#4)
The thead had position: sticky; top: var(--topbar-height), pinning it
to 64px from the viewport. Inside the new .table-card with a toolbar
above, this pulled the header up out of its natural flow and overlapped
the toolbar and first data row. Let thead flow normally — design
doesn't require sticky behavior.
2026-05-21 15:27:08 +02:00
Samuel Enocsson 88df98f269 fix: place history chart in right grid column of expanded row (#7)
The dl + button + chart were 3 direct children of .player-detail (a
2-column grid). Auto-placement put the button in the right column,
forcing the chart to wrap to a second row in the left column.
Wrap dl + button in .player-detail-left so the chart occupies col 2.
2026-05-21 15:23:53 +02:00
Samuel Enocsson 259a3fadf1 chore: remove dead .refresh-section CSS (#4) 2026-05-21 15:17:09 +02:00
Samuel Enocsson 7fb8cab5e2 feat: add 'View calculation details' link to expanded row (#4) 2026-05-21 15:16:51 +02:00
Samuel Enocsson 7af9d8d69e fix: null-safe icon selectors after table restructure (#4) 2026-05-21 15:16:09 +02:00
Samuel Enocsson 16d375ae10 refactor: design-fidelity pass on players page 2026-05-21 15:15:29 +02:00
Samuel Enocsson 686d7ca00c fix: use template-literal interpolation for KPI strip inside body string (#5)
The page body is assembled as a JS template literal inside <% ... %>;
EJS tags inside that string break the EJS parser (it sees the first %>
as the close of the outer tag). Switch to ${kpis.x} interpolation since
we're already inside a backtick string.
2026-05-21 15:03:02 +02:00
Samuel Enocsson ac6008aa14 chore: delete dead progress.js (#4) 2026-05-21 14:38:06 +02:00
Samuel Enocsson cc223a4b8a fix: drop unused html field from renderDeltaPill (#3) 2026-05-21 14:38:06 +02:00
Samuel Enocsson 0ded27f9df fix: address code review findings — DRY delta-pill, var→const/let, tokenize colors 2026-05-21 14:38:06 +02:00
Samuel Enocsson 9df151f109 fix: return latest N months in getMonthlyHistory (#6) 2026-05-21 14:38:06 +02:00
Samuel Enocsson b75e60da65 feat: redesign expanded row with detail-grid + history chart (#7) 2026-05-21 14:38:06 +02:00
Samuel Enocsson e5f16e624e feat: pass player record into player-history partial render (#7) 2026-05-21 14:38:06 +02:00
Samuel Enocsson 83ceaf0ea3 feat: add KPI summary tiles above players table (#5) 2026-05-21 14:38:06 +02:00
Samuel Enocsson b51ae19ae1 feat: render sparklines + wire trend-chart pill toggle (#6) 2026-05-21 14:37:58 +02:00
Samuel Enocsson 6129b6fd3b feat: wire computeKpis into the page render (#5) 2026-05-21 14:37:48 +02:00
Samuel Enocsson 3dcd3131a0 feat: add monthlyHistory[] per player via getMonthlyHistory + bulk fetch (#6)
Add getMonthlyHistory() to models/player for single-player use and
getAllMonthlyHistoriesFromDB() for bulk fetches (one query, grouped in
memory). Wire monthlyHistory into all player objects returned by
getPlayerDataFromDB and getAllRatingsFromDB. Bulk path pre-fetches in
one query to avoid N extra per-player queries.
2026-05-21 13:41:20 +02:00
Samuel Enocsson 19756b80e5 feat: expose lastMonthRating and deltaPredicted on player objects (#3)
Add two derived fields to all player objects returned by
getPlayerDataFromDB and the error branch in getAllRatingsFromDB.
No new DB columns — both fields are pure arithmetic derivations.
monthlyHistory placeholder [] included ahead of A2 implementation.
2026-05-21 13:38:04 +02:00
Samuel Enocsson 3f7a1bb7bf chore: remove dead code orphaned by topbar redesign (#4)
The new topbar's "Refresh all" button replaces the old SSE-driven
"Load All" link and progress UI. With those gone, several pieces of
infrastructure had no callers left:

- GET /api/load-all-players, POST /api/populate-database, and
  GET /api/database-status — SSE endpoints with no frontend consumers
- #progress-section / #loading divs in players + courses pages
- .progress-container / .progress-bar / .progress-text / .loading CSS
- public/js/progress.js script (defines fetchRatingsWithProgress, never
  called, and loadAllPlayers, no longer wired) — to be deleted manually
  since the sandbox blocks rm
2026-05-21 13:15:53 +02:00
Samuel Enocsson 53bc6e571d chore: remove redundant "Load All" link from players page (#4)
The topbar's "Refresh all" button (introduced in #4) supersedes this
link. Leaving the gear icon for clearCache() — that's a separate
concern.
2026-05-21 13:11:28 +02:00
Samuel Enocsson de99d4ede7 fix: address code review for visual layer + topbar (#4) 2026-05-21 12:50:31 +02:00
Samuel Enocsson 8c977d6624 feat: shared visual layer + redesigned topbar (#4)
Introduce new design token set (paper/ink/line/accent + radius/shadow)
with backward-compat aliases for legacy --surface/--navy/--text names.
Swap DM Sans for Plus Jakarta Sans, add JetBrains Mono with tabular
numerics. Replace .app-header with sticky .topbar partial (brand +
segmented nav + Next update / Last refresh meta + Refresh all button).

Add POST /api/refresh-all that runs refreshAllPlayersInDB() with an
in-memory mutex and returns the rendered topbar so HTMX can swap it
in. "Next update" is computed as first Tuesday of next month
(approximation of PDGA's monthly cycle). "Last refresh" derives
from MAX(players.last_updated).
2026-05-21 12:37:31 +02:00