Commit graph

10 commits

Author SHA1 Message Date
Claude
f91f7dd7ad
Show full matchup in My Upcoming Events for bracket matches
Bracket match matchLabel now includes "P1 vs P2" alongside the round
name (e.g. "Quarterfinals — Team Spirit vs G2 Esports") so users can
see who their drafted team is playing, not just the team they own.
relevantParticipants stays drafted-only since it also drives the
"X of your picks" badge UI.

https://claude.ai/code/session_01NpQNGWacjg7mbnq8aaUweJ
2026-06-16 19:43:19 +00:00
fe4e1b3f3c claude/beautiful-hawking-a72ilq (#92)
All checks were successful
🚀 Deploy / 🧪 Test (push) Successful in 3m24s
🚀 Deploy / ʦ🔍 Typecheck & Lint (push) Successful in 1m38s
🚀 Deploy / 🐳 Build (push) Successful in 1m29s
🚀 Deploy / 🚀 Deploy (push) Successful in 9s
2026-06-16 14:11:51 +00:00
a9d4954242 Fix World Cup group stage display and upcoming events (#55)
All checks were successful
🚀 Deploy / 🧪 Test (push) Successful in 1m28s
🚀 Deploy / ʦ TypeScript (push) Successful in 1m17s
🚀 Deploy / 🔍 Lint (push) Successful in 49s
🚀 Deploy / 🐳 Build (push) Successful in 14m50s
🚀 Deploy / 🚀 Deploy (push) Successful in 10s
## Summary

- **Group stage match list**: Removed MD 1/2/3 headings; matches now listed chronologically under date separators (e.g. "Jun 14"). Kick-off time appears below the team names instead of between them.
- **Sort order**: \`findMatchesByGroupIds\` / \`findMatchesByEventId\` now order by \`scheduledAt ASC NULLS LAST\` so unscheduled matches always trail scheduled ones.
- **Groups/Bracket toggle**: When both group stage and knockout bracket exist, a toggle appears (mirroring the NBA/AFL standings toggle). Sports with both regular-season standings and a group stage get all views available.
- **Upcoming events**: \`getUpcomingEventsForDraftedParticipants\` now also queries \`groupStageMatches\`, so World Cup group fixtures appear on the home page calendar sorted by kick-off time with a label like "Group A — France vs Germany".
- **\`isAllCompete\` fix**: \`UpcomingEventsCard\` and \`UpcomingCalendarPanel\` now treat \`group_stage_match\` as a bracket-style event, showing team badges instead of "N of your picks".

Fixes #53

## Test plan

- [ ] Navigate to a World Cup sports season page — groups should be listed chronologically under date headers with no MD labels; kick-off time should appear below each match row
- [ ] Once the knockout bracket has matches, confirm the Groups/Bracket toggle appears and both views render correctly
- [ ] On the home page, a user with drafted World Cup participants should see upcoming group fixtures in the calendar panel with individual team badges (not a participant count)
- [ ] NBA/AFL/NHL pages unaffected — their standings/playoffs/finished toggle still works normally
- [ ] \`npm run typecheck\` and \`npm run test:run\` pass

Co-authored-by: Chris Parsons <chrisparsons1127@gmail.com>
Reviewed-on: #55
2026-05-27 05:43:08 +00:00
Chris Parsons
e03bdd538f
Fix upcoming events grouping to separate individual bracket matches (#302)
Include playoffMatchId in the grouping key so that each match within a
scoring event (e.g. different Round of 32 matchups in snooker) appears
as its own calendar entry instead of being merged together.
2026-04-16 14:19:59 -07:00
Chris Parsons
efbd28b446
Exclude completed playoff matches from upcoming events query (#247)
* Exclude scored bracket matches from upcoming events calendar

Add `eq(schema.playoffMatches.isComplete, false)` to the bracket-sports
query in `getUpcomingEventsForDraftedParticipants` so that individual
playoff matches already scored (isComplete = true) no longer appear on
the upcoming events calendar, even when the parent scoring event is still
open.

Also update the schema mock in upcoming-calendar.test.ts to include
`playoffMatches.isComplete` and add a test covering this behaviour.

https://claude.ai/code/session_01GMLmjN9mwoANfpgSciD7Bi

* Fix leaked mockReturnValueOnce in scored-match test

The new test only triggers one selectDistinct call (rows is empty so the
max-game-number lookup is skipped). The second mockReturnValueOnce was
never consumed, leaving a makeMaxGameChain value in the queue that was
then picked up by the subsequent "uses leftJoin" test, causing it to fail
with "leftJoin is not a function".

https://claude.ai/code/session_01GMLmjN9mwoANfpgSciD7Bi

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-03-31 10:08:25 -07:00
Chris Parsons
3c4ed67946
Add upcoming events pages and fix timezone filtering, fixes #213 (#235)
- Fix UTC midnight rollover bug: server now queries from yesterday UTC
  as a buffer; UpcomingCalendarPanel filters to local-today client-side
  via useEffect + Intl.DateTimeFormat, removing the need for any
  cookie or server-side timezone detection
- Cap homepage and league page panels at 6 events with a "View all" link
- Add /upcoming-events page (60-day view across all leagues)
- Add /leagues/:leagueId/upcoming-events page (60-day per-league view)
- Add emptyMessage prop to UpcomingCalendarPanel for context-specific copy
- Change getUpcomingEventsForDraftedParticipants to accept pre-computed
  date strings instead of Date objects

fixes #213

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-27 00:49:16 -07:00
Chris Parsons
e4285876ad Fix oxlint errors. 2026-03-22 20:41:44 -07:00
Chris Parsons
88e18412ec
Don't show Game #1 label for single-game matchups in calendar (#206)
* Don't show Game #1 label for single-game matchups in calendar

When a matchup has only one game, showing "Game #1" is redundant and
unhelpful. Only show game numbers when there are multiple games in a
matchup (gameKeys.size > 1). For single-game matchups, show just the
round name (or null if it matches the event name).

Closes #198

https://claude.ai/code/session_01CRrqu43FKHshpJt1NyrDdX

* Show game number for Game #2+ in series, hide Game #1 for single-game matchups

If a matchup has only one game (game #1), the number is redundant — show
just the round name. If game #2 or higher is upcoming, it clearly belongs
to a multi-game series, so show the game number to distinguish it.

https://claude.ai/code/session_01CRrqu43FKHshpJt1NyrDdX

* Fix Game #1 label for multi-game series when only Game #1 is in date window

Previously, Game #1 of a multi-game series showed no game number (e.g.
"Semifinals") if Game #2 fell outside the calendar date range. Since at
least 2 games are always entered for a series from the start, a second
un-date-filtered query now checks the max game number per event. If max
> 1, the event is a series and Game #1 is labelled accordingly
(e.g. "Semifinals Game #1").

https://claude.ai/code/session_01CRrqu43FKHshpJt1NyrDdX

* Show game number when multiple games from same series are in date window

The gameKeys.size > 1 branch previously showed only the round name,
contradicting the rule that multi-game series always show "Game #x".
Now shows the lowest game number visible in the window (e.g. both
Game #1 and #2 upcoming → "Semifinals Game #1").

https://claude.ai/code/session_01CRrqu43FKHshpJt1NyrDdX

* Split series games into individual calendar entries, each showing Game #x

Each game in a multi-game bracket series (e.g. Game #1 on Mar 23,
Game #2 on Mar 25) now appears as its own row on the calendar with its
own date and "Round Game #x" label. Single-game matchups are unchanged.

Grouping key changes from eventId to eventId|gameNumber for series events.
The max-game-number lookup now runs before grouping so the correct key
can be determined while processing each row.

https://claude.ai/code/session_01CRrqu43FKHshpJt1NyrDdX

* Cache isSeries per entry to avoid re-deriving it in the finalization loop

https://claude.ai/code/session_01CRrqu43FKHshpJt1NyrDdX

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-03-22 16:39:26 -07:00
Chris Parsons
dc13d99f39
Add event_starts_at timestamp to scoring events for sub-day ordering (#146)
- New `event_starts_at timestamptz` column on `scoring_events`; backfilled
  from `event_date` (midnight UTC) via migration for all existing rows
- Admin create/edit forms consolidated from separate Date + Time inputs into
  a single `datetime-local` field; server derives `eventDate` from the UTC
  date portion of `eventStartsAt` so calendar-window queries continue to work
- Edit form pre-fill computed client-side via useEffect to avoid server-timezone
  mismatch for non-UTC admins
- Sort fix: replaced `eventDate ?? earliestGameTime.split("T")[0]` with
  `toEventSortKey` helper that prefers `earliestGameTime ?? eventDate` so
  bracket events with only per-game timestamps sort in the correct calendar position
- DB sort queries updated to use `eventStartsAt` as a tiebreaker after `eventDate`
- F1/IndyCar/golf events now populate `earliestGameTime` from `eventStartsAt`,
  giving time display in `UpcomingCalendarPanel`
- Bulk import gains optional `HH:MM` (UTC) third column
- New unit tests for `toEventSortKey` and `eventStartsAt` model behavior

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-15 10:22:42 -07:00
Chris Parsons
4fe76b6845
Display upcoming matches (#141) 2026-03-12 10:12:38 -07:00