all repos — caroster @ 79ed1eef33c7a3586f6ee448f9e6018a3fffdedd

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

frontend/layouts/Event.tsx (view raw)

 1import {PropsWithChildren, useEffect, useState} from 'react';
 2import {makeStyles} from '@material-ui/core/styles';
 3import {useTranslation} from 'react-i18next';
 4import ErrorPage from '../pages/_error';
 5import useEventStore from '../stores/useEventStore';
 6import Layout from '../layouts/Default';
 7import EventBar from '../containers/EventBar';
 8import {
 9  Event as EventType,
10  useEventByUuidQuery,
11  useUpdateEventMutation,
12  EditEventInput,
13} from '../generated/graphql';
14import useBannerStore from '../stores/useBannerStore';
15import DrawerMenu from '../containers/DrawerMenu';
16import AddToMyEventDialog from '../containers/AddToMyEventDialog';
17import useToastStore from '../stores/useToastStore';
18
19const POLL_INTERVAL = 10000;
20
21export type TabComponent = (props: {event: EventType}) => JSX.Element;
22
23interface Props {
24  eventUUID: string;
25  Tab: TabComponent;
26}
27
28const EventLayout = (props: PropsWithChildren<Props>) => {
29  const {eventUUID, Tab} = props;
30  const bannerOffset = useBannerStore(s => s.offset);
31  const classes = useStyles({bannerOffset});
32  const {t} = useTranslation();
33  const addToast = useToastStore(s => s.addToast);
34  const setEvent = useEventStore(s => s.setEvent);
35  const eventUpdate = useEventStore(s => s.event);
36  const setIsEditing = useEventStore(s => s.setIsEditing);
37  const [updateEvent] = useUpdateEventMutation();
38  const [isAddToMyEvent, setIsAddToMyEvent] = useState(false);
39  const {data: {eventByUUID: event} = {}} = useEventByUuidQuery({
40    pollInterval: POLL_INTERVAL,
41    variables: {uuid: eventUUID},
42  });
43
44  useEffect(() => {
45    if (event) setEvent(event as EventType);
46  }, [event]);
47
48  if (!event) return <ErrorPage statusCode={404} title={t`event.not_found`} />;
49
50  const onSave = async e => {
51    try {
52      const {uuid, ...data} = eventUpdate;
53      const {id, __typename, travels, users, waitingList, ...input} = data;
54      await updateEvent({
55        variables: {uuid, eventUpdate: input as EditEventInput},
56        refetchQueries: ['eventByUUID'],
57      });
58      setIsEditing(false);
59    } catch (error) {
60      console.error(error);
61      addToast(t('event.errors.cant_update'));
62    }
63  };
64
65  return (
66    <Layout
67      className={classes.layout}
68      pageTitle={t('event.title', {title: event.name})}
69      menuTitle={t('event.title', {title: event.name})}
70      displayMenu={false}
71    >
72      <EventBar event={event} onAdd={setIsAddToMyEvent} onSave={onSave} />
73      <DrawerMenu />
74      <Tab event={event} />
75      <AddToMyEventDialog
76        event={event}
77        open={isAddToMyEvent}
78        onClose={() => setIsAddToMyEvent(false)}
79      />
80    </Layout>
81  );
82};
83
84const useStyles = makeStyles(theme => ({
85  layout: ({bannerOffset}) => ({
86    paddingTop: theme.mixins.toolbar.minHeight + bannerOffset,
87  }),
88}));
89
90export default EventLayout;