feat: Add mini-leaderboard and user rank badge components#63
Conversation
…them into the bounty page and global navbar, and update leaderboard data fetching.
📝 WalkthroughWalkthroughAdds a MiniLeaderboard widget and NavRankBadge, integrates a Leaderboard link into the global navbar and bounty sidebar, and updates leaderboard hooks and API to accept an optional userId and adjust pagination and tag fallback behavior. Changes
Sequence Diagram(s)mermaid Browser->>Mini: mount Browser->>NavBadge: mount (with userId?) Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In `@components/leaderboard/mini-leaderboard.tsx`:
- Line 73: The AvatarFallback currently uses contributor.displayName[0] which
can be undefined for empty strings; update the AvatarFallback rendering to
safely extract the first character from contributor.displayName and provide a
default fallback character when displayName is empty or undefined (refer to
AvatarFallback and contributor.displayName in the mini-leaderboard component),
e.g., check length or use a nullish/default fallback so the UI always shows a
single safe character instead of undefined.
🧹 Nitpick comments (2)
components/global-navbar.tsx (1)
36-36: Replace hardcoded userId before production deployment.The hardcoded
userId="user-1"is a placeholder. Ensure this is replaced with the actual authenticated user ID from your auth context/session before merging to production. The TODO comment acknowledges this, but consider creating a tracked issue if auth integration is not part of this PR.Do you want me to open an issue to track replacing this placeholder with actual auth integration?
hooks/use-leaderboard.ts (1)
54-60: Inconsistent pagination logic withuseLeaderboard.
usePrefetchLeaderboardPagestill uses the olderflatMapapproach forgetNextPageParam, whileuseLeaderboard(lines 19-23) was optimized to use the math-based check. Consider applying the same optimization for consistency.♻️ Suggested refactor
getNextPageParam: (lastPage, allPages) => { - const loadedCount = allPages.flatMap(p => p.entries).length; - if (loadedCount < lastPage.totalCount) { + if (allPages.length * limit < lastPage.totalCount) { return allPages.length + 1; } return undefined; },
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In `@components/leaderboard/mini-leaderboard.tsx`:
- Line 73: The AvatarFallback currently uses a full name string ("John Doe")
which is too long for the avatar; update the fallback to a single character
(e.g. "?" or "U") or derive a 1-2 character initial from
contributor.displayName; modify the AvatarFallback usage (symbol:
AvatarFallback) so it renders either contributor.displayName?.[0] ?? "?" or a
small initials helper (use contributor.displayName to compute initials) instead
of the full "John Doe" string.
🧹 Nitpick comments (2)
components/leaderboard/mini-leaderboard.tsx (2)
82-82: Consider adding a fallback for the displayed name.If
contributor.displayNameis empty or undefined, nothing will be rendered for the contributor's name, which could confuse users. Consider adding a fallback display name.♻️ Proposed fix
<span className="font-medium text-white text-sm truncate group-hover:text-primary transition-colors"> - {contributor.displayName} + {contributor.displayName || "Anonymous"} </span>
88-88: Consider defensive coding fortotalScore.If
totalScoreis everundefinedornull, calling.toLocaleString()will throw a runtime error. Consider adding a fallback.🛡️ Proposed fix
<span className="text-[10px] text-white/70 font-mono"> - {contributor.totalScore.toLocaleString()} pts + {(contributor.totalScore ?? 0).toLocaleString()} pts </span>
This pull request introduces leaderboard feature to the application, including a mini leaderboard component for sidebars, a navigation badge showing the user's rank, and a main navigation link to the leaderboard page. It also includes supporting API and hook improvements for better error handling and efficiency.
Leaderboard UI Components:
MiniLeaderboardcomponent for displaying top contributors in sidebars, with loading and error states. (components/leaderboard/mini-leaderboard.tsx,app/bounty/page.tsx) [1] [2] [3]NavRankBadgecomponent to show the current user's leaderboard rank in the global navbar. (components/leaderboard/nav-rank-badge.tsx,components/global-navbar.tsx) [1] [2] [3]Navigation and Accessibility:
components/global-navbar.tsx)API and Hook Improvements:
nullinstead of throwing errors. (lib/api/leaderboard.ts,hooks/use-leaderboard.ts) [1] [2]hooks/use-leaderboard.ts)Minor Fixes:
components/leaderboard/leaderboard-filters.tsx)closes #59
Summary by CodeRabbit
New Features
Improvements
✏️ Tip: You can customize this high-level summary in your review settings.