Add Stadium Progress system and themed loading spinners

Stadium Progress & Achievements:
- Add StadiumVisit and Achievement SwiftData models
- Create Progress tab with interactive map view
- Implement photo-based visit import with GPS/date matching
- Add achievement badges (count-based, regional, journey)
- Create shareable progress cards for social media
- Add canonical data infrastructure (stadium identities, team aliases)
- Implement score resolution from free APIs (MLB, NBA, NHL stats)

UI Improvements:
- Add ThemedSpinner and ThemedSpinnerCompact components
- Replace all ProgressView() with themed spinners throughout app
- Fix sport selection state not persisting when navigating away

Bug Fixes:
- Fix Coast to Coast trips showing only 1 city (validation issue)
- Fix stadium progress showing 0/0 (filtering issue)
- Remove "Stadium Quest" title from progress view

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Trey t
2026-01-08 20:20:03 -06:00
parent 2281440bf8
commit 92d808caf5
55 changed files with 14348 additions and 61 deletions

View File

@@ -0,0 +1,227 @@
[
{
"id": "mlb_league",
"sport": "MLB",
"type": "league",
"name": "Major League Baseball",
"abbreviation": "MLB",
"parent_id": null,
"display_order": 0
},
{
"id": "mlb_al",
"sport": "MLB",
"type": "conference",
"name": "American League",
"abbreviation": "AL",
"parent_id": "mlb_league",
"display_order": 1
},
{
"id": "mlb_nl",
"sport": "MLB",
"type": "conference",
"name": "National League",
"abbreviation": "NL",
"parent_id": "mlb_league",
"display_order": 2
},
{
"id": "mlb_al_east",
"sport": "MLB",
"type": "division",
"name": "AL East",
"abbreviation": null,
"parent_id": "mlb_al",
"display_order": 1
},
{
"id": "mlb_al_central",
"sport": "MLB",
"type": "division",
"name": "AL Central",
"abbreviation": null,
"parent_id": "mlb_al",
"display_order": 2
},
{
"id": "mlb_al_west",
"sport": "MLB",
"type": "division",
"name": "AL West",
"abbreviation": null,
"parent_id": "mlb_al",
"display_order": 3
},
{
"id": "mlb_nl_east",
"sport": "MLB",
"type": "division",
"name": "NL East",
"abbreviation": null,
"parent_id": "mlb_nl",
"display_order": 1
},
{
"id": "mlb_nl_central",
"sport": "MLB",
"type": "division",
"name": "NL Central",
"abbreviation": null,
"parent_id": "mlb_nl",
"display_order": 2
},
{
"id": "mlb_nl_west",
"sport": "MLB",
"type": "division",
"name": "NL West",
"abbreviation": null,
"parent_id": "mlb_nl",
"display_order": 3
},
{
"id": "nba_league",
"sport": "NBA",
"type": "league",
"name": "National Basketball Association",
"abbreviation": "NBA",
"parent_id": null,
"display_order": 0
},
{
"id": "nba_eastern",
"sport": "NBA",
"type": "conference",
"name": "Eastern Conference",
"abbreviation": "East",
"parent_id": "nba_league",
"display_order": 1
},
{
"id": "nba_western",
"sport": "NBA",
"type": "conference",
"name": "Western Conference",
"abbreviation": "West",
"parent_id": "nba_league",
"display_order": 2
},
{
"id": "nba_atlantic",
"sport": "NBA",
"type": "division",
"name": "Atlantic",
"abbreviation": null,
"parent_id": "nba_eastern",
"display_order": 1
},
{
"id": "nba_central",
"sport": "NBA",
"type": "division",
"name": "Central",
"abbreviation": null,
"parent_id": "nba_eastern",
"display_order": 2
},
{
"id": "nba_southeast",
"sport": "NBA",
"type": "division",
"name": "Southeast",
"abbreviation": null,
"parent_id": "nba_eastern",
"display_order": 3
},
{
"id": "nba_northwest",
"sport": "NBA",
"type": "division",
"name": "Northwest",
"abbreviation": null,
"parent_id": "nba_western",
"display_order": 1
},
{
"id": "nba_pacific",
"sport": "NBA",
"type": "division",
"name": "Pacific",
"abbreviation": null,
"parent_id": "nba_western",
"display_order": 2
},
{
"id": "nba_southwest",
"sport": "NBA",
"type": "division",
"name": "Southwest",
"abbreviation": null,
"parent_id": "nba_western",
"display_order": 3
},
{
"id": "nhl_league",
"sport": "NHL",
"type": "league",
"name": "National Hockey League",
"abbreviation": "NHL",
"parent_id": null,
"display_order": 0
},
{
"id": "nhl_eastern",
"sport": "NHL",
"type": "conference",
"name": "Eastern Conference",
"abbreviation": "East",
"parent_id": "nhl_league",
"display_order": 1
},
{
"id": "nhl_western",
"sport": "NHL",
"type": "conference",
"name": "Western Conference",
"abbreviation": "West",
"parent_id": "nhl_league",
"display_order": 2
},
{
"id": "nhl_atlantic",
"sport": "NHL",
"type": "division",
"name": "Atlantic",
"abbreviation": null,
"parent_id": "nhl_eastern",
"display_order": 1
},
{
"id": "nhl_metropolitan",
"sport": "NHL",
"type": "division",
"name": "Metropolitan",
"abbreviation": null,
"parent_id": "nhl_eastern",
"display_order": 2
},
{
"id": "nhl_central",
"sport": "NHL",
"type": "division",
"name": "Central",
"abbreviation": null,
"parent_id": "nhl_western",
"display_order": 1
},
{
"id": "nhl_pacific",
"sport": "NHL",
"type": "division",
"name": "Pacific",
"abbreviation": null,
"parent_id": "nhl_western",
"display_order": 2
}
]

