From edb78f0e2fd5c329cd8f46ed22d20f570c284a7e Mon Sep 17 00:00:00 2001 From: ankitkr104 Date: Fri, 27 Mar 2026 12:05:53 +0530 Subject: [PATCH 1/3] feat: add real-time project search and filtering functionality --- src/app/projects/page.jsx | 63 ++++++++++++++++++++++++++++++++++----- 1 file changed, 56 insertions(+), 7 deletions(-) diff --git a/src/app/projects/page.jsx b/src/app/projects/page.jsx index 78d2d5aa..06ab36a0 100644 --- a/src/app/projects/page.jsx +++ b/src/app/projects/page.jsx @@ -1,5 +1,6 @@ 'use client' +import { useState, useMemo } from 'react' import Link from 'next/link' import Grid from '@mui/material/Grid' import MuiCard from '@mui/material/Card' @@ -15,7 +16,8 @@ import projects from '@/helper/projects' import { CardProduct } from '@/components/products/CardProduct' import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' import { faDiscord, faGithub } from '@fortawesome/free-brands-svg-icons' -import { motion } from 'framer-motion' +import { faSearch } from '@fortawesome/free-solid-svg-icons' +import { motion, AnimatePresence } from 'framer-motion' function LinkIcon(props) { return ( @@ -168,6 +170,8 @@ const styles = { } export default function Projects() { + const [searchQuery, setSearchQuery] = useState('') + const readyToDownload = projects.filter( (p) => p.category === 'Ready to download' ) @@ -176,9 +180,20 @@ export default function Projects() { ) const ongoing = projects.filter((p) => p.category === 'Ongoing') - const sortedProjects = [...projects].sort((a, b) => - (a.name || '').localeCompare(b.name || '', undefined, { sensitivity: 'base' }) - ) + const sortedProjects = useMemo(() => { + return [...projects].sort((a, b) => + (a.name || '').localeCompare(b.name || '', undefined, { sensitivity: 'base' }) + ) + }, []) + + const filteredProjects = useMemo(() => { + const query = searchQuery.toLowerCase().trim() + if (!query) return sortedProjects + + return sortedProjects.filter((project) => + (project.name || '').toLowerCase().includes(query) + ) + }, [searchQuery, sortedProjects]) return ( <> @@ -202,12 +217,46 @@ export default function Projects() { Free, open-source, and built by a global community of developers, designers, researchers, and innovators.

+ + {/* Search Bar */} +
+
+
+ +
+ setSearchQuery(e.target.value)} + /> +
+
- {sortedProjects.map((product) => ( - - ))} + + {filteredProjects.map((product) => ( + + + + ))} + + {filteredProjects.length === 0 && ( +
+

+ No projects found matching "{searchQuery}" +

+
+ )}
{/* From 7f2db39defae5b6ccd674d4e84407eaddcad560e Mon Sep 17 00:00:00 2001 From: Ankit kr Date: Fri, 27 Mar 2026 12:25:29 +0530 Subject: [PATCH 2/3] Update page.jsx --- src/app/projects/page.jsx | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/app/projects/page.jsx b/src/app/projects/page.jsx index 06ab36a0..b9a421b0 100644 --- a/src/app/projects/page.jsx +++ b/src/app/projects/page.jsx @@ -221,11 +221,16 @@ export default function Projects() { {/* Search Bar */}
+
+

+ {filteredProjects.length === 0 + ? `No projects found matching ${searchQuery.trim()}.` + : `${filteredProjects.length} project${filteredProjects.length === 1 ? '' : 's'} shown.`} +

From 5bf05a3e3c1b8870cca3a4df847e2da86c86402b Mon Sep 17 00:00:00 2001 From: Ankit kr Date: Fri, 27 Mar 2026 12:26:54 +0530 Subject: [PATCH 3/3] Update page.jsx