-
Notifications
You must be signed in to change notification settings - Fork 65
Build Rewards and Leaderboard Page — XP Display, Badge Grid, Reward History, and Top Learners #218
Copy link
Copy link
Open
Labels
Description
Labels
Frontend
Description
ByteChain Academy has a rewards system on the backend (Issue 3) and a /rewards route linked from the account dropdown, but the page does not exist. Users have no way to see their XP total, earned badges, reward history, or how they rank against other learners. A well-designed rewards page drives engagement and motivates continued learning. This issue builds the complete rewards and leaderboard frontend, wired to the backend rewards API.
Background & Context
frontend/app/rewards/has nopage.tsx— the route 404s- The account dropdown already links to
/rewards - Backend endpoints (Issue 3):
GET /api/v1/rewards/my,GET /api/v1/rewards/leaderboard GET /api/v1/rewards/myreturns{ xp, badges: [], rewardHistory: [] }GET /api/v1/rewards/leaderboardreturns top 10 users by XP- The dashboard currently shows hardcoded
experiencePoints: 2450— this page should be the source of truth for XP display
Requirements
- Create
frontend/app/rewards/page.tsxwith three main sections:- XP & Streak hero section: large XP number with an animated progress bar showing progress to next milestone, current streak with flame icon, longest streak
- Badges grid: all earned badges displayed as cards with badge name, description, and earned date. Locked/unearned badges shown as greyed-out silhouettes with unlock criteria
- Reward history feed: chronological list of XP-earning events — "Completed lesson: Intro to Bitcoin +10 XP", "Passed quiz: DeFi Basics +25 XP", "7-day streak! +50 XP"
- Create
frontend/app/rewards/leaderboard/page.tsx(or a tab on the rewards page) showing:- Top 10 learners ranked by XP with username, XP total, and badges count
- The authenticated user's rank highlighted even if outside top 10
- Rank change indicators (optional stretch goal)
- Use TanStack Query for all data fetching
Suggested Execution
Branch: git checkout -b feat/rewards-leaderboard-frontend
Files to create:
frontend/app/rewards/page.tsxfrontend/components/rewards/xp-hero.tsxfrontend/components/rewards/badge-card.tsxfrontend/components/rewards/reward-history-item.tsxfrontend/components/rewards/leaderboard-table.tsxfrontend/hooks/use-rewards.ts
Implement:
useRewardshook —useQueryforGET /api/v1/rewards/myandGET /api/v1/rewards/leaderboardXPHero— large animated XP counter, progress bar to next 100-XP milestone, streak flame with numberBadgeCard— earned state (coloured, with name and date) vs locked state (grayscale silhouette with unlock hint)RewardHistoryItem— icon based on reason type, human-readable label, XP amount in green, relative timestampLeaderboardTable— rank number, username, XP bar, badge count, highlight current user's row- Tabs or sections on the main rewards page: "My Rewards" and "Leaderboard"
Test & Validate:
/rewardsloads with real XP, badges, and history from backend- Badges section correctly shows earned vs locked badges
- Reward history shows events in reverse chronological order
- Leaderboard tab shows top 10 users
- Current user's row is highlighted in the leaderboard
- XP progress bar fills correctly based on current XP
Acceptance Criteria
-
/rewardspage fetches and displays real data fromGET /api/v1/rewards/my - XP total and streak shown with visual indicators
- Earned badges displayed with details; locked badges shown as greyed silhouettes
- Reward history feed shows all XP events with correct labels and amounts
- Leaderboard shows top 10 users ranked by XP
- Authenticated user's position is highlighted in the leaderboard
- TanStack Query used for all data fetching
- Design matches existing dark theme
Example Commit Message
feat: build rewards page with XP hero, badge grid, reward history, and leaderboard
Guidelines
- Assignment required before starting
- PR description must include
Closes #[issue_id] - Join our Telegram: https://t.me/ByteChainAcademy
- Complexity: High (200 pts)
Reactions are currently unavailable