frontend/layouts/Event.tsx (view raw)
1import {PropsWithChildren, useEffect, useMemo, 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 {
13 Event as EventType,
14 useEventByUuidQuery,
15 Module,
16} from '../generated/graphql';
17
18const POLL_INTERVAL = 10000;
19
20export type TabComponent<TabProps> = (
21 props: {
22 event: EventType & {id: string};
23 modulesSettings: Module;
24 } & TabProps
25) => JSX.Element;
26
27interface Props {
28 modulesSettings?: Module;
29 eventUUID: string;
30 Tab: TabComponent<{}>;
31 goBack?: () => void;
32 titleKey?: string;
33 tabProps?: any;
34}
35
36const EventLayout = (props: PropsWithChildren<Props>) => {
37 const {
38 eventUUID,
39 modulesSettings,
40 Tab,
41 goBack,
42 titleKey,
43 tabProps = {},
44 ...pageProps
45 } = props;
46 const {t} = useTranslation();
47 const theme = useTheme();
48
49 const isMobile = useMediaQuery(theme.breakpoints.down('md'));
50 const setEvent = useEventStore(s => s.setEvent);
51 const [isAddToMyEvent, setIsAddToMyEvent] = useState(false);
52 const {data: {eventByUUID: {data: {attributes, id} = {}} = {}} = {}} =
53 useEventByUuidQuery({
54 pollInterval: POLL_INTERVAL,
55 variables: {uuid: eventUUID},
56 });
57 const event = useMemo(() => ({id, ...attributes}), [id, attributes]);
58
59 useEffect(() => {
60 if (event) setEvent(event);
61 }, [event, setEvent]);
62
63 if (!event) return <ErrorPage statusCode={404} title={t`event.not_found`} />;
64
65 return (
66 <Layout
67 pageTitle={t('event.title', {title: event.name})}
68 menuTitle={t('event.title', {title: event.name})}
69 displayMenu={false}
70 {...pageProps}
71 >
72 <Box
73 flex={1}
74 display="flex"
75 alignItems="stretch"
76 height="calc(100% - 80px)"
77 overflow="hidden"
78 flexDirection={isMobile ? 'column-reverse' : 'row'}
79 >
80 <DrawerMenu eventUuid={event.uuid} />
81 <Box
82 sx={{
83 position: 'relative',
84 flex: 1,
85 maxWidth: 'calc(100% - 109px)',
86 overflow: 'auto',
87
88 [theme.breakpoints.down('md')]: {
89 maxWidth: '100%',
90 },
91 }}
92 id="event-content"
93 >
94 <EventBar
95 title={t(titleKey)}
96 goBack={goBack}
97 event={event}
98 onAdd={setIsAddToMyEvent}
99 />
100 <Tab event={event} modulesSettings={modulesSettings} {...tabProps} />
101 </Box>
102 </Box>
103 <AddToMyEventDialog
104 event={event}
105 open={isAddToMyEvent}
106 onClose={() => setIsAddToMyEvent(false)}
107 />
108 </Layout>
109 );
110};
111
112export default EventLayout;