From 9db94bd113e5ba59b94cb4f96ff0df6bb3a3cc27 Mon Sep 17 00:00:00 2001 From: Michele Riva Date: Thu, 17 Aug 2023 15:38:43 +0200 Subject: [PATCH] adds live search --- app/search/page.tsx | 25 +++++---- components/layout/navbar/search.tsx | 68 ++++++++++++++++-------- components/layout/product-grid-items.tsx | 4 +- 3 files changed, 63 insertions(+), 34 deletions(-) diff --git a/app/search/page.tsx b/app/search/page.tsx index 2f7a53bd4..99e9e7f73 100644 --- a/app/search/page.tsx +++ b/app/search/page.tsx @@ -1,7 +1,7 @@ import Grid from 'components/grid'; import ProductGridItems from 'components/layout/product-grid-items'; -import { defaultSort, sorting } from 'lib/constants'; -import { getProducts } from 'lib/shopify'; +import { orama } from 'lib/orama'; +import { Product } from 'lib/shopify/types'; export const runtime = 'edge'; @@ -16,24 +16,31 @@ export default async function SearchPage({ searchParams?: { [key: string]: string | string[] | undefined }; }) { const { sort, q: searchValue } = searchParams as { [key: string]: string }; - const { sortKey, reverse } = sorting.find((item) => item.slug === sort) || defaultSort; + // const { sortKey, reverse } = sorting.find((item) => item.slug === sort) || defaultSort; + const products = await orama.search({ + term: searchValue, + boost: { + title: 2 + }, + limit: 50, + }) - const products = await getProducts({ sortKey, reverse, query: searchValue }); - const resultsText = products.length > 1 ? 'results' : 'result'; + const resultsText = products.count > 1 ? 'results' : 'result'; + const docs = products.hits.map((hit) => hit.document) as Product[]; return ( <> {searchValue ? (

- {products.length === 0 + {products.count === 0 ? 'There are no products that match ' - : `Showing ${products.length} ${resultsText} for `} + : `Showing ${products.count} ${resultsText} for `} "{searchValue}"

) : null} - {products.length > 0 ? ( + {products.count > 0 ? ( - + ) : null} diff --git a/components/layout/navbar/search.tsx b/components/layout/navbar/search.tsx index 962794256..71445bc4a 100644 --- a/components/layout/navbar/search.tsx +++ b/components/layout/navbar/search.tsx @@ -1,7 +1,7 @@ 'use client'; import Link from 'next/link'; -import { useRouter, useSearchParams } from 'next/navigation'; +import { usePathname, useRouter, useSearchParams } from 'next/navigation'; import { useEffect, useRef, useState } from 'react'; import { MagnifyingGlassIcon } from '@heroicons/react/24/outline'; @@ -15,21 +15,30 @@ export default function Search() { const searchParams = useSearchParams(); const [searchValue, setSearchValue] = useState(''); const [searchResults, setSearchResults] = useState(); + const isSearchPage = usePathname() === '/search' + useEffect(() => { setSearchValue(searchParams?.get('q') || ''); }, [searchParams, setSearchValue]); useEffect(() => { - orama.search({ - term: searchValue, - limit: 5, - boost: { - title: 2, - } - }) - .then(setSearchResults) - .catch(console.log); + + if (isSearchPage) { + router.push(createUrl('/search', new URLSearchParams({ q: searchValue }))) + } else { + orama.search({ + term: searchValue, + limit: 5, + threshold: 0, + boost: { + title: 2, + } + }) + .then(setSearchResults) + .catch(console.log); + } + }, [searchValue]); @@ -55,7 +64,7 @@ export default function Search() { setSearchValue(''); }); - const showSearchResults = searchValue.length > 0 && !!searchResults + const showSearchResults = searchValue.length > 0 && !!searchResults && !isSearchPage; return (
@@ -74,18 +83,31 @@ export default function Search() { { showSearchResults && (
    - {searchResults?.hits?.map((product) => ( -
  • - -
    - {product.document.title as string} -
    -
    - {trimDescription((product.document.description || product.document.title) as string)} -
    - -
  • - ))} + { + searchResults.count + ? ( + searchResults?.hits?.map((product) => ( +
  • + +
    + {product.document.title as string} +
    +
    + {trimDescription((product.document.description || product.document.title) as string)} +
    + +
  • + )) + ) : ( +
  • +
    +
    + No results found for "{searchValue}" +
    +
    +
  • + ) + }
) } diff --git a/components/layout/product-grid-items.tsx b/components/layout/product-grid-items.tsx index ea8a5ebf7..0e8da5564 100644 --- a/components/layout/product-grid-items.tsx +++ b/components/layout/product-grid-items.tsx @@ -13,8 +13,8 @@ export default function ProductGridItems({ products }: { products: Product[] }) alt={product.title} label={{ title: product.title, - amount: product.priceRange.maxVariantPrice.amount, - currencyCode: product.priceRange.maxVariantPrice.currencyCode + amount: product.priceRange?.maxVariantPrice?.amount, + currencyCode: product.priceRange?.maxVariantPrice?.currencyCode }} src={product.featuredImage?.url} fill