all repos — caroster @ 832452704d5eae9e2164e58c086cdf365e51e5e7

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

frontend/layouts/Event.tsx (view raw)

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