all repos — caroster @ 8b292b59765e5453a63272be05822c149c511ef0

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

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;