all repos — caroster @ 9266a128ea9415a64c55fdc8e98990f815e0be66

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