/ frontend / containers / NewPassengerDialog / AddPassengerToWaitingList.tsx
AddPassengerToWaitingList.tsx
  1  import {FormEvent, useState} from 'react';
  2  import Dialog from '@mui/material/Dialog';
  3  import DialogContent from '@mui/material/DialogContent';
  4  import DialogTitle from '@mui/material/DialogTitle';
  5  import TextField from '@mui/material/TextField';
  6  import Box from '@mui/material/Box';
  7  import Typography from '@mui/material/Typography';
  8  import Icon from '@mui/material/Icon';
  9  import {useTranslation} from 'react-i18next';
 10  import useToastStore from '../../stores/useToastStore';
 11  import useEventStore from '../../stores/useEventStore';
 12  import useAddToEvents from '../../hooks/useAddToEvents';
 13  import usePassengersActions from '../../hooks/usePassengersActions';
 14  import useProfile from '../../hooks/useProfile';
 15  import SubmitButton from './SubmitButton';
 16  import Transition from './Transition';
 17  import AddPassengerCommonFields from './AddPassengerCommonFields';
 18  import useStyles from './useStyles';
 19  import {validateEmail} from '../../lib/validation';
 20  import {PassengerInput} from '../../generated/graphql';
 21  
 22  interface Props {
 23    toggle: () => void;
 24    open: boolean;
 25    addSelf: boolean;
 26  }
 27  
 28  const 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  
144  export default AddPassengerToWaitingList;