ordering-ui-react-native 0.15.22 → 0.15.23-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 (151) hide show
  1. package/package.json +5 -3
  2. package/src/DeliveryApp.tsx +43 -1
  3. package/src/components/BusinessTypeFilter/index.tsx +12 -2
  4. package/src/components/BusinessTypeFilter/styles.tsx +1 -1
  5. package/src/components/BusinessesListing/index.tsx +1 -1
  6. package/src/components/Checkout/index.tsx +0 -1
  7. package/src/components/LanguageSelector/index.tsx +1 -0
  8. package/src/components/OrderDetails/index.tsx +2 -2
  9. package/src/components/PaymentOptions/index.tsx +9 -16
  10. package/src/components/PaymentOptionsWebView/index.tsx +123 -124
  11. package/src/components/StripeElementsForm/index.tsx +27 -48
  12. package/src/components/UserProfileForm/index.tsx +63 -6
  13. package/src/components/UserProfileForm/styles.tsx +8 -0
  14. package/src/components/VerifyPhone/styles.tsx +1 -2
  15. package/src/config.json +0 -2
  16. package/src/navigators/HomeNavigator.tsx +6 -0
  17. package/src/pages/BusinessProductsList.tsx +1 -0
  18. package/src/pages/BusinessesListing.tsx +1 -1
  19. package/src/pages/Checkout.tsx +1 -1
  20. package/src/pages/Sessions.tsx +22 -0
  21. package/src/types/index.tsx +2 -9
  22. package/src/utils/index.tsx +68 -1
  23. package/themes/business/index.tsx +2 -0
  24. package/themes/business/src/components/AcceptOrRejectOrder/index.tsx +56 -8
  25. package/themes/business/src/components/AcceptOrRejectOrder/styles.tsx +5 -0
  26. package/themes/business/src/components/Chat/index.tsx +38 -86
  27. package/themes/business/src/components/Home/index.tsx +128 -55
  28. package/themes/business/src/components/Home/styles.tsx +8 -1
  29. package/themes/business/src/components/NewOrderNotification/index.tsx +59 -98
  30. package/themes/business/src/components/OrderDetails/Business.tsx +2 -1
  31. package/themes/business/src/components/OrderDetails/Delivery.tsx +22 -13
  32. package/themes/business/src/components/OrderDetails/OrderContentComponent.tsx +151 -89
  33. package/themes/business/src/components/OrderDetails/OrderHeaderComponent.tsx +91 -17
  34. package/themes/business/src/components/OrderDetails/styles.tsx +7 -0
  35. package/themes/business/src/components/OrdersListManager/index.tsx +874 -0
  36. package/themes/business/src/components/OrdersListManager/styles.tsx +123 -0
  37. package/themes/business/src/components/OrdersListManager/utils.tsx +216 -0
  38. package/themes/business/src/components/OrdersOption/index.tsx +53 -49
  39. package/themes/business/src/components/PreviousOrders/index.tsx +75 -22
  40. package/themes/business/src/types/index.tsx +2 -1
  41. package/themes/doordash/src/components/BusinessesListing/index.tsx +1 -1
  42. package/themes/doordash/src/components/LoginForm/index.tsx +1 -2
  43. package/themes/instacart/src/components/BusinessesListing/index.tsx +1 -1
  44. package/themes/kiosk/src/components/BusinessController/index.tsx +27 -6
  45. package/themes/kiosk/src/components/BusinessController/styles.tsx +1 -1
  46. package/themes/kiosk/src/components/BusinessProductsListing/index.tsx +48 -21
  47. package/themes/kiosk/src/components/Cart/index.tsx +98 -24
  48. package/themes/kiosk/src/components/Cart/styles.tsx +6 -0
  49. package/themes/kiosk/src/components/CartBottomSheet/index.tsx +1 -1
  50. package/themes/kiosk/src/components/CartBottomSheet/styles.tsx +1 -1
  51. package/themes/kiosk/src/components/CartContent/index.tsx +13 -3
  52. package/themes/kiosk/src/components/CartItem/index.tsx +20 -8
  53. package/themes/kiosk/src/components/CategoriesMenu/index.tsx +6 -5
  54. package/themes/kiosk/src/components/CustomerName/index.tsx +89 -88
  55. package/themes/kiosk/src/components/Intro/index.tsx +13 -13
  56. package/themes/kiosk/src/components/LanguageSelector/index.tsx +12 -8
  57. package/themes/kiosk/src/components/NavBar/index.tsx +14 -14
  58. package/themes/kiosk/src/components/OptionCard/index.tsx +1 -1
  59. package/themes/kiosk/src/components/OrderDetails/index.tsx +136 -41
  60. package/themes/kiosk/src/components/OrderDetails/styles.tsx +5 -0
  61. package/themes/kiosk/src/components/OrderSummary/index.tsx +1 -1
  62. package/themes/kiosk/src/components/OrderTypeCardSelector/index.tsx +10 -12
  63. package/themes/kiosk/src/components/ProductForm/index.tsx +174 -125
  64. package/themes/kiosk/src/components/ProductForm/styles.tsx +1 -1
  65. package/themes/kiosk/src/components/ProductOption/index.tsx +1 -0
  66. package/themes/kiosk/src/components/ProductOption/styles.tsx +1 -0
  67. package/themes/kiosk/src/components/UpsellingProducts/index.tsx +48 -34
  68. package/themes/kiosk/src/components/shared/OButton.tsx +5 -18
  69. package/themes/kiosk/src/components/shared/OCard.tsx +112 -78
  70. package/themes/kiosk/src/types/index.d.ts +2 -0
  71. package/themes/original/index.tsx +178 -1
  72. package/themes/original/src/components/AddressForm/index.tsx +15 -10
  73. package/themes/original/src/components/AddressList/index.tsx +56 -18
  74. package/themes/original/src/components/AppleLogin/index.tsx +117 -78
  75. package/themes/original/src/components/BusinessBasicInformation/index.tsx +96 -45
  76. package/themes/original/src/components/BusinessBasicInformation/styles.tsx +28 -1
  77. package/themes/original/src/components/BusinessController/index.tsx +52 -22
  78. package/themes/original/src/components/BusinessController/styles.tsx +22 -0
  79. package/themes/original/src/components/BusinessFeaturedController/index.tsx +20 -1
  80. package/themes/original/src/components/BusinessFeaturedController/styles.tsx +23 -0
  81. package/themes/original/src/components/BusinessListingSearch/index.tsx +4 -0
  82. package/themes/original/src/components/BusinessMenuList/index.tsx +11 -4
  83. package/themes/original/src/components/BusinessPreorder/index.tsx +141 -121
  84. package/themes/original/src/components/BusinessProductsCategories/index.tsx +7 -5
  85. package/themes/original/src/components/BusinessProductsList/index.tsx +127 -20
  86. package/themes/original/src/components/BusinessProductsList/styles.tsx +29 -2
  87. package/themes/original/src/components/BusinessProductsListing/index.tsx +92 -37
  88. package/themes/original/src/components/BusinessProductsListing/styles.tsx +22 -0
  89. package/themes/original/src/components/BusinessReviews/index.tsx +4 -25
  90. package/themes/original/src/components/BusinessTypeFilter/index.tsx +1 -2
  91. package/themes/original/src/components/BusinessesListing/index.tsx +48 -57
  92. package/themes/original/src/components/Cart/index.tsx +18 -14
  93. package/themes/original/src/components/CartContent/index.tsx +2 -2
  94. package/themes/original/src/components/Checkout/index.tsx +42 -27
  95. package/themes/original/src/components/ForgotPasswordForm/index.tsx +84 -4
  96. package/themes/original/src/components/GoogleMap/index.tsx +1 -0
  97. package/themes/original/src/components/Help/index.tsx +21 -4
  98. package/themes/original/src/components/HighestRatedBusinesses/index.tsx +97 -89
  99. package/themes/original/src/components/Home/index.tsx +1 -1
  100. package/themes/original/src/components/LastOrders/index.tsx +12 -1
  101. package/themes/original/src/components/LoginForm/index.tsx +73 -2
  102. package/themes/original/src/components/LoginForm/styles.tsx +6 -1
  103. package/themes/original/src/components/MessageListing/index.tsx +10 -1
  104. package/themes/original/src/components/Messages/index.tsx +34 -25
  105. package/themes/original/src/components/Messages/styles.tsx +1 -3
  106. package/themes/original/src/components/MomentOption/index.tsx +10 -1
  107. package/themes/original/src/components/MomentOption/styles.tsx +1 -1
  108. package/themes/original/src/components/OrderDetails/index.tsx +34 -27
  109. package/themes/original/src/components/OrderDetails/styles.tsx +1 -2
  110. package/themes/original/src/components/OrderProgress/index.tsx +4 -4
  111. package/themes/original/src/components/OrderProgress/styles.tsx +1 -0
  112. package/themes/original/src/components/OrderSummary/index.tsx +2 -2
  113. package/themes/original/src/components/OrderTypeSelector/index.tsx +4 -2
  114. package/themes/original/src/components/OrdersOption/index.tsx +25 -33
  115. package/themes/original/src/components/OrdersOption/styles.tsx +0 -6
  116. package/themes/original/src/components/PaymentOptionWallet/index.tsx +10 -4
  117. package/themes/original/src/components/PaymentOptionWallet/styles.tsx +1 -1
  118. package/themes/original/src/components/PaymentOptions/index.tsx +9 -19
  119. package/themes/original/src/components/PreviousOrders/index.tsx +19 -13
  120. package/themes/original/src/components/ProductForm/index.tsx +40 -33
  121. package/themes/original/src/components/ProductForm/styles.tsx +2 -2
  122. package/themes/original/src/components/ProductOptionSubOption/index.tsx +5 -3
  123. package/themes/original/src/components/Promotions/index.tsx +250 -0
  124. package/themes/original/src/components/Promotions/styles.tsx +60 -0
  125. package/themes/original/src/components/ReviewOrder/index.tsx +10 -9
  126. package/themes/original/src/components/ReviewProducts/index.tsx +1 -1
  127. package/themes/original/src/components/Sessions/index.tsx +160 -0
  128. package/themes/original/src/components/Sessions/styles.tsx +15 -0
  129. package/themes/original/src/components/SingleProductCard/index.tsx +47 -21
  130. package/themes/original/src/components/SingleProductCard/styles.tsx +28 -1
  131. package/themes/original/src/components/StripeElementsForm/index.tsx +55 -72
  132. package/themes/original/src/components/TaxInformation/index.tsx +10 -4
  133. package/themes/original/src/components/UpsellingProducts/index.tsx +87 -71
  134. package/themes/original/src/components/UserDetails/index.tsx +4 -95
  135. package/themes/original/src/components/UserFormDetails/index.tsx +32 -31
  136. package/themes/original/src/components/UserProfile/index.tsx +62 -14
  137. package/themes/original/src/components/UserProfileForm/index.tsx +20 -18
  138. package/themes/original/src/components/VerifyPhone/index.tsx +10 -7
  139. package/themes/original/src/components/VerifyPhone/styles.tsx +2 -1
  140. package/themes/original/src/components/Wallets/index.tsx +75 -8
  141. package/themes/original/src/components/Wallets/styles.tsx +21 -0
  142. package/themes/original/src/components/shared/HeaderTitle.tsx +21 -0
  143. package/themes/original/src/components/shared/index.tsx +2 -0
  144. package/themes/original/src/config/constants.tsx +6 -6
  145. package/themes/original/src/types/index.tsx +46 -4
  146. package/themes/original/src/utils/index.tsx +12 -2
  147. package/themes/single-business/src/components/AddressList/index.tsx +1 -1
  148. package/themes/single-business/src/components/OrderTypeSelector/index.tsx +6 -6
  149. package/themes/single-business/src/components/UserProfile/index.tsx +1 -1
  150. package/themes/uber-eats/src/components/BusinessesListing/index.tsx +1 -1
  151. package/src/components/StripeMethodForm/index.tsx +0 -168
