all repos — caroster @ 4881677aa9f44e54de7dd0a6ec068b116bb7bb31

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