import ClearIcon from "@mui/icons-material/Clear"; import DeleteIcon from "@mui/icons-material/Delete"; import EditIcon from "@mui/icons-material/Edit"; import FileDownloadIcon from "@mui/icons-material/FileDownload"; import SaveIcon from "@mui/icons-material/Save"; import { Button, Stack } from "@mui/material"; import Grid from "@mui/material/Grid2"; import React from "react"; import { useNavigate, useParams } from "react-router-dom"; import { ServerApi } from "../../../api/ServerApi"; import { Couple, CoupleApi } from "../../../api/genealogy/CoupleApi"; import { Member } from "../../../api/genealogy/MemberApi"; import { useAlert } from "../../../hooks/context_providers/AlertDialogProvider"; import { useConfirm } from "../../../hooks/context_providers/ConfirmDialogProvider"; import { useLoadingMessage } from "../../../hooks/context_providers/LoadingMessageProvider"; import { useSnackbar } from "../../../hooks/context_providers/SnackbarProvider"; import { useQuery } from "../../../hooks/useQuery"; import { AsyncWidget } from "../../../widgets/AsyncWidget"; import { useFamily } from "../../../widgets/BaseFamilyRoute"; import { ConfirmLeaveWithoutSaveDialog } from "../../../widgets/ConfirmLeaveWithoutSaveDialog"; import { CouplePhoto } from "../../../widgets/CouplePhoto"; import { FamilyPageTitle } from "../../../widgets/FamilyPageTitle"; import { MemberItem } from "../../../widgets/MemberItem"; import { PropertiesBox } from "../../../widgets/PropertiesBox"; import { RouterLink } from "../../../widgets/RouterLink"; import { DateInput } from "../../../widgets/forms/DateInput"; import { MemberInput } from "../../../widgets/forms/MemberInput"; import { PropSelect } from "../../../widgets/forms/PropSelect"; import { UploadPhotoButton } from "../../../widgets/forms/UploadPhotoButton"; import { useGenealogy } from "../../../widgets/genealogy/BaseGenealogyRoute"; /** * Create a new couple route */ export function FamilyCreateCoupleRoute(): React.ReactElement { const alert = useAlert(); const snackbar = useSnackbar(); const [shouldQuit, setShouldQuit] = React.useState(false); const n = useNavigate(); const genealogy = useGenealogy(); const family = useFamily(); const params = useQuery(); const couple = Couple.New(family.family.family_id); const wife = Number(params.get("wife")); const husband = Number(params.get("husband")); if (wife) couple.wife = wife; if (husband) couple.husband = husband; const create = async (m: Couple) => { try { const r = await CoupleApi.Create(m); await genealogy.reloadCouplesList(); setShouldQuit(true); n(family.family.coupleURL(r)); snackbar(`La fiche pour le couple a été créée avec succès !`); } catch (e) { console.error(e); alert("Echec de la création du couple !"); } }; const cancel = () => { setShouldQuit(true); n(family.family.URL("genealogy/couples")); }; return ( ); } /** * Get existing couple route */ export function FamilyCoupleRoute(): React.ReactElement { const count = React.useRef(1); const n = useNavigate(); const alert = useAlert(); const confirm = useConfirm(); const snackbar = useSnackbar(); const family = useFamily(); const genealogy = useGenealogy(); const { coupleId } = useParams(); const [couple, setCouple] = React.useState(); const load = async () => { setCouple(await CoupleApi.GetSingle(family.familyId, Number(coupleId))); }; const forceReload = async () => { count.current += 1; setCouple(undefined); await genealogy.reloadCouplesList(); }; const deleteCouple = async () => { try { if ( !(await confirm( "Voulez-vous vraiment supprimer cette fiche de couple ? L'opération n'est pas réversible !" )) ) return; await CoupleApi.Delete(couple!); snackbar("La fiche du couple a été supprimée avec succès !"); n(family.family.URL("genealogy/couples")); await genealogy.reloadCouplesList(); } catch (e) { console.error(e); alert("Échec de la suppression du couple !"); } }; return ( ( n(family.family.coupleURL(couple!, true))} onForceReload={forceReload} /> )} /> ); } /** * Edit existing couple route */ export function FamilyEditCoupleRoute(): React.ReactElement { const n = useNavigate(); const { coupleId } = useParams(); const alert = useAlert(); const snackbar = useSnackbar(); const [shouldQuit, setShouldQuit] = React.useState(false); const genealogy = useGenealogy(); const family = useFamily(); const [couple, setCouple] = React.useState(); const load = async () => { setCouple(await CoupleApi.GetSingle(family.familyId, Number(coupleId))); }; const cancel = () => { setShouldQuit(true); n(family.family.coupleURL(couple!)); //n(-1); }; const save = async (c: Couple) => { try { await CoupleApi.Update(c); snackbar("Les informations du couple ont été mises à jour avec succès !"); await genealogy.reloadCouplesList(); setShouldQuit(true); n(family.family.coupleURL(c, false)); } catch (e) { console.error(e); alert("Échec de la mise à jour des informations du couple !"); } }; return ( ( )} /> ); } export function CouplePage(p: { couple: Couple; editing: boolean; creating: boolean; shouldAllowLeaving?: boolean; children?: Member[]; onCancel?: () => void; onSave?: (m: Couple) => Promise; onRequestEdit?: () => void; onRequestDelete?: () => void; onForceReload?: () => void; }): React.ReactElement { const confirm = useConfirm(); const snackbar = useSnackbar(); const loadingMessage = useLoadingMessage(); const family = useFamily(); const [changed, setChanged] = React.useState(false); const [couple, setCouple] = React.useState( new Couple(structuredClone(p.couple)) ); const updatedCouple = () => { setChanged(true); setCouple(new Couple(structuredClone(couple))); }; const save = async () => { loadingMessage.show( "Enregistrement des informations du couple en cours..." ); await p.onSave!(couple); loadingMessage.hide(); }; const cancel = async () => { if ( changed && !(await confirm( "Voulez-vous vraiment retirer les modifications apportées ? Celles-ci seront perdues !" )) ) return; p.onCancel!(); }; const uploadNewPhoto = async (b: Blob) => { await CoupleApi.SetCouplePhoto(couple, b); snackbar("La photo du couple a été mise à jour avec succès !"); p.onForceReload?.(); }; const deletePhoto = async () => { try { if (!(await confirm("Voulez-vous supprimer cette photo ?"))) return; await CoupleApi.RemoveCouplePhoto(couple); snackbar("La photo du couple a été supprimée avec succès !"); p.onForceReload?.(); } catch (e) { console.error(e); alert("Échec de la suppresion de la photo !"); } }; return (
{/* Edit button */} {p.onRequestEdit && ( )} {/* Delete button */} {p.onRequestDelete && ( )} {/* Save button */} {p.editing && changed && ( )} {/* Cancel button */} {p.editing && ( )}
{/* General info */} {/* Husband */}
{ couple.husband = m; updatedCouple(); }} filter={(m) => m.sex === "M" || m.sex === undefined} current={couple.husband} /> {/* Wife */}
{ couple.wife = m; updatedCouple(); }} filter={(m) => m.sex === "F" || m.sex === undefined} current={couple.wife} />
{/* State */} { couple.state = s; updatedCouple(); }} options={ServerApi.Config.couples_states.map((s) => { return { label: s.fr, value: s.code }; })} /> {/* Wedding day */} { couple.wedding_year = d.year; couple.wedding_month = d.month; couple.wedding_day = d.day; updatedCouple(); }} /> {/* Divorce day */} { couple.divorce_year = d.year; couple.divorce_month = d.month; couple.divorce_day = d.day; updatedCouple(); }} />
{ /* Photo */ !family.family.disable_couple_photos && (

{p.editing ? (

Veuillez enregistrer / annuler les modifications apportées à la fiche avant de changer la photo du couple.

) : ( <> {" "} {couple.hasPhoto && ( )}{" "} {couple.hasPhoto && ( )} )}{" "}
) } {/* Children */} {p.children && ( {p.children.length === 0 ? ( <>Aucun enfant ) : ( p.children.map((c) => ( )) )} {couple.wife && couple.husband && (
)}
)}
); }