all repos — caroster @ fda8dfd8f0c5653fd865054042ea1423dbb07d12

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

feat: 🗃️ Set passenger as a model
Tim Izzo tim@octree.ch
Fri, 20 May 2022 12:40:22 +0200
commit

fda8dfd8f0c5653fd865054042ea1423dbb07d12

parent

2d426f3ead783465e40efb9d91142388b5ec43da

M backend/api/event/event.test.jsbackend/api/event/event.test.js

@@ -28,7 +28,7 @@ email: 'test@example.org',

date: '2022-01-12', address: 'Uni-mail, Geneva, CH', uuid: '00000000-0000-0000-0000-000000000000', - waitingList: expect.any(Array), + waitingPassengers: expect.any(Array), }) ); expect(result).toEqual(
M backend/api/event/models/event.settings.jsonbackend/api/event/models/event.settings.json

@@ -49,6 +49,10 @@ },

"description": { "type": "text", "maxLength": 250 + }, + "waitingPassengers": { + "via": "event", + "collection": "passenger" } } }
M backend/api/event/services/event.jsbackend/api/event/services/event.js

@@ -13,7 +13,7 @@ 'id',

'date', 'address', 'position', - 'waitingList', + 'waitingPassengers', 'travels', 'created_at', 'updated_at',

@@ -23,11 +23,11 @@ const {STRAPI_URL = ''} = process.env;

