Summary
#43 made GET /api/user/getallcourses paginated, searchable and filterable on the server. The catalogue never picked any of it up. frontend/src/components/common/AllCourses.jsx still calls the endpoint bare:
const res = await axiosInstance.get("/api/user/getallcourses");
setAllCourses(res.data.data || []);
normalizePagination in backend/utils/pagination.js defaults to DEFAULT_LIMIT = 12, so the response contains 12 courses. The component then filters those 12 in a useMemo, and res.data.pagination is dropped on the floor.
Expected result
- Every published course is reachable from the catalogue.
- The search box searches the whole catalogue, not just the loaded page.
- The Free/Paid filter filters the whole catalogue.
- The result count reflects the number of matching courses, not the number of matching rows in the current page.
- There is some way to move between pages.
Actual result
- The 13th course and everything after it is invisible and cannot be enrolled in. There is no page control anywhere in the UI.
- Searching for a course that exists but sits on page 2 shows "No courses match that search".
- The
{count} courses found counter maxes out at 12 and is wrong the moment there are more courses than that.
- The Free/Paid filter uses
/\d/.test(course.C_price), which classifies a course priced "Free for the first 100" as paid, while the server's FREE_PRICE_PATTERN gets it right. The two disagree.
- Every keystroke re-filters an array the server already knows how to filter, and no request is ever made after the first mount.
Steps to reproduce
- Seed more than 12 courses (
node backend/seed.js, then add a few, or insert directly).
- Open the catalogue on the home page.
- Count the cards — 12, regardless of how many exist.
- Type the exact title of the 15th course into the search box → "No courses match that search".
- Open DevTools → Network. Nothing is requested while typing; only the single mount request is ever sent.
curl 'http://localhost:5000/api/user/getallcourses?page=2' returns the missing courses, so the data is there and the API works.
Notes
- The server already accepts
page, limit, search, category, educator, priceType and sort, and returns pagination: { page, limit, totalItems, totalPages, hasNextPage, hasPreviousPage }. The fix is on the client.
- Typing needs to be debounced, otherwise the search box fires a request per keystroke.
- A request that resolves after a newer one must not overwrite the newer results; the component needs to ignore stale responses.
- The same page is rendered for signed-out visitors on
/ and for signed-in users through UserHome, so the paging controls have to work in both.
Summary
#43 made
GET /api/user/getallcoursespaginated, searchable and filterable on the server. The catalogue never picked any of it up.frontend/src/components/common/AllCourses.jsxstill calls the endpoint bare:normalizePaginationinbackend/utils/pagination.jsdefaults toDEFAULT_LIMIT = 12, so the response contains 12 courses. The component then filters those 12 in auseMemo, andres.data.paginationis dropped on the floor.Expected result
Actual result
{count} courses foundcounter maxes out at 12 and is wrong the moment there are more courses than that./\d/.test(course.C_price), which classifies a course priced"Free for the first 100"as paid, while the server'sFREE_PRICE_PATTERNgets it right. The two disagree.Steps to reproduce
node backend/seed.js, then add a few, or insert directly).curl 'http://localhost:5000/api/user/getallcourses?page=2'returns the missing courses, so the data is there and the API works.Notes
page,limit,search,category,educator,priceTypeandsort, and returnspagination: { page, limit, totalItems, totalPages, hasNextPage, hasPreviousPage }. The fix is on the client./and for signed-in users throughUserHome, so the paging controls have to work in both.