Skip to content

Conversation

@Dprof-in-tech
Copy link
Contributor

@Dprof-in-tech Dprof-in-tech commented Jan 30, 2026

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:

  • Added a new profile/[userId]/page.tsx that displays contributor reputation, activity history, and analytics tabs, with loading and error states. (app/profile/[userId]/page.tsxR1-R117)
  • Introduced ParticipantCard component 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:

  • Updated leaderboard and leaderboard table components to use text-foreground and text-muted-foreground classes instead of hardcoded white, ensuring consistent text color across the app. [1] [2] [3] [4] [5] [6] [7] [8]
  • Refactored leaderboard badge imports to use centralized reputation components for tier and streak badges, improving maintainability. [1] [2]

General UI and Theme Enhancements:

  • Adjusted global CSS variables for muted foreground color and added spacing between universal selector and body styles for clarity. [1] [2]
  • Simplified input and background styling in the bounty page for a cleaner look. [1] [2]

closes #65
Screenshot 2026-01-30 at 05 01 28

Screenshot 2026-01-30 at 04 47 05

Summary by CodeRabbit

  • New Features

    • Added user profile pages with reputation, bounty history, analytics, loading and error states.
    • Introduced participant card, reputation card, tooltip, score, breakdown, completion history, stats grid, streak & tier badges, and tier progress components.
    • Added a "Claimed by" indicator on bounties.
  • Style

    • Shifted color tokens from white to foreground/muted-foreground for consistent theming.
    • Simplified search input styling and minor CSS formatting tweaks.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link

coderabbitai bot commented Jan 30, 2026

📝 Walkthrough

Walkthrough

Adds 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

Cohort / File(s) Summary
Profile page & integration
app/profile/[userId]/page.tsx, components/bounty/participant-card.tsx, components/bounty/bounty-sidebar.tsx
Adds a client-side ProfilePage that fetches contributor reputation and shows tabs (Bounty History / Analytics); introduces ParticipantCard and conditionally renders a "Claimed by" block in the bounty sidebar when bounty.claimedBy is present.
Reputation UI components
components/reputation/completion-history.tsx, components/reputation/reputation-breakdown.tsx, components/reputation/reputation-card.tsx, components/reputation/reputation-score.tsx, components/reputation/reputation-tooltip.tsx, components/reputation/stats-grid.tsx, components/reputation/streak-badge.tsx, components/reputation/tier-badge.tsx, components/reputation/tier-progress.tsx
Adds nine new exported components (CompletionHistory, ReputationBreakdown, ReputationCard, ReputationScore, ReputationTooltip, StatsGrid, StreakBadge, TierBadge, TierProgress) with their props and UI behaviors supporting profile and hover displays.
Leaderboard theming & imports
app/leaderboard/page.tsx, components/leaderboard/...
Switched UI tokens from white variants to semantic foreground/muted-foreground, updated imports to reputation-scoped Tier/Streak components, and adjusted related classNames; no control-flow changes.
Bounty page UI tweaks
app/bounty/page.tsx
Simplified Search input classes by removing background/border/hover/focus utilities (className shortened) — styling-only change.
Global CSS formatting
app/globals.css
Minor whitespace/formatting change inside @layer base (no semantic CSS change).

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
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Poem

🐰 I hopped in to show the score,
Badges gleam and streaks galore,
A profile blooms with history bright,
Cards and tooltips take their flight,
Points counted, bounties sing tonight. 🌟

🚥 Pre-merge checks | ✅ 3 | ❌ 2
❌ Failed checks (2 warnings)
Check name Status Explanation Resolution
Title check ⚠️ Warning The PR title contains a typo ('sysem' instead of 'system') and is overly broad, not clearly highlighting the primary changes. Correct the typo and consider a more specific title like 'feat: Add user profile page with reputation system' or 'feat: Implement profile page and reputation components'.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Linked Issues check ✅ Passed All core objectives from issue #65 are implemented: reputation components (TierBadge, ReputationScore, TierProgress, ReputationBreakdown, StatsGrid, StreakBadge), ReputationCard, ReputationTooltip, CompletionHistory, profile page integration, and bounty sidebar integration with ParticipantCard.
Out of Scope Changes check ✅ Passed All changes are directly related to issue #65 objectives: reputation components, profile page, bounty sidebar integration, and UI/theming refinements (text-foreground/muted-foreground) are in scope.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a 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 | 🟠 Major

Remove unused TierBadge component.

This file is dead code. All leaderboard files (mini-leaderboard.tsx, leaderboard-table.tsx, user-rank-sidebar.tsx) already import TierBadge from @/components/reputation/tier-badge, not from the local leaderboard version. Delete components/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: The className prop is not applied to non-top-3 ranks.

The className prop 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 progress exceeds 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 currentTierPoints and nextTierThreshold are 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-white is hardcoded while the rest of the file migrates to semantic tokens like text-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-foreground causes 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">

Copy link

@coderabbitai coderabbitai bot left a 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.
Copy link

@coderabbitai coderabbitai bot left a 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.

@0xdevcollins
Copy link
Contributor

resolve the conflict @Dprof-in-tech =

@0xdevcollins 0xdevcollins merged commit eed9757 into boundlessfi:main Feb 11, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Build Reputation Display Components and Profile Integration

2 participants