on master help sign in
search: add dev.urbit.org searches
38e263fMatilde Park
components/Search.js+63−4
@@ -18,12 +18,17 @@ class Search extends Component {
18 this.onSelect = this.onSelect.bind(this);
18 this.onSelect = this.onSelect.bind(this);
19 this.glossarySearch = this.glossarySearch.bind(this);
19 this.glossarySearch = this.glossarySearch.bind(this);
20 this.patpSearch = this.patpSearch.bind(this);
20 this.patpSearch = this.patpSearch.bind(this);
21+ this.devSearch = this.devSearch.bind(this);
21 }
22 }
22
23
23 searchEndpoint(query) {
24 searchEndpoint(query) {
24 return `/api/search?q=${query}`;
25 return `/api/search?q=${query}`;
25 }
26 }
26
27
28+ devSearch(query) {
29+ return `/api/dev-search?q=${query}`;
30+ }
31+
27 glossarySearch(query) {
32 glossarySearch(query) {
28 const entries = glossary.filter((entry) => {
33 const entries = glossary.filter((entry) => {
29 return (
34 return (
@@ -54,12 +59,11 @@ class Search extends Component {
54 this.props.closeSearch();
59 this.props.closeSearch();
55 }
60 }
56
61
57− onInputValueChange = debounce((query) => {
62+ onInputValueChange = debounce(async (query) => {
58 if (query.length) {
63 if (query.length) {
59 fetch(this.searchEndpoint(query))
64 fetch(this.searchEndpoint(query))
60 .then((res) => res.json())
65 .then((res) => res.json())
61− .then((res) => {
66+ .then(async (res) => {
62− console.log(res);
63 // Wrap results in an object which will tell React what component to use to render results.
67 // Wrap results in an object which will tell React what component to use to render results.
64 const results = res.results.map((item) => ({
68 const results = res.results.map((item) => ({
65 type: "RESULT",
69 type: "RESULT",
@@ -89,7 +93,21 @@ class Search extends Component {
89 content: item,
93 content: item,
90 }));
94 }));
91
95
96+ const devResults = await fetch(this.devSearch(query))
97+ .then((res) => res.json())
98+ .then((res) => {
99+ return res.results.map((item) => ({
100+ type: "DEV_RESULT",
101+ content: item,
102+ }));
103+ });
104+
105+ const list = [
92− const list = [...glossaryResults, ...patpResult, ...results];
106+ ...glossaryResults,
107+ ...patpResult,
108+ ...results,
109+ ...devResults,
110+ ];
93
111
94 this.setState({ results: list });
112 this.setState({ results: list });
95 });
113 });
@@ -254,6 +272,47 @@ class Search extends Component {
254 </li>
272 </li>
255 );
273 );
256 }
274 }
275+ if (item.type === "DEV_RESULT") {
276+ const devItem = Object.assign({}, item.content);
277+ devItem[
278+ "slug"
279+ ] = `https://developers.urbit.org${item.content.slug}`;
280+ return (
281+ <li
282+ className={`cursor-pointer flex text-left w-full ${
283+ selected ? "bg-green-400" : ""
284+ }`}
285+ {...getItemProps({
286+ key: item.content.link + "-" + index,
287+ index,
288+ item: devItem,
289+ selected,
290+ })}
291+ >
292+ <div className="p-3">
293+ <p
294+ className={`font-medium text-base ${
295+ selected ? "text-white" : "text-wall-600"
296+ }`}
297+ >
298+ <span className="text-wall-400">
299+ {item.content.parent !== "Content"
300+ ? `developers.urbit.org / ${item.content.parent} /`
301+ : "developers.urbit.org /"}{" "}
302+ </span>
303+ {item.content.title}
304+ </p>
305+ <p
306+ className={`text-base font-regular text-small ${
307+ selected ? "text-midWhite" : "text-wall-500"
308+ }`}
309+ >
310+ {item.content.content}
311+ </p>
312+ </div>
313+ </li>
314+ );
315+ }
257 return null;
316 return null;
258 })
317 })
259 : null}
318 : null}
pages/api/dev-search.jsnew file+8
@@ -0,0 +1,8 @@
1+export default async (req, res) => {
2+ const results = await fetch(
3+ `https://developers.urbit.org/api/search?q=${req.query.q}`
4+ ).then((res) => res.json());
5+ res.statusCode = 200;
6+ res.setHeader("Content-Type", "application/json");
7+ res.end(JSON.stringify(results));
8+};