all repos — caroster @ 9706a05b8adf4b0adf97299733cfd9ea2c457a62

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

app/src/containers/Car/HeaderEditing.js (view raw)

  1import React, {useState, useReducer} from 'react';
  2import Typography from '@material-ui/core/Typography';
  3import IconButton from '@material-ui/core/IconButton';
  4import Icon from '@material-ui/core/Icon';
  5import Button from '@material-ui/core/Button';
  6import moment from 'moment';
  7import {makeStyles} from '@material-ui/core/styles';
  8import {DateTimePicker} from '@material-ui/pickers';
  9import {useTranslation} from 'react-i18next';
 10import TextField from '@material-ui/core/TextField';
 11import Slider from '@material-ui/core/Slider';
 12import {useStrapi} from 'strapi-react-context';
 13import {useToast} from '../../contexts/Toast';
 14import {useEvent} from '../../contexts/Event';
 15import RemoveDialog from './RemoveDialog';
 16
 17const HeaderEditing = ({car, toggleEditing}) => {
 18  const classes = useStyles();
 19  const {t} = useTranslation();
 20  const strapi = useStrapi();
 21  const {event} = useEvent();
 22  const {addToast} = useToast();
 23  const [removing, toggleRemoving] = useReducer(i => !i, false);
 24
 25  // States
 26  const [name, setName] = useState(car?.name ?? '');
 27  const [seats, setSeats] = useState(car?.seats ?? 4);
 28  const [meeting, setMeeting] = useState(car?.meeting ?? '');
 29  const [date, setDate] = useState(
 30    car?.departure ? moment(car.departure) : moment()
 31  );
 32  const [phone, setPhone] = useState(car?.phone_number ?? '');
 33  const [details, setDetails] = useState(car?.details ?? '');
 34
 35  const onSave = async () => {
 36    try {
 37      // If new seats count is under current passengers count, put excedent in event waiting list
 38      if (!!car.passengers && car.passengers.length > seats) {
 39        const lostPassengers = car.passengers.slice(seats);
 40        if (lostPassengers.length > 0)
 41          await strapi.services.events.update(event.id, {
 42            waiting_list: [...(event.waiting_list ?? []), ...lostPassengers],
 43          });
 44      }
 45      // Update car
 46      await strapi.services.cars.update(car.id, {
 47        name,
 48        seats,
 49        meeting,
 50        departure: date.toISOString(),
 51        phone_number: phone,
 52        details,
 53        passengers: car.passengers ? car.passengers.slice(0, seats) : [],
 54      });
 55      toggleEditing();
 56    } catch (error) {
 57      console.error(error);
 58      addToast('car.errors.cant_update');
 59    }
 60  };
 61
 62  const onRemove = async () => {
 63    try {
 64      // Put passengers in event waiting list (if any)
 65      if (Array.isArray(car?.passengers) && car.passengers.length > 0)
 66        await strapi.services.events.update(event.id, {
 67          waiting_list: [...(event.waiting_list ?? []), ...car.passengers],
 68        });
 69      // Remove car
 70      await strapi.services.cars.remove(car.id);
 71      addToast(t('car.actions.removed'));
 72      toggleEditing();
 73    } catch (error) {
 74      console.error(error);
 75      addToast('car.errors.cant_remove');
 76    }
 77  };
 78
 79  return (
 80    <div className={classes.header}>
 81      <IconButton className={classes.editBtn} onClick={onSave}>
 82        <Icon>done</Icon>
 83      </IconButton>
 84      <DateTimePicker
 85        label={t('event.creation.date')}
 86        value={date}
 87        onChange={setDate}
 88        className={classes.textField}
 89        fullWidth
 90        format="LLLL"
 91        disablePast
 92        id="UpdateCarDateTime"
 93        name="date"
 94      />
 95      <TextField
 96        className={classes.textField}
 97        label={t('car.creation.name')}
 98        fullWidth
 99        autoFocus
100        margin="dense"
101        value={name}
102        onChange={e => setName(e.target.value)}
103        id="UpdateCarName"
104        name="name"
105      />
106      <TextField
107        className={classes.textField}
108        label={t('car.creation.phone')}
109        fullWidth
110        autoFocus
111        margin="dense"
112        value={phone}
113        onChange={e => setPhone(e.target.value)}
114        id="UpdateCarPhone"
115        name="phone"
116      />
117      <TextField
118        className={classes.textField}
119        label={t('car.creation.meeting')}
120        fullWidth
121        margin="dense"
122        multiline
123        rows={2}
124        value={meeting}
125        onChange={e => setMeeting(e.target.value)}
126        id="UpdateCarMeeting"
127        name="meeting"
128      />
129      <TextField
130        className={classes.textField}
131        label={t('car.creation.notes')}
132        fullWidth
133        margin="dense"
134        multiline
135        rows={2}
136        value={details}
137        onChange={e => setDetails(e.target.value)}
138        id="UpdateCarDetails"
139        name="details"
140      />
141      <div className={classes.slider}>
142        <Typography variant="caption">{t('car.creation.seats')}</Typography>
143        <Slider
144          value={seats}
145          onChange={(e, value) => setSeats(value)}
146          step={1}
147          marks={[1, 2, 3, 4, 5, 6, 7, 8].map(value => ({
148            value,
149            label: value,
150          }))}
151          min={1}
152          max={8}
153          valueLabelDisplay="auto"
154        />
155      </div>
156      <div className={classes.actions}>
157        <Button color="secondary" variant="outlined" onClick={toggleRemoving}>
158          {t('car.actions.remove')}
159        </Button>
160      </div>
161      <RemoveDialog
162        open={removing}
163        toggle={toggleRemoving}
164        onRemove={onRemove}
165      />
166    </div>
167  );
168};
169
170const useStyles = makeStyles(theme => ({
171  header: {padding: theme.spacing(2)},
172  editBtn: {
173    position: 'absolute',
174    top: 0,
175    right: 0,
176    zIndex: theme.zIndex.speedDial,
177  },
178  section: {
179    marginTop: theme.spacing(2),
180  },
181  slider: {
182    marginTop: theme.spacing(2),
183  },
184  actions: {
185    display: 'flex',
186    justifyContent: 'center',
187    margin: theme.spacing(2, 0),
188  },
189}));
190
191export default HeaderEditing;