Skip to content

Commit

Permalink
feat: search result page revamp
Browse files Browse the repository at this point in the history
Signed-off-by: Maud Royer <[email protected]>
  • Loading branch information
jillro committed Oct 10, 2024
1 parent 41a79c0 commit 98ce92e
Show file tree
Hide file tree
Showing 4 changed files with 190 additions and 63 deletions.
64 changes: 45 additions & 19 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
179 changes: 136 additions & 43 deletions src/app/rechercher/page.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,130 @@
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 Image from "next/image";
import { fr } from "@codegouvfr/react-dsfr";
import Badge from "@codegouvfr/react-dsfr/Badge";
import Tag from "@codegouvfr/react-dsfr/Tag";
import List from "@mui/material/List";
import ListItem from "@mui/material/ListItem";
import ListItemText from "@mui/material/ListItemText";
import ListItemIcon from "@mui/material/ListItemIcon";
import ListItemButton from "@mui/material/ListItemButton";
import Divider from "@mui/material/Divider";
import SubdirectoryArrowRightIcon from "@mui/icons-material/SubdirectoryArrowRight";

import { formatSpecName } from "@/displayUtils";
import pillIcon from "@/customIcons/pill.svg";
import moleculeIcon from "@/customIcons/molecule.svg";
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 }) => (
<Link href={`/substance/${item.NomId}`}>
<ListItemButton sx={{ mb: 2 }}>
<ListItemIcon>
<Image src={moleculeIcon} width="24" height="24" alt="Substance" />
</ListItemIcon>
<ListItemText
disableTypography
primary={<b>{formatSpecName(item.NomLib)}</b>}
/>
<i className={fr.cx("fr-icon-arrow-right-line")} />
</ListItemButton>
</Link>
);

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 (
<li>
<ListItem component="div">
<ListItemIcon>
<Image src={pillIcon} width="24" height="24" alt="Médicament" />
</ListItemIcon>
<ListItemText
disableTypography
primary={
<div className={fr.cx("fr-mb-1v")}>
<b>{formatSpecName(item.groupName)}</b>
</div>
}
secondary={
<div>
{substance && (
<Tag
nativeButtonProps={{
className: fr.cx(
"fr-tag--purple-glycine",
"fr-mb-1v",
"fr-mr-2w",
),
}}
>
{substance}
</Tag>
)}
{subClass && (
<Tag
nativeButtonProps={{
className: fr.cx("fr-tag--yellow-tournesol"),
}}
>
{subClass}
</Tag>
)}
</div>
}
/>
</ListItem>
<List sx={{ mb: 2 }}>
{item.specialites?.map((specialite, i) => (
<li key={i} className={fr.cx("fr-py-0")}>
{i > 0 && <Divider sx={{ py: 0 }} />}
<Link
href={`/medicament/${specialite.SpecId}`}
key={specialite.SpecId}
>
<ListItemButton sx={{ pl: 4 }}>
<ListItemIcon>
<SubdirectoryArrowRightIcon />
</ListItemIcon>
<ListItemText
disableTypography
primary={formatSpecName(specialite.SpecDenom01)
.replace(`${formatSpecName(item.groupName)}, `, "")
.replace(formatSpecName(item.groupName), "")}
/>
<i className={fr.cx("fr-icon-arrow-right-line")} />
</ListItemButton>
</Link>
</li>
))}
</List>
</li>
);
};

export default async function Page({
searchParams,
}: {
Expand All @@ -30,47 +149,21 @@ export default async function Page({
{results && (
<>
<p>{results.length} RÉSULTATS</p>
<ul>
{results.map((result, index) => (
<li key={index} className={"fr-mb-2w"}>
{"NomLib" in result ? (
<>
<Link href={`/substance/${result.NomId}`}>
<b>{formatSpecName(result.NomLib)}</b>
</Link>
<Badge
className={fr.cx("fr-ml-2w", "fr-badge--purple-glycine")}
>
Substance
</Badge>
</>
) : (
<>
<b>{formatSpecName(result.groupName)}</b>
<Badge
className={fr.cx("fr-ml-2w", "fr-badge--green-emeraude")}
>
Médicament
</Badge>
<ul>
{result.specialites?.map((specialite) => (
<li key={specialite.SpecId}>
<Link href={`/medicament/${specialite.SpecId}`}>
{formatSpecName(specialite.SpecDenom01)
.replace(
`${formatSpecName(result.groupName)}, `,
"",
)
.replace(formatSpecName(result.groupName), "")}
</Link>
</li>
))}
</ul>
</>
)}
</li>
))}
</ul>
<div className={fr.cx("fr-grid-row")}>
<div className={fr.cx("fr-col-12", "fr-col-lg-9", "fr-col-md-10")}>
<List>
{results.map((result, index) => (
<Fragment key={index}>
{"NomLib" in result ? (
<SubstanceResult item={result} />
) : (
<MedicamentGroupResult key={index} item={result} />
)}
</Fragment>
))}
</List>
</div>
</div>
</>
)}
</>
Expand Down
7 changes: 7 additions & 0 deletions src/customIcons/pill.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 98ce92e

Please sign in to comment.