all repos — caroster @ 2f4d07042f9675732a9a3de4c6d3ec22bbcec360

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

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

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