mirror of
https://github.com/vercel/commerce.git
synced 2025-05-17 15:06:59 +00:00
Add use-search hooks
Signed-off-by: Chloe <pinkcloudvnn@gmail.com>
This commit is contained in:
parent
79b659048e
commit
2401a42b63
14
packages/opencommerce/schema.d.ts
vendored
14
packages/opencommerce/schema.d.ts
vendored
@ -7937,6 +7937,8 @@ export type AuthenticateMutation = {
|
|||||||
export type CatalogItemsQueryVariables = Exact<{
|
export type CatalogItemsQueryVariables = Exact<{
|
||||||
first?: InputMaybe<Scalars['ConnectionLimitInt']>
|
first?: InputMaybe<Scalars['ConnectionLimitInt']>
|
||||||
sortBy?: InputMaybe<CatalogItemSortByField>
|
sortBy?: InputMaybe<CatalogItemSortByField>
|
||||||
|
sortOrder?: InputMaybe<SortOrder>
|
||||||
|
sortByPriceCurrencyCode?: InputMaybe<Scalars['String']>
|
||||||
tagIds?: InputMaybe<
|
tagIds?: InputMaybe<
|
||||||
Array<InputMaybe<Scalars['ID']>> | InputMaybe<Scalars['ID']>
|
Array<InputMaybe<Scalars['ID']>> | InputMaybe<Scalars['ID']>
|
||||||
>
|
>
|
||||||
@ -8201,6 +8203,18 @@ export type GetProductBySlugQuery = {
|
|||||||
} | null
|
} | null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type GetShopCurrencyQueryVariables = Exact<{
|
||||||
|
id: Scalars['ID']
|
||||||
|
}>
|
||||||
|
|
||||||
|
export type GetShopCurrencyQuery = {
|
||||||
|
__typename?: 'Query'
|
||||||
|
shop?: {
|
||||||
|
__typename?: 'Shop'
|
||||||
|
currency: { __typename?: 'Currency'; code: string }
|
||||||
|
} | null
|
||||||
|
}
|
||||||
|
|
||||||
export type GetTagsQueryVariables = Exact<{
|
export type GetTagsQueryVariables = Exact<{
|
||||||
first: Scalars['ConnectionLimitInt']
|
first: Scalars['ConnectionLimitInt']
|
||||||
shopId: Scalars['ID']
|
shopId: Scalars['ID']
|
||||||
|
@ -0,0 +1,56 @@
|
|||||||
|
import type { ProductsEndpoint } from './products'
|
||||||
|
import getSearchVariables from '../../utils/get-search-variables'
|
||||||
|
import getSortVariables from '../../utils/get-sort-variables'
|
||||||
|
import { CatalogItemsQueryVariables } from '../../../../schema'
|
||||||
|
import getShopCurrencyQuery from '../../queries/get-shop-currency-query'
|
||||||
|
|
||||||
|
const getProducts: ProductsEndpoint['handlers']['getProducts'] = async ({
|
||||||
|
body: { brandId, search, sort, categoryId },
|
||||||
|
res,
|
||||||
|
config,
|
||||||
|
commerce,
|
||||||
|
}) => {
|
||||||
|
let sortParams = getSortVariables(sort)
|
||||||
|
if (sortParams?.sortBy === 'featured' && !categoryId) {
|
||||||
|
sortParams = null
|
||||||
|
}
|
||||||
|
|
||||||
|
let currency: string | null = null
|
||||||
|
|
||||||
|
if (sortParams?.sortBy === 'minPrice') {
|
||||||
|
const {
|
||||||
|
data: {
|
||||||
|
shop: {
|
||||||
|
currency: { code },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
} = await config.fetch(getShopCurrencyQuery, {
|
||||||
|
variables: { id: config.shopId },
|
||||||
|
})
|
||||||
|
currency = code
|
||||||
|
}
|
||||||
|
|
||||||
|
const { products } = await commerce.getAllProducts({
|
||||||
|
variables: {
|
||||||
|
...getSearchVariables({ brandId, search, categoryId }),
|
||||||
|
...(sortParams
|
||||||
|
? {
|
||||||
|
sortBy: sortParams.sortBy as CatalogItemsQueryVariables['sortBy'],
|
||||||
|
sortOrder:
|
||||||
|
sortParams.sortOrder as CatalogItemsQueryVariables['sortOrder'],
|
||||||
|
}
|
||||||
|
: {}),
|
||||||
|
...(currency ? { sortByPriceCurrencyCode: currency } : {}),
|
||||||
|
},
|
||||||
|
config,
|
||||||
|
})
|
||||||
|
|
||||||
|
res.status(200).json({
|
||||||
|
data: {
|
||||||
|
products,
|
||||||
|
found: !!products.length,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export default getProducts
|
@ -1 +0,0 @@
|
|||||||
export default function noopApi(...args: any[]): void {}
|
|
@ -1 +1,20 @@
|
|||||||
export default function noopApi(...args: any[]): void {}
|
import { CommerceAPI, createEndpoint, GetAPISchema } from '@vercel/commerce/api'
|
||||||
|
import productsEndpoint from '@vercel/commerce/api/endpoints/catalog/products'
|
||||||
|
import type { ProductsSchema } from '../../../types/product'
|
||||||
|
import type { OpenCommerceAPI } from '../../index'
|
||||||
|
import getProducts from './get-products'
|
||||||
|
|
||||||
|
export type ProductsAPI = GetAPISchema<OpenCommerceAPI, ProductsSchema>
|
||||||
|
|
||||||
|
export type ProductsEndpoint = ProductsAPI['endpoint']
|
||||||
|
|
||||||
|
export const handlers: ProductsEndpoint['handlers'] = {
|
||||||
|
getProducts,
|
||||||
|
}
|
||||||
|
|
||||||
|
const productsApi = createEndpoint<ProductsAPI>({
|
||||||
|
handler: productsEndpoint,
|
||||||
|
handlers,
|
||||||
|
})
|
||||||
|
|
||||||
|
export default productsApi
|
||||||
|
@ -15,7 +15,7 @@ export default function getAllProductsOperation({
|
|||||||
commerce,
|
commerce,
|
||||||
}: OperationContext<Provider>) {
|
}: OperationContext<Provider>) {
|
||||||
async function getAllProducts<T extends GetAllProductsOperation>(opts?: {
|
async function getAllProducts<T extends GetAllProductsOperation>(opts?: {
|
||||||
variables?: T['variables']
|
variables?: Omit<CatalogItemsQueryVariables, 'shopIds'>
|
||||||
config?: Partial<OpenCommerceConfig>
|
config?: Partial<OpenCommerceConfig>
|
||||||
preview?: boolean
|
preview?: boolean
|
||||||
}): Promise<T['data']>
|
}): Promise<T['data']>
|
||||||
@ -26,7 +26,7 @@ export default function getAllProductsOperation({
|
|||||||
config,
|
config,
|
||||||
}: {
|
}: {
|
||||||
query?: string
|
query?: string
|
||||||
variables?: T['variables']
|
variables?: Omit<CatalogItemsQueryVariables, 'shopIds'>
|
||||||
config?: Partial<OpenCommerceConfig>
|
config?: Partial<OpenCommerceConfig>
|
||||||
preview?: boolean
|
preview?: boolean
|
||||||
} = {}): Promise<T['data']> {
|
} = {}): Promise<T['data']> {
|
||||||
|
@ -2,6 +2,8 @@ const catalogItemsQuery = /* GraphQL */ `
|
|||||||
query catalogItems(
|
query catalogItems(
|
||||||
$first: ConnectionLimitInt = 250
|
$first: ConnectionLimitInt = 250
|
||||||
$sortBy: CatalogItemSortByField = updatedAt
|
$sortBy: CatalogItemSortByField = updatedAt
|
||||||
|
$sortOrder: SortOrder = desc
|
||||||
|
$sortByPriceCurrencyCode: String
|
||||||
$tagIds: [ID]
|
$tagIds: [ID]
|
||||||
$shopIds: [ID]!
|
$shopIds: [ID]!
|
||||||
$searchQuery: String
|
$searchQuery: String
|
||||||
@ -9,9 +11,11 @@ const catalogItemsQuery = /* GraphQL */ `
|
|||||||
catalogItems(
|
catalogItems(
|
||||||
first: $first
|
first: $first
|
||||||
sortBy: $sortBy
|
sortBy: $sortBy
|
||||||
|
sortOrder: $sortOrder
|
||||||
tagIds: $tagIds
|
tagIds: $tagIds
|
||||||
shopIds: $shopIds
|
shopIds: $shopIds
|
||||||
searchQuery: $searchQuery
|
searchQuery: $searchQuery
|
||||||
|
sortByPriceCurrencyCode: $sortByPriceCurrencyCode
|
||||||
) {
|
) {
|
||||||
pageInfo {
|
pageInfo {
|
||||||
hasNextPage
|
hasNextPage
|
||||||
|
@ -0,0 +1,11 @@
|
|||||||
|
const getShopCurrencyQuery = /* GraphQL */ `
|
||||||
|
query getShopCurrency($id: ID!) {
|
||||||
|
shop(id: $id) {
|
||||||
|
currency {
|
||||||
|
code
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
export default getShopCurrencyQuery
|
36
packages/opencommerce/src/api/utils/get-search-variables.ts
Normal file
36
packages/opencommerce/src/api/utils/get-search-variables.ts
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
export type SearchProductsInput = {
|
||||||
|
search?: string
|
||||||
|
categoryId?: number | string
|
||||||
|
brandId?: number | string
|
||||||
|
locale?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const getSearchVariables = ({
|
||||||
|
brandId,
|
||||||
|
search,
|
||||||
|
categoryId,
|
||||||
|
}: SearchProductsInput) => {
|
||||||
|
let searchQuery = ''
|
||||||
|
let tagIdsParam = {}
|
||||||
|
|
||||||
|
if (search) {
|
||||||
|
searchQuery += search
|
||||||
|
}
|
||||||
|
|
||||||
|
if (brandId) {
|
||||||
|
searchQuery += `${search ? ' ' : ''}${brandId}`
|
||||||
|
}
|
||||||
|
|
||||||
|
if (categoryId) {
|
||||||
|
tagIdsParam = {
|
||||||
|
tagIds: [categoryId],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
searchQuery,
|
||||||
|
...tagIdsParam,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default getSearchVariables
|
25
packages/opencommerce/src/api/utils/get-sort-variables.ts
Normal file
25
packages/opencommerce/src/api/utils/get-sort-variables.ts
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
type SortByField = 'minPrice' | 'featured' | 'createdAt'
|
||||||
|
|
||||||
|
const getSortVariables = (sort?: string) => {
|
||||||
|
if (!sort) return null
|
||||||
|
const [_sort, direction] = sort.split('-')
|
||||||
|
|
||||||
|
const SORT: { [key: string]: SortByField | undefined } = {
|
||||||
|
price: 'minPrice',
|
||||||
|
trending: 'featured',
|
||||||
|
latest: 'createdAt',
|
||||||
|
}
|
||||||
|
|
||||||
|
const sortValue = SORT[_sort]
|
||||||
|
|
||||||
|
if (sortValue && direction) {
|
||||||
|
return {
|
||||||
|
sortBy: sortValue,
|
||||||
|
sortOrder: direction,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
export default getSortVariables
|
@ -1,17 +1,45 @@
|
|||||||
import { SWRHook } from '@vercel/commerce/utils/types'
|
import { SWRHook } from '@vercel/commerce/utils/types'
|
||||||
import useSearch, { UseSearch } from '@vercel/commerce/product/use-search'
|
import useSearch, { UseSearch } from '@vercel/commerce/product/use-search'
|
||||||
|
import type { SearchProductsHook } from '../types/product'
|
||||||
|
|
||||||
export default useSearch as UseSearch<typeof handler>
|
export default useSearch as UseSearch<typeof handler>
|
||||||
|
|
||||||
export const handler: SWRHook<any> = {
|
export const handler: SWRHook<SearchProductsHook> = {
|
||||||
fetchOptions: {
|
fetchOptions: {
|
||||||
query: '',
|
url: '/api/catalog/products',
|
||||||
|
method: 'GET',
|
||||||
},
|
},
|
||||||
async fetcher({ input, options, fetch }) {},
|
async fetcher({
|
||||||
useHook: () => () => {
|
input: { search, categoryId, brandId, sort },
|
||||||
return {
|
options,
|
||||||
data: {
|
fetch,
|
||||||
products: [],
|
}) {
|
||||||
},
|
// Use a dummy base as we only care about the relative path
|
||||||
}
|
const url = new URL(options.url!, 'http://a')
|
||||||
|
if (search) url.searchParams.set('search', search)
|
||||||
|
if (categoryId) url.searchParams.set('categoryId', String(categoryId))
|
||||||
|
if (brandId) url.searchParams.set('brandId', String(brandId))
|
||||||
|
if (sort) url.searchParams.set('sort', sort)
|
||||||
|
|
||||||
|
return fetch({
|
||||||
|
url: url.pathname + url.search,
|
||||||
|
method: options.method,
|
||||||
|
})
|
||||||
},
|
},
|
||||||
|
useHook:
|
||||||
|
({ useData }) =>
|
||||||
|
(input = {}) => {
|
||||||
|
return useData({
|
||||||
|
input: [
|
||||||
|
['search', input.search],
|
||||||
|
['categoryId', input.categoryId],
|
||||||
|
['brandId', input.brandId],
|
||||||
|
['sort', input.sort],
|
||||||
|
],
|
||||||
|
swrOptions: {
|
||||||
|
revalidateOnFocus: false,
|
||||||
|
...input.swrOptions,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
@ -54,6 +54,7 @@ export default function Search({ categories, brands }: SearchPropsType) {
|
|||||||
locale,
|
locale,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
console.log({ data })
|
||||||
const handleClick = (event: any, filter: string) => {
|
const handleClick = (event: any, filter: string) => {
|
||||||
if (filter !== activeFilter) {
|
if (filter !== activeFilter) {
|
||||||
setToggleFilter(true)
|
setToggleFilter(true)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user