Why Gemfury? Push, build, and install  RubyGems npm packages Python packages Maven artifacts PHP packages Go Modules Debian packages RPM packages NuGet packages

Repository URL to install this package:

Details    
Size: Mime:
import React from 'react'
import { isSafe, isFunction, isArray, EMPTY_OBJ, EMPTY_ARRAY } from 'exotic'
import { Incrementer } from '@skava/ui/dist/inputs/Incrementer'
import { Empty } from '@skava/ui/dist/components/atoms/Empty'
import {
  ProductItemProps,
  FavoriteArgs,
  PriceProps,
  RatingProps,
  QuantityProps,
  TotalPriceProps,
} from './typings'
import {
  ImageWrapper,
  StyledToggleFavorite,
  StyledLink,
  Wrapper,
  StyledImagePlaceholder,
  StyledDetailedList,
  StyledProductImage,
  StyledBrandName,
  PriceWrapper,
  SalePrice,
  RegularPrice,
  StyledProductName,
  ProductWrapper,
  ProductDetailWrapper,
  StyledRatings,
  StyledQuantityValue,
  StyledText,
  IncrementerWrapper,
  TotalText,
  SaveText,
  TotalWrapper,
  StyledPromoText,
  StyledPromoWrapper,
} from './styled'

/** renderProp to render Brand Name */
function defaultRenderBrandName(props: ProductItemProps) {
  const { brandName = 'Brand Name', type } = props
  const productType = isSafe(type) && type !== '' ? type : 'vertical'

  return (
    isSafe(brandName) && (
      <StyledBrandName
        content={brandName}
        breedType={'h3'}
        type={productType}
      />
    )
  )
}

/** renderProp to render Product Name */
function defaultRenderProductName(props: ProductItemProps) {
  const { name = 'Product Name', url, identifier } = props
  const productUrl = isSafe(url) ? url : `/product/${identifier}`
  return (
    isSafe(name) && (
      <StyledLink target={'_self'} to={productUrl}>
        <StyledProductName content={name} breedType={'h4'} />
      </StyledLink>
    )
  )
}

/** renderProp to render Product Price */
function defaultRenderPrice(props: ProductItemProps) {
  const { price = EMPTY_OBJ as PriceProps, type } = props
  const productType = isSafe(type) && type !== '' ? type : 'vertical'
  const { salePrice, regPrice } = price

  const isOnlyPrice = !isSafe(salePrice) || !isSafe(regPrice)
  const isEqualPrice =
    isSafe(salePrice) && isSafe(regPrice) && salePrice === regPrice

  const priceView = (
    <PriceWrapper type={productType}>
      {isSafe(salePrice) && (
        <SalePrice aria-label="sale-price">{salePrice}</SalePrice>
      )}
      {isSafe(regPrice) && isEqualPrice === false && (
        <RegularPrice aria-label="regular-price" isOnlyPrice={isOnlyPrice}>
          {regPrice}
        </RegularPrice>
      )}
    </PriceWrapper>
  )
  return priceView
}

/** renderProp to render Product rating */
function defaultRenderRatings(props: ProductItemProps) {
  const { rating = EMPTY_OBJ as RatingProps } = props
  const { value, reviewCount } = rating
  const shouldShowCount = isSafe(reviewCount)

  return (
    isSafe(value) && (
      <StyledRatings
        starRating={value}
        shouldShowCount={shouldShowCount}
        userRating={reviewCount}
        width={12}
      />
    )
  )
}

/** renderProp to render Product Facet */
function defaultRenderFacetDetails(props: ProductItemProps) {
  const { facet = EMPTY_OBJ } = props
  return isArray(facet) && <StyledDetailedList list={facet} />
}

/** renderProp to render Product promo */
function defaultRenderPromoDetails(props: ProductItemProps) {
  const { promoOffer = EMPTY_ARRAY, onPromoOfferClick } = props
  const promoView = (
    <StyledPromoWrapper>
      {promoOffer.map((promo, index) => {
        const { name } = promo
        const handlePromoOffer = () => {
          if (isFunction(onPromoOfferClick)) {
            const changeArgs = {
              ...promo,
            }
            onPromoOfferClick(changeArgs)
          }
        }
        return (
          <StyledPromoText key={index} onClick={handlePromoOffer}>
            {name}
          </StyledPromoText>
        )
      })}
    </StyledPromoWrapper>
  )
  return promoView
}

/** renderProp to render Quantity */
function defaultRenderQuantity(props: ProductItemProps) {
  const {
    quantity = EMPTY_OBJ as QuantityProps,
    onQuantityChange,
    type,
  } = props
  const productType = isSafe(type) && type !== '' ? type : 'vertical'
  const { value, isIncrementer = false } = quantity

  const handleQuantityChange = args => {
    if (isFunction(onQuantityChange)) {
      onQuantityChange(args)
    }
  }

  const view =
    productType === 'checkout' && isIncrementer === true ? (
      <Incrementer count={value} onValueChange={handleQuantityChange} />
    ) : (
      isSafe(value) && (
        <React.Fragment>
          <StyledText type={productType}>{'Quantity:'}</StyledText>
          <StyledQuantityValue>{value}</StyledQuantityValue>
        </React.Fragment>
      )
    )
  return <IncrementerWrapper type={productType}>{view}</IncrementerWrapper>
}

