frontend/containers/WaitingList/TravelDialog.tsx (view raw)
1import {forwardRef} 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;