all repos — caroster @ 29d7480903bad90012edd657b3cd246c1dc76958

[Octree] Group carpool to your event https://caroster.io

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;