/** renderProp to render Product Total */
function defaultRenderTotal(props: ProductItemProps) {
  const { totalPriceDetails = EMPTY_OBJ as TotalPriceProps, type } = props
  const productType = isSafe(type) && type !== '' ? type : 'vertical'
  const { totalPrice, savePrice } = totalPriceDetails
  return (
    <TotalWrapper type={productType}>
      {isSafe(totalPrice) && (
        <TotalText>
          <StyledText type={productType}>{'Total:'}</StyledText>
          {totalPrice}
        </TotalText>
      )}
      {isSafe(savePrice) && (
        <SaveText>
          {'You save '}
          {savePrice}
        </SaveText>
      )}
    </TotalWrapper>
  )
}

/** renderProp to render Product Details */
function defaultRenderProductDetailsBox(props: ProductItemProps) {
  const {
    renderProductName,
    renderBrandName,
    renderPrice,
    renderRatings,
    renderFacetDetails,
    renderQuantity,
    productDetailsOrder = [],
    renderPromoDetails,
    ...remainingProps
  } = props

  const productType =
    isSafe(props.type) && props.type !== '' ? props.type : 'vertical'

  const mapNameToFunction = {
    brandName: isFunction(renderBrandName) && renderBrandName(remainingProps),
    productName:
      isFunction(renderProductName) && renderProductName(remainingProps),
    promoOffer:
      isFunction(renderPromoDetails) && renderPromoDetails(remainingProps),
    price:
      isFunction(renderPrice) &&
      (productType === 'vertical' || productType === 'horizontal') &&
      renderPrice(remainingProps),
    facet: isFunction(renderFacetDetails) && renderFacetDetails(remainingProps),
    rating: isFunction(renderRatings) && renderRatings(remainingProps),
    quantity:
      isFunction(renderQuantity) &&
      (productType === 'vertical' || productType === 'horizontal') &&
      renderQuantity(remainingProps),
  }

  const view = (
    <React.Fragment>
      {productDetailsOrder.map(name => {
        return isSafe(mapNameToFunction[name]) ? (
          mapNameToFunction[name]
        ) : (
          <Empty />
        )
      })}
    </React.Fragment>
  )
  return view
}

/** renderProp to render Image */
function defaultRenderImage(props: ProductItemProps) {
  const {
    image,
    url,
    identifier,
    onFavoriteClick,
    hasFavoriteIcon = false,
    isFavoriteActive = false,
    name,
    productCaption = '',
  } = props

  const onClick = (args: Partial<FavoriteArgs>) => {
    if (isFunction(onFavoriteClick)) {
      const changeArgs = {
        identifier,
        ...args,
      }
      onFavoriteClick(changeArgs)
    }
  }

  const productUrl = isSafe(url) ? url : `/product/${identifier}`
  const productType =
    isSafe(props.type) && props.type !== '' ? props.type : 'vertical'

  const imageView = isSafe(image) ? (
    <ImageWrapper type={productType}>
      {hasFavoriteIcon === true && (
        <StyledToggleFavorite
          iconType={'heart'}
          isSelected={isFavoriteActive}
          onToggle={onClick}
        />
      )}
      <StyledLink target={'_self'} to={productUrl}>
        <StyledProductImage
          src={image}
          caption={productCaption}
          alt={name}
          type={productType}
        />
      </StyledLink>
    </ImageWrapper>
  ) : (
    <StyledImagePlaceholder type={productType} />
  )

  return imageView
}

/** renderProp to render Layout */
function defaultRenderBox(props: ProductItemProps) {
  const {
    renderImage,
    renderProductDetailsBox,
    renderCheckoutQuantity,
    renderTotal,
    ...remainingProps
  } = props

  const productType =
    isSafe(props.type) && props.type !== '' ? props.type : 'vertical'

  const view = (
    <React.Fragment>
      {isFunction(renderImage) && renderImage(remainingProps)}
      <ProductWrapper type={productType}>
        <ProductDetailWrapper>
          {isFunction(renderProductDetailsBox) &&
            renderProductDetailsBox(remainingProps)}
        </ProductDetailWrapper>
        {props.type === 'checkout' && (
          <React.Fragment>
            {isFunction(defaultRenderQuantity) &&
              defaultRenderQuantity(remainingProps)}
            {isFunction(props.renderPrice) && props.renderPrice(remainingProps)}
            {isFunction(renderTotal) && renderTotal(remainingProps)}
          </React.Fragment>
        )}
      </ProductWrapper>
    </React.Fragment>
  )
  return view
}

/** renderProp to render Wrapper */
function defaultRenderWrapper(props: ProductItemProps) {
  const { className, children, type, dataQa } = props
  const productType = isSafe(type) && type !== '' ? type : 'vertical'
  const passThroughProps = {
    type: productType,
    className,
    'data-qa': dataQa,
  }
  return <Wrapper {...passThroughProps}>{children}</Wrapper>
}

export {
  defaultRenderTotal,
  defaultRenderPromoDetails,
  defaultRenderQuantity,
  defaultRenderFacetDetails,
  defaultRenderRatings,
  defaultRenderProductName,
  defaultRenderBrandName,
  defaultRenderPrice,
  defaultRenderProductDetailsBox,
  defaultRenderImage,
  defaultRenderBox,
  defaultRenderWrapper,
}