1+ import { Heading , Paragraph } from "@datacamp/waffles-text" ;
2+ import router from "next/router" ;
3+ import { useEffect , useState } from "react" ;
4+ import { API_URL } from "../lib/utils" ;
5+
6+ type Props = {
7+ searchInput : string
8+ } ;
9+
10+ export default function AutoComplete ( { searchInput } : Props ) {
11+
12+ const [ packageSuggestions , setPackageSuggestions ] = useState ( [ ] ) ;
13+ const [ topicSuggestions , setTopicSuggestions ] = useState ( [ ] ) ;
14+
15+ function onClick ( query ) {
16+ router . push ( `/search?q=${ encodeURIComponent ( query ) } ` ) ;
17+ } ;
18+
19+ async function autoComplete ( query ) {
20+ try {
21+ // fetch the data
22+ const [ resPackages , resTopics ] = await Promise . all ( [
23+ fetch (
24+ `${ API_URL } /search_packages?q=${ query } &page=1&latest=1` ,
25+ {
26+ headers : {
27+ Accept : 'application/json' ,
28+ } ,
29+ } ,
30+ ) ,
31+ fetch (
32+ `${ API_URL } /search_functions?q=${ query } &page=1&latest=1` ,
33+ {
34+ headers : {
35+ Accept : 'application/json' ,
36+ } ,
37+ } ,
38+ )
39+ ] ) ;
40+
41+ const { packages } = await resPackages ?. json ( ) ;
42+ const functions = await resTopics ?. json ( ) ;
43+ const topics = functions ?. functions ;
44+ const relevantPackages = packages ?. filter ( ( p ) => ( p ?. score > 1 ) ) ;
45+ const relevantTopics = topics ?. filter ( ( p ) => ( p ?. score > 1 ) ) ;
46+ setPackageSuggestions ( relevantPackages ?. slice ( 0 , Math . min ( relevantPackages ?. length , 5 ) ) ) ;
47+ setTopicSuggestions ( relevantTopics ?. slice ( 0 , Math . min ( relevantTopics ?. length , 5 ) ) ) ;
48+
49+ } catch ( err ) {
50+ console . error ( err ) ;
51+ }
52+ } ;
53+
54+ useEffect ( ( ) => {
55+ autoComplete ( searchInput ) ;
56+ } , [ searchInput ] )
57+
58+ return (
59+ < div className = "my-2 bg-white rounded-2xl shadow-lg" >
60+ {
61+ searchInput
62+ &&
63+ < div
64+ onClick = { ( ) => onClick ( searchInput ) }
65+ className = "flex items-center px-4 py-4 cursor-pointer hover:bg-dc-beige200 hover:opacity-0.5"
66+ >
67+ < Paragraph className = "pl-2 py-2" > { `View results for "${ searchInput } "` } </ Paragraph >
68+ </ div >
69+ }
70+ < div >
71+ {
72+ packageSuggestions ?. length > 0
73+ &&
74+ searchInput
75+ &&
76+ < ul >
77+ < li className = "my-2 ml-2 pl-4 text-dc-grey200 flex justify-between" >
78+ < Heading as = "h3" size = { 300 } > PACKAGES</ Heading >
79+ </ li >
80+ {
81+ packageSuggestions ?. map ( ( p ) => {
82+ return (
83+ < li
84+ key = { p ?. fields ?. package_name }
85+ onClick = { ( ) => onClick ( p ?. fields ?. package_name ) }
86+ className = "flex items-center px-4 py-2 cursor-pointer hover:bg-dc-beige200 hover:opacity-0.5"
87+ >
88+ < Paragraph className = "pl-2 text-lg" > { p ?. fields ?. package_name } </ Paragraph >
89+ </ li >
90+ )
91+ } ) }
92+ </ ul >
93+ }
94+ </ div >
95+ < div >
96+ {
97+ topicSuggestions ?. length > 0
98+ &&
99+ searchInput
100+ &&
101+ < ul >
102+ < li className = "my-2 ml-2 pl-4 text-dc-grey200 flex justify-between" >
103+ < Heading as = "h3" size = { 300 } > FUNCTIONS</ Heading >
104+ </ li >
105+ {
106+ topicSuggestions ?. map ( ( t ) => {
107+ return (
108+ < li
109+ key = { t ?. fields ?. package_name + t ?. fields ?. name }
110+ onClick = { ( ) => onClick ( t ?. fields ?. name ) }
111+ className = "flex items-center px-4 py-2 cursor-pointer hover:bg-dc-beige200 hover:opacity-0.5"
112+ >
113+ < div >
114+ < Paragraph className = "px-2 text-lg" > { `${ t ?. fields ?. name } ` } </ Paragraph >
115+ </ div >
116+ < div >
117+ < Paragraph className = "text-lg text-dc-red" > { `(${ t ?. fields ?. package_name } )` } </ Paragraph >
118+ </ div >
119+ </ li >
120+ )
121+ } ) }
122+ </ ul >
123+ }
124+ </ div >
125+ </ div >
126+ )
127+ }
0 commit comments