Skip to content

Comments

feat: profile page redesign #119#125

Merged
aviralsaxena16 merged 1 commit intoOpenLake:mainfrom
abhijeetgaur-dev:feat/profile-page-redesign
Nov 5, 2025
Merged

feat: profile page redesign #119#125
aviralsaxena16 merged 1 commit intoOpenLake:mainfrom
abhijeetgaur-dev:feat/profile-page-redesign

Conversation

@abhijeetgaur-dev
Copy link
Contributor

@abhijeetgaur-dev abhijeetgaur-dev commented Nov 5, 2025


name: "📦 Pull Request"
about: Submit changes for review
title: "PR: 🎨 Profile Page UI Redesign & Stats Visualization"
labels: "UI/UX, enhancement, hacktoberfest"
assignees: ""

📌 Related Issue

Connected to #119

✨ Changes Introduced

Added:

  • Level and streak badges beside username
  • Interactive stats grid with 6 stat cards (Solved, Coins, Streak, Followers, Following, Accuracy)
  • Codeforces tier-based rank colors and gradients
  • Streak calendar visualization in activity panel
  • Recent submissions and quiz performance sections
  • Mobile-responsive grid layout
  • Hover animations and smooth transitions

Updated:

  • Complete profile page component structure
  • CSS stylesheet with modern design system
  • Responsive breakpoints for all screen sizes
  • Color scheme using CanonForces palette

Removed:

  • Right-side illustration (replaced with activity panel)
  • Plain text stats display
  • Excessive whitespace and unbalanced layout

🤔 Why This Change?

Problem:

The current Profile Page UI felt plain and lacked hierarchy, failing to effectively highlight user achievements and community interactions. Essential details like solved problems, streaks, and Codeforces info appeared as raw text with too much whitespace.

Solution:

Transformed the profile into a professional, production-grade layout similar to LeetCode, GitHub, and Codeforces profiles with proper visual hierarchy, engaging stats visualization, and interactive elements.

Impact:

  • Users get a comprehensive view of their coding progress and achievements
  • Improved user engagement with visual stats and streaks
  • Better mobile experience with responsive design
  • Enhanced community interactions through better follower/following visibility

🖼️ Screenshots

Before After
old_profile_page new_profile_page

🧪 Testing

  • Tested manually on desktop (1440px) and mobile (375px) layouts
  • Verified responsiveness and alignment across sections
  • Ensured smooth hover animations and transitions
  • Confirmed that stats, streak, and Codeforces sections display dynamically fetched data without console errors
  • Checked accessibility (contrast and focus states)

📝 Documentation Updates

  • Added inline comments in profile.module.css for layout and variable usage
  • Updated README section for local style testing (optional)
  • Added JSDoc comments for future contributors

✅ Checklist

  • Created a new branch: feature/profile-ui-redesign
  • Follows JavaScript Styleguide
  • No console warnings/errors
  • Commit messages follow Git Guidelines
  • Self-reviewed my code
  • Added manual tests for new functionality
  • All tests pass locally
  • Code follows project conventions
  • No breaking changes

🚀 Deployment Notes

  • Requires environment variable update — ❌
  • Requires database migration — ❌
  • Requires third-party service configuration — ❌
  • Breaking changes — ❌

This is a pure frontend style enhancement and can be safely merged after review.

💡 Additional Notes

  • Design aligns with Hacktoberfest UI/UX contribution goals
  • Future enhancement: add data visualizations for streak calendar and Codeforces rating graph
  • Modularized CSS ensures future theming (dark/light mode) can be implemented easily

Summary by CodeRabbit

  • New Features
    • Redesigned profile layout with improved visual hierarchy and card-based design
    • Added comprehensive statistics dashboard displaying solved problems, coins, streak, followers, and accuracy
    • Integrated Codeforces rank display with progress indicator to next rank
    • Implemented 7-day streak tracking with calendar visualization
    • Added editable profile functionality with image upload capability
    • New activity dashboard showing recent submissions and quiz performance metrics

@vercel
Copy link

vercel bot commented Nov 5, 2025

@abhijeetgaur-dev is attempting to deploy a commit to the aviralsaxena16's projects Team on Vercel.

A member of the Team first needs to authorize it.

@github-actions
Copy link

github-actions bot commented Nov 5, 2025

🎉 Thanks for Your Contribution to CanonForces! ☺️

