all repos — caroster @ fead57d5709f6561867584c711251a8f23ccf587

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

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

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