From 4403976e141fa7780de0ff6a25dc8e5015b59b47 Mon Sep 17 00:00:00 2001 From: Shalini Date: Sat, 21 Feb 2026 15:03:39 +0530 Subject: [PATCH 1/2] feat: add search functionality for events with URL-based filtering and debounce (closes #163) --- src/app/[locale]/events/page.tsx | 23 +++++++++++++++++++---- src/components/common/navbar/index.tsx | 22 ++++++++++++++++++++++ 2 files changed, 41 insertions(+), 4 deletions(-) diff --git a/src/app/[locale]/events/page.tsx b/src/app/[locale]/events/page.tsx index 08a1561..0ee0d9b 100644 --- a/src/app/[locale]/events/page.tsx +++ b/src/app/[locale]/events/page.tsx @@ -46,15 +46,24 @@ export async function generateMetadata({ }; } -export default function EventsPage() { +export default function EventsPage({ searchParams }: { searchParams: { search?: string } }) { const t = useTranslations("Events"); + const searchQuery = searchParams?.search?.toLowerCase() || ""; - const upcomingEvents = events.filter((event) => { + const filteredEvents = events.filter((event) => { + const matchesSearch = + event.title.toLowerCase().includes(searchQuery) || + event.description?.toLowerCase().includes(searchQuery); + + return matchesSearch; + }); + + const upcomingEvents = filteredEvents.filter((event) => { const status = getEventStatus(event.startDateTime, event.endDateTime); return status === EVENT_STATUS.UPCOMING || status === EVENT_STATUS.ONGOING; }); - const pastEvents = events.filter((event) => { + const pastEvents = filteredEvents.filter((event) => { const status = getEventStatus(event.startDateTime, event.endDateTime); return status === EVENT_STATUS.PAST; }); @@ -147,7 +156,13 @@ export default function EventsPage() { {upcomingEvents.length === 0 && pastEvents.length === 0 && (
-

No events found.

+ {searchQuery ? ( +

+ No results found for "{searchQuery}" +

+ ) : ( +

No events found.

+ )}
)} diff --git a/src/components/common/navbar/index.tsx b/src/components/common/navbar/index.tsx index 3d88696..80d3c91 100644 --- a/src/components/common/navbar/index.tsx +++ b/src/components/common/navbar/index.tsx @@ -20,6 +20,18 @@ import { XLogo } from "../icons/XLogo"; const Navbar = () => { const [scrolled, setScrolled] = useState(false); const [open, setOpen] = useState(false); + const [searchQuery, setSearchQuery] = useState(""); + + useEffect(() => { + const delayDebounce = setTimeout(() => { + if (pathname.includes("/events")) { + router.push(`/events?search=${searchQuery}`); + } + }, 400); + + return () => clearTimeout(delayDebounce); + }, [searchQuery]); + const [hoveredIcon, setHoveredIcon] = useState(null); // State for the icon hover const [activeSection, setActiveSection] = useState(false); @@ -127,6 +139,16 @@ const Navbar = () => { })} +
+ setSearchQuery(e.target.value)} + className="rounded-md border border-slate-600 bg-slate-800 px-3 py-1 text-sm text-white outline-none focus:border-sky-400" + /> +
+
    Date: Mon, 23 Feb 2026 18:05:51 +0530 Subject: [PATCH 2/2] feat(events): add refined loading skeleton for events page --- src/app/[locale]/events/loading.tsx | 43 +++++++++++++++++++++++++++++ src/app/[locale]/events/page.tsx | 2 +- 2 files changed, 44 insertions(+), 1 deletion(-) create mode 100644 src/app/[locale]/events/loading.tsx diff --git a/src/app/[locale]/events/loading.tsx b/src/app/[locale]/events/loading.tsx new file mode 100644 index 0000000..7c1bdd3 --- /dev/null +++ b/src/app/[locale]/events/loading.tsx @@ -0,0 +1,43 @@ +function CardSkeleton({ className = "" }: { className?: string }) { + return ( +
    +
    +
    +
    +
    +
    +
    +
    + ); +} + +export default function EventsLoading() { + return ( +
    + {/* Title Skeleton */} +
    +
    +
    +
    + + {/* Featured Section */} +
    +
    + +
    + +
    + + +
    +
    + + {/* Grid Section */} +
    + {Array.from({ length: 3 }).map((_, i) => ( + + ))} +
    +
    + ); +} diff --git a/src/app/[locale]/events/page.tsx b/src/app/[locale]/events/page.tsx index 0ee0d9b..393e4e2 100644 --- a/src/app/[locale]/events/page.tsx +++ b/src/app/[locale]/events/page.tsx @@ -46,7 +46,7 @@ export async function generateMetadata({ }; } -export default function EventsPage({ searchParams }: { searchParams: { search?: string } }) { +export default async function EventsPage({ searchParams }: { searchParams: { search?: string } }) { const t = useTranslations("Events"); const searchQuery = searchParams?.search?.toLowerCase() || "";