Improve Contributor Profile header layout - #146
Conversation
WalkthroughThe PR adds navbar styling hooks and accessible action markup. It redesigns the contributor profile header with avatar fallback handling, GitHub and sharing actions, export controls, and responsive layout rules. ChangesContributor profile UI
Estimated code review effort: 3 (Moderate) | ~20 minutes Possibly related PRs
Suggested labels: Suggested reviewers: Poem
🚥 Pre-merge checks | ✅ 3 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (3 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
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 `@src/pages/ContributorProfilePage.jsx`:
- Around line 332-340: In ContributorProfilePage, keep all hooks unconditional
but add an early missing-profile render before the avatar identity expressions
and other username-dependent rendering execute. Guard the contributor lookup in
the avatarUrl derivation and the username.charAt() usage by returning the
existing fallback state when username is absent, while preserving normal
rendering for valid usernames.
In `@src/styles/global.css`:
- Around line 66-156: Reorder declarations alphabetically within the newly added
CSS blocks, especially `.contributor-profile-github` and the mobile
`.navbar-icon-action` rule, placing properties such as `height` before `width`
where applicable. Apply the same alphabetical ordering consistently to the other
changed selectors without changing their values or behavior.
🪄 Autofix
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: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 14b0d55c-3d69-4012-b861-81719e4146d4
📒 Files selected for processing (3)
src/components/Navbar.jsxsrc/pages/ContributorProfilePage.jsxsrc/styles/global.css
| const contributorAvatar = model?.contributors?.find( | ||
| contributor => contributor.login.toLowerCase() === username.toLowerCase() | ||
| )?.avatar_url | ||
| const contributionAvatar = rawContributions.find(item => item.user?.avatar_url)?.user.avatar_url | ||
| const avatarUrl = contributorAvatar || contributionAvatar | ||
|
|
||
| useEffect(() => { | ||
| setAvatarFailed(false) | ||
| }, [avatarUrl, username]) |
There was a problem hiding this comment.
🩺 Stability & Availability | 🟠 Major | ⚡ Quick win
Handle a missing username before deriving the profile identity.
When username is missing, the effect at Line 153 stops loading but does not stop rendering. Line 333 then calls username.toLowerCase(). Line 454 also calls username.charAt(). Both calls throw before the page can show a fallback state.
Keep hooks unconditional. Then render a missing-profile state before these identity expressions execute.
Also applies to: 432-496
🤖 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 `@src/pages/ContributorProfilePage.jsx` around lines 332 - 340, In
ContributorProfilePage, keep all hooks unconditional but add an early
missing-profile render before the avatar identity expressions and other
username-dependent rendering execute. Guard the contributor lookup in the
avatarUrl derivation and the username.charAt() usage by returning the existing
fallback state when username is absent, while preserving normal rendering for
valid usernames.
| .contributor-profile-actions .social-share-btn { | ||
| box-sizing: border-box; | ||
| height: 44px; | ||
| padding-top: 0; | ||
| padding-bottom: 0; | ||
| justify-content: center; | ||
| } | ||
|
|
||
| .contributor-profile-export { | ||
| transition: transform 0.2s ease, box-shadow 0.2s ease; | ||
| } | ||
|
|
||
| .contributor-profile-export:hover:not(:disabled) { | ||
| transform: translateY(-1px); | ||
| box-shadow: 0 8px 22px rgba(245,197,24,.25) !important; | ||
| } | ||
|
|
||
| .contributor-profile-back { | ||
| transition: background-color 0.2s ease, border-color 0.2s ease, color 0.2s ease; | ||
| } | ||
|
|
||
| .contributor-profile-back:hover { | ||
| background: var(--surface2) !important; | ||
| border-color: rgba(245, 197, 24, 0.35) !important; | ||
| color: var(--text) !important; | ||
| } | ||
|
|
||
| .contributor-profile-github { | ||
| display: inline-flex; | ||
| align-items: center; | ||
| justify-content: center; | ||
| width: 32px; | ||
| height: 32px; | ||
| flex: 0 0 32px; | ||
| align-self: center; | ||
| line-height: 0; | ||
| color: var(--text2); | ||
| transition: color 0.2s ease, transform 0.2s ease; | ||
| } | ||
|
|
||
| .contributor-profile-github:hover { | ||
| color: var(--accent); | ||
| transform: translateY(-1px); | ||
| } | ||
|
|
||
| @media (max-width: 600px) { | ||
| .app-navbar { | ||
| padding-left: 12px !important; | ||
| padding-right: 12px !important; | ||
| gap: 8px !important; | ||
| } | ||
|
|
||
| .app-navbar-links { | ||
| min-width: 0; | ||
| } | ||
|
|
||
| .app-navbar-actions { | ||
| gap: 6px !important; | ||
| } | ||
|
|
||
| .navbar-action-label { | ||
| display: none; | ||
| } | ||
|
|
||
| .navbar-icon-action { | ||
| width: 32px; | ||
| height: 32px; | ||
| padding: 0 !important; | ||
| justify-content: center; | ||
| } | ||
|
|
||
| .contributor-profile-heading > div { | ||
| flex-direction: column; | ||
| align-items: stretch !important; | ||
| gap: 16px; | ||
| } | ||
|
|
||
| .contributor-profile-actions { | ||
| width: 100%; | ||
| flex-direction: column; | ||
| align-items: stretch !important; | ||
| } | ||
|
|
||
| .contributor-profile-actions > div, | ||
| .contributor-profile-actions .social-share-btn, | ||
| .contributor-profile-actions .contributor-profile-export { | ||
| width: 100%; | ||
| } | ||
|
|
||
| .contributor-profile-stats { | ||
| grid-template-columns: repeat(2, minmax(0, 1fr)) !important; |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value
Use alphabetical declaration order in the new CSS blocks.
Several blocks do not follow the Google CSS declaration-order rule. For example, .contributor-profile-github starts with display before align-items, and .navbar-icon-action starts with width before height.
Reorder declarations consistently in the changed blocks. As per path instructions, review CSS against the Google CSS style guide.
🤖 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 `@src/styles/global.css` around lines 66 - 156, Reorder declarations
alphabetically within the newly added CSS blocks, especially
`.contributor-profile-github` and the mobile `.navbar-icon-action` rule, placing
properties such as `height` before `width` where applicable. Apply the same
alphabetical ordering consistently to the other changed selectors without
changing their values or behavior.
Source: Path instructions
|
Closing as duplicated by your recent PR# 147 |
Addressed Issues
Fixes #142
Screenshots/Recordings
Before
After
Additional Notes
This PR improves the Contributor Profile header by:
Verification
AI Disclosure
AI tools were used to assist with implementation and verification. The resulting changes were manually reviewed, tested, and validated against the issue requirements.
Checklist
We encourage contributors to use AI tools responsibly when creating Pull Requests. While AI can be a valuable aid, it is essential to ensure that your contributions meet the task requirements, build successfully, include relevant tests, and pass all linters. Submissions that do not meet these standards may be closed without warning to maintain the quality and integrity of the project. Please take the time to understand the changes you are proposing and their impact.
Summary by CodeRabbit