-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #789 from newsrevenuehub/DEV-1968-avatar-settings-…
…menu-basic DEV-1968: Avatar Menu
- Loading branch information
Showing
21 changed files
with
486 additions
and
96 deletions.
There are no files selected for viewing
This file contains 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 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,11 @@ | ||
// Required to import .svg files to TS files | ||
declare module '*.svg' { | ||
const content: any; | ||
export default content; | ||
} | ||
|
||
// Required to import .png files to TS files | ||
declare module '*.png' { | ||
const content: any; | ||
export default content; | ||
} |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
40 changes: 40 additions & 0 deletions
40
spa/src/components/common/AvatarMenu/AvatarMenu.stories.js
This file contains 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,40 @@ | ||
import AvatarMenu from './AvatarMenu'; | ||
|
||
export default { | ||
title: 'Common/AvatarMenu', | ||
component: AvatarMenu | ||
}; | ||
|
||
export const Default = (props) => ( | ||
<div style={{ background: '#523A5E', display: 'flex', justifyContent: 'end' }}> | ||
<AvatarMenu {...props} /> | ||
</div> | ||
); | ||
|
||
Default.args = { | ||
user: { | ||
firstName: 'Gui', | ||
lastName: 'Mend', | ||
email: 'gm@gmail.com' | ||
} | ||
}; | ||
|
||
export const NoNameAvatar = (props) => ( | ||
<div style={{ background: '#523A5E', display: 'flex', justifyContent: 'end' }}> | ||
<AvatarMenu {...props} /> | ||
</div> | ||
); | ||
|
||
NoNameAvatar.args = { | ||
user: { | ||
email: 'gm@gmail.com' | ||
} | ||
}; | ||
|
||
export const EmptyAvatar = (props) => ( | ||
<div style={{ background: '#523A5E', display: 'flex', justifyContent: 'end' }}> | ||
<AvatarMenu {...props} /> | ||
</div> | ||
); | ||
|
||
EmptyAvatar.args = {}; |
110 changes: 110 additions & 0 deletions
110
spa/src/components/common/AvatarMenu/AvatarMenu.styled.ts
This file contains 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,110 @@ | ||
import { | ||
Avatar as MuiAvatar, | ||
Popover as MuiPopover, | ||
MenuItem as MuiMenuItem, | ||
Typography as MuiTypography, | ||
ListItemIcon as MuiListItemIcon | ||
} from '@material-ui/core'; | ||
import styled from 'styled-components'; | ||
|
||
export const Container = styled.button<{ open: string }>` | ||
display: flex; | ||
align-items: center; | ||
cursor: pointer; | ||
padding: 0; | ||
background: transparent; | ||
border: none; | ||
padding: 9px 0 9px 10px; | ||
max-height: 48px; | ||
svg { | ||
fill: white; | ||
height: 27px; | ||
width: 27px; | ||
margin-left: -3px; | ||
} | ||
${(props) => | ||
props.open === 'open' && | ||
`background-color: ${props.theme.colors.account.purple[1]}; | ||
`} | ||
:hover { | ||
background-color: ${(props) => props.theme.colors.account.purple[1]}; | ||
} | ||
`; | ||
|
||
export const ModalHeader = styled.p` | ||
font-size: ${(props) => props.theme.fontSizesUpdated.sm}; | ||
font-family: ${(props) => props.theme.systemFont}; | ||
color: ${(props) => props.theme.colors.muiGrey[700]}; | ||
font-weight: 600; | ||
margin: 0 0 9px; | ||
`; | ||
|
||
export const ListWrapper = styled.ul` | ||
padding: 0; | ||
margin: 0; | ||
`; | ||
|
||
export const ListItemIcon = styled(MuiListItemIcon)` | ||
&& { | ||
min-width: unset; | ||
color: ${(props) => props.theme.colors.sidebarBackground}; | ||
svg { | ||
width: 20px; | ||
height: 20px; | ||
} | ||
} | ||
`; | ||
|
||
export const LogoutIconWrapper = styled.img` | ||
width: 20px; | ||
height: 20px; | ||
`; | ||
|
||
export const Avatar = styled(MuiAvatar)` | ||
&& { | ||
height: 31px; | ||
width: 31px; | ||
border: 1px solid white; | ||
font-size: ${(props) => props.theme.fontSizesUpdated.sm}; | ||
background-color: ${(props) => props.theme.colors.muiLightBlue[800]}; | ||
} | ||
`; | ||
|
||
export const Popover = styled(MuiPopover)` | ||
.MuiPaper-rounded { | ||
min-width: 207px; | ||
box-shadow: none; | ||
padding: 12px 15px; | ||
border: 1px solid ${(props) => props.theme.colors.muiGrey[300]}; | ||
background-color: ${(props) => props.theme.colors.muiGrey[100]}; | ||
filter: drop-shadow(0px 2px 20px rgba(0, 0, 0, 0.1)); | ||
} | ||
`; | ||
|
||
export const Typography = styled(MuiTypography)` | ||
&& { | ||
color: ${(props) => props.theme.colors.sidebarBackground}; | ||
font-size: ${(props) => props.theme.fontSizesUpdated.sm}; | ||
font-weight: 400; | ||
} | ||
`; | ||
|
||
export const MenuItem = styled(MuiMenuItem)` | ||
&& { | ||
padding: 5px 7px; | ||
margin: 0 -7px; | ||
border-radius: ${(props) => props.theme.muiBorderRadius.lg}; | ||
background-color: ${(props) => props.theme.colors.muiGrey[100]}; | ||
display: flex; | ||
align-items: center; | ||
gap: 18px; | ||
:hover { | ||
background-color: ${(props) => props.theme.colors.navSectionLabelColor}; | ||
} | ||
} | ||
`; |
102 changes: 102 additions & 0 deletions
102
spa/src/components/common/AvatarMenu/AvatarMenu.test.tsx
This file contains 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,102 @@ | ||
import { axe } from 'jest-axe'; | ||
import { render, screen, within } from 'test-utils'; | ||
import userEvent from '@testing-library/user-event'; | ||
|
||
import { FAQ_URL } from 'constants/helperUrls'; | ||
import onLogout from 'components/authentication/logout'; | ||
import AvatarMenu, { AvatarMenuProps } from './AvatarMenu'; | ||
|
||
jest.mock('components/authentication/logout'); | ||
|
||
const tree = (props?: AvatarMenuProps) => { | ||
return render(<AvatarMenu {...props} />); | ||
}; | ||
|
||
const settingsMenu = 'Settings'; | ||
|
||
describe('AvatarMenu', () => { | ||
it('should be enabled if has user', () => { | ||
tree({ user: { email: 'a@a.com' } }); | ||
expect(screen.getByRole('button', { name: settingsMenu })).toBeEnabled(); | ||
}); | ||
|
||
it('should be disabled if user is undefined', () => { | ||
tree(); | ||
expect(screen.getByRole('button', { name: settingsMenu })).toBeEnabled(); | ||
}); | ||
|
||
it('should render name initials', () => { | ||
const nameUser = { | ||
firstName: 'first-mock', | ||
lastName: 'last-mock', | ||
email: 'email@mock.com' | ||
}; | ||
tree({ user: nameUser }); | ||
|
||
const avatar = screen.getByTestId('avatar'); | ||
const title = within(avatar).getByText('FL'); | ||
expect(title).toBeInTheDocument(); | ||
}); | ||
|
||
it('should render email initial if name is empty', () => { | ||
const emailUser = { | ||
email: 'email@mock.com' | ||
}; | ||
tree({ user: emailUser }); | ||
|
||
const avatar = screen.getByTestId('avatar'); | ||
expect(avatar.innerHTML).toBe('E'); | ||
const title = within(avatar).getByText('E'); | ||
expect(title).toBeInTheDocument(); | ||
}); | ||
|
||
it('should render nothing if user is undefined', () => { | ||
tree(); | ||
|
||
const avatar = screen.getByTestId('avatar'); | ||
expect(avatar.innerHTML).toBe(''); | ||
}); | ||
|
||
it('should open settings menu with correct buttons', () => { | ||
const emailUser = { | ||
email: 'email@mock.com' | ||
}; | ||
tree({ user: emailUser }); | ||
|
||
userEvent.click(screen.getByRole('button', { name: settingsMenu })); | ||
expect(screen.getByRole('menuitem', { name: 'FAQ' })).toBeEnabled(); | ||
expect(screen.getByRole('menuitem', { name: 'Sign out' })).toBeEnabled(); | ||
}); | ||
|
||
it('should have correct FAQ link', () => { | ||
const oldOpen = jest.spyOn(window, 'open').mockImplementation(); | ||
const emailUser = { | ||
email: 'email@mock.com' | ||
}; | ||
tree({ user: emailUser }); | ||
|
||
userEvent.click(screen.getByRole('button', { name: settingsMenu })); | ||
userEvent.click(screen.getByRole('menuitem', { name: 'FAQ' })); | ||
expect(oldOpen).toBeCalledWith(FAQ_URL, '_blank', 'noopener, noreferrer'); | ||
oldOpen.mockRestore(); | ||
}); | ||
|
||
it('should logout', () => { | ||
const emailUser = { | ||
email: 'email@mock.com' | ||
}; | ||
tree({ user: emailUser }); | ||
|
||
userEvent.click(screen.getByRole('button', { name: settingsMenu })); | ||
userEvent.click(screen.getByRole('menuitem', { name: 'Sign out' })); | ||
expect(onLogout).toBeCalledTimes(1); | ||
}); | ||
|
||
it('is accessible', async () => { | ||
const { container } = tree({ user: { email: 'a@a.com' } }); | ||
expect(await axe(container)).toHaveNoViolations(); | ||
|
||
userEvent.click(screen.getByRole('button', { name: settingsMenu })); | ||
expect(await axe(container)).toHaveNoViolations(); | ||
}); | ||
}); |
Oops, something went wrong.