all repos — caroster @ ac45f0212dacd0394405edf159806f70927c2e13

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

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