View File

@@ -0,0 +1,306 @@
[
{
"id": "alias_nba_brk_njn",
"team_canonical_id": "team_nba_brk",
"alias_type": "abbreviation",
"alias_value": "NJN",
"valid_from": null,
"valid_until": "2012-05-01T00:00:00Z"
},
{
"id": "alias_nba_brk_nj_nets",
"team_canonical_id": "team_nba_brk",
"alias_type": "name",
"alias_value": "New Jersey Nets",
"valid_from": null,
"valid_until": "2012-05-01T00:00:00Z"
},
{
"id": "alias_nba_brk_nj_city",
"team_canonical_id": "team_nba_brk",
"alias_type": "city",
"alias_value": "New Jersey",
"valid_from": null,
"valid_until": "2012-05-01T00:00:00Z"
},
{
"id": "alias_nba_okc_sea",
"team_canonical_id": "team_nba_okc",
"alias_type": "abbreviation",
"alias_value": "SEA",
"valid_from": null,
"valid_until": "2008-07-01T00:00:00Z"
},
{
"id": "alias_nba_okc_sonics",
"team_canonical_id": "team_nba_okc",
"alias_type": "name",
"alias_value": "Seattle SuperSonics",
"valid_from": null,
"valid_until": "2008-07-01T00:00:00Z"
},
{
"id": "alias_nba_okc_seattle",
"team_canonical_id": "team_nba_okc",
"alias_type": "city",
"alias_value": "Seattle",
"valid_from": null,
"valid_until": "2008-07-01T00:00:00Z"
},
{
"id": "alias_nba_mem_van",
"team_canonical_id": "team_nba_mem",
"alias_type": "abbreviation",
"alias_value": "VAN",
"valid_from": null,
"valid_until": "2001-05-01T00:00:00Z"
},
{
"id": "alias_nba_mem_vancouver",
"team_canonical_id": "team_nba_mem",
"alias_type": "name",
"alias_value": "Vancouver Grizzlies",
"valid_from": null,
"valid_until": "2001-05-01T00:00:00Z"
},
{
"id": "alias_nba_nop_noh",
"team_canonical_id": "team_nba_nop",
"alias_type": "abbreviation",
"alias_value": "NOH",
"valid_from": "2002-01-01T00:00:00Z",
"valid_until": "2013-05-01T00:00:00Z"
},
{
"id": "alias_nba_nop_hornets",
"team_canonical_id": "team_nba_nop",
"alias_type": "name",
"alias_value": "New Orleans Hornets",
"valid_from": "2002-01-01T00:00:00Z",
"valid_until": "2013-05-01T00:00:00Z"
},
{
"id": "alias_nba_cho_cha_old",
"team_canonical_id": "team_nba_cho",
"alias_type": "abbreviation",
"alias_value": "CHA",
"valid_from": "2014-01-01T00:00:00Z",
"valid_until": null
},
{
"id": "alias_nba_was_wsh",
"team_canonical_id": "team_nba_was",
"alias_type": "abbreviation",
"alias_value": "WSH",
"valid_from": null,
"valid_until": null
},
{
"id": "alias_nba_uta_utj",
"team_canonical_id": "team_nba_uta",
"alias_type": "abbreviation",
"alias_value": "UTJ",
"valid_from": null,
"valid_until": null
},
{
"id": "alias_nba_pho_phx",
"team_canonical_id": "team_nba_pho",
"alias_type": "abbreviation",
"alias_value": "PHX",
"valid_from": null,
"valid_until": null
},
{
"id": "alias_mlb_mia_fla",
"team_canonical_id": "team_mlb_mia",
"alias_type": "abbreviation",
"alias_value": "FLA",
"valid_from": null,
"valid_until": "2012-01-01T00:00:00Z"
},
{
"id": "alias_mlb_mia_marlins_fl",
"team_canonical_id": "team_mlb_mia",
"alias_type": "name",
"alias_value": "Florida Marlins",
"valid_from": null,
"valid_until": "2012-01-01T00:00:00Z"
},
{
"id": "alias_mlb_mia_florida",
"team_canonical_id": "team_mlb_mia",
"alias_type": "city",
"alias_value": "Florida",
"valid_from": null,
"valid_until": "2012-01-01T00:00:00Z"
},
{
"id": "alias_mlb_laa_ana",
"team_canonical_id": "team_mlb_laa",
"alias_type": "abbreviation",
"alias_value": "ANA",
"valid_from": null,
"valid_until": "2005-01-01T00:00:00Z"
},
{
"id": "alias_mlb_laa_angels_ana",
"team_canonical_id": "team_mlb_laa",
"alias_type": "name",
"alias_value": "Anaheim Angels",
"valid_from": null,
"valid_until": "2005-01-01T00:00:00Z"
},
{
"id": "alias_mlb_laa_california",
"team_canonical_id": "team_mlb_laa",
"alias_type": "name",
"alias_value": "California Angels",
"valid_from": null,
"valid_until": "1996-01-01T00:00:00Z"
},
{
"id": "alias_mlb_tbr_tbd",
"team_canonical_id": "team_mlb_tbr",
"alias_type": "abbreviation",
"alias_value": "TBD",
"valid_from": null,
"valid_until": "2008-01-01T00:00:00Z"
},
{
"id": "alias_mlb_tbr_devil_rays",
"team_canonical_id": "team_mlb_tbr",
"alias_type": "name",
"alias_value": "Tampa Bay Devil Rays",
"valid_from": null,
"valid_until": "2008-01-01T00:00:00Z"
},
{
"id": "alias_mlb_was_mon",
"team_canonical_id": "team_mlb_was",
"alias_type": "abbreviation",
"alias_value": "MON",
"valid_from": null,
"valid_until": "2005-01-01T00:00:00Z"
},
{
"id": "alias_mlb_was_expos",
"team_canonical_id": "team_mlb_was",
"alias_type": "name",
"alias_value": "Montreal Expos",
"valid_from": null,
"valid_until": "2005-01-01T00:00:00Z"
},
{
"id": "alias_mlb_was_montreal",
"team_canonical_id": "team_mlb_was",
"alias_type": "city",
"alias_value": "Montreal",
"valid_from": null,
"valid_until": "2005-01-01T00:00:00Z"
},
{
"id": "alias_nhl_ari_pho",
"team_canonical_id": "team_nhl_uta",
"alias_type": "abbreviation",
"alias_value": "ARI",
"valid_from": "1996-01-01T00:00:00Z",
"valid_until": "2024-05-01T00:00:00Z"
},
{
"id": "alias_nhl_ari_coyotes",
"team_canonical_id": "team_nhl_uta",
"alias_type": "name",
"alias_value": "Arizona Coyotes",
"valid_from": "1996-01-01T00:00:00Z",
"valid_until": "2024-05-01T00:00:00Z"
},
{
"id": "alias_nhl_ari_phoenix",
"team_canonical_id": "team_nhl_uta",
"alias_type": "name",
"alias_value": "Phoenix Coyotes",
"valid_from": "1996-01-01T00:00:00Z",
"valid_until": "2014-01-01T00:00:00Z"
},
{
"id": "alias_nhl_wpg_atl",
"team_canonical_id": "team_nhl_wpg",
"alias_type": "abbreviation",
"alias_value": "ATL",
"valid_from": "1999-01-01T00:00:00Z",
"valid_until": "2011-05-01T00:00:00Z"
},
{
"id": "alias_nhl_wpg_thrashers",
"team_canonical_id": "team_nhl_wpg",
"alias_type": "name",
"alias_value": "Atlanta Thrashers",
"valid_from": "1999-01-01T00:00:00Z",
"valid_until": "2011-05-01T00:00:00Z"
},
{
"id": "alias_nhl_car_htf",
"team_canonical_id": "team_nhl_car",
"alias_type": "abbreviation",
"alias_value": "HTF",
"valid_from": null,
"valid_until": "1997-01-01T00:00:00Z"
},
{
"id": "alias_nhl_car_whalers",
"team_canonical_id": "team_nhl_car",
"alias_type": "name",
"alias_value": "Hartford Whalers",
"valid_from": null,
"valid_until": "1997-01-01T00:00:00Z"
},
{
"id": "alias_nhl_col_que",
"team_canonical_id": "team_nhl_col",
"alias_type": "abbreviation",
"alias_value": "QUE",
"valid_from": null,
"valid_until": "1995-05-01T00:00:00Z"
},
{
"id": "alias_nhl_col_nordiques",
"team_canonical_id": "team_nhl_col",
"alias_type": "name",
"alias_value": "Quebec Nordiques",
"valid_from": null,
"valid_until": "1995-05-01T00:00:00Z"
},
{
"id": "alias_nhl_dal_mns",
"team_canonical_id": "team_nhl_dal",
"alias_type": "abbreviation",
"alias_value": "MNS",
"valid_from": null,
"valid_until": "1993-05-01T00:00:00Z"
},
{
"id": "alias_nhl_dal_north_stars",
"team_canonical_id": "team_nhl_dal",
"alias_type": "name",
"alias_value": "Minnesota North Stars",
"valid_from": null,
"valid_until": "1993-05-01T00:00:00Z"
},
{
"id": "alias_nhl_ana_mda",
"team_canonical_id": "team_nhl_ana",
"alias_type": "name",
"alias_value": "Mighty Ducks of Anaheim",
"valid_from": null,
"valid_until": "2006-06-01T00:00:00Z"
},
{
"id": "alias_nhl_vgk_lv",
"team_canonical_id": "team_nhl_vgk",
"alias_type": "abbreviation",
"alias_value": "LV",
"valid_from": null,
"valid_until": null
}
]