all repos — caroster @ c61bf23768700cc6d5cb25b8cb79f22abb4471b9

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