Description
/courses renders 6 hardcoded fake courses with no search, no filtering, and no API call. This issue replaces the static list with real backend data, live search, difficulty and tag filters, sort options, and infinite scroll pagination.
Background
frontend/app/courses/page.tsx defines const courses = [...] — 6 fake entries, no API call
- Backend:
GET /api/v1/courses with query params: search, difficulty, tags, sortBy, sortOrder, page, limit
GET /api/v1/courses/tags returns available tags for filter chips
frontend/components/course-card.tsx exists and should be reused and extended
Implementation Guide
Remove hardcoded courses array. Create frontend/hooks/use-courses.ts using useInfiniteQuery calling GET /api/v1/courses.
Create frontend/components/courses/course-filters.tsx: debounced search input (300ms), difficulty pill buttons (All/Beginner/Intermediate/Advanced), tag chips populated from GET /courses/tags (multi-select), and a sort selector.
Update CourseCard to display enrollmentCount and an isEnrolled green badge for authenticated users.
Add "Load More" button calling fetchNextPage(). Show loading skeleton grid and empty state with "Clear filters" button.
Acceptance Criteria
Complexity: High - 200 points
Join: https://t.me/ByteChainAcademy | Contact: contact@nexacore.org
Description
/coursesrenders 6 hardcoded fake courses with no search, no filtering, and no API call. This issue replaces the static list with real backend data, live search, difficulty and tag filters, sort options, and infinite scroll pagination.Background
frontend/app/courses/page.tsxdefinesconst courses = [...]— 6 fake entries, no API callGET /api/v1/courseswith query params:search,difficulty,tags,sortBy,sortOrder,page,limitGET /api/v1/courses/tagsreturns available tags for filter chipsfrontend/components/course-card.tsxexists and should be reused and extendedImplementation Guide
Remove hardcoded courses array. Create
frontend/hooks/use-courses.tsusinguseInfiniteQuerycallingGET /api/v1/courses.Create
frontend/components/courses/course-filters.tsx: debounced search input (300ms), difficulty pill buttons (All/Beginner/Intermediate/Advanced), tag chips populated fromGET /courses/tags(multi-select), and a sort selector.Update
CourseCardto displayenrollmentCountand anisEnrolledgreen badge for authenticated users.Add "Load More" button calling
fetchNextPage(). Show loading skeleton grid and empty state with "Clear filters" button.Acceptance Criteria
courses/page.tsxGET /courses/tagsuseInfiniteQueryComplexity: High - 200 points
Join: https://t.me/ByteChainAcademy | Contact: contact@nexacore.org