From a9f4a0394fd208d1bd3bb7ee9374a4467f7ed512 Mon Sep 17 00:00:00 2001 From: Luis Gomez Date: Fri, 19 Aug 2022 11:30:24 -0500 Subject: [PATCH 1/2] Add pagination, increment categories to 4 --- .../catalog/products/get-products.ts | 15 ++++++---- .../bigcommerce/src/product/use-search.tsx | 9 +++++- packages/commerce/src/types/product.ts | 2 ++ site/components/common/Layout/Layout.tsx | 2 +- site/components/search.tsx | 30 ++++++++++++++++++- 5 files changed, 50 insertions(+), 8 deletions(-) diff --git a/packages/bigcommerce/src/api/endpoints/catalog/products/get-products.ts b/packages/bigcommerce/src/api/endpoints/catalog/products/get-products.ts index f88a231e1f..b1c8a2c8a7 100644 --- a/packages/bigcommerce/src/api/endpoints/catalog/products/get-products.ts +++ b/packages/bigcommerce/src/api/endpoints/catalog/products/get-products.ts @@ -12,7 +12,7 @@ const LIMIT = 12 // Return current cart info const getProducts: ProductsEndpoint['handlers']['getProducts'] = async ({ res, - body: { search, categoryId, brandId, sort }, + body: { search, categoryId, brandId, sort, page }, config, commerce, }) => { @@ -30,6 +30,8 @@ const getProducts: ProductsEndpoint['handlers']['getProducts'] = async ({ if (brandId && Number.isInteger(Number(brandId))) url.searchParams.set('brand_id', String(brandId)) + if (page) url.searchParams.set('page', String(page)) + if (sort) { const [_sort, direction] = sort.split('-') const sortValue = SORT[_sort] @@ -43,9 +45,12 @@ const getProducts: ProductsEndpoint['handlers']['getProducts'] = async ({ // We only want the id of each product url.searchParams.set('include_fields', 'id') - const { data } = await config.storeApiFetch<{ data: { id: number }[] }>( - url.pathname + url.search - ) + const { data, meta } = await config.storeApiFetch<{ + data: { id: number }[] + meta: any + }>(url.pathname + url.search) + + const pagination = meta.pagination const ids = data.map((p) => String(p.id)) const found = ids.length > 0 @@ -73,7 +78,7 @@ const getProducts: ProductsEndpoint['handlers']['getProducts'] = async ({ if (product) products.push(product) }) - res.status(200).json({ data: { products, found } }) + res.status(200).json({ data: { products, found, pagination } }) } export default getProducts diff --git a/packages/bigcommerce/src/product/use-search.tsx b/packages/bigcommerce/src/product/use-search.tsx index fd918e341e..2fc1b159ab 100644 --- a/packages/bigcommerce/src/product/use-search.tsx +++ b/packages/bigcommerce/src/product/use-search.tsx @@ -10,6 +10,7 @@ export type SearchProductsInput = { brandId?: number sort?: string locale?: string + page?: string | number } export const handler: SWRHook = { @@ -17,7 +18,11 @@ export const handler: SWRHook = { url: '/api/catalog/products', method: 'GET', }, - fetcher({ input: { search, categoryId, brandId, sort }, options, fetch }) { + fetcher({ + input: { search, categoryId, brandId, sort, page }, + options, + fetch, + }) { // Use a dummy base as we only care about the relative path const url = new URL(options.url!, 'http://a') @@ -27,6 +32,7 @@ export const handler: SWRHook = { if (Number.isInteger(brandId)) url.searchParams.set('brandId', String(brandId)) if (sort) url.searchParams.set('sort', sort) + if (page) url.searchParams.set('page', String(page)) return fetch({ url: url.pathname + url.search, @@ -42,6 +48,7 @@ export const handler: SWRHook = { ['categoryId', input.categoryId], ['brandId', input.brandId], ['sort', input.sort], + ['page', input.page], ], swrOptions: { revalidateOnFocus: false, diff --git a/packages/commerce/src/types/product.ts b/packages/commerce/src/types/product.ts index fb48ba00b4..46b84d9c9e 100644 --- a/packages/commerce/src/types/product.ts +++ b/packages/commerce/src/types/product.ts @@ -52,6 +52,7 @@ export type SearchProductsBody = { brandId?: string | number sort?: string locale?: string + page?: string | number } export type ProductTypes = { @@ -63,6 +64,7 @@ export type SearchProductsHook = { data: { products: T['product'][] found: boolean + pagination: any } body: T['searchBody'] input: T['searchBody'] diff --git a/site/components/common/Layout/Layout.tsx b/site/components/common/Layout/Layout.tsx index 6dda880e40..3171b4d6c5 100644 --- a/site/components/common/Layout/Layout.tsx +++ b/site/components/common/Layout/Layout.tsx @@ -108,7 +108,7 @@ const Layout: React.FC = ({ }) => { const { acceptedCookies, onAcceptCookies } = useAcceptCookies() const { locale = 'en-US' } = useRouter() - const navBarlinks = categories.slice(0, 2).map((c) => ({ + const navBarlinks = categories.slice(0, 4).map((c) => ({ label: c.name, href: `/search/${c.slug}`, })) diff --git a/site/components/search.tsx b/site/components/search.tsx index 664085e5b4..75b5b04163 100644 --- a/site/components/search.tsx +++ b/site/components/search.tsx @@ -1,7 +1,7 @@ import cn from 'clsx' import type { SearchPropsType } from '@lib/search-props' import Link from 'next/link' -import { useState } from 'react' +import { useEffect, useState } from 'react' import { useRouter } from 'next/router' import { Layout } from '@components/common' @@ -31,6 +31,7 @@ import { export default function Search({ categories, brands }: SearchPropsType) { const [activeFilter, setActiveFilter] = useState('') const [toggleFilter, setToggleFilter] = useState(false) + const [page, SetPage] = useState(1) const router = useRouter() const { asPath, locale } = router @@ -51,9 +52,14 @@ export default function Search({ categories, brands }: SearchPropsType) { categoryId: activeCategory?.id, brandId: (activeBrand as any)?.entityId, sort: typeof sort === 'string' ? sort : '', + page: page, locale, }) + useEffect(() => { + window.scrollTo(0, 0) + }, [page]) + const handleClick = (event: any, filter: string) => { if (filter !== activeFilter) { setToggleFilter(true) @@ -336,6 +342,28 @@ export default function Search({ categories, brands }: SearchPropsType) { ))} )}{' '} +
+ {page !== 1 && ( + + )} + {data?.pagination.total_pages !== data?.pagination.current_page && ( + + )} +
{/* Sort */} From 69204e9e625b79831ee205f3e85f2723ad1a0f86 Mon Sep 17 00:00:00 2001 From: Luis Gomez Date: Thu, 25 Aug 2022 14:59:05 -0500 Subject: [PATCH 2/2] Updates --- site/components/search.tsx | 53 ++++++++++++++++++++++++-------------- site/lib/search.tsx | 5 ++++ 2 files changed, 38 insertions(+), 20 deletions(-) diff --git a/site/components/search.tsx b/site/components/search.tsx index 75b5b04163..73b1ed868e 100644 --- a/site/components/search.tsx +++ b/site/components/search.tsx @@ -25,21 +25,21 @@ import { filterQuery, getCategoryPath, getDesignerPath, + getPaginationPath, useSearchMeta, } from '@lib/search' export default function Search({ categories, brands }: SearchPropsType) { const [activeFilter, setActiveFilter] = useState('') const [toggleFilter, setToggleFilter] = useState(false) - const [page, SetPage] = useState(1) const router = useRouter() const { asPath, locale } = router - const { q, sort } = router.query + const { q, sort, page } = router.query // `q` can be included but because categories and designers can't be searched // in the same way of products, it's better to ignore the search input if one // of those is selected - const query = filterQuery({ sort }) + const query = filterQuery({ sort, page }) const { pathname, category, brand } = useSearchMeta(asPath) const activeCategory = categories.find((cat: any) => cat.slug === category) @@ -52,7 +52,7 @@ export default function Search({ categories, brands }: SearchPropsType) { categoryId: activeCategory?.id, brandId: (activeBrand as any)?.entityId, sort: typeof sort === 'string' ? sort : '', - page: page, + page: typeof page === 'string' ? page : '', locale, }) @@ -343,25 +343,38 @@ export default function Search({ categories, brands }: SearchPropsType) { )}{' '}
- {page !== 1 && ( - + + )} - {data?.pagination.total_pages !== data?.pagination.current_page && ( - + + )}
diff --git a/site/lib/search.tsx b/site/lib/search.tsx index eaeaf66fc8..7d82875197 100644 --- a/site/lib/search.tsx +++ b/site/lib/search.tsx @@ -50,3 +50,8 @@ export const getDesignerPath = (path: string, category?: string) => { category ? `/${category}` : '' }` } + +export const getPaginationPath = (path: string, currentPage?: number) => { + const category = getSlug(path) + return `${category ? `/${category}` : ''}?page=${currentPage}` +}