all repos — caroster @ 441454a3d9f592007489fb7f437051b8402af111

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

frontend/containers/Travel/Header.tsx (view raw)

  1import moment from 'moment';
  2import Typography from '@mui/material/Typography';
  3import IconButton from '@mui/material/IconButton';
  4import TuneIcon from '@mui/icons-material/Tune';
  5import Box from '@mui/material/Box';
  6import Link from '@mui/material/Link';
  7import LinearProgress from '@mui/material/LinearProgress';
  8import {useTheme} from '@mui/material/styles';
  9import {useTranslation} from 'react-i18next';
 10import getMapsLink from '../../lib/getMapsLink';
 11import useMapStore from '../../stores/useMapStore';
 12import {TravelEntity} from '../../generated/graphql';
 13import usePermissions from '../../hooks/usePermissions';
 14import Chip from '@mui/material/Chip';
 15import useProfile from '../../hooks/useProfile';
 16
 17interface Props {
 18  travel: TravelEntity;
 19  toggleEditing: () => void;
 20}
 21
 22const Header = (props: Props) => {
 23  const {travel, toggleEditing} = props;
 24  const theme = useTheme();
 25  const {t} = useTranslation();
 26  const {
 27    userPermissions: {canEditTravel},
 28  } = usePermissions();
 29  const {setFocusOnTravel, focusedTravel} = useMapStore();
 30  const {userId} = useProfile();
 31  const isUserTripCreator =
 32    userId && userId === travel.attributes.user?.data?.id;
 33
 34  const passengersCount = travel?.attributes.passengers?.data.length || 0;
 35  const availableSeats = travel?.attributes.seats - passengersCount || 0;
 36
 37  return (
 38    <Box
 39      p={2}
 40      onClick={() => {
 41        setFocusOnTravel(travel);
 42        const mapElement = document?.getElementById('map');
 43        mapElement?.scrollIntoView({behavior: 'smooth'});
 44      }}
 45    >
 46      {canEditTravel(travel) && (
 47        <IconButton
 48          size="small"
 49          color="primary"
 50          sx={{
 51            position: 'absolute',
 52            top: theme.spacing(1),
 53            right: 0,
 54            margin: theme.spacing(1),
 55          }}
 56          onClick={e => {
 57            e.stopPropagation();
 58            toggleEditing();
 59          }}
 60          id="EditTravelBtn"
 61        >
 62          <TuneIcon />
 63        </IconButton>
 64      )}
 65      {!!travel.attributes.departure && (
 66        <Typography
 67          variant="overline"
 68          sx={{color: 'GrayText', textTransform: 'capitalize'}}
 69          id="TravelDeparture"
 70        >
 71          {moment(travel.attributes.departure).format('LLLL')}
 72        </Typography>
 73      )}
 74      <Typography variant="subtitle1">
 75        {travel.attributes.vehicleName}
 76        {isUserTripCreator && (
 77          <Typography component="span">
 78            <Chip sx={{mx: 1}} label={t`generic.me`} variant="outlined" />
 79          </Typography>
 80        )}
 81      </Typography>
 82
 83      {!!travel.attributes.phone_number && (
 84        <Box sx={{marginTop: 2}}>
 85          <Typography variant="overline" sx={{color: 'GrayText'}}>
 86            {t('travel.fields.phone')}
 87          </Typography>
 88          <Typography variant="body1" id="TravelPhone">
 89            {travel.attributes.phone_number}
 90          </Typography>
 91        </Box>
 92      )}
 93      {!!travel.attributes.meeting && (
 94        <Box sx={{marginTop: 2}}>
 95          <Typography variant="overline" sx={{color: 'GrayText'}}>
 96            {t('travel.fields.meeting_point')}
 97          </Typography>
 98          <Typography variant="body1">
 99            <Link
100              component="a"
101              target="_blank"
102              rel="noopener noreferrer"
103              href={getMapsLink(travel.attributes.meeting)}
104            >
105              {travel.attributes.meeting}
106            </Link>
107          </Typography>
108        </Box>
109      )}
110      {!!travel.attributes.details && (
111        <Box sx={{marginTop: 2}}>
112          <Typography variant="overline" sx={{color: 'GrayText'}}>
113            {t('travel.fields.details')}
114          </Typography>
115          <Typography variant="body1">{travel.attributes.details}</Typography>
116        </Box>
117      )}
118      <LinearProgress
119        sx={{
120          width: 1,
121          mt: 2,
122          mb: 1,
123          backgroundColor: 'LightGray',
124          '& .MuiLinearProgress-bar': {
125            backgroundColor: 'Gray',
126          },
127        }}
128        value={(passengersCount / travel?.attributes.seats) * 100}
129        variant="determinate"
130      />
131      <Box display="flex" justifyContent="space-between" sx={{width: 1}}>
132        <Typography variant="body1" sx={{color: 'GrayText'}}>
133          {t('passenger.assign.seats', {count: availableSeats})}
134        </Typography>
135      </Box>
136    </Box>
137  );
138};
139
140export default Header;