Can filter couples

This commit is contained in:
Pierre HUBERT 2023-08-17 14:59:06 +02:00
parent e753710964
commit fa7d60726f
3 changed files with 82 additions and 11 deletions

View File

@ -115,6 +115,14 @@ export class Member implements MemberDataApi {
: `${firstName} ${this.last_name ?? ""}`; : `${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 { get hasPhoto(): boolean {
return this.photo_id !== null; return this.photo_id !== null;
} }

View File

@ -1,11 +1,15 @@
import { Link } from "react-router-dom"; import { Link } from "react-router-dom";
import { RouterLink } from "../widgets/RouterLink";
import { Button } from "@mui/material";
export function NotFoundRoute(): React.ReactElement { export function NotFoundRoute(): React.ReactElement {
return ( return (
<div style={{ textAlign: "center" }}> <div style={{ textAlign: "center" }}>
<h1>Page non trouvée !</h1> <h1>Page non trouvée !</h1>
<p>La page que vous demandez n'a pas é trouvée !</p> <p>La page que vous demandez n'a pas é trouvée !</p>
<Link to="/">Retour à l'accueil</Link> <RouterLink to="/">
<Button>Retour à l'accueil</Button>
</RouterLink>
</div> </div>
); );
} }

View File

@ -1,23 +1,22 @@
import AddIcon from "@mui/icons-material/Add"; import AddIcon from "@mui/icons-material/Add";
import DeleteIcon from "@mui/icons-material/DeleteOutlined"; import DeleteIcon from "@mui/icons-material/DeleteOutlined";
import EditIcon from "@mui/icons-material/Edit"; 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 VisibilityIcon from "@mui/icons-material/Visibility";
import { Button, TextField, Tooltip } from "@mui/material"; import { Button, TextField, Tooltip } from "@mui/material";
import { DataGrid, GridActionsCellItem, GridColDef } from "@mui/x-data-grid"; import { DataGrid, GridActionsCellItem, GridColDef } from "@mui/x-data-grid";
import React from "react"; import React from "react";
import { useNavigate } from "react-router-dom"; 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 { useAlert } from "../../hooks/context_providers/AlertDialogProvider";
import { useConfirm } from "../../hooks/context_providers/ConfirmDialogProvider"; import { useConfirm } from "../../hooks/context_providers/ConfirmDialogProvider";
import { useSnackbar } from "../../hooks/context_providers/SnackbarProvider"; import { useSnackbar } from "../../hooks/context_providers/SnackbarProvider";
import { useFamily } from "../../widgets/BaseFamilyRoute"; 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 { CouplePhoto } from "../../widgets/CouplePhoto";
import { ServerApi } from "../../api/ServerApi"; import { FamilyPageTitle } from "../../widgets/FamilyPageTitle";
import { dateTimestamp, fmtDate } from "../../api/MemberApi"; import { MemberPhoto } from "../../widgets/MemberPhoto";
import { RouterLink } from "../../widgets/RouterLink";
export function FamilyCouplesListRoute(): React.ReactElement { export function FamilyCouplesListRoute(): React.ReactElement {
const alert = useAlert(); const alert = useAlert();
@ -83,7 +82,19 @@ export function FamilyCouplesListRoute(): React.ReactElement {
couples={ couples={
filter === "" filter === ""
? family.couples.fullList ? 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} onDelete={processDeletion}
/> />
@ -100,6 +111,19 @@ function CouplesTable(p: {
const family = useFamily(); const family = useFamily();
const n = useNavigate(); 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>[] = [ const columns: GridColDef<Couple>[] = [
{ {
field: "signed_photo_id", field: "signed_photo_id",
@ -116,18 +140,26 @@ function CouplesTable(p: {
field: "husband", field: "husband",
headerName: "Époux", headerName: "Époux",
flex: 5, flex: 5,
sortComparator: compareInvertedMembersNames,
renderCell(params) {
return <MemberCell id={params.row.husband} />;
},
}, },
{ {
field: "wife", field: "wife",
headerName: "Épouse", headerName: "Épouse",
flex: 5, flex: 5,
sortComparator: compareInvertedMembersNames,
renderCell(params) {
return <MemberCell id={params.row.wife} />;
},
}, },
{ {
field: "state", field: "state",
headerName: "État", headerName: "État",
width: 50, flex: 3,
renderCell(params) { renderCell(params) {
return ServerApi.Config.couples_states.find( return ServerApi.Config.couples_states.find(
(c) => c.code === params.row.state (c) => c.code === params.row.state
@ -200,7 +232,34 @@ function CouplesTable(p: {
columns={columns} columns={columns}
autoPageSize autoPageSize
getRowId={(c) => c.id} 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} /> &nbsp; {member.fullName}
</div>
</Tooltip>
);
}