Skip to content

feat: add public profile page with clickable leaderboard#38

Open
Aharshi3614 wants to merge 2 commits into
Rishabhworkspace:mainfrom
Aharshi3614:feat/public-profile-page
Open

feat: add public profile page with clickable leaderboard#38
Aharshi3614 wants to merge 2 commits into
Rishabhworkspace:mainfrom
Aharshi3614:feat/public-profile-page

Conversation

@Aharshi3614

@Aharshi3614 Aharshi3614 commented Jun 11, 2026

Copy link
Copy Markdown

Description

Adds public profile pages that users can view by clicking on any user in the leaderboard.

Changes

  • Backend: New /api/users/:userId/profile GET and PUT endpoints
  • Backend: Added bio field to User model in Prisma
  • Frontend: Created ProfileView.tsx component
  • Frontend: Made leaderboard users clickable
  • Frontend: Added profile routing to App.tsx

Testing

  • Click on any user in leaderboard → Profile page opens
  • Own profile shows Edit button
  • Can edit bio and avatar URL
  • Changes persist to database

Closes #22

Summary by CodeRabbit

  • New Features

    • View detailed user profiles with stats, membership year, and avatar display.
    • Click leaderboard entries to open other users' profiles.
    • Edit and save your own profile (bio and avatar) when signed in; changes persist.
    • Profile navigation integrated into app views with hash-based deep links.
  • Backend

    • New profile endpoints and persistent bio/avatar support.

@vercel

vercel Bot commented Jun 11, 2026

Copy link
Copy Markdown

@Aharshi3614 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 11, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: f536b9e4-d16a-44bf-845e-15a02bcc9a8d

📥 Commits

Reviewing files that changed from the base of the PR and between f1021bb and 5c29130.

📒 Files selected for processing (1)
  • backend/src/controllers/userController.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • backend/src/controllers/userController.ts

📝 Walkthrough

Walkthrough

Public user profile pages added: backend schema gains bio, new GET/PUT profile endpoints; frontend adds a profile view with hash routing in App.tsx, makes Leaderboard entries clickable, and introduces ProfileView for viewing and owner editing of profiles.

Changes

Public User Profile Feature

Layer / File(s) Summary
Data Model and Profile API Endpoints
backend/prisma/schema.prisma, backend/src/controllers/userController.ts
User model gains an optional bio field. New handlers: getUserProfile (GET /api/users/:userId/profile) and updateUserProfile (PUT /api/users/:userId/profile) with ownership checks and normalized profile response.
App Navigation and Hash Routing
app/src/App.tsx
Adds 'profile' view and selectedProfileUserId state, parses/restores #profile/<userId> hashes, provides handleProfileClick(userId) to set state and hash, and renders ProfileView when active.
Leaderboard Interactive Wiring
app/src/sections/Leaderboard.tsx
Component now accepts onProfileClick?: (userId: string) => void. Podium entries and list rows rendered as interactive motion.button elements that call onProfileClick(userId) on click.
ProfileView Component
app/src/sections/ProfileView.tsx
New component fetches profile data, shows loading/not-found states, displays avatar/name/level/xp/streak/solved/badges/memberSince and an editable bio/avatarUrl form for the profile owner that saves via PUT with bearer token.
Routing Wiring
backend/src/routes/userRoutes.ts
Adds protected routes for profile endpoints (GET and PUT) and updates controller imports.
Repository Tree (informational)
tree_output.txt
Adds repository tree output file enumerating project layout.

Sequence Diagram

sequenceDiagram
  participant User
  participant Leaderboard
  participant App
  participant BrowserHash
  participant ProfileAPI
  participant ProfileView
  User->>Leaderboard: clicks a username
  Leaderboard->>App: onProfileClick(userId)
  App->>BrowserHash: set hash "profile/<userId>"
  BrowserHash->>App: hashchange -> parse userId
  App->>ProfileView: render with userId
  ProfileView->>ProfileAPI: GET /api/users/:userId/profile
  ProfileAPI-->>ProfileView: profile data
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐰 I hopped from rows to names so bright,
A hash, a click — a profile in sight.
Edit your bio, set avatar true,
Share your progress, show what you do.
Hooray — persistent badges and views!

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Out of Scope Changes check ⚠️ Warning Tree_output.txt appears to be a repository structure artifact unrelated to the feature requirements in issue #22. Remove tree_output.txt as it is not part of the feature implementation and serves no functional purpose for the PR.
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.
Title check ✅ Passed The title clearly and concisely summarizes the main changes: adding public profile pages accessible via the leaderboard.
Linked Issues check ✅ Passed All key requirements from issue #22 are addressed: profile view, database schema update, API endpoints, leaderboard integration, and edit functionality.

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

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

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

Caution

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

⚠️ Outside diff range comments (1)
tree_output.txt (1)

1-255: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Remove auto-generated tree listing from version control.

