Build course category landing pages with sub categories - #307
Open
Idahjnr007 wants to merge 6 commits into
Open
Conversation
Added Autoplay Next Lecture Toggle in Video Player. Implemented an autoplay next lecture toggle in the video player so students can choose whether the next lecture starts automatically after the current one ends. 📋 Requirements Added an "Autoplay" toggle switch in VideoControls.tsx Default: on Persist preference in localStorage per user When lecture ends and autoplay is on: 5-second countdown overlay showing "Next: [lecture title]", then auto-navigate Cancel button during countdown cancels autoplay When autoplay is off: show "Next lecture" button on video end
https://github.com/Idahjnr007/Hamplard-frontend into Build-Course-Completion-Modal-with-Confetti-Animation
Added Video Playback Quality Selector Built a video playback quality selector so students on slower connections can reduce video quality to prevent buffering. 📋 Requirements Add quality selector button to VideoControls.tsx: Auto, 1080p, 720p, 480p, 360p When a quality is selected, switch the video src to the matching resolution URL Maintain current playback position when switching quality Show current quality label in button when not Auto "Auto" uses the browser's adaptive bitrate streaming 🔧 Technical Scope HTML5 video src switching src/components/learn/VideoControls.tsx 📂 Affected Path src/components/learn/VideoControls.tsx
Build Course Category Landing Page
CATEGORY_META — a lookup table mapping slugs to display name, emoji icon, tailored description, and a gradient pair. Covers all 10 existing Hamplard categories plus common extras.
getCategoryMeta(slug) — exported helper that falls back to a generated name for any unknown slug so the page degrades gracefully instead of crashing.
CategoryHero — renders the hero section: emoji icon bubble, h1, description, and a course-count pill badge. Gradient background comes from the category meta.
CategorySortSelect.tsx
Thin 'use client' component wrapping a <select> that calls router.push on change, keeping the page itself a pure Server Component.
src/app/categories/[slug]/page.tsx
generateStaticParams — fetches live categories from the API and falls back to CATEGORY_META keys if the API is unavailable during build.
generateMetadata — sets <title> and <description> per category.
Server-side data fetch with coursesApi.list({ category, limit: 100 }).
notFound() for slugs that are neither in CATEGORY_META nor have any API courses.
Subcategory pills — derived automatically from high-frequency words in course titles, rendered as <Link> pills that append ?sub=... to the URL (no JS needed).
Sort — ?sort=popular|rated|newest applied server-side to the fetched array.
Course grid — grid-cols-2 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 matching the exact breakpoint spec.
Instructor spotlight — top 3 instructors ranked by course count then total enrollments, showing avatar/initials, bio, stats, and avg rating.
Related categories row — horizontally scrollable on mobile, 6-column grid on desktop, links to sibling category pages.
Closes Hamplard-Hub#168
Build Course Category Landing Pages with Sub-Categories
CategoryHero.tsx — two changes:
Removed the gradient field from CategoryMeta and switched the section background from pastel gradients to bg-[#26215C] (the brand purple matching the Header). Text flipped to white/white-tinted accordingly.
Added catering to CATEGORY_META so it matches what the Header already had as a static entry.
categories/[slug]/page.tsx — full rebuild from Server Component → 'use client':
The previous version was a Server Component, which meant FilterSidebar (a client component with close/open drawer state) couldn't be composed into it.
URL params are now read via useSearchParams() and written via router.replace() — same pattern as
page.tsx
.
FilterSidebar is mounted with its category prop locked to the current category, so the category filter column in the sidebar reflects where you are but you can still filter by level, price, rating, and duration.
Subcategory pills are derived client-side from fetched course titles after load, so they're always accurate to real data.
Full filter chain: subcategory keyword → level → price → rating → duration → sort, all composed client-side with useMemo.
Loading state shows skeleton pill placeholders and CourseCardSkeleton grid.
Grid breakpoints: grid-cols-2 sm:grid-cols-2 md:grid-cols-3 xl:grid-cols-4.
Header.tsx — mega-menu populated from API:
Removed the hardcoded CATEGORIES array.
Added a useEffect that calls coursesApi.getCategories() on mount and maps the result to { name, slug, description, icon } using getCategoryMeta for the description/icon.
Falls back to STATIC_CATEGORIES (derived from CATEGORY_META) if the API call fails — so the menu is never empty.
All category links now point to /categories/[slug] instead of /search?category=....
Desktop mega-menu items show the emoji icon next to the name, with a "Browse all courses →" footer link.
Mobile drawer items show the emoji icon inline.
Closes Hamplard-Hub#190
|
@Idahjnr007 Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits. You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #190
Build course category landing pages with sub categories
CategoryHero.tsx — two changes:
Removed the gradient field from CategoryMeta and switched the section background from pastel gradients to bg-[#26215C] (the brand purple matching the Header). Text flipped to white/white-tinted accordingly.
Added catering to CATEGORY_META so it matches what the Header already had as a static entry.
categories/[slug]/page.tsx — full rebuild from Server Component → 'use client':
The previous version was a Server Component, which meant FilterSidebar (a client component with close/open drawer state) couldn't be composed into it.
URL params are now read via useSearchParams() and written via router.replace() — same pattern as
page.tsx
.
FilterSidebar is mounted with its category prop locked to the current category, so the category filter column in the sidebar reflects where you are but you can still filter by level, price, rating, and duration.
Subcategory pills are derived client-side from fetched course titles after load, so they're always accurate to real data.
Full filter chain: subcategory keyword → level → price → rating → duration → sort, all composed client-side with useMemo.
Loading state shows skeleton pill placeholders and CourseCardSkeleton grid.
Grid breakpoints: grid-cols-2 sm:grid-cols-2 md:grid-cols-3 xl:grid-cols-4.
Header.tsx — mega-menu populated from API:
Removed the hardcoded CATEGORIES array.
Added a useEffect that calls coursesApi.getCategories() on mount and maps the result to { name, slug, description, icon } using getCategoryMeta for the description/icon.
Falls back to STATIC_CATEGORIES (derived from CATEGORY_META) if the API call fails — so the menu is never empty.
All category links now point to /categories/[slug] instead of /search?category=....
Desktop mega-menu items show the emoji icon next to the name, with a "Browse all courses →" footer link.
Mobile drawer items show the emoji icon inline.
Closes #190