Can filter couples
This commit is contained in:
		@@ -115,6 +115,14 @@ export class Member implements MemberDataApi {
 | 
			
		||||
      : `${firstName} ${this.last_name ?? ""}`;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  get invertedFullName(): string {
 | 
			
		||||
    const lastName = this.last_name ?? "";
 | 
			
		||||
 | 
			
		||||
    return lastName.length === 0
 | 
			
		||||
      ? this.last_name ?? ""
 | 
			
		||||
      : `${lastName} ${this.first_name ?? ""}`;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  get hasPhoto(): boolean {
 | 
			
		||||
    return this.photo_id !== null;
 | 
			
		||||
  }
 | 
			
		||||
 
 | 
			
		||||
@@ -1,11 +1,15 @@
 | 
			
		||||
import { Link } from "react-router-dom";
 | 
			
		||||
import { RouterLink } from "../widgets/RouterLink";
 | 
			
		||||
import { Button } from "@mui/material";
 | 
			
		||||
 | 
			
		||||
export function NotFoundRoute(): React.ReactElement {
 | 
			
		||||
  return (
 | 
			
		||||
    <div style={{ textAlign: "center" }}>
 | 
			
		||||
      <h1>Page non trouvée !</h1>
 | 
			
		||||
      <p>La page que vous demandez n'a pas été trouvée !</p>
 | 
			
		||||
      <Link to="/">Retour à l'accueil</Link>
 | 
			
		||||
      <RouterLink to="/">
 | 
			
		||||
        <Button>Retour à l'accueil</Button>
 | 
			
		||||
      </RouterLink>
 | 
			
		||||
    </div>
 | 
			
		||||
  );
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,23 +1,22 @@
 | 
			
		||||
import AddIcon from "@mui/icons-material/Add";
 | 
			
		||||
import DeleteIcon from "@mui/icons-material/DeleteOutlined";
 | 
			
		||||
import EditIcon from "@mui/icons-material/Edit";
 | 
			
		||||
import FemaleIcon from "@mui/icons-material/Female";
 | 
			
		||||
import MaleIcon from "@mui/icons-material/Male";
 | 
			
		||||
import VisibilityIcon from "@mui/icons-material/Visibility";
 | 
			
		||||
import { Button, TextField, Tooltip } from "@mui/material";
 | 
			
		||||
import { DataGrid, GridActionsCellItem, GridColDef } from "@mui/x-data-grid";
 | 
			
		||||
import React from "react";
 | 
			
		||||
import { useNavigate } from "react-router-dom";
 | 
			
		||||
import { Couple, CoupleApi } from "../../api/CoupleApi";
 | 
			
		||||
import { dateTimestamp, fmtDate } from "../../api/MemberApi";
 | 
			
		||||
import { ServerApi } from "../../api/ServerApi";
 | 
			
		||||
import { useAlert } from "../../hooks/context_providers/AlertDialogProvider";
 | 
			
		||||
import { useConfirm } from "../../hooks/context_providers/ConfirmDialogProvider";
 | 
			
		||||
import { useSnackbar } from "../../hooks/context_providers/SnackbarProvider";
 | 
			
		||||
import { useFamily } from "../../widgets/BaseFamilyRoute";
 | 
			
		||||
import { FamilyPageTitle } from "../../widgets/FamilyPageTitle";
 | 
			
		||||
import { RouterLink } from "../../widgets/RouterLink";
 | 
			
		||||
import { Couple, CoupleApi } from "../../api/CoupleApi";
 | 
			
		||||
import { CouplePhoto } from "../../widgets/CouplePhoto";
 | 
			
		||||
import { ServerApi } from "../../api/ServerApi";
 | 
			
		||||
import { dateTimestamp, fmtDate } from "../../api/MemberApi";
 | 
			
		||||
import { FamilyPageTitle } from "../../widgets/FamilyPageTitle";
 | 
			
		||||
import { MemberPhoto } from "../../widgets/MemberPhoto";
 | 
			
		||||
import { RouterLink } from "../../widgets/RouterLink";
 | 
			
		||||
 | 
			
		||||
export function FamilyCouplesListRoute(): React.ReactElement {
 | 
			
		||||
  const alert = useAlert();
 | 
			
		||||
@@ -83,7 +82,19 @@ export function FamilyCouplesListRoute(): React.ReactElement {
 | 
			
		||||
            couples={
 | 
			
		||||
              filter === ""
 | 
			
		||||
                ? family.couples.fullList
 | 
			
		||||
                : family.couples.filter((m) => true /* TODO */)
 | 
			
		||||
                : family.couples.filter(
 | 
			
		||||
                    (m) =>
 | 
			
		||||
                      (m.wife &&
 | 
			
		||||
                        family.members
 | 
			
		||||
                          .get(m.wife)!
 | 
			
		||||
                          .fullName.toLocaleLowerCase()
 | 
			
		||||
                          .includes(filter.toLocaleLowerCase())) ||
 | 
			
		||||
                      (m.husband &&
 | 
			
		||||
                        family.members
 | 
			
		||||
                          .get(m.husband)!
 | 
			
		||||
                          .fullName.toLocaleLowerCase()
 | 
			
		||||
                          .includes(filter.toLocaleLowerCase())) === true
 | 
			
		||||
                  )
 | 
			
		||||
            }
 | 
			
		||||
            onDelete={processDeletion}
 | 
			
		||||
          />
 | 
			
		||||
@@ -100,6 +111,19 @@ function CouplesTable(p: {
 | 
			
		||||
  const family = useFamily();
 | 
			
		||||
  const n = useNavigate();
 | 
			
		||||
 | 
			
		||||
  const compareInvertedMembersNames = (
 | 
			
		||||
    v1: number | undefined,
 | 
			
		||||
    v2: number | undefined
 | 
			
		||||
  ) => {
 | 
			
		||||
    const n1 = ((v1 && family.members.get(v1)?.invertedFullName) ?? "") || "";
 | 
			
		||||
    const n2 = ((v2 && family.members.get(v2)?.invertedFullName) ?? "") || "";
 | 
			
		||||
 | 
			
		||||
    return n1?.localeCompare(n2, undefined, {
 | 
			
		||||
      ignorePunctuation: true,
 | 
			
		||||
      sensitivity: "base",
 | 
			
		||||
    });
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  const columns: GridColDef<Couple>[] = [
 | 
			
		||||
    {
 | 
			
		||||
      field: "signed_photo_id",
 | 
			
		||||
@@ -116,18 +140,26 @@ function CouplesTable(p: {
 | 
			
		||||
      field: "husband",
 | 
			
		||||
      headerName: "Époux",
 | 
			
		||||
      flex: 5,
 | 
			
		||||
      sortComparator: compareInvertedMembersNames,
 | 
			
		||||
      renderCell(params) {
 | 
			
		||||
        return <MemberCell id={params.row.husband} />;
 | 
			
		||||
      },
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    {
 | 
			
		||||
      field: "wife",
 | 
			
		||||
      headerName: "Épouse",
 | 
			
		||||
      flex: 5,
 | 
			
		||||
      sortComparator: compareInvertedMembersNames,
 | 
			
		||||
      renderCell(params) {
 | 
			
		||||
        return <MemberCell id={params.row.wife} />;
 | 
			
		||||
      },
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    {
 | 
			
		||||
      field: "state",
 | 
			
		||||
      headerName: "État",
 | 
			
		||||
      width: 50,
 | 
			
		||||
      flex: 3,
 | 
			
		||||
      renderCell(params) {
 | 
			
		||||
        return ServerApi.Config.couples_states.find(
 | 
			
		||||
          (c) => c.code === params.row.state
 | 
			
		||||
@@ -200,7 +232,34 @@ function CouplesTable(p: {
 | 
			
		||||
      columns={columns}
 | 
			
		||||
      autoPageSize
 | 
			
		||||
      getRowId={(c) => c.id}
 | 
			
		||||
      onRowDoubleClick={(p) => n(family.family.coupleURL(p.row))}
 | 
			
		||||
      onCellDoubleClick={(p) => {
 | 
			
		||||
        let member;
 | 
			
		||||
        if (p.field === "wife") member = family.members.get(p.row.wife);
 | 
			
		||||
        else if (p.field === "husband")
 | 
			
		||||
          member = family.members.get(p.row.husband);
 | 
			
		||||
 | 
			
		||||
        if (member) {
 | 
			
		||||
          n(family.family.memberURL(member));
 | 
			
		||||
          return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        n(family.family.coupleURL(p.row));
 | 
			
		||||
      }}
 | 
			
		||||
    />
 | 
			
		||||
  );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function MemberCell(p: { id?: number }): React.ReactElement {
 | 
			
		||||
  const family = useFamily();
 | 
			
		||||
  if (!p.id) return <></>;
 | 
			
		||||
 | 
			
		||||
  const member = family.members.get(p.id!)!;
 | 
			
		||||
 | 
			
		||||
  return (
 | 
			
		||||
    <Tooltip title="Double-cliquez ici pour accéder à la fiche du membre">
 | 
			
		||||
      <div style={{ display: "flex", alignItems: "center" }}>
 | 
			
		||||
        <MemberPhoto member={member} width={25} />   {member.fullName}
 | 
			
		||||
      </div>
 | 
			
		||||
    </Tooltip>
 | 
			
		||||
  );
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user