all repos — caroster @ 94ed421247e41b427d90cf078b579daf30b8842b

[Octree] Group carpool to your event https://caroster.io

frontend/containers/GenericToolbar/index.tsx (view raw)

  1import {useState, useEffect} from 'react';
  2import {useRouter} from 'next/router';
  3import {makeStyles} from '@material-ui/core/styles';
  4import AppBar from '@material-ui/core/AppBar';
  5import Toolbar from '@material-ui/core/Toolbar';
  6import Typography from '@material-ui/core/Typography';
  7import IconButton from '@material-ui/core/IconButton';
  8import Avatar from '@material-ui/core/Avatar';
  9import Icon from '@material-ui/core/Icon';
 10import useProfile from '../../hooks/useProfile';
 11import GenericMenu from '../GenericMenu';
 12import {ActionType} from '../GenericMenu/Action';
 13import useBannerStore from '../../stores/useBannerStore';
 14import Banner from '../../components/Banner';
 15import useSettings from '../../hooks/useSettings';
 16
 17let persistedLastAnnouncementSeen = '';
 18if (typeof localStorage !== 'undefined') {
 19  persistedLastAnnouncementSeen = localStorage.getItem('lastAnnouncementSeen');
 20}
 21
 22const GenericToolbar = ({
 23  title,
 24  actions = [],
 25  goBack = null,
 26}: {
 27  title: string;
 28  actions: Array<ActionType>;
 29  goBack: () => void | null;
 30}) => {
 31  const router = useRouter();
 32  const [anchorEl, setAnchorEl] = useState(null);
 33  const bannerOffset = useBannerStore(s => s.offset);
 34  const bannerHeight = useBannerStore(s => s.height);
 35  const classes = useStyles({bannerOffset, bannerHeight});
 36  const {user} = useProfile();
 37  const settings = useSettings();
 38  const announcement = settings?.announcement || '';
 39  const [lastAnnouncementSeen, setLastAnnouncementSeen] = useState(
 40    persistedLastAnnouncementSeen
 41  );
 42  const showAnnouncement =
 43    announcement !== '' && announcement !== lastAnnouncementSeen;
 44
 45  const onBannerClear = () => {
 46    if (typeof announcement != 'undefined') {
 47      localStorage.setItem('lastAnnouncementSeen', String(announcement));
 48    }
 49    setLastAnnouncementSeen(announcement);
 50  };
 51
 52  const userInfos = user
 53    ? [{label: user.username, id: 'Email'}, {divider: true}]
 54    : [];
 55
 56  useEffect(() => {
 57    window.scrollTo(0, 0);
 58  }, []);
 59
 60  return (
 61    <AppBar
 62      position="fixed"
 63      color="primary"
 64      className={classes.appbar}
 65      id="Menu"
 66    >
 67      <Banner
 68        message={announcement}
 69        open={showAnnouncement}
 70        onClear={onBannerClear}
 71      />
 72      <Toolbar>
 73        {goBack && (
 74          <IconButton
 75            edge="start"
 76            className={classes.goBack}
 77            onClick={() =>
 78              router.basePath.split('/').length > 2
 79                ? router.back()
 80                : router.push('/dashboard')
 81            }
 82          >
 83            <Icon>arrow_back</Icon>
 84          </IconButton>
 85        )}
 86        <div className={classes.name}>
 87          <Typography variant="h6" noWrap id="MenuHeaderTitle">
 88            {title}
 89          </Typography>
 90        </div>
 91        {actions.length > 0 && (
 92          <>
 93            <IconButton
 94              color="inherit"
 95              edge="end"
 96              id="MenuMoreInfo"
 97              onClick={e => setAnchorEl(e.currentTarget)}
 98            >
 99              {user ? (
100                <Avatar className={classes.avatar}>
101                  {`${user.username[0]}`.toUpperCase()}
102                </Avatar>
103              ) : (
104                <Icon>more_vert</Icon>
105              )}
106            </IconButton>
107
108            <GenericMenu
109              anchorEl={anchorEl}
110              setAnchorEl={setAnchorEl}
111              actions={[...userInfos, ...actions, {divider: true}]}
112            />
113          </>
114        )}
115      </Toolbar>
116    </AppBar>
117  );
118};
119
120const useStyles = makeStyles(theme => ({
121  appbar: ({bannerHeight, bannerOffset}) => ({
122    minHeight: theme.mixins.toolbar.minHeight,
123    transition: 'height 0.3s ease',
124    zIndex: theme.zIndex.appBar,
125    display: 'block',
126    marginTop: bannerOffset - bannerHeight,
127  }),
128  name: {
129    flexGrow: 1,
130    display: 'flex',
131    alignItems: 'center',
132  },
133  avatar: {
134    width: theme.spacing(3),
135    height: theme.spacing(3),
136    fontSize: 16,
137  },
138  goBack: {
139    color: theme.palette.common.white,
140  },
141}));
142
143export default GenericToolbar;