categories as search results

This commit is contained in:
Dom Sip 2022-04-07 20:48:46 +01:00
parent d7de7dc62e
commit ba873dfa1b
8 changed files with 110 additions and 21 deletions

View File

@ -1 +0,0 @@
export default function noopApi(...args: any[]): void {}

View File

@ -1 +0,0 @@
export default function noopApi(...args: any[]): void {}

View File

@ -0,0 +1,41 @@
import { normalizeSearchProducts } from '../../../utils/normalise-product';
import { ProductsEndpoint } from '.'
const getProducts: ProductsEndpoint['handlers']['getProducts'] = async ({
req,
res,
body: { search, categoryId, brandId, sort },
config
}) => {
const { sdk } = config;
let searchTerm = search;
if (categoryId) {
searchTerm = categoryId as string
}
const searchClient = await sdk.getSearchClient();
// use SDK search API for initial products
const searchResults = await searchClient.productSearch({
parameters: {
q: searchTerm,
limit: 20
}
});
let products = [];
let found = false;
if (searchResults.total) {
found = true;
products = normalizeSearchProducts(searchResults.hits) as any[];
} else {
// TODO: handle this better?
console.log("No results for search");
}
res.status(200).json({ data: { products, found } })
}
export default getProducts

View File

@ -0,0 +1,19 @@
import type { SFCCProviderAPI } from '../../..'
import { createEndpoint, GetAPISchema } from '@vercel/commerce/api'
import { ProductsSchema } from '@vercel/commerce/types/product'
import getProducts from './get-products'
import productsEndpoint from '@vercel/commerce/api/endpoints/catalog/products'
export type ProductsAPI = GetAPISchema<SFCCProviderAPI, ProductsSchema>
export type ProductsEndpoint = ProductsAPI['endpoint']
export const handlers: ProductsEndpoint['handlers'] = { getProducts }
const productsApi = createEndpoint<ProductsAPI>({
handler: productsEndpoint,
handlers,
})
export default productsApi

View File

@ -3,7 +3,7 @@
"features": { "features": {
"wishlist": false, "wishlist": false,
"cart": false, "cart": false,
"search": false, "search": true,
"customerAuth": false, "customerAuth": false,
"customCheckout": false "customCheckout": false
} }

View File

@ -1,11 +1,17 @@
import { Fetcher } from '@vercel/commerce/utils/types' import { Fetcher } from '@vercel/commerce/utils/types'
export const fetcher: Fetcher = async () => { const clientFetcher: Fetcher = async ({ method, url, body }) => {
console.log('FETCHER') const response = await fetch(url!, {
const res = await fetch('./data.json') method,
if (res.ok) { body: body ? JSON.stringify(body) : undefined,
const { data } = await res.json() headers: {
return data 'Content-Type': 'application/json',
} },
throw res })
.then((response) => response.json())
.then((response) => response.data)
return response
} }
export default clientFetcher

View File

@ -1,17 +1,42 @@
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 { SearchProductsHook } from '@vercel/commerce/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 }) {}, fetcher({ input: { search, categoryId, brandId, sort }, options, fetch }) {
useHook: () => () => { console.log('search', search, categoryId, options)
return { // Use a dummy base as we only care about the relative path
data: { const url = new URL(options.url!, 'http://a')
products: [],
}, if (search) url.searchParams.set('search', String(search))
} if (categoryId) url.searchParams.set('categoryId', String(categoryId))
if (brandId) url.searchParams.set('brandId', String(brandId))
if (sort) url.searchParams.set('sort', String(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,
},
})
},
} }

View File

@ -1,4 +1,4 @@
import { fetcher } from './fetcher' import fetcher from './fetcher'
import { handler as useCart } from './cart/use-cart' import { handler as useCart } from './cart/use-cart'
import { handler as useAddItem } from './cart/use-add-item' import { handler as useAddItem } from './cart/use-add-item'
import { handler as useUpdateItem } from './cart/use-update-item' import { handler as useUpdateItem } from './cart/use-update-item'