import React, { useState } from 'react'; import { useLanguage, useConfig, useOrder, useUtils, useSession, ToastType, useToast, SingleProductCard as SingleProductCardController } from 'ordering-components/native'; import { useTheme } from 'styled-components/native'; import { SingleProductCardParams } from '../../types'; import { CardInfo, SoldOut, QuantityContainer, PricesContainer, RibbonBox, LogoWrapper, TagsContainer } from './styles'; import { ScrollView, StyleSheet, TouchableWithoutFeedback, View } from 'react-native'; import { InView } from 'react-native-intersection-observer' import { Fade, Placeholder, PlaceholderLine } from 'rn-placeholder'; import { OButton, OIcon, OText } from '../shared'; import FastImage from 'react-native-fast-image' import { lightenDarkenColor, shape } from '../../utils'; import { LottieAnimation } from '../LottieAnimation'; import { CardAnimation } from '../shared/CardAnimation' function SingleProductCardPropsAreEqual(prevProps: any, nextProps: any) { return JSON.stringify(prevProps.product) === JSON.stringify(nextProps.product) && prevProps.isSoldOut === nextProps.isSoldOut && prevProps.productAddedToCartLength === nextProps.productAddedToCartLength && prevProps.categoryState === nextProps.categoryState } const SingleProductCardUI = React.memo((props: SingleProductCardParams) => { const { product, isSoldOut, onProductClick, productAddedToCartLength, style, handleFavoriteProduct, enableIntersection, navigation, businessId, isPreviously, viewString, businessSingleId } = props; const theme = useTheme(); const hideAddButton = theme?.business_view?.components?.products?.components?.add_to_cart_button?.hidden ?? true const isChewLayout = theme?.header?.components?.layout?.type?.toLowerCase() === 'chew' const hideProductDescription = theme?.business_view?.components?.products?.components?.product?.components?.description?.hidden const hideProductDummyLogo = theme?.business_view?.components?.products?.components?.product?.components?.dummy?.hidden const hideProductLogo = viewString ? theme?.[viewString]?.components?.cart?.components?.products?.image?.hidden : theme?.business_view?.components?.products?.components?.product?.components?.image?.hidden const textSize = isChewLayout ? 12 : 10 const logoPosition = theme?.business_view?.components?.products?.components?.product?.components?.image?.position const hideFavoriteIcon = theme?.business_view?.components?.products?.components?.product?.components?.favorite?.hidden const styles = StyleSheet.create({ container: { borderWidth: 1, borderColor: theme.colors.border, marginBottom: 25, minHeight: hideAddButton ? 100 : 165, flex: 1, flexDirection: hideAddButton ? 'row' : 'column', justifyContent: 'space-between', alignItems: 'center', padding: 12, borderRadius: 10, position: 'relative' }, titleWrapper: { flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between' }, line18: { lineHeight: 18, }, line15: { lineHeight: 15, }, soldOutBackgroundStyle: { backgroundColor: '#B8B8B8', }, soldOutTextStyle: { textTransform: 'uppercase', }, productStyle: { width: 85, height: 85, borderRadius: 7.6 }, quantityContainer: { position: 'absolute', right: 0, top: 0, width: 25, height: 25, textAlign: 'center', borderRadius: 25, alignItems: 'center' }, regularPriceStyle: { fontSize: 12, color: '#808080', textDecorationLine: 'line-through', marginLeft: 7, marginRight: 0 }, productTagsStyle: { width: 30, height: 30, marginRight: 5 } }); const [, t] = useLanguage(); const [stateConfig] = useConfig(); const [{ auth }] = useSession() const [{ parsePrice, optimizeImage, parseDate }] = useUtils(); const [orderState] = useOrder() const [, { showToast }] = useToast() const [isIntersectionObserver, setIsIntersectionObserver] = useState(!enableIntersection) const editMode = typeof product?.code !== 'undefined'; const removeToBalance = editMode ? product?.quantity : 0; const cartProducts: any = Object.values(orderState.carts).reduce((products: any, _cart: any) => [...products, ..._cart?.products], []) const productBalance = cartProducts.reduce((sum: any, _product: any) => sum + (_product.id === product?.id ? _product.quantity : 0), 0) const totalBalance = (productBalance || 0) - removeToBalance const maxCartProductConfig = (stateConfig.configs.max_product_amount ? parseInt(stateConfig.configs.max_product_amount) : 100) - totalBalance; let maxCartProductInventory = (product?.inventoried ? product?.quantity : undefined) - totalBalance; maxCartProductInventory = !isNaN(maxCartProductInventory) ? maxCartProductInventory : maxCartProductConfig; const maxProductQuantity = Math.min( maxCartProductConfig, maxCartProductInventory, ); const handleChangeFavorite = () => { if (auth) { handleFavoriteProduct && handleFavoriteProduct(!product?.favorite) } else { navigation && navigation.navigate('Login'); } } const handleChangeIntersection = () => { if (enableIntersection) { setIsIntersectionObserver(true); } } const handleClickproduct = () => { if (productAddedToCartLength && product?.maximum_per_order && productAddedToCartLength >= product?.maximum_per_order) { showToast(ToastType.Error, t('PRODUCT_ON_MAXIMUM_ORDER', 'The product is on maximum order')) return } onProductClick?.(product) } return ( {isIntersectionObserver ? ( handleClickproduct()} style={[ styles.container, (isSoldOut || maxProductQuantity <= 0) && styles.soldOutBackgroundStyle, (style && { ...style }) ]} > {productAddedToCartLength > 0 && ( {productAddedToCartLength.toString()} )} {product?.name} {!isPreviously && !hideFavoriteIcon && ( )} {!!product?.price && ( {parsePrice(product?.price)} )} {product?.offer_price !== null && !!product?.in_offer && ( {product?.offer_price ? parsePrice(product?.offer_price) : ''} )} {!isPreviously && product?.tags && product?.tags.length > 0 && ( {product?.tags.map((tag: any, i: any) => ( ))} )} {!hideProductDescription && ( {product?.description} )} {isPreviously && ( {t('LAST_ORDERED_ON', 'Last ordered on')} {parseDate(product?.last_ordered_date, { outputFormat: 'MMM DD, YYYY' })} )} {!!product?.ribbon?.enabled && ( {product?.ribbon?.text} )} {(!hideProductLogo && (product?.images || !hideProductDummyLogo)) && ( )} {(isSoldOut || maxProductQuantity <= 0) && ( {t('SOLD_OUT', 'SOLD OUT')} )} {!hideAddButton && ( handleClickproduct()} style={{ width: '100%', borderRadius: 7.6, marginTop: 10, height: 40 }} isDisabled={isSoldOut} text={t('ADD', 'Add')} /> )} ) : ( )} ); }, SingleProductCardPropsAreEqual); export const SingleProductCard = (props: SingleProductCardParams) => { const singleProductCardProps = { ...props, UIComponent: SingleProductCardUI } return }