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;