all repos — caroster @ 95876236a197ac3c43205c69fd4e70f3a300105c

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

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

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