Can respond to reservation requests
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing

This commit is contained in:
Pierre HUBERT 2024-06-22 08:57:33 +02:00
parent 2833bc8cdf
commit f6d8d6b3d1
2 changed files with 92 additions and 12 deletions

View File

@ -144,4 +144,20 @@ export class AccommodationsReservationsApi {
uri: `/family/${r.family_id}/accommodations/reservation/${r.id}`, uri: `/family/${r.family_id}/accommodations/reservation/${r.id}`,
}); });
} }
/**
* Validate or reject a reservation request
*/
static async Validate(
r: AccommodationReservation,
accept: boolean
): Promise<void> {
await APIClient.exec({
method: "POST",
uri: `/family/${r.family_id}/accommodations/reservation/${r.id}/validate`,
jsonData: {
validate: accept,
},
});
}
} }

View File

@ -20,6 +20,8 @@ import {
FormGroup, FormGroup,
FormLabel, FormLabel,
IconButton, IconButton,
Menu,
MenuItem,
Popover, Popover,
Tooltip, Tooltip,
Typography, Typography,
@ -92,6 +94,9 @@ export function AccommodationsReservationsRoute(): React.ReactElement {
} }
>(); >();
const [validateResaAnchorEl, setValidateResaAnchorEl] =
React.useState<null | HTMLElement>(null);
const load = async () => { const load = async () => {
setReservations( setReservations(
await AccommodationsReservationsApi.FullListOfFamily(family.family) 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) => { 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) => { const changeReservation = async (r: AccommodationReservation) => {
@ -473,18 +509,46 @@ export function AccommodationsReservationsRoute(): React.ReactElement {
<CardActions disableSpacing> <CardActions disableSpacing>
{activeEvent?.accommodation.need_validation && {activeEvent?.accommodation.need_validation &&
family.family.is_admin && ( family.family.is_admin && (
<Tooltip <>
title="Valider (ou rejeter) la réservation" <Tooltip
arrow title="Valider (ou rejeter) la réservation"
> arrow
<IconButton
onClick={() =>
validateReservation(activeEvent?.reservation)
}
> >
<RuleIcon /> <IconButton
</IconButton> onClick={(e) =>
</Tooltip> setValidateResaAnchorEl(e.currentTarget)
}
>
<RuleIcon />
</IconButton>
</Tooltip>
<Menu
anchorEl={validateResaAnchorEl}
open={!!validateResaAnchorEl && !!activeEvent}
onClose={() => setValidateResaAnchorEl(null)}
>
<MenuItem
disabled={
activeEvent.reservation.validated === true
}
onClick={() =>
validateReservation(activeEvent.reservation)
}
>
Valider
</MenuItem>
<MenuItem
disabled={
activeEvent.reservation.validated === false
}
onClick={() =>
rejectReservation(activeEvent.reservation)
}
>
Rejeter
</MenuItem>
</Menu>
</>
)} )}
{user.user.id === activeEvent?.reservation.user_id && ( {user.user.id === activeEvent?.reservation.user_id && (
<> <>