Sort Explore and keep filters in the URL #32

Open
opened 2026-10-03 19:44:36 +00:00 by jalenluorion · 0 comments
Member

Goal
Let students sort Explore by "Soonest" or "Most saved", and keep the search, tag, and type filters in the URL so a filtered view can be bookmarked or shared.

What you'll learn
URL query params, React state, and passing filters to the API.

Resources

Where to start

  • web/src/app/components/SearchResultSidebar.tsx: search text, tags (multi-select), date, and event type are all held in useState, so they reset on reload. Tag ids are sent to GET /api/events/?tags=1,2. The type and search filters run on the client.
  • api/app/api/events.py, get_all_events: already accepts term, tags, date, and event_type, and orders by start_datetime ascending, so "Soonest" is today's default order.
  • Use useSearchParams, useRouter, and usePathname from next/navigation. Read the initial state from the URL, and call router.replace when a filter changes.

Done when

  • A Sort control offers "Soonest" (default) and "Most saved", which sorts by saved_count descending
  • /explore?q=career&type=CAREER&tags=3&sort=saved restores exactly that view on reload
  • Changing a filter updates the URL without adding a history entry for every keystroke
  • Clearing filters returns to a clean /explore
  • Works in light and dark mode

Notes
Depends on "Show how many people saved an event" for saved_count. A tag filter already exists, so wire it to the URL instead of building a new one. Debounce the search box before writing it to the URL.

**Goal** Let students sort Explore by "Soonest" or "Most saved", and keep the search, tag, and type filters in the URL so a filtered view can be bookmarked or shared. **What you'll learn** URL query params, React state, and passing filters to the API. **Resources** - [Next.js useSearchParams](https://nextjs.org/docs/app/api-reference/functions/use-search-params) - [URLSearchParams](https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams) **Where to start** - `web/src/app/components/SearchResultSidebar.tsx`: search text, tags (multi-select), date, and event type are all held in `useState`, so they reset on reload. Tag ids are sent to `GET /api/events/?tags=1,2`. The type and search filters run on the client. - `api/app/api/events.py`, `get_all_events`: already accepts `term`, `tags`, `date`, and `event_type`, and orders by `start_datetime` ascending, so "Soonest" is today's default order. - Use `useSearchParams`, `useRouter`, and `usePathname` from `next/navigation`. Read the initial state from the URL, and call `router.replace` when a filter changes. **Done when** - [ ] A Sort control offers "Soonest" (default) and "Most saved", which sorts by `saved_count` descending - [ ] `/explore?q=career&type=CAREER&tags=3&sort=saved` restores exactly that view on reload - [ ] Changing a filter updates the URL without adding a history entry for every keystroke - [ ] Clearing filters returns to a clean `/explore` - [ ] Works in light and dark mode **Notes** Depends on "Show how many people saved an event" for `saved_count`. A tag filter already exists, so wire it to the URL instead of building a new one. Debounce the search box before writing it to the URL.
jalenluorion added this to the Phase 2 milestone 2026-10-03 19:44:36 +00:00
jalenluorion added this to the CMUCal project 2026-10-03 19:45:09 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
ScottyLabs/cal#32
No description provided.