Move userbar to separate component

This commit is contained in:
dominik-zeglen 2020-09-10 17:20:22 +02:00
parent ed3d168d22
commit a7c65f77e4
3 changed files with 164 additions and 126 deletions

View file

@ -1,24 +1,14 @@
import Avatar from "@material-ui/core/Avatar";
import Chip from "@material-ui/core/Chip";
import ClickAwayListener from "@material-ui/core/ClickAwayListener";
import Grow from "@material-ui/core/Grow";
import Hidden from "@material-ui/core/Hidden";
import LinearProgress from "@material-ui/core/LinearProgress";
import MenuItem from "@material-ui/core/MenuItem";
import Menu from "@material-ui/core/MenuList";
import Paper from "@material-ui/core/Paper";
import Popper from "@material-ui/core/Popper";
import { makeStyles } from "@material-ui/core/styles";
import { createConfigurationMenu } from "@saleor/configuration";
import useAppState from "@saleor/hooks/useAppState";
import useNavigator from "@saleor/hooks/useNavigator";
import useTheme from "@saleor/hooks/useTheme";
import useUser from "@saleor/hooks/useUser";
import ArrowDropdown from "@saleor/icons/ArrowDropdown";
import { staffMemberDetailsUrl } from "@saleor/staff/urls";
import classNames from "classnames";
import React from "react";
import { FormattedMessage, useIntl } from "react-intl";
import { useIntl } from "react-intl";
import useRouter from "use-react-router";
import Container from "../Container";
@ -26,6 +16,7 @@ import ErrorPage from "../ErrorPage";
import Navigator from "../Navigator";
import NavigatorButton from "../NavigatorButton/NavigatorButton";
import SideBar from "../SideBar";
import UserChip from "../UserChip";
import AppActionContext from "./AppActionContext";
import AppHeaderContext from "./AppHeaderContext";
import { appLoaderHeight } from "./consts";
@ -53,16 +44,7 @@ const useStyles = makeStyles(
height: appLoaderHeight,
marginBottom: theme.spacing(4)
},
arrow: {
marginLeft: theme.spacing(2),
transition: theme.transitions.duration.standard + "ms"
},
avatar: {
"&&": {
height: 32,
width: 32
}
},
content: {
flex: 1
},
@ -80,16 +62,11 @@ const useStyles = makeStyles(
height: 40,
marginBottom: theme.spacing(3)
},
popover: {
zIndex: 1
},
root: {
display: "flex",
width: `100%`
},
rotate: {
transform: "rotate(180deg)"
},
spacer: {
flex: 1
},
@ -97,19 +74,7 @@ const useStyles = makeStyles(
alignItems: "center",
display: "flex"
},
userChip: {
backgroundColor: theme.palette.background.paper,
borderRadius: 24,
color: theme.palette.text.primary,
height: 40,
padding: theme.spacing(0.5)
},
userMenuContainer: {
position: "relative"
},
userMenuItem: {
textAlign: "right"
},
view: {
flex: 1,
flexGrow: 1,
@ -135,10 +100,8 @@ interface AppLayoutProps {
const AppLayout: React.FC<AppLayoutProps> = ({ children }) => {
const classes = useStyles({});
const { isDark, toggleTheme } = useTheme();
const [isMenuOpened, setMenuState] = React.useState(false);
const appActionAnchor = React.useRef<HTMLDivElement>();
const appHeaderAnchor = React.useRef<HTMLDivElement>();
const anchor = React.useRef<HTMLDivElement>();
const { logout, user } = useUser();
const navigate = useNavigator();
const intl = useIntl();
@ -159,16 +122,6 @@ const AppLayout: React.FC<AppLayoutProps> = ({ children }) => {
)
);
const handleLogout = () => {
setMenuState(false);
logout();
};
const handleViewerProfile = () => {
setMenuState(false);
navigate(staffMemberDetailsUrl(user.id));
};
const handleErrorBack = () => {
navigate("/");
dispatchAppState({
@ -224,80 +177,13 @@ const AppLayout: React.FC<AppLayoutProps> = ({ children }) => {
.includes("mac")}
onClick={() => setNavigatorVisibility(true)}
/>
<div className={classes.userMenuContainer} ref={anchor}>
<Chip
avatar={
user.avatar && (
<Avatar alt="user" src={user.avatar.url} />
)
}
classes={{
avatar: classes.avatar
}}
className={classes.userChip}
label={
<>
{user.email}
<ArrowDropdown
className={classNames(classes.arrow, {
[classes.rotate]: isMenuOpened
})}
/>
</>
}
onClick={() => setMenuState(!isMenuOpened)}
data-test="userMenu"
/>
<Popper
className={classes.popover}
open={isMenuOpened}
anchorEl={anchor.current}
transition
placement="bottom-end"
>
{({ TransitionProps, placement }) => (
<Grow
{...TransitionProps}
style={{
transformOrigin:
placement === "bottom"
? "right top"
: "right bottom"
}}
>
<Paper>
<ClickAwayListener
onClickAway={() => setMenuState(false)}
mouseEvent="onClick"
>
<Menu>
<MenuItem
className={classes.userMenuItem}
onClick={handleViewerProfile}
data-test="accountSettingsButton"
>
<FormattedMessage
defaultMessage="Account Settings"
description="button"
/>
</MenuItem>
<MenuItem
className={classes.userMenuItem}
onClick={handleLogout}
data-test="logOutButton"
>
<FormattedMessage
defaultMessage="Log out"
description="button"
/>
</MenuItem>
</Menu>
</ClickAwayListener>
</Paper>
</Grow>
)}
</Popper>
</div>
<UserChip
onLogout={logout}
onProfileClick={() =>
navigate(staffMemberDetailsUrl(user.id))
}
user={user}
/>
</div>
</div>
<Hidden mdUp>

View file

@ -0,0 +1,150 @@
import Avatar from "@material-ui/core/Avatar";
import Chip from "@material-ui/core/Chip";
import ClickAwayListener from "@material-ui/core/ClickAwayListener";
import Grow from "@material-ui/core/Grow";
import MenuItem from "@material-ui/core/MenuItem";
import Menu from "@material-ui/core/MenuList";
import Paper from "@material-ui/core/Paper";
import Popper from "@material-ui/core/Popper";
import makeStyles from "@material-ui/core/styles/makeStyles";
import { User } from "@saleor/fragments/types/User";
import ArrowDropdown from "@saleor/icons/ArrowDropdown";
import classNames from "classnames";
import React from "react";
import { FormattedMessage } from "react-intl";
const useStyles = makeStyles(
theme => ({
arrow: {
marginLeft: theme.spacing(2),
transition: theme.transitions.duration.standard + "ms"
},
avatar: {
"&&": {
height: 32,
width: 32
}
},
popover: {
zIndex: 1
},
rotate: {
transform: "rotate(180deg)"
},
userChip: {
backgroundColor: theme.palette.background.paper,
borderRadius: 24,
color: theme.palette.text.primary,
height: 40,
padding: theme.spacing(0.5)
},
userMenuContainer: {
position: "relative"
},
userMenuItem: {
textAlign: "right"
}
}),
{
name: "UserChip"
}
);
export interface UserChipProps {
user: User;
onLogout: () => void;
onProfileClick: () => void;
}
const UserChip: React.FC<UserChipProps> = ({
user,
onLogout,
onProfileClick
}) => {
const classes = useStyles({});
const [isMenuOpened, setMenuState] = React.useState(false);
const anchor = React.useRef<HTMLDivElement>();
const handleLogout = () => {
setMenuState(false);
onLogout();
};
const handleViewerProfile = () => {
setMenuState(false);
onProfileClick();
};
return (
<div className={classes.userMenuContainer} ref={anchor}>
<Chip
avatar={user.avatar && <Avatar alt="user" src={user.avatar.url} />}
classes={{
avatar: classes.avatar
}}
className={classes.userChip}
label={
<>
{user.email}
<ArrowDropdown
className={classNames(classes.arrow, {
[classes.rotate]: isMenuOpened
})}
/>
</>
}
onClick={() => setMenuState(!isMenuOpened)}
data-test="userMenu"
/>
<Popper
className={classes.popover}
open={isMenuOpened}
anchorEl={anchor.current}
transition
placement="bottom-end"
>
{({ TransitionProps, placement }) => (
<Grow
{...TransitionProps}
style={{
transformOrigin:
placement === "bottom" ? "right top" : "right bottom"
}}
>
<Paper>
<ClickAwayListener
onClickAway={() => setMenuState(false)}
mouseEvent="onClick"
>
<Menu>
<MenuItem
className={classes.userMenuItem}
onClick={handleViewerProfile}
data-test="accountSettingsButton"
>
<FormattedMessage
defaultMessage="Account Settings"
description="button"
/>
</MenuItem>
<MenuItem
className={classes.userMenuItem}
onClick={handleLogout}
data-test="logOutButton"
>
<FormattedMessage
defaultMessage="Log out"
description="button"
/>
</MenuItem>
</Menu>
</ClickAwayListener>
</Paper>
</Grow>
)}
</Popper>
</div>
);
};
UserChip.displayName = "UserChip";
export default UserChip;

View file

@ -0,0 +1,2 @@
export * from "./UserChip";
export { default } from "./UserChip";