Fetch Spree Categories and Brands

This commit is contained in:
tniezg 2021-07-28 15:57:37 +02:00
parent c546d26bbe
commit 2209731d72
4 changed files with 113 additions and 40 deletions

View File

@ -8,3 +8,5 @@ NEXT_PUBLIC_SPREE_DEFAULT_LOCALE=en-us
NEXT_PUBLIC_SPREE_CART_COOKIE_NAME=spree_cart NEXT_PUBLIC_SPREE_CART_COOKIE_NAME=spree_cart
NEXT_PUBLIC_SPREE_IMAGE_HOST=http://localhost:3000 NEXT_PUBLIC_SPREE_IMAGE_HOST=http://localhost:3000
NEXT_PUBLIC_SPREE_ALLOWED_IMAGE_DOMAIN=localhost NEXT_PUBLIC_SPREE_ALLOWED_IMAGE_DOMAIN=localhost
NEXT_PUBLIC_SPREE_CATEGORIES_TAXONOMY_ID=1
NEXT_PUBLIC_SPREE_BRANDS_TAXONOMY_ID=27

View File

@ -1,6 +1,12 @@
import { OperationContext } from '@commerce/api/operations' import type {
import { Category } from '@commerce/types/site' OperationContext,
import { LocalConfig } from '../index' OperationOptions,
} from '@commerce/api/operations'
import type { Category, GetSiteInfoOperation } from '@commerce/types/site'
import type { ITaxons } from '@spree/storefront-api-v2-sdk/types/interfaces/Taxon'
import { requireConfigValue } from 'framework/spree/isomorphicConfig'
import type { SpreeSdkVariables } from 'framework/spree/types'
import type { SpreeApiConfig, SpreeApiProvider } from '..'
export type GetSiteInfoResult< export type GetSiteInfoResult<
T extends { categories: any[]; brands: any[] } = { T extends { categories: any[]; brands: any[] } = {
@ -9,35 +15,98 @@ export type GetSiteInfoResult<
} }
> = T > = T
export default function getSiteInfoOperation({}: OperationContext<any>) { export default function getSiteInfoOperation({
// TODO: Get Spree categories for display in React components. commerce,
function getSiteInfo({ }: OperationContext<SpreeApiProvider>) {
async function getSiteInfo<T extends GetSiteInfoOperation>(opts?: {
config?: Partial<SpreeApiConfig>
preview?: boolean
}): Promise<T['data']>
async function getSiteInfo<T extends GetSiteInfoOperation>(
opts: {
config?: Partial<SpreeApiConfig>
preview?: boolean
} & OperationOptions
): Promise<T['data']>
async function getSiteInfo<T extends GetSiteInfoOperation>({
query, query,
variables, variables: getSiteInfoVariables = {},
config: cfg, config: userConfig,
}: { }: {
query?: string query?: string
variables?: any variables?: any
config?: Partial<LocalConfig> config?: Partial<SpreeApiConfig>
preview?: boolean preview?: boolean
} = {}): Promise<GetSiteInfoResult> { } = {}): Promise<GetSiteInfoResult> {
return Promise.resolve({ console.info(
categories: [ 'getSiteInfo called. Configuration: ',
'query: ',
query,
'getSiteInfoVariables ',
getSiteInfoVariables,
'config: ',
userConfig
)
// Fetch first and level taxons
const createVariables = (parentId: string): SpreeSdkVariables => ({
methodPath: 'taxons.list',
arguments: [
{ {
id: 'new-arrivals', filter: {
name: 'New Arrivals', parent_id: parentId,
slug: 'new-arrivals', },
path: '/new-arrivals',
},
{
id: 'featured',
name: 'Featured',
slug: 'featured',
path: '/featured',
}, },
], ],
brands: [],
}) })
const config = commerce.getConfig(userConfig)
const { fetch: apiFetch } = config // TODO: Send config.locale to Spree.
const { data: spreeCategoriesSuccessResponse } = await apiFetch<ITaxons>(
'__UNUSED__',
{
variables: createVariables(
requireConfigValue('spreeCategoriesTaxonomyId')
),
}
)
const { data: spreeBrandsSuccessResponse } = await apiFetch<ITaxons>(
'__UNUSED__',
{
variables: createVariables(requireConfigValue('spreeBrandsTaxonomyId')),
}
)
const normalizedCategories: GetSiteInfoOperation['data']['categories'] =
spreeCategoriesSuccessResponse.data.map((spreeTaxon) => {
return {
id: spreeTaxon.id,
name: spreeTaxon.attributes.name,
slug: spreeTaxon.id,
path: spreeTaxon.id,
}
})
const normalizedBrands: GetSiteInfoOperation['data']['brands'] =
spreeBrandsSuccessResponse.data.map((spreeTaxon) => {
return {
node: {
entityId: spreeTaxon.id,
path: `brands/${spreeTaxon.id}`,
name: spreeTaxon.attributes.name,
},
}
})
return {
categories: normalizedCategories,
brands: normalizedBrands,
}
} }
return getSiteInfo return getSiteInfo

View File

@ -6,12 +6,22 @@ const isomorphicConfig = {
defaultLocale: process.env.NEXT_PUBLIC_SPREE_DEFAULT_LOCALE, defaultLocale: process.env.NEXT_PUBLIC_SPREE_DEFAULT_LOCALE,
cartCookieName: process.env.NEXT_PUBLIC_SPREE_CART_COOKIE_NAME, cartCookieName: process.env.NEXT_PUBLIC_SPREE_CART_COOKIE_NAME,
spreeImageHost: process.env.NEXT_PUBLIC_SPREE_IMAGE_HOST, spreeImageHost: process.env.NEXT_PUBLIC_SPREE_IMAGE_HOST,
spreeCategoriesTaxonomyId:
process.env.NEXT_PUBLIC_SPREE_CATEGORIES_TAXONOMY_ID,
spreeBrandsTaxonomyId: process.env.NEXT_PUBLIC_SPREE_BRANDS_TAXONOMY_ID,
} }
export default forceIsomorphicConfigValues( export default forceIsomorphicConfigValues(
isomorphicConfig, isomorphicConfig,
[], [],
['spreeApiHost', 'defaultLocale', 'cartCookieName', 'spreeImageHost'] [
'spreeApiHost',
'defaultLocale',
'cartCookieName',
'spreeImageHost',
'spreeCategoriesTaxonomyId',
'spreeBrandsTaxonomyId',
]
) )
type IsomorphicConfig = typeof isomorphicConfig type IsomorphicConfig = typeof isomorphicConfig

View File

@ -23,15 +23,16 @@ export const handler: SWRHook<SearchProductsHook> = {
options options
) )
const categoryOrBrandId = input.categoryId || input.brandId const taxons = [input.categoryId, input.brandId].filter(Boolean)
const filter = categoryOrBrandId const filter =
? { taxons.length > 0
filter: { ? {
taxons: categoryOrBrandId, filter: {
}, taxons: taxons.join(','),
} },
: {} }
: {}
const { data: spreeSuccessResponse } = await fetch< const { data: spreeSuccessResponse } = await fetch<
GraphQLFetcherResult<IProducts> GraphQLFetcherResult<IProducts>
@ -81,15 +82,6 @@ export const handler: SWRHook<SearchProductsHook> = {
}, },
}) })
}, },
// (input = {}) => {
// return {
// data: {
// // FIXME: Use actual fetcher
// products: [],
// },
// }
// },
} }
export default useSearch as UseSearch<typeof handler> export default useSearch as UseSearch<typeof handler>