all repos — caroster @ 3a6483727355d59a734458de22d13c6088c9ce29

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

frontend/containers/NewPassengerDialog/AddPassengerToWaitingList.tsx (view raw)

  1import {FormEvent, useState} from 'react';
  2import Dialog from '@mui/material/Dialog';
  3import DialogContent from '@mui/material/DialogContent';
  4import DialogTitle from '@mui/material/DialogTitle';
  5import TextField from '@mui/material/TextField';
  6import Box from '@mui/material/Box';
  7import Typography from '@mui/material/Typography';
  8import Icon from '@mui/material/Icon';
  9import {useTranslation} from 'react-i18next';
 10import useToastStore from '../../stores/useToastStore';
 11import useEventStore from '../../stores/useEventStore';
 12import useAddToEvents from '../../hooks/useAddToEvents';
 13import usePassengersActions from '../../hooks/usePassengersActions';
 14import useProfile from '../../hooks/useProfile';
 15import SubmitButton from './SubmitButton';
 16import Transition from './Transition';
 17import AddPassengerCommonFields from './AddPassengerCommonFields';
 18import useStyles from './useStyles';
 19import {validateEmail} from './validation';
 20import {PassengerInput} from '../../generated/graphql';
 21
 22interface Props {
 23  toggle: () => void;
 24  open: boolean;
 25  addSelf: boolean;
 26}
 27
 28const AddPassengerToWaitingList = ({open, toggle, addSelf}: Props) => {
 29  const {t} = useTranslation();
 30  const classes = useStyles();
 31  const event = useEventStore(s => s.event);
 32  const addToast = useToastStore(s => s.addToast);
 33  const {addToEvent} = useAddToEvents();
 34
 35  // States
 36  const [name, setName] = useState('');
 37  const [email, setEmail] = useState('');
 38  const emailValidated = validateEmail(email);
 39  const [location, setlocation] = useState('');
 40  const canAddPassenger = !!name && !!email;
 41  const {profile, userId} = useProfile();
 42  const {addPassenger} = usePassengersActions();
 43
 44  const onAddPassenger = async (e: FormEvent) => {
 45    e.preventDefault();
 46    let passenger: PassengerInput = {
 47      email,
 48      name,
 49      location,
 50    };
 51    if (addSelf && profile) {
 52      const hasName = profile.firstName && profile.lastName;
 53      const userName = profile.firstName + ' ' + profile.lastName;
 54      passenger = {
 55        user: userId,
 56        email: profile.email,
 57        name: hasName ? userName : profile.username,
 58        location,
 59      };
 60    }
 61
 62    try {
 63      await addPassenger({...passenger, event: event.id});
 64      addToEvent(event.id);
 65      addToast(
 66        t(
 67          addSelf
 68            ? 'passenger.success.added_self_to_waitlist'
 69            : 'passenger.success.added_to_waitlist',
 70          {name}
 71        )
 72      );
 73      toggle();
 74    } catch (error) {
 75      console.error(error);
 76      addToast(t('passenger.errors.cant_add_passenger'));
 77    }
 78  };
 79
 80  return (
 81    <Dialog
 82      fullWidth
 83      maxWidth="xs"
 84      open={open}
 85      onClose={toggle}
 86      TransitionComponent={Transition}
 87    >
 88      <form onSubmit={onAddPassenger}>
 89        <DialogTitle className={classes.title}>
 90          {t('travel.passengers.register_to_waiting_list')}
 91          <Icon
 92            className={classes.closeIcon}
 93            onClick={toggle}
 94            aria-label="close"
 95          >
 96            close
 97          </Icon>
 98        </DialogTitle>
 99        <DialogContent className={classes.dialogContent}>
100          {!addSelf && (
101            <AddPassengerCommonFields
102              email={email}
103              emailError={!emailValidated}
104              setEmail={setEmail}
105              name={name}
106              setName={setName}
107            />
108          )}
109          <Box className={classes.inputBox}>
110            <label htmlFor="location">
111              <Typography className={classes.label}>
112                <Icon className={classes.labelIcon}>place</Icon>{' '}
113                {t('travel.passengers.location')}
114              </Typography>
115            </label>
116            <TextField
117              id="Passengerlocation"
118              name="location"
119              value={location}
120              onChange={e => setlocation(e.target.value)}
121              variant="outlined"
122              size="small"
123              fullWidth
124              label=""
125              placeholder={t('travel.passengers.location_placeholder')}
126            />
127            <Typography variant="caption">
128              {t('travel.passengers.location_helper')}
129            </Typography>
130          </Box>
131          <SubmitButton
132            disabled={!addSelf && !canAddPassenger}
133            important={addSelf}
134          >
135            {!addSelf && t('travel.passengers.add_someone')}
136            {addSelf && t('travel.passengers.add_me')}
137          </SubmitButton>
138        </DialogContent>
139      </form>
140    </Dialog>
141  );
142};
143
144export default AddPassengerToWaitingList;