frontend/containers/AssignPassenger/AvailableTravel.tsx (view raw)
1import moment from 'moment';
2import Box from '@mui/material/Box';
3import Typography from '@mui/material/Typography';
4import ListItem from '@mui/material/ListItem';
5import Link from '@mui/material/Link';
6import Button from '@mui/material/Button';
7import Divider from '@mui/material/Divider';
8import LinearProgress from '@mui/material/LinearProgress';
9import {useTranslation} from 'react-i18next';
10import getMapsLink from '../../lib/getMapsLink';
11import {Travel, TravelEntity} from '../../generated/graphql';
12
13interface Props {
14 travel: TravelEntity;
15 assign: (travel: TravelEntity) => void;
16}
17
18const AvailableTravel = ({travel, assign}: Props) => {
19 const {t} = useTranslation();
20 const passengersCount = travel.attributes.passengers?.data.length || 0;
21 const availableSeats = travel.attributes.seats - passengersCount;
22
23 return (
24 <>
25 <Divider />
26 <ListItem sx={{flexDirection: 'column', p: 2}}>
27 <Box display="flex" justifyContent="space-between" width={1}>
28 <Box>
29 {travel.attributes.departure && (
30 <Typography variant="overline" color="GrayText">
31 {t('passenger.assign.departure')}
32 {moment(travel.attributes.departure).format('LLLL')}
33 </Typography>
34 )}
35 <Typography variant="body1" sx={{pt: 1}}>
36 {travel.attributes.vehicleName}
37 </Typography>
38 </Box>
39 <Button
40 color="primary"
41 variant="contained"
42 size="small"
43 sx={{maxHeight: '24px'}}
44 onClick={() => assign(travel)}
45 >
46 {t('passenger.assign.assign')}
47 </Button>
48 </Box>
49 <LinearProgress
50 sx={{
51 width: 1,
52 mt: 2,
53 mb: 1,
54 backgroundColor: 'LightGray',
55 '& .MuiLinearProgress-bar': {
56 backgroundColor: 'Gray',
57 },
58 }}
59 value={(passengersCount / travel.attributes.seats || 0) * 100}
60 variant={travel.attributes.seats ? 'determinate' : 'indeterminate'}
61 />
62 <Box display="flex" justifyContent="space-between" width={1}>
63 <Typography variant="body1" color="GrayText" minWidth="150px">
64 {t('passenger.assign.seats', {
65 count: availableSeats || 0,
66 })}
67 </Typography>
68 <Link
69 sx={{
70 maxWidth: 'calc(100% - 150px)',
71 overflow: 'hidden',
72 textOverflow: 'ellipsis',
73 whiteSpace: 'nowrap',
74 paddingLeft: 2,
75 }}
76 variant="overline"
77 target="_blank"
78 rel="noreferrer"
79 href={getMapsLink(travel.attributes.meeting)}
80 onClick={e => e.preventDefault}
81 >
82 {travel.attributes.meeting}
83 </Link>
84 </Box>
85 </ListItem>
86 </>
87 );
88};
89
90export default AvailableTravel;