all repos — caroster @ 62de78accc81066736a8ae9f2b99eb212d2abc2d

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