diff --git a/geneit_app/src/api/accommodations/AccommodationsReservationsApi.tsx b/geneit_app/src/api/accommodations/AccommodationsReservationsApi.tsx index 20801f9..8b3c15f 100644 --- a/geneit_app/src/api/accommodations/AccommodationsReservationsApi.tsx +++ b/geneit_app/src/api/accommodations/AccommodationsReservationsApi.tsx @@ -144,4 +144,20 @@ export class AccommodationsReservationsApi { uri: `/family/${r.family_id}/accommodations/reservation/${r.id}`, }); } + + /** + * Validate or reject a reservation request + */ + static async Validate( + r: AccommodationReservation, + accept: boolean + ): Promise { + await APIClient.exec({ + method: "POST", + uri: `/family/${r.family_id}/accommodations/reservation/${r.id}/validate`, + jsonData: { + validate: accept, + }, + }); + } } diff --git a/geneit_app/src/routes/family/accommodations/AccommodationsReservationsRoute.tsx b/geneit_app/src/routes/family/accommodations/AccommodationsReservationsRoute.tsx index 9410839..531464a 100644 --- a/geneit_app/src/routes/family/accommodations/AccommodationsReservationsRoute.tsx +++ b/geneit_app/src/routes/family/accommodations/AccommodationsReservationsRoute.tsx @@ -20,6 +20,8 @@ import { FormGroup, FormLabel, IconButton, + Menu, + MenuItem, Popover, Tooltip, Typography, @@ -92,6 +94,9 @@ export function AccommodationsReservationsRoute(): React.ReactElement { } >(); + const [validateResaAnchorEl, setValidateResaAnchorEl] = + React.useState(null); + const load = async () => { setReservations( await AccommodationsReservationsApi.FullListOfFamily(family.family) @@ -174,8 +179,39 @@ export function AccommodationsReservationsRoute(): React.ReactElement { }); }; + const respondToResaRequest = async ( + r: AccommodationReservation, + validate: boolean + ) => { + try { + loadingMessage.show("Validation de la réservation en cours..."); + + setActiveEvent(undefined); + + await AccommodationsReservationsApi.Validate(r, validate); + + reload(); + snackbar("La réservation a été mise à jour avec succès !"); + } catch (e) { + console.error("Failed to respond to reservation request!", e); + alert(`Echec de l'enregistrement de la réponse à la réservation ! ${e}`); + } finally { + loadingMessage.hide(); + } + }; + const validateReservation = async (r: AccommodationReservation) => { - // TODO + respondToResaRequest(r, true); + }; + + const rejectReservation = async (r: AccommodationReservation) => { + if ( + !(await confirm( + "Voulez-vous vraiment rejeter cette demande de réservation ?" + )) + ) + return; + respondToResaRequest(r, false); }; const changeReservation = async (r: AccommodationReservation) => { @@ -473,18 +509,46 @@ export function AccommodationsReservationsRoute(): React.ReactElement { {activeEvent?.accommodation.need_validation && family.family.is_admin && ( - - - validateReservation(activeEvent?.reservation) - } + <> + - - - + + setValidateResaAnchorEl(e.currentTarget) + } + > + + + + setValidateResaAnchorEl(null)} + > + + validateReservation(activeEvent.reservation) + } + > + Valider + + + rejectReservation(activeEvent.reservation) + } + > + Rejeter + + + )} {user.user.id === activeEvent?.reservation.user_id && ( <>