Page: Course Browse

Code: CBRO Route: /courses Access: Public Priority: P0 Test Script: scripts/page-tests/test-CBRO.sh Components: src/components/courses/CourseBrowse.tsx

Purpose

Allow visitors and users to discover courses through browsing, filtering, and searching.


Connections

Incoming (users arrive from)

Source Trigger Notes
HOME "Browse Courses" CTA Primary path
HOME "View All Courses" link From featured section
CDET Back/breadcrumb Return from course detail
CPRO "View Courses" on creator profile Filtered by creator
Nav "Courses" nav link Global navigation
(External) Direct URL, search /courses or /courses?q=...

Outgoing (users navigate to)

Target Trigger Notes
CDET Course card click View course details
CPRO Creator name/avatar click View creator profile
SGUP "Sign up to enroll" prompt If trying to enroll while logged out
LGIN "Log in" link Returning users

Data Requirements

Entity Fields Used Purpose
courses id, title, slug, thumbnail, price, rating, rating_count, level, duration, badge, student_count Course cards
categories id, name, slug Filter options
course_tags tag Filter/search
users (creators) id, name, avatar Creator info on cards

Sections

Header

  • Page title: "Browse Courses" or "Courses"
  • Search bar with placeholder text

Filters Sidebar/Bar

  • Category: Dropdown or checkbox list
  • Level: Beginner, Intermediate, Advanced
  • Duration: Short (<4 weeks), Medium (4-8 weeks), Long (8+ weeks)
  • Clear filters button
  • Active filter pills

Sort Options

  • Relevance (default for search)
  • Newest
  • Most Popular (student_count)
  • Highest Rated
  • Price: Low to High
  • Price: High to Low

Course Grid

  • Responsive grid: 3 columns desktop, 2 tablet, 1 mobile
  • Course card components:
  • - Thumbnail with badge overlay (if applicable)
  • - Title
  • - Creator name + avatar
  • - Rating stars + count
  • - Level badge
  • - Price
  • - Duration

Pagination/Load More

  • Pagination controls
  • Results count: "Showing 1-12 of 48 courses"

Empty State

  • No courses match filters
  • Suggestion to clear filters or browse all

User Stories Fulfilled

  • US-G005
  • US-S001
  • US-S003
  • US-S057
  • US-S058

States & Variations

State Description
Default All courses, no filters
Filtered Active filters applied, filter pills shown
Search Results Query in search bar, results sorted by relevance
Empty Results No courses match, show empty state
Loading Skeleton cards while fetching
Creator Filtered Arrived from CPRO, pre-filtered by creator

Mobile Considerations

  • Filters collapse into modal/drawer (tap "Filters" button)
  • Single column course cards
  • Sticky search bar at top
  • Sort dropdown accessible

Error Handling

Error Display
Search/filter fails "Unable to load courses. Please try again." + retry button
No results Empty state with clear filters suggestion

Analytics Events

Event Trigger Data
page_view Page load filters_applied, search_query
search Search submitted query, results_count
filter_applied Filter changed filter_type, filter_value
course_card_click Course clicked course_id, position, filters_active
sort_changed Sort option changed sort_option

Planned API Calls

Endpoint When Purpose
GET /api/courses Page load Course list with pagination
GET /api/categories Page load Filter options

Notes

  • Client-side filtering with URL state sync
  • Responsive grid: 3 → 2 → 1 columns
  • URL should reflect filters for shareability: /courses?level=beginner&category=ai
  • Genesis Cohort: Only 4 courses initially, consider hiding some filters
  • Consider saved filters for logged-in users (future)

Features

Search & Discovery

  • Course listing grid [US-G005]
  • Search with debounce [US-S001]
  • Sort dropdown (relevance, newest, popular, rating, price) [US-S003]

Filtering

  • Category filter (radio buttons list) [US-S058]
  • Level filter (Beginner, Intermediate, Advanced) [US-S057]
  • Price range filter (slider or preset ranges) [US-S003] Not implemented
  • Duration filter (Short, Medium, Long) [US-S003]
  • Clear filters button [US-S003]
  • Active filter pills [US-S003]

