@@ -2,7 +2,7 @@ import { db } from "@/database";
22import { users } from "@/schemas" ;
33import ProfileCard from "./ProfileCard" ;
44import Paginations from "../pagination/Paginations" ;
5- import { ilike , or , sql } from "drizzle-orm" ;
5+ import { ilike , sql , SQL } from "drizzle-orm" ;
66import Notfound from "../shared/Notfound" ;
77import Search from "../shared/search/Search" ;
88
@@ -12,61 +12,74 @@ type Props = {
1212} ;
1313
1414const ProfileGrid = async ( { page, searchParams } : Props ) => {
15- const currentPage = parseInt ( page ) ; // like 1
16- const itemPerPage = 5 ; // we want to show 5 item in per pages
17- const offset = ( currentPage - 1 ) * itemPerPage ; // (1 - 1) * 3 = 0
18- const searchSkills = searchParams
19- ? searchParams . toLowerCase ( ) . split ( / [ \s , ] + / )
20- : [ ] ; // regular expression to accept inputs separated by comma, space or both
15+ const currentPage = parseInt ( page , 10 ) || 1 ;
16+ const itemsPerPage = 5 ;
17+ const offset = ( currentPage - 1 ) * itemsPerPage ;
2118
22- // In order to get rid of the "error: operator does not exist: json @> json" I mannually cast the skills column to JSONB
23- const skillsCondition =
24- searchSkills . length > 0
25- ? sql . raw (
26- `lower("skills"::text)::JSONB @> '${ JSON . stringify ( searchSkills . map ( ( skill ) => skill . toLowerCase ( ) ) ) } '::JSONB` ,
19+ const whereConditions : SQL [ ] = [ ] ;
20+
21+ const searchQuery = searchParams ?. trim ( ) . toLowerCase ( ) || "" ;
22+ const searchTokens = searchQuery ? searchQuery . split ( / [ \s , ] + / ) : [ ] ;
23+
24+ // Text field search
25+ if ( searchQuery ) {
26+ whereConditions . push (
27+ ilike ( users . name , `%${ searchQuery } %` ) ,
28+ ilike ( users . location , `%${ searchQuery } %` ) ,
29+ ilike ( users . description , `%${ searchQuery } %` )
30+ ) ;
31+
32+ const skillConditions = searchTokens
33+ . map ( ( token ) => `skill ILIKE '%${ token } %'` )
34+ . join ( " OR " ) ;
35+
36+ if ( skillConditions ) {
37+ whereConditions . push (
38+ sql . raw ( `
39+ EXISTS (
40+ SELECT 1 FROM json_array_elements_text("skills") AS skill
41+ WHERE ${ skillConditions }
2742 )
28- : undefined ;
43+ ` )
44+ ) ;
45+ }
46+ }
47+
48+ const whereClause = whereConditions . length
49+ ? sql `(${ sql . join ( whereConditions , sql ` OR ` ) } )`
50+ : undefined ;
2951
30- const [ lengths , profiles ] = await Promise . all ( [
31- db . select ( { count : sql < number > `count(*)` } ) . from ( users ) ,
32- searchParams
33- ? db
34- . select ( )
35- . from ( users )
36- . where (
37- or (
38- ilike ( users . name , `%${ searchParams } %` ) ,
39- ilike ( users . location , `%${ searchParams } %` ) ,
40- ilike ( users . description , `%${ searchParams } %` ) ,
41- skillsCondition ,
42- ) ,
43- )
44- . limit ( itemPerPage )
45- . offset ( offset )
46- : db
47- . select ( )
48- . from ( users )
49- . orderBy ( sql . raw ( "RANDOM()" ) )
50- . limit ( itemPerPage )
51- . offset ( offset ) ,
52+ const [ countResult , profiles ] = await Promise . all ( [
53+ db
54+ . select ( { count : sql < number > `count(*)` } )
55+ . from ( users )
56+ . where ( whereClause ) ,
57+ db
58+ . select ( )
59+ . from ( users )
60+ . where ( whereClause )
61+ . orderBy ( sql . raw ( "RANDOM()" ) )
62+ . limit ( itemsPerPage )
63+ . offset ( offset ) ,
5264 ] ) ;
5365
54- const count = lengths [ 0 ] . count ;
66+ const count = countResult [ 0 ] ?. count ?? 0 ;
67+
5568 return (
5669 < div className = "lg:mt-32 mt-[10rem] mb-8 border-t-orange-500 lg:ml-[20rem] px-4 lg:px-6 relative" >
5770 < Search />
5871 < div className = "flex-center flex-col gap-3" >
59- { count <= 0 || profiles . length === 0 ? (
60- < Notfound />
61- ) : (
72+ { profiles . length ? (
6273 profiles . map ( ( profile , i ) => (
6374 < ProfileCard key = { i } profile = { profile } />
6475 ) )
76+ ) : (
77+ < Notfound />
6578 ) }
6679 </ div >
6780 < Paginations
68- hasNextPage = { currentPage < Math . ceil ( count / itemPerPage ) }
69- hasPrevPage = { currentPage !== 1 }
81+ hasNextPage = { currentPage < Math . ceil ( count / itemsPerPage ) }
82+ hasPrevPage = { currentPage > 1 }
7083 search = { searchParams }
7184 />
7285 </ div >
0 commit comments