-
-
Notifications
You must be signed in to change notification settings - Fork 888
[FIX] Figma User Portal: Organization Left Drawer Violates The Figma Style Guide #3430
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
Merged
palisadoes
merged 33 commits into
PalisadoesFoundation:develop-postgres
from
hustlernik:issue#3198
Jan 26, 2025
Merged
Changes from 23 commits
Commits
Show all changes
33 commits
Select commit
Hold shift + click to select a range
d2ed676
UI fix UserSidebarOrg
hustlernik 07bb47a
ui fix userSidebarOrg
hustlernik fcffaf3
Merge branch 'develop-postgres' of https://github.com/hustlernik/tala…
hustlernik 2df1906
fix
hustlernik c7393a2
Update src/components/ProfileDropdown/ProfileDropdown.tsx
hustlernik e36c58c
Update src/components/ProfileDropdown/ProfileDropdown.tsx
hustlernik efbca19
Update src/components/ProfileCard/ProfileCard.spec.tsx
hustlernik bf348f2
Update src/components/SignOut/SignOut.tsx
hustlernik 6468283
Update src/components/ProfileCard/ProfileCard.spec.tsx
hustlernik 2d0994e
fix
hustlernik 6a39793
Merge branch 'issue#3198' of https://github.com/hustlernik/talawa-adm…
hustlernik 765cc2d
fix
hustlernik 2ff63a9
Merge branch 'develop-postgres' of https://github.com/hustlernik/tala…
hustlernik df9baed
fix lint
hustlernik 727d7fe
type fix
hustlernik 65f92e0
Update src/style/app.module.css
hustlernik 3590e8e
Update docs/docs/auto-docs/components/SignOut/SignOut/functions/defau…
hustlernik 4802df0
Update src/components/UserPortal/UserSidebarOrg/UserSidebarOrg.tsx
hustlernik 392417a
lint fix
hustlernik 250d0eb
Update src/components/ProfileCard/ProfileCard.tsx
hustlernik d90030c
fix
hustlernik 56be5cb
Merge branch 'issue#3198' of https://github.com/hustlernik/talawa-adm…
hustlernik 7876346
fix
hustlernik 26f371b
Update docs/docs/auto-docs/components/SignOut/SignOut/functions/defau…
hustlernik f2a6122
fix
hustlernik b9d45a2
Merge branch 'issue#3198' of https://github.com/hustlernik/talawa-adm…
hustlernik 8a3bbbb
Update src/components/ProfileCard/ProfileCard.tsx
hustlernik 59a4e06
fix
hustlernik 9cb5450
Update src/components/SignOut/SignOut.tsx
hustlernik b5662d7
Update src/components/ProfileCard/ProfileCard.spec.tsx
hustlernik bf3457a
fix
hustlernik addc576
Merge branch 'issue#3198' of https://github.com/hustlernik/talawa-adm…
hustlernik 962ca52
fix
hustlernik File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
23 changes: 23 additions & 0 deletions
23
docs/docs/auto-docs/components/ProfileCard/ProfileCard/functions/default.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
[Admin Docs](/) | ||
|
||
*** | ||
|
||
# Function: default() | ||
|
||
> **default**(): `Element` | ||
|
||
Defined in: [src/components/ProfileCard/ProfileCard.tsx:21](https://github.com/PalisadoesFoundation/talawa-admin/blob/main/src/components/ProfileCard/ProfileCard.tsx#L21) | ||
|
||
Renders a profile card for the user. | ||
|
||
This component displays the user's profile picture or an avatar, their name (truncated if necessary), | ||
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. | ||
|
||
## Returns | ||
|
||
`Element` | ||
|
||
JSX.Element - The profile card . |
20 changes: 20 additions & 0 deletions
20
docs/docs/auto-docs/components/SignOut/SignOut/functions/default.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
[Admin Docs](/) | ||
|
||
*** | ||
|
||
# Function: default() | ||
|
||
> **default**(): `Element` | ||
|
||
Defined in: [src/components/SignOut/SignOut.tsx:20](https://github.com/PalisadoesFoundation/talawa-admin/blob/main/src/components/SignOut/SignOut.tsx#L20) | ||
|
||
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. | ||
|
||
## Returns | ||
|
||
`Element` | ||
|
||
JSX.Element - The sign-out button. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,191 @@ | ||
import React, { act } from 'react'; | ||
import { render, screen } from '@testing-library/react'; | ||
import userEvent from '@testing-library/user-event'; | ||
import { BrowserRouter, Route, Routes } from 'react-router-dom'; | ||
import ProfileCard from './ProfileCard'; | ||
import { MockedProvider } from '@apollo/react-testing'; | ||
import { REVOKE_REFRESH_TOKEN } from 'GraphQl/Mutations/mutations'; | ||
hustlernik marked this conversation as resolved.
Show resolved
Hide resolved
|
||
import useLocalStorage from 'utils/useLocalstorage'; | ||
import { I18nextProvider } from 'react-i18next'; | ||
import i18nForTest from 'utils/i18nForTest'; | ||
import { GET_COMMUNITY_SESSION_TIMEOUT_DATA } from 'GraphQl/Queries/Queries'; | ||
import { vi } from 'vitest'; | ||
|
||
const { setItem } = useLocalStorage(); | ||
|
||
const mockNavigate = vi.fn(); | ||
|
||
// Mock useNavigate hook | ||
vi.mock('react-router-dom', async () => { | ||
const actual = await vi.importActual('react-router-dom'); | ||
return { | ||
...actual, | ||
useNavigate: () => mockNavigate, | ||
}; | ||
}); | ||
|
||
const MOCKS = [ | ||
{ | ||
request: { | ||
query: REVOKE_REFRESH_TOKEN, | ||
}, | ||
result: { | ||
data: { | ||
revokeRefreshTokenForUser: true, | ||
}, | ||
}, | ||
}, | ||
{ | ||
request: { | ||
query: GET_COMMUNITY_SESSION_TIMEOUT_DATA, | ||
}, | ||
result: { | ||
data: { | ||
getCommunityData: { | ||
timeout: 30, | ||
}, | ||
}, | ||
}, | ||
delay: 1000, | ||
}, | ||
]; | ||
|
||
vi.mock('react-toastify', () => ({ | ||
toast: { | ||
success: vi.fn(), | ||
warn: vi.fn(), | ||
error: vi.fn(), | ||
}, | ||
clear: vi.fn(), | ||
})); | ||
|
||
beforeEach(() => { | ||
setItem('FirstName', 'John'); | ||
setItem('LastName', 'Doe'); | ||
setItem( | ||
'UserImage', | ||
'https://api.dicebear.com/5.x/initials/svg?seed=John%20Doe', | ||
); | ||
setItem('SuperAdmin', false); | ||
setItem('AdminFor', []); | ||
setItem('id', '123'); | ||
}); | ||
|
||
afterEach(() => { | ||
vi.clearAllMocks(); | ||
localStorage.clear(); | ||
}); | ||
|
||
describe('ProfileDropdown Component', () => { | ||
test('renders with user information', () => { | ||
render( | ||
<MockedProvider mocks={MOCKS} addTypename={false}> | ||
<BrowserRouter> | ||
<I18nextProvider i18n={i18nForTest}> | ||
<ProfileCard /> | ||
</I18nextProvider> | ||
</BrowserRouter> | ||
</MockedProvider>, | ||
); | ||
|
||
expect(screen.getByTestId('display-name')).toBeInTheDocument(); | ||
expect(screen.getByText('John Doe')).toBeInTheDocument(); | ||
expect(screen.getByText('User')).toBeInTheDocument(); | ||
expect(screen.getByTestId('display-type')).toBeInTheDocument(); | ||
expect(screen.getByAltText('profile picture')).toBeInTheDocument(); | ||
}); | ||
|
||
test('renders Super admin', () => { | ||
setItem('SuperAdmin', true); | ||
render( | ||
<MockedProvider mocks={MOCKS} addTypename={false}> | ||
<BrowserRouter> | ||
<ProfileCard /> | ||
</BrowserRouter> | ||
</MockedProvider>, | ||
); | ||
expect(screen.getByText('SuperAdmin')).toBeInTheDocument(); | ||
}); | ||
test('renders Admin', () => { | ||
setItem('AdminFor', ['123']); | ||
render( | ||
<MockedProvider mocks={MOCKS} addTypename={false}> | ||
<BrowserRouter> | ||
<ProfileCard /> | ||
</BrowserRouter> | ||
</MockedProvider>, | ||
); | ||
expect(screen.getByText('Admin')).toBeInTheDocument(); | ||
}); | ||
}); | ||
|
||
describe('Member screen routing testing', () => { | ||
test('navigates to /user/settings for a user', async () => { | ||
setItem('SuperAdmin', false); | ||
setItem('AdminFor', []); | ||
|
||
render( | ||
<MockedProvider mocks={MOCKS} addTypename={false}> | ||
<BrowserRouter> | ||
<I18nextProvider i18n={i18nForTest}> | ||
<ProfileCard /> | ||
</I18nextProvider> | ||
</BrowserRouter> | ||
</MockedProvider>, | ||
); | ||
|
||
await act(async () => { | ||
userEvent.click(screen.getByTestId('profileBtn')); | ||
}); | ||
|
||
expect(mockNavigate).toHaveBeenCalledWith('/user/settings'); | ||
}); | ||
|
||
test('navigates to /member/:orgId for non-user roles when orgId is not present', async () => { | ||
window.history.pushState({}, 'Test page', '/orglist'); | ||
setItem('SuperAdmin', true); // Set as admin | ||
setItem('id', '123'); | ||
|
||
render( | ||
<MockedProvider mocks={MOCKS} addTypename={false}> | ||
<BrowserRouter> | ||
<I18nextProvider i18n={i18nForTest}> | ||
<Routes> | ||
<Route path="/orglist" element={<ProfileCard />} /> | ||
</Routes> | ||
</I18nextProvider> | ||
</BrowserRouter> | ||
</MockedProvider>, | ||
); | ||
|
||
await act(async () => { | ||
userEvent.click(screen.getByTestId('profileBtn')); | ||
}); | ||
|
||
expect(mockNavigate).toHaveBeenCalledWith('/member/'); | ||
}); | ||
|
||
test('navigates to /member/:userID for non-user roles', async () => { | ||
window.history.pushState({}, 'Test page', '/321'); | ||
setItem('SuperAdmin', true); // Set as admin | ||
setItem('id', '123'); | ||
|
||
render( | ||
<MockedProvider mocks={MOCKS} addTypename={false}> | ||
<BrowserRouter> | ||
<I18nextProvider i18n={i18nForTest}> | ||
<Routes> | ||
<Route path="/:orgId" element={<ProfileCard />} /> | ||
</Routes> | ||
</I18nextProvider> | ||
</BrowserRouter> | ||
</MockedProvider>, | ||
); | ||
|
||
await act(async () => { | ||
userEvent.click(screen.getByTestId('profileBtn')); | ||
}); | ||
|
||
expect(mockNavigate).toHaveBeenCalledWith('/member/321'); | ||
}); | ||
}); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
import Avatar from 'components/Avatar/Avatar'; | ||
import React from 'react'; | ||
import { ButtonGroup, Dropdown } from 'react-bootstrap'; | ||
import { useNavigate, useParams } from 'react-router-dom'; | ||
import useLocalStorage from 'utils/useLocalstorage'; | ||
import styles from './../../style/app.module.css'; | ||
import ChevronRightIcon from '@mui/icons-material/ChevronRight'; | ||
|
||
/** | ||
* Renders a profile card for the user. | ||
* | ||
* This component displays the user's profile picture or an avatar, their name (truncated if necessary), | ||
* 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. | ||
|
||
* | ||
* @returns JSX.Element - The profile card . | ||
*/ | ||
const ProfileCard = (): JSX.Element => { | ||
const { getItem } = useLocalStorage(); | ||
const superAdmin = getItem('SuperAdmin'); | ||
const adminFor = getItem('AdminFor'); | ||
const userRole = superAdmin | ||
? 'SuperAdmin' | ||
: adminFor?.length > 0 | ||
? 'Admin' | ||
: 'User'; | ||
const firstName = getItem('FirstName'); | ||
const lastName = getItem('LastName'); | ||
const userImage = getItem('UserImage'); | ||
const navigate = useNavigate(); | ||
const { orgId } = useParams(); | ||
|
||
hustlernik marked this conversation as resolved.
Show resolved
Hide resolved
|
||
const MAX_NAME_LENGTH = 20; | ||
const fullName = `${firstName} ${lastName}`; | ||
const displayedName = | ||
fullName.length > MAX_NAME_LENGTH | ||
? fullName.substring(0, MAX_NAME_LENGTH - 3) + '...' | ||
: fullName; | ||
|
||
return ( | ||
<Dropdown as={ButtonGroup} variant="none"> | ||
<div className={styles.profileContainer}> | ||
<div className={styles.imageContainer}> | ||
{userImage && userImage !== 'null' ? ( | ||
<img | ||
src={userImage} | ||
alt={`profile picture`} | ||
data-testid="display-img" | ||
/> | ||
) : ( | ||
<Avatar | ||
data-testid="display-img" | ||
size={45} | ||
avatarStyle={styles.avatarStyle} | ||
name={`${firstName} ${lastName}`} | ||
alt={`dummy picture`} | ||
/> | ||
)} | ||
</div> | ||
hustlernik marked this conversation as resolved.
Show resolved
Hide resolved
|
||
<div className={styles.profileTextUserSidebarOrg}> | ||
<span className={styles.primaryText} data-testid="display-name"> | ||
{displayedName} | ||
</span> | ||
<span className={styles.secondaryText} data-testid="display-type"> | ||
{`${userRole}`} | ||
</span> | ||
</div> | ||
<button | ||
className={styles.chevronRightbtn} | ||
data-testid="profileBtn" | ||
onClick={() => | ||
userRole === 'User' | ||
? navigate(`/user/settings`) | ||
: navigate(`/member/${orgId || ''}`) | ||
} | ||
> | ||
<ChevronRightIcon className={styles.chevronIcon} /> | ||
</button> | ||
</div> | ||
</Dropdown> | ||
); | ||
}; | ||
|
||
export default ProfileCard; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.