From 7a506e1e3173907b9334d1fbf24148fcb7397e57 Mon Sep 17 00:00:00 2001 From: Maud Royer Date: Mon, 7 Oct 2024 14:52:06 +0200 Subject: [PATCH] feat: search result page revamp Signed-off-by: Maud Royer --- package-lock.json | 64 ++++++++--- package.json | 3 +- src/app/rechercher/page.tsx | 197 ++++++++++++++++++++++++-------- src/customIcons/customIcons.css | 7 +- src/customIcons/pill.svg | 7 ++ 5 files changed, 211 insertions(+), 67 deletions(-) create mode 100644 src/customIcons/pill.svg diff --git a/package-lock.json b/package-lock.json index 365b9f3..8a49338 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,7 +11,8 @@ "@codegouvfr/react-dsfr": "^1.9.22", "@emotion/react": "^11.13.3", "@emotion/styled": "^11.13.0", - "@mui/material": "^6.1.1", + "@mui/icons-material": "^6.1.2", + "@mui/material": "^6.1.2", "@sentry/nextjs": "^8.28.0", "csv-parse": "^5.5.6", "jszip": "^3.10.1", @@ -406,6 +407,19 @@ "stylis": "4.2.0" } }, + "node_modules/@emotion/babel-plugin/node_modules/convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==" + }, + "node_modules/@emotion/babel-plugin/node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/@emotion/cache": { "version": "11.13.1", "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.13.1.tgz", @@ -1468,6 +1482,31 @@ "url": "https://opencollective.com/mui-org" } }, + "node_modules/@mui/icons-material": { + "version": "6.1.3", + "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-6.1.3.tgz", + "integrity": "sha512-QBQCCIMSAv6IkArTg4Hg8q2sJRhHOci8oPAlkHWFlt2ghBdy3EqyLbIELLE/bhpqhX+E/ZkPYGIUQCd5/L0owA==", + "dependencies": { + "@babel/runtime": "^7.25.6" + }, + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@mui/material": "^6.1.3", + "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react": "^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, "node_modules/@mui/material": { "version": "6.1.3", "resolved": "https://registry.npmjs.org/@mui/material/-/material-6.1.3.tgz", @@ -4748,11 +4787,6 @@ "node": "^14.18.0 || >=16.10.0" } }, - "node_modules/convert-source-map": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", - "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==" - }, "node_modules/core-util-is": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", @@ -5206,6 +5240,11 @@ "is-arrayish": "^0.2.1" } }, + "node_modules/error-ex/node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==" + }, "node_modules/es-abstract": { "version": "1.23.3", "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.3.tgz", @@ -6787,11 +6826,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==" - }, "node_modules/is-async-function": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.0.0.tgz", @@ -9306,14 +9340,6 @@ "node": ">=8" } }, - "node_modules/source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/source-map-js": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", diff --git a/package.json b/package.json index 4d37882..4463231 100644 --- a/package.json +++ b/package.json @@ -15,7 +15,8 @@ "@codegouvfr/react-dsfr": "^1.9.22", "@emotion/react": "^11.13.3", "@emotion/styled": "^11.13.0", - "@mui/material": "^6.1.1", + "@mui/icons-material": "^6.1.2", + "@mui/material": "^6.1.2", "@sentry/nextjs": "^8.28.0", "csv-parse": "^5.5.6", "jszip": "^3.10.1", diff --git a/src/app/rechercher/page.tsx b/src/app/rechercher/page.tsx index 0fcd21e..7449064 100644 --- a/src/app/rechercher/page.tsx +++ b/src/app/rechercher/page.tsx @@ -1,11 +1,145 @@ +import path from "node:path"; +import { readFileSync } from "node:fs"; +import { Fragment } from "react"; +import { parse as csvParse } from "csv-parse/sync"; import Link from "next/link"; import { fr } from "@codegouvfr/react-dsfr"; -import Badge from "@codegouvfr/react-dsfr/Badge"; +import Tag from "@codegouvfr/react-dsfr/Tag"; +import { cx } from "@codegouvfr/react-dsfr/tools/cx"; +import List from "@mui/material/List"; +import ListItem from "@mui/material/ListItem"; +import ListItemText from "@mui/material/ListItemText"; +import ListItemButton from "@mui/material/ListItemButton"; +import Divider from "@mui/material/Divider"; -import { formatSpecName } from "@/displayUtils"; +import { atcToBreadcrumbs, formatSpecName } from "@/displayUtils"; +import { Specialite, SubstanceNom } from "@/db/pdbmMySQL/types"; import { getResults } from "@/db/search"; import AutocompleteSearch from "@/components/AutocompleteSearch"; +const atcData = csvParse( + readFileSync( + path.join(process.cwd(), "src", "data", "CIS-ATC_2024-04-07.csv"), + ), +) as string[][]; +function getAtc(CIS: string) { + const atc = atcData.find((row) => row[0] === CIS); + return atc ? atc[1] : null; +} + +const SubstanceResult = ({ item }: { item: SubstanceNom }) => ( +
  • + + + + + + {formatSpecName(item.NomLib)} + + + } + /> + + + +
  • +); + +const MedicamentGroupResult = ({ + item, +}: { + item: { groupName: string; specialites: Specialite[] }; +}) => { + const atc = getAtc(item.specialites[0].SpecId); + const atcBreadcrumbs = atc ? atcToBreadcrumbs(atc) : null; + const [, subClass, substance] = atcBreadcrumbs + ? atcBreadcrumbs + : [null, null, null]; + return ( +
  • + + + + {formatSpecName(item.groupName)} + + + } + secondary={ +
    + + {substance && ( + + {substance} + + )} + {subClass && ( + + {subClass} + + )} +
    + } + /> +
    + + {item.specialites?.map((specialite, i) => ( +
  • + + + + + {formatSpecName(specialite.SpecDenom01) + .replace(`${formatSpecName(item.groupName)}, `, "") + .replace(formatSpecName(item.groupName), "")} + + } + /> + + + +
  • + ))} + + + ); +}; + export default async function Page({ searchParams, }: { @@ -28,50 +162,21 @@ export default async function Page({ {results && ( - <> -

    {results.length} RÉSULTATS

    -
      - {results.map((result, index) => ( -
    • - {"NomLib" in result ? ( - <> - - {formatSpecName(result.NomLib)} - - - Substance - - - ) : ( - <> - {formatSpecName(result.groupName)} - - Médicament - -
        - {result.specialites?.map((specialite) => ( -
      • - - {formatSpecName(specialite.SpecDenom01) - .replace( - `${formatSpecName(result.groupName)}, `, - "", - ) - .replace(formatSpecName(result.groupName), "")} - -
      • - ))} -
      - - )} -
    • - ))} -
    - +
    +
    + + {results.map((result, index) => ( + + {"NomLib" in result ? ( + + ) : ( + + )} + + ))} + +
    +
    )} ); diff --git a/src/customIcons/customIcons.css b/src/customIcons/customIcons.css index 997aaae..8e43700 100644 --- a/src/customIcons/customIcons.css +++ b/src/customIcons/customIcons.css @@ -6,4 +6,9 @@ .fr-icon--custom-box::before, .fr-icon--custom-box::after { mask-image:url('box.svg') -} \ No newline at end of file +} + +.fr-icon--custom-pill::before, +.fr-icon--custom-pill::after { + mask-image:url('pill.svg') +} diff --git a/src/customIcons/pill.svg b/src/customIcons/pill.svg new file mode 100644 index 0000000..d9ef3b6 --- /dev/null +++ b/src/customIcons/pill.svg @@ -0,0 +1,7 @@ + + + + + + +