all repos — caroster @ 733f817f6e0839de8a601c2f0089aa608f11a982

[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 UserIcon = user ? (
113    <Avatar className={classes.avatar}>
114      {`${user.username[0]}`.toUpperCase()}
115    </Avatar>
116  ) : (
117    <Icon>more_vert</Icon>
118  );
119
120  return (
121    <AppBar
122      className={classes.appbar}
123      position="static"
124      color="primary"
125      id={(isEditing && 'EditEvent') || (detailsOpen && 'Details') || 'Menu'}
126    >
127      <Toolbar>
128        <div className={classes.name}>
129          <Link href={settings?.['about_link'] || ''}>
130            <img
131              className={classes.logo}
132              src="/assets/Logo_in_beta.svg"
133              alt="Logo"
134            />
135          </Link>
136          <Tooltip title={event.name}>
137            <Typography
138              variant="h6"
139              noWrap
140              id="MenuHeaderTitle"
141              className={classes.title}
142            >
143              {event.name}
144            </Typography>
145          </Tooltip>
146
147          {detailsOpen && (
148            <IconButton
149              className="tour_event_edit"
150              color="inherit"
151              edge="end"
152              id="HeaderAction"
153              onClick={isEditing ? onSave : () => setIsEditing(true)}
154            >
155              <Icon>{isEditing ? 'done' : 'edit'}</Icon>
156            </IconButton>
157          )}
158        </div>
159        {detailsOpen ? (
160          <IconButton
161            color="inherit"
162            edge="end"
163            id="CloseDetailsBtn"
164            onClick={() => {
165              setIsEditing(false);
166              toggleDetails();
167            }}
168          >
169            <Icon>close</Icon>
170          </IconButton>
171        ) : (
172          <>
173            <IconButton
174              className={classes.shareIcon}
175              color="inherit"
176              edge="end"
177              id="ShareBtn"
178              onClick={toggleDetails}
179            >
180              <Icon>share</Icon>
181            </IconButton>
182            <IconButton
183              className={clsx(classes.iconButtons, 'tour_event_infos')}
184              color="inherit"
185              edge="end"
186              id="ShareBtn"
187              onClick={toggleDetails}
188            >
189              <Icon>information_outline</Icon>
190            </IconButton>
191            <IconButton
192              color="inherit"
193              edge="end"
194              id="MenuMoreInfo"
195              onClick={e => setAnchorEl(e.currentTarget)}
196            >
197              {UserIcon}
198            </IconButton>
199          </>
200        )}
201        {!detailsOpen && (
202          <GenericMenu
203            anchorEl={anchorEl}
204            setAnchorEl={setAnchorEl}
205            actions={[
206              ...userInfos,
207              ...[
208                {
209                  label: detailsOpen
210                    ? t('event.actions.hide_details')
211                    : t('event.actions.show_details'),
212                  onClick: e => {
213                    setAnchorEl(null);
214                    toggleDetails();
215                  },
216                  id: 'DetailsTab',
217                },
218              ],
219              ...menuActions,
220            ]}
221          />
222        )}
223      </Toolbar>
224      {detailsOpen && (
225        <EventDetails toggleDetails={toggleDetails} onShare={onShare} />
226      )}
227    </AppBar>
228  );
229};
230
231const onTourChange = (toggleDetails: Function) => {
232  const {prev, step, isCreator} = useTourStore.getState();
233  const fromTo = (step1: number, step2: number) =>
234    prev === step1 && step === step2;
235
236  if (isCreator) {
237    if (fromTo(3, 2) || fromTo(2, 3) || fromTo(4, 5)) toggleDetails();
238  } else if (fromTo(2, 3) || fromTo(3, 2) || fromTo(3, 4)) toggleDetails();
239};
240
241const useStyles = makeStyles(theme => ({
242  appbar: ({detailsOpen}) => ({
243    overflow: 'hidden',
244    height: detailsOpen ? '100vh' : theme.mixins.toolbar.minHeight,
245    overflowY: detailsOpen ? 'scroll' : 'hidden',
246    transition: 'height 0.3s ease',
247    zIndex: theme.zIndex.appBar,
248    position: 'fixed',
249    top: 0,
250  }),
251  logo: {
252    marginRight: theme.spacing(2),
253    width: 64,
254    height: 32,
255    cursor: 'pointer',
256  },
257  name: {
258    flexGrow: 1,
259    display: 'flex',
260    alignItems: 'center',
261  },
262  title: {
263    maxWidth: `calc(100vw - ${theme.spacing(30)}px)`,
264  },
265  iconButtons: {
266    margin: theme.spacing(0),
267  },
268  avatar: {
269    width: theme.spacing(3),
270    height: theme.spacing(3),
271    fontSize: 16,
272  },
273  shareIcon: {
274    marginRight: 0,
275  },
276}));
277
278export default EventBar;