import React, { useState, useRef, useEffect } from 'react' import { ProductForm as ProductOptions, useSession, useLanguage, useOrder, useUtils } from 'ordering-components-external/native' import { ProductIngredient } from '../ProductIngredient' import { ProductOption } from '../ProductOption' import { View, TouchableOpacity, StyleSheet, Dimensions, ScrollView, I18nManager, TextStyle, Platform, KeyboardAvoidingView, Keyboard } from 'react-native' import { ProductHeader, WrapHeader, TopHeader, WrapContent, ProductTitle, ProductDescription, ProductEditions, SectionTitle, WrapperIngredients, WrapperSubOption, ProductComment, ProductActions } from './styles' import { useTheme } from 'styled-components/native' import { OButton, OIcon, OInput, OText } from '../shared' import { ProductOptionSubOption } from '../ProductOptionSubOption' import { NotFoundSource } from '../NotFoundSource' import { Placeholder, PlaceholderLine, Fade } from 'rn-placeholder' import { useSafeAreaInsets } from 'react-native-safe-area-context' const windowHeight = Dimensions.get('window').height; const windowWidth = Dimensions.get('window').width export const ProductOptionsUI = (props: any) => { const { navigation, editMode, isSoldOut, productCart, increment, decrement, showOption, maxProductQuantity, errors, handleSave, handleChangeIngredientState, handleChangeSuboptionState, handleChangeCommentState, productObject, onClose, isFromCheckout, businessSlug } = props const theme = useTheme(); const styles = StyleSheet.create({ mainContainer: { flex: 1, height: windowHeight }, headerItem: { overflow: 'hidden', borderRadius: 50, backgroundColor: '#CCCCCC80', width: 35, margin: 15 }, optionContainer: { marginBottom: 20 }, comment: { borderRadius: 7.6, height: 92, alignItems: 'flex-start', backgroundColor: theme.colors.backgroundGray }, quantityControl: { flexDirection: 'row', width: '30%', justifyContent: 'space-between', alignItems: 'center', }, btnBackArrow: { borderWidth: 0, color: '#FFF', backgroundColor: 'rgba(0,0,0,0.3)', borderRadius: 24, marginRight: 15, }, productHeaderSkeleton: { flexDirection: 'row', width: '100%', position: 'relative', maxHeight: 260, height: 260, resizeMode: 'cover', minHeight: 200, zIndex: 0 }, closeButton: { width: 11, height: 32, backgroundColor: theme.colors.white, alignItems: 'center', justifyContent: 'center' }, quantityWrap: { width: 40, height: 24, alignItems: 'center', justifyContent: 'center', borderRadius: 7.6, backgroundColor: theme.colors.inputDisabled }, productTagWrapper: { flexDirection: 'row', alignItems: 'center' }, productTagImageStyle: { width: 32, height: 32, borderRadius: 8, resizeMode: 'cover' }, productTagNameStyle: { paddingHorizontal: 6, marginRight: 5 } }) const [{ optimizeImage, parsePrice }] = useUtils() const [, t] = useLanguage() const [orderState] = useOrder() const [{ auth }] = useSession() const { product, loading, error } = productObject const { bottom } = useSafeAreaInsets(); const [commentY, setCommentY] = useState(0) const productFormRef = useRef() const isError = (id: number) => { let bgColor = theme.colors.white if (errors[`id:${id}`]) { bgColor = 'rgba(255, 0, 0, 0.05)' } if (isSoldOut || maxProductQuantity <= 0) { bgColor = 'hsl(0, 0%, 72%)' } return bgColor } const handleSaveProduct = () => { const isErrors = Object.values(errors).length > 0 if (!isErrors) { handleSave && handleSave() return } } const handleRedirectLogin = (product: any) => { onClose() navigation.navigate('Home', { showAuth: true, product: { businessId: product?.businessId, id: product?.id, categoryId: product?.categoryId, slug: businessSlug } }) } const saveErrors = orderState.loading || maxProductQuantity === 0 || Object.keys(errors).length > 0 useEffect(() => { Keyboard.addListener('keyboardDidShow', () => { if (commentY > 100) { productFormRef?.current?.scrollTo?.({ x: 0, y: commentY + 300, animated: true }) } }) return () => { Keyboard.removeAllListeners('keyboardDidShow') } }, [productFormRef?.current, commentY]) return ( productFormRef.current = ref}> {!error && ( {loading && !product ? ( ) : ( <> )} {loading && !product ? ( ) : ( {product?.name || productCart.name} {((product?.sku && product?.sku !== '-1' && product?.sku !== '1') || (product?.estimated_person)) && ( { ((product?.sku && product?.sku !== '-1' && product?.sku !== '1') || (productCart?.sku && productCart?.sku !== '-1' && productCart?.sku !== '1')) && <>{t('SKU', 'Sku')}{' '}{product?.sku || productCart?.sku} } {product?.sku && product?.sku !== '-1' && product?.sku !== '1' && product?.estimated_person && ( <> ·  )} {product?.estimated_person && <>{product?.estimated_person}{' '}{t('ESTIMATED_PERSONS', 'persons')} } )} {productCart.price ? parsePrice(productCart.price) : ''} )} {(product?.description || productCart?.description) && ( {product?.description || productCart?.description} )} {product?.tags?.map((tag: any) => ( {tag?.image ? ( ) : ( )} {tag.name} ))} {loading && !product ? ( <> {[...Array(2)].map((item, i) => ( {[...Array(3)].map((item, i) => ( ))} ))} ) : ( {product?.ingredients?.length > 0 && ( {t('INGREDIENTS', 'Ingredients')} {product?.ingredients.map((ingredient: any) => ( ))} )} {product?.extras?.map((extra: any) => extra.options.map((option: any) => { const currentState = productCart.options[`id:${option.id}`] || {} return ( { showOption(option) && ( { option.suboptions.map((suboption: any) => { const currentState = productCart.options[`id:${option.id}`]?.suboptions[`id:${suboption.id}`] || {} const balance = productCart.options[`id:${option.id}`]?.balance || 0 return suboption?.enabled ? ( ) : null }) } ) } ) }))} {!product?.hide_special_instructions && ( setCommentY(e.nativeEvent.layout.y + e.nativeEvent.layout.height)}> {t('SPECIAL_COMMENT', 'Special comment')} handleChangeCommentState({ target: { value: val } })} isDisabled={!(productCart && !isSoldOut && maxProductQuantity)} style={styles.comment} inputStyle={{ fontSize: 12, paddingBottom: 7, paddingTop: 17 }} /> )} {productCart && !isSoldOut && maxProductQuantity > 0 && ( {t('PREFERENCES', 'Preferences')} {t('QUANTITY', 'Quantity')} {productCart.quantity} = maxProductQuantity || isSoldOut} > = maxProductQuantity || isSoldOut ? theme.colors.textSecondary : theme.colors.backgroundDark} /> )} )} )} {error && error.length > 0 && ( )} {!loading && !error && product && ( {/* {productCart && !isSoldOut && maxProductQuantity > 0 && auth && orderState.options?.address_id && ( */} handleSaveProduct()} imgRightSrc='' text={`${orderState.loading ? t('LOADING', 'Loading') : editMode ? t('UPDATE', 'Update') : t('ADD_TO_CART', 'Add to Cart')}`} textSub={`${orderState.loading ? '' : productCart.total ? parsePrice(productCart?.total) : ''}`} textStyle={{ color: saveErrors ? theme.colors.textSecondary : theme.colors.white, fontSize: 14, fontWeight: Platform.OS === 'ios' ? '600' : 'bold' }} style={{ bottom: 5, backgroundColor: saveErrors ? theme.colors.backgroundGray300 : theme.colors.primary, borderWidth: 1, shadowOpacity: 0, height: 40, borderColor: saveErrors ? theme.colors.backgroundGray300 : theme.colors.primary, }} /> {/* )} */} {auth && !orderState.options?.address_id && ( orderState.loading ? ( ) : ( ) )} {(!auth || isSoldOut || maxProductQuantity <= 0) && ( handleRedirectLogin(productCart)} text={isSoldOut || maxProductQuantity <= 0 ? t('SOLD_OUT', 'Sold out') : t('LOGIN_SIGNUP', 'Login / Sign Up')} imgRightSrc='' textStyle={{ color: theme.colors.primary, ...theme.labels.middle }} style={{ bottom: 5, marginTop: 2, height: 40, borderWidth: 1, borderColor: theme.colors.primary, backgroundColor: theme.colors.white }} /> )} )} ) } export const ProductForm = (props: any) => { const productOptionsProps = { ...props, UIComponent: ProductOptionsUI } return }