@@ -12,6 +12,8 @@ import {
1212  SelectTrigger , 
1313  SelectValue , 
1414}  from  '../ui/select' 
15+ import  {  Label  }  from  '../ui/label' 
16+ import  {  Input  }  from  '../ui/input' 
1517
1618interface  Props  { 
1719  className ?: string 
@@ -23,6 +25,7 @@ const GuideList: React.FC<Props> = ({ className, allGuides }) => {
2325  const  sortBy  =  searchParams ?. get ( 'sort' )  ||  'published_date' 
2426  const  selectedTags  =  searchParams ?. get ( 'tags' ) ?. split ( ',' )  ||  [ ] 
2527  const  selectedLangs  =  searchParams ?. get ( 'langs' ) ?. split ( ',' )  ||  [ ] 
28+   const  query  =  searchParams ?. get ( 'q' )  ||  '' 
2629
2730  const  filteredGuides  =  useMemo ( ( )  =>  { 
2831    return  allGuides 
@@ -35,6 +38,15 @@ const GuideList: React.FC<Props> = ({ className, allGuides }) => {
3538          ) 
3639        } 
3740
41+         if  ( query . trim ( ) )  { 
42+           include  = 
43+             include  && 
44+             ( guide . title . toLowerCase ( ) . includes ( query . toLowerCase ( ) )  || 
45+               ( guide . description  ||  '' ) 
46+                 . toLowerCase ( ) 
47+                 . includes ( query . toLowerCase ( ) ) ) 
48+         } 
49+ 
3850        if  ( ! selectedTags . length )  return  include 
3951
4052        return  include  &&  selectedTags . some ( ( tag )  =>  guide . tags ?. includes ( tag ) ) 
@@ -52,43 +64,66 @@ const GuideList: React.FC<Props> = ({ className, allGuides }) => {
5264          ? b . title . localeCompare ( a . title ) 
5365          : a . title . localeCompare ( b . title ) 
5466      } ) 
55-   } ,  [ allGuides ,  selectedTags ,  selectedLangs ,  sortBy ] ) 
67+   } ,  [ allGuides ,  selectedTags ,  selectedLangs ,  sortBy ,   query ] ) 
5668
57-   return  filteredGuides . length  ===  0  ? ( 
58-     < div  className = { className } > 
59-       < p  className = "text-lg" > 
60-         No guides found. Please try selecting different filters.
61-       </ p > 
62-     </ div > 
63-   )  : ( 
69+   // Handle input change and pass the input value directly 
70+   const  handleChange  =  ( e : React . ChangeEvent < HTMLInputElement > )  =>  { 
71+     setParams ( 'q' ,  e . target . value ) 
72+   } 
73+ 
74+   return  ( 
6475    < div  className = { cn ( 'flex flex-col gap-4' ,  className ) } > 
65-       < Select 
66-         value = { sortBy } 
67-         onValueChange = { ( val )  =>  { 
68-           // This is necessary to fix a ui update delay causing 200ms lag 
69-           setTimeout ( ( )  =>  setParams ( 'sort' ,  val ) ,  0 ) 
70-         } } 
71-       > 
72-         < SelectTrigger 
73-           aria-label = "Sort options" 
74-           className = "ml-auto max-w-52 bg-white/5 text-xs font-medium ring-1 ring-inset ring-zinc-300/10 hover:bg-white/7.5 dark:bg-white/2.5 dark:text-zinc-400 dark:hover:bg-white/5 md:flex" 
76+       < div  className = "flex flex-col items-center justify-between gap-2 sm:flex-row" > 
77+         < div  className = "w-full sm:w-52" > 
78+           < Label  htmlFor = "search-guides"  className = "sr-only" > 
79+             Email
80+           </ Label > 
81+           < Input 
82+             className = "w-full bg-white/5 text-xs font-medium ring-1 ring-inset ring-zinc-300/10 hover:bg-white/7.5 dark:bg-white/2.5 dark:text-zinc-400 dark:hover:bg-white/5" 
83+             type = "search" 
84+             id = "search-guides" 
85+             value = { query } 
86+             onChange = { handleChange } 
87+             placeholder = "Search guides" 
88+           /> 
89+         </ div > 
90+         < Select 
91+           value = { sortBy } 
92+           onValueChange = { ( val )  =>  { 
93+             // This is necessary to fix a ui update delay causing 200ms lag 
94+             setTimeout ( ( )  =>  setParams ( 'sort' ,  val ) ,  0 ) 
95+           } } 
7596        > 
76-           < SelectValue  /> 
77-         </ SelectTrigger > 
78-         < SelectContent  position = "item-aligned" > 
79-           < SelectItem  value = "published_date" > Sort by Date Published</ SelectItem > 
80-           < SelectItem  value = "alpha" > Sort Alphabetically (A-Z)</ SelectItem > 
81-           < SelectItem  value = "alpha-reverse" > 
82-             Sort Alphabetically (Z-A)
83-           </ SelectItem > 
84-         </ SelectContent > 
85-       </ Select > 
97+           < SelectTrigger 
98+             aria-label = "Sort options" 
99+             className = "w-full bg-white/5 text-xs font-medium ring-1 ring-inset ring-zinc-300/10 hover:bg-white/7.5 dark:bg-white/2.5 dark:text-zinc-400 dark:hover:bg-white/5 sm:flex sm:max-w-52" 
100+           > 
101+             < SelectValue  /> 
102+           </ SelectTrigger > 
103+           < SelectContent  position = "item-aligned" > 
104+             < SelectItem  value = "published_date" > 
105+               Sort by Date Published
106+             </ SelectItem > 
107+             < SelectItem  value = "alpha" > Sort Alphabetically (A-Z)</ SelectItem > 
108+             < SelectItem  value = "alpha-reverse" > 
109+               Sort Alphabetically (Z-A)
110+             </ SelectItem > 
111+           </ SelectContent > 
112+         </ Select > 
113+       </ div > 
114+ 
86115      < ul  className = { 'space-y-4' } > 
87-         { filteredGuides . map ( ( guide )   =>  ( 
88-           < li  key = { guide . slug } > 
89-             < GuideItem   guide = { guide }   /> 
116+         { filteredGuides . length   ===   0  ?  ( 
117+           < li  className = "text-lg" > 
118+             No guides found. Please try selecting different filters. 
90119          </ li > 
91-         ) ) } 
120+         )  : ( 
121+           filteredGuides . map ( ( guide )  =>  ( 
122+             < li  key = { guide . slug } > 
123+               < GuideItem  guide = { guide }  /> 
124+             </ li > 
125+           ) ) 
126+         ) } 
92127      </ ul > 
93128    </ div > 
94129  ) 
0 commit comments