From 335ff4f061bb3a85b98471255c9238f21ae0fd85 Mon Sep 17 00:00:00 2001 From: ash1shkumar Date: Sat, 6 Jun 2026 00:42:48 +0530 Subject: [PATCH] perf: optimize project search filtering workflow --- frontend/app/projects/page.tsx | 58 ++++++++++++++++++++++++---------- 1 file changed, 41 insertions(+), 17 deletions(-) diff --git a/frontend/app/projects/page.tsx b/frontend/app/projects/page.tsx index b06e61f..7f37b3f 100644 --- a/frontend/app/projects/page.tsx +++ b/frontend/app/projects/page.tsx @@ -17,6 +17,26 @@ type Project = { createdAt: string; }; +function filterProjects( + projects: Array< + Project & { searchText?: string } + >, + query: string +) { + const normalizedQuery = + query.trim().toLowerCase(); + + if (!normalizedQuery) { + return projects; + } + + return projects.filter((project) => + project.searchText?.includes( + normalizedQuery + ) + ); +} + export default function ProjectsPage() { const router = useRouter(); const [searchTerm, setSearchTerm] = useState(""); @@ -79,25 +99,29 @@ export default function ProjectsPage() { return () => subscription.unsubscribe(); }, []); - const filteredProjects = useMemo(() => { - const query = debouncedSearchTerm.trim().toLowerCase(); - - if (!query) { - return projects; - } - return projects.filter((project) => { - const projectName = (project.name || "").toLowerCase(); + const searchableProjects = useMemo( + () => + projects.map((project) => ({ + ...project, + searchText: [ + project.name, + ...(project.tags || []), + ] + .join(" ") + .toLowerCase(), + })), + [projects] + ); - return ( - projectName.includes(query) || - (project.tags && - project.tags.some((tag: string) => - tag.toLowerCase().includes(query) - )) - ); - }); - }, [projects, debouncedSearchTerm]); + const filteredProjects = useMemo( + () => + filterProjects( + searchableProjects, + debouncedSearchTerm + ), + [searchableProjects, debouncedSearchTerm] + ); const hasProjects = filteredProjects.length > 0;