From b45c7e7330e4acecb7e6563b710897757f4f5489 Mon Sep 17 00:00:00 2001 From: vasiliki Date: Mon, 1 Jun 2026 16:40:37 +0100 Subject: [PATCH] change URL to ids pattern to fix stale UI issue --- app/page.tsx | 42 ++++++++++------------------- components/ConceptList.tsx | 26 +++++++----------- components/DomainSelect.tsx | 18 +++++++++---- components/NoteCard.tsx | 48 +++++++++------------------------- components/NotesList.tsx | 26 +++++++++--------- components/NotesPagination.tsx | 13 ++++----- lib/helpers.ts | 14 +++++----- 7 files changed, 73 insertions(+), 114 deletions(-) diff --git a/app/page.tsx b/app/page.tsx index e4b5042..703830d 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -1,41 +1,28 @@ -import { Suspense } from "react"; -import { use } from "react"; import ConceptsSection from "@/components/ConceptsSection"; import NotesSection from "@/components/NotesSection"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import DomainSelect from "@/components/DomainSelect"; import { ModeToggle } from "@/components/mode-toggle"; -export default function Page(props: { - searchParams: Promise<{ - conceptId?: string; - domain?: string; - }>; -}) { - return ( - Loading page...}> - - - ); -} - -function PageContent({ +export default async function Page({ searchParams, }: { searchParams: Promise<{ - conceptId?: string | string[]; + ids?: string | string[]; domain?: string; page?: string; }>; }) { - const params = use(searchParams); + const params = await searchParams; + + const ids = + typeof params.ids === "string" ? params.ids.split(",").filter(Boolean) : []; + + const domain = + typeof params.domain === "string" && params.domain.length > 0 + ? params.domain + : "All"; - const conceptIds = Array.isArray(params.conceptId) - ? params.conceptId - : params.conceptId - ? [params.conceptId] - : []; - const domain = params.domain ?? "All"; const page = Math.max(1, parseInt(params.page ?? "1", 10) || 1); return (
@@ -64,12 +51,11 @@ function PageContent({
- + - - - + +
diff --git a/components/ConceptList.tsx b/components/ConceptList.tsx index f428d92..025e735 100644 --- a/components/ConceptList.tsx +++ b/components/ConceptList.tsx @@ -1,52 +1,44 @@ "use client"; + import { usePathname, useRouter, useSearchParams } from "next/navigation"; import type { Concept } from "@/types/OmopTables"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { Button } from "@/components/ui/button"; import { ScrollArea, ScrollBar } from "@/components/ui/scroll-area"; import { buildSearchParams } from "@/lib/helpers"; -import { useEffect, useState } from "react"; export default function ConceptList({ concepts }: { concepts: Concept[] }) { const router = useRouter(); const pathname = usePathname(); const searchParams = useSearchParams(); - const selectedConcepts = searchParams.getAll("conceptId") - const [loading, setLoading] = useState(false); + const selectedConcepts = + searchParams.get("ids")?.split(",").filter(Boolean) ?? []; const onSelect = (conceptId: string) => { - if (loading) return; - - setLoading(true); - - const current = searchParams.getAll("conceptId"); + const current = selectedConcepts; const nextConceptIds = current.includes(conceptId) ? current.filter((id) => id !== conceptId) : [...current, conceptId]; const query = buildSearchParams({ - conceptIds: nextConceptIds, + ids: nextConceptIds, domain: searchParams.get("domain"), page: 1, }); - router.replace(`${pathname}?${query}`, { + router.push(`${pathname}?${query}`, { scroll: false, }); - }; - useEffect(() => { - setLoading(false); -}, [searchParams]); + const clearSelection = () => { const query = buildSearchParams({ - conceptIds: [], + ids: [], domain: searchParams.get("domain"), page: 1, }); - - router.replace(`${pathname}?${query}`, { scroll: false }); + router.push(`${pathname}?${query}`, { scroll: false }); }; return ( diff --git a/components/DomainSelect.tsx b/components/DomainSelect.tsx index a9f1a85..bc11632 100644 --- a/components/DomainSelect.tsx +++ b/components/DomainSelect.tsx @@ -14,22 +14,30 @@ export default function DomainSelect({ domain }: { domain: string }) { const pathname = usePathname(); function handleChange(domain: string) { - const params = new URLSearchParams(); + const params = new URLSearchParams(searchParams.toString()); - // Keep domain if exists + // Keep domain if it's not "All" if (domain && domain !== "All") { params.set("domain", domain); + } else { + params.delete("domain"); } // Keep selected concepts - const conceptIds = searchParams.getAll("conceptId") - conceptIds.forEach((id) => params.append("conceptId", id)); + const ids = searchParams.get("ids")?.split(",").filter(Boolean) ?? []; + + if (ids.length > 0) { + params.set("ids", ids.join(",")); + } // Reset page number params.set("page", "1"); - router.replace(`${pathname}?${params.toString()}`, { scroll: false }); + router.push(`${pathname}?${params.toString()}`, { + scroll: false, + }); } + return (