diff --git a/components/NoteCard.tsx b/components/NoteCard.tsx index f8fb043..1661d3e 100644 --- a/components/NoteCard.tsx +++ b/components/NoteCard.tsx @@ -1,4 +1,5 @@ "use client"; + import { Concept, Note } from "@/types/OmopTables"; import { Button } from "@/components/ui/button"; import { @@ -15,7 +16,10 @@ import { } from "@/components/ui/collapsible"; import { Badge } from "@/components/ui/badge"; import { ChevronDownIcon } from "@radix-ui/react-icons"; -import Link from 'next/link' +import Link from "next/link"; +import { usePathname, useRouter, useSearchParams } from "next/navigation"; +import { buildSearchParams } from "@/lib/helpers"; + export default function NoteCard({ note, article, @@ -23,18 +27,53 @@ export default function NoteCard({ note: Note; article: any; }) { - const pmcid = note.note_source_value?.match(/PMC(\d+)/)?.[1]; + const router = useRouter(); + const pathname = usePathname(); + const searchParams = useSearchParams(); + const selectedConceptIds = searchParams.getAll("conceptId"); + const pmcid = note.note_source_value?.match(/PMC(\d+)/)?.[1]; const uniqueConcepts = Array.from( - new Map((note.concepts || []).map((c: any) => [c.concept_id, c])).values(), + new Map( + (note.concepts || []).map((c: any) => [ + String(c.concept_id), + { + ...c, + concept_id: String(c.concept_id), + }, + ]), + ).values(), ); + const selectConcept = (conceptId: string) => { + const existing = searchParams.getAll("conceptId"); + + const nextConceptIds = existing.includes(conceptId) + ? existing.filter((id) => id !== conceptId) + : [...existing, conceptId]; + + const query = buildSearchParams({ + conceptIds: nextConceptIds, + domain: searchParams.get("domain"), + page: 1, + }); + + router.push(`${pathname}?${query}`); + router.refresh(); + }; + return ( - {article.articleUrl && pmcid ? ( -

{article.title}

+ {article?.articleUrl && pmcid ? ( + + {article.title} + ) : (

Loading article...

)} @@ -43,13 +82,14 @@ export default function NoteCard({ {article ? ( - + - + {article.description} @@ -61,20 +101,44 @@ export default function NoteCard({
- {uniqueConcepts.map((c: Concept) => ( - - {c.name} - - ))} + {uniqueConcepts.map((c: Concept) => { + const selected = selectedConceptIds.includes(String(c.concept_id)); + + return ( + selectConcept(String(c.concept_id))} + className={` + cursor-pointer transition hover:opacity-80 + flex flex-wrap gap-2 py-0 text-sm + ${selected ? "ring-2 ring-primary" : ""} + ${ + c.domain === "Condition" + ? "bg-sky-100 dark:bg-[#1B3C53]" + : "" + } + ${ + c.domain === "Drug" + ? "bg-emerald-100 dark:bg-[#3F4F44]" + : "" + } + ${ + c.domain === "Procedure" + ? "bg-violet-100 dark:bg-[#49243E]" + : "" + } + ${ + c.domain === "Measurement" + ? "bg-orange-100 dark:bg-amber-800" + : "" + } + `} + > + {c.name} + + ); + })}
diff --git a/lib/helpers.ts b/lib/helpers.ts new file mode 100644 index 0000000..f963913 --- /dev/null +++ b/lib/helpers.ts @@ -0,0 +1,26 @@ +export function buildSearchParams({ + conceptIds = [], + domain, + page = 1, +}: { + conceptIds?: string[]; + domain?: string | null; + page?: number; +}) { + const params = new URLSearchParams(); + + // Set domain + if (domain && domain !== "All") { + params.set("domain", domain); + } + + // Sort and add unique conceptIds + [...new Set(conceptIds)] + .sort((a, b) => Number(a) - Number(b)) + .forEach((id) => params.append("conceptId", id)); + + // Set page + params.set("page", String(page)); + + return params.toString(); +} \ No newline at end of file