all repos — caroster @ 64235997e5bde9d3bc1a2afda911dda2d952b866

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

app/src/pages/Event.js (view raw)

  1import React, {useState, useReducer, useEffect} from 'react';
  2import {Helmet} from 'react-helmet';
  3import {useTranslation} from 'react-i18next';
  4import AppBar from '@material-ui/core/AppBar';
  5import Toolbar from '@material-ui/core/Toolbar';
  6import Container from '@material-ui/core/Container';
  7import Typography from '@material-ui/core/Typography';
  8import IconButton from '@material-ui/core/IconButton';
  9import Icon from '@material-ui/core/Icon';
 10import {makeStyles} from '@material-ui/core/styles';
 11import {useEvent, EventProvider} from '../contexts/Event';
 12import {useToast} from '../contexts/Toast';
 13import Layout from '../layouts/Default';
 14import Loading from '../pages/Loading';
 15import EventMenu from '../containers/EventMenu';
 16import EventDetails from '../containers/EventDetails';
 17import EventFab from '../containers/EventFab';
 18import CarColumns from '../containers/CarColumns';
 19import NewCarDialog from '../containers/NewCarDialog';
 20
 21const Event = () => {
 22  const {t} = useTranslation();
 23  const {addToast} = useToast();
 24  const [anchorEl, setAnchorEl] = useState(null);
 25  const [detailsOpen, toggleDetails] = useReducer(i => !i, false);
 26  const classes = useStyles({detailsOpen});
 27  const [openNewCar, toggleNewCar] = useReducer(i => !i, false);
 28  const {event, isEditing, setIsEditing, updateEvent} = useEvent();
 29
 30  useEffect(() => {
 31    window.scrollTo(0, 0);
 32  }, []);
 33
 34  useEffect(() => {
 35    if (!detailsOpen) setIsEditing(false);
 36  }, [detailsOpen]); // eslint-disable-line react-hooks/exhaustive-deps
 37
 38  const onEventSave = async e => {
 39    try {
 40      await updateEvent();
 41      setIsEditing(false);
 42    } catch (error) {
 43      console.error(error);
 44      addToast(t('event.errors.cant_update'));
 45    }
 46  };
 47
 48  const onShare = async () => {
 49    if (!event) return null;
 50    // If navigator as share capability
 51    if (!!navigator.share)
 52      return await navigator.share({
 53        title: `Caroster ${event.name}`,
 54        url: `${window.location.href}`,
 55      });
 56    // Else copy URL in clipboard
 57    else if (!!navigator.clipboard) {
 58      await navigator.clipboard.writeText(window.location.href);
 59      addToast(t('event.actions.copied'));
 60      return true;
 61    }
 62  };
 63
 64  if (!event) return <Loading />;
 65
 66  return (
 67    <Layout>
 68      <Helmet>
 69        <title>{t('meta.title', {title: event.name})}</title>
 70      </Helmet>
 71      <AppBar
 72        position="static"
 73        color="primary"
 74        className={classes.appbar}
 75        id={(isEditing && 'EditEvent') || (detailsOpen && 'Details') || 'Menu'}
 76      >
 77        <Toolbar>
 78          <div className={classes.name}>
 79            <Typography variant="h6" noWrap id="MenuHeaderTitle">
 80              {event.name}
 81            </Typography>
 82            {detailsOpen && !isEditing && (
 83              <IconButton
 84                color="inherit"
 85                edge="end"
 86                id="CloseDetailsBtn"
 87                onClick={() => setIsEditing(true)}
 88              >
 89                <Icon>edit</Icon>
 90              </IconButton>
 91            )}
 92            {detailsOpen && isEditing && (
 93              <IconButton
 94                color="inherit"
 95                edge="end"
 96                id="EditEventSubmit"
 97                onClick={onEventSave}
 98              >
 99                <Icon>done</Icon>
100              </IconButton>
101            )}
102          </div>
103          {!detailsOpen && (
104            <>
105              <IconButton
106                color="inherit"
107                edge="end"
108                id="ShareBtn"
109                onClick={onShare}
110                className={classes.shareIcon}
111              >
112                <Icon>share</Icon>
113              </IconButton>
114              <IconButton
115                color="inherit"
116                edge="end"
117                id="MenuMoreInfo"
118                onClick={e => setAnchorEl(e.currentTarget)}
119              >
120                <Icon>more_vert</Icon>
121              </IconButton>
122            </>
123          )}
124          {detailsOpen && (
125            <IconButton
126              color="inherit"
127              edge="end"
128              id="CloseDetailsBtn"
129              onClick={() => {
130                setIsEditing(false);
131                toggleDetails();
132              }}
133            >
134              <Icon>close</Icon>
135            </IconButton>
136          )}
137          <EventMenu
138            anchorEl={anchorEl}
139            setAnchorEl={setAnchorEl}
140            actions={[
141              {
142                label: detailsOpen
143                  ? t('event.actions.hide_details')
144                  : t('event.actions.show_details'),
145                onClick: toggleDetails,
146                id: 'DetailsTab',
147              },
148              {
149                label: t('event.actions.add_car'),
150                onClick: toggleNewCar,
151                id: 'NewCarTab',
152              },
153              {
154                label: t('event.actions.invite'),
155                onClick: () => {},
156                id: 'InviteTab',
157              },
158            ]}
159          />
160        </Toolbar>
161        <Container className={classes.container} maxWidth="sm">
162          <EventDetails toggleDetails={toggleDetails} />
163        </Container>
164      </AppBar>
165      <CarColumns toggleNewCar={toggleNewCar} />
166      <EventFab toggleNewCar={toggleNewCar} open={openNewCar} />
167      <NewCarDialog open={openNewCar} toggle={toggleNewCar} />
168    </Layout>
169  );
170};
171
172const useStyles = makeStyles(theme => ({
173  container: {
174    padding: theme.spacing(2),
175  },
176  appbar: ({detailsOpen}) => ({
177    overflow: 'hidden',
178    height: detailsOpen ? '100vh' : theme.mixins.toolbar.minHeight,
179    transition: 'height 0.3s ease',
180    zIndex: theme.zIndex.appBar,
181    position: 'fixed',
182    top: 0,
183  }),
184  name: {
185    flexGrow: 1,
186    display: 'flex',
187    alignItems: 'center',
188  },
189  shareIcon: {
190    marginRight: theme.spacing(0),
191  },
192}));
193
194const EventWithContext = props => (
195  <EventProvider {...props}>
196    <Event {...props} />
197  </EventProvider>
198);
199export default EventWithContext;