mirror of
https://github.com/vercel/commerce.git
synced 2025-05-17 15:06:59 +00:00
Add pagination, increment categories to 4
This commit is contained in:
parent
87134e2990
commit
a9f4a0394f
@ -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
|
||||
|
@ -10,6 +10,7 @@ export type SearchProductsInput = {
|
||||
brandId?: number
|
||||
sort?: string
|
||||
locale?: string
|
||||
page?: string | number
|
||||
}
|
||||
|
||||
export const handler: SWRHook<SearchProductsHook> = {
|
||||
@ -17,7 +18,11 @@ export const handler: SWRHook<SearchProductsHook> = {
|
||||
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<SearchProductsHook> = {
|
||||
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<SearchProductsHook> = {
|
||||
['categoryId', input.categoryId],
|
||||
['brandId', input.brandId],
|
||||
['sort', input.sort],
|
||||
['page', input.page],
|
||||
],
|
||||
swrOptions: {
|
||||
revalidateOnFocus: false,
|
||||
|
@ -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<T extends ProductTypes = ProductTypes> = {
|
||||
data: {
|
||||
products: T['product'][]
|
||||
found: boolean
|
||||
pagination: any
|
||||
}
|
||||
body: T['searchBody']
|
||||
input: T['searchBody']
|
||||
|
@ -108,7 +108,7 @@ const Layout: React.FC<Props> = ({
|
||||
}) => {
|
||||
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}`,
|
||||
}))
|
||||
|
@ -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) {
|
||||
))}
|
||||
</div>
|
||||
)}{' '}
|
||||
<div className="flex justify-center mt-5">
|
||||
{page !== 1 && (
|
||||
<button
|
||||
type="button"
|
||||
className="mr-3 rounded-sm border border-accent-3 px-4 py-3 bg-accent-0 text-sm leading-5 font-medium text-accent-4 hover:text-accent-5 focus:outline-none focus:border-blue-300 focus:shadow-outline-normal active:bg-accent-1 active:text-accent-8 transition ease-in-out duration-150"
|
||||
onClick={() => SetPage(page - 1)}
|
||||
>
|
||||
{' '}
|
||||
Previous{' '}
|
||||
</button>
|
||||
)}
|
||||
{data?.pagination.total_pages !== data?.pagination.current_page && (
|
||||
<button
|
||||
type="button"
|
||||
className="rounded-sm border border-accent-3 px-4 py-3 bg-accent-0 text-sm leading-5 font-medium text-accent-4 hover:text-accent-5 focus:outline-none focus:border-blue-300 focus:shadow-outline-normal active:bg-accent-1 active:text-accent-8 transition ease-in-out duration-150"
|
||||
onClick={() => SetPage(page + 1)}
|
||||
>
|
||||
{' '}
|
||||
Next{' '}
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Sort */}
|
||||
|
Loading…
x
Reference in New Issue
Block a user