Allow placeholder images for products and line items without images

This commit is contained in:
tniezg 2021-08-25 11:34:22 +02:00
parent 448100290d
commit be0e246699
5 changed files with 49 additions and 2 deletions

View File

@ -14,3 +14,5 @@ NEXT_PUBLIC_SPREE_CATEGORIES_TAXONOMY_ID=1
NEXT_PUBLIC_SPREE_BRANDS_TAXONOMY_ID=27
NEXT_PUBLIC_SPREE_SHOW_SINGLE_VARIANT_OPTIONS=false
NEXT_PUBLIC_SPREE_LAST_UPDATED_PRODUCTS_PRERENDER_COUNT=10
NEXT_PUBLIC_SPREE_PRODUCT_PLACEHOLDER_IMAGE_URL=/product-img-placeholder.svg
NEXT_PUBLIC_SPREE_LINE_ITEM_PLACEHOLDER_IMAGE_URL=/product-img-placeholder.svg

View File

@ -1,6 +1,7 @@
import forceIsomorphicConfigValues from './utils/force-isomorphic-config-values'
import requireConfig from './utils/require-config'
import validateCookieExpire from './utils/validate-cookie-expire'
import validatePlaceholderImageUrl from './utils/validate-placeholder-image-url'
import validateProductsPrerenderCount from './utils/validate-products-prerender-count'
const isomorphicConfig = {
@ -18,6 +19,12 @@ const isomorphicConfig = {
lastUpdatedProductsPrerenderCount: validateProductsPrerenderCount(
process.env.NEXT_PUBLIC_SPREE_LAST_UPDATED_PRODUCTS_PRERENDER_COUNT
),
productPlaceholderImageUrl: validatePlaceholderImageUrl(
process.env.NEXT_PUBLIC_SPREE_PRODUCT_PLACEHOLDER_IMAGE_URL
),
lineItemPlaceholderImageUrl: validatePlaceholderImageUrl(
process.env.NEXT_PUBLIC_SPREE_LINE_ITEM_PLACEHOLDER_IMAGE_URL
),
}
export default forceIsomorphicConfigValues(
@ -33,6 +40,8 @@ export default forceIsomorphicConfigValues(
'brandsTaxonomyId',
'showSingleVariantOptions',
'lastUpdatedProductsPrerenderCount',
'productPlaceholderImageUrl',
'lineItemPlaceholderImageUrl',
]
)

View File

@ -21,6 +21,11 @@ import type {
OptionTypeAttr,
VariantAttr,
} from '@framework/types'
import type { Image } from '@commerce/types/common'
const placeholderImage = requireConfigValue('lineItemPlaceholderImageUrl') as
| string
| false
const isColorProductOption = (productOptionType: OptionTypeAttr) => {
return productOptionType.attributes.presentation === 'Color'
@ -74,6 +79,10 @@ const normalizeVariant = (
lineItemImage = productImage
}
const image: Image =
lineItemImage ??
(placeholderImage === false ? undefined : { url: placeholderImage })
return {
id: spreeVariant.id,
sku: spreeVariant.attributes.sku,
@ -81,7 +90,7 @@ const normalizeVariant = (
requiresShipping: true,
price: parseFloat(spreeVariant.attributes.price),
listPrice: parseFloat(spreeVariant.attributes.price),
image: lineItemImage,
image,
isInStock: spreeVariant.attributes.in_stock,
availableForSale: spreeVariant.attributes.purchasable,
...(spreeVariant.attributes.weight === '0.0'

View File

@ -1,5 +1,6 @@
import type {
Product,
ProductImage,
ProductOption,
ProductPrice,
ProductVariant,
@ -18,6 +19,10 @@ import { findIncluded, findIncludedOfType } from './find-json-api-documents'
import getProductPath from './get-product-path'
import MissingPrimaryVariantError from '@framework/errors/MissingPrimaryVariantError'
const placeholderImage = requireConfigValue('productPlaceholderImageUrl') as
| string
| false
const normalizeProduct = (
spreeSuccessResponse: JsonApiSingleResponse | JsonApiListResponse,
spreeProduct: ProductAttr
@ -44,11 +49,18 @@ const normalizeProduct = (
'images'
)
const images = getMediaGallery(
const productImages = getMediaGallery(
spreeImageRecords,
createGetAbsoluteImageUrl(requireConfigValue('imageHost') as string)
)
const images: ProductImage[] =
productImages.length === 0
? placeholderImage === false
? []
: [{ url: placeholderImage }]
: productImages
const price: ProductPrice = {
value: parseFloat(spreeProduct.attributes.price),
currencyCode: spreeProduct.attributes.currency,

View File

@ -0,0 +1,15 @@
const validatePlaceholderImageUrl = (
placeholderUrlOrFalse: unknown
): string | false => {
if (!placeholderUrlOrFalse || placeholderUrlOrFalse === 'false') {
return false
}
if (typeof placeholderUrlOrFalse === 'string') {
return placeholderUrlOrFalse
}
throw new TypeError('placeholderUrlOrFalse must be a string or falsy.')
}
export default validatePlaceholderImageUrl