Skip to content

Commit

Permalink
v1.3.0 (#58)
Browse files Browse the repository at this point in the history
* chore: add lodash.omit

* feat: add pagination to useSearch

* feat: return basePrice in the product query

* update login sso documentation

* chore: update schema

* docs: update CHANGELOG

* docs: clarify CHANGELOG

Co-authored-by: magicspon <[email protected]>
  • Loading branch information
jorgemasta and magicspon authored Apr 14, 2021
1 parent e6196b0 commit 6fc95f3
Show file tree
Hide file tree
Showing 10 changed files with 522 additions and 20 deletions.
20 changes: 20 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,23 @@
# 1.3.0
### Login SSO Documentation

- Fix a bug in the Login SSO sample code: The `url` param must be passed inside the `options` object.

### Add pagination to `useSearch`

- Update `README.me`
- Add a new param to the `useSearch` hook: `page`
- Get the results based on the provided `page`.

*Resolves [#38](https://github.com/bigcommerce/storefront-data-hooks/issues/38)*

### Return `basePrice` in the product query

- Return `basePrice` in the product query
- Update GraphQL schema to generate the updated types (also includes updated types from the latest [Storefront GraphQL API](https://developer.bigcommerce.com/changelog#labels/storefront-api) updates)

*Related to [#37](https://github.com/bigcommerce/storefront-data-hooks/issues/37)*

# 1.2.0
### Embedded checkout

Expand Down
12 changes: 9 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,9 @@ To authenticate a user using the Customer Login API, it's necessary to point the

```jsx
const login = useLogin({
url: '/api/your-own-authentication',
options: {
url: '/api/your-own-authentication'
},
})
```

Expand Down Expand Up @@ -337,7 +339,7 @@ const WishlistButton = ({ productId, variant }) => {
### useSearch
`useSearch` handles searching the bigcommerce storefront product catalog by catalog, brand, and query string.
`useSearch` handles searching the bigcommerce storefront product catalog by catalog, brand, and query string. It also allows pagination.
```jsx
...
Expand All @@ -349,13 +351,17 @@ const SearchPage = ({ searchString, category, brand, sortStr }) => {
categoryId: category?.entityId,
brandId: brand?.entityId,
sort: sortStr || '',
page: 1
})

const { products, pagination } = data

return (
<Grid layout="normal">
{data.products.map(({ node }) => (
{products.map(({ node }) => (
<ProductCard key={node.path} product={node} />
))}
<Pagination {...pagination}>
</Grid>
)
}
Expand Down
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
"cookie": "0.4.1",
"js-cookie": "2.2.1",
"lodash.debounce": "4.0.8",
"lodash.omit": "^4.5.0",
"swr": "0.3.6"
},
"devDependencies": {
Expand All @@ -40,6 +41,7 @@
"@types/cookie": "^0.4.0",
"@types/js-cookie": "^2.2.6",
"@types/lodash.debounce": "^4.0.6",
"@types/lodash.omit": "^4.5.6",
"@types/node": "^14.14.3",
"@types/react": "^16.9.53",
"graphql": "^15.4.0",
Expand Down
62 changes: 59 additions & 3 deletions src/api/catalog/handlers/get-products.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import omit from 'lodash.omit';
import getAllProducts, { ProductEdge } from '../../operations/get-all-products'
import type { ProductsHandlers } from '../products'

Expand All @@ -8,10 +9,52 @@ const SORT: { [key: string]: string | undefined } = {
}
const LIMIT = 12

export type Meta = {
pagination: {
/**
* Total number of items in the collection response.
*/
count: number
/**
* The page you are currently on within the collection.
*/
current_page: number
/**
* Pagination links for the previous and next parts of the whole collection.
*/
links?: {
/**
* Link to the current page returned in the response.
*/
current?: string
/**
* Link to the next page returned in the response.
*/
next?: string
/**
* Link to the previous page returned in the response.
*/
previous?: string
}
/**
* The amount of items returned in the collection per page, controlled by the limit parameter.
*/
per_page: number
/**
* Total number of items in the result set.
*/
total: number
/**
* The total number of pages in the collection.
*/
total_pages: number
}
}

// Return current cart info
const getProducts: ProductsHandlers['getProducts'] = async ({
res,
body: { search, category, categories, brand, sort },
body: { search, category, categories, brand, sort, page },
config,
}) => {
// Use a dummy base as we only care about the relative path
Expand All @@ -21,6 +64,7 @@ const getProducts: ProductsHandlers['getProducts'] = async ({
url.searchParams.set('limit', String(LIMIT))

if (search) url.searchParams.set('keyword', search)
if (page) url.searchParams.set('page', page)

const categoriesIn = [...categories?.split(',') || [], category].reduce((acc, category) => {
if (category && Number.isInteger(Number(category))) return [...acc, category]
Expand All @@ -46,7 +90,7 @@ const getProducts: ProductsHandlers['getProducts'] = async ({
// We only want the id of each product
url.searchParams.set('include_fields', 'id')

const { data } = await config.storeApiFetch<{ data: { id: number }[] }>(
const { data, meta } = await config.storeApiFetch<{ data: { id: number }[], meta: Meta }>(
url.pathname + url.search
)
const entityIds = data.map((p) => p.id)
Expand All @@ -72,7 +116,19 @@ const getProducts: ProductsHandlers['getProducts'] = async ({
if (product) products.push(product)
})

res.status(200).json({ data: { products, found } })
const pagination = {
...omit(meta.pagination, ['links', 'current_page']),
pages: {
current: meta.pagination.current_page,
...meta.pagination.links?.previous ? {
previous: meta.pagination.current_page - 1
} : {},
...meta.pagination.links?.next ? {
next: meta.pagination.current_page + 1
} : {}
}
}
res.status(200).json({ data: { products, found, pagination } })
}

export default getProducts
20 changes: 18 additions & 2 deletions src/api/catalog/products.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,33 @@ import createApiHandler, {
} from '../utils/create-api-handler'
import { BigcommerceApiError } from '../utils/errors'
import type { ProductEdge } from '../operations/get-all-products'
import getProducts from './handlers/get-products'
import getProducts, { Meta } from './handlers/get-products'

export type SearchProductsData = {
products: ProductEdge[]
found: boolean
pagination: Omit<Meta["pagination"], "links" | "current_page"> & {
pages: {
/**
* The page you are currently on within the collection.
*/
current: Meta["pagination"]["current_page"],
/**
* The previous page within the same collection
*/
previous?: number,
/**
* The next page within the same collection
*/
next?: number
}
}
}

export type ProductsHandlers = {
getProducts: BigcommerceHandler<
SearchProductsData,
{ search?: 'string'; category?: string; categories?: string, brand?: string; sort?: string }
{ search?: 'string'; category?: string; categories?: string, brand?: string; sort?: string, page?: string }
>
}

Expand Down
4 changes: 4 additions & 0 deletions src/api/fragments/product.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ export const productPrices = /* GraphQL */ `
value
currencyCode
}
basePrice {
value
currencyCode
}
}
`

Expand Down
5 changes: 4 additions & 1 deletion src/products/use-search.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export type SearchProductsInput = {
search?: string
categoryId?: number
categoryIds?: number[]
page?: number
brandId?: number
sort?: string
}
Expand All @@ -21,13 +22,14 @@ export type SearchProductsPayload = Omit<SearchProductsInput, "categoryIds"> & {

export const fetcher: HookFetcher<SearchProductsData, SearchProductsPayload> = (
options,
{ search, categoryId, stringifiedCategoryIds, brandId, sort },
{ search, categoryId, stringifiedCategoryIds, brandId, sort, page },
fetch
) => {
// Use a dummy base as we only care about the relative path
const url = new URL(options?.url ?? defaultOpts.url, 'http://a')

if (search) url.searchParams.set('search', search)
if (page) url.searchParams.set('page', String(page))
if (Number.isInteger(categoryId))
url.searchParams.set('category', String(categoryId))
const categoryIds: SearchProductsInput["categoryIds"] = JSON.parse(stringifiedCategoryIds || '[]')
Expand Down Expand Up @@ -63,6 +65,7 @@ export function extendHook(
['stringifiedCategoryIds', JSON.stringify(input.categoryIds)],
['brandId', input.brandId],
['sort', input.sort],
['page', input.page],
],
customFetcher,
{ revalidateOnFocus: false, ...swrOptions }
Expand Down
Loading

0 comments on commit 6fc95f3

Please sign in to comment.