feat: profile page redesign #119#125
Conversation
|
@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. |
🎉 Thanks for Your Contribution to CanonForces!
|
WalkthroughThe 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
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
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Areas requiring extra attention:
Poem
Pre-merge checks and finishing touches✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
src/common/components/Profile/Profile.module.css(1 hunks)src/common/components/Profile/Profile.tsx(3 hunks)
| 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 | ||
| }); |
There was a problem hiding this comment.
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.
| <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> |
There was a problem hiding this comment.
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.
aviralsaxena16
left a comment
There was a problem hiding this comment.
@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.
|
Thank you so much @aviralsaxena16 I really enjoyed the whole process as well. Would love to stay connected and work on future collabs!!! |
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:
Updated:
Removed:
🤔 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:
🖼️ Screenshots
🧪 Testing
📝 Documentation Updates
profile.module.cssfor layout and variable usage✅ Checklist
feature/profile-ui-redesign🚀 Deployment Notes
This is a pure frontend style enhancement and can be safely merged after review.
💡 Additional Notes
Summary by CodeRabbit