all repos — caroster @ 331e51912018b9b1b3b123e7c8b1c08dbfef8cfb

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