all repos — caroster @ 25b044cdc2c4f79f286f1ff7fcf2ac916192f7da

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

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

  1import {useState} 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 useProfile from '../../hooks/useProfile';
 17import useSettings from '../../hooks/useSettings';
 18import GenericMenu from '../GenericMenu';
 19import EventDetails from '../EventDetails';
 20import useBannerStore from '../../stores/useBannerStore';
 21import Banner from '../../components/Banner';
 22
 23const EventBar = ({event, onAdd, onSave}) => {
 24  const {t} = useTranslation();
 25  const router = useRouter();
 26  const [anchorEl, setAnchorEl] = useState(null);
 27  const isEditing = useEventStore(s => s.isEditing);
 28  const areDetailsOpened = useEventStore(s => s.areDetailsOpened);
 29  const setIsEditing = useEventStore(s => s.setIsEditing);
 30  const setAreDetailsOpened = useEventStore(s => s.setAreDetailsOpened);
 31  const token = useAuthStore(s => s.token);
 32  const {user} = useProfile();
 33  const settings = useSettings();
 34  const bannerOffset = useBannerStore(s => s.offset);
 35  const bannerHeight = useBannerStore(s => s.height);
 36  const classes = useStyles({areDetailsOpened, bannerOffset, bannerHeight});
 37  const announcement = settings?.announcement || '';
 38  const [lastAnnouncementSeen, setLastAnnouncementSeen] = useState(
 39    typeof localStorage !== 'undefined'
 40      ? localStorage.getItem('lastAnnouncementSeen')
 41      : ''
 42  );
 43  const showAnnouncement =
 44    announcement !== '' && announcement !== lastAnnouncementSeen;
 45
 46  const onBannerClear = () => {
 47    if (typeof announcement != 'undefined') {
 48      localStorage.setItem('lastAnnouncementSeen', String(announcement));
 49    }
 50    setLastAnnouncementSeen(announcement);
 51  };
 52
 53  const signUp = () =>
 54    router.push({
 55      pathname: '/auth/register',
 56      state: {event: event?.id},
 57    });
 58  const signIn = () => router.push('/auth/login');
 59  const goToDashboard = () => router.push('/dashboard');
 60  const goProfile = () => router.push('/profile');
 61
 62  const noUserMenuActions = [
 63    {
 64      label: t('event.actions.add_to_my_events'),
 65      onClick: () => {
 66        onAdd(true);
 67      },
 68      id: 'AddToMyEventsTab',
 69    },
 70    {divider: true},
 71    {
 72      label: t('menu.login'),
 73      onClick: signIn,
 74      id: 'SignInTab',
 75    },
 76    {
 77      label: t('menu.register'),
 78      onClick: signUp,
 79      id: 'SignUpTab',
 80    },
 81    {divider: true},
 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
 98  const menuActions = token ? loggedMenuActions : noUserMenuActions;
 99  const userInfos = user
100    ? [{label: user.username, id: 'Email'}, {divider: true}]
101    : [];
102
103  const appLink = user ? '/dashboard' : `/e/${event.uuid}` || '';
104
105  const UserIcon = user ? (
106    <Avatar className={classes.avatar}>
107      {`${user.username[0]}`.toUpperCase()}
108    </Avatar>
109  ) : (
110    <Icon>more_vert</Icon>
111  );
112
113  return (
114    <AppBar
115      className={classes.appbar}
116      position="fixed"
117      color="primary"
118      id={
119        (isEditing && 'EditEvent') || (areDetailsOpened && 'Details') || 'Menu'
120      }
121    >
122      <Banner
123        message={announcement}
124        open={showAnnouncement}
125        onClear={onBannerClear}
126      />
127      <Toolbar>
128        <div className={classes.name}>
129          <Link href={appLink}>
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          {areDetailsOpened && (
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        {areDetailsOpened ? (
160          <IconButton
161            color="inherit"
162            edge="end"
163            id="CloseDetailsBtn"
164            onClick={() => {
165              setIsEditing(false);
166              setAreDetailsOpened(!areDetailsOpened);
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={() => setAreDetailsOpened(!areDetailsOpened)}
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={() => setAreDetailsOpened(!areDetailsOpened)}
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        {!areDetailsOpened && (
202          <GenericMenu
203            anchorEl={anchorEl}
204            setAnchorEl={setAnchorEl}
205            actions={[
206              ...userInfos,
207              ...[
208                {
209                  label: areDetailsOpened
210                    ? t('event.actions.hide_details')
211                    : t('event.actions.show_details'),
212                  onClick: e => {
213                    setAnchorEl(null);
214                    setAreDetailsOpened(!areDetailsOpened);
215                  },
216                  id: 'DetailsTab',
217                },
218              ],
219              ...menuActions,
220            ]}
221          />
222        )}
223      </Toolbar>
224      {areDetailsOpened && <EventDetails />}
225    </AppBar>
226  );
227};
228
229const useStyles = makeStyles(theme => ({
230  appbar: ({detailsOpen, bannerOffset, bannerHeight}) => ({
231    overflow: 'hidden',
232    minHeight: detailsOpen ? '100vh' : theme.mixins.toolbar.minHeight,
233    overflowY: detailsOpen ? 'scroll' : 'hidden',
234    transition: 'height 0.3s ease',
235    marginTop: bannerOffset - bannerHeight,
236  }),
237  logo: {
238    marginRight: theme.spacing(2),
239    width: 64,
240    height: 32,
241    cursor: 'pointer',
242  },
243  name: {
244    flexGrow: 1,
245    display: 'flex',
246    alignItems: 'center',
247  },
248  title: {
249    maxWidth: `calc(100vw - ${theme.spacing(30)}px)`,
250  },
251  iconButtons: {
252    margin: theme.spacing(0),
253  },
254  avatar: {
255    width: theme.spacing(3),
256    height: theme.spacing(3),
257    fontSize: 16,
258  },
259  shareIcon: {
260    marginRight: 0,
261  },
262}));
263
264export default EventBar;