Description
SSR page displaying paginated contests with dynamic filters.
Acceptance Criteria:
- URL params control filters:
/contests?sport=nba&minFee=0.1&page=2
- Server-side rendered initial data using
getServerSideProps
- Client-side pagination via
useSWRInfinite
- Filter sidebar with:
- Sport multi-select (NBA/NFL/MLB)
- Entry fee range slider
- Date picker for start time
- Loading states with skeleton screens
Technical Details:
// pages/contests.tsx
export const getServerSideProps: GetServerSideProps = async ({ query }) => {
const res = await fetch(`${API_URL}/contests?${qs.stringify(query)}`);
return { props: { initialData: await res.json() } };
};
function ContestsPage({ initialData }) {
const { data, setSize } = useSWRInfinite((pageIndex) =>
`/api/contests?${qs.stringify({ ...query, page: pageIndex + 1 })}`
);
return (
<div>
<ContestFilters />
<InfiniteLoader onLoadMore={() => setSize(size => size + 1)}>
{data?.map(page => page.contests.map(contest =>
<ContestCard key={contest.id} {...contest} />
))}
</InfiniteLoader>
</div>
);
}
Notes:
- Use
next-query-params for URL state management
- Debounce filter updates by 500ms
- Implement scroll restoration
Description
SSR page displaying paginated contests with dynamic filters.
Acceptance Criteria:
/contests?sport=nba&minFee=0.1&page=2getServerSidePropsuseSWRInfiniteTechnical Details:
Notes:
next-query-paramsfor URL state management