Skip to content

Add empty states for dashboard and leaderboard#42

Open
Riddhi0124 wants to merge 2 commits into
Rishabhworkspace:mainfrom
Riddhi0124:fix/dashboard-leaderboard-empty-state
Open

Add empty states for dashboard and leaderboard#42
Riddhi0124 wants to merge 2 commits into
Rishabhworkspace:mainfrom
Riddhi0124:fix/dashboard-leaderboard-empty-state

Conversation

@Riddhi0124

@Riddhi0124 Riddhi0124 commented Jun 14, 2026

Copy link
Copy Markdown

Summary

  • Added empty state UI for Dashboard recent activity when no activity exists
  • Added empty state UI for Leaderboard when no leaderboard data exists
  • Added CTA buttons to guide users toward solving problems
  • Kept existing UI unchanged when real data is available

Testing

  • Ran the app locally with npm run dev
  • Verified leaderboard still displays real data when available
  • Verified dashboard loads successfully for a new user

Summary by CodeRabbit

  • Bug Fixes

    • Fixed surrounding layout/JSX structure in the Dashboard component.
  • Enhancements

    • Dashboard now shows a “No activity yet” card with a “Start Solving Problems” button when there’s no recent activity.
    • Leaderboard now displays an empty-state glass card with a “Start Solving Problems” button when no leaderboard data is available (including a right-arrow icon).
  • Chores

    • Updated the Vite build configuration (simplified config factory and removed the development-only inspection plugin conditional).

@vercel

vercel Bot commented Jun 14, 2026

Copy link
Copy Markdown

@Riddhi0124 is attempting to deploy a commit to the rishabhjtripathi2903-3434's projects Team on Vercel.

A member of the Team first needs to authorize it.

@coderabbitai

coderabbitai Bot commented Jun 14, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

Dashboard adds a missing closing </div> to fix JSX structure and replaces the bare empty-state paragraph in "Recent Activity" with a styled card and a "Start Solving Problems" CTA. Leaderboard gains an identical empty-state card with an ArrowRight icon. The Vite config drops the mode-dependent dev plugin and reformats the build chunking block.

Changes

Empty-state UI for Dashboard and Leaderboard

Layer / File(s) Summary
Dashboard JSX fix and Recent Activity empty state
app/src/sections/Dashboard.tsx
Inserts a missing closing </div> before the max-w-7xl container and replaces the simple empty-state paragraph in "Recent Activity" with a styled card containing a "No activity yet" message and a "Start Solving Problems" CTA button navigating to problems.
Leaderboard empty-state card and navigation
app/src/sections/Leaderboard.tsx
Adds ArrowRight to the lucide-react import, wraps the leaderboard list render in a conditional that shows a glass-styled empty-state card with a button setting window.location.hash to #problems, and adjusts the surrounding JSX closures.

Vite Config Cleanup

Layer / File(s) Summary
Remove mode-dependent plugin and reformat build block
app/vite.config.ts
Changes the config factory from ({ mode }) to a parameterless function, removes the conditional kimi-plugin-inspect-react inclusion, and reformats the build.rollupOptions.output.manualChunks block without altering the vendor-chunk logic.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related issues

Poem

🐇 When the leaderboard sleeps and no scores appear,
A card now wakes up to say "Start here, dear!"
A button glows bright with an arrow in tow,
The dashboard is tidy, the JSX aligned so.
With mode params removed and the config made lean,
The forge hops to life — the cleanest it's been! ✨

