aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorEugene Sokolov <eug-vs@keemail.me>2020-08-11 23:17:28 +0300
committerGitHub <noreply@github.com>2020-08-11 23:17:28 +0300
commit94067ef2a0d9ac5c2aa5f45eca5366a2251ac04a (patch)
tree51e502c7d1be7c8ad2179daf2f5c9bfd27911636 /src
parentc6723fa8a2a303f356b1756b45b2190203c96582 (diff)
parentb5ce9be31993f5b4bee9abbe57d775b7ea407507 (diff)
downloadwhich-ui-94067ef2a0d9ac5c2aa5f45eca5366a2251ac04a.tar.gz
Merge pull request #76 from which-ecosystem/redesign
Initial header redesign
Diffstat (limited to 'src')
-rw-r--r--src/components/Avatar/Avatar.tsx36
-rw-r--r--src/components/Header/BottomBar.tsx39
-rw-r--r--src/components/Header/BrowserHeader.tsx51
-rw-r--r--src/components/Header/Header.tsx103
-rw-r--r--src/components/Header/MobileHeader.tsx43
-rw-r--r--src/components/UserStrip/UserStrip.tsx26
-rw-r--r--src/containers/Page/Page.tsx2
-rw-r--r--src/containers/Profile/ProfileInfo.tsx11
8 files changed, 228 insertions, 83 deletions
diff --git a/src/components/Avatar/Avatar.tsx b/src/components/Avatar/Avatar.tsx
new file mode 100644
index 0000000..e445891
--- /dev/null
+++ b/src/components/Avatar/Avatar.tsx
@@ -0,0 +1,36 @@
+import React from 'react';
+import { useHistory } from 'react-router-dom';
+import { Avatar as AvatarBase } from '@material-ui/core';
+import AccountCircle from '@material-ui/icons/AccountCircle';
+import { User } from 'which-types';
+
+interface PropTypes {
+ user: User;
+ className?: string;
+}
+
+const Avatar: React.FC<PropTypes> = ({ user, className }) => {
+ const history = useHistory();
+ const { username, avatarUrl } = user;
+
+ const handleClick = () => {
+ history.push(`/profile/${username}`);
+ };
+
+ return avatarUrl ? (
+ <AvatarBase
+ src={avatarUrl}
+ alt={username[0].toUpperCase()}
+ onClick={handleClick}
+ className={className}
+ style={{ cursor: 'pointer' }}
+ />
+ ) : (
+ <AccountCircle
+ className={className}
+ onClick={handleClick}
+ />
+ );
+};
+
+export default Avatar;
diff --git a/src/components/Header/BottomBar.tsx b/src/components/Header/BottomBar.tsx
new file mode 100644
index 0000000..67fe219
--- /dev/null
+++ b/src/components/Header/BottomBar.tsx
@@ -0,0 +1,39 @@
+import React from 'react';
+import { AppBar, Toolbar } from '@material-ui/core';
+import { makeStyles } from '@material-ui/core/styles';
+
+interface PropTypes {
+ profile: JSX.Element;
+ feed: JSX.Element;
+ notifications: JSX.Element;
+}
+
+const useStyles = makeStyles({
+ root: {
+ top: 'auto',
+ bottom: 0
+ },
+ toolbar: {
+ display: 'flex',
+ justifyContent: 'space-around'
+ }
+});
+
+
+const BottomBar: React.FC<PropTypes> = React.memo(props => {
+ const classes = useStyles();
+ const { profile, feed, notifications } = props;
+
+ return (
+ <AppBar position="fixed" className={classes.root}>
+ <Toolbar className={classes.toolbar}>
+ {notifications}
+ {feed}
+ {profile}
+ </Toolbar>
+ </AppBar>
+ );
+});
+
+export default BottomBar;
+
diff --git a/src/components/Header/BrowserHeader.tsx b/src/components/Header/BrowserHeader.tsx
new file mode 100644
index 0000000..2dda717
--- /dev/null
+++ b/src/components/Header/BrowserHeader.tsx
@@ -0,0 +1,51 @@
+import React from 'react';
+import { AppBar, Toolbar } from '@material-ui/core';
+import { makeStyles } from '@material-ui/core/styles';
+import SearchBar from './SearchBar';
+
+interface PropTypes {
+ logo: JSX.Element;
+ feed: JSX.Element;
+ notifications: JSX.Element;
+ profile: JSX.Element;
+}
+
+const useStyles = makeStyles({
+ root: {
+ width: '60%',
+ margin: 'auto',
+ display: 'flex',
+ justifyContent: 'space-around'
+ },
+ group: {
+ display: 'flex'
+ }
+});
+
+
+const BrowserHeader: React.FC<PropTypes> = React.memo(props => {
+ const classes = useStyles();
+ const {
+ logo,
+ feed,
+ notifications,
+ profile
+ } = props;
+
+ return (
+ <AppBar position="fixed">
+ <Toolbar className={classes.root}>
+ {logo}
+ <SearchBar />
+ <div className={classes.group}>
+ {feed}
+ {notifications}
+ {profile}
+ </div>
+ </Toolbar>
+ </AppBar>
+ );
+});
+
+export default BrowserHeader;
+
diff --git a/src/components/Header/Header.tsx b/src/components/Header/Header.tsx
index c3a678c..5621dbf 100644
--- a/src/components/Header/Header.tsx
+++ b/src/components/Header/Header.tsx
@@ -1,47 +1,38 @@
import React from 'react';
import { useHistory } from 'react-router-dom';
import {
- AppBar,
- Toolbar,
IconButton,
Typography,
- Avatar,
useMediaQuery
} from '@material-ui/core';
+import {
+ AccountCircle,
+ Notifications,
+ Home,
+ Menu,
+ Search
+} from '@material-ui/icons';
import { makeStyles, useTheme } from '@material-ui/core/styles';
-import AccountCircle from '@material-ui/icons/AccountCircle';
-import NotificationsIcon from '@material-ui/icons/Notifications';
-import HomeIcon from '@material-ui/icons/Home';
import { useAuth } from '../../hooks/useAuth';
-import SearchBar from './SearchBar';
+import MobileHeader from './MobileHeader';
+import BottomBar from './BottomBar';
+import BrowserHeader from './BrowserHeader';
+import Avatar from '../Avatar/Avatar';
const useStyles = makeStyles(theme => ({
- mobile: {
- top: 'auto',
- bottom: 0
- },
- toolbar: {
- display: 'flex',
- justifyContent: 'space-around'
- },
- browserToolbar: {
- width: '60%',
- margin: 'auto'
- },
logo: {
fontWeight: 'bold',
cursor: 'pointer',
color: 'white'
},
- round: {
+ avatar: {
width: theme.spacing(3),
height: theme.spacing(3)
}
}));
-
const Header: React.FC = React.memo(() => {
const classes = useStyles();
const { user } = useAuth();
@@ -66,58 +57,54 @@ const Header: React.FC = React.memo(() => {
history.push('/notifications');
};
- const FeedButton = (
+ const feed = (
<IconButton onClick={handleFeed}>
- <HomeIcon />
+ <Home />
</IconButton>
);
- const NotificationsButton = (
+ const notifications = (
<IconButton onClick={handleNotifications}>
- <NotificationsIcon />
+ <Notifications />
</IconButton>
);
- const ProfileButton = (
- <IconButton onClick={handleProfile}>
- {
- user?.avatarUrl
- ? <Avatar className={classes.round} src={user?.avatarUrl} />
- : <AccountCircle />
- }
+ const menu = (
+ <IconButton>
+ <Menu />
</IconButton>
);
- const BrowserVersion = (
- <AppBar position="fixed">
- <Toolbar className={`${classes.toolbar} ${classes.browserToolbar}`}>
- <Typography variant="h5" className={classes.logo} onClick={handleHome}>
- Which
- </Typography>
- <SearchBar />
- <div>
- {FeedButton}
- {NotificationsButton}
- {ProfileButton}
- </div>
- </Toolbar>
- </AppBar>
+ const search = (
+ <IconButton>
+ <Search />
+ </IconButton>
+ );
+
+ const logo = (
+ <Typography variant="h5" className={classes.logo} onClick={handleHome}>
+ Which
+ </Typography>
);
- const MobileVersion = (
- <AppBar position="fixed" className={classes.mobile}>
- <Toolbar className={classes.toolbar}>
- <IconButton onClick={handleHome}>
- <Typography className={`${classes.logo} ${classes.round}`}>W</Typography>
- </IconButton>
- {FeedButton}
- {NotificationsButton}
- {ProfileButton}
- </Toolbar>
- </AppBar>
+ const profile = (
+ <IconButton onClick={handleProfile}>
+ {
+ user
+ ? <Avatar className={classes.avatar} user={user} />
+ : <AccountCircle className={classes.avatar} />
+ }
+ </IconButton>
);
- return isMobile ? MobileVersion : BrowserVersion;
+ return isMobile ? (
+ <>
+ <MobileHeader logo={logo} menu={menu} search={search} />
+ <BottomBar feed={feed} profile={profile} notifications={notifications} />
+ </>
+ ) : (
+ <BrowserHeader logo={logo} profile={profile} notifications={notifications} feed={feed} />
+ );
});
export default Header;
diff --git a/src/components/Header/MobileHeader.tsx b/src/components/Header/MobileHeader.tsx
new file mode 100644
index 0000000..a20d54a
--- /dev/null
+++ b/src/components/Header/MobileHeader.tsx
@@ -0,0 +1,43 @@
+import React from 'react';
+import {
+ AppBar,
+ Toolbar,
+ useScrollTrigger,
+ Slide
+} from '@material-ui/core';
+import { makeStyles } from '@material-ui/core/styles';
+
+interface PropTypes {
+ menu: JSX.Element;
+ logo: JSX.Element;
+ search: JSX.Element;
+}
+
+const useStyles = makeStyles({
+ root: {
+ display: 'flex',
+ justifyContent: 'space-between'
+ }
+});
+
+
+const MobileHeader: React.FC<PropTypes> = React.memo(props => {
+ const classes = useStyles();
+ const trigger = useScrollTrigger();
+ const { menu, search, logo } = props;
+
+ return (
+ <Slide appear={false} direction="down" in={!trigger}>
+ <AppBar position="fixed">
+ <Toolbar className={classes.root}>
+ {menu}
+ {logo}
+ {search}
+ </Toolbar>
+ </AppBar>
+ </Slide>
+ );
+});
+
+export default MobileHeader;
+
diff --git a/src/components/UserStrip/UserStrip.tsx b/src/components/UserStrip/UserStrip.tsx
index 73d9363..a837961 100644
--- a/src/components/UserStrip/UserStrip.tsx
+++ b/src/components/UserStrip/UserStrip.tsx
@@ -1,10 +1,11 @@
import React from 'react';
-import { useHistory } from 'react-router-dom';
import { makeStyles } from '@material-ui/core/styles';
import VerifiedIcon from '@material-ui/icons/CheckCircleOutline';
-import { Avatar, CardHeader } from '@material-ui/core/';
+import { CardHeader } from '@material-ui/core/';
import { User } from 'which-types';
+import Avatar from '../Avatar/Avatar';
+
interface PropTypes {
user: User;
@@ -21,30 +22,15 @@ const useStyles = makeStyles(theme => ({
marginLeft: theme.spacing(0.5),
width: theme.spacing(2),
height: theme.spacing(2)
- },
- avatar: {
- cursor: 'pointer'
}
}));
const UserStrip: React.FC<PropTypes> = ({ user, info }) => {
const classes = useStyles();
- const history = useHistory();
- const { username, avatarUrl, verified } = user;
-
- const handleNavigate = () => {
- history.push(`/profile/${username}`);
- };
-
- const avatar = (
- <Avatar
- src={avatarUrl}
- alt={username[0].toUpperCase()}
- onClick={handleNavigate}
- className={classes.avatar}
- />
- );
+ const { username, verified } = user;
+
+ const avatar = <Avatar user={user} />;
const title = (
<div className={classes.root}>
diff --git a/src/containers/Page/Page.tsx b/src/containers/Page/Page.tsx
index 643e6de..f6a0aa5 100644
--- a/src/containers/Page/Page.tsx
+++ b/src/containers/Page/Page.tsx
@@ -16,7 +16,7 @@ const Notifications = React.lazy(() => import('../Notifications/Notifications'))
const useStyles = makeStyles(theme => ({
root: {
[theme.breakpoints.down('sm')]: {
- margin: theme.spacing(2, 0, 12, 0)
+ margin: theme.spacing(15, 0, 12, 0)
},
[theme.breakpoints.up('md')]: {
margin: theme.spacing(15, 5, 8, 5)
diff --git a/src/containers/Profile/ProfileInfo.tsx b/src/containers/Profile/ProfileInfo.tsx
index 9eee4c1..a01c222 100644
--- a/src/containers/Profile/ProfileInfo.tsx
+++ b/src/containers/Profile/ProfileInfo.tsx
@@ -1,5 +1,5 @@
import React, { useState } from 'react';
-import { Avatar, Badge, Typography } from '@material-ui/core/';
+import { Badge, Typography } from '@material-ui/core/';
import { makeStyles } from '@material-ui/core/styles';
import { User } from 'which-types';
import CameraAltIcon from '@material-ui/icons/CameraAlt';
@@ -8,9 +8,11 @@ import Skeleton from '@material-ui/lab/Skeleton';
import MoreMenu from './MoreMenu';
import Highlight from './Highlight';
import UploadImage from '../../components/UploadImage/UploadImage';
+import Avatar from '../../components/Avatar/Avatar';
import { patch } from '../../requests';
import { useAuth } from '../../hooks/useAuth';
+
interface PropTypes {
savedPolls: number;
totalVotes: number;
@@ -116,19 +118,20 @@ const ProfileInfo: React.FC<PropTypes> = ({
vertical: 'bottom',
horizontal: 'right'
}}
+ onClick={handleClick}
badgeContent={(
<div className={classes.badge}>
- <CameraAltIcon onClick={handleClick} />
+ <CameraAltIcon />
</div>
)}
>
- <Avatar className={classes.avatar} src={userInfo?.avatarUrl} />
+ <Avatar className={classes.avatar} user={userInfo} />
</Badge>
</div>
<UploadImage isOpen={input} setIsOpen={setInput} callback={patchAvatar} />
</div>
)
- : <Avatar className={classes.avatar} src={userInfo?.avatarUrl} />
+ : <Avatar className={classes.avatar} user={userInfo} />
}
{
!userInfo