all repos — caroster @ 8348766d9bcad4a9f09713120ea7589e9fed3881

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

feat: 💄 Improve car selection modal


#237
Simon Mulquin simon@octree.ch
Thu, 03 Feb 2022 08:59:43 +0000
commit

8348766d9bcad4a9f09713120ea7589e9fed3881

parent

82a6b00ced5640055e8caff7e67636e5746cc112

M frontend/containers/TravelColumns/index.tsxfrontend/containers/TravelColumns/index.tsx

@@ -37,7 +37,6 @@ const slider = useRef(null);

const {t} = useTranslation(); const tourStep = useTourStore(s => s.step); const addToast = useToastStore(s => s.addToast); - const [updateTravel] = useUpdateTravelMutation(); const {addToEvent} = useAddToEvents(); const {user} = useProfile(); const classes = useStyles();

@@ -47,8 +46,10 @@ } | null>(null);

const [addPassengerToWaitingListContext, toggleNewPassengerToWaitingList] = useState<NewPassengerDialogContext | null>(null); const {addPassengerToTravel} = usePassengersActions(); + const sortedTravels = travels?.slice().sort(sortTravels); const canAddSelf = useMemo(() => { + if (!user) return false; const isInWaitingList = event?.waitingList?.some( passenger => passenger.user?.id === user.id );

@@ -75,6 +76,14 @@ },

}); }; + const slideToTravel = (travelId: string) => { + const travelIndex = sortedTravels.findIndex( + travel => travel.id === travelId + ); + const slideIndex = travelIndex + 1; + slider.current.slickGoTo(slideIndex); + }; + // On tour step changes : component update useEffect(() => { onTourChange(slider.current);

@@ -87,34 +96,28 @@ <div className={classes.slider}>

<Slider ref={slider} {...sliderSettings}> <Container maxWidth="sm" className={classes.slide}> <WaitingList + slideToTravel={slideToTravel} canAddSelf={canAddSelf} getToggleNewPassengerDialogFunction={(addSelf: boolean) => () => toggleNewPassengerToWaitingList({addSelf})} /> </Container> - {travels - ?.slice() - .sort(sortTravels) - .map(travel => ( - <Container - key={travel.id} - maxWidth="sm" - className={classes.slide} - > - <Travel - travel={travel} - {...props} - canAddSelf={canAddSelf} - getAddPassengerFunction={(addSelf: boolean) => () => { - if (addSelf) { - return addSelfToTravel(travel); - } else { - return toggleNewPassengerToTravel({travel}); - } - }} - /> - </Container> - ))} + {sortedTravels?.map(travel => ( + <Container key={travel.id} maxWidth="sm" className={classes.slide}> + <Travel + travel={travel} + {...props} + canAddSelf={canAddSelf} + getAddPassengerFunction={(addSelf: boolean) => () => { + if (addSelf) { + return addSelfToTravel(travel); + } else { + return toggleNewPassengerToTravel({travel}); + } + }} + /> + </Container> + ))} <Container maxWidth="sm" className={classes.slide}> <AddTravel {...props} /> </Container>
M frontend/containers/WaitingList/TravelDialog.tsxfrontend/containers/WaitingList/TravelDialog.tsx

@@ -1,13 +1,17 @@

import {forwardRef} from 'react'; +import moment from 'moment'; +import Link from '@material-ui/core/Link'; +import Typography from '@material-ui/core/Typography'; +import Button from '@material-ui/core/Button'; import Slide from '@material-ui/core/Slide'; import Dialog from '@material-ui/core/Dialog'; import AppBar from '@material-ui/core/AppBar'; import Toolbar from '@material-ui/core/Toolbar'; -import ListItemText from '@material-ui/core/ListItemText'; import ListItem from '@material-ui/core/ListItem'; import List from '@material-ui/core/List'; import IconButton from '@material-ui/core/IconButton'; import Icon from '@material-ui/core/Icon'; +import Box from '@material-ui/core/Box'; import {makeStyles} from '@material-ui/core/styles'; import {useTranslation} from 'react-i18next';

@@ -27,6 +31,9 @@ <Toolbar>

