forked from crowetic/commerce
Moved useSearch to the new hook
This commit is contained in:
parent
883fbcbcb9
commit
1549368c88
@ -1,63 +1,4 @@
|
|||||||
import type { HookFetcher } from '@commerce/utils/types'
|
import useSearch, { UseSearch } from '@commerce/products/use-search'
|
||||||
import type { SwrOptions } from '@commerce/utils/use-data'
|
import type { BigcommerceProvider } from '..'
|
||||||
import useCommerceSearch from '@commerce/products/use-search'
|
|
||||||
import type { SearchProductsData } from '../api/catalog/products'
|
|
||||||
|
|
||||||
const defaultOpts = {
|
export default useSearch as UseSearch<BigcommerceProvider>
|
||||||
url: '/api/bigcommerce/catalog/products',
|
|
||||||
method: 'GET',
|
|
||||||
}
|
|
||||||
|
|
||||||
export type SearchProductsInput = {
|
|
||||||
search?: string
|
|
||||||
categoryId?: number
|
|
||||||
brandId?: number
|
|
||||||
sort?: string
|
|
||||||
}
|
|
||||||
|
|
||||||
export const fetcher: HookFetcher<SearchProductsData, SearchProductsInput> = (
|
|
||||||
options,
|
|
||||||
{ search, categoryId, brandId, sort },
|
|
||||||
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 (Number.isInteger(categoryId))
|
|
||||||
url.searchParams.set('category', String(categoryId))
|
|
||||||
if (Number.isInteger(brandId)) url.searchParams.set('brand', String(brandId))
|
|
||||||
if (sort) url.searchParams.set('sort', sort)
|
|
||||||
|
|
||||||
return fetch({
|
|
||||||
url: url.pathname + url.search,
|
|
||||||
method: options?.method ?? defaultOpts.method,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
export function extendHook(
|
|
||||||
customFetcher: typeof fetcher,
|
|
||||||
swrOptions?: SwrOptions<SearchProductsData, SearchProductsInput>
|
|
||||||
) {
|
|
||||||
const useSearch = (input: SearchProductsInput = {}) => {
|
|
||||||
const response = useCommerceSearch(
|
|
||||||
defaultOpts,
|
|
||||||
[
|
|
||||||
['search', input.search],
|
|
||||||
['categoryId', input.categoryId],
|
|
||||||
['brandId', input.brandId],
|
|
||||||
['sort', input.sort],
|
|
||||||
],
|
|
||||||
customFetcher,
|
|
||||||
{ revalidateOnFocus: false, ...swrOptions }
|
|
||||||
)
|
|
||||||
|
|
||||||
return response
|
|
||||||
}
|
|
||||||
|
|
||||||
useSearch.extend = extendHook
|
|
||||||
|
|
||||||
return useSearch
|
|
||||||
}
|
|
||||||
|
|
||||||
export default extendHook(fetcher)
|
|
||||||
|
@ -5,6 +5,7 @@ import type { FetchCartInput } from '@commerce/cart/use-cart'
|
|||||||
import { normalizeCart } from './lib/normalize'
|
import { normalizeCart } from './lib/normalize'
|
||||||
import type { Wishlist } from './api/wishlist'
|
import type { Wishlist } from './api/wishlist'
|
||||||
import type { Customer, CustomerData } from './api/customers'
|
import type { Customer, CustomerData } from './api/customers'
|
||||||
|
import type { SearchProductsData } from './api/catalog/products'
|
||||||
import useCustomer from './customer/use-customer'
|
import useCustomer from './customer/use-customer'
|
||||||
import type { Cart } from './types'
|
import type { Cart } from './types'
|
||||||
|
|
||||||
@ -153,6 +154,56 @@ const useCustomerHandler: HookHandler<
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type SearchProductsInput = {
|
||||||
|
search?: string
|
||||||
|
categoryId?: number
|
||||||
|
brandId?: number
|
||||||
|
sort?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const useSearch: HookHandler<
|
||||||
|
SearchProductsData,
|
||||||
|
SearchProductsInput,
|
||||||
|
SearchProductsInput,
|
||||||
|
any,
|
||||||
|
any
|
||||||
|
> = {
|
||||||
|
fetchOptions: {
|
||||||
|
url: '/api/bigcommerce/catalog/products',
|
||||||
|
method: 'GET',
|
||||||
|
},
|
||||||
|
fetcher({ input: { search, categoryId, brandId, sort }, options, fetch }) {
|
||||||
|
// 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 (Number.isInteger(categoryId))
|
||||||
|
url.searchParams.set('category', String(categoryId))
|
||||||
|
if (Number.isInteger(brandId))
|
||||||
|
url.searchParams.set('brand', String(brandId))
|
||||||
|
if (sort) url.searchParams.set('sort', sort)
|
||||||
|
|
||||||
|
return fetch({
|
||||||
|
url: url.pathname + url.search,
|
||||||
|
method: options.method,
|
||||||
|
})
|
||||||
|
},
|
||||||
|
useHook({ input, useData }) {
|
||||||
|
return useData({
|
||||||
|
input: [
|
||||||
|
['search', input.search],
|
||||||
|
['categoryId', input.categoryId],
|
||||||
|
['brandId', input.brandId],
|
||||||
|
['sort', input.sort],
|
||||||
|
],
|
||||||
|
swrOptions: {
|
||||||
|
revalidateOnFocus: false,
|
||||||
|
...input.swrOptions,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
export const bigcommerceProvider = {
|
export const bigcommerceProvider = {
|
||||||
locale: 'en-us',
|
locale: 'en-us',
|
||||||
cartCookie: 'bc_cartId',
|
cartCookie: 'bc_cartId',
|
||||||
@ -161,6 +212,7 @@ export const bigcommerceProvider = {
|
|||||||
cart: { useCart },
|
cart: { useCart },
|
||||||
wishlist: { useWishlist },
|
wishlist: { useWishlist },
|
||||||
customer: { useCustomer: useCustomerHandler },
|
customer: { useCustomer: useCustomerHandler },
|
||||||
|
products: { useSearch },
|
||||||
}
|
}
|
||||||
|
|
||||||
export type BigcommerceProvider = typeof bigcommerceProvider
|
export type BigcommerceProvider = typeof bigcommerceProvider
|
||||||
|
@ -8,7 +8,7 @@ import {
|
|||||||
} from 'react'
|
} from 'react'
|
||||||
import { Fetcher, HookHandler } from './utils/types'
|
import { Fetcher, HookHandler } from './utils/types'
|
||||||
import type { FetchCartInput } from './cart/use-cart'
|
import type { FetchCartInput } from './cart/use-cart'
|
||||||
import type { Cart, Wishlist, Customer } from './types'
|
import type { Cart, Wishlist, Customer, SearchProductsData } from './types'
|
||||||
|
|
||||||
const Commerce = createContext<CommerceContextValue<any> | {}>({})
|
const Commerce = createContext<CommerceContextValue<any> | {}>({})
|
||||||
|
|
||||||
@ -23,6 +23,9 @@ export type Provider = CommerceConfig & {
|
|||||||
customer: {
|
customer: {
|
||||||
useCustomer?: HookHandler<Customer | null, any, any>
|
useCustomer?: HookHandler<Customer | null, any, any>
|
||||||
}
|
}
|
||||||
|
products: {
|
||||||
|
useSearch?: HookHandler<SearchProductsData, any, any>
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export type CommerceProps<P extends Provider> = {
|
export type CommerceProps<P extends Provider> = {
|
||||||
|
@ -1,5 +1,57 @@
|
|||||||
import useData from '../utils/use-data'
|
import type { SearchProductsData } from '../types'
|
||||||
|
import type {
|
||||||
|
Prop,
|
||||||
|
HookFetcherFn,
|
||||||
|
UseHookInput,
|
||||||
|
UseHookResponse,
|
||||||
|
} from '../utils/types'
|
||||||
|
import defaultFetcher from '../utils/default-fetcher'
|
||||||
|
import useData from '../utils/use-data-2'
|
||||||
|
import { Provider, useCommerce } from '..'
|
||||||
|
import { BigcommerceProvider } from '@framework'
|
||||||
|
|
||||||
const useSearch = useData
|
export type UseSearchHandler<P extends Provider> = Prop<
|
||||||
|
Prop<P, 'products'>,
|
||||||
|
'useSearch'
|
||||||
|
>
|
||||||
|
|
||||||
export default useSearch
|
export type UseSeachInput<P extends Provider> = UseHookInput<
|
||||||
|
UseSearchHandler<P>
|
||||||
|
>
|
||||||
|
|
||||||
|
export type SearchResponse<P extends Provider> = UseHookResponse<
|
||||||
|
UseSearchHandler<P>
|
||||||
|
>
|
||||||
|
|
||||||
|
export type UseSearch<P extends Provider> = Partial<
|
||||||
|
UseSeachInput<P>
|
||||||
|
> extends UseSeachInput<P>
|
||||||
|
? (input?: UseSeachInput<P>) => SearchResponse<P>
|
||||||
|
: (input: UseSeachInput<P>) => SearchResponse<P>
|
||||||
|
|
||||||
|
export const fetcher = defaultFetcher as HookFetcherFn<SearchProductsData>
|
||||||
|
|
||||||
|
export default function useSearch<P extends Provider>(
|
||||||
|
input: UseSeachInput<P> = {}
|
||||||
|
) {
|
||||||
|
const { providerRef, fetcherRef } = useCommerce<P>()
|
||||||
|
|
||||||
|
const provider = providerRef.current
|
||||||
|
const opts = provider.products?.useSearch
|
||||||
|
|
||||||
|
const fetcherFn = opts?.fetcher ?? fetcher
|
||||||
|
const useHook = opts?.useHook ?? ((ctx) => ctx.useData())
|
||||||
|
|
||||||
|
return useHook({
|
||||||
|
input,
|
||||||
|
useData(ctx) {
|
||||||
|
const response = useData(
|
||||||
|
{ ...opts!, fetcher: fetcherFn },
|
||||||
|
ctx?.input ?? [],
|
||||||
|
provider.fetcher ?? fetcherRef.current,
|
||||||
|
ctx?.swrOptions ?? input.swrOptions
|
||||||
|
)
|
||||||
|
return response
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import type { Wishlist as BCWishlist } from '@framework/api/wishlist'
|
import type { Wishlist as BCWishlist } from '@framework/api/wishlist'
|
||||||
import type { Customer as BCCustomer } from '@framework/api/customers'
|
import type { Customer as BCCustomer } from '@framework/api/customers'
|
||||||
|
import type { SearchProductsData as BCSearchProductsData } from '@framework/api/catalog/products'
|
||||||
|
|
||||||
export interface Discount {
|
export interface Discount {
|
||||||
// The value of the discount, can be an amount or percentage
|
// The value of the discount, can be an amount or percentage
|
||||||
@ -96,6 +97,9 @@ export interface Wishlist extends BCWishlist {}
|
|||||||
// TODO: Properly define this type
|
// TODO: Properly define this type
|
||||||
export interface Customer extends BCCustomer {}
|
export interface Customer extends BCCustomer {}
|
||||||
|
|
||||||
|
// TODO: Properly define this type
|
||||||
|
export interface SearchProductsData extends BCSearchProductsData {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cart mutations
|
* Cart mutations
|
||||||
*/
|
*/
|
||||||
|
Loading…
x
Reference in New Issue
Block a user