193 lines
5.2 KiB
TypeScript
193 lines
5.2 KiB
TypeScript
import {
|
|
Alert,
|
|
Button,
|
|
Dialog,
|
|
DialogActions,
|
|
DialogContent,
|
|
DialogTitle,
|
|
} from "@mui/material";
|
|
import React from "react";
|
|
import {
|
|
AccommodationReservation,
|
|
AccommodationsReservationsApi,
|
|
UpdateAccommodationReservation,
|
|
} from "../../api/accommodations/AccommodationsReservationsApi";
|
|
import { useAlert } from "../../hooks/context_providers/AlertDialogProvider";
|
|
import { fmtUnixDate } from "../../utils/time_utils";
|
|
import { useFamily } from "../../widgets/BaseFamilyRoute";
|
|
import { useAccommodations } from "../../widgets/accommodations/BaseAccommodationsRoute";
|
|
import { PropDateInput } from "../../widgets/forms/PropDateInput";
|
|
import { PropSelect } from "../../widgets/forms/PropSelect";
|
|
|
|
export function UpdateReservationDialog(p: {
|
|
open: boolean;
|
|
create: boolean;
|
|
reservation?: UpdateAccommodationReservation;
|
|
onClose: () => void;
|
|
onSubmitted: (c: UpdateAccommodationReservation) => void;
|
|
}): React.ReactElement {
|
|
const alert = useAlert();
|
|
|
|
const family = useFamily();
|
|
const accommodations = useAccommodations();
|
|
|
|
const [reservation, setReservation] = React.useState<
|
|
UpdateAccommodationReservation | undefined
|
|
>();
|
|
|
|
const [conflicts, setConflicts] = React.useState<
|
|
AccommodationReservation[] | undefined
|
|
>(undefined);
|
|
|
|
const clearForm = () => {
|
|
setReservation(undefined);
|
|
};
|
|
|
|
const cancel = () => {
|
|
clearForm();
|
|
p.onClose();
|
|
};
|
|
|
|
const submit = async () => {
|
|
clearForm();
|
|
p.onSubmitted(reservation!);
|
|
};
|
|
|
|
React.useEffect(() => {
|
|
if (!reservation) setReservation(p.reservation);
|
|
}, [p.open, p.reservation]);
|
|
|
|
React.useEffect(() => {
|
|
setConflicts(undefined);
|
|
(async () => {
|
|
try {
|
|
if (
|
|
!reservation ||
|
|
reservation.accommodation_id < 1 ||
|
|
reservation.start < 1 ||
|
|
reservation.start > reservation.end
|
|
) {
|
|
setConflicts([]);
|
|
return;
|
|
}
|
|
|
|
setConflicts(
|
|
(
|
|
await AccommodationsReservationsApi.ReservationsForInterval(
|
|
family.family,
|
|
accommodations.accommodations.get(reservation.accommodation_id)!,
|
|
reservation.start,
|
|
reservation.end
|
|
)
|
|
).filter(
|
|
(r) =>
|
|
r.id !== p.reservation?.reservation_id && r.validated !== false
|
|
)
|
|
);
|
|
} catch (e) {
|
|
console.error(e);
|
|
alert(
|
|
"Echec de la vérification de la présence de conflits de calendrier !"
|
|
);
|
|
}
|
|
})();
|
|
}, [
|
|
p.open,
|
|
reservation?.accommodation_id,
|
|
reservation?.start,
|
|
reservation?.end,
|
|
]);
|
|
|
|
return (
|
|
<Dialog open={p.open} onClose={cancel}>
|
|
<DialogTitle>
|
|
{p.create ? "Création" : "Mise à jour"} d'une réservation
|
|
</DialogTitle>
|
|
<DialogContent style={{ display: "flex", flexDirection: "column" }}>
|
|
<PropSelect
|
|
editing={p.create}
|
|
label="Logement ciblé"
|
|
onValueChange={(v) => {
|
|
setReservation((a) => {
|
|
return {
|
|
...a!,
|
|
accommodation_id: Number(v),
|
|
};
|
|
});
|
|
}}
|
|
options={accommodations.accommodations.openToReservationList.map(
|
|
(a) => {
|
|
return { label: a.name, value: a.id.toString() };
|
|
}
|
|
)}
|
|
value={
|
|
reservation?.accommodation_id === -1
|
|
? ""
|
|
: reservation?.accommodation_id?.toString()
|
|
}
|
|
/>
|
|
|
|
<PropDateInput
|
|
editable
|
|
label="Date de début"
|
|
value={reservation?.start}
|
|
onChange={(s) => {
|
|
setReservation((r) => {
|
|
return { ...r!, start: s ?? -1 };
|
|
});
|
|
}}
|
|
minDate={Math.floor(new Date().getTime() / 1000) - 3600 * 24 * 60}
|
|
canSetMiddleDay
|
|
/>
|
|
|
|
<PropDateInput
|
|
editable
|
|
label="Date de fin"
|
|
value={reservation?.end}
|
|
lastSecOfDay={true}
|
|
onChange={(s) => {
|
|
setReservation((r) => {
|
|
return { ...r!, end: s ?? -1 };
|
|
});
|
|
}}
|
|
minDate={reservation?.start}
|
|
canSetMiddleDay
|
|
/>
|
|
|
|
{conflicts && conflicts.length > 0 && (
|
|
<Alert severity="error">
|
|
<p>
|
|
Cette réservation est en conflit avec d'autres réservations sur
|
|
les intervalles suivants :
|
|
</p>
|
|
<ul>
|
|
{conflicts.map((c, num) => (
|
|
<li key={num}>
|
|
Réservation du {fmtUnixDate(c.reservation_start)} au{" "}
|
|
{fmtUnixDate(c.reservation_end)}
|
|
</li>
|
|
))}
|
|
</ul>
|
|
</Alert>
|
|
)}
|
|
</DialogContent>
|
|
<DialogActions>
|
|
<Button onClick={cancel}>Annuler</Button>
|
|
<Button
|
|
onClick={submit}
|
|
disabled={
|
|
!(
|
|
(reservation?.accommodation_id ?? -1) > 0 &&
|
|
(reservation?.start ?? -1) > 0 &&
|
|
(reservation?.end ?? -1) > (reservation?.start ?? 0) &&
|
|
(conflicts?.length ?? 0) === 0
|
|
)
|
|
}
|
|
>
|
|
{p.create ? "Créer" : "Mettre à jour"}
|
|
</Button>
|
|
</DialogActions>
|
|
</Dialog>
|
|
);
|
|
}
|