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);