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?.vehicle?.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?.vehicle?.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.vehicle?.name}
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;