Can create a member
This commit is contained in:
		@@ -1,3 +1,5 @@
 | 
			
		||||
import { APIClient } from "./ApiClient";
 | 
			
		||||
 | 
			
		||||
export type Sex = "M" | "F";
 | 
			
		||||
 | 
			
		||||
export interface MemberApi {
 | 
			
		||||
@@ -85,4 +87,30 @@ export class Member implements MemberApi {
 | 
			
		||||
    this.death_day = m.death_day;
 | 
			
		||||
    this.note = m.note;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Create an empty member object
 | 
			
		||||
   */
 | 
			
		||||
  static New(family_id: number): Member {
 | 
			
		||||
    return new Member({
 | 
			
		||||
      id: 0,
 | 
			
		||||
      dead: false,
 | 
			
		||||
      family_id: family_id,
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export class MemberApi {
 | 
			
		||||
  /**
 | 
			
		||||
   * Create a new member
 | 
			
		||||
   */
 | 
			
		||||
  static async Create(m: Member): Promise<Member> {
 | 
			
		||||
    const res = await APIClient.exec({
 | 
			
		||||
      uri: `/family/${m.family_id}/member/create`,
 | 
			
		||||
      method: "POST",
 | 
			
		||||
      jsonData: m,
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    return new Member(res.data);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,23 +1,49 @@
 | 
			
		||||
import ClearIcon from "@mui/icons-material/Clear";
 | 
			
		||||
import SaveIcon from "@mui/icons-material/Save";
 | 
			
		||||
import { Button, Grid, Stack } from "@mui/material";
 | 
			
		||||
import React from "react";
 | 
			
		||||
import { Member } from "../../api/MemberApi";
 | 
			
		||||
import { useFamily } from "../../widgets/BaseFamilyRoute";
 | 
			
		||||
import { Grid, Typography } from "@mui/material";
 | 
			
		||||
import { PropertiesBox } from "../../widgets/PropertiesBox";
 | 
			
		||||
import { PropEdit } from "../../widgets/PropEdit";
 | 
			
		||||
import { useNavigate } from "react-router-dom";
 | 
			
		||||
import { Member, MemberApi } from "../../api/MemberApi";
 | 
			
		||||
import { ServerApi } from "../../api/ServerApi";
 | 
			
		||||
import { useAlert } from "../../context_providers/AlertDialogProvider";
 | 
			
		||||
import { useConfirm } from "../../context_providers/ConfirmDialogProvider";
 | 
			
		||||
import { useFamily } from "../../widgets/BaseFamilyRoute";
 | 
			
		||||
import { FamilyPageTitle } from "../../widgets/FamilyPageTitle";
 | 
			
		||||
import { PropEdit } from "../../widgets/PropEdit";
 | 
			
		||||
import { PropertiesBox } from "../../widgets/PropertiesBox";
 | 
			
		||||
import { SexSelection } from "../../widgets/SexSelection";
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Create a new member route
 | 
			
		||||
 */
 | 
			
		||||
export function FamilyCreateMemberRoute(): React.ReactElement {
 | 
			
		||||
  const alert = useAlert();
 | 
			
		||||
 | 
			
		||||
  const n = useNavigate();
 | 
			
		||||
  const family = useFamily();
 | 
			
		||||
  const member = new Member({
 | 
			
		||||
    id: 0,
 | 
			
		||||
    dead: false,
 | 
			
		||||
    family_id: family.family.family_id,
 | 
			
		||||
  });
 | 
			
		||||
  return <MemberPage member={member} creating={true} forceEdit={true} />;
 | 
			
		||||
 | 
			
		||||
  const create = async (m: Member) => {
 | 
			
		||||
    try {
 | 
			
		||||
      const r = await MemberApi.Create(m);
 | 
			
		||||
 | 
			
		||||
      // TODO : trigger update
 | 
			
		||||
 | 
			
		||||
      n(family.family.URL(`member/${r.id}`));
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      console.error(e);
 | 
			
		||||
      alert("Echec de la création de la personne !");
 | 
			
		||||
    }
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  return (
 | 
			
		||||
    <MemberPage
 | 
			
		||||
      member={Member.New(family.family.family_id)}
 | 
			
		||||
      creating={true}
 | 
			
		||||
      editing={true}
 | 
			
		||||
      onCancel={() => n(family.family.URL("members"))}
 | 
			
		||||
      onSave={create}
 | 
			
		||||
    />
 | 
			
		||||
  );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -29,21 +55,79 @@ export function FamilyMemberRoute(): React.ReactElement {
 | 
			
		||||
 | 
			
		||||
export function MemberPage(p: {
 | 
			
		||||
  member: Member;
 | 
			
		||||
  forceEdit: boolean;
 | 
			
		||||
  editing: boolean;
 | 
			
		||||
  creating: boolean;
 | 
			
		||||
  onCancel: () => void;
 | 
			
		||||
  onSave: (m: Member) => void;
 | 
			
		||||
  onRequestEdit?: () => void;
 | 
			
		||||
}): React.ReactElement {
 | 
			
		||||
  const confirm = useConfirm();
 | 
			
		||||
 | 
			
		||||
  // TODO : add confirmation when leaving page https://dev.to/bangash1996/detecting-user-leaving-page-with-react-router-dom-v602-33ni
 | 
			
		||||
  const [editing, setEditing] = React.useState(p.forceEdit);
 | 
			
		||||
  const [changed, setChanged] = React.useState(false);
 | 
			
		||||
  const [member, setMember] = React.useState(structuredClone(p.member));
 | 
			
		||||
 | 
			
		||||
  const updatedMember = () => {
 | 
			
		||||
    // TODO : add confirmation
 | 
			
		||||
    setChanged(true);
 | 
			
		||||
    setMember(structuredClone(member));
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  const save = () => {
 | 
			
		||||
    p.onSave(member);
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  const cancel = async () => {
 | 
			
		||||
    if (
 | 
			
		||||
      !(await confirm(
 | 
			
		||||
        "Voulez-vous vraiment retirer les modifications apportées ? Celles-ci seront perdues !"
 | 
			
		||||
      ))
 | 
			
		||||
    )
 | 
			
		||||
      return;
 | 
			
		||||
 | 
			
		||||
    p.onCancel();
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  return (
 | 
			
		||||
    <div style={{ maxWidth: "2000px", margin: "auto" }}>
 | 
			
		||||
      <Typography variant="h3">Fiche de membre</Typography>
 | 
			
		||||
      <div
 | 
			
		||||
        style={{
 | 
			
		||||
          display: "flex",
 | 
			
		||||
          justifyContent: "space-between",
 | 
			
		||||
          alignItems: "center",
 | 
			
		||||
        }}
 | 
			
		||||
      >
 | 
			
		||||
        <FamilyPageTitle
 | 
			
		||||
          title={
 | 
			
		||||
            (p.creating ? "Création" : "Édition") + " d'une fiche de membre"
 | 
			
		||||
          }
 | 
			
		||||
        />
 | 
			
		||||
        <Stack direction="row" spacing={1}>
 | 
			
		||||
          {/* Save button */}
 | 
			
		||||
          {p.editing && (
 | 
			
		||||
            <Button
 | 
			
		||||
              variant="contained"
 | 
			
		||||
              startIcon={<SaveIcon />}
 | 
			
		||||
              onClick={save}
 | 
			
		||||
              size="large"
 | 
			
		||||
            >
 | 
			
		||||
              Enregistrer
 | 
			
		||||
            </Button>
 | 
			
		||||
          )}
 | 
			
		||||
 | 
			
		||||
          {/* Cancel button */}
 | 
			
		||||
          {p.editing && (
 | 
			
		||||
            <Button
 | 
			
		||||
              variant="outlined"
 | 
			
		||||
              startIcon={<ClearIcon />}
 | 
			
		||||
              onClick={cancel}
 | 
			
		||||
              size="small"
 | 
			
		||||
            >
 | 
			
		||||
              Annuler les modifications
 | 
			
		||||
            </Button>
 | 
			
		||||
          )}
 | 
			
		||||
        </Stack>
 | 
			
		||||
      </div>
 | 
			
		||||
      <Grid container spacing={2}>
 | 
			
		||||
        <Grid item sm={12} md={6}>
 | 
			
		||||
          <PropertiesBox title="Informations générales">
 | 
			
		||||
@@ -59,7 +143,7 @@ export function MemberPage(p: {
 | 
			
		||||
            {/* First name */}
 | 
			
		||||
            <PropEdit
 | 
			
		||||
              label="Prénom"
 | 
			
		||||
              editable={editing}
 | 
			
		||||
              editable={p.editing}
 | 
			
		||||
              value={member.first_name}
 | 
			
		||||
              onValueChange={(v) => {
 | 
			
		||||
                member.first_name = v;
 | 
			
		||||
@@ -71,7 +155,7 @@ export function MemberPage(p: {
 | 
			
		||||
            {/* Last name */}
 | 
			
		||||
            <PropEdit
 | 
			
		||||
              label="Nom"
 | 
			
		||||
              editable={editing}
 | 
			
		||||
              editable={p.editing}
 | 
			
		||||
              value={member.last_name}
 | 
			
		||||
              onValueChange={(v) => {
 | 
			
		||||
                member.last_name = v;
 | 
			
		||||
@@ -81,7 +165,7 @@ export function MemberPage(p: {
 | 
			
		||||
            />
 | 
			
		||||
            <PropEdit
 | 
			
		||||
              label="Nom de naissance"
 | 
			
		||||
              editable={editing}
 | 
			
		||||
              editable={p.editing}
 | 
			
		||||
              value={member.birth_last_name}
 | 
			
		||||
              onValueChange={(v) => {
 | 
			
		||||
                member.birth_last_name = v;
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user