diff --git a/assets/base.css b/assets/base.css index dfdaf1475..e63ea1aa4 100644 --- a/assets/base.css +++ b/assets/base.css @@ -127,4 +127,3 @@ a { opacity: 1; } } - diff --git a/assets/components.css b/assets/components.css index 8c4c5a357..ebebcc238 100644 --- a/assets/components.css +++ b/assets/components.css @@ -1,3 +1,3 @@ .fit { min-height: calc(100vh - 88px); -} \ No newline at end of file +} diff --git a/framework/commerce/types.ts b/framework/commerce/types.ts index 7bf44e774..b36a3c26c 100644 --- a/framework/commerce/types.ts +++ b/framework/commerce/types.ts @@ -111,8 +111,8 @@ export type CartItemBody = { productId?: string quantity?: number pricing?: { - amount: number, - currencyCode: string, + amount: number + currencyCode: string } } diff --git a/framework/reactioncommerce/utils/normalize.ts b/framework/reactioncommerce/utils/normalize.ts index 982444f08..8aec1717e 100644 --- a/framework/reactioncommerce/utils/normalize.ts +++ b/framework/reactioncommerce/utils/normalize.ts @@ -1,4 +1,10 @@ -import {Product, Customer, ProductVariant, ProductOption, ProductOptionValues} from '@commerce/types' +import { + Product, + Customer, + ProductVariant, + ProductOption, + ProductOptionValues, +} from '@commerce/types' import { Account, @@ -11,12 +17,12 @@ import { CartItem, } from '../schema' -import type {Cart, LineItem} from '../types' +import type { Cart, LineItem } from '../types' const normalizeProductImages = (images: ImageInfo[], name: string) => images.map((image) => ({ url: image?.URLs?.original || image?.URLs?.medium || '', - alt: name + alt: name, })) const normalizeProductOption = (variant: CatalogProductVariant) => { @@ -24,104 +30,139 @@ const normalizeProductOption = (variant: CatalogProductVariant) => { __typename: 'MultipleChoiceOption', id: variant._id, displayName: variant.attributeLabel, - values: variant.optionTitle ? [{label: variant.optionTitle}] : [] + values: variant.optionTitle ? [{ label: variant.optionTitle }] : [], } - option.values = option.values.map(value => colorizeProductOptionValue(value, option.displayName)) + option.values = option.values.map((value) => + colorizeProductOptionValue(value, option.displayName) + ) - return option; + return option } -function colorizeProductOptionValue(value: ProductOptionValues, displayName: string): ProductOptionValues { +function colorizeProductOptionValue( + value: ProductOptionValues, + displayName: string +): ProductOptionValues { if (displayName.toLowerCase() === 'color') { value.hexColors = [value.label] } - return value; + return value } -const normalizeProductVariants = (variants: Array): ProductVariant[] => { - console.log(variants); - return variants.reduce((productVariants: ProductVariant[], variant: CatalogProductVariant) => { +const normalizeProductVariants = ( + variants: Array +): ProductVariant[] => { + return variants.reduce( + (productVariants: ProductVariant[], variant: CatalogProductVariant) => { + if (variantHasOptions(variant)) { + productVariants.push(...flatVariantOptions(variant)) + return productVariants + } - if (variantHasOptions(variant)) { - productVariants.push(...flatVariantOptions(variant)) - return productVariants - } + const { sku, title, pricing = [], variantId } = variant ?? {} + const variantPrice = pricing[0]?.price ?? pricing[0]?.minPrice ?? 0 - const {sku, title, pricing = [], variantId} = variant ?? {} - const variantPrice = pricing[0]?.price ?? pricing[0]?.minPrice ?? 0 - - productVariants.push({ - id: variantId ?? '', - name: title, - sku: sku ?? variantId, - price: variantPrice, - listPrice: pricing[0]?.compareAtPrice?.amount ?? variantPrice, - requiresShipping: true, - options: [normalizeProductOption(variant)] - }); - - return productVariants; - }, []) -} - -function groupProductOptionsByAttributeLabel(variants: CatalogProductVariant[]): ProductOption[] { - return variants.reduce((groupedOptions: ProductOption[], currentVariant: CatalogProductVariant) => { - - groupedOptions = mergeVariantOptionsWithExistingOptions(groupedOptions, currentVariant); - - if (variantHasOptions(currentVariant)) { - (currentVariant.options).forEach(variantOption => { - groupedOptions = mergeVariantOptionsWithExistingOptions(groupedOptions, variantOption) + productVariants.push({ + id: variantId ?? '', + name: title, + sku: sku ?? variantId, + price: variantPrice, + listPrice: pricing[0]?.compareAtPrice?.amount ?? variantPrice, + requiresShipping: true, + options: [normalizeProductOption(variant)], }) - } - return groupedOptions - }, []) + return productVariants + }, + [] + ) +} - function mergeVariantOptionsWithExistingOptions( - groupedOptions: ProductOption[], - currentVariant: CatalogProductVariant): ProductOption[] { +function groupProductOptionsByAttributeLabel( + variants: CatalogProductVariant[] +): ProductOption[] { + return variants.reduce( + ( + groupedOptions: ProductOption[], + currentVariant: CatalogProductVariant + ) => { + groupedOptions = mergeVariantOptionsWithExistingOptions( + groupedOptions, + currentVariant + ) - const matchingOptionIndex = findCurrentVariantOptionsInGroupedOptions(groupedOptions, currentVariant) + if (variantHasOptions(currentVariant)) { + (currentVariant.options).forEach( + (variantOption) => { + groupedOptions = mergeVariantOptionsWithExistingOptions( + groupedOptions, + variantOption + ) + } + ) + } - return matchingOptionIndex !== -1 ? - mergeWithExistingOptions(groupedOptions, currentVariant, matchingOptionIndex) : - addNewProductOption(groupedOptions, currentVariant) - } + return groupedOptions + }, + [] + ) +} - function findCurrentVariantOptionsInGroupedOptions( - groupedOptions: ProductOption[], - currentVariant: CatalogProductVariant): number { +function mergeVariantOptionsWithExistingOptions( + groupedOptions: ProductOption[], + currentVariant: CatalogProductVariant +): ProductOption[] { + const matchingOptionIndex = findCurrentVariantOptionsInGroupedOptions( + groupedOptions, + currentVariant + ) - return groupedOptions.findIndex(option => - (option.displayName.toLowerCase() === currentVariant.attributeLabel.toLowerCase()) - ); - } + return matchingOptionIndex !== -1 + ? mergeWithExistingOptions( + groupedOptions, + currentVariant, + matchingOptionIndex + ) + : addNewProductOption(groupedOptions, currentVariant) +} - function mergeWithExistingOptions( - groupedOptions: ProductOption[], - currentVariant: CatalogProductVariant, - matchingOptionIndex: number) { +function findCurrentVariantOptionsInGroupedOptions( + groupedOptions: ProductOption[], + currentVariant: CatalogProductVariant +): number { + return groupedOptions.findIndex( + (option) => + option.displayName.toLowerCase() === + currentVariant.attributeLabel.toLowerCase() + ) +} - const currentVariantOption = normalizeProductOption(currentVariant); - groupedOptions[matchingOptionIndex].values = [ - ...groupedOptions[matchingOptionIndex].values, - ...currentVariantOption.values - ] +function mergeWithExistingOptions( + groupedOptions: ProductOption[], + currentVariant: CatalogProductVariant, + matchingOptionIndex: number +) { + const currentVariantOption = normalizeProductOption(currentVariant) + groupedOptions[matchingOptionIndex].values = [ + ...groupedOptions[matchingOptionIndex].values, + ...currentVariantOption.values, + ] - return groupedOptions; - } + return groupedOptions +} - function addNewProductOption(groupedOptions: ProductOption[], currentVariant: CatalogProductVariant) { - return [ - ...groupedOptions, - normalizeProductOption(currentVariant), - ]; - } +function addNewProductOption( + groupedOptions: ProductOption[], + currentVariant: CatalogProductVariant +) { + return [...groupedOptions, normalizeProductOption(currentVariant)] } export function normalizeProduct(productNode: CatalogItemProduct): Product { - const product = productNode.product as CatalogProduct + const product = productNode.product + if (!product) { + return {} + } const { _id, @@ -132,8 +173,8 @@ export function normalizeProduct(productNode: CatalogItemProduct): Product { sku, media, pricing, - variants - } = product + variants, + } = product return { id: productId ?? _id, @@ -142,14 +183,20 @@ export function normalizeProduct(productNode: CatalogItemProduct): Product { slug: slug?.replace(/^\/+|\/+$/g, '') ?? '', path: slug ?? '', sku: sku ?? '', - images: media?.length ? normalizeProductImages(media, title ?? '') : [], + images: media?.length + ? normalizeProductImages(media, title ?? '') + : [], vendor: product.vendor, price: { value: pricing[0]?.minPrice ?? 0, currencyCode: pricing[0]?.currency.code, }, - variants: !!variants ? normalizeProductVariants(variants) : [], - options: !!variants ? groupProductOptionsByAttributeLabel(variants) : [] + variants: !!variants + ? normalizeProductVariants(variants) + : [], + options: !!variants + ? groupProductOptionsByAttributeLabel(variants) + : [], } } @@ -163,7 +210,10 @@ export function normalizeCart(cart: ReactionCart): Cart { code: cart.checkout?.summary?.total?.currency.code ?? '', }, taxesIncluded: false, - lineItems: cart.items?.edges?.map(cartItem => normalizeLineItem(cartItem)) ?? [], + lineItems: + cart.items?.edges?.map((cartItem) => + normalizeLineItem(cartItem) + ) ?? [], lineItemsSubtotalPrice: +(cart.checkout?.summary?.itemTotal?.amount ?? 0), subtotalPrice: +(cart.checkout?.summary?.itemTotal?.amount ?? 0), totalPrice: cart.checkout?.summary?.total?.amount ?? 0, @@ -171,7 +221,13 @@ export function normalizeCart(cart: ReactionCart): Cart { } } -function normalizeLineItem(cartItem: CartItemEdge): LineItem { +function normalizeLineItem(cartItemEdge: CartItemEdge): LineItem { + const cartItem = cartItemEdge.node + + if (!cartItem) { + return {} + } + const { _id, compareAtPrice, @@ -181,10 +237,9 @@ function normalizeLineItem(cartItem: CartItemEdge): LineItem { priceWhenAdded, optionTitle, variantTitle, - quantity - } = cartItem.node + quantity, + } = cartItem - console.log('imageURLs', cartItem) return { id: _id, variantId: String(productConfiguration?.productVariantId), @@ -201,7 +256,7 @@ function normalizeLineItem(cartItem: CartItemEdge): LineItem { requiresShipping: true, price: priceWhenAdded?.amount, listPrice: compareAtPrice?.amount ?? 0, - options: [] + options: [], }, path: '', discounts: [], @@ -226,15 +281,14 @@ export function normalizeCustomer(viewer: Account): Customer { } function flatVariantOptions(variant: CatalogProductVariant): ProductVariant[] { - const variantOptions = variant.options; + const variantOptions = variant.options - return normalizeProductVariants(variantOptions) - .map(variantOption => { - variantOption.options.push(normalizeProductOption(variant)) - return variantOption - }); + return normalizeProductVariants(variantOptions).map((variantOption) => { + variantOption.options.push(normalizeProductOption(variant)) + return variantOption + }) } function variantHasOptions(variant: CatalogProductVariant) { - return !!variant.options && variant.options.length != 0; + return !!variant.options && variant.options.length != 0 }