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 { useEvent, EventProvider } from "../contexts/Event";
15import CarColumns from "../containers/CarColumns";
16import { useToast } from "../contexts/Toast";
17
18const Event = () => {
19 const { t } = useTranslation();
20 const { addToast } = useToast();
21 const [anchorEl, setAnchorEl] = useState(null);
22 const [detailsOpen, toggleDetails] = useReducer((i) => !i, false);
23 const classes = useStyles({ detailsOpen });
24 const {
25 event,
26 isEditing,
27 setIsEditing,
28 editingEvent,
29 setEditingEvent,
30 updateEvent,
31 } = useEvent();
32
33 useEffect(() => {
34 if (!detailsOpen) setIsEditing(false);
35 }, [detailsOpen]);
36
37 const onEventSave = async (e) => {
38 try {
39 await updateEvent();
40 setIsEditing(false);
41 } catch (error) {
42 console.error(error);
43 addToast(t("event.errors.cant_update"));
44 }
45 };
46
47 if (!event) return <div>{t("generic.loading")}</div>;
48
49 return (
50 <Layout>
51 <AppBar position="static" className={classes.appbar}>
52 <Toolbar>
53 {isEditing ? (
54 <TextField
55 light
56 value={editingEvent.name ?? event.name}
57 onChange={(e) =>
58 setEditingEvent({ ...editingEvent, name: e.target.value })
59 }
60 id="NewEventName"
61 name="name"
62 />
63 ) : (
64 <Typography variant="h6" className={classes.name}>
65 {event.name}
66 </Typography>
67 )}
68 {!detailsOpen && (
69 <IconButton
70 edge="end"
71 onClick={(e) => setAnchorEl(e.currentTarget)}
72 >
73 <Icon className={classes.barIcon}>more_vert</Icon>
74 </IconButton>
75 )}
76 {detailsOpen && !isEditing && (
77 <IconButton edge="end" onClick={(e) => setIsEditing(true)}>
78 <Icon className={classes.barIcon}>edit</Icon>
79 </IconButton>
80 )}
81 {detailsOpen && isEditing && (
82 <IconButton edge="end" onClick={onEventSave}>
83 <Icon className={classes.barIcon}>done</Icon>
84 </IconButton>
85 )}
86 <EventMenu
87 anchorEl={anchorEl}
88 setAnchorEl={setAnchorEl}
89 actions={[
90 {
91 label: detailsOpen
92 ? t("event.actions.hide_details")
93 : t("event.actions.show_details"),
94 onClick: toggleDetails,
95 },
96 { label: t("event.actions.add_car"), onClick: () => {} },
97 { label: t("event.actions.invite"), onClick: () => {} },
98 ]}
99 />
100 </Toolbar>
101 <Container className={classes.container} maxWidth="sm">
102 <EventDetails toggleDetails={toggleDetails} />
103 </Container>
104 </AppBar>
105 <CarColumns cars={event.cars} />
106 </Layout>
107 );
108};
109
110const useStyles = makeStyles((theme) => ({
111 container: { padding: theme.spacing(2) },
112 appbar: ({ detailsOpen }) => ({
113 transition: "height 0.3s ease",
114 overflow: "hidden",
115 height: detailsOpen ? "100vh" : theme.mixins.toolbar.minHeight,
116 }),
117 name: {
118 flexGrow: 1,
119 },
120 barIcon: {
121 color: "white",
122 },
123}));
124
125export default (props) => (
126 <EventProvider {...props}>
127 <Event {...props} />
128 </EventProvider>
129);