module.exports = { sanitize: event => { - const waitingList = event?.waitingList?.map(list => + const waitingPassengers = event?.waitingPassengers?.map(list => _pick(list, ['id', 'name', 'location', 'user']) ); const sanitizedEvent = _pick(event, PUBLIC_FIELDS); - return {...sanitizedEvent, waitingList}; + return {...sanitizedEvent, waitingPassengers}; }, sendDailyRecap: async event => {

@@ -56,7 +56,7 @@ },

{ event, eventLink: `${STRAPI_URL}/e/${event.uuid}`, - waitingListCount: event.waitingList?.length || 0, + waitingPassengersCount: event.waitingPassengers?.length || 0, travelsCount: event.travels?.length || 0, newTravelsCount: newTravels?.length || 0, }
A backend/api/passenger/controllers/passenger.js

@@ -0,0 +1,8 @@

+'use strict'; + +/** + * Read the documentation (https://strapi.io/documentation/developer-docs/latest/development/backend-customization.html#core-controllers) + * to customize this controller + */ + +module.exports = {};
A backend/api/passenger/models/passenger.js

@@ -0,0 +1,8 @@

+'use strict'; + +/** + * Read the documentation (https://strapi.io/documentation/developer-docs/latest/development/backend-customization.html#lifecycle-hooks) + * to customize this model + */ + +module.exports = {};
A backend/api/passenger/models/passenger.settings.json

@@ -0,0 +1,38 @@

+{ + "kind": "collectionType", + "collectionName": "passengers", + "info": { + "name": "Passenger", + "description": "" + }, + "options": { + "increments": true, + "timestamps": true, + "draftAndPublish": false + }, + "attributes": { + "name": { + "type": "string", + "required": true + }, + "email": { + "type": "email" + }, + "location": { + "type": "string" + }, + "user": { + "plugin": "users-permissions", + "model": "user", + "via": "passengers" + }, + "event": { + "via": "waitingPassengers", + "model": "event" + }, + "travel": { + "via": "passengers", + "model": "travel" + } + } +}
A backend/api/passenger/services/passenger.js

@@ -0,0 +1,8 @@

+'use strict'; + +/** + * Read the documentation (https://strapi.io/documentation/developer-docs/latest/development/backend-customization.html#core-services) + * to customize this service + */ + +module.exports = {};
M backend/api/travel/models/travel.jsbackend/api/travel/models/travel.js

@@ -6,6 +6,10 @@ const {STRAPI_URL = ''} = process.env;

module.exports = { lifecycles: { + async afterCreate(result) { + sendEmailsToWaitingPassengers(result); + }, + async beforeUpdate(query, update) { const travel = await strapi.services.travel.findOne(query); if (update.passengers && travel?.vehicle) {

@@ -14,16 +18,34 @@ throw new Error('no_enough_seats');

} }, - async afterCreate(result) { - sendEmailsToWaitingList(result); + async afterUpdate(result) { + const {passengers = [], seats, event} = result; + const overflowPassengers = passengers.slice(seats); + + if (overflowPassengers.length > 0) { + await Promise.all( + overflowPassengers.map(movePassengerToWaitingList(event.id)) + ); + } + }, + + async beforeDelete(params) { + const travel = await strapi.services.travel.findOne(params); + const {passengers = []} = travel; + + await Promise.all( + passengers.map(movePassengerToWaitingList(travel.event.id)) + ); }, }, }; -const sendEmailsToWaitingList = async travel => { +const sendEmailsToWaitingPassengers = async travel => { const event = travel.event; - const eventWaitingList = event?.waitingList || []; - const userEmails = eventWaitingList.map(user => user.email).filter(Boolean); + const eventWaitingPassengers = event?.waitingPassengers || []; + const userEmails = eventWaitingPassengers + .map(user => user.email) + .filter(Boolean); const templateId = await strapi.plugins[ 'email-designer' ].services.template.getId('waitinglist_notif');

@@ -52,3 +74,12 @@ }. Error: ${JSON.stringify(error)}`

); } }; + +const movePassengerToWaitingList = eventId => async passenger => + strapi.services.passenger.update( + {id: passenger.id}, + { + travel: null, + event: eventId, + } + );
M backend/api/travel/models/travel.settings.jsonbackend/api/travel/models/travel.settings.json

@@ -20,7 +20,7 @@ },

"details": { "type": "text" }, - "passengers": { + "passengersCompo": { "type": "component", "repeatable": true, "component": "passenger.passenger"

@@ -39,6 +39,10 @@ "min": 0

}, "phone_number": { "type": "string" + }, + "passengers": { + "via": "travel", + "collection": "passenger" } } }
M backend/config/permissions.jsonbackend/config/permissions.json

@@ -21,6 +21,10 @@ "name": "event",

"actions": ["create", "update", "findone"] }, { + "name": "passenger", + "actions": ["create", "delete", "update"] + }, + { "name": "page", "actions": ["find", "findone"] },

@@ -50,6 +54,10 @@ },

{ "name": "event", "actions": ["create", "update", "findone"] + }, + { + "name": "passenger", + "actions": ["create", "delete", "update"] }, { "name": "page",
M backend/extensions/users-permissions/models/User.settings.jsonbackend/extensions/users-permissions/models/User.settings.json

@@ -97,6 +97,10 @@ },

"vehicles": { "via": "user", "collection": "vehicle" + }, + "passengers": { + "via": "user", + "collection": "passenger" } } }
A backend/migrations/passengers-model.js

@@ -0,0 +1,62 @@

+/** + * Migrate passengers components to passengers model + * for event waiting list & travel passengers + * + */ + +const Strapi = require('strapi'); + +const main = async () => { + await Strapi().load(); + + /** + * Migrate event waiting list + */ + const events = await strapi.services.event.find({_limit: -1}); + for (let i = 0; i < events.length; i++) { + const event = events[i]; + const {waitingList} = event; + + if (!waitingList || waitingList.length === 0) continue; + + for (let j = 0; j < waitingList.length; j++) { + const passengerCompo = waitingList[j]; + const passengerModel = await strapi.services.passenger.create({ + name: passengerCompo.name, + email: passengerCompo.email, + location: passengerCompo.location, + user: passengerCompo.user?.id, + event: event.id, + }); + console.log(passengerModel); + } + } + + /** + * Migrate travel passengers + */ + const travels = await strapi.services.travel.find({_limit: -1}); + for (let i = 0; i < travels.length; i++) { + const travel = travels[i]; + const {passengers} = travel; + + if (!passengers || passengers.length === 0) continue; + + for (let j = 0; j < passengers.length; j++) { + const passengerCompo = passengers[j]; + const passengerModel = await strapi.services.passenger.create({ + name: passengerCompo.name, + email: passengerCompo.email, + location: passengerCompo.location, + user: passengerCompo.user?.id, + travel: travel.id, + }); + console.log(passengerModel); + } + } + + strapi.log.debug('Done.'); + process.exit(0); +}; + +main();
M frontend/containers/NewPassengerDialog/AddPassengerToTravel.tsxfrontend/containers/NewPassengerDialog/AddPassengerToTravel.tsx

@@ -33,7 +33,7 @@ const [name, setName] = useState('');

const [email, setEmail] = useState(''); const emailValidated = validateEmail(email); const canAddPassenger = !!name; - const {addPassengerToTravel} = usePassengersActions(); + const {addPassenger} = usePassengersActions(); const onSubmit = async (e: FormEvent) => { e.preventDefault();

@@ -43,7 +43,7 @@ name,

}; try { - await addPassengerToTravel({passenger, travel}); + await addPassenger({...passenger, travel: travel.id}); addToEvent(event.id); addToast(t('passenger.success.added_to_car', {name})); toggle();

@@ -78,7 +78,7 @@ <AddPassengerCommonFields

email={email} emailError={!emailValidated} setEmail={setEmail} - optionalEmail + optionalEmail name={name} setName={setName} />
M frontend/containers/NewPassengerDialog/AddPassengerToWaitingList.tsxfrontend/containers/NewPassengerDialog/AddPassengerToWaitingList.tsx

@@ -10,13 +10,14 @@ import {useTranslation} from 'react-i18next';

import useToastStore from '../../stores/useToastStore'; import useEventStore from '../../stores/useEventStore'; import useAddToEvents from '../../hooks/useAddToEvents'; -import usepassengersActions from '../../hooks/usePassengersActions'; +import usePassengersActions from '../../hooks/usePassengersActions'; import useProfile from '../../hooks/useProfile'; import SubmitButton from './SubmitButton'; import Transition from './Transition'; import AddPassengerCommonFields from './AddPassengerCommonFields'; import useStyles from './useStyles'; -import { validateEmail } from './validation'; +import {validateEmail} from './validation'; +import {PassengerInput} from '../../generated/graphql'; interface Props { toggle: () => void;

@@ -38,28 +39,25 @@ const emailValidated = validateEmail(email);

const [location, setlocation] = useState(''); const canAddPassenger = !!name && !!email; const {user} = useProfile(); - const {addPassengerToWaitingList} = usepassengersActions(); + const {addPassenger} = usePassengersActions(); - const addPassenger = async (e: FormEvent) => { + const onAddPassenger = async (e: FormEvent) => { e.preventDefault(); - const passenger = - addSelf && user - ? { - user: user, - email: user.email, - name: user.username, - location, - } - : { - email, - name, - location, - }; + let passenger: PassengerInput = { + email, + name, + location, + }; + if (addSelf && user) + passenger = { + user: user.id, + email: user.email, + name: user.username, + location, + }; + try { - await addPassengerToWaitingList({ - passenger, - event, - }); + await addPassenger({...passenger, event: event.id}); addToEvent(event.id); addToast( t(

@@ -84,7 +82,7 @@ open={open}

onClose={toggle} TransitionComponent={Transition} > - <form onSubmit={addPassenger}> + <form onSubmit={onAddPassenger}> <DialogTitle className={classes.title}> {t('travel.passengers.register_to_waiting_list')} <Icon
M frontend/containers/NewPassengerDialog/index.tsxfrontend/containers/NewPassengerDialog/index.tsx

@@ -1,7 +1,4 @@

import AddPassengerToTravel from './AddPassengerToTravel'; import AddPassengerToWaitingList from './AddPassengerToWaitingList'; -export { - AddPassengerToTravel, - AddPassengerToWaitingList -}+export {AddPassengerToTravel, AddPassengerToWaitingList};
D frontend/containers/PassengersList/Input.tsx

@@ -1,95 +0,0 @@

-import {useState} from 'react'; -import Box from '@material-ui/core/Box'; -import TextField from '@material-ui/core/TextField'; -import IconButton from '@material-ui/core/IconButton'; -import Divider from '@material-ui/core/Divider'; -import Icon from '@material-ui/core/Icon'; -import {useTranslation} from 'react-i18next'; -import {EditComponentPassengerPassengerInput as PassengerInput} from '../../generated/graphql'; -import {makeStyles} from '@material-ui/core'; -import {isValidEmail} from '../../lib/formValidation'; - -interface Props { - addPassenger: (passenger: PassengerInput) => void; - id: number; - isTravel?: boolean; -} - -const Input = (props: Props) => { - const {addPassenger, id, isTravel} = props; - const [name, setName] = useState(''); - const [email, setEmail] = useState(''); - const [error, setError] = useState<string>(); - const classes = useStyles({showEmail: !!name}); - const {t} = useTranslation(); - - const onSave = () => { - if (email && !isValidEmail(email)) setError('email'); - else if (name) { - addPassenger({name, email}); - setName(''); - setEmail(''); - setError(null); - } - }; - - const onKeyDown = e => { - if (e.keyCode === 13) onSave(); - }; - - return ( - <Box pb={1}> - <Box display="flex" flexDirection="row" alignItems="center" px={2}> - <TextField - value={name} - onChange={e => setName(e.target.value)} - onKeyDown={onKeyDown} - fullWidth - label={t('travel.passengers.add')} - id={`NewPassenger-${id}-name`} - name={`passenger-${id}-name`} - /> - <IconButton - color="primary" - edge="end" - size="small" - disabled={!name} - onClick={onSave} - tabIndex={-1} - > - <Icon>check</Icon> - </IconButton> - </Box> - <Box pl={2} pt={1} pr={5} mb={2} className={classes.emailBox}> - <TextField - value={email} - onChange={e => setEmail(e.target.value)} - onKeyDown={onKeyDown} - fullWidth - label={t`passenger.input.email`} - id={`NewPassenger-${id}-email`} - name={`passenger-${id}-email`} - helperText={ - isTravel - ? t`passenger.input.email_helper_travel` - : t`passenger.input.email_helper` - } - error={error === 'email'} - /> - </Box> - <Divider /> - </Box> - ); -}; - -const useStyles = makeStyles(theme => ({ - emailBox: { - //We need this to prevent the placeholder to unexpectedly show when the element is selected with tab key - visibility: ({showEmail}) => (showEmail ? 'visible' : 'hidden'), - transition: 'all 0.3s ease', - maxHeight: ({showEmail}) => (showEmail ? '6rem' : 0), - overflow: 'hidden', - }, -})); - -export default Input;
M frontend/containers/PassengersList/Passenger.tsxfrontend/containers/PassengersList/Passenger.tsx

@@ -5,12 +5,12 @@ import ListItemText from '@material-ui/core/ListItemText';

import Icon from '@material-ui/core/Icon'; import {makeStyles} from '@material-ui/core/styles'; import {useTranslation} from 'react-i18next'; -import {ComponentPassengerPassenger} from '../../generated/graphql'; +import {Passenger as PassengerType} from '../../generated/graphql'; import useProfile from '../../hooks/useProfile'; import Chip from '@material-ui/core/Chip'; interface Props { - passenger?: ComponentPassengerPassenger; + passenger?: PassengerType; button?: ReactNode; isVehicle?: boolean; }
M frontend/containers/PassengersList/index.tsxfrontend/containers/PassengersList/index.tsx

@@ -2,12 +2,10 @@ import List from '@material-ui/core/List';

import ListItem from '@material-ui/core/ListItem'; import {makeStyles} from '@material-ui/core/styles'; import Passenger from './Passenger'; -import { - ComponentPassengerPassenger, -} from '../../generated/graphql'; +import {Passenger as PassengerType} from '../../generated/graphql'; interface Props { - passengers: ComponentPassengerPassenger[]; + passengers: PassengerType[]; Button: ({ onClick, disabled,
M frontend/containers/Travel/useActions.tsfrontend/containers/Travel/useActions.ts

@@ -3,11 +3,11 @@ import useEventStore from '../../stores/useEventStore';

import useToastStore from '../../stores/useToastStore'; import { useUpdateTravelMutation, - useUpdateEventMutation, useDeleteTravelMutation, EventByUuidDocument, Travel, EditTravelInput, + useUpdatePassengerMutation, } from '../../generated/graphql'; interface Props {

@@ -19,107 +19,45 @@ const {travel} = props;

const {t} = useTranslation(); const event = useEventStore(s => s.event); const addToast = useToastStore(s => s.addToast); - const [updateEventMutation] = useUpdateEventMutation(); const [updateTravelMutation] = useUpdateTravelMutation(); const [deleteTravelMutation] = useDeleteTravelMutation(); + const [updatePassenger] = useUpdatePassengerMutation(); const sendPassengerToWaitingList = async (passengerId: string) => { - if (travel?.passengers) { - try { - const {id, ...removedPassenger} = travel.passengers?.find( - item => item.id === passengerId - ); - if (!removedPassenger) { - throw 'No corresponding passenger'; - } - const existingPassengers = - travel.passengers?.map(({__typename, user, ...item}) => - user && user.id ? {...item, user: user.id} : item - ) || []; - const waitingList = [...event.waitingList, removedPassenger].map( - ({__typename, user, ...item}) => - user && user.id ? {...item, user: user.id} : item - ); - const passengers = existingPassengers.filter( - item => item.id !== passengerId - ); - await updateEventMutation({ - variables: { - uuid: event.uuid, - eventUpdate: { - waitingList, - }, - }, - }); - await updateTravelMutation({ - variables: { - id: travel.id, - travelUpdate: { - passengers, - }, + try { + await updatePassenger({ + variables: { + id: passengerId, + passengerUpdate: { + event: event.id, + travel: null, }, - refetchQueries: ['eventByUUID'], - }); - } catch (error) { - console.error(error); - addToast(t('travel.errors.cant_remove_passenger')); - } + }, + refetchQueries: ['eventByUUID'], + }); + } catch (error) { + console.error(error); + addToast(t('travel.errors.cant_remove_passenger')); } }; const updateTravel = async (travelUpdate: EditTravelInput) => { try { - // If new seats count is under current passengers count, put excedent in event waiting list - // TODO: Move these logics to backend - if (travel.passengers?.length > travelUpdate.seats) { - const lostPassengers = travel.passengers.slice(travelUpdate.seats); - if (lostPassengers.length > 0) - await updateEventMutation({ - variables: { - uuid: event.uuid, - eventUpdate: { - waitingList: formatPassengers([ - ...(event.waitingList || []), - ...lostPassengers.map(({name}) => ({name})), - ]), - }, - }, - refetchQueries: ['eventByUUID'], - }); - } await updateTravelMutation({ variables: { id: travel.id, - travelUpdate: { - ...travelUpdate, - passengers: formatPassengers(travel.passengers, travel.seats), - }, + travelUpdate, }, + refetchQueries: ['eventByUUID'], }); } catch (error) { console.error(error); addToast(t('travel.errors.cant_update')); } - return false; }; const removeTravel = async () => { try { - // Put passengers in event waiting list (if any) - // TODO Move these logics to backend and delete vehicle if no user linked - if (Array.isArray(travel?.passengers) && travel.passengers.length > 0) { - await updateEventMutation({ - variables: { - uuid: event.uuid, - eventUpdate: { - waitingList: formatPassengers([ - ...(event.waitingList || []), - ...travel.passengers.map(({user, name}) => ({name, user})), - ]), - }, - }, - }); - } await deleteTravelMutation({ variables: { id: travel.id,

@@ -136,14 +74,6 @@ }

}; return {sendPassengerToWaitingList, updateTravel, removeTravel}; -}; - -const formatPassengers = (passengers = [], seats: number = 1000) => { - if (!passengers) return []; - return passengers.slice(0, seats).map(({__typename, user, ...passenger}) => ({ - ...passenger, - user: user?.id, - })); }; export default useActions;
M frontend/containers/TravelColumns/index.tsxfrontend/containers/TravelColumns/index.tsx

@@ -3,9 +3,7 @@ import {makeStyles} from '@material-ui/core/styles';

import Container from '@material-ui/core/Container'; import Slider from 'react-slick'; import {useTranslation} from 'react-i18next'; -import { - Travel as TravelType, -} from '../../generated/graphql'; +import {Travel as TravelType} from '../../generated/graphql'; import useEventStore from '../../stores/useEventStore'; import useTourStore from '../../stores/useTourStore'; import useToastStore from '../../stores/useToastStore';

@@ -42,16 +40,14 @@ const classes = useStyles();

const [newPassengerTravelContext, toggleNewPassengerToTravel] = useState<{ travel: TravelType; } | null>(null); - const [ - addPassengerToWaitingListContext, - toggleNewPassengerToWaitingList, - ] = useState<NewPassengerDialogContext | null>(null); - const {addPassengerToTravel} = usePassengersActions(); + const [addPassengerToWaitingListContext, toggleNewPassengerToWaitingList] = + useState<NewPassengerDialogContext | null>(null); + const {addPassenger} = usePassengersActions(); const sortedTravels = travels?.slice().sort(sortTravels); const canAddSelf = useMemo(() => { if (!user) return false; - const isInWaitingList = event?.waitingList?.some( + const isInWaitingList = event?.waitingPassengers?.some( passenger => passenger.user?.id === `${user.id}` ); const isInTravel = event?.travels.some(travel =>

@@ -61,20 +57,18 @@ return !(isInWaitingList || isInTravel);

}, [event, user]); const addSelfToTravel = async (travel: TravelType) => { - const passenger = { - user: user, - email: user.email, - name: user.username, - }; - - return addPassengerToTravel({ - passenger, - travel, - onSucceed: () => { - addToEvent(event.id); - addToast(t('passenger.success.added_self_to_car')); - }, - }); + try { + await addPassenger({ + user: user?.id, + email: user.email, + name: user.username, + travel: travel.id, + }); + addToEvent(event.id); + addToast(t('passenger.success.added_self_to_car')); + } catch (error) { + console.error(error); + } }; const slideToTravel = (travelId: string) => {

@@ -186,13 +180,14 @@ position: 'static',

'& li': { display: 'block', '& button:before': { - fontSize: '20px' + fontSize: '20px', }, }, }, - '& .slick-dots li:first-child button:before, & .slick-dots li:last-child button:before': { - color: theme.palette.primary.main, - }, + '& .slick-dots li:first-child button:before, & .slick-dots li:last-child button:before': + { + color: theme.palette.primary.main, + }, }, slider: { flexGrow: 1,
M frontend/containers/WaitingList/TravelDialog.tsxfrontend/containers/WaitingList/TravelDialog.tsx

@@ -14,7 +14,7 @@ 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'; -import {ComponentPassengerPassenger, Travel} from '../../generated/graphql'; +import {Passenger, Travel} from '../../generated/graphql'; import getMapsLink from '../../utils/getMapsLink'; import Copylink from '../../components/CopyLink'; import useToastStore from '../../stores/useToastStore';

@@ -22,7 +22,7 @@

interface Props { eventName: string; travels: Array<Travel>; - passenger: ComponentPassengerPassenger; + passenger: Passenger; open: boolean; onClose: () => void; onSelect: (travel: Travel) => void;
M frontend/containers/WaitingList/index.tsxfrontend/containers/WaitingList/index.tsx

@@ -9,7 +9,6 @@ import clsx from 'clsx';

import {Trans, useTranslation} from 'react-i18next'; import useToastStore from '../../stores/useToastStore'; import useEventStore from '../../stores/useEventStore'; -import useAddToEvents from '../../hooks/useAddToEvents'; import PassengersList from '../PassengersList'; import RemoveDialog from '../RemoveDialog'; import AddPassengerButtons from '../AddPassengerButtons';

@@ -33,14 +32,12 @@ const classes = useStyles();

const {t} = useTranslation(); const event = useEventStore(s => s.event); const addToast = useToastStore(s => s.addToast); - const {addToEvent} = useAddToEvents(); const [isEditing, toggleEditing] = useReducer(i => !i, false); const [removingPassenger, setRemovingPassenger] = useState(null); const [addingPassenger, setAddingPassenger] = useState(null); const travels = event?.travels?.length > 0 ? event.travels.slice().sort(sortTravels) : []; - const {addPassengerToTravel, removePassengerFromWaitingList} = - usePassengersActions(); + const {updatePassenger, removePassenger} = usePassengersActions(); const availability = useMemo(() => { if (!travels) return;

@@ -51,28 +48,14 @@ return count + vehicle.seats - passengers.length;

}, 0); }, [travels]); - const removePassengerFromWaitingListFallBack = useCallback( - removePassengerFromWaitingList, - [event] - ); + const removePassengerCallback = useCallback(removePassenger, [event]); const selectTravel = useCallback( async travel => { - const {id, ...passenger} = addingPassenger; - try { - await addPassengerToTravel({ - travel, - passenger, - }); - await removePassengerFromWaitingListFallBack({ - passenger: addingPassenger, - event: { - ...event, - waitingList: event.waitingList.filter( - item => item.id !== addingPassenger.id - ), - }, + await updatePassenger(addingPassenger.id, { + event: null, + travel: travel.id, }); setAddingPassenger(null); slideToTravel(travel.id);

@@ -91,7 +74,7 @@ );

const onPress = useCallback( (passengerId: string) => { - const selectedPassenger = event.waitingList.find( + const selectedPassenger = event.waitingPassengers.find( item => item.id === passengerId ); if (isEditing) setRemovingPassenger(selectedPassenger);

@@ -102,11 +85,7 @@ );

const onRemove = async () => { try { - await removePassengerFromWaitingListFallBack({ - passenger: removingPassenger, - event, - }); - addToEvent(event.id); + await removePassengerCallback(removingPassenger.id); } catch (error) { console.error(error); addToast(t('passenger.errors.cant_remove_passenger'));

@@ -129,7 +108,7 @@ <IconButton

size="small" color="primary" className={classes.editBtn} - disabled={!event.waitingList?.length} + disabled={!event.waitingPassengers?.length} onClick={toggleEditing} > {isEditing ? <Icon>check</Icon> : <Icon>edit</Icon>}

@@ -147,7 +126,7 @@ variant="waitingList"

/> <Divider /> <PassengersList - passengers={event.waitingList} + passengers={event.waitingPassengers} onPress={onPress} Button={ListButton} />
M frontend/generated/graphql.tsxfrontend/generated/graphql.tsx

@@ -109,6 +109,7 @@ waitingList?: Maybe<Array<Maybe<ComponentPassengerPassenger>>>;

description?: Maybe<Scalars['String']>; users?: Maybe<Array<Maybe<UsersPermissionsUser>>>; travels?: Maybe<Array<Maybe<Travel>>>; + waitingPassengers?: Maybe<Array<Maybe<Passenger>>>; };

@@ -121,6 +122,14 @@ };

export type EventTravelsArgs = { + sort?: Maybe<Scalars['String']>; + limit?: Maybe<Scalars['Int']>; + start?: Maybe<Scalars['Int']>; + where?: Maybe<Scalars['JSON']>; +}; + + +export type EventWaitingPassengersArgs = { sort?: Maybe<Scalars['String']>; limit?: Maybe<Scalars['Int']>; start?: Maybe<Scalars['Int']>;

@@ -225,6 +234,7 @@ uuid?: Maybe<Scalars['String']>;

waitingList?: Maybe<Array<Maybe<ComponentPassengerPassengerInput>>>; travels?: Maybe<Array<Maybe<Scalars['ID']>>>; description?: Maybe<Scalars['String']>; + waitingPassengers?: Maybe<Array<Maybe<Scalars['ID']>>>; created_by?: Maybe<Scalars['ID']>; updated_by?: Maybe<Scalars['ID']>; newsletter?: Maybe<Scalars['Boolean']>;

@@ -284,7 +294,7 @@ };

-export type Morph = Dependency | Info | UsersPermissionsMe | UsersPermissionsMeRole | UsersPermissionsLoginPayload | UserPermissionsPasswordPayload | Event | EventConnection | EventAggregator | EventGroupBy | EventConnectionId | EventConnectionCreated_At | EventConnectionUpdated_At | EventConnectionName | EventConnectionEmail | EventConnectionDate | EventConnectionAddress | EventConnectionPosition | EventConnectionUuid | EventConnectionDescription | CreateEventPayload | UpdateEventPayload | DeleteEventPayload | Page | PageConnection | PageAggregator | PageGroupBy | PageConnectionId | PageConnectionCreated_At | PageConnectionUpdated_At | PageConnectionName | PageConnectionContent | PageConnectionType | CreatePagePayload | UpdatePagePayload | DeletePagePayload | Settings | UpdateSettingPayload | DeleteSettingPayload | Travel | TravelConnection | TravelAggregator | TravelAggregatorSum | TravelAggregatorAvg | TravelAggregatorMin | TravelAggregatorMax | TravelGroupBy | TravelConnectionId | TravelConnectionCreated_At | TravelConnectionUpdated_At | TravelConnectionMeeting | TravelConnectionDeparture | TravelConnectionDetails | TravelConnectionEvent | TravelConnectionVehicleName | TravelConnectionSeats | TravelConnectionPhone_Number | CreateTravelPayload | UpdateTravelPayload | DeleteTravelPayload | Vehicle | VehicleConnection | VehicleAggregator | VehicleAggregatorSum | VehicleAggregatorAvg | VehicleAggregatorMin | VehicleAggregatorMax | VehicleGroupBy | VehicleConnectionId | VehicleConnectionCreated_At | VehicleConnectionUpdated_At | VehicleConnectionName | VehicleConnectionSeats | VehicleConnectionPhone_Number | VehicleConnectionUser | CreateVehiclePayload | UpdateVehiclePayload | DeleteVehiclePayload | EmailDesignerEmailTemplate | UploadFile | UploadFileConnection | UploadFileAggregator | UploadFileAggregatorSum | UploadFileAggregatorAvg | UploadFileAggregatorMin | UploadFileAggregatorMax | UploadFileGroupBy | UploadFileConnectionId | UploadFileConnectionCreated_At | UploadFileConnectionUpdated_At | UploadFileConnectionName | UploadFileConnectionAlternativeText | UploadFileConnectionCaption | UploadFileConnectionWidth | UploadFileConnectionHeight | UploadFileConnectionFormats | UploadFileConnectionHash | UploadFileConnectionExt | UploadFileConnectionMime | UploadFileConnectionSize | UploadFileConnectionUrl | UploadFileConnectionPreviewUrl | UploadFileConnectionProvider | UploadFileConnectionProvider_Metadata | DeleteFilePayload | UsersPermissionsPermission | UsersPermissionsRole | UsersPermissionsRoleConnection | UsersPermissionsRoleAggregator | UsersPermissionsRoleGroupBy | UsersPermissionsRoleConnectionId | UsersPermissionsRoleConnectionName | UsersPermissionsRoleConnectionDescription | UsersPermissionsRoleConnectionType | CreateRolePayload | UpdateRolePayload | DeleteRolePayload | UsersPermissionsUser | UsersPermissionsUserConnection | UsersPermissionsUserAggregator | UsersPermissionsUserGroupBy | UsersPermissionsUserConnectionId | UsersPermissionsUserConnectionCreated_At | UsersPermissionsUserConnectionUpdated_At | UsersPermissionsUserConnectionUsername | UsersPermissionsUserConnectionFirstName | UsersPermissionsUserConnectionLastName | UsersPermissionsUserConnectionEmail | UsersPermissionsUserConnectionProvider | UsersPermissionsUserConnectionConfirmed | UsersPermissionsUserConnectionBlocked | UsersPermissionsUserConnectionRole | UsersPermissionsUserConnectionOnboardingUser | UsersPermissionsUserConnectionOnboardingCreator | UsersPermissionsUserConnectionLang | CreateUserPayload | UpdateUserPayload | DeleteUserPayload | ComponentPassengerPassenger; +export type Morph = Dependency | Info | UsersPermissionsMe | UsersPermissionsMeRole | UsersPermissionsLoginPayload | UserPermissionsPasswordPayload | Event | EventConnection | EventAggregator | EventGroupBy | EventConnectionId | EventConnectionCreated_At | EventConnectionUpdated_At | EventConnectionName | EventConnectionEmail | EventConnectionDate | EventConnectionAddress | EventConnectionPosition | EventConnectionUuid | EventConnectionDescription | CreateEventPayload | UpdateEventPayload | DeleteEventPayload | Page | PageConnection | PageAggregator | PageGroupBy | PageConnectionId | PageConnectionCreated_At | PageConnectionUpdated_At | PageConnectionName | PageConnectionContent | PageConnectionType | CreatePagePayload | UpdatePagePayload | DeletePagePayload | Passenger | PassengerConnection | PassengerAggregator | PassengerGroupBy | PassengerConnectionId | PassengerConnectionCreated_At | PassengerConnectionUpdated_At | PassengerConnectionName | PassengerConnectionEmail | PassengerConnectionLocation | PassengerConnectionUser | PassengerConnectionEvent | PassengerConnectionTravel | CreatePassengerPayload | UpdatePassengerPayload | DeletePassengerPayload | Settings | UpdateSettingPayload | DeleteSettingPayload | Travel | TravelConnection | TravelAggregator | TravelAggregatorSum | TravelAggregatorAvg | TravelAggregatorMin | TravelAggregatorMax | TravelGroupBy | TravelConnectionId | TravelConnectionCreated_At | TravelConnectionUpdated_At | TravelConnectionMeeting | TravelConnectionDeparture | TravelConnectionDetails | TravelConnectionEvent | TravelConnectionVehicleName | TravelConnectionSeats | TravelConnectionPhone_Number | CreateTravelPayload | UpdateTravelPayload | DeleteTravelPayload | Vehicle | VehicleConnection | VehicleAggregator | VehicleAggregatorSum | VehicleAggregatorAvg | VehicleAggregatorMin | VehicleAggregatorMax | VehicleGroupBy | VehicleConnectionId | VehicleConnectionCreated_At | VehicleConnectionUpdated_At | VehicleConnectionName | VehicleConnectionSeats | VehicleConnectionPhone_Number | VehicleConnectionUser | CreateVehiclePayload | UpdateVehiclePayload | DeleteVehiclePayload | EmailDesignerEmailTemplate | UploadFile | UploadFileConnection | UploadFileAggregator | UploadFileAggregatorSum | UploadFileAggregatorAvg | UploadFileAggregatorMin | UploadFileAggregatorMax | UploadFileGroupBy | UploadFileConnectionId | UploadFileConnectionCreated_At | UploadFileConnectionUpdated_At | UploadFileConnectionName | UploadFileConnectionAlternativeText | UploadFileConnectionCaption | UploadFileConnectionWidth | UploadFileConnectionHeight | UploadFileConnectionFormats | UploadFileConnectionHash | UploadFileConnectionExt | UploadFileConnectionMime | UploadFileConnectionSize | UploadFileConnectionUrl | UploadFileConnectionPreviewUrl | UploadFileConnectionProvider | UploadFileConnectionProvider_Metadata | DeleteFilePayload | UsersPermissionsPermission | UsersPermissionsRole | UsersPermissionsRoleConnection | UsersPermissionsRoleAggregator | UsersPermissionsRoleGroupBy | UsersPermissionsRoleConnectionId | UsersPermissionsRoleConnectionName | UsersPermissionsRoleConnectionDescription | UsersPermissionsRoleConnectionType | CreateRolePayload | UpdateRolePayload | DeleteRolePayload | UsersPermissionsUser | UsersPermissionsUserConnection | UsersPermissionsUserAggregator | UsersPermissionsUserGroupBy | UsersPermissionsUserConnectionId | UsersPermissionsUserConnectionCreated_At | UsersPermissionsUserConnectionUpdated_At | UsersPermissionsUserConnectionUsername | UsersPermissionsUserConnectionFirstName | UsersPermissionsUserConnectionLastName | UsersPermissionsUserConnectionEmail | UsersPermissionsUserConnectionProvider | UsersPermissionsUserConnectionConfirmed | UsersPermissionsUserConnectionBlocked | UsersPermissionsUserConnectionRole | UsersPermissionsUserConnectionOnboardingUser | UsersPermissionsUserConnectionOnboardingCreator | UsersPermissionsUserConnectionLang | CreateUserPayload | UpdateUserPayload | DeleteUserPayload | ComponentPassengerPassenger; export type Mutation = { __typename?: 'Mutation';

@@ -294,6 +304,9 @@ deleteEvent?: Maybe<DeleteEventPayload>;

createPage?: Maybe<CreatePagePayload>; updatePage?: Maybe<UpdatePagePayload>; deletePage?: Maybe<DeletePagePayload>; + createPassenger?: Maybe<CreatePassengerPayload>; + updatePassenger?: Maybe<UpdatePassengerPayload>; + deletePassenger?: Maybe<DeletePassengerPayload>; updateSetting?: Maybe<UpdateSettingPayload>; deleteSetting?: Maybe<DeleteSettingPayload>; createTravel?: Maybe<CreateTravelPayload>;

@@ -359,6 +372,21 @@ input?: Maybe<DeletePageInput>;

}; +export type MutationCreatePassengerArgs = { + input?: Maybe<CreatePassengerInput>; +}; + + +export type MutationUpdatePassengerArgs = { + input?: Maybe<UpdatePassengerInput>; +}; + + +export type MutationDeletePassengerArgs = { + input?: Maybe<DeletePassengerInput>; +}; + + export type MutationUpdateSettingArgs = { input?: Maybe<UpdateSettingInput>; };

@@ -567,6 +595,110 @@ created_by?: Maybe<Scalars['ID']>;

updated_by?: Maybe<Scalars['ID']>; }; +export type Passenger = { + __typename?: 'Passenger'; + id: Scalars['ID']; + created_at: Scalars['DateTime']; + updated_at: Scalars['DateTime']; + name: Scalars['String']; + email?: Maybe<Scalars['String']>; + location?: Maybe<Scalars['String']>; + user?: Maybe<UsersPermissionsUser>; + event?: Maybe<Event>; + travel?: Maybe<Travel>; +}; + +export type PassengerAggregator = { + __typename?: 'PassengerAggregator'; + count?: Maybe<Scalars['Int']>; + totalCount?: Maybe<Scalars['Int']>; +}; + +export type PassengerConnection = { + __typename?: 'PassengerConnection'; + values?: Maybe<Array<Maybe<Passenger>>>; + groupBy?: Maybe<PassengerGroupBy>; + aggregate?: Maybe<PassengerAggregator>; +}; + +export type PassengerConnectionCreated_At = { + __typename?: 'PassengerConnectionCreated_at'; + key?: Maybe<Scalars['DateTime']>; + connection?: Maybe<PassengerConnection>; +}; + +export type PassengerConnectionEmail = { + __typename?: 'PassengerConnectionEmail'; + key?: Maybe<Scalars['String']>; + connection?: Maybe<PassengerConnection>; +}; + +export type PassengerConnectionEvent = { + __typename?: 'PassengerConnectionEvent'; + key?: Maybe<Scalars['ID']>; + connection?: Maybe<PassengerConnection>; +}; + +export type PassengerConnectionId = { + __typename?: 'PassengerConnectionId'; + key?: Maybe<Scalars['ID']>; + connection?: Maybe<PassengerConnection>; +}; + +export type PassengerConnectionLocation = { + __typename?: 'PassengerConnectionLocation'; + key?: Maybe<Scalars['String']>; + connection?: Maybe<PassengerConnection>; +}; + +export type PassengerConnectionName = { + __typename?: 'PassengerConnectionName'; + key?: Maybe<Scalars['String']>; + connection?: Maybe<PassengerConnection>; +}; + +export type PassengerConnectionTravel = { + __typename?: 'PassengerConnectionTravel'; + key?: Maybe<Scalars['ID']>; + connection?: Maybe<PassengerConnection>; +}; + +export type PassengerConnectionUpdated_At = { + __typename?: 'PassengerConnectionUpdated_at'; + key?: Maybe<Scalars['DateTime']>; + connection?: Maybe<PassengerConnection>; +}; + +export type PassengerConnectionUser = { + __typename?: 'PassengerConnectionUser'; + key?: Maybe<Scalars['ID']>; + connection?: Maybe<PassengerConnection>; +}; + +export type PassengerGroupBy = { + __typename?: 'PassengerGroupBy'; + id?: Maybe<Array<Maybe<PassengerConnectionId>>>; + created_at?: Maybe<Array<Maybe<PassengerConnectionCreated_At>>>; + updated_at?: Maybe<Array<Maybe<PassengerConnectionUpdated_At>>>; + name?: Maybe<Array<Maybe<PassengerConnectionName>>>; + email?: Maybe<Array<Maybe<PassengerConnectionEmail>>>; + location?: Maybe<Array<Maybe<PassengerConnectionLocation>>>; + user?: Maybe<Array<Maybe<PassengerConnectionUser>>>; + event?: Maybe<Array<Maybe<PassengerConnectionEvent>>>; + travel?: Maybe<Array<Maybe<PassengerConnectionTravel>>>; +}; + +export type PassengerInput = { + name: Scalars['String']; + email?: Maybe<Scalars['String']>; + location?: Maybe<Scalars['String']>; + user?: Maybe<Scalars['ID']>; + event?: Maybe<Scalars['ID']>; + travel?: Maybe<Scalars['ID']>; + created_by?: Maybe<Scalars['ID']>; + updated_by?: Maybe<Scalars['ID']>; +}; + export enum PublicationState { Live = 'LIVE', Preview = 'PREVIEW'

@@ -580,6 +712,9 @@ eventsConnection?: Maybe<EventConnection>;

page?: Maybe<Page>; pages?: Maybe<Array<Maybe<Page>>>; pagesConnection?: Maybe<PageConnection>; + passenger?: Maybe<Passenger>; + passengers?: Maybe<Array<Maybe<Passenger>>>; + passengersConnection?: Maybe<PassengerConnection>; setting?: Maybe<Settings>; travel?: Maybe<Travel>; travels?: Maybe<Array<Maybe<Travel>>>;

@@ -648,6 +783,29 @@ where?: Maybe<Scalars['JSON']>;

}; +export type QueryPassengerArgs = { + id: Scalars['ID']; + publicationState?: Maybe<PublicationState>; +}; + + +export type QueryPassengersArgs = { + sort?: Maybe<Scalars['String']>; + limit?: Maybe<Scalars['Int']>; + start?: Maybe<Scalars['Int']>; + where?: Maybe<Scalars['JSON']>; + publicationState?: Maybe<PublicationState>; +}; + + +export type QueryPassengersConnectionArgs = { + sort?: Maybe<Scalars['String']>; + limit?: Maybe<Scalars['Int']>; + start?: Maybe<Scalars['Int']>; + where?: Maybe<Scalars['JSON']>; +}; + + export type QuerySettingArgs = { publicationState?: Maybe<PublicationState>; };

@@ -803,11 +961,20 @@ updated_at: Scalars['DateTime'];

meeting?: Maybe<Scalars['String']>; departure?: Maybe<Scalars['DateTime']>; details?: Maybe<Scalars['String']>; - passengers?: Maybe<Array<Maybe<ComponentPassengerPassenger>>>; + passengersCompo?: Maybe<Array<Maybe<ComponentPassengerPassenger>>>; event?: Maybe<Event>; vehicleName?: Maybe<Scalars['String']>; seats?: Maybe<Scalars['Int']>; phone_number?: Maybe<Scalars['String']>; + passengers?: Maybe<Array<Maybe<Passenger>>>; +}; + + +export type TravelPassengersArgs = { + sort?: Maybe<Scalars['String']>; + limit?: Maybe<Scalars['Int']>; + start?: Maybe<Scalars['Int']>; + where?: Maybe<Scalars['JSON']>; }; export type TravelAggregator = {

@@ -925,11 +1092,12 @@ export type TravelInput = {

meeting?: Maybe<Scalars['String']>; departure?: Maybe<Scalars['DateTime']>; details?: Maybe<Scalars['String']>; - passengers?: Maybe<Array<Maybe<ComponentPassengerPassengerInput>>>; + passengersCompo?: Maybe<Array<Maybe<ComponentPassengerPassengerInput>>>; event?: Maybe<Scalars['ID']>; vehicleName?: Maybe<Scalars['String']>; seats?: Maybe<Scalars['Int']>; phone_number?: Maybe<Scalars['String']>; + passengers?: Maybe<Array<Maybe<Scalars['ID']>>>; created_by?: Maybe<Scalars['ID']>; updated_by?: Maybe<Scalars['ID']>; createVehicle?: Maybe<Scalars['Boolean']>;

@@ -1151,6 +1319,7 @@ onboardingUser?: Maybe<Scalars['Boolean']>;

onboardingCreator?: Maybe<Scalars['Boolean']>; lang?: Maybe<Enum_Userspermissionsuser_Lang>; vehicles?: Maybe<Array<Maybe<Scalars['ID']>>>; + passengers?: Maybe<Array<Maybe<Scalars['ID']>>>; created_by?: Maybe<Scalars['ID']>; updated_by?: Maybe<Scalars['ID']>; };

@@ -1300,6 +1469,7 @@ onboardingCreator?: Maybe<Scalars['Boolean']>;

lang?: Maybe<Enum_Userspermissionsuser_Lang>; events?: Maybe<Array<Maybe<Event>>>; vehicles?: Maybe<Array<Maybe<Vehicle>>>; + passengers?: Maybe<Array<Maybe<Passenger>>>; };

@@ -1312,6 +1482,14 @@ };

export type UsersPermissionsUserVehiclesArgs = { + sort?: Maybe<Scalars['String']>; + limit?: Maybe<Scalars['Int']>; + start?: Maybe<Scalars['Int']>; + where?: Maybe<Scalars['JSON']>; +}; + + +export type UsersPermissionsUserPassengersArgs = { sort?: Maybe<Scalars['String']>; limit?: Maybe<Scalars['Int']>; start?: Maybe<Scalars['Int']>;

@@ -1561,6 +1739,15 @@ __typename?: 'createPagePayload';

page?: Maybe<Page>; }; +export type CreatePassengerInput = { + data?: Maybe<PassengerInput>; +}; + +export type CreatePassengerPayload = { + __typename?: 'createPassengerPayload'; + passenger?: Maybe<Passenger>; +}; + export type CreateRoleInput = { data?: Maybe<RoleInput>; };

@@ -1624,6 +1811,15 @@ __typename?: 'deletePagePayload';

page?: Maybe<Page>; }; +export type DeletePassengerInput = { + where?: Maybe<InputId>; +}; + +export type DeletePassengerPayload = { + __typename?: 'deletePassengerPayload'; + passenger?: Maybe<Passenger>; +}; + export type DeleteRoleInput = { where?: Maybe<InputId>; };

@@ -1697,6 +1893,7 @@ uuid?: Maybe<Scalars['String']>;

waitingList?: Maybe<Array<Maybe<EditComponentPassengerPassengerInput>>>; travels?: Maybe<Array<Maybe<Scalars['ID']>>>; description?: Maybe<Scalars['String']>; + waitingPassengers?: Maybe<Array<Maybe<Scalars['ID']>>>; created_by?: Maybe<Scalars['ID']>; updated_by?: Maybe<Scalars['ID']>; };

@@ -1729,6 +1926,17 @@ created_by?: Maybe<Scalars['ID']>;

updated_by?: Maybe<Scalars['ID']>; }; +export type EditPassengerInput = { + name?: Maybe<Scalars['String']>; + email?: Maybe<Scalars['String']>; + location?: Maybe<Scalars['String']>; + user?: Maybe<Scalars['ID']>; + event?: Maybe<Scalars['ID']>; + travel?: Maybe<Scalars['ID']>; + created_by?: Maybe<Scalars['ID']>; + updated_by?: Maybe<Scalars['ID']>; +}; + export type EditRoleInput = { name?: Maybe<Scalars['String']>; description?: Maybe<Scalars['String']>;

@@ -1751,11 +1959,12 @@ export type EditTravelInput = {

meeting?: Maybe<Scalars['String']>; departure?: Maybe<Scalars['DateTime']>; details?: Maybe<Scalars['String']>; - passengers?: Maybe<Array<Maybe<EditComponentPassengerPassengerInput>>>; + passengersCompo?: Maybe<Array<Maybe<EditComponentPassengerPassengerInput>>>; event?: Maybe<Scalars['ID']>; vehicleName?: Maybe<Scalars['String']>; seats?: Maybe<Scalars['Int']>; phone_number?: Maybe<Scalars['String']>; + passengers?: Maybe<Array<Maybe<Scalars['ID']>>>; created_by?: Maybe<Scalars['ID']>; updated_by?: Maybe<Scalars['ID']>; };

@@ -1777,6 +1986,7 @@ onboardingUser?: Maybe<Scalars['Boolean']>;

onboardingCreator?: Maybe<Scalars['Boolean']>; lang?: Maybe<Enum_Userspermissionsuser_Lang>; vehicles?: Maybe<Array<Maybe<Scalars['ID']>>>; + passengers?: Maybe<Array<Maybe<Scalars['ID']>>>; created_by?: Maybe<Scalars['ID']>; updated_by?: Maybe<Scalars['ID']>; old_password?: Maybe<Scalars['String']>;

@@ -1814,6 +2024,16 @@

export type UpdatePagePayload = { __typename?: 'updatePagePayload'; page?: Maybe<Page>; +}; + +export type UpdatePassengerInput = { + where?: Maybe<InputId>; + data?: Maybe<EditPassengerInput>; +}; + +export type UpdatePassengerPayload = { + __typename?: 'updatePassengerPayload'; + passenger?: Maybe<Passenger>; }; export type UpdateRoleInput = {

@@ -1940,9 +2160,9 @@

export type EventFieldsFragment = ( { __typename?: 'Event' } & Pick<Event, 'id' | 'uuid' | 'name' | 'description' | 'email' | 'date' | 'address' | 'position'> - & { waitingList?: Maybe<Array<Maybe<( - { __typename?: 'ComponentPassengerPassenger' } - & Pick<ComponentPassengerPassenger, 'id' | 'name' | 'location'> + & { waitingPassengers?: Maybe<Array<Maybe<( + { __typename?: 'Passenger' } + & Pick<Passenger, 'id' | 'name' | 'email' | 'location'> & { user?: Maybe<( { __typename?: 'UsersPermissionsUser' } & Pick<UsersPermissionsUser, 'id' | 'firstName' | 'lastName'>

@@ -1951,8 +2171,8 @@ )>>>, travels?: Maybe<Array<Maybe<(

{ __typename?: 'Travel' } & Pick<Travel, 'id' | 'meeting' | 'departure' | 'details' | 'vehicleName' | 'phone_number' | 'seats'> & { passengers?: Maybe<Array<Maybe<( - { __typename?: 'ComponentPassengerPassenger' } - & Pick<ComponentPassengerPassenger, 'id' | 'name' | 'location'> + { __typename?: 'Passenger' } + & Pick<Passenger, 'id' | 'name' | 'location'> & { user?: Maybe<( { __typename?: 'UsersPermissionsUser' } & Pick<UsersPermissionsUser, 'id' | 'firstName' | 'lastName'>

@@ -2012,6 +2232,64 @@ & EventFieldsFragment

)> } ); +export type PassengerFieldsFragment = ( + { __typename?: 'Passenger' } + & Pick<Passenger, 'id' | 'name' | 'location' | 'email'> + & { user?: Maybe<( + { __typename?: 'UsersPermissionsUser' } + & Pick<UsersPermissionsUser, 'id' | 'firstName' | 'lastName'> + )> } +); + +export type CreatePassengerMutationVariables = Exact<{ + passenger?: Maybe<PassengerInput>; +}>; + + +export type CreatePassengerMutation = ( + { __typename?: 'Mutation' } + & { createPassenger?: Maybe<( + { __typename?: 'createPassengerPayload' } + & { passenger?: Maybe<( + { __typename?: 'Passenger' } + & PassengerFieldsFragment + )> } + )> } +); + +export type UpdatePassengerMutationVariables = Exact<{ + id: Scalars['ID']; + passengerUpdate: EditPassengerInput; +}>; + + +export type UpdatePassengerMutation = ( + { __typename?: 'Mutation' } + & { updatePassenger?: Maybe<( + { __typename?: 'updatePassengerPayload' } + & { passenger?: Maybe<( + { __typename?: 'Passenger' } + & PassengerFieldsFragment + )> } + )> } +); + +export type DeletePassengerMutationVariables = Exact<{ + id: Scalars['ID']; +}>; + + +export type DeletePassengerMutation = ( + { __typename?: 'Mutation' } + & { deletePassenger?: Maybe<( + { __typename?: 'deletePassengerPayload' } + & { passenger?: Maybe<( + { __typename?: 'Passenger' } + & Pick<Passenger, 'id'> + )> } + )> } +); + export type SettingQueryVariables = Exact<{ [key: string]: never; }>;

@@ -2027,8 +2305,8 @@ export type TravelFieldsFragment = (

{ __typename?: 'Travel' } & Pick<Travel, 'id' | 'meeting' | 'departure' | 'details' | 'vehicleName' | 'phone_number' | 'seats'> & { passengers?: Maybe<Array<Maybe<( - { __typename?: 'ComponentPassengerPassenger' } - & Pick<ComponentPassengerPassenger, 'id' | 'name' | 'location'> + { __typename?: 'Passenger' } + & Pick<Passenger, 'id' | 'name' | 'location'> & { user?: Maybe<( { __typename?: 'UsersPermissionsUser' } & Pick<UsersPermissionsUser, 'id' | 'firstName' | 'lastName'>

@@ -2182,9 +2460,10 @@ email

date address position - waitingList { + waitingPassengers { id name + email location user { id

@@ -2213,6 +2492,19 @@ }

} } `; +export const PassengerFieldsFragmentDoc = gql` + fragment PassengerFields on Passenger { + id + name + location + email + user { + id + firstName + lastName + } +} + `; export const TravelFieldsFragmentDoc = gql` fragment TravelFields on Travel { id

@@ -2515,6 +2807,109 @@ }

export type EventByUuidQueryHookResult = ReturnType<typeof useEventByUuidQuery>; export type EventByUuidLazyQueryHookResult = ReturnType<typeof useEventByUuidLazyQuery>; export type EventByUuidQueryResult = Apollo.QueryResult<EventByUuidQuery, EventByUuidQueryVariables>; +export const CreatePassengerDocument = gql` + mutation createPassenger($passenger: PassengerInput) { + createPassenger(input: {data: $passenger}) { + passenger { + ...PassengerFields + } + } +} + ${PassengerFieldsFragmentDoc}`; +export type CreatePassengerMutationFn = Apollo.MutationFunction<CreatePassengerMutation, CreatePassengerMutationVariables>; + +/** + * __useCreatePassengerMutation__ + * + * To run a mutation, you first call `useCreatePassengerMutation` within a React component and pass it any options that fit your needs. + * When your component renders, `useCreatePassengerMutation` returns a tuple that includes: + * - A mutate function that you can call at any time to execute the mutation + * - An object with fields that represent the current status of the mutation's execution + * + * @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2; + * + * @example + * const [createPassengerMutation, { data, loading, error }] = useCreatePassengerMutation({ + * variables: { + * passenger: // value for 'passenger' + * }, + * }); + */ +export function useCreatePassengerMutation(baseOptions?: Apollo.MutationHookOptions<CreatePassengerMutation, CreatePassengerMutationVariables>) { + return Apollo.useMutation<CreatePassengerMutation, CreatePassengerMutationVariables>(CreatePassengerDocument, baseOptions); + } +export type CreatePassengerMutationHookResult = ReturnType<typeof useCreatePassengerMutation>; +export type CreatePassengerMutationResult = Apollo.MutationResult<CreatePassengerMutation>; +export type CreatePassengerMutationOptions = Apollo.BaseMutationOptions<CreatePassengerMutation, CreatePassengerMutationVariables>; +export const UpdatePassengerDocument = gql` + mutation updatePassenger($id: ID!, $passengerUpdate: editPassengerInput!) { + updatePassenger(input: {where: {id: $id}, data: $passengerUpdate}) { + passenger { + ...PassengerFields + } + } +} + ${PassengerFieldsFragmentDoc}`; +export type UpdatePassengerMutationFn = Apollo.MutationFunction<UpdatePassengerMutation, UpdatePassengerMutationVariables>; + +/** + * __useUpdatePassengerMutation__ + * + * To run a mutation, you first call `useUpdatePassengerMutation` within a React component and pass it any options that fit your needs. + * When your component renders, `useUpdatePassengerMutation` returns a tuple that includes: + * - A mutate function that you can call at any time to execute the mutation + * - An object with fields that represent the current status of the mutation's execution + * + * @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2; + * + * @example + * const [updatePassengerMutation, { data, loading, error }] = useUpdatePassengerMutation({ + * variables: { + * id: // value for 'id' + * passengerUpdate: // value for 'passengerUpdate' + * }, + * }); + */ +export function useUpdatePassengerMutation(baseOptions?: Apollo.MutationHookOptions<UpdatePassengerMutation, UpdatePassengerMutationVariables>) { + return Apollo.useMutation<UpdatePassengerMutation, UpdatePassengerMutationVariables>(UpdatePassengerDocument, baseOptions); + } +export type UpdatePassengerMutationHookResult = ReturnType<typeof useUpdatePassengerMutation>; +export type UpdatePassengerMutationResult = Apollo.MutationResult<UpdatePassengerMutation>; +export type UpdatePassengerMutationOptions = Apollo.BaseMutationOptions<UpdatePassengerMutation, UpdatePassengerMutationVariables>; +export const DeletePassengerDocument = gql` + mutation deletePassenger($id: ID!) { + deletePassenger(input: {where: {id: $id}}) { + passenger { + id + } + } +} + `; +export type DeletePassengerMutationFn = Apollo.MutationFunction<DeletePassengerMutation, DeletePassengerMutationVariables>; + +/** + * __useDeletePassengerMutation__ + * + * To run a mutation, you first call `useDeletePassengerMutation` within a React component and pass it any options that fit your needs. + * When your component renders, `useDeletePassengerMutation` returns a tuple that includes: + * - A mutate function that you can call at any time to execute the mutation + * - An object with fields that represent the current status of the mutation's execution + * + * @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2; + * + * @example + * const [deletePassengerMutation, { data, loading, error }] = useDeletePassengerMutation({ + * variables: { + * id: // value for 'id' + * }, + * }); + */ +export function useDeletePassengerMutation(baseOptions?: Apollo.MutationHookOptions<DeletePassengerMutation, DeletePassengerMutationVariables>) { + return Apollo.useMutation<DeletePassengerMutation, DeletePassengerMutationVariables>(DeletePassengerDocument, baseOptions); + } +export type DeletePassengerMutationHookResult = ReturnType<typeof useDeletePassengerMutation>; +export type DeletePassengerMutationResult = Apollo.MutationResult<DeletePassengerMutation>; +export type DeletePassengerMutationOptions = Apollo.BaseMutationOptions<DeletePassengerMutation, DeletePassengerMutationVariables>; export const SettingDocument = gql` query setting { setting {
M frontend/graphql/event.gqlfrontend/graphql/event.gql

@@ -7,9 +7,10 @@ email

date address position - waitingList { + waitingPassengers { id name + email location user { id
A frontend/graphql/passenger.gql

@@ -0,0 +1,35 @@

+fragment PassengerFields on Passenger { + id + name + location + email + user { + id + firstName + lastName + } +} + +mutation createPassenger($passenger: PassengerInput) { + createPassenger(input: {data: $passenger}) { + passenger { + ...PassengerFields + } + } +} + +mutation updatePassenger($id: ID!, $passengerUpdate: editPassengerInput!) { + updatePassenger(input: {where: {id: $id}, data: $passengerUpdate}) { + passenger { + ...PassengerFields + } + } +} + +mutation deletePassenger($id: ID!) { + deletePassenger(input: {where: {id: $id}}) { + passenger { + id + } + } +}
M frontend/hooks/usePassengersActions.tsfrontend/hooks/usePassengersActions.ts

@@ -1,89 +1,47 @@

import { - Travel, - Event, - useUpdateTravelMutation, - useUpdateEventMutation, - ComponentPassengerPassenger, - ComponentPassengerPassengerInput, + EditPassengerInput, + PassengerInput, + useCreatePassengerMutation, + useDeletePassengerMutation, + useUpdatePassengerMutation, } from '../generated/graphql'; -interface AddPassengerToTravelArgs { - passenger: ComponentPassengerPassengerInput; - travel: Travel; -} - -interface AddPassengerToWaitingList { - passenger: ComponentPassengerPassenger; - event: Event; -} +const usePassengersActions = () => { + const [createPassenger] = useCreatePassengerMutation(); + const [setPassenger] = useUpdatePassengerMutation(); + const [deletePassenger] = useDeletePassengerMutation(); -interface RemovePassengerArgs { - passenger: ComponentPassengerPassenger; - event: Event; -} - -const usepassengersActions = () => { - const [updateEvent] = useUpdateEventMutation(); - const [updateTravel] = useUpdateTravelMutation(); - - const addPassengerToTravel = async ({ - passenger, - travel, - }: AddPassengerToTravelArgs) => { - const passengers = - [...travel.passengers, passenger].map(({__typename, user, ...item}) => { - return user && typeof user !== 'string' - ? { - ...item, - user: user.id, - } - : item; - }) || []; - - return updateTravel({ + const addPassenger = async (passenger: PassengerInput) => + createPassenger({ variables: { - id: travel.id, - travelUpdate: { - passengers, - }, + passenger, }, + refetchQueries: ['eventByUUID'], }); - }; - const addPassengerToWaitingList = async ({ - passenger, - event, - }: AddPassengerToWaitingList) => { - const waitingList = [ - ...event.waitingList, - passenger, - ].map(({__typename, user, ...item}) => - user ? {...item, user: user.id} : item - ); - return updateEvent({ - variables: {uuid: event.uuid, eventUpdate: {waitingList}}, + const updatePassenger = async ( + passengerId: string, + passenger: EditPassengerInput + ) => + setPassenger({ + variables: {id: passengerId, passengerUpdate: passenger}, refetchQueries: ['eventByUUID'], }); - }; - const removePassengerFromWaitingList = async ({ - passenger, - event, - }: RemovePassengerArgs) => { - const waitingList = event.waitingList - .filter(waitingListPassenger => waitingListPassenger.id !== passenger?.id) - .map(({__typename, user, ...item}) => item); - return updateEvent({ - variables: {uuid: event.uuid, eventUpdate: {waitingList}}, + const removePassenger = async (passengerId: string) => { + return deletePassenger({ + variables: { + id: passengerId, + }, refetchQueries: ['eventByUUID'], }); }; return { - addPassengerToTravel, - addPassengerToWaitingList, - removePassengerFromWaitingList, + addPassenger, + updatePassenger, + removePassenger, }; }; -export default usepassengersActions; +export default usePassengersActions;