Make members information globally available

This commit is contained in:
Pierre HUBERT 2023-08-09 08:55:37 +02:00
parent 1128b5ebd4
commit 359dd2f9ee
3 changed files with 143 additions and 96 deletions

View File

@ -2,7 +2,7 @@ import { APIClient } from "./ApiClient";
export type Sex = "M" | "F"; export type Sex = "M" | "F";
export interface MemberApi { export interface MemberDataApi {
id: number; id: number;
family_id: number; family_id: number;
first_name?: string; first_name?: string;
@ -31,7 +31,7 @@ export interface MemberApi {
note?: string; note?: string;
} }
export class Member implements MemberApi { export class Member implements MemberDataApi {
id: number; id: number;
family_id: number; family_id: number;
first_name?: string; first_name?: string;
@ -59,7 +59,7 @@ export class Member implements MemberApi {
death_day?: number; death_day?: number;
note?: string; note?: string;
constructor(m: MemberApi) { constructor(m: MemberDataApi) {
this.id = m.id; this.id = m.id;
this.family_id = m.family_id; this.family_id = m.family_id;
this.first_name = m.first_name; this.first_name = m.first_name;
@ -108,6 +108,20 @@ export class Member implements MemberApi {
} }
} }
export class MembersList {
private list: Member[];
private map: Map<number, Member>;
constructor(list: Member[]) {
this.list = list;
this.map = new Map();
for (const m of list) {
this.map.set(m.id, m);
}
}
}
export class MemberApi { export class MemberApi {
/** /**
* Create a new member * Create a new member
@ -137,6 +151,18 @@ export class MemberApi {
return new Member(res.data); return new Member(res.data);
} }
/**
* Get the entire list of family members of a family
*/
static async GetEntireList(family_id: number): Promise<MembersList> {
const res = await APIClient.exec({
uri: `/family/${family_id}/members`,
method: "GET",
});
return new MembersList(res.data.map((d: any) => new Member(d)));
}
/** /**
* Update a member information * Update a member information
*/ */

View File

@ -33,7 +33,7 @@ export function FamilyCreateMemberRoute(): React.ReactElement {
try { try {
const r = await MemberApi.Create(m); const r = await MemberApi.Create(m);
// TODO : trigger update await family.reloadMembersList();
setShouldQuit(true); setShouldQuit(true);
n(family.family.URL(`member/${r.id}`)); n(family.family.URL(`member/${r.id}`));
@ -92,7 +92,7 @@ export function FamilyMemberRoute(): React.ReactElement {
snackbar("La fiche de membre a été supprimée avec succès !"); snackbar("La fiche de membre a été supprimée avec succès !");
n(family.family.URL("members")); n(family.family.URL("members"));
// TODO : refresh cached members list await family.reloadMembersList();
} catch (e) { } catch (e) {
console.error(e); console.error(e);
alert("Échec de la suppression du membre !"); alert("Échec de la suppression du membre !");
@ -148,7 +148,7 @@ export function FamilyEditMemberRoute(): React.ReactElement {
snackbar("Les informations du membre ont été mises à jour avec succès !"); snackbar("Les informations du membre ont été mises à jour avec succès !");
// TODO : update family hook info await family.reloadMembersList();
setShouldQuit(true); setShouldQuit(true);
n(family.family.URL(`member/${member!.id}`)); n(family.family.URL(`member/${member!.id}`));
@ -193,7 +193,6 @@ export function MemberPage(p: {
const [member, setMember] = React.useState(structuredClone(p.member)); const [member, setMember] = React.useState(structuredClone(p.member));
const updatedMember = () => { const updatedMember = () => {
// TODO : add confirmation
setChanged(true); setChanged(true);
setMember(structuredClone(member)); setMember(structuredClone(member));
}; };

View File

@ -30,11 +30,14 @@ import { RouterLink } from "./RouterLink";
import { useSnackbar } from "../hooks/context_providers/SnackbarProvider"; import { useSnackbar } from "../hooks/context_providers/SnackbarProvider";
import { useConfirm } from "../hooks/context_providers/ConfirmDialogProvider"; import { useConfirm } from "../hooks/context_providers/ConfirmDialogProvider";
import { useAlert } from "../hooks/context_providers/AlertDialogProvider"; import { useAlert } from "../hooks/context_providers/AlertDialogProvider";
import { Member, MemberApi, MembersList } from "../api/MemberApi";
interface FamilyContext { interface FamilyContext {
family: Family; family: Family;
members: MembersList;
familyId: number; familyId: number;
reloadFamilyInfo: () => void; reloadFamilyInfo: () => void;
reloadMembersList: () => Promise<void>;
} }
const FamilyContextK = React.createContext<FamilyContext | null>(null); const FamilyContextK = React.createContext<FamilyContext | null>(null);
@ -46,16 +49,26 @@ export function BaseFamilyRoute(): React.ReactElement {
const confirm = useConfirm(); const confirm = useConfirm();
const [family, setFamily] = React.useState<null | Family>(null); const [family, setFamily] = React.useState<null | Family>(null);
const [members, setMembers] = React.useState<null | MembersList>(null);
const loadKey = React.useRef(1); const loadKey = React.useRef(1);
const loadPromise = React.useRef<() => void>();
const load = async () => { const load = async () => {
setFamily(await FamilyApi.GetSingle(Number(familyId))); const familyID = Number(familyId);
setFamily(await FamilyApi.GetSingle(familyID));
setMembers(await MemberApi.GetEntireList(familyID));
}; };
const onReload = () => { const onReload = async () => {
loadKey.current += 1; loadKey.current += 1;
setFamily(null); setFamily(null);
setMembers(null);
return new Promise<void>((res, _rej) => {
loadPromise.current = () => res();
});
}; };
const copyInvitationCode = async () => { const copyInvitationCode = async () => {
@ -85,16 +98,24 @@ export function BaseFamilyRoute(): React.ReactElement {
return ( return (
<AsyncWidget <AsyncWidget
ready={family != null} ready={family !== null && members !== null}
loadKey={`${familyId}-${loadKey.current}`} loadKey={`${familyId}-${loadKey.current}`}
load={load} load={load}
errMsg="Échec du chargement des informations de la famille !" errMsg="Échec du chargement des informations de la famille !"
build={() => ( build={() => {
if (loadPromise.current != null) {
loadPromise.current?.();
loadPromise.current = undefined;
}
return (
<FamilyContextK.Provider <FamilyContextK.Provider
value={{ value={{
family: family!, family: family!,
members: members!,
familyId: family!.family_id, familyId: family!.family_id,
reloadFamilyInfo: onReload, reloadFamilyInfo: onReload,
reloadMembersList: onReload,
}} }}
> >
<Box <Box
@ -191,7 +212,8 @@ export function BaseFamilyRoute(): React.ReactElement {
</Box> </Box>
</Box> </Box>
</FamilyContextK.Provider> </FamilyContextK.Provider>
)} );
}}
/> />
); );
} }