Display

  • Responsive grid: 3 columns desktop, 2 tablet, 1 mobile [US-G005]
  • Course cards with thumbnail, title, creator, rating, level, price [US-G005]
  • Badge overlay on cards (if applicable) [US-G005]
  • Pagination [US-G005]
  • Results count display [US-G005]

States

  • Loading state (skeleton cards) [US-G005]
  • Empty state (no results with suggestions) [US-G005]
  • Mobile filter drawer [US-S003]

Interactive Elements

Buttons: 36/36 active Links: 20/20 active

Buttons

Element Component Action Status
Search input CourseBrowse Debounced search (300ms), updates filter active
Sort dropdown CourseBrowse Changes sort order (popular, rating, newest, price) active
Mobile filters button CourseBrowse Opens filter drawer (mobile only) active
Category radio buttons (15) FilterContent Sets selectedCategory, resets page active
Level radio buttons (3) FilterContent Sets selectedLevel, resets page active
Duration radio buttons (3) FilterContent Sets selectedDuration, resets page active
Clear all filters link FilterContent Resets all filters and search active
Category pill × button CourseBrowse Clears category filter active
Level pill × button CourseBrowse Clears level filter active
Duration pill × button CourseBrowse Clears duration filter active
Search query pill × button CourseBrowse Clears search query active
Previous button CourseBrowse Decrements page active
Next button CourseBrowse Increments page active
Page number buttons CourseBrowse Sets specific page active
Backdrop click (mobile) CourseBrowse Closes drawer active
Close (×) button (mobile) CourseBrowse Closes drawer active
Clear All button (mobile) CourseBrowse Clears filters, closes drawer active
Apply Filters button (mobile) CourseBrowse Closes drawer (filters already applied) active
Clear all filters button (empty state) CourseBrowse Resets all filters active

Links

Course Cards

Element Target Status
Course card (entire card) /courses/{slug} active

Header Navigation

Element Target Status
Logo "Peerloop" / active
"Courses" /courses active
"How It Works" /how-it-works active
"Pricing" /pricing active
"For Creators" /for-creators active
User menu (dropdown) active

Footer

Element Target Status
Platform links /courses, /creators, /teachers, /how-it-works, /pricing active
Get Involved links /become-a-teacher, /for-creators, /stories, /testimonials active
Company links /about, /blog, /careers, /contact active
Support links /faq, /help, /privacy, /terms active
Social (external) Twitter, LinkedIn, GitHub active
Bottom bar /privacy, /terms, /cookies active

Target Pages Status

Target Page Code Status
/courses/{slug} CDET Implemented
/how-it-works HOWI PageSpecView
/pricing PRIC PageSpecView
/for-creators FCRE PageSpecView
/ HOME Implemented

Verification Notes

Verified: 2026-01-07 Consolidated: 2026-01-08

Verified Components

  • src/components/courses/CourseBrowse.tsx
  • src/components/courses/CourseCard.tsx
  • src/pages/courses/index.astro

Screenshots

  • 📷 CBRO-2026-01-07-05-51-53.png - Course browse with filter sidebar

Notes

  • All filtering works client-side (no server round-trips)
  • Duration filter IS implemented (spec was outdated)
  • Price range filter NOT implemented
  • URL does not reflect current filters (not shareable)
  • No analytics events implemented

Test Coverage

Component ✓ Page ○ SSR ✓ API 0/0 ✓ Ready
Script: scripts/page-tests/test-CBRO.sh
Page Test: tests/pages/courses/index.test.tsx
Component Test: tests/pages/courses/CourseBrowse.test.tsx
SSR Loader Test: tests/ssr/courses.test.ts fetchCourseBrowseData()

Discrepancies (Spec vs Implementation)

As of 2026-01-08

Planned but Not Implemented

Feature Original Spec Status Priority
Price range filter Slider or preset ranges (Free, $1-100, $100-500, $500+) Not implemented Low
URL state sync URL should reflect filters for shareability Not implemented Medium
Analytics events 5 events (page_view, search, filter_applied, course_card_click, sort_changed) Not implemented Low

Browse Courses

Discover courses taught by expert creators with 1-on-1 guidance.