all repos — caroster @ 63428b58d9a5b0438d9e4d8afb2fd46e9dab1a08

[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: onTourRestart,
 77      id: 'TourTab',
 78    },
 79  ];
 80
 81  const loggedMenuActions = [
 82    {
 83      label: t('menu.dashboard'),
 84      onClick: goToDashboard,
 85      id: 'GoToDashboardTab',
 86    },
 87    {
 88      label: t('menu.profile'),
 89      onClick: goProfile,
 90      id: 'ProfileTab',
 91    },
 92    {divider: true},
 93    {
 94      label: t('menu.tour'),
 95      onClick: onTourRestart,
 96      id: 'TourTab',
 97    },
 98  ];
 99
100  const menuActions = token ? loggedMenuActions : noUserMenuActions;
101  const userInfos = user
102    ? [{label: user.username, id: 'Email'}, {divider: true}]
103    : [];
104
105  return (
106    <AppBar
107      className={classes.appbar}
108      position="static"
109      color="primary"
110      id={(isEditing && 'EditEvent') || (detailsOpen && 'Details') || 'Menu'}
111    >
112      <Toolbar>
113        <div className={classes.name}>
114          <Link href={settings?.['about_link'] || ''}>
115            <img className={classes.logo} src="/assets/Logo_in_beta.svg" alt="Logo" />
116          </Link>
117          <Typography variant="h6" noWrap id="MenuHeaderTitle">
118            {event.name}
119          </Typography>
120          {detailsOpen && (
121            <IconButton
122              className="tour_event_edit"
123              color="inherit"
124              edge="end"
125              id="HeaderAction"
126              onClick={isEditing ? onSave : () => setIsEditing(true)}
127            >
128              <Icon>{isEditing ? 'done' : 'edit'}</Icon>
129            </IconButton>
130          )}
131        </div>
132        {detailsOpen ? (
133          <IconButton
134            color="inherit"
135            edge="end"
136            id="CloseDetailsBtn"
137            onClick={() => {
138              setIsEditing(false);
139              toggleDetails();
140            }}
141          >
142            <Icon>close</Icon>
143          </IconButton>
144        ) : (
145          <>
146            <IconButton
147              className={classes.shareIcon}
148              color="inherit"
149              edge="end"
150              id="ShareBtn"
151              onClick={toggleDetails}
152            >
153              <Icon>share</Icon>
154            </IconButton>
155            <IconButton
156              className={clsx(classes.iconButtons, 'tour_event_infos')}
157              color="inherit"
158              edge="end"
159              id="ShareBtn"
160              onClick={toggleDetails}
161            >
162              <Icon>information_outline</Icon>
163            </IconButton>
164            <IconButton
165              color="inherit"
166              edge="end"
167              id="MenuMoreInfo"
168              onClick={e => setAnchorEl(e.currentTarget)}
169            >
170              {user ? (
171                <Avatar className={classes.avatar}>
172                  {`${user.username[0]}`.toUpperCase()}
173                </Avatar>
174              ) : (
175                <Icon>more_vert</Icon>
176              )}
177            </IconButton>
178          </>
179        )}
180        {!detailsOpen && (
181          <GenericMenu
182            anchorEl={anchorEl}
183            setAnchorEl={setAnchorEl}
184            actions={[
185              ...userInfos,
186              ...[
187                {
188                  label: detailsOpen
189                    ? t('event.actions.hide_details')
190                    : t('event.actions.show_details'),
191                  onClick: e => {
192                    setAnchorEl(null);
193                    toggleDetails();
194                  },
195                  id: 'DetailsTab',
196                },
197              ],
198              ...menuActions,
199            ]}
200          />
201        )}
202      </Toolbar>
203      {detailsOpen && (
204        <EventDetails toggleDetails={toggleDetails} onShare={onShare} />
205      )}
206    </AppBar>
207  );
208};
209
210const onTourChange = (toggleDetails: Function) => {
211  const {prev, step, isCreator} = useTourStore.getState();
212  const fromTo = (step1: number, step2: number) =>
213    prev === step1 && step === step2;
214
215  if (isCreator) {
216    if (fromTo(1, 0) || fromTo(0, 1) || fromTo(3, 2) || fromTo(2, 3))
217      toggleDetails();
218  } else if (fromTo(2, 3) || fromTo(3, 2)) toggleDetails();
219};
220
221const useStyles = makeStyles(theme => ({
222  appbar: ({detailsOpen}) => ({
223    overflow: 'hidden',
224    height: detailsOpen ? '100vh' : theme.mixins.toolbar.minHeight,
225    overflowY: detailsOpen ? 'scroll' : 'hidden',
226    transition: 'height 0.3s ease',
227    zIndex: theme.zIndex.appBar,
228    position: 'fixed',
229    top: 0,
230  }),
231  logo: {
232    marginRight: theme.spacing(2),
233    width: 64,
234    height: 32,
235    cursor: 'pointer',
236  },
237  name: {
238    flexGrow: 1,
239    display: 'flex',
240    alignItems: 'center',
241  },
242  iconButtons: {
243    margin: theme.spacing(0),
244  },
245  avatar: {
246    width: theme.spacing(3),
247    height: theme.spacing(3),
248    fontSize: 16,
249  },
250  shareIcon: {
251    marginRight: 0,
252  },
253}));
254
255export default EventBar;