🚥 Pre-merge checks | ✅ 4 | ❌ 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 (4 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—adding empty states for dashboard and leaderboard sections—and clearly matches the primary objectives of the PR.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 Biome (2.5.0)
app/src/sections/Leaderboard.tsx

File contains syntax errors that prevent linting: Line 233: expected ... but instead found leaderboardData; Line 234: Expected corresponding JSX closing tag for 'motion.button'.; Line 277: expected } but instead found ); Line 232: Expected corresponding JSX closing tag for 'motion.div'.; Line 277: Unexpected token. Did you mean {'}'} or &rbrace;?; Line 279: expected ) but instead found }


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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@app/src/sections/Dashboard.tsx`:
- Around line 270-271: The container div with className="relative z-10 max-w-7xl
mx-auto px-4 sm:px-6 lg:px-8" is being closed prematurely on line 271, which
causes all dashboard content to fall outside the intended wrapper and breaks the
responsive layout. Remove the closing </div> tag from line 271 so that the
container wraps all dashboard content instead. Then verify that a closing </div>
tag exists at the appropriate location near the end of the Dashboard component,
just before the closing </section> tag, to properly close the container div
after all dashboard content.

In `@app/src/sections/Leaderboard.tsx`:
- Around line 199-216: The Leaderboard component uses direct hash manipulation
in the button's onClick handler instead of following the consistent callback
pattern used by Dashboard. Refactor the Leaderboard component to accept an
onNavigate prop in its function signature, then update the button's onClick
handler to call onNavigate('problems') instead of setting window.location.hash
directly. Finally, update the parent component where Leaderboard is rendered to
pass the onNavigate callback prop, matching the pattern already established for
the Dashboard component.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 317a3d3f-48d6-47bc-8b0c-7d2c4acb561b

📥 Commits

Reviewing files that changed from the base of the PR and between 209465d and 8f96aad.

⛔ Files ignored due to path filters (1)
  • app/package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (3)
  • app/src/sections/Dashboard.tsx
  • app/src/sections/Leaderboard.tsx
  • app/vite.config.ts

Comment on lines 270 to +271
<div className="relative z-10 max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
</div>

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

Critical JSX structure error: container closed before content.

The container div opened on line 270 is immediately closed on line 271, leaving all dashboard content (lines 272-936) outside the intended max-w-7xl wrapper. This breaks the responsive layout and centering.

🔧 Proposed fix

Remove the closing </div> from line 271. The container should wrap all dashboard content and be closed at the end, just before the closing </section> tag:

       <div className="relative z-10 max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
-      </div>
         {/* Header + Motivational Banner */}

Verify that the closing </div> exists at the appropriate location before </section> (around line 937).

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@app/src/sections/Dashboard.tsx` around lines 270 - 271, The container div
with className="relative z-10 max-w-7xl mx-auto px-4 sm:px-6 lg:px-8" is being
closed prematurely on line 271, which causes all dashboard content to fall
outside the intended wrapper and breaks the responsive layout. Remove the
closing </div> tag from line 271 so that the container wraps all dashboard
content instead. Then verify that a closing </div> tag exists at the appropriate
location near the end of the Dashboard component, just before the closing
</section> tag, to properly close the container div after all dashboard content.

