frontend/containers/EventDetails/index.tsx (view raw)
1import {useRef} from 'react';
2import {makeStyles, createMuiTheme, ThemeProvider} from '@material-ui/core';
3import Typography from '@material-ui/core/Typography';
4import TextField from '@material-ui/core/TextField';
5import Link from '@material-ui/core/Link';
6import Box from '@material-ui/core/Box';
7import {DatePicker} from '@material-ui/pickers';
8import {useTranslation} from 'react-i18next';
9import moment from 'moment';
10import useEventStore from '../../stores/useEventStore';
11import {caroster} from '../../theme';
12import CopyLink from '../../components/CopyLink';
13import useToastStore from '../../stores/useToastStore';
14import useBannerStore from '../../stores/useBannerStore';
15
16const EventDetails = () => {
17 const {t} = useTranslation();
18 const event = useEventStore(s => s.event);
19 const addToast = useToastStore(s => s.addToast);
20 const setEventUpdate = useEventStore(s => s.setEventUpdate);
21 const isEditing = useEventStore(s => s.isEditing);
22 const shareInput = useRef(null);
23 const idPrefix = isEditing ? 'EditEvent' : 'Event';
24 const bannerOffset = useBannerStore(s => s.offset);
25 const classes = useStyles({bannerOffset});
26
27 if (!event) return null;
28
29 return (
30 <ThemeProvider theme={theme}>
31 <Box className={classes.container}>
32 <div className={classes.section}>
33 {isEditing && (
34 <div className={classes.section}>
35 <Typography variant="h6">{t('event.fields.name')}</Typography>
36 <TextField
37 fullWidth
38 value={event.name}
39 onChange={e => setEventUpdate({name: e.target.value})}
40 name="name"
41 id="EditEventName"
42 />
43 </div>
44 )}
45 <Typography variant="h6">{t('event.fields.date')}</Typography>
46 {isEditing ? (
47 <DatePicker
48 fullWidth
49 placeholder={t('event.fields.date_placeholder')}
50 value={event.date}
51 onChange={date =>
52 setEventUpdate({
53 date: !date ? null : moment(date).format('YYYY-MM-DD'),
54 })
55 }
56 format="DD/MM/YYYY"
57 cancelLabel={t('generic.cancel')}
58 clearable
59 clearLabel={t('generic.clear')}
60 id={`${idPrefix}Date`}
61 />
62 ) : (
63 <Typography variant="body1" id={`${idPrefix}Date`}>
64 {event.date
65 ? moment(event.date).format('DD/MM/YYYY')
66 : t('event.fields.empty')}
67 </Typography>
68 )}
69 </div>
70 <div className={classes.section}>
71 <Typography variant="h6">{t('event.fields.address')}</Typography>
72 {isEditing ? (
73 <TextField
74 fullWidth
75 multiline
76 rowsMax={4}
77 inputProps={{maxLength: 250}}
78 helperText={`${event.address?.length ?? 0}/250`}
79 defaultValue={event.address}
80 value={event.address}
81 onChange={e => setEventUpdate({address: e.target.value})}
82 id={`${idPrefix}Address`}
83 name="address"
84 />
85 ) : (
86 <Typography variant="body1" id={`${idPrefix}Address`}>
87 {event.address ? (
88 <Link
89 target="_blank"
90 rel="noreferrer"
91 href={`https://www.google.com/maps/search/?api=1&query=${encodeURIComponent(
92 event.address
93 )}`}
94 onClick={e => e.preventDefault}
95 >
96 {event.address}
97 </Link>
98 ) : (
99 t('event.fields.empty')
100 )}
101 </Typography>
102 )}
103 </div>
104 <div className={classes.section}>
105 <Typography variant="h6">{t('event.fields.description')}</Typography>
106 {isEditing ? (
107 <TextField
108 fullWidth
109 multiline
110 rowsMax={4}
111 inputProps={{maxLength: 250}}
112 helperText={`${event.description?.length || 0}/250`}
113 defaultValue={event.description}
114 value={event.description || ''}
115 onChange={e => setEventUpdate({description: e.target.value})}
116 id={`${idPrefix}Description`}
117 name="description"
118 />
119 ) : (
120 <Typography variant="body1" id={`${idPrefix}Description`}>
121 {event.description ?? t('event.fields.empty')}
122 </Typography>
123 )}
124 </div>
125 <Typography variant="h6">{t('event.fields.link')}</Typography>
126 <Typography>{t('event.fields.link_desc')}</Typography>
127 <TextField
128 value={window.location.href}
129 inputProps={{
130 ref: shareInput,
131 }}
132 InputProps={{disableUnderline: true}}
133 onFocus={() => {
134 if (shareInput) shareInput.current.select();
135 }}
136 fullWidth
137 readOnly
138 name="eventShareLink"
139 id="ShareLink"
140 />
141
142 <CopyLink
143 buttonText={t('event.fields.share')}
144 title={`Caroster ${event.name}`}
145 url={`${window.location.href}`}
146 onShare={() => {
147 addToast(t('event.actions.copied'));
148 }}
149 />
150 </Box>
151 </ThemeProvider>
152 );
153};
154
155const theme = createMuiTheme({
156 ...caroster,
157 palette: {
158 ...caroster.palette,
159 type: 'dark',
160 },
161});
162
163const useStyles = makeStyles(theme => ({
164 container: ({bannerOffset}) => ({
165 padding: theme.spacing(2, 9),
166 marginBottom: theme.spacing(12),
167 minHeight: `calc(100vh - ${
168 theme.mixins.toolbar.minHeight + bannerOffset
169 }px)`,
170
171 [theme.breakpoints.down('xs')]: {
172 padding: theme.spacing(2),
173 minHeight: `calc(100vh - ${
174 theme.mixins.toolbar.minHeight + bannerOffset + 56
175 }px)`,
176 },
177 }),
178 section: {
179 marginBottom: theme.spacing(2),
180 width: '540px',
181 maxWidth: '100%',
182 },
183 map: {
184 marginTop: theme.spacing(4),
185 },
186 seeOnGMapButton: {
187 marginLeft: theme.spacing(2),
188 },
189}));
190
191export default EventDetails;