ordering-ui-react-native 0.15.23 → 0.15.25-release

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (160) hide show
  1. package/package.json +5 -3
  2. package/src/DeliveryApp.tsx +43 -1
  3. package/src/components/BusinessController/index.tsx +8 -2
  4. package/src/components/BusinessTypeFilter/index.tsx +12 -2
  5. package/src/components/BusinessTypeFilter/styles.tsx +1 -1
  6. package/src/components/BusinessesListing/index.tsx +1 -1
  7. package/src/components/Checkout/index.tsx +0 -1
  8. package/src/components/LanguageSelector/index.tsx +7 -2
  9. package/src/components/OrderDetails/index.tsx +2 -2
  10. package/src/components/PaymentOptions/index.tsx +9 -16
  11. package/src/components/PaymentOptionsWebView/index.tsx +123 -124
  12. package/src/components/SingleProductCard/index.tsx +16 -4
  13. package/src/components/StripeElementsForm/index.tsx +27 -48
  14. package/src/components/UserProfileForm/index.tsx +63 -6
  15. package/src/components/UserProfileForm/styles.tsx +8 -0
  16. package/src/components/VerifyPhone/styles.tsx +1 -2
  17. package/src/components/shared/OModal.tsx +1 -1
  18. package/src/config.json +0 -2
  19. package/src/hooks/useCountdownTimer.tsx +26 -0
  20. package/src/navigators/HomeNavigator.tsx +6 -0
  21. package/src/pages/BusinessProductsList.tsx +1 -0
  22. package/src/pages/BusinessesListing.tsx +1 -1
  23. package/src/pages/Checkout.tsx +1 -1
  24. package/src/pages/Sessions.tsx +22 -0
  25. package/src/types/index.tsx +5 -11
  26. package/src/utils/index.tsx +68 -1
  27. package/themes/business/index.tsx +2 -0
  28. package/themes/business/src/components/AcceptOrRejectOrder/index.tsx +103 -15
  29. package/themes/business/src/components/AcceptOrRejectOrder/styles.tsx +6 -0
  30. package/themes/business/src/components/Chat/index.tsx +38 -86
  31. package/themes/business/src/components/Home/index.tsx +128 -55
  32. package/themes/business/src/components/Home/styles.tsx +8 -1
  33. package/themes/business/src/components/LoginForm/index.tsx +89 -2
  34. package/themes/business/src/components/LoginForm/styles.tsx +6 -0
  35. package/themes/business/src/components/NewOrderNotification/index.tsx +61 -98
  36. package/themes/business/src/components/OrderDetails/Business.tsx +2 -1
  37. package/themes/business/src/components/OrderDetails/Delivery.tsx +32 -15
  38. package/themes/business/src/components/OrderDetails/OrderContentComponent.tsx +151 -89
  39. package/themes/business/src/components/OrderDetails/OrderHeaderComponent.tsx +91 -17
  40. package/themes/business/src/components/OrderDetails/styles.tsx +7 -0
  41. package/themes/business/src/components/OrdersListManager/index.tsx +874 -0
  42. package/themes/business/src/components/OrdersListManager/styles.tsx +123 -0
  43. package/themes/business/src/components/OrdersListManager/utils.tsx +216 -0
  44. package/themes/business/src/components/OrdersOption/index.tsx +54 -50
  45. package/themes/business/src/components/PreviousOrders/index.tsx +75 -22
  46. package/themes/business/src/components/shared/OModal.tsx +1 -1
  47. package/themes/business/src/types/index.tsx +5 -1
  48. package/themes/doordash/src/components/BusinessesListing/index.tsx +1 -1
  49. package/themes/doordash/src/components/LoginForm/index.tsx +1 -2
  50. package/themes/instacart/src/components/BusinessesListing/index.tsx +1 -1
  51. package/themes/kiosk/src/components/Cart/index.tsx +98 -24
  52. package/themes/kiosk/src/components/Cart/styles.tsx +6 -0
  53. package/themes/kiosk/src/components/CartBottomSheet/index.tsx +1 -1
  54. package/themes/kiosk/src/components/CartBottomSheet/styles.tsx +1 -1
  55. package/themes/kiosk/src/components/CartContent/index.tsx +13 -3
  56. package/themes/kiosk/src/components/CartItem/index.tsx +20 -8
  57. package/themes/kiosk/src/components/CustomerName/index.tsx +89 -88
  58. package/themes/kiosk/src/components/Intro/index.tsx +13 -13
  59. package/themes/kiosk/src/components/NavBar/index.tsx +14 -14
  60. package/themes/kiosk/src/components/OptionCard/index.tsx +1 -1
  61. package/themes/kiosk/src/components/OrderDetails/index.tsx +136 -41
  62. package/themes/kiosk/src/components/OrderDetails/styles.tsx +5 -0
  63. package/themes/kiosk/src/components/OrderSummary/index.tsx +1 -1
  64. package/themes/kiosk/src/components/OrderTypeCardSelector/index.tsx +10 -12
  65. package/themes/kiosk/src/components/ProductForm/index.tsx +174 -125
  66. package/themes/kiosk/src/components/ProductForm/styles.tsx +1 -1
  67. package/themes/kiosk/src/components/ProductOption/index.tsx +1 -0
  68. package/themes/kiosk/src/components/ProductOption/styles.tsx +1 -0
  69. package/themes/kiosk/src/components/UpsellingProducts/index.tsx +48 -34
  70. package/themes/kiosk/src/components/shared/OButton.tsx +5 -18
  71. package/themes/kiosk/src/types/index.d.ts +2 -0
  72. package/themes/original/index.tsx +178 -1
  73. package/themes/original/src/components/AddressForm/index.tsx +15 -10
  74. package/themes/original/src/components/AddressList/index.tsx +56 -18
  75. package/themes/original/src/components/AppleLogin/index.tsx +117 -78
  76. package/themes/original/src/components/BusinessBasicInformation/index.tsx +96 -45
  77. package/themes/original/src/components/BusinessBasicInformation/styles.tsx +28 -1
  78. package/themes/original/src/components/BusinessController/index.tsx +52 -22
  79. package/themes/original/src/components/BusinessController/styles.tsx +22 -0
  80. package/themes/original/src/components/BusinessFeaturedController/index.tsx +20 -1
  81. package/themes/original/src/components/BusinessFeaturedController/styles.tsx +23 -0
  82. package/themes/original/src/components/BusinessListingSearch/index.tsx +121 -7
  83. package/themes/original/src/components/BusinessListingSearch/styles.tsx +14 -1
  84. package/themes/original/src/components/BusinessMenuList/index.tsx +11 -4
  85. package/themes/original/src/components/BusinessPreorder/index.tsx +142 -122
  86. package/themes/original/src/components/BusinessProductsCategories/index.tsx +9 -7
  87. package/themes/original/src/components/BusinessProductsList/index.tsx +127 -20
  88. package/themes/original/src/components/BusinessProductsList/styles.tsx +29 -2
  89. package/themes/original/src/components/BusinessProductsListing/index.tsx +92 -37
  90. package/themes/original/src/components/BusinessProductsListing/styles.tsx +22 -0
  91. package/themes/original/src/components/BusinessReviews/index.tsx +4 -25
  92. package/themes/original/src/components/BusinessTypeFilter/index.tsx +1 -2
  93. package/themes/original/src/components/BusinessesListing/index.tsx +51 -58
  94. package/themes/original/src/components/Cart/index.tsx +19 -15
  95. package/themes/original/src/components/CartContent/index.tsx +2 -2
  96. package/themes/original/src/components/Checkout/index.tsx +42 -27
  97. package/themes/original/src/components/ForgotPasswordForm/index.tsx +84 -4
  98. package/themes/original/src/components/GoogleMap/index.tsx +1 -0
  99. package/themes/original/src/components/Help/index.tsx +21 -4
  100. package/themes/original/src/components/HighestRatedBusinesses/index.tsx +97 -89
  101. package/themes/original/src/components/Home/index.tsx +1 -1
  102. package/themes/original/src/components/LastOrders/index.tsx +12 -1
  103. package/themes/original/src/components/LoginForm/Otp/index.tsx +90 -0
  104. package/themes/original/src/components/LoginForm/Otp/styles.tsx +7 -0
  105. package/themes/original/src/components/LoginForm/index.tsx +389 -156
  106. package/themes/original/src/components/LoginForm/styles.tsx +7 -4
  107. package/themes/original/src/components/LogoutButton/index.tsx +7 -1
  108. package/themes/original/src/components/MessageListing/index.tsx +10 -1
  109. package/themes/original/src/components/Messages/index.tsx +34 -25
  110. package/themes/original/src/components/Messages/styles.tsx +1 -3
  111. package/themes/original/src/components/MomentOption/index.tsx +10 -1
  112. package/themes/original/src/components/MomentOption/styles.tsx +1 -1
  113. package/themes/original/src/components/OrderDetails/index.tsx +35 -28
  114. package/themes/original/src/components/OrderDetails/styles.tsx +1 -2
  115. package/themes/original/src/components/OrderProgress/index.tsx +4 -4
  116. package/themes/original/src/components/OrderProgress/styles.tsx +1 -0
  117. package/themes/original/src/components/OrderSummary/index.tsx +3 -3
  118. package/themes/original/src/components/OrderTypeSelector/index.tsx +4 -2
  119. package/themes/original/src/components/OrdersOption/index.tsx +25 -33
  120. package/themes/original/src/components/OrdersOption/styles.tsx +0 -6
  121. package/themes/original/src/components/PaymentOptionCash/index.tsx +2 -2
  122. package/themes/original/src/components/PaymentOptionWallet/index.tsx +22 -24
  123. package/themes/original/src/components/PaymentOptionWallet/styles.tsx +1 -1
  124. package/themes/original/src/components/PaymentOptions/index.tsx +9 -19
  125. package/themes/original/src/components/PhoneInputNumber/index.tsx +1 -1
  126. package/themes/original/src/components/PreviousOrders/index.tsx +19 -13
  127. package/themes/original/src/components/ProductForm/index.tsx +76 -61
  128. package/themes/original/src/components/ProductForm/styles.tsx +2 -2
  129. package/themes/original/src/components/ProductItemAccordion/index.tsx +2 -2
  130. package/themes/original/src/components/ProductOptionSubOption/index.tsx +18 -12
  131. package/themes/original/src/components/Promotions/index.tsx +250 -0
  132. package/themes/original/src/components/Promotions/styles.tsx +60 -0
  133. package/themes/original/src/components/ReviewOrder/index.tsx +10 -9
  134. package/themes/original/src/components/ReviewProducts/index.tsx +1 -1
  135. package/themes/original/src/components/Sessions/index.tsx +160 -0
  136. package/themes/original/src/components/Sessions/styles.tsx +15 -0
  137. package/themes/original/src/components/SingleProductCard/index.tsx +47 -21
  138. package/themes/original/src/components/SingleProductCard/styles.tsx +28 -1
  139. package/themes/original/src/components/StripeElementsForm/index.tsx +55 -72
  140. package/themes/original/src/components/TaxInformation/index.tsx +10 -4
  141. package/themes/original/src/components/UpsellingProducts/index.tsx +87 -71
  142. package/themes/original/src/components/UserDetails/index.tsx +4 -95
  143. package/themes/original/src/components/UserFormDetails/index.tsx +32 -31
  144. package/themes/original/src/components/UserProfile/index.tsx +62 -14
  145. package/themes/original/src/components/UserProfileForm/index.tsx +20 -18
  146. package/themes/original/src/components/VerifyPhone/index.tsx +10 -7
  147. package/themes/original/src/components/VerifyPhone/styles.tsx +2 -1
  148. package/themes/original/src/components/Wallets/index.tsx +76 -9
  149. package/themes/original/src/components/Wallets/styles.tsx +21 -0
  150. package/themes/original/src/components/shared/HeaderTitle.tsx +21 -0
  151. package/themes/original/src/components/shared/OModal.tsx +1 -1
  152. package/themes/original/src/components/shared/index.tsx +2 -0
  153. package/themes/original/src/config/constants.tsx +6 -6
  154. package/themes/original/src/types/index.tsx +62 -5
  155. package/themes/original/src/utils/index.tsx +28 -2
  156. package/themes/single-business/src/components/AddressList/index.tsx +1 -1
  157. package/themes/single-business/src/components/OrderTypeSelector/index.tsx +6 -6
  158. package/themes/single-business/src/components/UserProfile/index.tsx +1 -1
  159. package/themes/uber-eats/src/components/BusinessesListing/index.tsx +1 -1
  160. package/src/components/StripeMethodForm/index.tsx +0 -168