Comment on lines +199 to +216
{leaderboardData.length === 0 ? (
<div className="glass rounded-2xl p-8 text-center border border-white/10">
<Trophy className="w-12 h-12 text-[#ffd700] mx-auto mb-4" />
<h3 className="text-white text-xl font-semibold">
No leaderboard data yet
</h3>
<p className="text-white/50 text-sm mt-2">
Rankings will appear here once learners start solving problems.
</p>

<button
onClick={() => window.location.hash = '#problems'}
className="mt-6 inline-flex items-center gap-2 rounded-xl bg-gradient-to-r from-[#a088ff] to-[#63e3ff] px-4 py-2 text-sm font-semibold text-[#141414]"
>
Start Solving Problems
<ArrowRight className="w-4 h-4" />
</button>
</div>

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion | 🟠 Major | 🏗️ Heavy lift

Navigation inconsistency: direct hash manipulation vs callback pattern.

The empty-state button navigates by setting window.location.hash = '#problems' directly (line 210), while Dashboard's equivalent button uses the onNavigate('problems') callback pattern. This creates inconsistent navigation approaches across the codebase.

While both methods work (verified via App.tsx hash handling), the direct hash manipulation is more brittle and harder to maintain. If navigation logic evolves, changes would be needed in multiple locations rather than centrally.

Consider refactoring Leaderboard to accept an onNavigate prop matching the Dashboard pattern for consistency.

♻️ Suggested refactor

Update the component signature to accept navigation prop:

-export function Leaderboard() {
+export function Leaderboard({ onNavigate }: { onNavigate: (view: 'home' | 'dashboard' | 'topic' | 'problems' | 'notes' | 'leaderboard' | 'daily-challenges') => void }) {

Then update the button onClick:

     <button
-      onClick={() => window.location.hash = '`#problems`'}
+      onClick={() => onNavigate('problems')}
       className="mt-6 inline-flex items-center gap-2 rounded-xl bg-gradient-to-r from-[`#a088ff`] to-[`#63e3ff`] px-4 py-2 text-sm font-semibold text-[`#141414`]"

This requires passing the prop from the parent component (App.tsx).

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@app/src/sections/Leaderboard.tsx` around lines 199 - 216, The Leaderboard
component uses direct hash manipulation in the button's onClick handler instead
of following the consistent callback pattern used by Dashboard. Refactor the
Leaderboard component to accept an onNavigate prop in its function signature,
then update the button's onClick handler to call onNavigate('problems') instead
of setting window.location.hash directly. Finally, update the parent component
where Leaderboard is rendered to pass the onNavigate callback prop, matching the
pattern already established for the Dashboard component.

@Rishabhworkspace

Copy link
Copy Markdown
Owner

@Riddhi0124 add the issue no

@vercel

vercel Bot commented Jun 18, 2026

Copy link
Copy Markdown

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

Project Deployment Actions Updated (UTC)
algo-forge-2-0 Error Error Jun 18, 2026 7:56pm

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

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)
app/src/sections/Leaderboard.tsx (1)

231-279: ⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

Fix malformed JSX in the non-empty leaderboard branch (build blocker).

Line 231 through Line 279 duplicates the map(...) expression and mismatches element nesting (motion.div/motion.button), which matches the parser failures and will break compilation.

💡 Minimal fix
-) : (
-  leaderboardData.slice(3).map((user, index) => (
-            <motion.div
-          {leaderboardData.slice(3).map((user, index) => (
-            <motion.button
+) : (
+  leaderboardData.slice(3).map((user, index) => (
+    <motion.button
               key={user.id}
               onClick={() => onProfileClick?.(user.id)}
               initial={{ opacity: 0, x: -20 }}
               animate={{ opacity: 1, x: 0 }}
               transition={{ duration: 0.4, delay: 0.4 + index * 0.05 }}
               className="glass rounded-xl p-4 flex items-center gap-4 hover:bg-white/5 transition-colors w-full text-left"
             >
@@
-            </motion.div>
-          )))}
-            </motion.button>
-          ))}
+            </motion.button>
+          ))
+)}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@app/src/sections/Leaderboard.tsx` around lines 231 - 279, The
leaderboardData.slice(3).map() call is duplicated and the JSX elements are
mismatched in the non-empty leaderboard branch. Remove the duplicate opening of
the map function and the extra motion.div element, then ensure the motion.button
wrapper (which is correct since it has the onClick handler and should be
semantically interactive) has matching opening and closing tags with all content
properly nested inside it. The structure should have a single map call with
motion.button as the top-level wrapper element containing the rank, avatar,
name, and stats sections, followed by proper closure of the map expression.

Source: Linters/SAST tools

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@app/src/sections/Leaderboard.tsx`:
- Around line 231-279: The leaderboardData.slice(3).map() call is duplicated and
the JSX elements are mismatched in the non-empty leaderboard branch. Remove the
duplicate opening of the map function and the extra motion.div element, then
ensure the motion.button wrapper (which is correct since it has the onClick
handler and should be semantically interactive) has matching opening and closing
tags with all content properly nested inside it. The structure should have a
single map call with motion.button as the top-level wrapper element containing
the rank, avatar, name, and stats sections, followed by proper closure of the
map expression.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: a906d86c-463e-45de-942e-a252d1689b6b

📥 Commits

Reviewing files that changed from the base of the PR and between 8f96aad and fb92134.

📒 Files selected for processing (1)
  • app/src/sections/Leaderboard.tsx

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