all repos — caroster @ 2e4e192becc64475ea9245eb5fec57f72cb7088e

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

frontend/containers/NewPassengerDialog/AddPassengerToTravel.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 Icon from '@mui/material/Icon';
 6import {useTranslation} from 'next-i18next';
 7import useAddToEvents from '../../hooks/useAddToEvents';
 8import useEventStore from '../../stores/useEventStore';
 9import {TravelEntity} from '../../generated/graphql';
10import SubmitButton from './SubmitButton';
11import Transition from './Transition';
12import AddPassengerCommonFields from './AddPassengerCommonFields';
13import useStyles from './useStyles';
14import useToastStore from '../../stores/useToastStore';
15import usePassengersActions from '../../hooks/usePassengersActions';
16import {validateEmail} from '../../lib/validation';
17import usePermissions from '../../hooks/usePermissions';
18import {getTravelName} from '../../lib/travels';
19
20interface Props {
21  travel: TravelEntity;
22  toggle: () => void;
23  open: boolean;
24}
25
26const AddPassengerToTravel = ({open, toggle, travel}: Props) => {
27  const {t} = useTranslation();
28  const classes = useStyles();
29  const event = useEventStore(s => s.event);
30  const {addToEvent} = useAddToEvents();
31  const addToast = useToastStore(s => s.addToast);
32  const {
33    userPermissions: {canSeeFullName},
34  } = usePermissions();
35
36  // States
37  const [name, setName] = useState('');
38  const [email, setEmail] = useState('');
39  const emailValidated = validateEmail(email);
40  const canAddPassenger = !!name;
41  const {addPassenger} = usePassengersActions();
42
43  const onSubmit = async (e: FormEvent) => {
44    e.preventDefault();
45    const passenger = {
46      email: email || null,
47      name,
48    };
49
50    try {
51      await addPassenger({...passenger, travel: travel.id, event: event.id});
52      addToEvent(event.id);
53      addToast(t('passenger.success.added_to_car', {name}));
54      toggle();
55    } catch (error) {
56      console.error(error);
57      if (error.message === 'no_enough_seats')
58        addToast(t`passenger.errors.car_full`);
59    }
60  };
61
62  return (
63    <Dialog
64      fullWidth
65      maxWidth="xs"
66      open={open}
67      onClose={toggle}
68      TransitionComponent={Transition}
69    >
70      <form onSubmit={onSubmit}>
71        <DialogTitle className={classes.title}>
72          {getTravelName(travel, canSeeFullName())}
73          <Icon
74            className={classes.closeIcon}
75            onClick={toggle}
76            aria-label="close"
77          >
78            close
79          </Icon>
80        </DialogTitle>
81        <DialogContent className={classes.dialogContent}>
82          <AddPassengerCommonFields
83            email={email}
84            emailError={!emailValidated}
85            setEmail={setEmail}
86            optionalEmail
87            name={name}
88            setName={setName}
89          />
90          <SubmitButton disabled={!canAddPassenger}>
91            {t('travel.passengers.add_to_car')}
92          </SubmitButton>
93        </DialogContent>
94      </form>
95    </Dialog>
96  );
97};
98
99export default AddPassengerToTravel;