Skip to content

Commit bd0936d

Browse files
authored
Merge pull request #119 from datacamp/bb/search-autocomplete
[CT-3469] - Autocomplete for home search bar
2 parents d22df62 + d4c6ace commit bd0936d

File tree

2 files changed

+132
-0
lines changed

2 files changed

+132
-0
lines changed

components/Autocomplete.tsx

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
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+
}

pages/index.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,11 @@ import { useState } from 'react';
55
import HomeSearchBar from '../components/HomeSearchBar';
66
import Layout from '../components/Layout';
77
import { API_URL } from '../lib/utils';
8+
import AutoComplete from '../components/Autocomplete';
89

910
export default function HomePage({ packageCount }: { packageCount?: number }) {
1011
const [searchInput, setSearchInput] = useState('');
12+
1113
const router = useRouter();
1214

1315
function handleChangeSearchInput(e) {
@@ -36,6 +38,9 @@ export default function HomePage({ packageCount }: { packageCount?: number }) {
3638
value={searchInput}
3739
/>
3840
</form>
41+
<AutoComplete
42+
searchInput={searchInput}
43+
/>
3944
</div>
4045
</Layout>
4146
);

0 commit comments

Comments
 (0)