Skip to content

feat(leaderboard): add user avatars to table rows with DiceBear fallback#308

Merged
ViktorSvertoka merged 2 commits into
developfrom
feat/user-avatars-leaderboard
Feb 11, 2026
Merged

feat(leaderboard): add user avatars to table rows with DiceBear fallback#308
ViktorSvertoka merged 2 commits into
developfrom
feat/user-avatars-leaderboard

Conversation

@TiZorii
Copy link
Copy Markdown
Collaborator

@TiZorii TiZorii commented Feb 11, 2026

Summary by CodeRabbit

  • Bug Fixes

    • Improved handling of invalid or missing avatar data in leaderboard displays with automatic fallback to generated avatars.
  • Style

    • Simplified and refined avatar styling in leaderboard podium and table views for a cleaner visual presentation.

@netlify
Copy link
Copy Markdown

netlify Bot commented Feb 11, 2026

Deploy Preview for develop-devlovers ready!

Name Link
🔨 Latest commit 69a6c26
🔍 Latest deploy log https://app.netlify.com/projects/develop-devlovers/deploys/698caf6e2d0d560008a5613d
😎 Deploy Preview https://deploy-preview-308--develop-devlovers.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@vercel
Copy link
Copy Markdown
Contributor

vercel Bot commented Feb 11, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
devlovers-net Ready Ready Preview, Comment Feb 11, 2026 4:34pm

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Feb 11, 2026

📝 Walkthrough

Walkthrough

This PR introduces a new UserAvatar component for consistent avatar rendering across leaderboard UI, replacing inline Image components and styling logic. It includes error handling with DiceBear SVG fallback and updates the database query to validate non-whitespace avatar strings.

Changes

Cohort / File(s) Summary
New UserAvatar Component
frontend/components/leaderboard/UserAvatar.tsx
New client-side component that renders avatars with Next.js Image and error handling; falls back to DiceBear-generated SVG on load failure. Supports custom className and sizes props.
Leaderboard UI Updates
frontend/components/leaderboard/LeaderboardPodium.tsx, frontend/components/leaderboard/LeaderboardTable.tsx
Replace inline Image usage with UserAvatar component. Refactor current-user avatar styling from background/shadow to border-based indicator. Simplify non-current-user styling and remove gradient/hover effects on avatar containers.
Database Query
frontend/db/queries/leaderboard.ts
Update avatar selection logic to validate against whitespace-only strings in addition to null values before using provided avatar URL.

Sequence Diagram

sequenceDiagram
    participant Client as Client/UI
    participant UserAvatar as UserAvatar Component
    participant Image as Next.js Image
    participant DiceBear as DiceBear API

    Client->>UserAvatar: Render with src & username
    UserAvatar->>Image: Load avatar image
    Image->>Image: Image load attempt
    alt Image loads successfully
        Image-->>UserAvatar: onLoadSuccess
        UserAvatar-->>Client: Display loaded avatar
    else Image fails to load
        Image-->>UserAvatar: onError
        UserAvatar->>DiceBear: Generate fallback SVG<br/>based on username
        DiceBear-->>UserAvatar: Return SVG avatar
        UserAvatar-->>Client: Display fallback avatar
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested reviewers

  • AM1007
  • ViktorSvertoka

Poem

🐰 A UserAvatar hops into view,
With error bounds and fallback too,
The leaderboard table now stands tall,
One component to handle them all! ✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
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 (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: introducing user avatars to leaderboard table rows with a DiceBear fallback mechanism, which aligns with all modified files.

✏️ 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
  • Commit unit tests in branch feat/user-avatars-leaderboard

Tip

Issue Planner is now in beta. Read the docs and try it out! Share your feedback on Discord.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

Copy link
Copy Markdown
Contributor

@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.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
frontend/db/queries/leaderboard.ts (1)

28-33: ⚠️ Potential issue | 🟡 Minor

DiceBear seed inconsistency with UserAvatar fallback.

The seed here is ${username}-${u.id}, but in UserAvatar.tsx (line 23) the client-side fallback seed is just username. This causes two problems:

  1. If the DB-generated DiceBear URL somehow fails to load in the browser, the UserAvatar onError handler produces a different avatar (different seed).
  2. Two users sharing the same username will get distinct avatars from the DB layer (thanks to u.id) but identical fallback avatars from the component layer.

Align the seeds. The simplest approach is to always include the user ID in both places, or generate the fallback exclusively in one layer.

🧹 Nitpick comments (3)
frontend/components/leaderboard/UserAvatar.tsx (1)

15-37: Stale hasError when src prop changes.

If the parent supplies a new src (e.g., user updates their avatar and data revalidates), hasError remains true from the previous render and the component continues showing the DiceBear fallback. Reset the error state when src changes:

Proposed fix
+ import { useState, useEffect } from 'react';
  ...
  const [hasError, setHasError] = useState(false);
+
+ useEffect(() => {
+   setHasError(false);
+ }, [src]);

In the leaderboard context (1-hour cache), this is unlikely to manifest, but it makes the component safe for reuse elsewhere.

frontend/components/leaderboard/LeaderboardPodium.tsx (1)

88-91: Pass an appropriate sizes prop for podium avatars.

The podium avatar container is h-14 w-14 md:h-20 md:w-20 (56px / 80px), but UserAvatar defaults to sizes="40px". This tells the browser to pick a ~40px-wide source from the srcset, which may appear slightly blurry at the larger rendered size. For non-SVG avatars, consider:

 <UserAvatar
   src={user.avatar}
   username={user.username}
+  sizes="(min-width: 768px) 80px, 56px"
 />
frontend/components/leaderboard/LeaderboardTable.tsx (1)

110-116: Both branches of leftBorderClass and rightBorderClass are identical.

These ternaries evaluate to the same string regardless of isCurrentUser. This is pre-existing, but since the surrounding avatar styling was updated in this PR, it's a good time to simplify:

Suggested simplification
- const leftBorderClass = isCurrentUser
-   ? 'border-l-[1px] sm:border-l-[1px] border-l-transparent'
-   : 'border-l-[1px] sm:border-l-[1px] border-l-transparent';
+ const leftBorderClass = 'border-l-[1px] sm:border-l-[1px] border-l-transparent';

- const rightBorderClass = isCurrentUser
-   ? 'border-r-[1px] sm:border-r-[1px] border-r-transparent'
-   : 'border-r-[1px] sm:border-r-[1px] border-r-transparent';
+ const rightBorderClass = 'border-r-[1px] sm:border-r-[1px] border-r-transparent';

@ViktorSvertoka ViktorSvertoka merged commit 6b6d16b into develop Feb 11, 2026
9 checks passed
@ViktorSvertoka ViktorSvertoka deleted the feat/user-avatars-leaderboard branch February 11, 2026 16:38
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.

2 participants