@@ -1,8 +1,8 @@
1
1
  import React, { useState, useEffect } from 'react'
2
- import { Platform, StyleSheet, View } from 'react-native'
2
+ import { View } from 'react-native'
3
3
  import { Fade, Placeholder, PlaceholderLine } from 'rn-placeholder';
4
4
  import { useTheme } from 'styled-components/native'
5
- import CheckBox from '@react-native-community/checkbox';
5
+ import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons';
6
6
  import {
7
7
  PaymentOptionWallet as PaymentOptionWalletController,
8
8
  useLanguage,
@@ -20,6 +20,7 @@ import { OText } from '../shared'
20
20
 
21
21
  const PaymentOptionWalletUI = (props: any) => {
22
22
  const {
23
+ businessConfigs,
23
24
  businessId,
24
25
  walletsState,
25
26
  selectWallet,
@@ -37,12 +38,8 @@ const PaymentOptionWalletUI = (props: any) => {
37
38
  const isWalletCashEnabled = configs?.wallet_cash_enabled?.value === '1'
38
39
  const isWalletPointsEnabled = configs?.wallet_credit_point_enabled?.value === '1'
39
40
 
40
- const styles = StyleSheet.create({
41
- checkBoxStyle: {
42
- width: 25,
43
- height: 25,
44
- }
45
- });
41
+ const isBusinessWalletCashEnabled = businessConfigs.find((config: any) => config.key === 'wallet_cash_enabled')?.value === '1'
42
+ const isBusinessWalletPointsEnabled = businessConfigs.find((config: any) => config.key === 'wallet_credit_point_enabled')?.value === '1'
46
43
 
47
44
  const [checkedState, setCheckedState] = useState(
48
45
  new Array(walletsState.result?.length).fill(false)
@@ -53,11 +50,11 @@ const PaymentOptionWalletUI = (props: any) => {
53
50
  const walletName: any = {
54
51
  cash: {
55
52
  name: t('PAY_WITH_CASH_WALLET', 'Pay with Cash Wallet'),
56
- isActive: isWalletCashEnabled
53
+ isActive: isWalletCashEnabled && isBusinessWalletCashEnabled
57
54
  },
58
55
  credit_point: {
59
56
  name: t('PAY_WITH_CREDITS_POINTS_WALLET', 'Pay with Credit Points Wallet'),
60
- isActive: isWalletPointsEnabled
57
+ isActive: isWalletPointsEnabled && isBusinessWalletPointsEnabled
61
58
  }
62
59
  }
63
60
 
@@ -96,22 +93,23 @@ const PaymentOptionWalletUI = (props: any) => {
96
93
  <Container
97
94
  key={wallet.id}
98
95
  isBottomBorder={idx === walletsState.result?.filter((wallet: any) => wallet.valid)?.length - 1}
96
+ onPress={() => handleOnChange(idx, wallet)}
97
+ disabled={(cart?.balance === 0 && !checkedState[idx]) || wallet.balance === 0}
99
98
  >
100
99
  <SectionLeft>
101
- <CheckBox
102
- value={checkedState[idx]}
103
- onValueChange={() => handleOnChange(idx, wallet)}
104
- disabled={(cart?.balance === 0 && !checkedState[idx]) || wallet.balance === 0 }
105
- boxType={'square'}
106
- tintColors={{
107
- true: theme.colors.primary,
108
- false: theme.colors.disabled
109
- }}
110
- tintColor={theme.colors.disabled}
111
- onCheckColor={theme.colors.primary}
112
- onTintColor={theme.colors.primary}
113
- style={Platform.OS === 'ios' && styles.checkBoxStyle}
114
- />
100
+ {checkedState[idx] ? (
101
+ <MaterialCommunityIcons
102
+ name="checkbox-marked"
103
+ size={25}
104
+ color={theme.colors.primary}
105
+ />
106
+ ) : (
107
+ <MaterialCommunityIcons
108
+ name="checkbox-blank-outline"
109
+ size={25}
110
+ color={theme.colors.disabled}
111
+ />
112
+ )}
115
113
  <View style={{ alignItems: 'baseline', marginLeft: 5 }}>
116
114
  <View>
117
115
  <OText
@@ -1,6 +1,6 @@
1
1
  import styled, { css } from 'styled-components/native'
2
2
 
3
- export const Container = styled.View`
3
+ export const Container = styled.TouchableOpacity`
4
4
  width: 100%;
5
5
  display: flex;
6
6
  padding: 20px 0;
@@ -32,8 +32,6 @@ import {
32
32
  import { getIconCard, flatArray } from '../../utils';
33
33
 
34
34
  const stripeOptions: any = ['stripe_direct', 'stripe', 'stripe_connect']
35
- const methodsPay = ['google_pay', 'apple_pay']
36
- const stripeDirectMethods = ['stripe_direct', ...methodsPay]
37
35
  // const stripeRedirectOptions = [
38
36
  // { name: 'Bancontact', value: 'bancontact' },
39
37
  // { name: 'Alipay', value: 'alipay' },
@@ -56,8 +54,7 @@ const PaymentOptionsUI = (props: any) => {
56
54
  handlePaymethodClick,
57
55
  handlePaymethodDataChange,
58
56
  isOpenMethod,
59
- handlePaymentMethodClickCustom,
60
- handlePlaceOrder
57
+ handlePaymentMethodClickCustom
61
58
  } = props
62
59
 
63
60
  const theme = useTheme();
@@ -125,16 +122,12 @@ const PaymentOptionsUI = (props: any) => {
125
122
 
126
123
  useEffect(() => {
127
124
  if (props.paySelected && props.paySelected?.data) {
128
- setPaymethodData && setPaymethodData(props.paySelected?.data)
125
+ requestAnimationFrame(() => {
126
+ setPaymethodData && setPaymethodData(props.paySelected?.data)
127
+ })
129
128
  }
130
129
  }, [props.paySelected])
131
130
 
132
- useEffect(() => {
133
- if (methodsPay.includes(paymethodSelected?.gateway) && paymethodData?.id && paymethodSelected?.data?.card) {
134
- handlePlaceOrder()
135
- }
136
- }, [paymethodData, paymethodSelected])
137
-
138
131
  const renderPaymethods = ({ item }: any) => {
139
132
  return (
140
133
  <TouchableOpacity
@@ -163,7 +156,7 @@ const PaymentOptionsUI = (props: any) => {
163
156
  )
164
157
  }
165
158
 
166
- const excludeIds: any = [32]; //exclude paypal & connect & redirect
159
+ const excludeIds: any = [32, 66]; //exclude paypal & connect & redirect
167
160
 
168
161
  return (
169
162
  <PMContainer>
@@ -296,11 +289,11 @@ const PaymentOptionsUI = (props: any) => {
296
289
  </KeyboardAvoidingView>
297
290
  </OModal>
298
291
 
299
- {/* Stripe direct, Google pay, Apple pay */}
292
+ {/* Stripe direct */}
300
293
  <OModal
301
294
  entireModal
302
295
  title={t('ADD_CREDIT_OR_DEBIT_CARD', 'Add credit or debit card')}
303
- open={stripeDirectMethods?.includes(isOpenMethod?.paymethod?.gateway) && !paymethodData.id}
296
+ open={isOpenMethod?.paymethod?.gateway === 'stripe_direct' && !paymethodData?.id}
304
297
  onClose={() => handlePaymethodClick(null)}
305
298
  >
306
299
  <KeyboardAvoidingView
@@ -309,13 +302,10 @@ const PaymentOptionsUI = (props: any) => {
309
302
  enabled={Platform.OS === 'ios' ? true : false}
310
303
  >
311
304
  <StripeElementsForm
312
- cart={cart}
313
- paymethod={isOpenMethod?.paymethod?.gateway}
314
- methodsPay={methodsPay}
315
305
  businessId={props.businessId}
316
- publicKey={isOpenMethod?.paymethod?.credentials?.publishable || isOpenMethod?.paymethod?.credentials?.publishable_key}
306
+ publicKey={isOpenMethod?.paymethod?.credentials?.publishable}
317
307
  handleSource={handlePaymethodDataChange}
318
- onCancel={() => handlePaymethodClick(null)}
308
+ onCancel={() => handlePaymethodClick(false)}
319
309
  />
320
310
  </KeyboardAvoidingView>
321
311
  </OModal>
@@ -58,7 +58,7 @@ export const PhoneInputNumber = (props: PhoneInputParams) => {
58
58
  }
59
59
 
60
60
  useEffect(() => {
61
- if ((defaultValue && userphoneNumber) || defaultValue === undefined || defaultValue === '') {
61
+ if ((defaultValue && userphoneNumber) || !defaultValue) {
62
62
  if (userphoneNumber) {
63
63
  const checkValid = phoneInput.current?.isValidNumber(userphoneNumber);
64
64
  const callingCode = phoneInput.current?.getCallingCode();
@@ -85,7 +85,11 @@ export const PreviousOrders = (props: PreviousOrdersParams) => {
85
85
  order: {
86
86
  id: order?.id,
87
87
  business_id: order?.business_id,
88
- logo: order.business?.logo,
88
+ logo: order?.business?.logo,
89
+ driver: order?.driver,
90
+ products: order?.products,
91
+ review: order?.review,
92
+ user_review: order?.user_review
89
93
  },
90
94
  });
91
95
  };
@@ -139,18 +143,20 @@ export const PreviousOrders = (props: PreviousOrdersParams) => {
139
143
  </OText>
140
144
  </Information>
141
145
  <Status>
142
- <OButton
143
- text={t('REORDER', 'Reorder')}
144
- imgRightSrc={''}
145
- textStyle={styles.buttonText}
146
- style={
147
- reorderLoading && order.id === reorderSelected
148
- ? styles.reorderLoading
149
- : styles.reorderbutton
150
- }
151
- onClick={() => handleReorderClick(order.id)}
152
- isLoading={reorderLoading && order.id === reorderSelected}
153
- />
146
+ {order.cart && (
147
+ <OButton
148
+ text={t('REORDER', 'Reorder')}
149
+ imgRightSrc={''}
150
+ textStyle={styles.buttonText}
151
+ style={
152
+ reorderLoading && order.id === reorderSelected
153
+ ? styles.reorderLoading
154
+ : styles.reorderbutton
155
+ }
156
+ onClick={() => handleReorderClick(order.id)}
157
+ isLoading={reorderLoading && order.id === reorderSelected}
158
+ />
159
+ )}
154
160
  {allowedOrderStatus.includes(parseInt(order?.status)) &&
155
161
  !order.review && (
156
162
  <TouchableOpacity
@@ -46,7 +46,6 @@ import { ProductOptionSubOption } from '../ProductOptionSubOption';
46
46
  import { NotFoundSource } from '../NotFoundSource';
47
47
  import { Placeholder, PlaceholderLine, Fade } from 'rn-placeholder';
48
48
  import { useState } from 'react';
49
-
50
49
  const windowHeight = Dimensions.get('window').height;
51
50
  const windowWidth = Dimensions.get('window').width;
52
51
 
@@ -176,6 +175,7 @@ export const ProductOptionsUI = (props: any) => {
176
175
  const [optionLayout, setOptionLayout] = useState<any>({})
177
176
  const [headerRefHeight, setHeaderRefHeight] = useState(0)
178
177
  const [summaryRefHeight, setSummaryRefHeight] = useState(0)
178
+ const [isScrollAvailable, setIsScrollAvailable] = useState(null)
179
179
 
180
180
  const isError = (id: number) => {
181
181
  let bgColor = theme.colors.white;
@@ -279,39 +279,6 @@ export const ProductOptionsUI = (props: any) => {
279
279
  setOptionLayout(_optionLayout)
280
280
  }
281
281
 
282
- useEffect(() => {
283
- const imageList: any = []
284
- const videoList: any = []
285
- product?.images && imageList.push(product.images)
286
- if (product?.gallery && product?.gallery.length > 0) {
287
- for (const img of product?.gallery) {
288
- if (img?.file) {
289
- imageList.push(img?.file)
290
- }
291
- if (img?.video) {
292
- const keys = img?.video.split('/')
293
- let _videoId = keys[keys.length - 1]
294
- if (_videoId.includes('watch')) {
295
- const __url = _videoId.split('=')[1]
296
- _videoId = __url
297
- }
298
- if (_videoId.includes('?')) {
299
- const __url = _videoId.split('?')[0]
300
- _videoId = __url
301
- }
302
- videoList.push(_videoId)
303
- }
304
- }
305
- }
306
- const gallery = imageList.concat(videoList)
307
- setGallery(gallery)
308
-
309
- if (product?.weight && product?.weight_unit) {
310
- setIsHaveWeight(true)
311
- setPricePerWeightUnit(product?.price / product?.weight)
312
- }
313
- }, [product])
314
-
315
282
  const saveErrors =
316
283
  orderState.loading ||
317
284
  maxProductQuantity === 0 ||
@@ -319,28 +286,9 @@ export const ProductOptionsUI = (props: any) => {
319
286
 
320
287
  const ExtraOptions = ({ eID, options }: any) => (
321
288
  <>
322
- {product?.ingredients.length > 0 && (
323
- <TouchableOpacity
324
- key={`eopt_all_00`}
325
- onPress={() => setSelectedOpt(-1)}
326
- style={[
327
- styles.extraItem,
328
- {
329
- borderBottomColor:
330
- selOpt == -1 ? theme.colors.textNormal : theme.colors.border,
331
- },
332
- ]}>
333
- <OText
334
- color={selOpt == -1 ? theme.colors.textNormal : theme.colors.textSecondary}
335
- size={selOpt == -1 ? 14 : 12}
336
- weight={selOpt == -1 ? '600' : 'normal'}>
337
- {t('INGREDIENTS', 'Ingredients')}
338
- </OText>
339
- </TouchableOpacity>
340
- )}
341
- {options.map(({ id, name, respect_to }: any) => (
289
+ {options.map(({ id, name, respect_to, suboptions }: any) => (
342
290
  <React.Fragment key={`cont_key_${id}`}>
343
- {respect_to == null && (
291
+ {respect_to == null && suboptions?.length > 0 && (
344
292
  <TouchableOpacity
345
293
  key={`eopt_key_${id}`}
346
294
  onPress={() => setSelectedOpt(id)}
@@ -370,6 +318,54 @@ export const ProductOptionsUI = (props: any) => {
370
318
  ? () => navigation.goBack()
371
319
  : () => navigation.navigate('Business', { store: props.businessSlug })
372
320
 
321
+ useEffect(() => {
322
+ if (isScrollAvailable) {
323
+ setIsScrollAvailable(null)
324
+ scrollDown(isScrollAvailable)
325
+ }
326
+ }, [errors])
327
+
328
+ useEffect(() => {
329
+ const imageList: any = []
330
+ const videoList: any = []
331
+ product?.images && imageList.push(product.images)
332
+ if (product?.gallery && product?.gallery.length > 0) {
333
+ for (const img of product?.gallery) {
334
+ if (img?.file) {
335
+ imageList.push(img?.file)
336
+ }
337
+ if (img?.video) {
338
+ const keys = img?.video.split('/')
339
+ let _videoId = keys[keys.length - 1]
340
+
341
+ if (_videoId.includes('watch')) {
342
+ const __url = _videoId.split('=')[1]
343
+ _videoId = __url
344
+ } else if (_videoId.includes('?')) {
345
+ const __url = _videoId.split('?')[0]
346
+ _videoId = __url
347
+ }
348
+
349
+ if (_videoId.search(/&/i) >= 0) {
350
+ _videoId = _videoId.split('&')[0]
351
+ } else if (_videoId.search(/\?/i) >= 0) {
352
+ _videoId = _videoId.split('?')[0]
353
+ }
354
+ if ((_videoId.length === 11)) {
355
+ videoList.push(_videoId)
356
+ }
357
+ }
358
+ }
359
+ }
360
+ const gallery = imageList.concat(videoList)
361
+ setGallery(gallery)
362
+
363
+ if (product?.weight && product?.weight_unit) {
364
+ setIsHaveWeight(true)
365
+ setPricePerWeightUnit(product?.price / product?.weight)
366
+ }
367
+ }, [product])
368
+
373
369
  return (
374
370
  <SafeAreaView style={{ flex: 1 }}>
375
371
  <TopHeader>
@@ -658,6 +654,25 @@ export const ProductOptionsUI = (props: any) => {
658
654
  {t('ALL', 'All')}
659
655
  </OText>
660
656
  </TouchableOpacity>
657
+ {product?.ingredients.length > 0 && (
658
+ <TouchableOpacity
659
+ key={`eopt_all_00`}
660
+ onPress={() => setSelectedOpt(-1)}
661
+ style={[
662
+ styles.extraItem,
663
+ {
664
+ borderBottomColor:
665
+ selOpt == -1 ? theme.colors.textNormal : theme.colors.border,
666
+ },
667
+ ]}>
668
+ <OText
669
+ color={selOpt == -1 ? theme.colors.textNormal : theme.colors.textSecondary}
670
+ size={selOpt == -1 ? 14 : 12}
671
+ weight={selOpt == -1 ? '600' : 'normal'}>
672
+ {t('INGREDIENTS', 'Ingredients')}
673
+ </OText>
674
+ </TouchableOpacity>
675
+ )}
661
676
  {product?.extras.map((extra: any) =>
662
677
  <ExtraOptions key={extra.id} options={extra.options} />
663
678
  )}
@@ -687,8 +702,8 @@ export const ProductOptionsUI = (props: any) => {
687
702
  </WrapperIngredients>
688
703
  </View>
689
704
  )}
690
- {product?.extras.map((extra: any) =>
691
- extra.options.map((option: any) => {
705
+ {product?.extras.sort((a: any, b: any) => a.rank - b.rank).map((extra: any) =>
706
+ extra.options.sort((a: any, b: any) => a.rank - b.rank).map((option: any) => {
692
707
  const currentState =
693
708
  productCart.options[`id:${option.id}`] || {};
694
709
  return (
@@ -704,7 +719,7 @@ export const ProductOptionsUI = (props: any) => {
704
719
  backgroundColor: isError(option.id),
705
720
  borderRadius: 7.6
706
721
  }}>
707
- {option.suboptions.map(
722
+ {option.suboptions.sort((a: any, b: any) => a.rank - b.rank).map(
708
723
  (suboption: any) => {
709
724
  const currentState =
710
725
  productCart.options[
@@ -731,7 +746,7 @@ export const ProductOptionsUI = (props: any) => {
731
746
  isSoldOut ||
732
747
  maxProductQuantity <= 0
733
748
  }
734
- scrollDown={scrollDown}
749
+ setIsScrollAvailable={setIsScrollAvailable}
735
750
  error={errors[`id:${option.id}`]}
736
751
  />
737
752
  );
@@ -772,7 +787,7 @@ export const ProductOptionsUI = (props: any) => {
772
787
  ) : (
773
788
  <>
774
789
  {product?.extras.map((extra: any) =>
775
- extra.options.map((option: any) => {
790
+ extra.options.sort((a: any, b: any) => a.rank - b.rank).map((option: any) => {
776
791
  if (
777
792
  option.id == selOpt ||
778
793
  (hasRespected(
@@ -797,7 +812,7 @@ export const ProductOptionsUI = (props: any) => {
797
812
  option.id,
798
813
  ),
799
814
  }}>
800
- {option.suboptions.map(
815
+ {option.suboptions.sort((a: any, b: any) => a.rank - b.rank).map(
801
816
  (suboption: any) => {
802
817
  const currentState =
803
818
  productCart.options[
@@ -6,9 +6,10 @@ export const WrapHeader = styled.View`
6
6
  `
7
7
 
8
8
  export const TopActions = styled.TouchableOpacity`
9
- height: 44px;
9
+ height: 60px;
10
10
  justify-content: center;
11
11
  padding-horizontal: 30px;
12
+ width: 80px;
12
13
  `;
13
14
 
14
15
  export const TopHeader = styled.View`
@@ -48,7 +49,6 @@ export const ProductDescription = styled.View`
48
49
  `
49
50
 
50
51
  export const ProductEditions = styled.View`
51
-
52
52
  `
53
53
 
54
54
  export const SectionTitle = styled.View`
@@ -40,7 +40,7 @@ export const ProductItemAccordion = (props: ProductItemAccordionParams) => {
40
40
 
41
41
  const pickerStyle = StyleSheet.create({
42
42
  inputAndroid: {
43
- width: 27,
43
+ width: 34,
44
44
  textAlign: 'center',
45
45
  overflow: 'visible',
46
46
  fontSize: 12,
@@ -49,7 +49,7 @@ export const ProductItemAccordion = (props: ProductItemAccordionParams) => {
49
49
  color: theme.colors.textNormal
50
50
  },
51
51
  inputIOS: {
52
- width: 27,
52
+ width: 34,
53
53
  textAlign: 'center',
54
54
  overflow: 'visible',
55
55
  fontSize: 12,
@@ -28,36 +28,40 @@ export const ProductOptionSubOptionUI = (props: any) => {
28
28
  toggleSelect,
29
29
  changePosition,
30
30
  disabled,
31
- error,
32
- scrollDown
31
+ setIsScrollAvailable
33
32
  } = props
34
33
 
34
+ const disableIncrement = option?.limit_suboptions_by_max ? balance === option?.max : state.quantity === suboption?.max || (!state.selected && balance === option?.max)
35
+ const price = option?.with_half_option && suboption?.half_price && state.position !== 'whole' ? suboption?.half_price : suboption?.price
36
+
35
37
  const theme = useTheme();
36
-
37
38
  const [, t] = useLanguage()
38
39
  const [{ parsePrice }] = useUtils()
39
40
  const [showMessage, setShowMessage] = useState(false)
41
+ const [isDirty, setIsDirty] = useState(false)
40
42
 
41
43
  const handleSuboptionClick = () => {
42
44
  toggleSelect()
43
-
44
- if (balance === option?.max - 1 && !state.selected) {
45
- scrollDown(option?.id)
46
- }
45
+ setIsDirty(true)
47
46
 
48
47
  if (balance === option?.max && option?.suboptions?.length > balance && !(option?.min === 1 && option?.max === 1)) {
49
48
  setShowMessage(true)
50
49
  }
51
50
  }
52
51
 
52
+ useEffect(() => {
53
+ if (balance === option?.max && state?.selected && isDirty) {
54
+ setIsDirty(false)
55
+ setIsScrollAvailable(option?.id)
56
+ }
57
+ }, [state?.selected])
58
+
53
59
  useEffect(() => {
54
60
  if (!(balance === option?.max && option?.suboptions?.length > balance && !(option?.min === 1 && option?.max === 1))) {
55
61
  setShowMessage(false)
56
62
  }
57
63
  }, [balance])
58
64
 
59
- const disableIncrement = option?.limit_suboptions_by_max ? balance === option?.max : state.quantity === suboption?.max || (!state.selected && balance === option?.max)
60
- const price = option?.with_half_option && suboption?.half_price && state.position !== 'whole' ? suboption?.half_price : suboption?.price
61
65
  return (
62
66
  <View>
63
67
  <Container onPress={() => handleSuboptionClick()}>
@@ -130,9 +134,11 @@ export const ProductOptionSubOptionUI = (props: any) => {
130
134
  </>
131
135
  )}
132
136
  </PositionControl>
133
- <OText size={12} lineHeight={18} color={theme.colors.textSecondary}>
134
- + {parsePrice(price)}
135
- </OText>
137
+ {price > 0 && (
138
+ <OText size={12} lineHeight={18} color={theme.colors.textSecondary}>
139
+ + {parsePrice(price)}
140
+ </OText>
141
+ )}
136
142
  </Container>
137
143
  {showMessage && <OText size={10} mLeft={4} mRight={4} style={{ flex: 1, textAlign: 'center' }} color={theme.colors.primary}>{`${t('OPTIONS_MAX_LIMIT', 'Maximum options to choose')}: ${option?.max}`}</OText>}
138
144
  </View>