all repos — caroster @ 7aa17436c75503123cefb51191e8a757883333e9

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

frontend/containers/PassengersList/Passenger.tsx (view raw)

  1import {ReactNode} from 'react';
  2import {
  3  ListItemAvatar,
  4  ListItemIcon,
  5  ListItemText,
  6  Chip,
  7  Box,
  8  Typography,
  9  Icon,
 10  useTheme,
 11} from '@mui/material';
 12import {useTranslation} from 'next-i18next';
 13import useProfile from '../../hooks/useProfile';
 14import {PassengerEntity} from '../../generated/graphql';
 15import usePermissions from '../../hooks/usePermissions';
 16
 17interface Props {
 18  passenger?: PassengerEntity;
 19  isTravel?: boolean;
 20  Actions?: (props: {passenger: PassengerEntity}) => ReactNode;
 21}
 22
 23const Passenger = (props: Props) => {
 24  const {passenger, isTravel, Actions} = props;
 25  const theme = useTheme();
 26  const {t} = useTranslation();
 27  const {
 28    userPermissions: {canSeeFullName},
 29  } = usePermissions();
 30
 31  const {userId} = useProfile();
 32  const isUser = `${userId}` === passenger?.attributes.user?.data?.id;
 33
 34  if (passenger) {
 35    return (
 36      <Box
 37        aria-label="user informations"
 38        sx={{
 39          display: 'flex',
 40          alignItems: 'center',
 41          justifyContent: 'space-between',
 42          width: '100%',
 43          padding: 0,
 44        }}
 45      >
 46        <ListItemText
 47          primary={
 48            <Box
 49              sx={{
 50                overflow: 'hidden',
 51                textOverflow: 'ellipsis',
 52                whiteSpace: 'nowrap',
 53              }}
 54            >
 55              <Icon fontSize="inherit" sx={{verticalAlign: 'middle', mr: 0.5}}>
 56                person_outlined
 57              </Icon>
 58              <Typography
 59                component="span"
 60                variant="body1"
 61                sx={{
 62                  overflow: 'hidden',
 63                  textOverflow: 'ellipsis',
 64                  whiteSpace: 'nowrap',
 65                }}
 66              >
 67                {getPassengerName(passenger, canSeeFullName() || isUser)}
 68              </Typography>
 69              {isUser && (
 70                <Chip
 71                  sx={{ml: 1}}
 72                  label={t('generic.me')}
 73                  variant="outlined"
 74                  size="small"
 75                />
 76              )}
 77              {!isTravel && (
 78                <Typography
 79                  sx={{pl: 1, color: 'GrayText'}}
 80                  component="span"
 81                  variant="caption"
 82                >
 83                  {passenger.attributes.location}
 84                </Typography>
 85              )}
 86            </Box>
 87          }
 88        />
 89        <Actions passenger={passenger} />
 90      </Box>
 91    );
 92  } else {
 93    return (
 94      <>
 95        <ListItemAvatar>
 96          <ListItemIcon color="disabled">
 97            <Icon>person</Icon>
 98          </ListItemIcon>
 99        </ListItemAvatar>
100        <ListItemText
101          primary={t('travel.passengers.empty')}
102          sx={{color: theme.palette.text.secondary}}
103        />
104      </>
105    );
106  }
107};
108
109const getPassengerName = (
110  passenger: PassengerEntity,
111  canSeeFullName: boolean
112) => {
113  const hideName = (name: string) => (canSeeFullName ? name : `${name[0]}.`);
114
115  if (passenger.attributes.name && passenger.attributes.lastname)
116    return `${passenger.attributes.name} ${hideName(
117      passenger.attributes.lastname
118    )}`;
119
120  const linkedUser = passenger.attributes?.user?.data?.attributes;
121  if (linkedUser?.firstName && linkedUser?.lastName)
122    return `${linkedUser.firstName} ${hideName(linkedUser.lastName)}`;
123
124  return passenger.attributes.name;
125};
126
127export default Passenger;