all repos — caroster @ 21c0aa54a8e688b65f1bd228f78ef37a775a96d8

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

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

  1import {useEffect, useState, useReducer} from 'react';
  2import {useRouter} from 'next/router';
  3import Link from 'next/link';
  4import {makeStyles} from '@material-ui/core/styles';
  5import AppBar from '@material-ui/core/AppBar';
  6import Toolbar from '@material-ui/core/Toolbar';
  7import Typography from '@material-ui/core/Typography';
  8import IconButton from '@material-ui/core/IconButton';
  9import Tooltip from '@material-ui/core/Tooltip';
 10import Avatar from '@material-ui/core/Avatar';
 11import Icon from '@material-ui/core/Icon';
 12import clsx from 'clsx';
 13import {useTranslation} from 'react-i18next';
 14import useAuthStore from '../../stores/useAuthStore';
 15import useEventStore from '../../stores/useEventStore';
 16import useTourStore from '../../stores/useTourStore';
 17import useProfile from '../../hooks/useProfile';
 18import useSettings from '../../hooks/useSettings';
 19import GenericMenu from '../GenericMenu';
 20import EventDetails from '../EventDetails';
 21
 22const EventBar = ({event, onAdd, onSave, onShare}) => {
 23  const {t} = useTranslation();
 24  const router = useRouter();
 25  const [detailsOpen, toggleDetails] = useReducer(i => !i, false);
 26  const classes = useStyles({detailsOpen});
 27  const [anchorEl, setAnchorEl] = useState(null);
 28  const isEditing = useEventStore(s => s.isEditing);
 29  const setIsEditing = useEventStore(s => s.setIsEditing);
 30  const token = useAuthStore(s => s.token);
 31  const {user} = useProfile();
 32  const settings = useSettings();
 33  const setTour = useTourStore(s => s.setTour);
 34  const tourStep = useTourStore(s => s.step);
 35
 36  useEffect(() => {
 37    onTourChange(toggleDetails);
 38  }, [tourStep]);
 39
 40  useEffect(() => {
 41    if (!detailsOpen) setIsEditing(false);
 42  }, [detailsOpen]); // eslint-disable-line react-hooks/exhaustive-deps
 43
 44  const signUp = () =>
 45    router.push({
 46      pathname: '/auth/register',
 47      state: {event: event?.id},
 48    });
 49  const signIn = () => router.push('/auth/login');
 50  const goToDashboard = () => router.push('/dashboard');
 51  const goProfile = () => router.push('/profile');
 52
 53  const onTourRestart = () => setTour({showWelcome: true});
 54
 55  const noUserMenuActions = [
 56    {
 57      label: t('event.actions.add_to_my_events'),
 58      onClick: () => {
 59        onAdd(true);
 60      },
 61      id: 'AddToMyEventsTab',
 62    },
 63    {divider: true},
 64    {
 65      label: t('menu.login'),
 66      onClick: signIn,
 67      id: 'SignInTab',
 68    },
 69    {
 70      label: t('menu.register'),
 71      onClick: signUp,
 72      id: 'SignUpTab',
 73    },
 74    {divider: true},
 75    {
 76      label: t('menu.tour'),
 77      onClick: () => {
 78        setAnchorEl(null);
 79        onTourRestart();
 80      },
 81      id: 'TourTab',
 82    },
 83  ];
 84
 85  const loggedMenuActions = [
 86    {
 87      label: t('menu.dashboard'),
 88      onClick: goToDashboard,
 89      id: 'GoToDashboardTab',
 90    },
 91    {
 92      label: t('menu.profile'),
 93      onClick: goProfile,
 94      id: 'ProfileTab',
 95    },
 96    {divider: true},
 97    {
 98      label: t('menu.tour'),
 99      onClick: () => {
100        setAnchorEl(null);
101        onTourRestart();
102      },
103      id: 'TourTab',
104    },
105  ];
106
107  const menuActions = token ? loggedMenuActions : noUserMenuActions;
108  const userInfos = user
109    ? [{label: user.username, id: 'Email'}, {divider: true}]
110    : [];
111
112  const appLink = user ? '/dashboard' : settings?.['about_link'] || '';
113
114  const UserIcon = user ? (
115    <Avatar className={classes.avatar}>
116      {`${user.username[0]}`.toUpperCase()}
117    </Avatar>
118  ) : (
119    <Icon>more_vert</Icon>
120  );
121
122  return (
123    <AppBar
124      className={classes.appbar}
125      position="static"
126      color="primary"
127      id={(isEditing && 'EditEvent') || (detailsOpen && 'Details') || 'Menu'}
128    >
129      <Toolbar>
130        <div className={classes.name}>
131          <Link href={appLink}>
132            <img
133              className={classes.logo}
134              src="/assets/Logo_in_beta.svg"
135              alt="Logo"
136            />
137          </Link>
138          <Tooltip title={event.name}>
139            <Typography
140              variant="h6"
141              noWrap
142              id="MenuHeaderTitle"
143              className={classes.title}
144            >
145              {event.name}
146            </Typography>
147          </Tooltip>
148
149          {detailsOpen && (
150            <IconButton
151              className="tour_event_edit"
152              color="inherit"
153              edge="end"
154              id="HeaderAction"
155              onClick={isEditing ? onSave : () => setIsEditing(true)}
156            >
157              <Icon>{isEditing ? 'done' : 'edit'}</Icon>
158            </IconButton>
159          )}
160        </div>
161        {detailsOpen ? (
162          <IconButton
163            color="inherit"
164            edge="end"
165            id="CloseDetailsBtn"
166            onClick={() => {
167              setIsEditing(false);
168              toggleDetails();
169            }}
170          >
171            <Icon>close</Icon>
172          </IconButton>
173        ) : (
174          <>
175            <IconButton
176              className={classes.shareIcon}
177              color="inherit"
178              edge="end"
179              id="ShareBtn"
180              onClick={toggleDetails}
181            >
182              <Icon>share</Icon>
183            </IconButton>
184            <IconButton
185              className={clsx(classes.iconButtons, 'tour_event_infos')}
186              color="inherit"
187              edge="end"
188              id="ShareBtn"
189              onClick={toggleDetails}
190            >
191              <Icon>information_outline</Icon>
192            </IconButton>
193            <IconButton
194              color="inherit"
195              edge="end"
196              id="MenuMoreInfo"
197              onClick={e => setAnchorEl(e.currentTarget)}
198            >
199              {UserIcon}
200            </IconButton>
201          </>
202        )}
203        {!detailsOpen && (
204          <GenericMenu
205            anchorEl={anchorEl}
206            setAnchorEl={setAnchorEl}
207            actions={[
208              ...userInfos,
209              ...[
210                {
211                  label: detailsOpen
212                    ? t('event.actions.hide_details')
213                    : t('event.actions.show_details'),
214                  onClick: e => {
215                    setAnchorEl(null);
216                    toggleDetails();
217                  },
218                  id: 'DetailsTab',
219                },
220              ],
221              ...menuActions,
222            ]}
223          />
224        )}
225      </Toolbar>
226      {detailsOpen && (
227        <EventDetails toggleDetails={toggleDetails} onShare={onShare} />
228      )}
229    </AppBar>
230  );
231};
232
233const onTourChange = (toggleDetails: Function) => {
234  const {prev, step, isCreator} = useTourStore.getState();
235  const fromTo = (step1: number, step2: number) =>
236    prev === step1 && step === step2;
237
238  if (isCreator) {
239    if (fromTo(3, 2) || fromTo(2, 3) || fromTo(4, 5)) toggleDetails();
240  } else if (fromTo(2, 3) || fromTo(3, 2) || fromTo(3, 4)) toggleDetails();
241};
242
243const useStyles = makeStyles(theme => ({
244  appbar: ({detailsOpen}) => ({
245    overflow: 'hidden',
246    height: detailsOpen ? '100vh' : theme.mixins.toolbar.minHeight,
247    overflowY: detailsOpen ? 'scroll' : 'hidden',
248    transition: 'height 0.3s ease',
249    zIndex: theme.zIndex.appBar,
250    position: 'fixed',
251    top: 0,
252  }),
253  logo: {
254    marginRight: theme.spacing(2),
255    width: 64,
256    height: 32,
257    cursor: 'pointer',
258  },
259  name: {
260    flexGrow: 1,
261    display: 'flex',
262    alignItems: 'center',
263  },
264  title: {
265    maxWidth: `calc(100vw - ${theme.spacing(30)}px)`,
266  },
267  iconButtons: {
268    margin: theme.spacing(0),
269  },
270  avatar: {
271    width: theme.spacing(3),
272    height: theme.spacing(3),
273    fontSize: 16,
274  },
275  shareIcon: {
276    marginRight: 0,
277  },
278}));
279
280export default EventBar;