This file appears to be an auto-generated directory listing unrelated to the profile page feature. Directory tree outputs typically become stale as the repository evolves and should not be committed to version control.

🧹 Recommended fix
  1. Remove the file from the repository:
git rm tree_output.txt
  1. Add it to .gitignore to prevent future accidental commits:
+# Tree output files
+tree_output.txt
🤖 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 `@tree_output.txt` around lines 1 - 255, The repo contains an auto-generated
file tree_output.txt that should not be versioned; remove it from Git and
prevent re-adding by updating ignore rules: run git rm to remove tree_output.txt
and then add an entry for tree_output.txt (or a pattern) to .gitignore so future
commits don't include the auto-generated listing; update any commit that
introduced tree_output.txt if needed to keep history clean.
🤖 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/ProfileView.tsx`:
- Around line 52-55: The catch block currently treats every fetch failure as
"not found" by calling setNotFound(true); instead add a separate error state
(e.g., setError / error state variable) and only setNotFound(true) when the HTTP
response indicates a 404; for other failures set the error state and log the
error. Locate the profile-loading routine (the async function in ProfileView,
e.g., fetchProfile / the useEffect that calls it) and change the logic so you
inspect response.status (or the thrown HttpError) to decide: if status === 404
call setNotFound(true), else call setError(error) and do not mark not-found;
apply the same change to the other fetch block referenced around lines 102-107
to keep consistent behavior.

In `@backend/src/controllers/userController.ts`:
- Around line 172-192: The PUT profile response is missing memberSince which the
frontend expects; update the res.status(200).json response in userController.ts
(the block that returns data after the update using the updated variable) to
include memberSince (derived from updated.memberSince or updated.createdAt as
appropriate) alongside id, name, avatar, bio, xp, streak, and solved so the
saved profile payload matches the GET profile schema and fixes the profile
header replacement.

---

Outside diff comments:
In `@tree_output.txt`:
- Around line 1-255: The repo contains an auto-generated file tree_output.txt
that should not be versioned; remove it from Git and prevent re-adding by
updating ignore rules: run git rm to remove tree_output.txt and then add an
entry for tree_output.txt (or a pattern) to .gitignore so future commits don't
include the auto-generated listing; update any commit that introduced
tree_output.txt if needed to keep history clean.
🪄 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: e4549feb-67b8-4adb-86bc-d1e982d55a6f

📥 Commits

Reviewing files that changed from the base of the PR and between f9d8990 and f1021bb.

📒 Files selected for processing (7)
  • app/src/App.tsx
  • app/src/sections/Leaderboard.tsx
  • app/src/sections/ProfileView.tsx
  • backend/prisma/schema.prisma
  • backend/src/controllers/userController.ts
  • backend/src/routes/userRoutes.ts
  • tree_output.txt

Comment on lines +52 to +55
} catch (error) {
console.error('Failed to fetch profile', error);
setNotFound(true);
} finally {

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 | 🟡 Minor | ⚡ Quick win

Don’t render “Profile not found” for non-404 failures.

Line 54 marks every fetch failure as not-found, so server/network errors are misreported as missing users. Keep a separate error state and reserve not-found UI for true 404 responses.

Proposed fix
   const [notFound, setNotFound] = useState(false);
+  const [loadError, setLoadError] = useState(false);

   useEffect(() => {
     const fetchProfile = async () => {
       setLoading(true);
       setNotFound(false);
+      setLoadError(false);
       try {
         const res = await fetch(`${API_BASE_URL}/api/users/${userId}/profile`);
         if (res.status === 404) {
           setNotFound(true);
           return;
         }
+        if (!res.ok) {
+          setLoadError(true);
+          return;
+        }
-        if (res.ok) {
-          const data = await res.json();
-          setProfile(data);
-          setEditBio(data.bio || '');
-          setEditAvatarUrl(data.avatar || '');
-        }
+        const data = await res.json();
+        setProfile(data);
+        setEditBio(data.bio || '');
+        setEditAvatarUrl(data.avatar || '');
       } catch (error) {
         console.error('Failed to fetch profile', error);
-        setNotFound(true);
+        setLoadError(true);
       } finally {
         setLoading(false);
       }
     };

Also applies to: 102-107

🤖 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/ProfileView.tsx` around lines 52 - 55, The catch block
currently treats every fetch failure as "not found" by calling
setNotFound(true); instead add a separate error state (e.g., setError / error
state variable) and only setNotFound(true) when the HTTP response indicates a
404; for other failures set the error state and log the error. Locate the
profile-loading routine (the async function in ProfileView, e.g., fetchProfile /
the useEffect that calls it) and change the logic so you inspect response.status
(or the thrown HttpError) to decide: if status === 404 call setNotFound(true),
else call setError(error) and do not mark not-found; apply the same change to
the other fetch block referenced around lines 102-107 to keep consistent
behavior.

Comment thread backend/src/controllers/userController.ts Outdated
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.

Add Public User Profile Pages Accessible via URL

1 participant