all repos — caroster @ 8396b80d084b9f803ad3232ad760aca778f3301f

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