Add an accommodations reservations module #188
@ -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<void> {
|
||||
await APIClient.exec({
|
||||
method: "POST",
|
||||
uri: `/family/${r.family_id}/accommodations/reservation/${r.id}/validate`,
|
||||
jsonData: {
|
||||
validate: accept,
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -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 | HTMLElement>(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 {
|
||||
<CardActions disableSpacing>
|
||||
{activeEvent?.accommodation.need_validation &&
|
||||
family.family.is_admin && (
|
||||
<Tooltip
|
||||
title="Valider (ou rejeter) la réservation"
|
||||
arrow
|
||||
>
|
||||
<IconButton
|
||||
onClick={() =>
|
||||
validateReservation(activeEvent?.reservation)
|
||||
}
|
||||
<>
|
||||
<Tooltip
|
||||
title="Valider (ou rejeter) la réservation"
|
||||
arrow
|
||||
>
|
||||
<RuleIcon />
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
<IconButton
|
||||
onClick={(e) =>
|
||||
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 && (
|
||||
<>
|
||||
|
Loading…
Reference in New Issue
Block a user