@@ -3,7 +3,7 @@ import { AnimatePresence, motion } from 'framer-motion'
33import { startCase } from 'lodash'
44import { useSearchParams } from 'next/navigation'
55import { useRouter } from 'next/router'
6- import { useEffect , useState } from 'react'
6+ import { useEffect , useRef , useState } from 'react'
77import { useKey } from 'react-use'
88import type PostTypes from '~/types/post'
99
@@ -13,9 +13,10 @@ import {
1313 DropdownMenuContent ,
1414 DropdownMenuItem ,
1515 DropdownMenuTrigger ,
16+ Input ,
1617 cn ,
1718} from 'ui'
18- import { ChevronDown } from 'lucide-react'
19+ import { ChevronDown , Search , X as CloseIcon } from 'lucide-react'
1920
2021interface Props {
2122 allEvents : PostTypes [ ]
@@ -30,6 +31,7 @@ interface Props {
3031 */
3132
3233function EventFilters ( { allEvents, setEvents, categories } : Props ) {
34+ const inputRef = useRef < HTMLInputElement > ( null )
3335 const [ category , setCategory ] = useState < string > ( 'all' )
3436 const [ searchTerm , setSearchTerm ] = useState < string > ( '' )
3537 const [ showSearchInput , setShowSearchInput ] = useState < boolean > ( false )
@@ -41,6 +43,11 @@ function EventFilters({ allEvents, setEvents, categories }: Props) {
4143 const isMobile = useBreakpoint ( 1023 )
4244 const is2XL = useBreakpoint ( 1535 )
4345
46+ const handleSearchChange = ( event : any ) => {
47+ activeCategory && setCategory ( 'all' )
48+ handleSearchByText ( event . target . value )
49+ }
50+
4451 useEffect ( ( ) => {
4552 if ( ! q ) {
4653 handlePosts ( )
@@ -117,6 +124,13 @@ function EventFilters({ allEvents, setEvents, categories }: Props) {
117124 } )
118125 }
119126
127+ useEffect ( ( ) => {
128+ if ( ! inputRef . current ) return
129+ if ( showSearchInput && isMobile ) {
130+ inputRef . current ?. focus ( )
131+ }
132+ } , [ showSearchInput , isMobile ] )
133+
120134 return (
121135 < div className = "flex flex-row items-center justify-between gap-2" >
122136 < AnimatePresence mode = "wait" >
@@ -195,6 +209,58 @@ function EventFilters({ allEvents, setEvents, categories }: Props) {
195209 ) ) }
196210 </ div >
197211 </ AnimatePresence >
212+ { ! showSearchInput && (
213+ < motion . div
214+ className = "flex-1 flex justify-end"
215+ initial = { { opacity : 0 } }
216+ animate = { { opacity : 1 } }
217+ exit = { { opacity : 0 , transition : { duration : 0.05 } } }
218+ >
219+ < Button
220+ className = "px-2 w-9 h-9"
221+ size = "large"
222+ type = "default"
223+ onClick = { ( ) => setShowSearchInput ( true ) }
224+ >
225+ < Search size = "14" />
226+ </ Button >
227+ </ motion . div >
228+ ) }
229+ { showSearchInput && (
230+ < motion . div
231+ initial = { { opacity : 0 } }
232+ animate = { { opacity : 1 } }
233+ exit = { { opacity : 0 , transition : { duration : 0.05 } } }
234+ className = "w-full h-[38px] flex justify-end gap-2 items-stretch lg:max-w-[240px] xl:max-w-[280px]"
235+ >
236+ < Input
237+ inputRef = { inputRef }
238+ icon = { < Search size = "14" /> }
239+ size = "small"
240+ layout = "vertical"
241+ autoComplete = "off"
242+ type = "search"
243+ placeholder = "Search event"
244+ value = { searchTerm }
245+ onChange = { handleSearchChange }
246+ className = "w-full"
247+ actions = {
248+ isMobile && (
249+ < Button
250+ type = "link"
251+ onClick = { ( ) => {
252+ setSearchTerm ( '' )
253+ setShowSearchInput ( false )
254+ } }
255+ className = "text-foreground-light hover:text-foreground bg-control/100 hover:bg-selection"
256+ >
257+ < CloseIcon size = "14" />
258+ </ Button >
259+ )
260+ }
261+ />
262+ </ motion . div >
263+ ) }
198264 </ div >
199265 )
200266}
0 commit comments