From 2209731d72785f3107c0dd49ad770fe0c61037b7 Mon Sep 17 00:00:00 2001 From: tniezg Date: Wed, 28 Jul 2021 15:57:37 +0200 Subject: [PATCH] Fetch Spree Categories and Brands --- framework/spree/.env.template | 2 + .../spree/api/operations/get-site-info.ts | 113 ++++++++++++++---- framework/spree/isomorphicConfig.ts | 12 +- framework/spree/product/use-search.tsx | 26 ++-- 4 files changed, 113 insertions(+), 40 deletions(-) diff --git a/framework/spree/.env.template b/framework/spree/.env.template index 42de48b17..82a00d7be 100644 --- a/framework/spree/.env.template +++ b/framework/spree/.env.template @@ -8,3 +8,5 @@ NEXT_PUBLIC_SPREE_DEFAULT_LOCALE=en-us NEXT_PUBLIC_SPREE_CART_COOKIE_NAME=spree_cart NEXT_PUBLIC_SPREE_IMAGE_HOST=http://localhost:3000 NEXT_PUBLIC_SPREE_ALLOWED_IMAGE_DOMAIN=localhost +NEXT_PUBLIC_SPREE_CATEGORIES_TAXONOMY_ID=1 +NEXT_PUBLIC_SPREE_BRANDS_TAXONOMY_ID=27 diff --git a/framework/spree/api/operations/get-site-info.ts b/framework/spree/api/operations/get-site-info.ts index 159fb6004..d211968af 100644 --- a/framework/spree/api/operations/get-site-info.ts +++ b/framework/spree/api/operations/get-site-info.ts @@ -1,6 +1,12 @@ -import { OperationContext } from '@commerce/api/operations' -import { Category } from '@commerce/types/site' -import { LocalConfig } from '../index' +import type { + OperationContext, + 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< T extends { categories: any[]; brands: any[] } = { @@ -9,35 +15,98 @@ export type GetSiteInfoResult< } > = T -export default function getSiteInfoOperation({}: OperationContext) { - // TODO: Get Spree categories for display in React components. - function getSiteInfo({ +export default function getSiteInfoOperation({ + commerce, +}: OperationContext) { + async function getSiteInfo(opts?: { + config?: Partial + preview?: boolean + }): Promise + + async function getSiteInfo( + opts: { + config?: Partial + preview?: boolean + } & OperationOptions + ): Promise + + async function getSiteInfo({ query, - variables, - config: cfg, + variables: getSiteInfoVariables = {}, + config: userConfig, }: { query?: string variables?: any - config?: Partial + config?: Partial preview?: boolean } = {}): Promise { - return Promise.resolve({ - categories: [ + console.info( + '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', - name: 'New Arrivals', - slug: 'new-arrivals', - path: '/new-arrivals', - }, - { - id: 'featured', - name: 'Featured', - slug: 'featured', - path: '/featured', + filter: { + parent_id: parentId, + }, }, ], - brands: [], }) + + const config = commerce.getConfig(userConfig) + const { fetch: apiFetch } = config // TODO: Send config.locale to Spree. + + const { data: spreeCategoriesSuccessResponse } = await apiFetch( + '__UNUSED__', + { + variables: createVariables( + requireConfigValue('spreeCategoriesTaxonomyId') + ), + } + ) + + const { data: spreeBrandsSuccessResponse } = await apiFetch( + '__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 diff --git a/framework/spree/isomorphicConfig.ts b/framework/spree/isomorphicConfig.ts index 650125842..e472fdefe 100644 --- a/framework/spree/isomorphicConfig.ts +++ b/framework/spree/isomorphicConfig.ts @@ -6,12 +6,22 @@ const isomorphicConfig = { defaultLocale: process.env.NEXT_PUBLIC_SPREE_DEFAULT_LOCALE, cartCookieName: process.env.NEXT_PUBLIC_SPREE_CART_COOKIE_NAME, 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( isomorphicConfig, [], - ['spreeApiHost', 'defaultLocale', 'cartCookieName', 'spreeImageHost'] + [ + 'spreeApiHost', + 'defaultLocale', + 'cartCookieName', + 'spreeImageHost', + 'spreeCategoriesTaxonomyId', + 'spreeBrandsTaxonomyId', + ] ) type IsomorphicConfig = typeof isomorphicConfig diff --git a/framework/spree/product/use-search.tsx b/framework/spree/product/use-search.tsx index f9d49df97..6b58c77f6 100644 --- a/framework/spree/product/use-search.tsx +++ b/framework/spree/product/use-search.tsx @@ -23,15 +23,16 @@ export const handler: SWRHook = { options ) - const categoryOrBrandId = input.categoryId || input.brandId + const taxons = [input.categoryId, input.brandId].filter(Boolean) - const filter = categoryOrBrandId - ? { - filter: { - taxons: categoryOrBrandId, - }, - } - : {} + const filter = + taxons.length > 0 + ? { + filter: { + taxons: taxons.join(','), + }, + } + : {} const { data: spreeSuccessResponse } = await fetch< GraphQLFetcherResult @@ -81,15 +82,6 @@ export const handler: SWRHook = { }, }) }, - // (input = {}) => { - - // return { - // data: { - // // FIXME: Use actual fetcher - // products: [], - // }, - // } - // }, } export default useSearch as UseSearch