-
-
Notifications
You must be signed in to change notification settings - Fork 871
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[FIX] Figma User Portal: Organization Left Drawer Violates The Figma Style Guide #3430
[FIX] Figma User Portal: Organization Left Drawer Violates The Figma Style Guide #3430
Conversation
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Warning Rate limit exceeded@hustlernik has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 2 minutes and 21 seconds before requesting another review. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. 📒 Files selected for processing (2)
WalkthroughThis pull request introduces comprehensive documentation and styling updates across multiple components in the Talawa Admin project. The changes focus on enhancing the user interface consistency, particularly in the user portal, by consolidating CSS styles, adding new components like ProfileCard and SignOut, and updating documentation for various functions. The modifications aim to align the application more closely with the Figma design guidelines. Changes
Assessment against linked issues
Possibly related issues
Possibly related PRs
Suggested labels
Suggested reviewers
Poem
Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media? 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
Documentation and Community
|
Our Pull Request Approval ProcessThanks for contributing! Testing Your CodeRemember, your PRs won't be reviewed until these criteria are met:
Our policies make our code better. ReviewersDo not assign reviewers. Our Queue Monitors will review your PR and assign them.
Reviewing Your CodeYour reviewer(s) will have the following roles:
CONTRIBUTING.mdRead our CONTRIBUTING.md file. Most importantly:
Other
|
There was a problem hiding this 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
🧹 Nitpick comments (9)
src/components/SignOut/SignOut.tsx (2)
16-16
: Fix copy-paste error in JSDoc.The @returns description incorrectly mentions "profile card" instead of "sign out button".
-@returns JSX.Element - The profile card . +@returns JSX.Element - The sign out button component.
24-39
: Improve error handling and function organization.Consider these improvements:
- Add return type to handleSignOut function
- Move handleSignOut outside the logout function for better readability
- Add more specific error handling
+const handleSignOut = (): void => { + localStorage.clear(); + endSession(); + navigate('/'); +}; + const logout = async (): Promise<void> => { - const handleSignOut = () => { - localStorage.clear(); - endSession(); - navigate('/'); - }; - try { await revokeRefreshToken(); handleSignOut(); - } catch (error) { + } catch (error: unknown) { console.error('Error revoking refresh token:', error); // Still sign out the user locally even if token revocation fails handleSignOut(); } };🧰 Tools
🪛 eslint
[error] 25-25: Missing return type on function.
(@typescript-eslint/explicit-function-return-type)
src/components/ProfileCard/ProfileCard.tsx (2)
23-29
: Consider extracting role determination logic.The role determination logic could be more maintainable by extracting it into a separate function.
+const determineUserRole = (superAdmin: boolean | null, adminFor: unknown): string => { + if (superAdmin) return 'SuperAdmin'; + if (Array.isArray(adminFor) && adminFor.length > 0) return 'Admin'; + return 'User'; +}; + const superAdmin = getItem('SuperAdmin'); const adminFor = getItem('AdminFor'); -const userRole = superAdmin - ? 'SuperAdmin' - : adminFor?.length > 0 - ? 'Admin' - : 'User'; +const userRole = determineUserRole(superAdmin, adminFor);
80-88
: Move inline styles to CSS modules.Consider moving the ChevronRightIcon styles to the CSS module for better maintainability.
+// In app.module.css +.chevronRightIcon { + color: gray; + background: white; + font-size: 40px; + stroke-width: 0.5; + margin-left: 50px; +} -<ChevronRightIcon - sx={{ - color: 'gray', - background: 'white', - fontSize: 40, - strokeWidth: 0.5, - marginLeft: '50px', - }} -/> +<ChevronRightIcon className={styles.chevronRightIcon} />src/components/SignOut/SignOut.spec.tsx (1)
33-127
: Consider adding more edge cases to the test suite.The current tests cover the main functionality well. Consider adding these test cases:
- Network timeout during token revocation
- Multiple rapid sign-out attempts
- Session already ended scenario
src/components/ProfileCard/ProfileCard.spec.tsx (1)
79-191
: Add tests for name truncation and image loading.Consider adding these test cases:
- Verify name truncation for long names
- Test image loading error fallback
- Test empty first/last name scenarios
src/components/UserPortal/UserSidebarOrg/UserSidebarOrg.tsx (2)
14-17
: Consider keeping CSS modules for better style encapsulation.Switching from a local CSS module to a global CSS file could lead to style conflicts and make the component less maintainable. CSS modules provide scoped styling that prevents unintended style leaks.
Consider keeping the CSS module approach:
-import styles from '../../../style/app.module.css'; +import styles from './UserSidebarOrg.module.css';
164-165
: Improve button variant clarity.Using an empty string as a variant is unclear and may lead to confusion. Consider using a more explicit variant name or removing it if not needed.
-variant={isActive === true ? '' : ''} +variant={isActive ? 'primary' : 'default'}docs/docs/auto-docs/components/SignOut/SignOut/functions/default.md (1)
11-14
: Improve grammar and consistency in the description.Apply these grammatical improvements:
- Use hyphenated form "sign-out" when used as a noun/modifier
- Use "log out" (two words) when used as a verb
-Renders a sign out button. +Renders a sign-out button. -This component helps to logout. +This component helps to log out. -The logout function revokes the refresh token and clears local storage before redirecting to the home page. +The log out function revokes the refresh token and clears local storage before redirecting to the home page.🧰 Tools
🪛 LanguageTool
[uncategorized] ~11-~11: When ‘sign-out’ is used as a noun or modifier, it needs to be hyphenated.
Context: ...nts/SignOut/SignOut.tsx#L20) Renders a sign out button. This component helps to logout...(VERB_NOUN_CONFUSION)
[misspelling] ~13-~13: Did you mean the verb “log out” instead of the noun ‘logout’?
Context: ...gn out button. This component helps to logout. The logout function revokes the refres...(LOG_IN)
📜 Review details
Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (12)
docs/docs/auto-docs/components/ProfileCard/ProfileCard/functions/default.md
(1 hunks)docs/docs/auto-docs/components/SignOut/SignOut/functions/default.md
(1 hunks)docs/docs/auto-docs/components/UserPortal/UserSidebarOrg/UserSidebarOrg/functions/default.md
(1 hunks)docs/docs/auto-docs/components/UserPortal/UserSidebarOrg/UserSidebarOrg/interfaces/InterfaceUserSidebarOrgProps.md
(1 hunks)src/components/ProfileCard/ProfileCard.spec.tsx
(1 hunks)src/components/ProfileCard/ProfileCard.tsx
(1 hunks)src/components/ProfileDropdown/ProfileDropdown.tsx
(1 hunks)src/components/SignOut/SignOut.spec.tsx
(1 hunks)src/components/SignOut/SignOut.tsx
(1 hunks)src/components/UserPortal/UserSidebarOrg/UserSidebarOrg.module.css
(0 hunks)src/components/UserPortal/UserSidebarOrg/UserSidebarOrg.tsx
(4 hunks)src/style/app.module.css
(4 hunks)
💤 Files with no reviewable changes (1)
- src/components/UserPortal/UserSidebarOrg/UserSidebarOrg.module.css
✅ Files skipped from review due to trivial changes (4)
- docs/docs/auto-docs/components/UserPortal/UserSidebarOrg/UserSidebarOrg/functions/default.md
- src/components/ProfileDropdown/ProfileDropdown.tsx
- docs/docs/auto-docs/components/ProfileCard/ProfileCard/functions/default.md
- docs/docs/auto-docs/components/UserPortal/UserSidebarOrg/UserSidebarOrg/interfaces/InterfaceUserSidebarOrgProps.md
🧰 Additional context used
🪛 eslint
src/components/SignOut/SignOut.tsx
[error] 25-25: Missing return type on function.
(@typescript-eslint/explicit-function-return-type)
🪛 GitHub Actions: PR Workflow
src/style/app.module.css
[warning] Code style issues found. Run Prettier with --write to fix formatting issues.
🪛 LanguageTool
docs/docs/auto-docs/components/SignOut/SignOut/functions/default.md
[uncategorized] ~11-~11: When ‘sign-out’ is used as a noun or modifier, it needs to be hyphenated.
Context: ...nts/SignOut/SignOut.tsx#L20) Renders a sign out button. This component helps to logout...
(VERB_NOUN_CONFUSION)
[misspelling] ~13-~13: Did you mean the verb “log out” instead of the noun ‘logout’?
Context: ...gn out button. This component helps to logout. The logout function revokes the refres...
(LOG_IN)
🔇 Additional comments (8)
src/components/SignOut/SignOut.tsx (1)
40-47
: LGTM! Clean and accessible implementation.The component follows the Figma style guide with proper icon usage and styling.
src/components/ProfileCard/ProfileCard.tsx (2)
1-21
: LGTM! Well-documented component.The documentation clearly explains the component's purpose and behavior.
43-62
: LGTM! Accessible image implementation.The component handles image fallback gracefully and follows accessibility best practices with proper alt text.
src/components/UserPortal/UserSidebarOrg/UserSidebarOrg.tsx (1)
189-192
: LGTM! Footer components enhance user experience.The addition of ProfileCard and SignOut components in the footer improves navigation and user interaction, aligning with the Figma style guide.
src/style/app.module.css (4)
138-142
: LGTM! Well-structured CSS variables.The new CSS variables are well-named and provide good theme customization options for the user sidebar organization component.
🧰 Tools
🪛 GitHub Actions: PR Workflow
[warning] Code style issues found. Run Prettier with --write to fix formatting issues.
7424-7843
: LGTM! Well-structured and responsive sidebar styles.The UserSidebarOrg styles are well-organized with:
- Proper use of CSS variables for theming
- Comprehensive responsive design with media queries
- Good component structure and hierarchy
🧰 Tools
🪛 GitHub Actions: PR Workflow
[warning] Code style issues found. Run Prettier with --write to fix formatting issues.
7844-7940
: LGTM! Well-implemented component styles.The ProfileCard and SignOut component styles are well-implemented with:
- Consistent use of CSS variables
- Good responsive design
- Proper styling hierarchy
🧰 Tools
🪛 GitHub Actions: PR Workflow
[warning] Code style issues found. Run Prettier with --write to fix formatting issues.
Line range hint
1-7940
: Fix code formatting with Prettier.The pipeline reports code style issues. Please run Prettier to fix the formatting:
🧰 Tools
🪛 GitHub Actions: PR Workflow
[warning] Code style issues found. Run Prettier with --write to fix formatting issues.
docs/docs/auto-docs/components/SignOut/SignOut/functions/default.md
Outdated
Show resolved
Hide resolved
There was a problem hiding this 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
🧹 Nitpick comments (2)
src/style/app.module.css (2)
7424-7440
: Replace hardcoded colors with CSS variables.Some colors are hardcoded instead of using the newly defined CSS variables. This reduces maintainability and breaks the theming system.
Use the new CSS variables consistently:
.leftDrawer { - background-color: #ffffff !important; + background-color: var(--user-sidebar-org-bg) !important; } .leftDrawer .optionList button { - background-color: #eaebef; + background-color: var(--user-sidebar-org-option-bg); /* Other properties */ }Also applies to: 7514-7527
7485-7512
: Improve scrollbar styling for better accessibility.The current scrollbar implementation hides visual feedback. Consider making it subtly visible for better UX while maintaining the clean design.
Apply this enhancement:
.leftDrawer .optionList { scrollbar-width: thin; - scrollbar-color: var(--table-bg) transparent; + scrollbar-color: var(--user-sidebar-org-option-bg) transparent; } .leftDrawer .optionList::-webkit-scrollbar-thumb { - background-color: transparent; + background-color: var(--user-sidebar-org-option-bg); + opacity: 0.5; }
📜 Review details
Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
src/style/app.module.css
(4 hunks)
🔇 Additional comments (1)
src/style/app.module.css (1)
138-142
: LGTM! Well-structured CSS variables for theming.The new CSS variables follow good naming conventions and provide a consistent theming system for the Organization Left Drawer.
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
…lt.md Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## develop-postgres #3430 +/- ##
=====================================================
+ Coverage 6.39% 89.73% +83.34%
=====================================================
Files 312 336 +24
Lines 8168 8672 +504
Branches 1837 1925 +88
=====================================================
+ Hits 522 7782 +7260
+ Misses 7586 628 -6958
- Partials 60 262 +202
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. |
@coderabbitai full review |
✅ Actions performedFull review triggered. |
There was a problem hiding this 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
🔭 Outside diff range comments (2)
src/components/ProfileDropdown/ProfileDropdown.tsx (2)
Line range hint
23-23
: Component name should follow React naming conventions.React components should use PascalCase naming convention.
Rename the component:
-const profileDropdown = (): JSX.Element => { +const ProfileDropdown = (): JSX.Element => {
Line range hint
41-54
: Consider using the SignOut component to avoid logic duplication.The logout logic is duplicated from the SignOut component. Consider reusing the SignOut component to maintain DRY principles.
Replace the logout function with the SignOut component:
- const logout = async (): Promise<void> => { - try { - await revokeRefreshToken(); - } catch (error) { - console.error('Error revoking refresh token:', error); - } - localStorage.clear(); - endSession(); - navigate('/'); - }; + import SignOut from 'components/SignOut/SignOut'; + // ... in the dropdown menu + <SignOut />
♻️ Duplicate comments (1)
docs/docs/auto-docs/components/SignOut/SignOut/functions/default.md (1)
11-14
: 🛠️ Refactor suggestionFix grammar and improve documentation clarity.
The documentation contains grammar issues and could be more precise.
-Renders a sign out button. +Renders a sign-out button. -This component helps to logout. -The logout function revokes the refresh token and clears local storage before redirecting to the home page. +This component handles the user sign-out process. +The sign-out function: +- Revokes the refresh token +- Clears local storage +- Redirects to the home page🧰 Tools
🪛 LanguageTool
[uncategorized] ~11-~11: When ‘sign-out’ is used as a noun or modifier, it needs to be hyphenated.
Context: ...nts/SignOut/SignOut.tsx#L20) Renders a sign out button. This component helps to logout...(VERB_NOUN_CONFUSION)
[misspelling] ~13-~13: Did you mean the verb “log out” instead of the noun ‘logout’?
Context: ...gn out button. This component helps to logout. The logout function revokes the refres...(LOG_IN)
🧹 Nitpick comments (12)
src/components/SignOut/SignOut.tsx (3)
9-18
: Documentation needs improvement.The JSDoc comment has incorrect formatting and grammar issues.
Apply these changes:
/** * Renders a sign out button. * - * This component helps to logout. - * The logout function revokes the refresh token and clears local storage before redirecting to the home page. + * This component handles user sign-out. + * The sign-out process includes: + * - Revoking the refresh token + * - Clearing local storage + * - Redirecting to the home page * - * * @returns JSX.Element - The profile card . + * @returns {JSX.Element} The sign-out button */
24-39
: Consider enhancing error handling.While the error handling is present, it could be improved by:
- Adding specific error types
- Providing user feedback on error
const logout = async (): Promise<void> => { const handleSignOut = (): void => { localStorage.clear(); endSession(); navigate('/'); }; try { await revokeRefreshToken(); handleSignOut(); } catch (error) { - console.error('Error revoking refresh token:', error); + // Log the error for debugging + console.error('Failed to revoke refresh token:', error); + // Show user-friendly error message + // Note: Import toast from react-toastify if not already imported + toast.warn('Unable to complete sign-out process on server. Signing out locally.'); // Still sign out the user locally even if token revocation fails handleSignOut(); } };🧰 Tools
🪛 GitHub Check: codecov/patch
[warning] 24-28: src/components/SignOut/SignOut.tsx#L24-L28
Added lines #L24 - L28 were not covered by tests
[warning] 31-33: src/components/SignOut/SignOut.tsx#L31-L33
Added lines #L31 - L33 were not covered by tests
[warning] 35-35: src/components/SignOut/SignOut.tsx#L35
Added line #L35 was not covered by tests
[warning] 37-37: src/components/SignOut/SignOut.tsx#L37
Added line #L37 was not covered by tests
41-50
: Add loading state during sign-out process.The button should indicate when the sign-out process is in progress to prevent multiple clicks.
+ const [isLoading, setIsLoading] = useState(false); + const logout = async (): Promise<void> => { + setIsLoading(true); try { // ... existing code ... } catch (error) { // ... existing code ... + } finally { + setIsLoading(false); } }; return ( <div className={styles.signOutContainer}> <LogoutIcon /> <button className={styles.signOutButton} onClick={logout} aria-label="Sign out" + disabled={isLoading} > - Sign Out + {isLoading ? 'Signing out...' : 'Sign Out'} </button> </div> );src/components/ProfileCard/ProfileCard.tsx (2)
36-41
: Consider moving name truncation logic to a utility function.The name truncation logic could be reused in other components.
+const truncateName = (name: string, maxLength: number = 20): string => { + return name.length > maxLength + ? `${name.substring(0, maxLength - 3)}...` + : name; +}; - const MAX_NAME_LENGTH = 20; const fullName = `${firstName} ${lastName}`; - const displayedName = - fullName.length > MAX_NAME_LENGTH - ? fullName.substring(0, MAX_NAME_LENGTH - 3) + '...' - : fullName; + const displayedName = truncateName(fullName);🧰 Tools
🪛 GitHub Check: codecov/patch
[warning] 36-37: src/components/ProfileCard/ProfileCard.tsx#L36-L37
Added lines #L36 - L37 were not covered by tests
74-78
: Extract navigation logic to a separate function.The inline navigation logic in the onClick handler reduces readability.
+ const handleProfileNavigation = () => { + const path = userRole === 'User' + ? '/user/settings' + : `/member/${orgId || ''}`; + navigate(path); + }; // In the JSX - onClick={() => - userRole === 'User' - ? navigate(`/user/settings`) - : navigate(`/member/${orgId || ''}`) - } + onClick={handleProfileNavigation}src/components/SignOut/SignOut.spec.tsx (2)
49-79
: Test coverage could be enhanced with loading state verification.Consider adding a test case to verify the component's behavior during the loading state of the mutation.
Add this test case:
test('shows loading state while mutation is in progress', async () => { render( <MockedProvider mocks={[mockRevokeRefreshToken]} addTypename={false}> <BrowserRouter> <SignOut /> </BrowserRouter> </MockedProvider> ); const signOutButton = screen.getByText('Sign Out'); fireEvent.click(signOutButton); // Verify button is disabled during mutation expect(signOutButton).toBeDisabled(); // Wait for mutation to complete await waitFor(() => { expect(signOutButton).not.toBeDisabled(); }); });
1-8
: Consider adding accessibility tests.The SignOut component should be accessible to all users. Consider adding tests for ARIA attributes and keyboard navigation.
Add these imports and test case:
import { axe, toHaveNoViolations } from 'jest-axe'; expect.extend(toHaveNoViolations); test('should not have accessibility violations', async () => { const { container } = render( <MockedProvider mocks={[mockRevokeRefreshToken]} addTypename={false}> <BrowserRouter> <SignOut /> </BrowserRouter> </MockedProvider> ); const results = await axe(container); expect(results).toHaveNoViolations(); });docs/docs/auto-docs/components/ProfileCard/ProfileCard/functions/default.md (1)
11-18
: Documentation could be enhanced with examples and prop types.Consider adding usage examples and prop types documentation to make it more developer-friendly.
Add these sections to the documentation:
## Props | Prop | Type | Description | Required | |------|------|-------------|----------| | image | string | User's profile image URL | No | | name | string | User's full name | Yes | | role | 'SuperAdmin' \| 'Admin' \| 'User' | User's role | Yes | ## Example ```tsx <ProfileCard image="https://example.com/profile.jpg" name="John Doe" role="Admin" /></blockquote></details> <details> <summary>docs/docs/auto-docs/components/UserPortal/UserSidebarOrg/UserSidebarOrg/functions/default.md (1)</summary><blockquote> Line range hint `11-15`: **Documentation should mention new component integrations.** The documentation should be updated to reflect the integration with ProfileCard and SignOut components. Add these points to the documentation: ```diff Provides: - Branding with the Talawa logo. - Displays the current organization's details. - Navigation options with links and collapsible dropdowns. +- User profile information through the ProfileCard component. +- Sign-out functionality through the SignOut component.
src/components/UserPortal/UserSidebarOrg/UserSidebarOrg.tsx (2)
164-165
: Consider using a constant for the active state class name.The empty variant strings could be confusing. Consider using a constant for the active state class name to improve maintainability.
+const ACTIVE_ITEM_CLASS = styles.activeItem; -variant={isActive === true ? '' : ''} -className={isActive === true ? styles.activeItem : ''} +variant="" +className={isActive === true ? ACTIVE_ITEM_CLASS : ''}
171-171
: Use CSS variable for icon color.Instead of hardcoding the hex color, use the CSS variable
--sidebar-icon-stroke-active
defined in the global styles.-isActive === true ? '#000000' : 'var(--bs-secondary)' +isActive === true ? 'var(--sidebar-icon-stroke-active)' : 'var(--bs-secondary)'src/style/app.module.css (1)
7427-7845
: Optimize UserSidebarOrg styles for better maintainability.The UserSidebarOrg styles could be optimized:
- Consider using CSS nesting to reduce repetition
- Use CSS custom properties for repeated values
- Consolidate media queries
// Example of using CSS nesting and custom properties +:root { + --sidebar-width: calc(300px + 2rem); + --sidebar-padding: 1rem; + --sidebar-animation-duration: 0.5s; +} .leftDrawer { width: var(--sidebar-width); padding: var(--sidebar-padding); + .talawaLogo { + width: 50px; + height: 50px; + } + + .optionList { + button { + /* Button styles */ + } + } + + @media (max-width: 1120px) { + --sidebar-width: calc(250px + 2rem); + } }
📜 Review details
Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (12)
docs/docs/auto-docs/components/ProfileCard/ProfileCard/functions/default.md
(1 hunks)docs/docs/auto-docs/components/SignOut/SignOut/functions/default.md
(1 hunks)docs/docs/auto-docs/components/UserPortal/UserSidebarOrg/UserSidebarOrg/functions/default.md
(1 hunks)docs/docs/auto-docs/components/UserPortal/UserSidebarOrg/UserSidebarOrg/interfaces/InterfaceUserSidebarOrgProps.md
(1 hunks)src/components/ProfileCard/ProfileCard.spec.tsx
(1 hunks)src/components/ProfileCard/ProfileCard.tsx
(1 hunks)src/components/ProfileDropdown/ProfileDropdown.tsx
(1 hunks)src/components/SignOut/SignOut.spec.tsx
(1 hunks)src/components/SignOut/SignOut.tsx
(1 hunks)src/components/UserPortal/UserSidebarOrg/UserSidebarOrg.module.css
(0 hunks)src/components/UserPortal/UserSidebarOrg/UserSidebarOrg.tsx
(4 hunks)src/style/app.module.css
(4 hunks)
💤 Files with no reviewable changes (1)
- src/components/UserPortal/UserSidebarOrg/UserSidebarOrg.module.css
🧰 Additional context used
🪛 LanguageTool
docs/docs/auto-docs/components/SignOut/SignOut/functions/default.md
[uncategorized] ~11-~11: When ‘sign-out’ is used as a noun or modifier, it needs to be hyphenated.
Context: ...nts/SignOut/SignOut.tsx#L20) Renders a sign out button. This component helps to logout...
(VERB_NOUN_CONFUSION)
[misspelling] ~13-~13: Did you mean the verb “log out” instead of the noun ‘logout’?
Context: ...gn out button. This component helps to logout. The logout function revokes the refres...
(LOG_IN)
🪛 GitHub Check: codecov/patch
src/components/SignOut/SignOut.tsx
[warning] 19-22: src/components/SignOut/SignOut.tsx#L19-L22
Added lines #L19 - L22 were not covered by tests
[warning] 24-28: src/components/SignOut/SignOut.tsx#L24-L28
Added lines #L24 - L28 were not covered by tests
[warning] 31-33: src/components/SignOut/SignOut.tsx#L31-L33
Added lines #L31 - L33 were not covered by tests
[warning] 35-35: src/components/SignOut/SignOut.tsx#L35
Added line #L35 was not covered by tests
[warning] 37-37: src/components/SignOut/SignOut.tsx#L37
Added line #L37 was not covered by tests
[warning] 40-40: src/components/SignOut/SignOut.tsx#L40
Added line #L40 was not covered by tests
src/components/ProfileCard/ProfileCard.tsx
[warning] 21-24: src/components/ProfileCard/ProfileCard.tsx#L21-L24
Added lines #L21 - L24 were not covered by tests
[warning] 30-34: src/components/ProfileCard/ProfileCard.tsx#L30-L34
Added lines #L30 - L34 were not covered by tests
[warning] 36-37: src/components/ProfileCard/ProfileCard.tsx#L36-L37
Added lines #L36 - L37 were not covered by tests
[warning] 43-43: src/components/ProfileCard/ProfileCard.tsx#L43
Added line #L43 was not covered by tests
🔇 Additional comments (9)
src/components/SignOut/SignOut.tsx (2)
1-8
: LGTM! Imports are well-organized and necessary.All required dependencies are properly imported.
1-54
: Address test coverage gaps.The static analysis indicates several uncovered code paths in the component.
🧰 Tools
🪛 GitHub Check: codecov/patch
[warning] 19-22: src/components/SignOut/SignOut.tsx#L19-L22
Added lines #L19 - L22 were not covered by tests
[warning] 24-28: src/components/SignOut/SignOut.tsx#L24-L28
Added lines #L24 - L28 were not covered by tests
[warning] 31-33: src/components/SignOut/SignOut.tsx#L31-L33
Added lines #L31 - L33 were not covered by tests
[warning] 35-35: src/components/SignOut/SignOut.tsx#L35
Added line #L35 was not covered by tests
[warning] 37-37: src/components/SignOut/SignOut.tsx#L37
Added line #L37 was not covered by tests
[warning] 40-40: src/components/SignOut/SignOut.tsx#L40
Added line #L40 was not covered by testssrc/components/ProfileCard/ProfileCard.spec.tsx (1)
1-191
: LGTM! Comprehensive test coverage.The test suite effectively covers:
- Component rendering
- User role handling
- Navigation logic
- Proper cleanup between tests
docs/docs/auto-docs/components/UserPortal/UserSidebarOrg/UserSidebarOrg/interfaces/InterfaceUserSidebarOrgProps.md (1)
7-39
: LGTM!The interface documentation is accurate and properly reflects the current code structure.
src/components/UserPortal/UserSidebarOrg/UserSidebarOrg.tsx (2)
14-17
: LGTM! Import changes look good.The changes to import styles from the global CSS module and adding new components follow best practices.
189-192
: LGTM! Footer components enhance user experience.The addition of ProfileCard and SignOut components in the footer improves the user interface by providing easy access to profile information and sign-out functionality.
src/style/app.module.css (3)
138-142
: LGTM! Well-organized CSS variables.The new CSS variables for the user sidebar follow the established naming convention and provide good flexibility for theme customization.
7920-7942
: LGTM! SignOut component styles are well-structured.The SignOut component styles are clean and follow the established patterns. The use of CSS variables for colors and spacing is good.
7848-7917
: 🛠️ Refactor suggestionConsolidate duplicate styles between UserSidebarOrg and ProfileCard.
There are duplicate styles between UserSidebarOrg and ProfileCard components. Consider creating shared classes.
+/* Shared styles */ +.sharedProfileContainer { + border: none; + padding: 2.1rem 0.5rem; + height: 52px; + border-radius: 8px; + display: flex; + align-items: center; + background-color: var(--tablerow-bg-color); +} +.sharedImageContainer { + width: 56px; + height: 56px; + border-radius: 100%; + margin-right: 10px; +} -/* Remove duplicate styles from both components and use shared classes */ .profileContainer { + composes: sharedProfileContainer; - border: none; - padding: 2.1rem 0.5rem; - /* ... */ } .imageContainer { + composes: sharedImageContainer; - width: 56px; - height: 56px; - /* ... */ }Likely invalid or redundant comment.
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
@coderabbitai full review |
✅ Actions performedFull review triggered. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 4
🔭 Outside diff range comments (1)
src/components/ProfileDropdown/ProfileDropdown.tsx (1)
Line range hint
41-52
: Improve error handling in logout function.The current error handling only logs to console. Consider:
- Showing a user-friendly error message
- Implementing retry logic for token revocation
- Handling errors during localStorage.clear()
const logout = async (): Promise<void> => { + const MAX_RETRIES = 3; + let retries = 0; try { - await revokeRefreshToken(); + while (retries < MAX_RETRIES) { + try { + await revokeRefreshToken(); + break; + } catch (error) { + retries++; + if (retries === MAX_RETRIES) throw error; + await new Promise(resolve => setTimeout(resolve, 1000 * retries)); + } + } } catch (error) { console.error('Error revoking refresh token:', error); + // Show user-friendly error message + // You can use your preferred notification system here } - localStorage.clear(); + try { + localStorage.clear(); + } catch (error) { + console.error('Error clearing local storage:', error); + } endSession(); navigate('/'); };
♻️ Duplicate comments (1)
src/style/app.module.css (1)
7427-7747
: 🛠️ Refactor suggestionConsolidate duplicate styles between UserSidebarOrg and ProfileCard components.
The
.profileContainer
and related styles are duplicated between UserSidebarOrg and ProfileCard components. Consider consolidating these into shared classes to improve maintainability.Apply this diff to create shared classes:
// Create shared classes +.sharedProfileContainer { + border: none; + padding: 2.1rem 0.5rem; + height: 52px; + border-radius: 8px; + display: flex; + align-items: center; + background-color: var(--tablerow-bg-color); +} +.sharedProfileText { + flex: 1; + text-align: start; + overflow: hidden; +} +.sharedPrimaryText { + font-size: 1rem; + font-weight: 600; + overflow: hidden; + display: -webkit-box; + -webkit-line-clamp: 2; + -webkit-box-orient: vertical; + word-wrap: break-word; + white-space: normal; } +.sharedSecondaryText { + font-size: 0.8rem; + font-weight: 400; + color: var(--bs-secondary); + display: block; + text-transform: capitalize; } // Use composition in both components -.profileContainer { +.profileContainer { + composes: sharedProfileContainer; /* Component specific overrides only */ } -.profileText { +.profileText { + composes: sharedProfileText; /* Component specific overrides only */ } -.primaryText { +.primaryText { + composes: sharedPrimaryText; /* Component specific overrides only */ } -.secondaryText { +.secondaryText { + composes: sharedSecondaryText; /* Component specific overrides only */ }
🧹 Nitpick comments (12)
src/components/SignOut/SignOut.tsx (2)
24-39
: Consider using a more robust error handling approach.The current implementation continues with sign-out even if token revocation fails. While this ensures users can sign out, it might leave orphaned tokens.
Consider this enhanced implementation:
const logout = async (): Promise<void> => { const handleSignOut = (): void => { localStorage.clear(); endSession(); navigate('/'); }; try { await revokeRefreshToken(); handleSignOut(); } catch (error) { - console.error('Error revoking refresh token:', error); - // Still sign out the user locally even if token revocation fails + // Log the error with more context + console.error('Error revoking refresh token. Proceeding with local sign-out:', { + error, + timestamp: new Date().toISOString(), + }); + // Consider showing a user-friendly notification + // Still proceed with sign-out for better UX handleSignOut(); } };🧰 Tools
🪛 GitHub Check: codecov/patch
[warning] 24-28: src/components/SignOut/SignOut.tsx#L24-L28
Added lines #L24 - L28 were not covered by tests
[warning] 31-33: src/components/SignOut/SignOut.tsx#L31-L33
Added lines #L31 - L33 were not covered by tests
[warning] 35-35: src/components/SignOut/SignOut.tsx#L35
Added line #L35 was not covered by tests
[warning] 37-37: src/components/SignOut/SignOut.tsx#L37
Added line #L37 was not covered by tests
41-50
: Add loading state during sign-out process.The button should indicate when the sign-out process is in progress.
Consider this enhancement:
+const [isLoading, setIsLoading] = useState(false); const logout = async (): Promise<void> => { + setIsLoading(true); try { // ... existing code ... } catch (error) { // ... existing code ... + } finally { + setIsLoading(false); } }; return ( <div className={styles.signOutContainer}> <LogoutIcon /> <button className={styles.signOutButton} onClick={logout} aria-label="Sign out" + disabled={isLoading} > - Sign Out + {isLoading ? 'Signing out...' : 'Sign Out'} </button> </div> );src/components/ProfileCard/ProfileCard.tsx (2)
21-34
: Consider moving user role logic to a custom hook.The user role determination logic could be reused across components.
Extract the logic to a custom hook:
+// In hooks/useUserRole.ts +const useUserRole = () => { + const { getItem } = useLocalStorage(); + const superAdmin = getItem('SuperAdmin'); + const adminFor = getItem('AdminFor'); + + return superAdmin + ? 'SuperAdmin' + : adminFor?.length > 0 + ? 'Admin' + : 'User'; +}; // In ProfileCard.tsx -const superAdmin = getItem('SuperAdmin'); -const adminFor = getItem('AdminFor'); -const userRole = superAdmin - ? 'SuperAdmin' - : adminFor?.length > 0 - ? 'Admin' - : 'User'; +const userRole = useUserRole();🧰 Tools
🪛 GitHub Check: codecov/patch
[warning] 21-24: src/components/ProfileCard/ProfileCard.tsx#L21-L24
Added lines #L21 - L24 were not covered by tests
[warning] 30-34: src/components/ProfileCard/ProfileCard.tsx#L30-L34
Added lines #L30 - L34 were not covered by tests
36-41
: Consider using a utility function for name truncation.The name truncation logic could be reused across components.
Extract the logic to a utility function:
+// In utils/string.ts +export const truncateText = (text: string, maxLength: number): string => { + return text.length > maxLength + ? text.substring(0, maxLength - 3) + '...' + : text; +}; // In ProfileCard.tsx -const MAX_NAME_LENGTH = 20; -const fullName = `${firstName} ${lastName}`; -const displayedName = - fullName.length > MAX_NAME_LENGTH - ? fullName.substring(0, MAX_NAME_LENGTH - 3) + '...' - : fullName; +const fullName = `${firstName} ${lastName}`; +const displayedName = truncateText(fullName, 20);🧰 Tools
🪛 GitHub Check: codecov/patch
[warning] 36-37: src/components/ProfileCard/ProfileCard.tsx#L36-L37
Added lines #L36 - L37 were not covered by testssrc/components/UserPortal/UserSidebarOrg/UserSidebarOrg.tsx (1)
171-171
: Use CSS variables for consistent theming.Direct hex color values should be replaced with CSS variables for better maintainability.
-isActive === true ? '#000000' : 'var(--bs-secondary)' +isActive === true ? 'var(--primary-text)' : 'var(--bs-secondary)'docs/docs/auto-docs/components/ProfileCard/ProfileCard/functions/default.md (1)
11-18
: Consider enhancing documentation with props/parameters section.While the documentation clearly describes the component's functionality, consider adding a Parameters section if the component accepts any props, especially since it handles user data and images.
src/components/SignOut/SignOut.spec.tsx (1)
81-126
: Consider adding more error scenarios.While the error handling test is good, consider adding tests for:
- Network timeout scenarios
- Server returning different error responses
- Cases where localStorage.clear() fails
Example test case:
test('handles localStorage.clear failure', async () => { const mockLocalStorage = { clear: vi.fn().mockImplementation(() => { throw new Error('Storage quota exceeded'); }), }; Object.defineProperty(window, 'localStorage', { value: mockLocalStorage, }); // ... rest of the test implementation });src/components/ProfileDropdown/ProfileDropdown.tsx (1)
Line range hint
60-107
: Enhance accessibility for profile section.Consider adding ARIA labels and roles to improve accessibility:
- <div className={styles.profileContainer}> + <div className={styles.profileContainer} role="presentation"> - <div className={styles.imageContainer}> + <div className={styles.imageContainer} role="img" aria-label={`${firstName} ${lastName}'s profile picture`}>src/components/ProfileCard/ProfileCard.spec.tsx (4)
27-51
: Consider removing unnecessary mock delay.The GraphQL mock for
GET_COMMUNITY_SESSION_TIMEOUT_DATA
includes a 1-second delay which could slow down the test suite unnecessarily. Unless this delay is specifically required for testing async behavior, consider removing it.{ request: { query: GET_COMMUNITY_SESSION_TIMEOUT_DATA, }, result: { data: { getCommunityData: { timeout: 30, }, }, }, - delay: 1000, },
62-77
: Add TypeScript types for test data.Consider defining interfaces for the user data being stored in localStorage to improve type safety and maintainability.
interface UserTestData { FirstName: string; LastName: string; UserImage: string; SuperAdmin: boolean; AdminFor: string[]; id: string; } const defaultUserData: UserTestData = { FirstName: 'John', LastName: 'Doe', UserImage: 'https://api.dicebear.com/5.x/initials/svg?seed=John%20Doe', SuperAdmin: false, AdminFor: [], id: '123' }; beforeEach(() => { Object.entries(defaultUserData).forEach(([key, value]) => { setItem(key, value); }); });
79-120
: Enhance test coverage with additional scenarios.Consider adding the following test cases to improve coverage:
- Error state when user data is missing or invalid
- Loading state during GraphQL operations
- Edge cases for user roles (e.g., user is both SuperAdmin and in AdminFor)
- Image loading fallback behavior
Example test case:
test('renders fallback when user image fails to load', async () => { setItem('UserImage', 'invalid-url'); render( <MockedProvider mocks={MOCKS} addTypename={false}> <BrowserRouter> <ProfileCard /> </BrowserRouter> </MockedProvider> ); const img = screen.getByAltText('profile picture'); fireEvent.error(img); expect(screen.getByTestId('avatar-fallback')).toBeInTheDocument(); });
122-191
: Strengthen route testing implementation.The current routing tests could be improved in several ways:
- Add error handling tests for invalid routes
- Test navigation with query parameters
- Verify URL encoding/decoding
- Clean up route state after each test
Add cleanup in afterEach:
afterEach(() => { vi.clearAllMocks(); localStorage.clear(); + window.history.pushState({}, '', '/'); });
Add test for query parameters:
test('handles routes with query parameters correctly', async () => { window.history.pushState({}, 'Test page', '/321?tab=settings'); setItem('SuperAdmin', true); setItem('id', '123'); render( <MockedProvider mocks={MOCKS} addTypename={false}> <BrowserRouter> <Routes> <Route path="/:orgId" element={<ProfileCard />} /> </Routes> </BrowserRouter> </MockedProvider> ); await act(async () => { userEvent.click(screen.getByTestId('profileBtn')); }); expect(mockNavigate).toHaveBeenCalledWith('/member/321?tab=settings'); });
📜 Review details
Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (12)
docs/docs/auto-docs/components/ProfileCard/ProfileCard/functions/default.md
(1 hunks)docs/docs/auto-docs/components/SignOut/SignOut/functions/default.md
(1 hunks)docs/docs/auto-docs/components/UserPortal/UserSidebarOrg/UserSidebarOrg/functions/default.md
(1 hunks)docs/docs/auto-docs/components/UserPortal/UserSidebarOrg/UserSidebarOrg/interfaces/InterfaceUserSidebarOrgProps.md
(1 hunks)src/components/ProfileCard/ProfileCard.spec.tsx
(1 hunks)src/components/ProfileCard/ProfileCard.tsx
(1 hunks)src/components/ProfileDropdown/ProfileDropdown.tsx
(1 hunks)src/components/SignOut/SignOut.spec.tsx
(1 hunks)src/components/SignOut/SignOut.tsx
(1 hunks)src/components/UserPortal/UserSidebarOrg/UserSidebarOrg.module.css
(0 hunks)src/components/UserPortal/UserSidebarOrg/UserSidebarOrg.tsx
(4 hunks)src/style/app.module.css
(4 hunks)
💤 Files with no reviewable changes (1)
- src/components/UserPortal/UserSidebarOrg/UserSidebarOrg.module.css
🧰 Additional context used
🪛 LanguageTool
docs/docs/auto-docs/components/SignOut/SignOut/functions/default.md
[uncategorized] ~11-~11: When ‘sign-out’ is used as a noun or modifier, it needs to be hyphenated.
Context: ...nts/SignOut/SignOut.tsx#L20) Renders a sign out button. This component helps to logout...
(VERB_NOUN_CONFUSION)
[misspelling] ~13-~13: Did you mean the verb “log out” instead of the noun ‘logout’?
Context: ...gn out button. This component helps to logout. The logout function revokes the refres...
(LOG_IN)
🪛 GitHub Check: codecov/patch
src/components/SignOut/SignOut.tsx
[warning] 19-22: src/components/SignOut/SignOut.tsx#L19-L22
Added lines #L19 - L22 were not covered by tests
[warning] 24-28: src/components/SignOut/SignOut.tsx#L24-L28
Added lines #L24 - L28 were not covered by tests
[warning] 31-33: src/components/SignOut/SignOut.tsx#L31-L33
Added lines #L31 - L33 were not covered by tests
[warning] 35-35: src/components/SignOut/SignOut.tsx#L35
Added line #L35 was not covered by tests
[warning] 37-37: src/components/SignOut/SignOut.tsx#L37
Added line #L37 was not covered by tests
[warning] 40-40: src/components/SignOut/SignOut.tsx#L40
Added line #L40 was not covered by tests
src/components/ProfileCard/ProfileCard.tsx
[warning] 21-24: src/components/ProfileCard/ProfileCard.tsx#L21-L24
Added lines #L21 - L24 were not covered by tests
[warning] 30-34: src/components/ProfileCard/ProfileCard.tsx#L30-L34
Added lines #L30 - L34 were not covered by tests
[warning] 36-37: src/components/ProfileCard/ProfileCard.tsx#L36-L37
Added lines #L36 - L37 were not covered by tests
[warning] 43-43: src/components/ProfileCard/ProfileCard.tsx#L43
Added line #L43 was not covered by tests
🔇 Additional comments (11)
src/components/SignOut/SignOut.tsx (2)
1-8
: LGTM! Clean imports and good organization.The imports are well-organized and properly scoped.
1-54
: Add unit tests for the SignOut component.The static analysis indicates missing test coverage for this component.
Let's verify if there are any existing tests:
Please add tests to cover:
- Successful sign-out flow
- Error handling during token revocation
- Loading state
- Navigation after sign-out
Would you like me to help generate the test suite for this component?
🧰 Tools
🪛 GitHub Check: codecov/patch
[warning] 19-22: src/components/SignOut/SignOut.tsx#L19-L22
Added lines #L19 - L22 were not covered by tests
[warning] 24-28: src/components/SignOut/SignOut.tsx#L24-L28
Added lines #L24 - L28 were not covered by tests
[warning] 31-33: src/components/SignOut/SignOut.tsx#L31-L33
Added lines #L31 - L33 were not covered by tests
[warning] 35-35: src/components/SignOut/SignOut.tsx#L35
Added line #L35 was not covered by tests
[warning] 37-37: src/components/SignOut/SignOut.tsx#L37
Added line #L37 was not covered by tests
[warning] 40-40: src/components/SignOut/SignOut.tsx#L40
Added line #L40 was not covered by testssrc/components/UserPortal/UserSidebarOrg/UserSidebarOrg.tsx (2)
14-17
: LGTM! Clean imports for new components.The new imports are properly organized.
189-192
: LGTM! Good component composition.The footer section is well-organized with the new ProfileCard and SignOut components.
docs/docs/auto-docs/components/UserPortal/UserSidebarOrg/UserSidebarOrg/functions/default.md (1)
9-9
: LGTM! Documentation accurately reflects the updated line number.The documentation provides clear and comprehensive information about the component's purpose and features.
docs/docs/auto-docs/components/UserPortal/UserSidebarOrg/UserSidebarOrg/interfaces/InterfaceUserSidebarOrgProps.md (1)
7-39
: LGTM! Interface documentation is properly updated.The line number updates are consistent with the code changes, and all properties are well-documented with their respective types.
src/components/SignOut/SignOut.spec.tsx (1)
49-79
: LGTM! Comprehensive test coverage for successful sign-out flow.The test properly verifies the complete sign-out flow including token revocation, local storage clearing, and navigation.
src/components/ProfileCard/ProfileCard.spec.tsx (1)
1-191
: Overall implementation looks good!The test suite is well-structured with good coverage of the main functionality. The suggested improvements would further enhance the robustness and maintainability of the tests, but the current implementation is solid.
src/style/app.module.css (3)
138-142
: LGTM! Well-structured CSS variables.The new CSS variables follow consistent naming conventions and provide clear semantic meaning for their intended usage.
7928-7950
: LGTM! Well-structured SignOut component styles.The styles follow consistent naming conventions and BEM-like methodology, making them maintainable and scalable.
4073-4076
:⚠️ Potential issueFix the standalone font-weight declaration.
The font-weight property is declared without a selector, which could cause unintended inheritance issues.
Apply this diff to fix the issue:
- font-weight: 500; +.leftDrawer .optionList button:active, +.leftDrawer .optionList button:focus { + font-weight: 500; +}Likely invalid or redundant comment.
docs/docs/auto-docs/components/SignOut/SignOut/functions/default.md
Outdated
Show resolved
Hide resolved
…lt.md Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🧹 Nitpick comments (1)
src/components/ProfileCard/ProfileCard.tsx (1)
75-86
: Simplify the navigation logic.The conditional navigation logic can be simplified by using a ternary operator or by extracting the path determination into a separate function for better readability.
+ const getNavigationPath = (role: string): string => { + return role === 'User' ? '/user/settings' : `/member/${orgId || ''}`; + }; + <button className={styles.chevronRightbtn} data-testid="profileBtn" - onClick={() => - userRole === 'User' - ? navigate(`/user/settings`) - : navigate(`/member/${orgId || ''}`) - } + onClick={() => navigate(getNavigationPath(userRole))} >
📜 Review details
Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (4)
docs/docs/auto-docs/components/SignOut/SignOut/functions/default.md
(1 hunks)src/components/ProfileCard/ProfileCard.spec.tsx
(1 hunks)src/components/ProfileCard/ProfileCard.tsx
(1 hunks)src/components/UserPortal/UserSidebarOrg/UserSidebarOrg.tsx
(4 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
- docs/docs/auto-docs/components/SignOut/SignOut/functions/default.md
- src/components/UserPortal/UserSidebarOrg/UserSidebarOrg.tsx
- src/components/ProfileCard/ProfileCard.spec.tsx
⏰ Context from checks skipped due to timeout of 90000ms (1)
- GitHub Check: Test Application
🔇 Additional comments (4)
src/components/ProfileCard/ProfileCard.tsx (4)
1-20
: Well-structured imports and comprehensive documentation!The imports are properly organized, and the JSDoc documentation clearly explains the component's purpose and behavior.
36-41
: Clean and efficient name formatting logic!Good use of constants and clear implementation of name truncation.
47-65
: Enhance error handling for invalid image URLs.The current error handling only hides the invalid image but doesn't switch to the avatar component as a fallback.
52-56
: Verify test coverage for image error handling.According to the codecov report, the image error handling code is not covered by tests. Please add test cases to verify this functionality.
// Add to your test file: test('should handle image loading error correctly', () => { render(<ProfileCard />); const img = screen.getByTestId('display-img'); fireEvent.error(img); expect(img.style.display).toBe('none'); });✅ Verification successful
Test coverage missing for ProfileCard component
The verification confirms that there are no test files for the ProfileCard component, including the image error handling functionality. The original review comment is valid and the suggested test case should be implemented.
- Create a new test file for ProfileCard component (e.g.,
src/components/ProfileCard/ProfileCard.test.tsx
)- Implement the suggested test case for image error handling
🏁 Scripts executed
The following scripts were executed for the analysis:
Error: No shell scripts found
Script:
#!/bin/bash # Find test files related to ProfileCard echo "=== Looking for ProfileCard test files ===" fd "ProfileCard.*test.*" || fd "ProfileCard.*spec.*" # Search for existing image error handling tests echo -e "\n=== Searching for image error tests ===" rg -l "test.*image.*error" || rg -l "test.*onError" # Check for coverage configuration echo -e "\n=== Looking for coverage configuration ===" fd "jest.config" || fd "vitest.config" || fd "coverage"Length of output: 435
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
@coderabbitai full review |
✅ Actions performedFull review triggered. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 3
🔭 Outside diff range comments (2)
src/components/ProfileDropdown/ProfileDropdown.tsx (2)
Line range hint
41-59
: Add debounce to prevent multiple rapid logout attempts.The logout function should be protected against multiple rapid clicks to prevent race conditions.
+import { debounce } from 'lodash'; - const logout = async (): Promise<void> => { + const logout = debounce(async (): Promise<void> => { try { await revokeRefreshToken(); } catch (error) { console.error('Error revoking refresh token:', error); } localStorage.clear(); endSession(); navigate('/'); - }; + }, 1000, { leading: true, trailing: false });
Line range hint
41-59
: Improve error handling in the logout function.The current error handling could be more robust and informative to users.
const logout = async (): Promise<void> => { try { await revokeRefreshToken(); + localStorage.clear(); + endSession(); + navigate('/'); } catch (error) { - console.error('Error revoking refresh token:', error); + // Still proceed with logout even if token revocation fails + console.error('Error during logout:', error); + localStorage.clear(); + endSession(); + navigate('/'); } - localStorage.clear(); - endSession(); - navigate('/'); };
♻️ Duplicate comments (2)
src/components/ProfileCard/ProfileCard.spec.tsx (1)
7-7
:⚠️ Potential issueFix GraphQL import path casing.
The import paths for GraphQL files use inconsistent casing which could cause issues on case-sensitive filesystems.
-import { REVOKE_REFRESH_TOKEN } from 'GraphQl/Mutations/mutations'; -import { GET_COMMUNITY_SESSION_TIMEOUT_DATA } from 'GraphQl/Queries/Queries'; +import { REVOKE_REFRESH_TOKEN } from 'graphql/mutations/mutations'; +import { GET_COMMUNITY_SESSION_TIMEOUT_DATA } from 'graphql/queries/queries';Also applies to: 11-11
src/style/app.module.css (1)
7427-7747
: 🛠️ Refactor suggestionConsolidate duplicate styles between UserSidebarOrg and ProfileCard components.
The
.profileContainer
and related styles are duplicated between UserSidebarOrg and ProfileCard components. Consider consolidating these into a shared class.Apply this diff to consolidate the duplicate styles:
// Create a shared class +.sharedProfileContainer { + border: none; + padding: 2.1rem 0.5rem; + height: 52px; + border-radius: 8px; + display: flex; + align-items: center; + background-color: var(--tablerow-bg-color); +} // Use composition in both components -.profileContainer { +.profileContainer extends .sharedProfileContainer { - border: none; - padding: 2.1rem 0.5rem; - height: 52px; - border-radius: 8px; - display: flex; - align-items: center; - background-color: var(--tablerow-bg-color); /* Component specific overrides only */ }
🧹 Nitpick comments (9)
src/components/SignOut/SignOut.tsx (1)
41-50
: Improve accessibility of the sign-out button.The button should have a more descriptive aria-label and include a tooltip for better user experience.
<div className={styles.signOutContainer}> <LogoutIcon /> <button className={styles.signOutButton} onClick={logout} - aria-label="Sign out" + aria-label="Sign out from application" + title="Click to sign out from the application" > Sign Out </button> </div>src/components/ProfileCard/ProfileCard.tsx (1)
75-85
: Improve button accessibility and keyboard navigation.The profile navigation button needs better accessibility attributes.
<button className={styles.chevronRightbtn} data-testid="profileBtn" + aria-label={`View ${displayedName}'s profile`} + title={`View ${displayedName}'s profile`} onClick={() => userRole === 'User' ? navigate(`/user/settings`) : navigate(`/member/${orgId || ''}`) } > <ChevronRightIcon className={styles.chevronIcon} /> </button>src/components/UserPortal/UserSidebarOrg/UserSidebarOrg.tsx (2)
189-192
: Consider adding a divider between ProfileCard and SignOut.The footer components should be visually separated for better UX.
<div className={styles.userSidebarOrgFooter}> <ProfileCard /> + <hr className={styles.footerDivider} /> <SignOut /> </div>
171-171
: Use CSS variables for consistent color management.Hard-coded color values should be replaced with CSS variables for better maintainability.
-isActive === true ? '#000000' : 'var(--bs-secondary)' +isActive === true ? 'var(--active-icon-color)' : 'var(--bs-secondary)'docs/docs/auto-docs/components/ProfileCard/ProfileCard/functions/default.md (1)
11-18
: Consider adding parameter documentation.While the documentation clearly describes the component's functionality, it would be beneficial to document any props or parameters the component accepts, even if there are none.
Add a Parameters section to explicitly state whether the component accepts any props:
and their role (SuperAdmin, Admin, or User). It provides options to view the profile. - If a user image is available, it displays that; otherwise, it shows an avatar. - The displayed name is truncated if it exceeds a specified length. +## Parameters + +None + ## Returnssrc/components/SignOut/SignOut.spec.tsx (1)
81-126
: Consider adding more edge cases to error handling tests.While the error case is well tested, consider adding tests for:
- Network timeout scenarios
- Multiple consecutive sign-out attempts
- Cases where localStorage.clear() fails
Example test case:
test('handles multiple sign-out attempts', async () => { const mockEndSession = vi.fn(); (useSession as jest.Mock).mockReturnValue({ endSession: mockEndSession, }); render( <MockedProvider mocks={[mockRevokeRefreshToken]} addTypename={false}> <BrowserRouter> <SignOut /> </BrowserRouter> </MockedProvider>, ); const signOutButton = screen.getByText('Sign Out'); // Click multiple times in quick succession fireEvent.click(signOutButton); fireEvent.click(signOutButton); await waitFor(() => { // Verify that the logout flow is only executed once expect(mockEndSession).toHaveBeenCalledTimes(1); expect(mockNavigate).toHaveBeenCalledTimes(1); }); });src/components/ProfileDropdown/ProfileDropdown.tsx (2)
60-60
: Consider using a styled component or CSS-in-JS solution.Using inline styles for the dropdown toggle could make maintenance more difficult. Consider moving these styles to a CSS module or styled component.
-<Dropdown.Toggle - split - variant="none" - style={{ backgroundColor: 'white' }} - data-testid="togDrop" - id="dropdown-split-basic" - className={styles.dropdownToggle} - aria-label="User Profile Menu" -/> +<Dropdown.Toggle + split + variant="none" + data-testid="togDrop" + id="dropdown-split-basic" + className={`${styles.dropdownToggle} ${styles.whiteBackground}`} + aria-label="User Profile Menu" +/>
Line range hint
52-52
: Extract MAX_NAME_LENGTH as a constant at module level.Magic numbers should be defined as named constants at the module level for better maintainability.
+const MAX_NAME_LENGTH = 20; + const profileDropdown = (): JSX.Element => { // ... existing code ... - const MAX_NAME_LENGTH = 20; const fullName = `${firstName} ${lastName}`;src/components/ProfileCard/ProfileCard.spec.tsx (1)
49-49
: Consider removing or reducing the GraphQL mock delay.The 1-second delay in the GraphQL mock could make tests slower and potentially flaky. Consider removing it or reducing it unless it's specifically needed to test loading states.
📜 Review details
Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (12)
docs/docs/auto-docs/components/ProfileCard/ProfileCard/functions/default.md
(1 hunks)docs/docs/auto-docs/components/SignOut/SignOut/functions/default.md
(1 hunks)docs/docs/auto-docs/components/UserPortal/UserSidebarOrg/UserSidebarOrg/functions/default.md
(1 hunks)docs/docs/auto-docs/components/UserPortal/UserSidebarOrg/UserSidebarOrg/interfaces/InterfaceUserSidebarOrgProps.md
(1 hunks)src/components/ProfileCard/ProfileCard.spec.tsx
(1 hunks)src/components/ProfileCard/ProfileCard.tsx
(1 hunks)src/components/ProfileDropdown/ProfileDropdown.tsx
(1 hunks)src/components/SignOut/SignOut.spec.tsx
(1 hunks)src/components/SignOut/SignOut.tsx
(1 hunks)src/components/UserPortal/UserSidebarOrg/UserSidebarOrg.module.css
(0 hunks)src/components/UserPortal/UserSidebarOrg/UserSidebarOrg.tsx
(4 hunks)src/style/app.module.css
(4 hunks)
💤 Files with no reviewable changes (1)
- src/components/UserPortal/UserSidebarOrg/UserSidebarOrg.module.css
🧰 Additional context used
🪛 GitHub Check: codecov/patch
src/components/SignOut/SignOut.tsx
[warning] 19-22: src/components/SignOut/SignOut.tsx#L19-L22
Added lines #L19 - L22 were not covered by tests
[warning] 24-28: src/components/SignOut/SignOut.tsx#L24-L28
Added lines #L24 - L28 were not covered by tests
[warning] 31-33: src/components/SignOut/SignOut.tsx#L31-L33
Added lines #L31 - L33 were not covered by tests
[warning] 35-35: src/components/SignOut/SignOut.tsx#L35
Added line #L35 was not covered by tests
[warning] 37-37: src/components/SignOut/SignOut.tsx#L37
Added line #L37 was not covered by tests
[warning] 40-40: src/components/SignOut/SignOut.tsx#L40
Added line #L40 was not covered by tests
src/components/ProfileCard/ProfileCard.tsx
[warning] 21-24: src/components/ProfileCard/ProfileCard.tsx#L21-L24
Added lines #L21 - L24 were not covered by tests
[warning] 30-34: src/components/ProfileCard/ProfileCard.tsx#L30-L34
Added lines #L30 - L34 were not covered by tests
[warning] 36-37: src/components/ProfileCard/ProfileCard.tsx#L36-L37
Added lines #L36 - L37 were not covered by tests
[warning] 43-43: src/components/ProfileCard/ProfileCard.tsx#L43
Added line #L43 was not covered by tests
[warning] 53-54: src/components/ProfileCard/ProfileCard.tsx#L53-L54
Added lines #L53 - L54 were not covered by tests
🔇 Additional comments (11)
src/components/SignOut/SignOut.tsx (1)
1-7
: Add test coverage for the SignOut component.The static analysis indicates missing test coverage for critical functionality.
src/components/ProfileCard/ProfileCard.tsx (2)
21-35
: Add type safety for localStorage values.The current implementation assumes localStorage values will always be present and correctly formatted.
🧰 Tools
🪛 GitHub Check: codecov/patch
[warning] 21-24: src/components/ProfileCard/ProfileCard.tsx#L21-L24
Added lines #L21 - L24 were not covered by tests
[warning] 30-34: src/components/ProfileCard/ProfileCard.tsx#L30-L34
Added lines #L30 - L34 were not covered by tests
47-65
: 🛠️ Refactor suggestionEnhance image error handling with fallback state.
The current error handling only hides the image. Consider maintaining a state to properly trigger the Avatar fallback.
+const [imageError, setImageError] = useState(false); -{userImage && userImage !== 'null' ? ( +{userImage && userImage !== 'null' && !imageError ? ( <img src={userImage} alt={`profile picture`} data-testid="display-img" onError={(e) => { - e.currentTarget.onerror = null; - e.currentTarget.style.display = 'none'; + setImageError(true); }} /> ) : ( <Avatar data-testid="display-img" size={45} avatarStyle={styles.avatarStyle} name={`${firstName} ${lastName}`} alt={`dummy picture`} /> )}Likely invalid or redundant comment.
🧰 Tools
🪛 GitHub Check: codecov/patch
[warning] 53-54: src/components/ProfileCard/ProfileCard.tsx#L53-L54
Added lines #L53 - L54 were not covered by testsdocs/docs/auto-docs/components/SignOut/SignOut/functions/default.md (1)
1-20
: Documentation looks good!The documentation is clear, concise, and correctly describes the component's functionality.
docs/docs/auto-docs/components/UserPortal/UserSidebarOrg/UserSidebarOrg/functions/default.md (1)
9-9
: LGTM! Documentation accurately reflects the updated line number.The documentation is well-structured and provides clear information about the component's purpose and features.
docs/docs/auto-docs/components/UserPortal/UserSidebarOrg/UserSidebarOrg/interfaces/InterfaceUserSidebarOrgProps.md (1)
7-39
: LGTM! Documentation accurately reflects the updated line numbers.The interface properties are well documented with clear line references.
src/components/SignOut/SignOut.spec.tsx (1)
49-79
: LGTM! Comprehensive test coverage for the happy path.The test properly verifies the sign-out flow, including token revocation, local storage clearing, and navigation.
src/components/ProfileCard/ProfileCard.spec.tsx (1)
83-216
: Well-structured test coverage!The test suite provides comprehensive coverage of the ProfileCard component:
- Renders user information correctly
- Handles different user roles (User, Admin, SuperAdmin)
- Verifies navigation behavior for different scenarios
- Uses proper test isolation and cleanup
src/style/app.module.css (3)
138-142
: LGTM! New CSS variables for user sidebar organization drawer.The new CSS variables are well-organized and follow the existing naming convention:
--user-sidebar-org-option-bg
--user-sidebar-org-item-bg
--user-sidebar-org-bg
--sign-out-bg
--dropdown-toggle-bg
7928-7950
: LGTM! Sign out container styles.The sign out container styles are well-structured and use appropriate CSS variables for colors and spacing.
4073-4076
:⚠️ Potential issueFix the standalone font-weight declaration.
The font-weight property is declared without a selector, which could cause unintended inheritance issues.
Apply this diff to fix the issue:
- font-weight: 500; +.leftDrawer .optionList button:active, +.leftDrawer .optionList button:focus { + font-weight: 500; +}Likely invalid or redundant comment.
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
91e0df0
into
PalisadoesFoundation:develop-postgres
What kind of change does this PR introduce?
UI fix according to figma.
Issue Number:
Fixes #3198
Snapshots/Videos:
UserSidebarOrg1.mp4
Does this PR introduce a breaking change?
No
Checklist
CodeRabbit AI Review
Test Coverage
Have you read the contributing guide?
Yes
Summary by CodeRabbit
New Features
ProfileCard
component for displaying user profile information.SignOut
component to facilitate user logout functionality.Documentation
ProfileCard
,SignOut
, andUserSidebarOrg
components.Style Updates
Tests
ProfileCard
andSignOut
components to ensure proper functionality.