We'll review it as soon as possible. In the meantime, please:

  • ✅ Double-check the file changes.
  • ✅ Ensure that all commits are clean and meaningful.
  • ✅ Link the PR to its related issue (e.g., Closes #123).
  • ✅ Resolve any unaddressed review comments promptly.

💬 Need help or want faster feedback?
Join our Discord 👉 CanonForces Discord

Thanks again for contributing 🙌 – @abhijeetgaur-dev!
cc: @aviralsaxena16

@coderabbitai
Copy link

coderabbitai bot commented Nov 5, 2025

Walkthrough

The Profile component undergoes a comprehensive redesign, transitioning from a flex-based layout to a grid-based two-column structure with new sections for profile header, stats display, Codeforces ranking, and activity panels. The accompanying CSS module is extensively expanded with new styling classes, responsive breakpoints, animations, and interactive states. The TypeScript component is refactored to add streak tracking, level calculation, profile editing with image upload, and enhanced activity displays.

Changes

Cohort / File(s) Summary
Profile Component CSS Redesign
src/common/components/Profile/Profile.module.css
Complete layout overhaul from flex to grid (2fr/1fr columns). Introduces 50+ new classes including profileHeader, banner, avatarContainer, statsGrid, cfSection, badges, difficulty tags, form controls, and animations (pulse, flame). Adds responsive breakpoints at 1024px, 768px, and 480px. Removes/reshapes profileCard and illustrationWrapper. Implements gradient backgrounds, soft shadows, and outlined cards for cohesive light UI.
Profile Component TypeScript Refactor
src/common/components/Profile/Profile.tsx
Substantial refactor adding rank-based gradient styling, streak calculation logic (calculateCurrentStreak, isStreakInDanger, generateStreakCalendar), level calculation, and Codeforces data integration with dynamic rank-based styling. Introduces leftColumn/rightColumn layout structure replacing single-column design. Adds profile editing form with Cloudinary image upload, validation, and error handling. Expands activity display with recent submissions, quiz performance, and streak calendar visualization. Restructures JSX with modular sections and enhanced statistics grid.

Sequence Diagram(s)

sequenceDiagram
    actor User
    participant Profile Component
    participant Edit Flow
    participant Cloudinary
    participant State

    User->>Profile Component: View profile
    Profile Component->>State: Calculate streak, level
    Profile Component->>Profile Component: Render header + stats
    
    Note over Profile Component: Display<br/>- Badges (level, streak)<br/>- Stats grid<br/>- CF ranking<br/>- Recent activity

    User->>Profile Component: Click edit button
    activate Edit Flow
    Profile Component->>Edit Flow: Show edit form
    User->>Edit Flow: Upload image
    Edit Flow->>Cloudinary: Upload image
    Cloudinary-->>Edit Flow: Return URL
    User->>Edit Flow: Save changes
    Edit Flow->>State: Update profile
    State-->>Profile Component: Refresh display
    deactivate Edit Flow
    
    Profile Component->>Profile Component: Re-render with new data
    User->>User: Profile updated
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Areas requiring extra attention:

  • CSS module: Validate all new responsive breakpoints (1024px, 768px, 480px) and ensure consistent spacing/sizing across all breakpoint transitions
  • Streak calculation logic: Review calculateCurrentStreak, isStreakInDanger, and generateStreakCalendar for edge cases (timezone handling, day-of-week calculations)
  • Image upload flow: Verify uploadImageToCloudinary integration, error handling, and 5MB size validation
  • New grid layouts (statsGrid, calendarGrid): Confirm grid column counts, gap values, and alignment across breakpoints match design intent
  • State management: Ensure isEditing toggle, form validation, and error states are properly handled throughout the edit flow
  • Level and badge calculations: Verify getRankGradient color mapping and badge styling logic match intended visualization

Poem

🐰 A profile redesigned with grid and grace,
Two columns dance in perfect space,
Streaks and ranks in banners bloom,
Stats and edits fill each room,
From old flex bones to grids anew,
The profile shines—refreshed and true! ✨

Pre-merge checks and finishing touches

✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title 'feat: profile page redesign #119' is specific and directly reflects the main change—a redesign of the profile page component.
Description check ✅ Passed The PR description is comprehensive, covering all required template sections: related issue, detailed changes (Added/Updated/Removed), problem/solution/impact rationale, before/after screenshots, testing verification, documentation updates, and deployment notes.
✨ 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: 2

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e1ec7a8 and 60b51be.

📒 Files selected for processing (2)
  • src/common/components/Profile/Profile.module.css (1 hunks)
  • src/common/components/Profile/Profile.tsx (3 hunks)

Comment on lines +279 to +288
for (let i = 6; i >= 0; i--) {
const date = new Date(today);
date.setDate(date.getDate() - i);
const isActive = i >= (6 - Math.min(streak - 1, 6));

calendarDays.push({
date: date.getDate(),
month: date.getMonth(),
isActive: isActive && streak > 0
});
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Fix streak calendar highlight logic

Line [283] treats i as a forward index and flags cells with i >= (6 - Math.min(streak - 1, 6)). Because i actually represents “days ago”, this lights up days far in the past (a 1‑day streak lights the cell six days ago). The calendar ends up contradicting the computed streak length. Please derive the active state from the actual days-ago value instead.

-      const isActive = i >= (6 - Math.min(streak - 1, 6));
-      
-      calendarDays.push({
-        date: date.getDate(),
-        month: date.getMonth(),
-        isActive: isActive && streak > 0
-      });
+      const isActive = streak > 0 && i < Math.min(streak, 7);
+
+      calendarDays.push({
+        date: date.getDate(),
+        month: date.getMonth(),
+        isActive
+      });
🤖 Prompt for AI Agents
In src/common/components/Profile/Profile.tsx around lines 279 to 288, the loop
variable i represents "days ago" (6 = six days ago, 0 = today) but the active
calculation uses i as a forward index; change the logic to derive daysAgo = i
and mark a day active when daysAgo <= Math.min(streak - 1, 6) and streak > 0.
Replace the current isActive expression with one that computes daysAgo and uses
that comparison so recent days (today, yesterday, etc.) up to the streak length
are highlighted, not days far in the past.

Comment on lines +455 to +462
<span>Progress to next rank</span>
<span>65%</span>
</div>
<div className={styles.progressBar}>
<div
className={styles.progressFill}
style={{ width: '65%', background: getRankColor(cfData.rank) }}
></div>
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Remove hard-coded 65% CF progress bar

Lines [456-462] render “Progress to next rank” at a fixed 65% width/text, so every user—regardless of their actual Codeforces rating—sees the same progress. That’s misleading and makes the new visualization untrustworthy. Please compute the percentage from the current rating (with rank thresholds) or hide the bar when you can’t derive a real value.

-                  <span>65%</span>
+                  <span>
+                    {progressPercent !== null ? `${progressPercent}%` : '—'}
+                  </span>
...
-                    className={styles.progressFill} 
-                    style={{ width: '65%', background: getRankColor(cfData.rank) }}
+                    className={styles.progressFill}
+                    style={{
+                      width: progressPercent !== null ? `${progressPercent}%` : '0%',
+                      background: getRankColor(cfData.rank),
+                    }}

Example helper (place next to the other rank helpers):

+  const rankBounds: Record<string, { min: number; next?: number }> = {
+    newbie: { min: 0, next: 1200 },
+    pupil: { min: 1200, next: 1400 },
+    specialist: { min: 1400, next: 1600 },
+    expert: { min: 1600, next: 1900 },
+    'candidate master': { min: 1900, next: 2100 },
+    master: { min: 2100, next: 2300 },
+    'international master': { min: 2300, next: 2400 },
+    grandmaster: { min: 2400, next: 2600 },
+    'international grandmaster': { min: 2600, next: 2900 },
+    'legendary grandmaster': { min: 2900 },
+  };
+
+  const getRankProgressPercent = (rank: string | undefined, rating: number | undefined) => {
+    if (!rank || rating == null) return null;
+    const bounds = rankBounds[rank.toLowerCase()];
+    if (!bounds || bounds.next == null || rating < bounds.min) return null;
+    const clamped = Math.min(rating, bounds.next);
+    return Math.round(((clamped - bounds.min) / (bounds.next - bounds.min)) * 100);
+  };
-  const streakDanger = isStreakInDanger();
+  const streakDanger = isStreakInDanger();
+  const progressPercent = getRankProgressPercent(cfData?.rank, cfData?.rating);

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In src/common/components/Profile/Profile.tsx around lines 455 to 462, the CF
progress bar and displayed "65%" are hard-coded; replace this with a computed
percentage based on cfData.rating and rank thresholds (or hide the bar when
rating or thresholds are unavailable). Add a helper function next to the other
rank helpers that: 1) maps ranks to min/max rating, 2) given cfData.rating
returns fraction = (rating - min) / (max - min) clamped 0..1, and 3) formats
percentage string; then use that helper to set the progressFill width and the
displayed text, and ensure null/undefined ratings render no bar or a fallback
UI.

Copy link
Member

@aviralsaxena16 aviralsaxena16 left a comment

Choose a reason for hiding this comment

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

@abhijeetgaur-dev Thanks for your contribution throughout Hacktoberfest! 😇
You were one of our top and most consistent contributors, really appreciate your efforts, even after the event ended.

@aviralsaxena16 aviralsaxena16 merged commit f3e7885 into OpenLake:main Nov 5, 2025
2 of 3 checks passed
@abhijeetgaur-dev
Copy link
Contributor Author

Thank you so much @aviralsaxena16 I really enjoyed the whole process as well. Would love to stay connected and work on future collabs!!!

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