203 lines
6.8 KiB
TypeScript
203 lines
6.8 KiB
TypeScript
import { DateSelectArg } from "@fullcalendar/core";
|
|
import frLocale from "@fullcalendar/core/locales/fr";
|
|
import dayGridPlugin from "@fullcalendar/daygrid";
|
|
import interactionPlugin from "@fullcalendar/interaction";
|
|
import listPlugin from "@fullcalendar/list";
|
|
import FullCalendar from "@fullcalendar/react";
|
|
import {
|
|
Checkbox,
|
|
FormControl,
|
|
FormControlLabel,
|
|
FormGroup,
|
|
FormLabel,
|
|
} from "@mui/material";
|
|
import React from "react";
|
|
import { FamilyApi, FamilyUser } from "../../../api/FamilyApi";
|
|
import {
|
|
AccommodationsReservationsApi,
|
|
AccommodationsReservationsList,
|
|
} from "../../../api/accommodations/AccommodationsReservationsApi";
|
|
import { useUpdateAccommodationReservation } from "../../../hooks/context_providers/accommodations/UpdateReservationDialogProvider";
|
|
import { AsyncWidget } from "../../../widgets/AsyncWidget";
|
|
import { useFamily } from "../../../widgets/BaseFamilyRoute";
|
|
import { FamilyPageTitle } from "../../../widgets/FamilyPageTitle";
|
|
import { useAccommodations } from "../../../widgets/accommodations/BaseAccommodationsRoute";
|
|
|
|
export function AccommodationsReservationsRoute(): React.ReactElement {
|
|
const loadKey = React.useRef(1);
|
|
|
|
const family = useFamily();
|
|
const accommodations = useAccommodations();
|
|
const updateReservation = useUpdateAccommodationReservation();
|
|
|
|
const [reservations, setReservations] = React.useState<
|
|
AccommodationsReservationsList | undefined
|
|
>();
|
|
const [users, setUsers] = React.useState<FamilyUser[] | null>(null);
|
|
|
|
const [showValidated, setShowValidated] = React.useState(true);
|
|
const [showRejected, setShowRejected] = React.useState(true);
|
|
const [showPending, setShowPending] = React.useState(true);
|
|
|
|
const [hiddenPeople, setHiddenPeople] = React.useState<Set<number>>(
|
|
new Set()
|
|
);
|
|
const [hiddenAccommodations, setHiddenAccommodations] = React.useState<
|
|
Set<number>
|
|
>(new Set());
|
|
|
|
const load = async () => {
|
|
setReservations(
|
|
await AccommodationsReservationsApi.FullListOfFamily(family.family)
|
|
);
|
|
setUsers(await FamilyApi.GetUsersList(family.family.family_id));
|
|
};
|
|
|
|
const reload = async () => {
|
|
loadKey.current += 1;
|
|
setUsers(null);
|
|
};
|
|
|
|
const onSelect = (d: DateSelectArg) => {
|
|
// TODO : render this functional
|
|
// TODO : handle busy case
|
|
console.info(d);
|
|
updateReservation(
|
|
{
|
|
accommodation_id: -1,
|
|
start: Math.floor(d.start.getTime() / 1000),
|
|
end: Math.floor(d.end.getTime() / 1000),
|
|
},
|
|
true
|
|
);
|
|
};
|
|
|
|
return (
|
|
<>
|
|
<FamilyPageTitle title="Réservation" />
|
|
<AsyncWidget
|
|
loadKey={loadKey.current}
|
|
load={load}
|
|
errMsg="Echec du chargement de la liste des réservations !"
|
|
build={() => (
|
|
<div style={{ display: "flex", flexDirection: "row" }}>
|
|
<div style={{ flex: 1, maxWidth: "250px" }}>
|
|
{/* Invitation status */}
|
|
<FormControl
|
|
sx={{ m: 3 }}
|
|
component="fieldset"
|
|
variant="standard"
|
|
>
|
|
<FormLabel component="legend">Status</FormLabel>
|
|
<FormGroup>
|
|
<FormControlLabel
|
|
control={
|
|
<Checkbox
|
|
checked={showValidated}
|
|
onChange={(_ev, v) => setShowValidated(v)}
|
|
/>
|
|
}
|
|
label="Validé"
|
|
/>
|
|
<FormControlLabel
|
|
control={
|
|
<Checkbox
|
|
checked={showRejected}
|
|
onChange={(_ev, v) => setShowRejected(v)}
|
|
/>
|
|
}
|
|
label="Rejetés"
|
|
/>
|
|
<FormControlLabel
|
|
control={
|
|
<Checkbox
|
|
checked={showPending}
|
|
onChange={(_ev, v) => setShowPending(v)}
|
|
/>
|
|
}
|
|
label="En attente de validation"
|
|
/>
|
|
</FormGroup>
|
|
</FormControl>
|
|
|
|
{/* Accommodations */}
|
|
<FormControl
|
|
sx={{ m: 3 }}
|
|
component="fieldset"
|
|
variant="standard"
|
|
>
|
|
<FormLabel component="legend">Logements</FormLabel>
|
|
<FormGroup>
|
|
{accommodations.accommodations.fullList.map((a) => (
|
|
<FormControlLabel
|
|
key={a.id}
|
|
control={
|
|
<Checkbox
|
|
checked={!hiddenAccommodations.has(a.id)}
|
|
onChange={(_ev, v) => {
|
|
if (v) hiddenAccommodations.delete(a.id);
|
|
else hiddenAccommodations.add(a.id);
|
|
setHiddenAccommodations(
|
|
new Set(hiddenAccommodations)
|
|
);
|
|
}}
|
|
/>
|
|
}
|
|
label={a.name}
|
|
/>
|
|
))}
|
|
</FormGroup>
|
|
</FormControl>
|
|
|
|
{/* People */}
|
|
<FormControl
|
|
sx={{ m: 3 }}
|
|
component="fieldset"
|
|
variant="standard"
|
|
>
|
|
<FormLabel component="legend">Personnes</FormLabel>
|
|
<FormGroup>
|
|
{users?.map((u) => (
|
|
<FormControlLabel
|
|
key={u.user_id}
|
|
control={
|
|
<Checkbox
|
|
checked={!hiddenPeople.has(u.user_id)}
|
|
onChange={(_ev, v) => {
|
|
if (v) hiddenPeople.delete(u.user_id);
|
|
else hiddenPeople.add(u.user_id);
|
|
setHiddenPeople(new Set(hiddenPeople));
|
|
}}
|
|
/>
|
|
}
|
|
label={u.user_name}
|
|
/>
|
|
))}
|
|
</FormGroup>
|
|
</FormControl>
|
|
</div>
|
|
|
|
{/* The calendar */}
|
|
<div style={{ flex: 5 }}>
|
|
<FullCalendar
|
|
editable={true}
|
|
selectable={true}
|
|
plugins={[dayGridPlugin, listPlugin, interactionPlugin]}
|
|
initialView="dayGridMonth"
|
|
height="700px"
|
|
locale={frLocale}
|
|
headerToolbar={{
|
|
left: "prev,next today",
|
|
center: "title",
|
|
right: "dayGridMonth,dayGridWeek,listWeek",
|
|
}}
|
|
select={onSelect}
|
|
/>
|
|
</div>
|
|
</div>
|
|
)}
|
|
/>
|
|
</>
|
|
);
|
|
}
|