diff --git a/app/search/[collection]/page.tsx b/app/search/[collection]/page.tsx index 0e1782b7d..873701bf7 100644 --- a/app/search/[collection]/page.tsx +++ b/app/search/[collection]/page.tsx @@ -4,6 +4,7 @@ import { notFound } from 'next/navigation'; import Grid from 'components/grid'; import ProductGridItems from 'components/layout/product-grid-items'; +import { defaultSort, sorting } from 'lib/constants'; export const runtime = 'edge'; @@ -32,8 +33,16 @@ export async function generateMetadata({ }; } -export default async function CategoryPage({ params }: { params: { collection: string } }) { - const products = await getCollectionProducts(params.collection); +export default async function CategoryPage({ + params, + searchParams +}: { + params: { collection: string }; + searchParams?: { [key: string]: string | string[] | undefined }; +}) { + const { sort } = searchParams as { [key: string]: string }; + const { sortKey, reverse } = sorting.find((item) => item.slug === sort) || defaultSort; + const products = await getCollectionProducts({ collection: params.collection, sortKey, reverse }); return (
diff --git a/components/carousel.tsx b/components/carousel.tsx index 30b6a4733..d86d17f45 100644 --- a/components/carousel.tsx +++ b/components/carousel.tsx @@ -4,7 +4,7 @@ import Link from 'next/link'; export async function Carousel() { // Collections that start with `hidden-*` are hidden from the search page. - const products = await getCollectionProducts('hidden-homepage-carousel'); + const products = await getCollectionProducts({ collection: 'hidden-homepage-carousel' }); if (!products?.length) return null; diff --git a/components/grid/three-items.tsx b/components/grid/three-items.tsx index 6814a171a..2280de26e 100644 --- a/components/grid/three-items.tsx +++ b/components/grid/three-items.tsx @@ -37,7 +37,9 @@ function ThreeItemGridItem({ export async function ThreeItemGrid() { // Collections that start with `hidden-*` are hidden from the search page. - const homepageItems = await getCollectionProducts('hidden-homepage-featured-items'); + const homepageItems = await getCollectionProducts({ + collection: 'hidden-homepage-featured-items' + }); if (!homepageItems[0] || !homepageItems[1] || !homepageItems[2]) return null; diff --git a/components/layout/navbar/search.tsx b/components/layout/navbar/search.tsx index b3ff9a6bb..fff895f43 100644 --- a/components/layout/navbar/search.tsx +++ b/components/layout/navbar/search.tsx @@ -3,6 +3,7 @@ import { useRouter, useSearchParams } from 'next/navigation'; import SearchIcon from 'components/icons/search'; +import { createUrl } from 'lib/utils'; export default function Search() { const router = useRouter(); @@ -13,12 +14,15 @@ export default function Search() { const val = e.target as HTMLFormElement; const search = val.search as HTMLInputElement; + const newParams = new URLSearchParams(searchParams.toString()); if (search.value) { - router.push(`/search?q=${search.value}`); + newParams.set('q', search.value); } else { - router.push(`/search`); + newParams.delete('q'); } + + router.push(createUrl('/search', newParams)); } return ( diff --git a/components/layout/search/filter/item.tsx b/components/layout/search/filter/item.tsx index f56d6114b..1a3b73ad3 100644 --- a/components/layout/search/filter/item.tsx +++ b/components/layout/search/filter/item.tsx @@ -12,6 +12,9 @@ function PathFilterItem({ item }: { item: PathFilterItem }) { const pathname = usePathname(); const searchParams = useSearchParams(); const [active, setActive] = useState(pathname === item.path); + const newParams = new URLSearchParams(searchParams.toString()); + + newParams.delete('q'); useEffect(() => { setActive(pathname === item.path); @@ -20,7 +23,7 @@ function PathFilterItem({ item }: { item: PathFilterItem }) { return (
  • { setActive(searchParams.get('sort') === item.slug); @@ -43,7 +47,13 @@ function SortFilterItem({ item }: { item: SortFilterItem }) { const href = item.slug && item.slug.length - ? createUrl(pathname, new URLSearchParams({ sort: item.slug })) + ? createUrl( + pathname, + new URLSearchParams({ + ...(q && { q }), + sort: item.slug + }) + ) : pathname; return ( diff --git a/lib/shopify/index.ts b/lib/shopify/index.ts index a2f45a36f..5d3972536 100644 --- a/lib/shopify/index.ts +++ b/lib/shopify/index.ts @@ -257,16 +257,26 @@ export async function getCollection(handle: string): Promise { +export async function getCollectionProducts({ + collection, + reverse, + sortKey +}: { + collection: string; + reverse?: boolean; + sortKey?: string; +}): Promise { const res = await shopifyFetch({ query: getCollectionProductsQuery, variables: { - handle + handle: collection, + reverse, + sortKey } }); if (!res.body.data.collection) { - console.log('No collection found for handle', handle); + console.log(`No collection found for \`${collection}\``); return []; } diff --git a/lib/shopify/queries/collection.ts b/lib/shopify/queries/collection.ts index ac3fb4dd9..6396ff8eb 100644 --- a/lib/shopify/queries/collection.ts +++ b/lib/shopify/queries/collection.ts @@ -37,9 +37,13 @@ export const getCollectionsQuery = /* GraphQL */ ` `; export const getCollectionProductsQuery = /* GraphQL */ ` - query getCollectionProducts($handle: String!) { + query getCollectionProducts( + $handle: String! + $sortKey: ProductCollectionSortKeys + $reverse: Boolean + ) { collection(handle: $handle) { - products(first: 100) { + products(sortKey: $sortKey, reverse: $reverse, first: 100) { edges { node { ...product diff --git a/lib/shopify/types.ts b/lib/shopify/types.ts index b18ed3b63..23dc02d46 100644 --- a/lib/shopify/types.ts +++ b/lib/shopify/types.ts @@ -201,6 +201,8 @@ export type ShopifyCollectionProductsOperation = { }; variables: { handle: string; + reverse?: boolean; + sortKey?: string; }; };