โ– humdrum codex / sportsball
license AGPL-3.0

โ† issues

TASK-016 League standings view

๐Ÿ Done feature priority: medium

created 2026-06-17 17:43 ยท updated 2026-06-18 01:17

Description

Show league tables/standings (W-L, GP, pts, GB/GD, rank) for the selected league, fetched from ESPN's standings endpoint. A new view reachable from the dashboard; respects the user's enabled-league set. Soccer = group/table standings; stick-and-ball = division/conference records.

Acceptance Criteria

Implementation Plan

  1. model.Standings{League,Groups[]} -> StandingsGroup{Name,Columns[],Rows[]} -> StandingsRow{Rank,Team,Values[]}.
  2. espn.Client.Standings(ctx,l): GET apis/v2 base (not apis/site/v2); recursive walk of children -> emit a group per node that has entries (soccer=groups, MLB=AL/NL, NBA/NHL/NFL=conferences). Per-sport column spec (soccer P/W/D/L/GD/Pts; baseball+nba PCT/GB; nfl T; nhl OTL/PTS). Stats keyed by type->displayValue. Rank = entry index.
  3. UI viewStandings: open with key from dashboard for selected league (filter=All -> first enabled; tab/arrows cycle leagues). Own cursor over flattened team rows; enter opens that team's schedule (TASK-017). esc closes. Grouped, ranked, team-colored tables; scroll-clamped body like detail.

Final Summary

Added a standings view (viewStandings, opened with 'S').

What:

Tests: mapStandings (nested flatten + per-sport columns + missing-stat blanks), Standings.RowAt/RowCount. Live-smoke verified MLB AL/NL and World Cup 12 groups map correctly. go vet + go test ./... pass.