-
Notifications
You must be signed in to change notification settings - Fork 19
feat: Implement user profile page and a comprehensive reputation sysem #72
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: Implement user profile page and a comprehensive reputation sysem #72
Conversation
…em with dedicated components.
📝 WalkthroughWalkthroughAdds a client ProfilePage and nine reputation UI components, integrates ParticipantCard into the bounty sidebar, and applies theming/text-color tweaks plus minor CSS and search-input class adjustments. Changes
Sequence Diagram(s)sequenceDiagram
participant Profile as ProfilePage (Client)
participant Hook as useContributorReputation (Client Hook)
participant API as /api/reputation (Server)
participant DB as Database
participant UI as ReputationCard / CompletionHistory (Client UI)
Profile->>Hook: call useContributorReputation(userId)
Hook->>API: fetch contributor reputation
API->>DB: query reputation tables
DB-->>API: reputation payload
API-->>Hook: JSON response
Hook-->>Profile: reputation data (react-query)
Profile->>UI: render ReputationCard and CompletionHistory with data
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (2 warnings)
✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
🧪 Generate unit tests (beta)
Comment |
…and remove unused imports.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 3
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
components/leaderboard/tier-badge.tsx (1)
10-18:⚠️ Potential issue | 🟠 MajorRemove unused TierBadge component.
This file is dead code. All leaderboard files (
mini-leaderboard.tsx,leaderboard-table.tsx,user-rank-sidebar.tsx) already importTierBadgefrom@/components/reputation/tier-badge, not from the local leaderboard version. Deletecomponents/leaderboard/tier-badge.tsx.
🤖 Fix all issues with AI agents
In `@app/profile/`[userId]/page.tsx:
- Line 3: The import list in page.tsx includes an unused symbol useLinkWallet
which triggers a lint warning; remove useLinkWallet from the import statement
(leave useContributorReputation) in the import that currently reads import {
useContributorReputation, useLinkWallet } from "@/hooks/use-reputation" so the
file only imports symbols actually used.
In `@components/leaderboard/user-rank-sidebar.tsx`:
- Around line 123-125: The value contributor.stats.completionRate is already a
0–100 percentage, but user-rank-sidebar multiplies it by 100, producing
incorrect values; update the render in user-rank-sidebar (the JSX rendering the
completion rate, e.g., the <div> that currently uses
Math.round(contributor.stats.completionRate * 100)) to stop multiplying by 100
and instead display the already-percentage value (for example
Math.round(contributor.stats.completionRate) + "%"), matching how StatsGrid and
ReputationTooltip consume the same field.
In `@components/reputation/completion-history.tsx`:
- Line 4: The import statement brings in CheckCircle2, Clock, Coins and Star but
only Star is used; remove the unused imports (CheckCircle2, Clock, Coins) from
the import declaration so it only imports Star from "lucide-react" and ensure
there are no other references to the removed symbols in the component (e.g.,
CompletionHistory) before committing.
🧹 Nitpick comments (5)
components/leaderboard/rank-badge.tsx (1)
17-21: TheclassNameprop is not applied to non-top-3 ranks.The
classNameprop is only used in the top-3 case (line 11) but ignored here. This inconsistency prevents customizing lower-ranked badges.♻️ Proposed fix to apply className consistently
return ( - <div className="flex items-center justify-center w-6 h-6 text-foreground font-semibold text-sm"> + <div className={cn("flex items-center justify-center w-6 h-6 text-foreground font-semibold text-sm", className)}> {rank} </div> );components/reputation/tier-progress.tsx (1)
10-21: Consider clamping the progress value for defensive rendering.If
progressexceeds the expected 0-100 range,Math.round(progress)could display values like "150%" which would be confusing. Consider clamping:♻️ Suggested improvement
export function TierProgress({ progress, className, showLabel = true }: TierProgressProps) { + const clampedProgress = Math.min(100, Math.max(0, progress)); return ( <div className={cn("w-full space-y-1.5", className)}> {showLabel && ( <div className="flex justify-between text-xs text-muted-foreground"> <span>Progress to next tier</span> - <span>{Math.round(progress)}%</span> + <span>{Math.round(clampedProgress)}%</span> </div> )} - <Progress value={progress} className="h-2" /> + <Progress value={clampedProgress} className="h-2" /> </div> ); }components/leaderboard/user-rank-sidebar.tsx (1)
136-154: TODO comment with mock values should be tracked.The mock values for
currentTierPointsandnextTierThresholdare noted as temporary. Consider creating an issue to track this technical debt once the API provides these fields.Would you like me to open an issue to track the removal of these mock values?
components/leaderboard/mini-leaderboard.tsx (2)
45-47: Inconsistent hover color token.
hover:text-whiteis hardcoded while the rest of the file migrates to semantic tokens liketext-foreground. For consistency with the theming updates:♻️ Suggested fix
- <Link href="/leaderboard" className="text-xs text-muted-foreground hover:text-white transition-colors flex items-center"> + <Link href="/leaderboard" className="text-xs text-muted-foreground hover:text-foreground transition-colors flex items-center">
81-83: Hover state dims the text instead of highlighting it.
group-hover:text-muted-foregroundcauses the contributor name to become less prominent on hover, which is counterintuitive for an interactive link. Typically hover states increase visual prominence.♻️ Suggested fix
- <span className="font-medium text-foreground text-sm truncate group-hover:text-muted-foreground transition-colors"> + <span className="font-medium text-foreground text-sm truncate group-hover:text-primary transition-colors">
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
🤖 Fix all issues with AI agents
In `@app/profile/`[userId]/page.tsx:
- Around line 51-64: The current render block treats any truthy error or missing
reputation as "Profile Not Found", which mislabels network/server failures;
change the logic in the page component where you check error and reputation (the
if (error || !reputation) block) to distinguish a 404 from other failures —
detect a 404 via error?.status === 404 or your fetch result/response status and
only render the "Profile Not Found" UI for that case, otherwise render a neutral
generic error UI (e.g., "Something went wrong" with a retry/return-home action)
so network/server errors are not presented as a missing profile.
- Around line 19-37: The mockHistory useMemo builds
reputation.stats.totalCompleted items unbounded which can stall the UI; change
the logic in the useMemo that creates mockHistory to cap the count (e.g., let
count = Math.min(reputation.stats.totalCompleted, MAX_MOCK_HISTORY)) and iterate
up to that capped count instead of totalCompleted, or replace with a
paginated/fetch-backed implementation for real history; update the constant name
(e.g., MAX_MOCK_HISTORY) and ensure useMemo depends on reputation and the cap so
renders remain bounded.
…ic error states, limit mock history generation, and correct leaderboard completion rate display.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In `@app/profile/`[userId]/page.tsx:
- Around line 21-24: The current useMemo for mockHistory can throw a RangeError
when reputation.stats.totalCompleted is undefined because Math.min(undefined,
MAX_MOCK_HISTORY) yields NaN; update the calculation inside the mockHistory
useMemo (the block referencing mockHistory, reputation,
reputation.stats.totalCompleted, and MAX_MOCK_HISTORY) to defensively coalesce
totalCompleted to 0 (e.g., use reputation.stats.totalCompleted ?? 0) before
passing it to Math.min so Array(...) always receives a valid non-NaN length.
|
resolve the conflict @Dprof-in-tech = |
This pull request introduces several improvements across the bounty, leaderboard, and profile pages, with a focus on enhanced contributor reputation features and a more consistent UI theme. The most significant updates include the addition of a new profile page, improved display of contributor reputation, and UI refinements for better readability and user experience.
Contributor Reputation Features:
profile/[userId]/page.tsxthat displays contributor reputation, activity history, and analytics tabs, with loading and error states. (app/profile/[userId]/page.tsxR1-R117)ParticipantCardcomponent to show contributor details and reputation, now used in the bounty sidebar to highlight the user who claimed a bounty. [1] [2]Leaderboard and Table UI Consistency:
text-foregroundandtext-muted-foregroundclasses instead of hardcoded white, ensuring consistent text color across the app. [1] [2] [3] [4] [5] [6] [7] [8]General UI and Theme Enhancements:
closes #65

Summary by CodeRabbit
New Features
Style
✏️ Tip: You can customize this high-level summary in your review settings.