All files / src/components/SearchBox index.tsx

0% Statements 0/0
0% Branches 0/0
0% Functions 0/0
0% Lines 0/0

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100                                                                                                                                                                                                       
import React, { Component } from "react";
import "./index.scss";
import ReactGA from "react-ga4";
// https://github.com/algolia/algoliasearch-client-javascript/issues/1152
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const source =
  (index: any, parameters: Record<string, unknown>) =>
  (query: string, cb: CallableFunction) =>
    index
      .search(query, parameters)
      .then((res: { hits: unknown[] }) => cb(res.hits, res))
      .catch((err: unknown) => cb([], err));
 
class SearchBox extends Component {
  async componentDidMount() {
    if (typeof window === "undefined") {
      return;
    }
 
    try {
      const algoliasearchModule = await import("algoliasearch/lite");
      const algoliasearch = algoliasearchModule.default || algoliasearchModule;
      const autocompleteModule = await import("autocomplete.js");
      const autocomplete = autocompleteModule.default || autocompleteModule;
 
      const client = algoliasearch(
        import.meta.env.PUBLIC_ALGOLIA_APP_ID ||
          process.env.STORYBOOK_ALGOLIA_APP_ID,
        import.meta.env.PUBLIC_ALGOLIA_SEARCH_API_KEY ||
          process.env.STORYBOOK_ALGOLIA_SEARCH_API_KEY,
      );
      const index = client.initIndex(
        import.meta.env.PUBLIC_ALGOLIA_INDEX_NAME ||
          process.env.STORYBOOK_ALGOLIA_INDEX_NAME ||
          "posts",
      );
 
      autocomplete("#algolia-search-input", { hint: false }, [
        {
          source: source(index, { hitsPerPage: 3 }),
          displayKey: "title",
          templates: {
            suggestion({
              _highlightResult: { title, description },
            }: {
              _highlightResult: {
                title: {
                  value: string;
                };
                description: {
                  value: string;
                };
              };
            }) {
              return `
                  <b><p class="title">${title.value}</p></b>
                  <p class="description">${description.value}</p>
                  `;
            },
            footer:
              '<div class="branding"><img src="https://i.imgur.com/HXG1uHY.png" alt="Powered by Algolia" decoding="async" /></div>',
          },
        },
      ]).on(
        "autocomplete:selected",
        (_event: unknown, suggestion: { url: string; title: string }) => {
          ReactGA.event({
            category: "User",
            action: `Click Searchbox item: ${suggestion.title}`,
          });
          window.location.href = suggestion.url;
        },
      );
    } catch (err) {
      console.error("Failed to initialize Algolia search:", err);
    }
  }
 
  render() {
    return (
      <div>
        <p>
          <label htmlFor="algolia-search-input">
            <span className="icon-search" />
            &nbsp;SearchBox
          </label>
        </p>
        <input
          type="search"
          id="algolia-search-input"
          placeholder="Enter the keyword..."
          data-testid="algolia-search-input"
        />
      </div>
    );
  }
}
 
export default SearchBox;