@@ -47,7 +47,7 @@ import { getTypesText, convertToRadian } from '../../utils';
47
47
  import { OrderProgress } from '../OrderProgress';
48
48
  import { useFocusEffect, useIsFocused } from '@react-navigation/native';
49
49
 
50
- const PIXELS_TO_SCROLL = 1000;
50
+ const PIXELS_TO_SCROLL = 2000;
51
51
 
52
52
  const BusinessesListingUI = (props: BusinessesListingParams) => {
53
53
  const {
@@ -61,7 +61,6 @@ const BusinessesListingUI = (props: BusinessesListingParams) => {
61
61
  handleChangeSearch,
62
62
  businessId
63
63
  } = props;
64
-
65
64
  const theme = useTheme();
66
65
  const isFocused = useIsFocused();
67
66
  const appState = useRef(AppState.currentState)
@@ -117,10 +116,10 @@ const BusinessesListingUI = (props: BusinessesListingParams) => {
117
116
  const [featuredBusiness, setFeaturedBusinesses] = useState(Array);
118
117
  const [isFarAway, setIsFarAway] = useState(false)
119
118
  const [businessTypes, setBusinessTypes] = useState(null)
120
-
119
+ const [orderTypeValue, setOrderTypeValue] = useState(orderState?.options.value)
121
120
  const isPreorderEnabled = (configs?.preorder_status_enabled?.value === '1' || configs?.preorder_status_enabled?.value === 'true') &&
122
121
  Number(configs?.max_days_preorder?.value) > 0
123
-
122
+ const isPreOrderSetting = configs?.preorder_status_enabled?.value === '1'
124
123
  const timerId = useRef<any>(false)
125
124
  // const panResponder = useRef(
126
125
  // PanResponder.create({
@@ -166,8 +165,15 @@ const BusinessesListingUI = (props: BusinessesListingParams) => {
166
165
  return R * c
167
166
  }
168
167
 
168
+ const resetInactivityTimeout = () => {
169
+ clearTimeout(timerId.current)
170
+ timerId.current = setInterval(() => {
171
+ getBusinesses(true)
172
+ }, 120000)
173
+ }
174
+
169
175
  useEffect(() => {
170
- if (businessesList.businesses.length > 0) {
176
+ if (!businessesList?.loading) {
171
177
  const fb = businessesList.businesses.filter((b) => b.featured === true && b?.open);
172
178
  const ary = [];
173
179
  while (fb.length > 0) {
@@ -175,16 +181,6 @@ const BusinessesListingUI = (props: BusinessesListingParams) => {
175
181
  }
176
182
  setFeaturedBusinesses(ary);
177
183
  }
178
- }, [businessesList.businesses]);
179
-
180
- const resetInactivityTimeout = () => {
181
- clearTimeout(timerId.current)
182
- timerId.current = setInterval(() => {
183
- getBusinesses(true)
184
- }, 300000)
185
- }
186
-
187
- useEffect(() => {
188
184
  resetInactivityTimeout()
189
185
  }, [businessesList.loading])
190
186
 
@@ -208,26 +204,13 @@ const BusinessesListingUI = (props: BusinessesListingParams) => {
208
204
  }, [orderState?.options?.address?.location])
209
205
 
210
206
  useEffect(() => {
211
- const onFocusApp = (nextAppState: any) => {
212
- if (
213
- appState.current.match(/inactive|background/) &&
214
- nextAppState === "active"
215
- ) {
216
- getBusinesses(true);
217
- }
218
- appState.current = nextAppState;
219
- setAppStateVisible(appState.current);
207
+ if(!orderState?.loading){
208
+ setOrderTypeValue(orderState?.options?.type)
220
209
  }
221
-
222
- AppState.addEventListener("change", onFocusApp);
223
- return () => {
224
- AppState.removeEventListener('change', onFocusApp);
225
- };
226
- }, [])
210
+ }, [orderState?.options?.type])
227
211
 
228
212
  useFocusEffect(
229
213
  useCallback(() => {
230
- getBusinesses(true)
231
214
  resetInactivityTimeout()
232
215
  return () => clearTimeout(timerId.current)
233
216
  }, [navigation])
@@ -280,33 +263,35 @@ const BusinessesListingUI = (props: BusinessesListingParams) => {
280
263
  )}
281
264
  <OrderControlContainer>
282
265
  <View style={styles.wrapperOrderOptions}>
283
- <WrapMomentOption onPress={() => navigation.navigate('OrderTypes', { configTypes: configTypes })}>
284
- <OText size={12} numberOfLines={1} ellipsizeMode={'tail'} color={theme.colors.textSecondary}>{t(getTypesText(orderState?.options?.type || 1), 'Delivery')}</OText>
266
+ <WrapMomentOption onPress={() => navigation.navigate('OrderTypes', { configTypes: configTypes, setOrderTypeValue })}>
267
+ <OText size={12} numberOfLines={1} ellipsizeMode={'tail'} color={theme.colors.textSecondary}>{t(getTypesText(orderTypeValue || orderState?.options?.type || 1), 'Delivery')}</OText>
285
268
  <OIcon
286
269
  src={theme.images.general.arrow_down}
287
270
  width={10}
288
271
  style={{ marginStart: 8 }}
289
272
  />
290
273
  </WrapMomentOption>
291
- <WrapMomentOption
292
- onPress={() => handleMomentClick()}>
293
- <OText
294
- size={12}
295
- numberOfLines={1}
296
- ellipsizeMode="tail"
297
- color={theme.colors.textSecondary}>
298
- {orderState.options?.momentß
299
- ? parseDate(orderState.options?.moment, { outputFormat: configs?.dates_moment_format?.value })
300
- : t('ASAP_ABBREVIATION', 'ASAP')}
301
- </OText>
302
- {isPreorderEnabled && (
303
- <OIcon
304
- src={theme.images.general.arrow_down}
305
- width={10}
306
- style={{ marginStart: 8 }}
307
- />
308
- )}
309
- </WrapMomentOption>
274
+ {isPreOrderSetting && (
275
+ <WrapMomentOption
276
+ onPress={() => handleMomentClick()}>
277
+ <OText
278
+ size={12}
279
+ numberOfLines={1}
280
+ ellipsizeMode="tail"
281
+ color={theme.colors.textSecondary}>
282
+ {orderState.options?.moment
283
+ ? parseDate(orderState.options?.moment, { outputFormat: configs?.dates_moment_format?.value })
284
+ : t('ASAP_ABBREVIATION', 'ASAP')}
285
+ </OText>
286
+ {isPreorderEnabled && (
287
+ <OIcon
288
+ src={theme.images.general.arrow_down}
289
+ width={10}
290
+ style={{ marginStart: 8 }}
291
+ />
292
+ )}
293
+ </WrapMomentOption>
294
+ )}
310
295
 
311
296
  {!businessId && (
312
297
  <SearchBar
@@ -338,7 +323,7 @@ const BusinessesListingUI = (props: BusinessesListingParams) => {
338
323
  {
339
324
  !businessId && !props.franchiseId && featuredBusiness && featuredBusiness.length > 0 && (
340
325
  <FeaturedWrapper>
341
- <OText size={16} style={{ marginLeft: 40 }} weight={Platform.OS === 'ios' ? '600' : 'bold'}>{t('FEATURED_BUSINESS', 'Featured business')}</OText>
326
+ <OText size={16} style={{ marginLeft: 40 }} weight={Platform.OS === 'ios' ? '600' : 'bold'}>{t('BUSINESS_FEATURE', 'Featured business')}</OText>
342
327
  <ScrollView
343
328
  showsHorizontalScrollIndicator={false}
344
329
  nestedScrollEnabled
@@ -346,7 +331,6 @@ const BusinessesListingUI = (props: BusinessesListingParams) => {
346
331
  {featuredBusiness.map((bAry: any, idx) => (
347
332
  <View key={'f-listing_' + idx}>
348
333
  <BusinessFeaturedController
349
- key={bAry[0].id}
350
334
  business={bAry[0]}
351
335
  isBusinessOpen={bAry[0]?.open}
352
336
  handleCustomClick={handleBusinessClick}
@@ -354,7 +338,6 @@ const BusinessesListingUI = (props: BusinessesListingParams) => {
354
338
  />
355
339
  {bAry.length > 1 && (
356
340
  <BusinessFeaturedController
357
- key={bAry[1].id}
358
341
  business={bAry[1]}
359
342
  isBusinessOpen={bAry[1]?.open}
360
343
  handleCustomClick={handleBusinessClick}
@@ -393,14 +376,22 @@ const BusinessesListingUI = (props: BusinessesListingParams) => {
393
376
  />
394
377
  )}
395
378
  {businessesList.businesses?.map(
396
- (business: any) => (
379
+ (business: any, i : number) => (
397
380
  <BusinessController
398
- key={business.id}
381
+ key={`${business.id}_` + i}
399
382
  business={business}
400
383
  isBusinessOpen={business.open}
401
384
  handleCustomClick={handleBusinessClick}
402
385
  orderType={orderState?.options?.type}
403
386
  navigation={navigation}
387
+ businessHeader={business?.header}
388
+ businessFeatured={business?.featured}
389
+ businessLogo={business?.logo}
390
+ businessReviews={business?.reviews}
391
+ businessDeliveryPrice={business?.delivery_price}
392
+ businessDeliveryTime={business?.delivery_time}
393
+ businessPickupTime={business?.pickup_time}
394
+ businessDistance={business?.distance}
404
395
  />
405
396
  )
406
397
  )}
@@ -166,9 +166,9 @@ const CartUI = (props: any) => {
166
166
  handleClickCheckout={() => setOpenUpselling(true)}
167
167
  checkoutButtonDisabled={(openUpselling && !canOpenUpselling) || cart?.subtotal < cart?.minimum || !cart?.valid_address}
168
168
  >
169
- {cart?.products?.length > 0 && cart?.products.map((product: any) => (
169
+ {cart?.products?.length > 0 && cart?.products.map((product: any, i: number) => (
170
170
  <ProductItemAccordion
171
- key={product.code}
171
+ key={`${product.code}_${i}`}
172
172
  isCartPending={isCartPending}
173
173
  isCartProduct
174
174
  product={product}
@@ -202,8 +202,8 @@ const CartUI = (props: any) => {
202
202
  </OSTable>
203
203
  )}
204
204
  {
205
- cart?.offers?.length > 0 && cart?.offers?.filter((offer: any) => offer?.target === 1)?.map((offer: any) => (
206
- <OSTable key={offer.id}>
205
+ cart?.offers?.length > 0 && cart?.offers?.filter((offer: any) => offer?.target === 1)?.map((offer: any, i: number) => (
206
+ <OSTable key={`${offer.id}_${i}`}>
207
207
  <OSRow>
208
208
  <OText size={12} lineHeight={18}>{offer.name}</OText>
209
209
  {offer.rate_type === 1 && (
@@ -234,8 +234,8 @@ const CartUI = (props: any) => {
234
234
  </OSTable>
235
235
  )}
236
236
  {
237
- cart.taxes?.length > 0 && cart.taxes.filter((tax: any) => tax.type === 2 && tax?.rate !== 0).map((tax: any) => (
238
- <OSTable key={tax.id}>
237
+ cart.taxes?.length > 0 && cart.taxes.filter((tax: any) => tax.type === 2 && tax?.rate !== 0).map((tax: any, i: number) => (
238
+ <OSTable key={`${tax.id}_${i}`}>
239
239
  <OSRow>
240
240
  <OText size={12} lineHeight={18} numberOfLines={1} >
241
241
  {tax.name || t('INHERIT_FROM_BUSINESS', 'Inherit from business')}{' '}
@@ -250,12 +250,12 @@ const CartUI = (props: any) => {
250
250
  ))
251
251
  }
252
252
  {
253
- cart?.fees?.length > 0 && cart?.fees?.filter((fee: any) => !(fee.fixed === 0 && fee.percentage === 0)).map((fee: any) => (
254
- <OSTable key={fee?.id}>
253
+ cart?.fees?.length > 0 && cart?.fees?.filter((fee: any) => !(fee.fixed === 0 && fee.percentage === 0)).map((fee: any, i: number) => (
254
+ <OSTable key={`${fee.id}_${i}`}>
255
255
  <OSRow>
256
256
  <OText size={12} lineHeight={18} numberOfLines={1}>
257
257
  {fee.name || t('INHERIT_FROM_BUSINESS', 'Inherit from business')}{' '}
258
- ({fee?.fixed > 0 && `${parsePrice(fee?.fixed)} + `}{fee.percentage}%){' '}
258
+ ({fee?.fixed > 0 && `${parsePrice(fee?.fixed)}${fee.percentage > 0 ? ' + ' : ''}`}{fee.percentage > 0 && `${fee.percentage}%`}){' '}
259
259
  </OText>
260
260
  <TouchableOpacity onPress={() => setOpenTaxModal({ open: true, data: fee, type: 'fee' })} >
261
261
  <AntIcon name='infocirlceo' size={16} color={theme.colors.primary} />
@@ -293,8 +293,8 @@ const CartUI = (props: any) => {
293
293
  </OSTable>
294
294
  )}
295
295
  {
296
- cart?.offers?.length > 0 && cart?.offers?.filter((offer: any) => offer?.target === 2)?.map((offer: any) => (
297
- <OSTable key={offer.id}>
296
+ cart?.offers?.length > 0 && cart?.offers?.filter((offer: any) => offer?.target === 2)?.map((offer: any, i: number) => (
297
+ <OSTable key={`${offer.id}_${i}`}>
298
298
  <OSRow>
299
299
  <OText size={12} lineHeight={18}>{offer.name}</OText>
300
300
  {offer.rate_type === 1 && (
@@ -409,7 +409,7 @@ const CartUI = (props: any) => {
409
409
  )}
410
410
  </OSBill>
411
411
  )}
412
- {cart?.valid_products && (
412
+ {cart?.valid_products ? (
413
413
  <CheckoutAction>
414
414
  <OButton
415
415
  text={(cart?.subtotal >= cart?.minimum || !cart?.minimum) && cart?.valid_address ? (
@@ -428,6 +428,12 @@ const CartUI = (props: any) => {
428
428
  style={{ width: '100%', flexDirection: 'row', justifyContent: 'center', borderRadius: 7.6, shadowOpacity: 0 }}
429
429
  />
430
430
  </CheckoutAction>
431
+ ) : (
432
+ <View style={{ alignItems: 'center', width: '100%' }}>
433
+ <OText size={12} color={theme.colors.red} style={{ textAlign: 'center', marginTop: 5 }}>
434
+ {t('WARNING_INVALID_PRODUCTS_CHECKOUT', 'To continue with your checkout, please remove from your cart the products that are not available.')}
435
+ </OText>
436
+ </View>
431
437
  )}
432
438
  </BusinessItemAccordion>
433
439
 
@@ -446,8 +452,6 @@ const CartUI = (props: any) => {
446
452
  open={openTaxModal.open}
447
453
  onClose={() => setOpenTaxModal({ open: false, data: null, type: '' })}
448
454
  entireModal
449
- title={`${openTaxModal.data?.name ||
450
- t('INHERIT_FROM_BUSINESS', 'Inherit from business')} ${openTaxModal.data?.rate_type !== 2 ? `(${typeof openTaxModal.data?.rate === 'number' ? `${openTaxModal.data?.rate}%` : `${parsePrice(openTaxModal.data?.fixed ?? 0)} + ${openTaxModal.data?.percentage}%`})` : ''} `}
451
455
  >
452
456
  <TaxInformation
453
457
  type={openTaxModal.type}
@@ -22,9 +22,9 @@ export const CartContent = (props: any) => {
22
22
  <CCContainer>
23
23
  {isOrderStateCarts && carts?.length > 0 && (
24
24
  <>
25
- <OText size={24} lineHeight={36} weight={'600'} style={{ marginBottom: 20 }}>
25
+ {/* <OText size={24} lineHeight={36} weight={'600'} style={{ marginBottom: 20 }}>
26
26
  {carts.length > 1 ? t('MY_CARTS', 'My Carts') : t('CART', 'Cart')}
27
- </OText>
27
+ </OText> */}
28
28
  {carts.map((cart: any, i: number) => (
29
29
  <CCList key={i} style={{ overflow: 'visible' }}>
30
30
  {cart.products.length > 0 && (
@@ -112,7 +112,10 @@ const CheckoutUI = (props: any) => {
112
112
  right: Platform.OS === 'ios' ? 5 : (I18nManager.isRTL ? 30 : 0),
113
113
  position: 'absolute',
114
114
  fontSize: 20
115
- }
115
+ },
116
+ wrapperNavbar: Platform.OS === 'ios'
117
+ ? { paddingVertical: 0, paddingHorizontal: 40 }
118
+ : { paddingVertical: 20, paddingHorizontal: 40 }
116
119
  })
117
120
 
118
121
  const [, { showToast }] = useToast();
@@ -132,11 +135,20 @@ const CheckoutUI = (props: any) => {
132
135
  const [isDeliveryOptionModalVisible, setIsDeliveryOptionModalVisible] = useState(false)
133
136
  const [showGateway, setShowGateway] = useState<any>({ closedByUsed: false, open: false });
134
137
  const [webviewPaymethod, setWebviewPaymethod] = useState<any>(null)
135
-
138
+
136
139
  const placeSpotTypes = [3, 4]
137
- const isWalletEnabled = configs?.wallet_enabled?.value === '1' && (configs?.wallet_cash_enabled?.value === '1' || configs?.wallet_credit_point_enabled?.value === '1')
140
+ const businessConfigs = businessDetails?.business?.configs ?? []
141
+ const isWalletCashEnabled = businessConfigs.find((config: any) => config.key === 'wallet_cash_enabled')?.value === '1'
142
+ const isWalletCreditPointsEnabled = businessConfigs.find((config: any) => config.key === 'wallet_credit_point_enabled')?.value === '1'
143
+ const isWalletEnabled = configs?.cash_wallet?.value && configs?.wallet_enabled?.value === '1' && (isWalletCashEnabled || isWalletCreditPointsEnabled)
144
+
138
145
  const isPreOrder = configs?.preorder_status_enabled?.value === '1'
139
- const isDisabledButtonPlace = loading || !cart?.valid || (!paymethodSelected && cart?.balance > 0) || placing || errorCash || cart?.subtotal < cart?.minimum || (placeSpotTypes.includes(options?.type) && !cart?.place)
146
+ const isDisabledButtonPlace = loading || !cart?.valid || (!paymethodSelected && cart?.balance > 0) || placing || errorCash ||
147
+ cart?.subtotal < cart?.minimum || (placeSpotTypes.includes(options?.type) && !cart?.place) ||
148
+ (options.type === 1 &&
149
+ validationFields?.fields?.checkout?.driver_tip?.enabled &&
150
+ validationFields?.fields?.checkout?.driver_tip?.required &&
151
+ (Number(cart?.driver_tip) <= 0))
140
152
 
141
153
  const driverTipsOptions = typeof configs?.driver_tip_options?.value === 'string'
142
154
  ? JSON.parse(configs?.driver_tip_options?.value) || []
@@ -249,13 +261,18 @@ const CheckoutUI = (props: any) => {
249
261
  return (
250
262
  <>
251
263
  <Container noPadding>
252
- <NavBar
253
- isVertical
254
- onActionLeft={() => navigation?.canGoBack() && navigation.goBack()}
255
- title={t('CHECKOUT', 'Checkout')}
256
- style={styles.pagePadding}
257
- titleStyle={{ marginLeft: 0, marginRight: 0 }}
258
- />
264
+ <View style={styles.wrapperNavbar}>
265
+ <NavBar
266
+ title={t('CHECKOUT', 'Checkout')}
267
+ titleAlign={'center'}
268
+ onActionLeft={() => navigation?.canGoBack() && navigation.goBack()}
269
+ showCall={false}
270
+ btnStyle={{ paddingLeft: 0 }}
271
+ style={{ marginTop: Platform.OS === 'ios' ? 0 : 30 }}
272
+ titleWrapStyle={{ paddingHorizontal: 0 }}
273
+ titleStyle={{ marginRight: 0, marginLeft: 0 }}
274
+ />
275
+ </View>
259
276
  <ChContainer style={styles.pagePadding}>
260
277
  <ChSection style={{ paddingTop: 0 }}>
261
278
  <ChHeader>
@@ -546,17 +563,17 @@ const CheckoutUI = (props: any) => {
546
563
  onNavigationRedirect={onNavigationRedirect}
547
564
  paySelected={paymethodSelected}
548
565
  handlePaymentMethodClickCustom={handlePaymentMethodClick}
549
- handlePlaceOrder={handlePlaceOrder}
550
566
  />
551
567
  </ChPaymethods>
552
568
  </ChSection>
553
569
  )}
554
570
 
555
- {!cartState.loading && cart && isWalletEnabled && (
571
+ {!cartState.loading && cart && isWalletEnabled && businessDetails?.business?.configs && (
556
572
  <WalletPaymentOptionContainer>
557
573
  <PaymentOptionWallet
558
574
  cart={cart}
559
575
  businessId={cart?.business_id}
576
+ businessConfigs={businessDetails?.business?.configs}
560
577
  />
561
578
  </WalletPaymentOptionContainer>
562
579
  )}
@@ -646,7 +663,7 @@ const CheckoutUI = (props: any) => {
646
663
  color={theme.colors.error}
647
664
  size={12}
648
665
  >
649
- {t('WARNING_INVALID_PRODUCTS', 'Some products are invalid, please check them.')}
666
+ {t('WARNING_INVALID_PRODUCTS_CHECKOUT', 'To continue with your checkout, please remove from your cart the products that are not available.')}
650
667
  </OText>
651
668
  )}
652
669
  {placeSpotTypes.includes(options?.type) && !cart?.place && (
@@ -657,6 +674,17 @@ const CheckoutUI = (props: any) => {
657
674
  {t('WARNING_PLACE_SPOT', 'Please, select your spot to place order.')}
658
675
  </OText>
659
676
  )}
677
+ {options.type === 1 &&
678
+ validationFields?.fields?.checkout?.driver_tip?.enabled &&
679
+ validationFields?.fields?.checkout?.driver_tip?.required &&
680
+ (Number(cart?.driver_tip) <= 0) && (
681
+ <OText
682
+ color={theme.colors.error}
683
+ size={12}
684
+ >
685
+ {t('WARNING_INVALID_DRIVER_TIP', 'Driver Tip is required.')}
686
+ </OText>
687
+ )}
660
688
  </ChErrors>
661
689
  </View>
662
690
  )}
@@ -705,19 +733,6 @@ const CheckoutUI = (props: any) => {
705
733
  setShowGateway={setShowGateway}
706
734
  />
707
735
  )}
708
- {webviewPaymethod?.gateway === 'square' && showGateway.open && (
709
- <PaymentOptionsWebView
710
- onNavigationRedirect={onNavigationRedirect}
711
- uri={`https://test-square-f50f7.web.app`}
712
- user={user}
713
- token={token}
714
- cart={cart}
715
- currency={currency}
716
- webviewPaymethod={webviewPaymethod}
717
- setShowGateway={setShowGateway}
718
- locationId={'L1NGAY5M6KJRX'}
719
- />
720
- )}
721
736
  </>
722
737
  )
723
738
  }
@@ -1,16 +1,20 @@
1
- import React, { useEffect, useState } from 'react';
1
+ import React, { useEffect, useState, useRef } from 'react';
2
2
  import { StyleSheet } from 'react-native';
3
3
  import { useForm, Controller } from 'react-hook-form';
4
+ import Recaptcha from 'react-native-recaptcha-that-works'
5
+ import { TouchableOpacity } from 'react-native-gesture-handler';
6
+ import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons';
4
7
 
5
8
  import {
6
9
  ForgotPasswordForm as ForgotPasswordController,
7
10
  useLanguage,
8
11
  useToast,
9
12
  ToastType,
13
+ useConfig
10
14
  } from 'ordering-components/native';
11
15
  import { useTheme } from 'styled-components/native';
12
16
  import NavBar from '../NavBar';
13
- import { FormInput, FormSide } from '../LoginForm/styles'
17
+ import { FormInput, FormSide, RecaptchaButton } from '../LoginForm/styles'
14
18
  import { Container } from './styles'
15
19
 
16
20
  import { OButton, OInput, OText } from '../shared';
@@ -20,10 +24,16 @@ const ForgotPasswordUI = (props: any) => {
20
24
  navigation,
21
25
  formState,
22
26
  handleButtonForgotPasswordClick,
27
+ handleReCaptcha,
28
+ enableReCaptcha,
29
+ reCaptchaValue
23
30
  } = props;
24
31
  const [, t] = useLanguage();
25
32
  const [, { showToast }] = useToast();
33
+ const [{ configs }] = useConfig();
26
34
  const { control, handleSubmit, errors } = useForm();
35
+ const [recaptchaConfig, setRecaptchaConfig] = useState<any>({})
36
+ const [recaptchaVerified, setRecaptchaVerified] = useState(false)
27
37
 
28
38
  const theme = useTheme();
29
39
 
@@ -38,6 +48,7 @@ const ForgotPasswordUI = (props: any) => {
38
48
  });
39
49
 
40
50
  const [emailSent, setEmailSent] = useState(null);
51
+ const recaptchaRef = useRef<any>({});
41
52
 
42
53
  const onSubmit = (values: any) => {
43
54
  setEmailSent(values.email)
@@ -48,23 +59,60 @@ const ForgotPasswordUI = (props: any) => {
48
59
  onChange(value.toLowerCase().replace(/[&,()%";:ç?<>{}\\[\]\s]/g, ''))
49
60
  }
50
61
 
62
+ const handleOpenRecaptcha = () => {
63
+ setRecaptchaVerified(false)
64
+ handleReCaptcha(null)
65
+ if (reCaptchaValue) return
66
+
67
+ if (!recaptchaConfig?.siteKey) {
68
+ showToast(ToastType.Error, t('NO_RECAPTCHA_SITE_KEY', 'The config doesn\'t have recaptcha site key'));
69
+ return
70
+ }
71
+ if (!recaptchaConfig?.baseUrl) {
72
+ showToast(ToastType.Error, t('NO_RECAPTCHA_BASE_URL', 'The config doesn\'t have recaptcha base url'));
73
+ return
74
+ }
75
+ recaptchaRef.current.open()
76
+ }
77
+
78
+ const onRecaptchaVerify = (token: any) => {
79
+ setRecaptchaVerified(true)
80
+ handleReCaptcha(token)
81
+ }
82
+
83
+ const handleRecaptchaExpire = () => {
84
+ setRecaptchaVerified(false)
85
+ handleReCaptcha(null)
86
+ }
87
+
51
88
  useEffect(() => {
52
89
  if (!formState.loading && emailSent) {
53
90
  if (formState.result?.error) {
54
91
  setEmailSent(null)
55
92
  formState.result?.result && showToast(
56
93
  ToastType.Error,
57
- formState.result?.result[0]
94
+ typeof formState.result?.result === 'string'
95
+ ? formState.result?.result
96
+ : formState.result?.result[0]
58
97
  )
59
98
  return
60
99
  }
61
100
  showToast(
62
101
  ToastType.Success,
63
- `${t('SUCCESS_SEND_FORGOT_PASSWORD', 'Your link has been sent to the email')}: ${emailSent}`
102
+ t('IF_ACCOUNT_EXIST_EMAIL_SEND_PASSWORD', 'If an account exists with this email a password will be sent')
64
103
  )
65
104
  }
66
105
  }, [formState])
67
106
 
107
+ useEffect(() => {
108
+ if (configs && Object.keys(configs).length > 0 && enableReCaptcha) {
109
+ setRecaptchaConfig({
110
+ siteKey: configs?.security_recaptcha_site_key?.value || null,
111
+ baseUrl: configs?.security_recaptcha_base_url?.value || null
112
+ })
113
+ }
114
+ }, [configs, enableReCaptcha])
115
+
68
116
  return (
69
117
  <Container>
70
118
  <NavBar
@@ -126,6 +174,37 @@ const ForgotPasswordUI = (props: any) => {
126
174
  }}
127
175
  defaultValue=""
128
176
  />
177
+ {enableReCaptcha && (
178
+ <>
179
+ <TouchableOpacity
180
+ onPress={handleOpenRecaptcha}
181
+ >
182
+ <RecaptchaButton>
183
+ {recaptchaVerified ? (
184
+ <MaterialCommunityIcons
185
+ name="checkbox-marked"
186
+ size={26}
187
+ color={theme.colors.primary}
188
+ />
189
+ ) : (
190
+ <MaterialCommunityIcons
191
+ name="checkbox-blank-outline"
192
+ size={26}
193
+ color={theme.colors.mediumGray}
194
+ />
195
+ )}
196
+ <OText size={14} mLeft={8}>{t('VERIFY_ReCAPTCHA', 'Verify reCAPTCHA')}</OText>
197
+ </RecaptchaButton>
198
+ </TouchableOpacity>
199
+ <Recaptcha
200
+ ref={recaptchaRef}
201
+ siteKey={recaptchaConfig?.siteKey}
202
+ baseUrl={recaptchaConfig?.baseUrl}
203
+ onVerify={onRecaptchaVerify}
204
+ onExpire={handleRecaptchaExpire}
205
+ />
206
+ </>
207
+ )}
129
208
 
130
209
  <OButton
131
210
  text={emailSent && !formState.result?.error ? t('LINK_SEND_FORGOT_PASSWORD', 'Link Sent') : t('FRONT_RECOVER_PASSWORD', 'Recover Password')}
@@ -146,6 +225,7 @@ const ForgotPasswordUI = (props: any) => {
146
225
  export const ForgotPasswordForm = (props: any) => {
147
226
  const ForgotPasswordProps = {
148
227
  ...props,
228
+ isRecaptchaEnable: true,
149
229
  UIComponent: ForgotPasswordUI
150
230
  }
151
231
  return <ForgotPasswordController {...ForgotPasswordProps} />
@@ -193,6 +193,7 @@ export const GoogleMap = (props: GoogleMapsParams) => {
193
193
  <React.Fragment key={i}>
194
194
  {
195
195
  <Marker
196
+ zIndex={i}
196
197
  coordinate={location}
197
198
  title={locations[i]?.title}
198
199
  >
@@ -1,9 +1,11 @@
1
- import React from 'react'
1
+ import React, { useState } from 'react'
2
+ import { RefreshControl } from 'react-native'
2
3
  import { HelpParams } from '../../types'
3
4
  import { useLanguage } from 'ordering-components/native'
4
5
  import NavBar from '../NavBar'
5
6
  import { OText } from '../shared'
6
7
  import { LastOrders } from '../LastOrders'
8
+ import { Container } from '../../layouts/Container'
7
9
 
8
10
  import {
9
11
  HelpSubItem,
@@ -15,13 +17,28 @@ export const Help = (props: HelpParams) => {
15
17
  navigation
16
18
  } = props
17
19
  const [, t] = useLanguage()
20
+ const [refreshing] = useState(false);
21
+ const [refresh, setRefresh] = useState(false)
18
22
 
19
23
  const goToBack = () => navigation?.canGoBack() && navigation.goBack()
20
24
  const onRedirect = (route: string, params?: any) => {
21
25
  navigation.navigate(route, params)
22
26
  }
27
+
28
+ const handleOnRefresh = () => {
29
+ setRefresh(true)
30
+ }
31
+
23
32
  return (
24
- <>
33
+ <Container
34
+ noPadding
35
+ refreshControl={
36
+ <RefreshControl
37
+ refreshing={refreshing}
38
+ onRefresh={() => handleOnRefresh()}
39
+ />
40
+ }
41
+ >
25
42
  <NavBar
26
43
  title={t('HELP', 'Help')}
27
44
  titleAlign={'center'}
@@ -48,8 +65,8 @@ export const Help = (props: HelpParams) => {
48
65
 
49
66
  <LastOrdersContainer>
50
67
  <OText size={18} weight={600}>{t('LAST_ORDERS', 'Last Orders')}</OText>
51
- <LastOrders {...props} onRedirect={onRedirect} />
68
+ <LastOrders {...props} onRedirect={onRedirect} refresh={refresh} setRefresh={setRefresh} />
52
69
  </LastOrdersContainer>
53
- </>
70
+ </Container>
54
71
  )
55
72
  }