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