all repos — caroster @ ea414277b269eb8ba96835769f2e44ca1069f093

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

frontend/containers/WaitingList/TravelDialog.tsx (view raw)

  1import {forwardRef, useEffect} from 'react';
  2import moment from 'moment';
  3import Link from '@material-ui/core/Link';
  4import Typography from '@material-ui/core/Typography';
  5import Button from '@material-ui/core/Button';
  6import Slide from '@material-ui/core/Slide';
  7import Dialog from '@material-ui/core/Dialog';
  8import AppBar from '@material-ui/core/AppBar';
  9import Toolbar from '@material-ui/core/Toolbar';
 10import ListItem from '@material-ui/core/ListItem';
 11import List from '@material-ui/core/List';
 12import IconButton from '@material-ui/core/IconButton';
 13import Icon from '@material-ui/core/Icon';
 14import Box from '@material-ui/core/Box';
 15import Container from '@material-ui/core/Container';
 16import {makeStyles} from '@material-ui/core/styles';
 17import {useTranslation} from 'react-i18next';
 18import {ComponentPassengerPassenger, Travel} from '../../generated/graphql';
 19import getMapsLink from '../../utils/getMapsLink';
 20
 21interface Props {
 22  travels: Array<Travel>;
 23  passenger: ComponentPassengerPassenger;
 24  open: boolean;
 25  onClose: () => void;
 26  onSelect: (travel: Travel) => void;
 27}
 28
 29const TravelDialog = ({travels, passenger, open, onClose, onSelect}: Props) => {
 30  const classes = useStyles();
 31  const {t} = useTranslation();
 32
 33  const availableTravels = travels?.filter(
 34    travel =>
 35      travel.passengers && travel?.seats > travel.passengers.length
 36  );
 37
 38  return (
 39    <Dialog
 40      fullScreen
 41      open={open}
 42      onClose={onClose}
 43      TransitionComponent={Transition}
 44    >
 45      <AppBar>
 46        <Toolbar>
 47          <IconButton onClick={onClose} color="inherit">
 48            <Icon>arrow_back_ios</Icon>
 49          </IconButton>
 50          <Typography variant="h5">
 51            {t('passenger.creation.available_cars')}
 52          </Typography>
 53        </Toolbar>
 54      </AppBar>
 55      {(availableTravels.length === 0 && (
 56        <Typography className={classes.noTravel}>
 57          {t('passenger.creation.no_travel', {name: passenger?.name})}
 58        </Typography>
 59      )) || (
 60        <div className={classes.offset}>
 61          <List disablePadding>
 62            {availableTravels.map((travel, i) => {
 63              const passengersCount = travel?.passengers?.length || 0;
 64              const counter = `${passengersCount} / ${
 65                travel?.seats || 0
 66              }`;
 67              return (
 68                <ListItem key={i} divider className={classes.listItem}>
 69                  <Box className={classes.rtlBox}>
 70                    <Box className={classes.info}>
 71                      <Typography variant="subtitle1" className={classes.date}>
 72                        {t('passenger.creation.departure')}
 73                        {moment(travel.departure).format('LLLL')}
 74                      </Typography>
 75                      <Link
 76                        target="_blank"
 77                        rel="noreferrer"
 78                        href={getMapsLink(travel.meeting)}
 79                        onClick={e => e.preventDefault}
 80                      >
 81                        {travel.meeting}
 82                      </Link>
 83                    </Box>
 84                    <Box className={classes.info}>
 85                      <Typography variant="h6">
 86                        {travel.vehicleName}
 87                      </Typography>
 88                      <Typography variant="body2">
 89                        {t('passenger.creation.seats', {seats: counter})}
 90                      </Typography>
 91                    </Box>
 92                  </Box>
 93                  <Button
 94                    color="primary"
 95                    variant="contained"
 96                    onClick={() => onSelect(travel)}
 97                    className={classes.button}
 98                  >
 99                    {t('passenger.creation.assign')}
100                  </Button>
101                </ListItem>
102              );
103            })}
104          </List>
105        </div>
106      )}
107    </Dialog>
108  );
109};
110
111const Transition = forwardRef(function Transition(props, ref) {
112  return <Slide direction="up" ref={ref} {...props} />;
113});
114
115const useStyles = makeStyles(theme => ({
116  offset: {
117    paddingTop: theme.spacing(7),
118  },
119  rtlBox: {
120    display: 'flex',
121    padding: 0,
122    margin: 0,
123    direction: 'rtl',
124    [theme.breakpoints.down('sm')]: {
125      display: 'block',
126      paddingBottom: theme.spacing(1),
127    },
128  },
129  info: {
130    padding: theme.spacing(0, 4, 0, 0),
131    width: '350px',
132    [theme.breakpoints.down('sm')]: {
133      padding: theme.spacing(0.5, 1),
134      width: '100%',
135      textAlign: 'left',
136    },
137  },
138  listItem: {
139    display: 'flex',
140    justifyContent: 'left',
141    [theme.breakpoints.down('sm')]: {
142      display: 'block',
143      textAlign: 'center',
144    },
145  },
146  date: {
147    textTransform: 'capitalize',
148    padding: theme.spacing(0, 0, 0.5, 0),
149  },
150  button: {
151    padding: theme.spacing(1, 15),
152    margin: theme.spacing(1),
153  },
154  noTravel: {
155    margin: '45vh auto',
156    textAlign: 'center',
157  },
158}));
159
160export default TravelDialog;