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 position="sticky" className={classes.appbar}>
55 <Toolbar>
56 {isEditing ? (
57 <TextField
58 light
59 value={editingEvent.name ?? event.name}
60 onChange={(e) =>
61 setEditingEvent({ ...editingEvent, name: e.target.value })
62 }
63 id="NewEventName"
64 name="name"
65 />
66 ) : (
67 <Typography variant="h6" className={classes.name}>
68 {event.name}
69 </Typography>
70 )}
71 {!detailsOpen && (
72 <IconButton
73 edge="end"
74 onClick={(e) => setAnchorEl(e.currentTarget)}
75 >
76 <Icon className={classes.barIcon}>more_vert</Icon>
77 </IconButton>
78 )}
79 {detailsOpen && !isEditing && (
80 <IconButton edge="end" onClick={(e) => setIsEditing(true)}>
81 <Icon className={classes.barIcon}>edit</Icon>
82 </IconButton>
83 )}
84 {detailsOpen && isEditing && (
85 <IconButton edge="end" onClick={onEventSave}>
86 <Icon className={classes.barIcon}>done</Icon>
87 </IconButton>
88 )}
89 <EventMenu
90 anchorEl={anchorEl}
91 setAnchorEl={setAnchorEl}
92 actions={[
93 {
94 label: detailsOpen
95 ? t("event.actions.hide_details")
96 : t("event.actions.show_details"),
97 onClick: toggleDetails,
98 },
99 { label: t("event.actions.add_car"), onClick: toggleNewCar },
100 { label: t("event.actions.invite"), onClick: () => {} },
101 ]}
102 />
103 </Toolbar>
104 <Container className={classes.container} maxWidth="sm">
105 <EventDetails toggleDetails={toggleDetails} />
106 </Container>
107 </AppBar>
108 <CarColumns toggleNewCar={toggleNewCar} />
109 <EventFab toggleNewCar={toggleNewCar} />
110 <NewCarDialog open={openNewCar} toggle={toggleNewCar} />
111 </Layout>
112 );
113};
114
115const useStyles = makeStyles((theme) => ({
116 container: { padding: theme.spacing(2) },
117 appbar: ({ detailsOpen }) => ({
118 transition: "height 0.3s ease",
119 overflow: "hidden",
120 height: detailsOpen ? "100vh" : theme.mixins.toolbar.minHeight,
121 zIndex: theme.zIndex.appBar,
122 }),
123 name: {
124 flexGrow: 1,
125 },
126 barIcon: {
127 color: "white",
128 },
129}));
130
131export default (props) => (
132 <EventProvider {...props}>
133 <Event {...props} />
134 </EventProvider>
135);