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
}