frontend/layouts/Event.tsx (view raw)
1import {PropsWithChildren, useEffect, useState} from 'react';
2import useMediaQuery from '@mui/material/useMediaQuery';
3import Box from '@mui/material/Box';
4import {useTheme} from '@mui/material/styles';
5import {useTranslation} from 'react-i18next';
6import ErrorPage from '../pages/_error';
7import useEventStore from '../stores/useEventStore';
8import Layout from '../layouts/Default';
9import EventBar from '../containers/EventBar';
10import DrawerMenu from '../containers/DrawerMenu';
11import AddToMyEventDialog from '../containers/AddToMyEventDialog';
12import {Event as EventType, useEventByUuidQuery} from '../generated/graphql';
13
14const POLL_INTERVAL = 10000;
15
16export type TabComponent = (props: {
17 event: EventType & {id: string};
18}) => JSX.Element;
19
20interface Props {
21 eventUUID: string;
22 Tab: TabComponent;
23 goBack?: () => void;
24 titleKey?: string;
25}
26
27const EventLayout = (props: PropsWithChildren<Props>) => {
28 const {eventUUID, Tab, goBack, titleKey, ...pageProps} = props;
29 const {t} = useTranslation();
30 const theme = useTheme();
31
32 const isMobile = useMediaQuery(theme.breakpoints.down('md'));
33 const setEvent = useEventStore(s => s.setEvent);
34 const [isAddToMyEvent, setIsAddToMyEvent] = useState(false);
35 const {data: {eventByUUID: {data: {attributes, id} = {}} = {}} = {}} =
36 useEventByUuidQuery({
37 pollInterval: POLL_INTERVAL,
38 variables: {uuid: eventUUID},
39 });
40 const event = {id, ...attributes};
41
42 useEffect(() => {
43 if (event) setEvent(event);
44 }, [event]);
45
46 if (!event) return <ErrorPage statusCode={404} title={t`event.not_found`} />;
47
48 return (
49 <Layout
50 pageTitle={t('event.title', {title: event.name})}
51 menuTitle={t('event.title', {title: event.name})}
52 displayMenu={false}
53 {...pageProps}
54 >
55 <Box
56 flex={1}
57 display="flex"
58 alignItems="stretch"
59 height="calc(100% - 80px)"
60 overflow="hidden"
61 flexDirection={isMobile ? 'column-reverse' : 'row'}
62 >
63 <DrawerMenu eventUuid={event.uuid} />
64 <Box
65 sx={{
66 position: 'relative',
67 flex: 1,
68 maxWidth: 'calc(100% - 109px)',
69 overflow: 'auto',
70
71 [theme.breakpoints.down('md')]: {
72 maxWidth: '100%',
73 },
74 }}
75 id="event-content"
76 >
77 <EventBar title={t(titleKey)} goBack={goBack} event={event} onAdd={setIsAddToMyEvent} />
78 <Tab event={event} />
79 </Box>
80 </Box>
81 <AddToMyEventDialog
82 event={event}
83 open={isAddToMyEvent}
84 onClose={() => setIsAddToMyEvent(false)}
85 />
86 </Layout>
87 );
88};
89
90export default EventLayout;