Skip to content

feat(competitions): calendar events, country selector, non-empty default #201

Description

@AnayDhawan

Blocked by #195 and #200.

Competition dates become calendar events, alongside the exam sessions and personal events already there.

Files

  • src/app/calendar/CalendarView.tsx - extend, currently 478 lines
  • src/lib/competition-events.ts - new, flattens competitions into calendar events

What exists today

CalendarView.tsx is a hand-rolled month grid with no date library, and that stays true. Plain Date, plain CSS Grid.

  • :25-29 BOARD_COLORS for SAT, IB, IGCSE
  • :31 PERSONAL_EVENT_COLOR
  • :61-71 getEventsInMonth
  • :91-104 getActiveDaysForEvent handles multi-day windows
  • :201-205 builds the day cell array
  • :380-464 the grid itself, colored dots per board

Two event sources today: the static EXAM_EVENTS array (src/lib/exam-dates.ts) and the user_events Supabase table. Competitions is the third. Add a COMPETITION_EVENT_COLOR next to the existing constants.

The density problem, which has to be designed for rather than discovered

50 competitions with roughly 4 dates each, plus 13 country tracks with roughly 3 stages each, is well over 2000 potential events. Dropping all of that onto a month grid makes it unusable, particularly on mobile.

Three controls, in this order of importance:

  1. Signed-in users with at least one save default to saved competitions only, with a toggle to show all.
  2. Everyone else defaults to all competitions filtered to their country, never to an empty grid. This matters: a saved-only default would give every new and signed-out visitor a blank calendar, and an empty first screen is a bad first screen.
  3. Country tracks render one country at a time. Default to the country on the user's profile (feat(onboarding): user_profiles table with RLS and CHECK constraints (SQL inline) #203) when present, otherwise a picker defaulting to a sensible guess. Never render all 13 at once.

Estimated dates

The estimated flag exists on every date and stage in the dataset. Render those visibly differently from confirmed ones: an outline dot rather than a filled one, and say so in the legend. ExamEvent already carries the same idea via resultsEstimated (src/lib/exam-dates.ts:13-29), so follow whatever that does.

Acceptance criteria

  • Competition dates appear on the correct days in the correct month
  • Signed out: the calendar is not empty, and shows country-scoped competitions
  • Signed in with saves: defaults to saved only, toggle reveals all
  • Signed in with no saves: does not show an empty grid
  • Only one country's stages render at a time
  • Estimated dates are visually distinct and explained in the legend
  • A day with many events stays legible at 360px wide
  • Month navigation stays smooth with all competitions shown
  • Supabase unconfigured: exam events and competitions still render, personal events and the saved filter are absent

Activity

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

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions