3
3
import { useState , useCallback , useRef , useEffect } from "react" ;
4
4
import axios , { AxiosError } from "axios" ;
5
5
import { Search } from "lucide-react" ;
6
- import debounce from ' debounce' ;
7
- import { useRouter } from "next/navigation" ;
6
+ import debounce from " debounce" ;
7
+ import { useRouter } from "next/navigation" ;
8
8
import { Input } from "@/components/ui/input" ;
9
9
10
- function SearchBar ( ) {
11
- const router = useRouter ( ) ;
10
+ function SearchBar ( ) {
11
+ const router = useRouter ( ) ;
12
12
const [ searchText , setSearchText ] = useState ( "" ) ;
13
13
const [ suggestions , setSuggestions ] = useState < string [ ] > ( [ ] ) ;
14
14
const [ error , setError ] = useState < string | null > ( null ) ;
@@ -25,12 +25,15 @@ function SearchBar () {
25
25
} ) ;
26
26
27
27
const { subjects } = searchResponse . data ;
28
- const suggestionList = subjects . map ( ( subjectObj : { subject : string } ) => subjectObj . subject ) ;
28
+ const suggestionList = subjects . map (
29
+ ( subjectObj : { subject : string } ) => subjectObj . subject ,
30
+ ) ;
29
31
setSuggestions ( suggestionList ) ;
30
32
setError ( null ) ;
31
33
} catch ( error ) {
32
34
const typedError = error as AxiosError < { message ?: string } > ;
33
- const errorMessage = typedError . response ?. data ?. message ?? "Error fetching suggestions" ;
35
+ const errorMessage =
36
+ typedError . response ?. data ?. message ?? "Error fetching suggestions" ;
34
37
setError ( errorMessage ) ;
35
38
} finally {
36
39
setLoading ( false ) ;
@@ -39,7 +42,7 @@ function SearchBar () {
39
42
setSuggestions ( [ ] ) ;
40
43
}
41
44
} , 500 ) ,
42
- [ ]
45
+ [ ] ,
43
46
) ;
44
47
45
48
const handleSearchChange = ( e : React . ChangeEvent < HTMLInputElement > ) => {
@@ -48,7 +51,7 @@ function SearchBar () {
48
51
if ( text . length <= 1 ) {
49
52
setSuggestions ( [ ] ) ;
50
53
}
51
- debouncedSearch ( text ) ;
54
+ debouncedSearch ( text ) ;
52
55
} ;
53
56
54
57
const handleSelectSuggestion = async ( suggestion : string ) => {
@@ -58,7 +61,10 @@ function SearchBar () {
58
61
} ;
59
62
60
63
const handleClickOutside = ( event : MouseEvent ) => {
61
- if ( suggestionsRef . current && ! suggestionsRef . current . contains ( event . target as Node ) ) {
64
+ if (
65
+ suggestionsRef . current &&
66
+ ! suggestionsRef . current . contains ( event . target as Node )
67
+ ) {
62
68
setSuggestions ( [ ] ) ;
63
69
}
64
70
} ;
@@ -75,38 +81,52 @@ function SearchBar () {
75
81
< form className = "w-full max-w-xl" >
76
82
< div className = "relative" >
77
83
< Input
78
- type = "text"
79
- value = { searchText }
84
+ type = "text"
85
+ value = { searchText }
80
86
onChange = { handleSearchChange }
81
- placeholder = "Search..."
82
- className = { `w-full rounded-xl border px-4 py-6 pr-10 bg-[#7480FF] placeholder: text-white text-white opacity-50 shadow-sm focus:outline-none focus:ring-2 ${ loading ? ' opacity-70' : '' } ` }
87
+ placeholder = "Search..."
88
+ className = { `w-full rounded-xl border bg-[#7480FF] px-4 py-6 pr-10 text-white opacity-50 shadow-sm placeholder:text-white focus:outline-none focus:ring-2 ${ loading ? " opacity-70" : "" } ` }
83
89
/>
84
- < button type = "submit" className = "absolute inset-y-0 right-0 flex items-center pr-3" disabled > { /* disabled={loading} */ }
90
+ < button
91
+ type = "submit"
92
+ className = "absolute inset-y-0 right-0 flex items-center pr-3"
93
+ disabled = { loading }
94
+ >
95
+ { " " }
96
+ { /* disabled={loading} replace with disabled */ }
85
97
< Search className = "h-5 w-5 text-white opacity-50" />
86
98
</ button >
87
- { loading && (
88
- < div className = "absolute z-20 w-full max-w-xl border bg-white border-[#7480FF] dark:bg-[#030712] rounded-md mt-2 p-2 text-center" >
89
- Loading suggestions...
90
- </ div >
91
- ) }
92
- { ( suggestions . length > 0 || error ) && ! loading && (
93
- < ul ref = { suggestionsRef } className = "absolute mx-0.5 md:mx-0 w-full text-center max-w-xl z-20 border bg-white border-[#7480FF] dark:bg-[#030712] rounded-md mt-2" >
94
- { error ? (
95
- < li className = "p-2 text-red" > { error } </ li >
96
- ) : (
97
- suggestions . map ( ( suggestion , index ) => (
98
- < li
99
- key = { index }
100
- onClick = { ( ) => handleSelectSuggestion ( suggestion ) }
101
- className = "cursor-pointer p-2 truncate hover:opacity-50"
102
- style = { { width : '100%' , overflow : 'hidden' , whiteSpace : 'nowrap' , textOverflow : 'ellipsis' } }
103
- >
104
- { suggestion }
105
- </ li >
106
- ) )
107
- ) }
108
- </ ul >
109
- ) }
99
+ { loading && (
100
+ < div className = "absolute z-20 mt-2 w-full max-w-xl rounded-md border border-[#7480FF] bg-white p-2 text-center dark:bg-[#030712]" >
101
+ Loading suggestions...
102
+ </ div >
103
+ ) }
104
+ { ( suggestions . length > 0 || error ) && ! loading && (
105
+ < ul
106
+ ref = { suggestionsRef }
107
+ className = "absolute z-20 mx-0.5 mt-2 w-full max-w-xl rounded-md border border-[#7480FF] bg-white text-center dark:bg-[#030712] md:mx-0"
108
+ >
109
+ { error ? (
110
+ < li className = "text-red p-2" > { error } </ li >
111
+ ) : (
112
+ suggestions . map ( ( suggestion , index ) => (
113
+ < li
114
+ key = { index }
115
+ onClick = { ( ) => handleSelectSuggestion ( suggestion ) }
116
+ className = "cursor-pointer truncate p-2 hover:opacity-50"
117
+ style = { {
118
+ width : "100%" ,
119
+ overflow : "hidden" ,
120
+ whiteSpace : "nowrap" ,
121
+ textOverflow : "ellipsis" ,
122
+ } }
123
+ >
124
+ { suggestion }
125
+ </ li >
126
+ ) )
127
+ ) }
128
+ </ ul >
129
+ ) }
110
130
</ div >
111
131
</ form >
112
132
</ div >
0 commit comments