all repos — caroster @ 11ead31f4aee86f2a841b8775231bc52abb9df0e

[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, 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;