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