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;