all repos — caroster @ 3ede449ef52ab927e5e9bee37b447b5c86a65723

[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.departureDate && (
 66        <Typography
 67          variant="overline"
 68          sx={{color: 'GrayText', textTransform: 'capitalize'}}
 69          id="TravelDeparture"
 70        >
 71          {moment(travel.attributes.departureDate).format('dddd LL')}{' '}
 72          {travel.attributes.departureTime}
 73        </Typography>
 74      )}
 75      <Typography variant="subtitle1">
 76        {travel.attributes.vehicleName}
 77        {isUserTripCreator && (
 78          <Typography component="span">
 79            <Chip sx={{mx: 1}} label={t`generic.me`} variant="outlined" />
 80          </Typography>
 81        )}
 82      </Typography>
 83
 84      {!!travel.attributes.phone_number && (
 85        <Box sx={{marginTop: 2}}>
 86          <Typography variant="overline" sx={{color: 'GrayText'}}>
 87            {t('travel.fields.phone')}
 88          </Typography>
 89          <Typography variant="body1" id="TravelPhone">
 90            {travel.attributes.phone_number}
 91          </Typography>
 92        </Box>
 93      )}
 94      {!!travel.attributes.meeting && (
 95        <Box sx={{marginTop: 2}}>
 96          <Typography variant="overline" sx={{color: 'GrayText'}}>
 97            {t('travel.fields.meeting_point')}
 98          </Typography>
 99          <Typography variant="body1">
100            <Link
101              component="a"
102              target="_blank"
103              rel="noopener noreferrer"
104              href={getMapsLink(travel.attributes.meeting)}
105            >
106              {travel.attributes.meeting}
107            </Link>
108          </Typography>
109        </Box>
110      )}
111      {!!travel.attributes.details && (
112        <Box sx={{marginTop: 2}}>
113          <Typography variant="overline" sx={{color: 'GrayText'}}>
114            {t('travel.fields.details')}
115          </Typography>
116          <Typography variant="body1">{travel.attributes.details}</Typography>
117        </Box>
118      )}
119      <LinearProgress
120        sx={{
121          width: 1,
122          mt: 2,
123          mb: 1,
124          backgroundColor: 'LightGray',
125          '& .MuiLinearProgress-bar': {
126            backgroundColor: 'Gray',
127          },
128        }}
129        value={(passengersCount / travel?.attributes.seats) * 100}
130        variant="determinate"
131      />
132      <Box display="flex" justifyContent="space-between" sx={{width: 1}}>
133        <Typography variant="body1" sx={{color: 'GrayText'}}>
134          {t('passenger.assign.seats', {count: availableSeats})}
135        </Typography>
136      </Box>
137    </Box>
138  );
139};
140
141export default Header;