all repos — caroster @ e5866e282ec32d06493d72dfed2aa7f36fe4ceae

[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 TextField from "../components/TextField";
  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 Layout from "../layouts/Default";
 12import EventMenu from "../containers/EventMenu";
 13import EventDetails from "../containers/EventDetails";
 14import EventFab from "../containers/EventFab";
 15import { useEvent, EventProvider } from "../contexts/Event";
 16import CarColumns from "../containers/CarColumns";
 17import { useToast } from "../contexts/Toast";
 18import NewCarDialog from "../containers/NewCarDialog";
 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 {
 28    event,
 29    isEditing,
 30    setIsEditing,
 31    editingEvent,
 32    setEditingEvent,
 33    updateEvent,
 34  } = useEvent();
 35
 36  useEffect(() => {
 37    if (!detailsOpen) setIsEditing(false);
 38  }, [detailsOpen]); // eslint-disable-line react-hooks/exhaustive-deps
 39
 40  const onEventSave = async (e) => {
 41    try {
 42      await updateEvent();
 43      setIsEditing(false);
 44    } catch (error) {
 45      console.error(error);
 46      addToast(t("event.errors.cant_update"));
 47    }
 48  };
 49
 50  if (!event) return <div>{t("generic.loading")}</div>;
 51
 52  return (
 53    <Layout>
 54      <AppBar
 55        position="sticky"
 56        className={classes.appbar}
 57        id={isEditing ? "EditEvent" : detailsOpen ? "Details" : "Menu"}
 58      >
 59        <Toolbar>
 60          {isEditing ? (
 61            <TextField
 62              light
 63              value={editingEvent.name ?? event.name}
 64              onChange={(e) =>
 65                setEditingEvent({ ...editingEvent, name: e.target.value })
 66              }
 67              id="EditEventName"
 68              name="name"
 69            />
 70          ) : (
 71            <Typography
 72              variant="h6"
 73              className={classes.name}
 74              id="MenuHeaderTitle"
 75            >
 76              {event.name}
 77            </Typography>
 78          )}
 79          {!detailsOpen && (
 80            <IconButton
 81              edge="end"
 82              id="MenuMoreInfo"
 83              onClick={(e) => setAnchorEl(e.currentTarget)}
 84            >
 85              <Icon className={classes.barIcon}>more_vert</Icon>
 86            </IconButton>
 87          )}
 88          {detailsOpen && !isEditing && (
 89            <IconButton
 90              edge="end"
 91              id="DetailsEditBtn"
 92              onClick={(e) => setIsEditing(true)}
 93            >
 94              <Icon className={classes.barIcon}>edit</Icon>
 95            </IconButton>
 96          )}
 97          {detailsOpen && isEditing && (
 98            <IconButton edge="end" id="EditEventSubmit" onClick={onEventSave}>
 99              <Icon className={classes.barIcon}>done</Icon>
100            </IconButton>
101          )}
102          <EventMenu
103            anchorEl={anchorEl}
104            setAnchorEl={setAnchorEl}
105            actions={[
106              {
107                label: detailsOpen
108                  ? t("event.actions.hide_details")
109                  : t("event.actions.show_details"),
110                onClick: toggleDetails,
111                id: "DetailsTab",
112              },
113              {
114                label: t("event.actions.add_car"),
115                onClick: toggleNewCar,
116                id: "NewCarTab",
117              },
118              {
119                label: t("event.actions.invite"),
120                onClick: () => {},
121                id: "InviteTab",
122              },
123            ]}
124          />
125        </Toolbar>
126        <Container className={classes.container} maxWidth="sm">
127          <EventDetails toggleDetails={toggleDetails} />
128        </Container>
129      </AppBar>
130      <CarColumns toggleNewCar={toggleNewCar} />
131      <EventFab toggleNewCar={toggleNewCar} />
132      <NewCarDialog open={openNewCar} toggle={toggleNewCar} />
133    </Layout>
134  );
135};
136
137const useStyles = makeStyles((theme) => ({
138  container: { padding: theme.spacing(2) },
139  appbar: ({ detailsOpen }) => ({
140    transition: "height 0.3s ease",
141    overflow: "hidden",
142    height: detailsOpen ? "100vh" : theme.mixins.toolbar.minHeight,
143    zIndex: theme.zIndex.appBar,
144  }),
145  name: {
146    flexGrow: 1,
147  },
148  barIcon: {
149    color: "white",
150  },
151}));
152
153export default (props) => (
154  <EventProvider {...props}>
155    <Event {...props} />
156  </EventProvider>
157);