Search code examples
javascriptreactjsnext.jsalgolia

Algolia Hit Component is not working with grid


Im converting my next api to a algolia search, and hit component is a single component that renders foreach record, but i am unable to use grid, i will show how i was doing (it was working):


      { {propostas.length == 0 ? (
        <div className="mt-6 grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3">
          {timesToRenderPropostas.map((_, index) => (
            <SkeletonPropostas index={index} key={index} />
          ))}
        </div>
      ) : (
        <div className="mt-6 grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3">
          {propostas.map((proposta: any) => (
            <div key={proposta.id} className=" rounded-lg ">
              <div className="mx-auto mt-4 max-w-sm overflow-hidden rounded-2xl bg-white p-2">
                <p className="bg-white font-semibold text-gray-700">
                  {proposta.Categoria?.name}
                </p>
                <div className="mb-2 bg-white pt-2 text-lg font-bold">
                  {proposta.title}
                </div>
                <div>
                  {proposta.textComplete != null ? (
                    <h1 className="bg-white pl-2 font-semibold text-slate-500">
                      {proposta.textComplete}
                    </h1>
                  ) : (
                    <div></div>
                  )}
                </div>
                <div className=" bg-white pb-2 pt-4">
                  {proposta.Status?.name == "Sem dados" ? (
                    <span className="mb-2 mr-2 inline-block rounded-full bg-[#ACACAC] px-3 py-1 text-sm font-semibold text-white">
                      Sem Dados
                    </span>
                  ) : proposta.Status?.name == "Cumpriu" ? (
                    <span className="mb-2 mr-2 inline-block rounded-full bg-[#51A975] px-3 py-1 text-sm font-semibold text-white">
                      Cumpriu
                    </span>
                  ) : proposta.Status?.name == "Não cumpriu" ? (
                    <span className="mb-2 mr-2 inline-block rounded-full bg-[#FF4D4D] px-3 py-1 text-sm font-semibold text-white">
                      Não cumpriu
                    </span>
                  ) : proposta.Status?.name == "Em partes" ? (
                    <span className="mb-2 mr-2 inline-block rounded-full bg-[#FFBB5D] px-3 py-1 text-sm font-semibold text-white">
                      Em partes
                    </span>
                  ) : (
                    <p>.</p>
                  )}
                  <button
                    onClick={() => {
                      navigator.clipboard.writeText(proposta.title);
                      const showToastMessage = () => {
                        toast.success("Copiado", {
                          position: toast.POSITION.TOP_RIGHT,
                          autoClose: 1500,
                        });
                      };
                      showToastMessage();
                    }}
                    className="mb-2 mr-2 inline-block rounded-full bg-gray-300 px-3 py-1 text-sm font-semibold text-slate-700"
                  >
                    Copiar
                  </button>
                  <Link href={`/edit/proposta/${proposta.id}`}>
                    <span className="mb-2 mr-2 inline-block rounded-full bg-gray-300 px-3 py-1 text-sm font-semibold text-slate-700">
                      Editar
                    </span>
                  </Link>
                </div>
              </div>
            </div>
          ))}
          <ToastContainer />
        </div>
      )} 

with algolia it goes like that

variable:

  const Hit = ({ hit }) => (
    <div className="rounded-lg">
      <div className="mx-auto mt-4 max-w-sm overflow-hidden rounded-2xl bg-white p-2">
        <p className="bg-white font-semibold text-gray-700">
          {hit.Categoria?.name}
        </p>
        <div className="mb-2 bg-white pt-2 text-lg font-bold">
          {hit.title}
        </div>
        <div>
          {hit.textComplete != null ? (
            <h1 className="bg-white pl-2 font-semibold text-slate-500">
              {hit.textComplete}
            </h1>
          ) : (
            <div></div>
          )}
          <div className=" bg-white pb-2 pt-4">
            {hit.Status?.name == "Sem dados" ? (
              <span className="mb-2 mr-2 inline-block rounded-full bg-[#ACACAC] px-3 py-1 text-sm font-semibold text-white">
                Sem Dados
              </span>
            ) : hit.Status?.name == "Cumpriu" ? (
              <span className="mb-2 mr-2 inline-block rounded-full bg-[#51A975] px-3 py-1 text-sm font-semibold text-white">
                Cumpriu
              </span>
            ) : hit.Status?.name == "Não cumpriu" ? (
              <span className="mb-2 mr-2 inline-block rounded-full bg-[#FF4D4D] px-3 py-1 text-sm font-semibold text-white">
                Não cumpriu
              </span>
            ) : hit.Status?.name == "Em partes" ? (
              <span className="mb-2 mr-2 inline-block rounded-full bg-[#FFBB5D] px-3 py-1 text-sm font-semibold text-white">
                Em partes
              </span>
            ) : (
              <p>.</p>
            )}
            <button
              onClick={() => {
                navigator.clipboard.writeText(hit.title);
                const showToastMessage = () => {
                  toast.success("Copiado", {
                    position: toast.POSITION.TOP_RIGHT,
                    autoClose: 1500,
                  });
                };
                showToastMessage();
              }}
              className="mb-2 mr-2 inline-block rounded-full bg-gray-300 px-3 py-1 text-sm font-semibold text-slate-700"
            >
              Copiar
            </button>
            <Link href={`/edit/proposta/${hit.id}`}>
              <span className="mb-2 mr-2 inline-block rounded-full bg-gray-300 px-3 py-1 text-sm font-semibold text-slate-700">
                Editar
              </span>
            </Link>
          </div>
        </div>
      </div>
    </div>
  );

and the component:

   <InstantSearch
        searchClient={searchClient}
        indexName="propostas"
        onStateChange={onStateChange}
      >
        <SearchBox />
        <div className="mt-6 grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3">
          <Hits hitComponent={Hit} />
        </div>
      </InstantSearch>

how to make each hit record inside a grid of 3 elements, like the previous code?


Solution

  • I got my hit layout in a grid when using import "instantsearch.css/themes/algolia-min.css"; I am currently trying to reuse that theme and customize it to overwrite some styles, but I haven't achieved that yet.

    this is the documentation page that has led me thus far https://www.algolia.com/doc/guides/building-search-ui/widgets/customize-an-existing-widget/react/#style-your-widgets

    Update: If you want to have more customizability in the components, they have js and ts examples that you can copy and style - SearchBox, Breadcrumbs, HitsPerPage, etc. I found a Custom Hits component to be what I needed and added classNames to the other widgets I used - https://www.algolia.com/doc/api-reference/widgets/hits/react/?client=ts