Skip to content

Add pagination, filtering, and sorting to the bounty board with mock-data parity #28

Description

@chonilius

Problem

src/app/issues/page.tsx renders the bounty board — presumably the highest-traffic, most performance-sensitive route since it's the primary discovery surface for contributors per the README's feature map. fetchBounties in src/lib/api.ts has no pagination, filtering, or sorting parameters — it fetches the entire /bounties collection in one call every time the page renders. As the platform grows past a small demo dataset, this becomes a scaling problem on multiple axes simultaneously: unbounded server-side payload size and Server Component render time, no way for a contributor to filter by difficulty/asset/repo/reward-range without client-side filtering of an already-fully-loaded dataset (wasteful and eventually infeasible), and no URL-shareable filter/sort state (a contributor can't bookmark or share "beginner USDC bounties over $50" as a link).

Why this is hard

  • This requires designing a pagination/filtering contract against a backend (mergefi-backend) that, per the currently visible frontend code, has no evidence of supporting query params on /bounties at all — you need to either verify the backend already supports this (check the mergefi/backend repo) or explicitly scope this as a paired frontend+backend change and design the frontend to degrade sensibly if backend support lands later.
  • Filter/sort state needs to live in the URL (Next.js searchParams in the Server Component) for shareability and correct back/forward browser navigation, not in client-only React state — this affects whether /issues can remain a Server Component or needs restructuring, since reading searchParams in a Server Component and passing filtered/paginated results down is the correct App Router pattern but requires re-architecting how fetchBounties/adaptBounty are invoked (per-page-load with params, not once with a static fallback).
  • The mock-data fallback path (fetchWithFallback/fetchBounties's catch-and-return-fallback) needs to also respect the same filter/sort/pagination params against mock-data.ts so the "always demoable without a backend" property from the README isn't broken by this change — i.e. mock-data.ts needs in-memory filter/sort/paginate logic mirroring what the backend would do.
  • Must design sensible defaults and limits (page size, max sortable fields) and handle edge cases: filters that produce zero results, invalid/out-of-range page numbers in the URL, combining multiple simultaneous filters.

Scope

  • Design and document the pagination/filter/sort query contract (params, defaults, limits).
  • Update fetchBounties (and request) to accept and forward these params to the backend.
  • Add equivalent in-memory filter/sort/pagination logic for the mock-data.ts fallback path so demos remain fully functional offline.
  • Restructure src/app/issues/page.tsx to read searchParams, pass them through, and render filter/sort controls that update the URL (not just local state).
  • Add an empty-state and invalid-page-number handling (e.g. clamp or redirect to a valid page).
  • Coordinate/document the required backend contract as a note in the PR if backend support doesn't yet exist.

Acceptance criteria

  • Filtering and sorting the bounty board produces a shareable, bookmarkable URL that reproduces the same filtered view on reload.
  • The page works fully (with correct filtering/sorting/pagination) against mock data with no backend running.
  • Invalid page/filter query params degrade gracefully rather than erroring the page.

Metadata

Metadata

Assignees

No one assigned

    Labels

    GrantFox OSSIssue tracked in GrantFox OSSMaybe RewardedIssue may be eligible for a GrantFox rewardOfficial Campaign | FWC26Campaign: Official Campaign | FWC26enhancementNew feature or requestperformancePerformance/optimization issuevery hardVery difficult task, expert-level effort required

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions