@@ -3,18 +3,54 @@ import { ArrowDownIcon, SearchIcon } from '@/assets/icons'
3
3
import Button from '@/components/Button'
4
4
import Input from '@/components/Input'
5
5
import { Context } from '@/context/context'
6
+ import debounce from '@/hooks/debounce'
7
+ import { instance } from '@/hooks/instance'
8
+ import { CategoryType } from '@/types/HeaderType'
6
9
import { useTranslations } from 'next-intl'
7
- import React , { FC , useContext } from 'react'
10
+ import React , { FC , useContext , useEffect , useState } from 'react'
8
11
9
12
const HeaderSearch :FC < { isMobile ?:boolean } > = ( { isMobile} ) => {
10
13
const t = useTranslations ( "HeaderCenterContent" )
11
14
const { setOpenCategory, openCategory} = useContext ( Context )
12
- return (
15
+
16
+ const [ isLoading , setIsLoading ] = useState < boolean > ( false )
17
+ const [ searchValue , setSearchValue ] = useState < string > ( "empty" )
18
+ const [ value , setValue ] = useState < string > ( "" )
19
+ const [ categorySearchData , setCategorySearchData ] = useState < CategoryType [ ] > ( [ ] )
20
+ const name = debounce ( searchValue , 800 )
21
+
22
+ function handleSearch ( text :string ) {
23
+ setIsLoading ( true )
24
+ setValue ( text )
25
+ if ( text ) {
26
+ setSearchValue ( text )
27
+ }
28
+ else {
29
+ setIsLoading ( false )
30
+ setSearchValue ( "empty" )
31
+ }
32
+ }
33
+
34
+ useEffect ( ( ) => {
35
+ instance ( ) . get ( "/categories/search" , { params :{ name} } ) . then ( res => {
36
+ setIsLoading ( false )
37
+ setCategorySearchData ( res . data )
38
+ } )
39
+ } , [ name ] )
40
+
41
+ function handleSearchClick ( data :string ) {
42
+ setValue ( data )
43
+ setSearchValue ( "empty" )
44
+ }
45
+ return (
13
46
< div className = { `flex gap-[5px] sm:gap-[10px] ${ isMobile ? "hidden-searchbar" :"" } ` } >
14
- < Button onBlur = { ( ) => setOpenCategory ( false ) } onClick = { ( ) => setOpenCategory ( ! openCategory ) } extraClass = '!w-[35%] !h-[40px] sm:!w-[160px] sm:!h-[47px]' icon = { < ArrowDownIcon extrClass = { `${ openCategory && "rotate-[180deg]" } ` } /> } iconPosition = { "right" } > { t ( "category" ) } </ Button >
47
+ < Button onClick = { ( ) => setOpenCategory ( ! openCategory ) } extraClass = '!w-[35%] !h-[40px] sm:!w-[160px] sm:!h-[47px]' icon = { < ArrowDownIcon extrClass = { `${ openCategory && "rotate-[180deg]" } ` } /> } iconPosition = { "right" } > { t ( "category" ) } </ Button >
15
48
< div className = { `relative ${ ! isMobile && "w-[65%] sm:w-full" } ` } >
16
- < Input extraClass = { `${ ! isMobile && "!w-full" } ` } placeholder = { t ( "inputPlaceholder" ) } type = 'text' name = 'search' />
49
+ < Input value = { value } onChange = { ( e ) => handleSearch ( e . target . value ) } extraClass = { `${ ! isMobile && "!w-full" } ` } placeholder = { t ( "inputPlaceholder" ) } type = 'text' name = 'search' />
17
50
< Button extraClass = '!absolute top-0 right-0 !w-[40px] !h-[40px] sm:!h-[48px] sm:!w-[60px] !p-0' > < SearchIcon extraClass = 'w-[16px] h-[16px] sm:w-[20px] sm:h-[20px]' /> </ Button >
51
+ < ul className = { `absolute ${ categorySearchData . length > 0 || isLoading ? "" : "h-0 opacity-0" } duration-300 overflow-hidden z-50 w-full sm:w-[60%] py-[20px] shadow-lg shadow-slate-400 bg-white rounded-md` } >
52
+ { isLoading ? < li className = 'pl-[20px] sm:pl-[40px] text-[13px] sm:text-[16px]' > Loading...</ li > : categorySearchData . map ( ( item :CategoryType ) => < li className = 'pl-[20px] sm:pl-[40px] py-[8px] sm:py-[14px] border-b-[1px] border-slate-300 hover:bg-[#134E9B] hover:text-white text-[13px] sm:text-[16px] duration-300 cursor-pointer' onClick = { ( ) => handleSearchClick ( item . name ) } key = { item . id } > { item . name } </ li > ) }
53
+ </ ul >
18
54
</ div >
19
55
</ div >
20
56
)
0 commit comments