import React, { useState } from 'react' import FastImage from 'react-native-fast-image' import { View, TouchableOpacity, StyleSheet, Animated, ScrollView, ImageBackground, } from 'react-native' import { ProductForm as ProductOptions, useSession, useLanguage, useOrder, useUtils } from 'ordering-components/native' import MaterialCommunityIcon from 'react-native-vector-icons/MaterialCommunityIcons' import { useTheme } from 'styled-components/native' import { ProductIngredient } from '../ProductIngredient' import { ProductOption } from '../ProductOption' import { WrapContent, ProductDescription, ProductEditions, SectionTitle, WrapperIngredients, WrapperSubOption, ProductComment, ProductActions } from './styles' import { OButton, OInput, OText } from '../shared' import { ProductOptionSubOption } from '../ProductOptionSubOption' import { NotFoundSource } from '../NotFoundSource' import NavBar from '../NavBar' import { useDeviceOrientation } from '../../../../../src/hooks/DeviceOrientation' export const ProductOptionsUI = (props: any) => { const { navigation, editMode, isSoldOut, productCart, increment, decrement, showOption, maxProductQuantity, errors, handleSave, handleChangeIngredientState, handleChangeSuboptionState, handleChangeCommentState, productObject, onClose, isDrawer } = props; const theme = useTheme(); const [{ parsePrice }] = useUtils(); const [, t] = useLanguage(); const [orderState] = useOrder(); const [{ auth }] = useSession(); const [orientationState] = useDeviceOrientation(); const { product, loading, error } = productObject; const HEADER_EXPANDED_HEIGHT = orientationState?.dimensions?.height * 0.4; const HEADER_COLLAPSED_HEIGHT = orientationState?.dimensions?.height * 0.2; 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) { props.onProductStateChange && props.onProductStateChange(props.isEdit ? { product, productCart }: productCart) handleSave && handleSave() return } } const handleRedirectLogin = () => { onClose && onClose() navigation?.navigate('Login') } const saveErrors = orderState.loading || maxProductQuantity === 0 || Object.keys(errors)?.length > 0 const [scrollY] = useState(new Animated.Value(0)); const headerHeight = scrollY.interpolate({ inputRange: [0, HEADER_EXPANDED_HEIGHT - HEADER_COLLAPSED_HEIGHT], outputRange: [HEADER_EXPANDED_HEIGHT, HEADER_COLLAPSED_HEIGHT], extrapolate: 'clamp' }); const heroContainerOpacity = scrollY.interpolate({ inputRange: [0, HEADER_EXPANDED_HEIGHT - HEADER_COLLAPSED_HEIGHT], outputRange: [1, 0], extrapolate: 'clamp' }); const heroTranslateY = scrollY.interpolate({ inputRange: [0, HEADER_EXPANDED_HEIGHT - HEADER_COLLAPSED_HEIGHT], outputRange: [0, -(HEADER_EXPANDED_HEIGHT - HEADER_COLLAPSED_HEIGHT)], extrapolate: 'clamp' }); const navBar1ContainerOpacity = scrollY.interpolate({ inputRange: [0, HEADER_EXPANDED_HEIGHT - HEADER_COLLAPSED_HEIGHT], outputRange: [1, 0], extrapolate: 'clamp' }); const navBar2ContainerOpacity = scrollY.interpolate({ inputRange: [0, HEADER_EXPANDED_HEIGHT - HEADER_COLLAPSED_HEIGHT], outputRange: [0, 1], extrapolate: 'clamp' }); const collapsedBarContainerOpacity = scrollY.interpolate({ inputRange: [HEADER_EXPANDED_HEIGHT - HEADER_COLLAPSED_HEIGHT - ((HEADER_EXPANDED_HEIGHT - HEADER_COLLAPSED_HEIGHT) * 0.08), HEADER_EXPANDED_HEIGHT - HEADER_COLLAPSED_HEIGHT], outputRange: [0, 1], extrapolate: 'clamp' }); const goToBack = () => navigation?.goBack(); const navBarProps = { style: { backgroundColor: 'transparent', width: orientationState?.dimensions?.width, borderBottomWidth: 0 }, paddingTop: 20, onActionLeft: onClose ? onClose : navigation ? goToBack : undefined, }; const styles = StyleSheet.create({ mainContainer: { flex: 1, height: orientationState?.dimensions?.height, backgroundColor: theme.colors.white, }, headerItem: { flexDirection: 'row', alignItems: 'center', marginVertical: 15, marginHorizontal: 20, zIndex: 1 }, optionContainer: { marginBottom: 20 }, comment: { borderWidth: 1, borderRadius: 0, borderBottomLeftRadius: 10, borderBottomRightRadius: 10, borderColor: '#DBDCDB', height: 100, alignItems: 'flex-start', }, quantityControl: { flexDirection: 'row', width: '30%', justifyContent: 'space-between', alignItems: 'center', flex: 1, marginRight: 10, backgroundColor: theme.colors.paleGray, paddingHorizontal: 4, borderColor: theme.colors.mediumGray, borderWidth: 1, borderRadius: 6, }, quantityControlButton: { color: theme.colors.primary, }, quantityControlButtonBorder: { borderRadius: 6, borderWidth: 2, borderColor: theme.colors.primary, marginHorizontal: 10 }, quantityControlButtonDisabled: { opacity: 0.5, }, btnBackArrow: { borderWidth: 0, color: '#FFF', backgroundColor: 'rgba(0,0,0,0.3)', borderRadius: 24, marginRight: 15, }, container: { flex: 1, backgroundColor: '#fff', }, scrollContainer: { padding: 16, }, header: { backgroundColor: '#fff', position: 'absolute', width: orientationState?.dimensions?.width, top: 0, left: 0, zIndex: 9999, }, title: { marginVertical: 16, color: "black", fontWeight: "bold", fontSize: 24 }, shadow: { shadowColor: '#000', shadowOffset: { width: 1, height: 1 }, shadowOpacity: 0.4, shadowRadius: 3, elevation: 5, }, imageStyle: { width: '100%', height: HEADER_EXPANDED_HEIGHT, } }); return ( <> {!isDrawer ? ( {!isDrawer && ( )} {product?.images ? ( ) : ( )} {product?.name} {product?.images ? ( ) : ( )} ) : ( {product?.images ? ( ) : ( )} )} {!loading && !error && product && ( {product?.name || productCart?.name} {(product?.description || productCart?.description) && ( {product?.description || productCart?.description} )} {((product?.sku && product?.sku !== '-1' && product?.sku !== '1') || (productCart?.sku && productCart?.sku !== '-1' && productCart?.sku !== '1') ) && ( {t('SKU', 'Sku')} {product?.sku || productCart?.sku} )} {product?.ingredients.length > 0 && ( {t('INGREDIENTS', 'Ingredients')} {product?.ingredients.map((ingredient: any) => ( ))} )} {product?.extras.sort((a: any, b: any) => a.rank - b.rank).map((extra: any) => extra.options.sort((a: any, b: any) => a.rank - b.rank).map((option: any) => { const currentState = productCart.options[`id:${option.id}`] || {} return ( { showOption(option) && ( { option.suboptions.sort((a: any, b: any) => a.rank - b.rank).map((suboption: any) => { const currentState = productCart.options[`id:${option.id}`]?.suboptions[`id:${suboption.id}`] || {} const balance = productCart.options[`id:${option.id}`]?.balance || 0 return ( ) }) } ) } ) }))} {!product?.hide_special_instructions && ( {t('SPECIAL_COMMENT', 'Special comment')} handleChangeCommentState({ target: { value: val } })} isDisabled={!(productCart && !isSoldOut && maxProductQuantity)} style={styles.comment} /> )} )} {error && error.length > 0 && ( )} {!loading && !error && product && ( {productCart && !isSoldOut && maxProductQuantity > 0 && ( {productCart.quantity} = maxProductQuantity || isSoldOut} style={[ styles.quantityControlButtonBorder, (maxProductQuantity <= 0 || productCart.quantity >= maxProductQuantity || isSoldOut) && styles.quantityControlButtonDisabled, ]} > = maxProductQuantity || isSoldOut) && styles.quantityControlButtonDisabled, ]} /> )} {productCart && !isSoldOut && maxProductQuantity > 0 && auth && ( handleSaveProduct()} imgRightSrc='' text={`${orderState.loading ? t('LOADING', 'Loading') : editMode ? t('UPDATE', 'Update') : t('ADD_TO_CART', 'Add to Cart')} ${productCart.total ? parsePrice(productCart?.total) : ''}`} textStyle={{ color: saveErrors ? theme.colors.primary : theme.colors.white }} style={{ backgroundColor: saveErrors ? theme.colors.white : theme.colors.primary, opacity: saveErrors ? 0.3 : 1, height: 60 }} /> )} {(!auth || isSoldOut || maxProductQuantity <= 0) && ( handleRedirectLogin()} text={isSoldOut || maxProductQuantity <= 0 ? t('SOLD_OUT', 'Sold out') : t('LOGIN_SIGNUP', 'Login / Sign Up')} imgRightSrc='' /> )} )} ); } export const ProductForm = (props: any) => { const productOptionsProps = { ...props, UIComponent: ProductOptionsUI } return }