17 |
}; |
}; |
18 |
|
|
19 |
export default function SearchModal({ onClose }: SearchModalProps) { |
export default function SearchModal({ onClose }: SearchModalProps) { |
20 |
const [query, isQueued, setQuery] = useDebouncedState<string | null>( |
const [query, , setQuery] = useDebouncedState<string | null>(null, 500); |
|
null, |
|
|
500, |
|
|
); |
|
21 |
const [results, setResults] = useState<SearchResultItem[] | null>(null); |
const [results, setResults] = useState<SearchResultItem[] | null>(null); |
22 |
const [isLoading, setIsLoading] = useState(false); |
const [isLoading, setIsLoading] = useState(false); |
23 |
const [isNotFound, setIsNotFound] = useState(false); |
const [isNotFound, setIsNotFound] = useState(false); |
29 |
|
|
30 |
const controller = new AbortController(); |
const controller = new AbortController(); |
31 |
|
|
32 |
if (!isLoading) { |
setIsLoading(true); |
|
setIsLoading(true); |
|
|
} |
|
33 |
|
|
34 |
fetch(`/search?q=${encodeURIComponent(query)}`, { |
fetch(`/search?q=${encodeURIComponent(query)}`, { |
35 |
signal: controller.signal, |
signal: controller.signal, |
36 |
}) |
}) |
37 |
.then(response => response.json()) |
.then(response => response.json()) |
38 |
.then(data => { |
.then(data => { |
39 |
if (isNotFound) { |
setIsNotFound(false); |
|
setIsNotFound(false); |
|
|
} |
|
|
|
|
40 |
setIsLoading(false); |
setIsLoading(false); |
41 |
setResults(data.results); |
setResults(data.results); |
42 |
|
setIsNotFound(data.results.length === 0); |
|
if (data.results.length === 0) { |
|
|
setIsNotFound(true); |
|
|
} |
|
43 |
}) |
}) |
44 |
.catch(console.error); |
.catch(console.error); |
45 |
|
|