From d4311b8e0075d61d8d4cbf9403510f4887164868 Mon Sep 17 00:00:00 2001 From: devlopersabbir Date: Tue, 5 Aug 2025 03:34:08 +0600 Subject: [PATCH] =?UTF-8?q?[fix=20=F0=9F=90=B1=E2=80=8D=F0=9F=91=A4]=20fix?= =?UTF-8?q?ed=20filtering/search=20issues=20=F0=9F=91=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/layout.tsx | 4 +- src/components/contents/ProfileGrid.tsx | 95 +++++++++++++---------- src/components/shared/sidebar/Sidebar.tsx | 1 + 3 files changed, 57 insertions(+), 43 deletions(-) diff --git a/src/app/layout.tsx b/src/app/layout.tsx index 1245925..735385b 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -28,12 +28,12 @@ export default function RootLayout({ children: React.ReactNode; }) { return ( - + { - const currentPage = parseInt(page); // like 1 - const itemPerPage = 5; // we want to show 5 item in per pages - const offset = (currentPage - 1) * itemPerPage; // (1 - 1) * 3 = 0 - const searchSkills = searchParams - ? searchParams.toLowerCase().split(/[\s,]+/) - : []; // regular expression to accept inputs separated by comma, space or both + const currentPage = parseInt(page, 10) || 1; + const itemsPerPage = 5; + const offset = (currentPage - 1) * itemsPerPage; - // In order to get rid of the "error: operator does not exist: json @> json" I mannually cast the skills column to JSONB - const skillsCondition = - searchSkills.length > 0 - ? sql.raw( - `lower("skills"::text)::JSONB @> '${JSON.stringify(searchSkills.map((skill) => skill.toLowerCase()))}'::JSONB`, + const whereConditions: SQL[] = []; + + const searchQuery = searchParams?.trim().toLowerCase() || ""; + const searchTokens = searchQuery ? searchQuery.split(/[\s,]+/) : []; + + // Text field search + if (searchQuery) { + whereConditions.push( + ilike(users.name, `%${searchQuery}%`), + ilike(users.location, `%${searchQuery}%`), + ilike(users.description, `%${searchQuery}%`) + ); + + const skillConditions = searchTokens + .map((token) => `skill ILIKE '%${token}%'`) + .join(" OR "); + + if (skillConditions) { + whereConditions.push( + sql.raw(` + EXISTS ( + SELECT 1 FROM json_array_elements_text("skills") AS skill + WHERE ${skillConditions} ) - : undefined; + `) + ); + } + } + + const whereClause = whereConditions.length + ? sql`(${sql.join(whereConditions, sql` OR `)})` + : undefined; - const [lengths, profiles] = await Promise.all([ - db.select({ count: sql`count(*)` }).from(users), - searchParams - ? db - .select() - .from(users) - .where( - or( - ilike(users.name, `%${searchParams}%`), - ilike(users.location, `%${searchParams}%`), - ilike(users.description, `%${searchParams}%`), - skillsCondition, - ), - ) - .limit(itemPerPage) - .offset(offset) - : db - .select() - .from(users) - .orderBy(sql.raw("RANDOM()")) - .limit(itemPerPage) - .offset(offset), + const [countResult, profiles] = await Promise.all([ + db + .select({ count: sql`count(*)` }) + .from(users) + .where(whereClause), + db + .select() + .from(users) + .where(whereClause) + .orderBy(sql.raw("RANDOM()")) + .limit(itemsPerPage) + .offset(offset), ]); - const count = lengths[0].count; + const count = countResult[0]?.count ?? 0; + return (
- {count <= 0 || profiles.length === 0 ? ( - - ) : ( + {profiles.length ? ( profiles.map((profile, i) => ( )) + ) : ( + )}
1} search={searchParams} />
diff --git a/src/components/shared/sidebar/Sidebar.tsx b/src/components/shared/sidebar/Sidebar.tsx index ad33676..d740105 100644 --- a/src/components/shared/sidebar/Sidebar.tsx +++ b/src/components/shared/sidebar/Sidebar.tsx @@ -32,6 +32,7 @@ const Sidebar = () => { alt="donate button" width={130} height={80} + objectFit="cover" />