<IconButton onClick={onClose} color="inherit"> <Icon>arrow_back_ios</Icon> </IconButton> + <Typography variant="h5"> + {t('passenger.creation.available_cars')} + </Typography> </Toolbar> </AppBar> <div className={classes.offset}>

@@ -37,15 +44,42 @@ const counter = `${passengers} / ${travel?.vehicle?.seats}`;

return ( <ListItem key={i} - button divider disabled={passengers === travel.seats} - onClick={() => onSelect(travel)} + className={classes.listItem} > - <ListItemText - primary={travel.vehicle?.name} - secondary={t('passenger.creation.seats', {seats: counter})} - /> + <Box className={classes.rtlBox}> + <Box className={classes.info}> + <Typography variant="subtitle1" className={classes.date}> + {t('passenger.creation.departure')} + {moment(travel.departure).format('LLLL')} + </Typography> + <Link + target="_blank" + rel="noreferrer" + href={`https://www.google.com/maps/search/?api=1&query=${encodeURIComponent( + travel.meeting + )}`} + onClick={e => e.preventDefault} + > + {travel.meeting} + </Link> + </Box> + <Box className={classes.info}> + <Typography variant="h6">{travel.vehicle?.name}</Typography> + <Typography variant="body2"> + {t('passenger.creation.seats', {seats: counter})} + </Typography> + </Box> + </Box> + <Button + color="primary" + variant="contained" + onClick={() => onSelect(travel)} + className={classes.button} + > + {t('passenger.creation.assign')} + </Button> </ListItem> ); })}

@@ -62,6 +96,39 @@

const useStyles = makeStyles(theme => ({ offset: { paddingTop: theme.spacing(7), + }, + rtlBox: { + display: 'flex', + padding: 0, + margin: 0, + direction: 'rtl', + [theme.breakpoints.down('sm')]: { + display: 'block', + paddingBottom: theme.spacing(1), + }, + }, + info: { + padding: theme.spacing(0, 4, 0, 0), + [theme.breakpoints.down('sm')]: { + padding: theme.spacing(0.5, 1), + width: '100%', + textAlign: 'left', + }, + }, + listItem: { + display: 'flex', + justifyContent: 'space-between', + [theme.breakpoints.down('sm')]: { + display: 'block', + textAlign: 'center', + }, + }, + date: { + textTransform: 'capitalize', + padding: theme.spacing(0, 0, 0.5, 0), + }, + button: { + padding: theme.spacing(1, 15), }, }));
M frontend/containers/WaitingList/index.tsxfrontend/containers/WaitingList/index.tsx

@@ -21,11 +21,13 @@

interface Props { getToggleNewPassengerDialogFunction: (addSelf: boolean) => () => void; canAddSelf: boolean; + slideToTravel: (travelId: string) => void; } const WaitingList = ({ getToggleNewPassengerDialogFunction, canAddSelf, + slideToTravel, }: Props) => { const classes = useStyles(); const {t} = useTranslation();

@@ -68,7 +70,11 @@ ),

}, onError, - onSucceed: () => setAddingPassenger(null), + onSucceed: () => { + setAddingPassenger(null); + slideToTravel(travel.id); + addToast(t('passenger.success.added_to_car', {name: addingPassenger.name})); + }, }), }); },
M frontend/locales/en.jsonfrontend/locales/en.json

@@ -214,7 +214,10 @@ "seats": "{{count}} seat available",

"seats_plural": "{{count}} seats available" }, "creation": { - "seats": "Number of passengers: {{seats}}" + "seats": "Number of passengers: {{seats}}", + "departure": "Departure: ", + "assign": "Assign", + "available_cars": "Available cars" }, "actions": { "remove_alert": "Are you sure you want to remove <italic> <bold> {{name}} </bold> </italic> from the waitlist?",
M frontend/locales/fr.jsonfrontend/locales/fr.json

@@ -213,7 +213,10 @@ "seats": "{{count}} place disponible",

"seats_plural": "{{count}} places disponibles" }, "creation": { - "seats": "Nombre de passagers: {{seats}}" + "seats": "Nombre de passagers: {{seats}}", + "departure": "Depart: ", + "assign": "Placer", + "available_cars": "Voitures disponibles" }, "actions": { "remove_alert": "Voulez-vous vraiment supprimer <italic><bold>{{name}}</bold></italic> de la liste d'attente ?",