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 Toolbar from '@material-ui/core/Toolbar';
5import Container from '@material-ui/core/Container';
6import Typography from '@material-ui/core/Typography';
7import IconButton from '@material-ui/core/IconButton';
8import Icon from '@material-ui/core/Icon';
9import {makeStyles} from '@material-ui/core/styles';
10import Layout from '../layouts/Default';
11import EventMenu from '../containers/EventMenu';
12import EventDetails from '../containers/EventDetails';
13import EventFab from '../containers/EventFab';
14import {useEvent, EventProvider} from '../contexts/Event';
15import CarColumns from '../containers/CarColumns';
16import {useToast} from '../contexts/Toast';
17import NewCarDialog from '../containers/NewCarDialog';
18import Loading from '../pages/Loading';
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 {event, isEditing, setIsEditing, updateEvent} = useEvent();
28
29 useEffect(() => {
30 window.scrollTo(0, 0);
31 }, []);
32
33 useEffect(() => {
34 if (!detailsOpen) setIsEditing(false);
35 }, [detailsOpen]); // eslint-disable-line react-hooks/exhaustive-deps
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 const onShare = async () => {
48 if (!event) return null;
49 // If navigator as share capability
50 if (!!navigator.share)
51 return await navigator.share({
52 title: `Caroster ${event.name}`,
53 url: `${window.location.href}`,
54 });
55 // Else copy URL in clipboard
56 else if (!!navigator.clipboard) {
57 await navigator.clipboard.writeText(window.location.href);
58 addToast(t('event.actions.copied'));
59 return true;
60 }
61 };
62
63 if (!event) return <Loading />;
64
65 return (
66 <Layout>
67 <AppBar
68 position="static"
69 color="primary"
70 className={classes.appbar}
71 id={(isEditing && 'EditEvent') || (detailsOpen && 'Details') || 'Menu'}
72 >
73 <Toolbar>
74 {
75 <div className={classes.name}>
76 <Typography variant="h6" noWrap id="MenuHeaderTitle">
77 {event.name}
78 </Typography>
79 {detailsOpen && !isEditing && (
80 <IconButton
81 color="inherit"
82 edge="end"
83 id="CloseDetailsBtn"
84 onClick={() => setIsEditing(true)}
85 >
86 <Icon className={classes.barIcon}>edit</Icon>
87 </IconButton>
88 )}
89 {detailsOpen && isEditing && (
90 <IconButton
91 color="inherit"
92 edge="end"
93 id="EditEventSubmit"
94 onClick={onEventSave}
95 >
96 <Icon className={classes.barIcon}>done</Icon>
97 </IconButton>
98 )}
99 </div>
100 }
101 {!detailsOpen && (
102 <>
103 <IconButton
104 color="inherit"
105 edge="end"
106 id="ShareBtn"
107 onClick={onShare}
108 className={classes.shareIcon}
109 >
110 <Icon>share</Icon>
111 </IconButton>
112 <IconButton
113 color="inherit"
114 edge="end"
115 id="MenuMoreInfo"
116 onClick={e => setAnchorEl(e.currentTarget)}
117 >
118 <Icon>more_vert</Icon>
119 </IconButton>
120 </>
121 )}
122 {detailsOpen && (
123 <IconButton
124 color="inherit"
125 edge="end"
126 id="CloseDetailsBtn"
127 onClick={() => {
128 setIsEditing(false);
129 toggleDetails();
130 }}
131 >
132 <Icon className={classes.barIcon}>close</Icon>
133 </IconButton>
134 )}
135 <EventMenu
136 anchorEl={anchorEl}
137 setAnchorEl={setAnchorEl}
138 actions={[
139 {
140 label: detailsOpen
141 ? t('event.actions.hide_details')
142 : t('event.actions.show_details'),
143 onClick: toggleDetails,
144 id: 'DetailsTab',
145 },
146 {
147 label: t('event.actions.add_car'),
148 onClick: toggleNewCar,
149 id: 'NewCarTab',
150 },
151 {
152 label: t('event.actions.invite'),
153 onClick: () => {},
154 id: 'InviteTab',
155 },
156 ]}
157 />
158 </Toolbar>
159 <Container className={classes.container} maxWidth="sm">
160 <EventDetails toggleDetails={toggleDetails} />
161 </Container>
162 </AppBar>
163 <CarColumns toggleNewCar={toggleNewCar} />
164 <EventFab toggleNewCar={toggleNewCar} open={openNewCar} />
165 <NewCarDialog open={openNewCar} toggle={toggleNewCar} />
166 </Layout>
167 );
168};
169
170const useStyles = makeStyles(theme => ({
171 container: {
172 padding: theme.spacing(2),
173 },
174 appbar: ({detailsOpen}) => ({
175 overflow: 'hidden',
176 height: detailsOpen ? '100vh' : theme.mixins.toolbar.minHeight,
177 transition: 'height 0.3s ease',
178 zIndex: theme.zIndex.appBar,
179 position: 'fixed',
180 top: 0,
181 }),
182 name: {
183 flexGrow: 1,
184 display: 'flex',
185 alignItems: 'center',
186 },
187 shareIcon: {
188 marginRight: theme.spacing(2),
189 },
190}));
191
192const EventWithContext = props => (
193 <EventProvider {...props}>
194 <Event {...props} />
195 </EventProvider>
196);
197export default EventWithContext;