Skip to content

feat(competitions): list and grid view toggle on browse #202

Description

@AnayDhawan

Blocked by #196.

A list/grid switch on /competitions. List is the dense deadline-scanning view; grid is the browsing view.

Files

  • src/components/competitions/view-toggle.tsx - new, 'use client'
  • src/components/competitions/competitions-browser.tsx - consume it
  • src/components/competitions/competition-card.tsx - support both variants

Nothing like this exists in the repo yet

Grep for viewMode|view_mode|LayoutGrid|toggle.*view across src/ returns zero hits. The nearest relatives:

  • src/components/docs/docs-index-list.tsx:8-12 - its comment records that a vertical list replaced an icon-card grid
  • src/components/map/results-list.tsx:29 - a generic toggle?: { label, onClick } prop used for "Show all"

Build it once here properly, because #205 needs the same control for the docs index and should reuse this component rather than growing a second one.

Behaviour

  • Two-state segmented control, list and grid, with aria-pressed and a visible label or a title, not an unlabelled icon pair
  • Default is list: deadlines are the reason people come to this page and a list scans faster
  • Persist in localStorage under a namespaced key, read it in an effect so the server render is deterministic and hydration stays clean
  • Wrap the read in try/catch; localStorage throws outright in some privacy modes

Card variants

List: full width, description clamped to three lines, four meta pills in a row, countdown on the right.

Grid: sm:grid-cols-2 lg:grid-cols-3, description clamped to two lines, meta pills wrapping, countdown under the title. Cards in a row must be equal height, so the save row pins to the bottom.

Same component with a variant prop, not two components that drift apart.

Acceptance criteria

  • Toggle switches the layout with no full page reload
  • Choice survives a reload and a navigation away and back
  • Private browsing with localStorage blocked: defaults to list, no console error
  • No hydration warning
  • Keyboard operable, focus visible, state announced via aria-pressed
  • Grid cards in a row are equal height at every breakpoint
  • Both variants readable at 360px

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

    competitionsCompetitions catalog verticaldesignVisual and UX designowner-yashOwned by Yash

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions