ordering-ui-react-native 0.22.53 → 0.22.54-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 (129) hide show
  1. package/package.json +5 -7
  2. package/src/DeliveryApp.tsx +1 -1
  3. package/src/components/BusinessesListing/index.tsx +1 -1
  4. package/src/components/Checkout/index.tsx +40 -39
  5. package/src/components/VerifyPhone/styles.tsx +1 -2
  6. package/src/context/OfflineActions/index.tsx +236 -0
  7. package/src/providers/AlertProvider.tsx +3 -1
  8. package/themes/business/src/components/AcceptOrRejectOrder/index.tsx +9 -6
  9. package/themes/business/src/components/AcceptOrRejectOrder/styles.tsx +1 -0
  10. package/themes/business/src/components/BusinessController/index.tsx +8 -3
  11. package/themes/business/src/components/BusinessProductList/index.tsx +3 -2
  12. package/themes/business/src/components/Chat/index.tsx +15 -3
  13. package/themes/business/src/components/DriverMap/index.tsx +44 -33
  14. package/themes/business/src/components/FloatingButton/index.tsx +3 -2
  15. package/themes/business/src/components/LanguageSelector/index.tsx +1 -1
  16. package/themes/business/src/components/LoginForm/index.tsx +123 -98
  17. package/themes/business/src/components/LogoutButton/index.tsx +13 -4
  18. package/themes/business/src/components/MapView/index.tsx +22 -17
  19. package/themes/business/src/components/NewOrderNotification/index.tsx +25 -14
  20. package/themes/business/src/components/OrderDetails/Business.tsx +56 -20
  21. package/themes/business/src/components/OrderDetails/Delivery.tsx +134 -53
  22. package/themes/business/src/components/OrderDetails/OrderContentComponent.tsx +155 -45
  23. package/themes/business/src/components/OrderDetails/OrderHeaderComponent.tsx +51 -28
  24. package/themes/business/src/components/OrderDetails/styles.tsx +39 -3
  25. package/themes/business/src/components/OrderDetails/usePrinterCommands.tsx +17 -16
  26. package/themes/business/src/components/OrderDetailsLogistic/index.tsx +3 -2
  27. package/themes/business/src/components/OrderSummary/index.tsx +271 -176
  28. package/themes/business/src/components/OrdersListManager/index.tsx +13 -1
  29. package/themes/business/src/components/OrdersOption/index.tsx +345 -231
  30. package/themes/business/src/components/OrdersOption/styles.tsx +14 -0
  31. package/themes/business/src/components/PreviousMessages/index.tsx +26 -3
  32. package/themes/business/src/components/PreviousOrders/OrderItem.tsx +30 -18
  33. package/themes/business/src/components/PreviousOrders/index.tsx +74 -66
  34. package/themes/business/src/components/PreviousOrders/styles.tsx +2 -1
  35. package/themes/business/src/components/PrinterEdition/MessageAlert.tsx +33 -0
  36. package/themes/business/src/components/PrinterEdition/index.tsx +143 -75
  37. package/themes/business/src/components/PrinterEdition/printerList.tsx +23 -0
  38. package/themes/business/src/components/PrinterSettings/index.tsx +1 -1
  39. package/themes/business/src/components/ProductItemAccordion/index.tsx +3 -2
  40. package/themes/business/src/components/ReviewCustomer/index.tsx +2 -0
  41. package/themes/business/src/components/StoresList/index.tsx +2 -2
  42. package/themes/business/src/components/UserProfileForm/index.tsx +48 -10
  43. package/themes/business/src/components/UserProfileForm/styles.tsx +7 -0
  44. package/themes/business/src/components/WebsocketStatus/index.tsx +2 -2
  45. package/themes/business/src/config/currency.tsx +1010 -0
  46. package/themes/business/src/hooks/useLocation.tsx +16 -12
  47. package/themes/business/src/layouts/SafeAreaContainer.tsx +35 -19
  48. package/themes/business/src/types/index.tsx +22 -7
  49. package/themes/business/src/utils/index.tsx +28 -3
  50. package/themes/doordash/src/components/BusinessesListing/index.tsx +1 -1
  51. package/themes/doordash/src/components/LoginForm/index.tsx +1 -2
  52. package/themes/instacart/src/components/BusinessesListing/index.tsx +1 -1
  53. package/themes/kiosk/src/components/Checkout/index.tsx +9 -5
  54. package/themes/kiosk/src/components/CustomerName/index.tsx +1 -1
  55. package/themes/kiosk/src/components/NavBar/index.tsx +14 -14
  56. package/themes/kiosk/src/components/OptionCard/index.tsx +1 -1
  57. package/themes/kiosk/src/components/OrderTypeCardSelector/index.tsx +8 -10
  58. package/themes/kiosk/src/components/PaymentOptions/index.tsx +121 -57
  59. package/themes/kiosk/src/components/shared/OButton.tsx +5 -18
  60. package/themes/original/index.tsx +9 -1
  61. package/themes/original/src/components/AddressForm/index.tsx +19 -8
  62. package/themes/original/src/components/AppleLogin/index.tsx +4 -4
  63. package/themes/original/src/components/BusinessBasicInformation/index.tsx +1 -1
  64. package/themes/original/src/components/BusinessController/index.tsx +4 -2
  65. package/themes/original/src/components/BusinessItemAccordion/index.tsx +10 -4
  66. package/themes/original/src/components/BusinessListingSearch/BusinessSearchFooter.tsx +103 -92
  67. package/themes/original/src/components/BusinessListingSearch/BusinessSearchHeader.tsx +7 -3
  68. package/themes/original/src/components/BusinessPreorder/index.tsx +34 -15
  69. package/themes/original/src/components/BusinessProductsList/SubcategoriesComponent/index.tsx +73 -70
  70. package/themes/original/src/components/BusinessProductsList/index.tsx +6 -7
  71. package/themes/original/src/components/BusinessProductsList/styles.tsx +0 -3
  72. package/themes/original/src/components/BusinessProductsListing/index.tsx +10 -6
  73. package/themes/original/src/components/BusinessTypeFilter/index.tsx +9 -8
  74. package/themes/original/src/components/BusinessesListing/Layout/Appointment/index.tsx +2 -1
  75. package/themes/original/src/components/BusinessesListing/Layout/Original/styles.tsx +1 -1
  76. package/themes/original/src/components/BusinessesListing/index.tsx +0 -1
  77. package/themes/original/src/components/Cart/index.tsx +48 -13
  78. package/themes/original/src/components/CartContent/index.tsx +2 -3
  79. package/themes/original/src/components/Checkout/index.tsx +109 -82
  80. package/themes/original/src/components/Favorite/index.tsx +1 -5
  81. package/themes/original/src/components/ForgotPasswordForm/index.tsx +1 -2
  82. package/themes/original/src/components/GoogleMap/index.tsx +39 -18
  83. package/themes/original/src/components/HighestRatedBusinesses/index.tsx +1 -1
  84. package/themes/original/src/components/Home/index.tsx +35 -16
  85. package/themes/original/src/components/LoginForm/index.tsx +12 -5
  86. package/themes/original/src/components/MessageListing/index.tsx +1 -1
  87. package/themes/original/src/components/Messages/index.tsx +20 -13
  88. package/themes/original/src/components/MomentOption/TimeListItem.tsx +56 -0
  89. package/themes/original/src/components/MomentOption/index.tsx +72 -51
  90. package/themes/original/src/components/MomentSelector/index.tsx +5 -2
  91. package/themes/original/src/components/MultiCartsPaymethodsAndWallets/index.tsx +1 -0
  92. package/themes/original/src/components/MultiCheckout/index.tsx +55 -26
  93. package/themes/original/src/components/MyOrders/index.tsx +2 -2
  94. package/themes/original/src/components/NavBar/index.tsx +6 -2
  95. package/themes/original/src/components/OrderDetails/OrderEta.tsx +4 -3
  96. package/themes/original/src/components/OrderDetails/OrderHistory.tsx +11 -4
  97. package/themes/original/src/components/OrderDetails/index.tsx +44 -19
  98. package/themes/original/src/components/OrderDetails/styles.tsx +0 -1
  99. package/themes/original/src/components/OrderProgress/index.tsx +4 -3
  100. package/themes/original/src/components/OrderSummary/index.tsx +32 -11
  101. package/themes/original/src/components/OrderTypeSelector/index.tsx +4 -3
  102. package/themes/original/src/components/OrdersOption/index.tsx +3 -6
  103. package/themes/original/src/components/PaymentOptionWallet/index.tsx +56 -56
  104. package/themes/original/src/components/PaymentOptions/index.tsx +462 -459
  105. package/themes/original/src/components/PhoneInputNumber/index.tsx +92 -7
  106. package/themes/original/src/components/ProductForm/ActionButton.tsx +7 -11
  107. package/themes/original/src/components/ProductItemAccordion/index.tsx +28 -37
  108. package/themes/original/src/components/ProductOptionSubOption/index.tsx +16 -8
  109. package/themes/original/src/components/ServiceForm/index.tsx +1 -1
  110. package/themes/original/src/components/SignupForm/index.tsx +41 -24
  111. package/themes/original/src/components/SingleOrderCard/index.tsx +7 -4
  112. package/themes/original/src/components/SingleProductCard/index.tsx +3 -4
  113. package/themes/original/src/components/SingleProductCard/styles.tsx +0 -3
  114. package/themes/original/src/components/StripeCardsList/index.tsx +16 -3
  115. package/themes/original/src/components/StripeElementsForm/index.tsx +6 -3
  116. package/themes/original/src/components/StripeElementsForm/naked.tsx +1 -1
  117. package/themes/original/src/components/TaxInformation/index.tsx +3 -2
  118. package/themes/original/src/components/UpsellingProducts/UpsellingContent.tsx +7 -2
  119. package/themes/original/src/components/UserDetails/index.tsx +17 -16
  120. package/themes/original/src/components/UserFormDetails/index.tsx +112 -68
  121. package/themes/original/src/components/UserProfile/index.tsx +9 -1
  122. package/themes/original/src/components/UserVerification/index.tsx +18 -5
  123. package/themes/original/src/components/shared/OAlert.tsx +2 -1
  124. package/themes/original/src/components/shared/OButton.tsx +2 -2
  125. package/themes/original/src/components/shared/OInput.tsx +4 -8
  126. package/themes/original/src/components/shared/OModal.tsx +7 -2
  127. package/themes/original/src/types/index.tsx +12 -4
  128. package/themes/original/src/utils/index.tsx +29 -0
  129. package/themes/uber-eats/src/components/BusinessesListing/index.tsx +1 -1
@@ -1,4 +1,4 @@
1
- import React, { useState, useEffect, useCallback, useRef } from 'react';
1
+ import React, { useState, useEffect, useCallback, useRef, useMemo } from 'react';
2
2
  import { View, StyleSheet, TouchableOpacity, Platform, I18nManager, ScrollView, Keyboard, BackHandler, SafeAreaView } from 'react-native';
3
3
  import { initStripe, useConfirmPayment } from '@stripe/stripe-react-native';
4
4
  import NativeStripeSdk from '@stripe/stripe-react-native/src/NativeStripeSdk'
@@ -7,7 +7,7 @@ import MaterialIcons from 'react-native-vector-icons/MaterialIcons'
7
7
  import IconAntDesign from 'react-native-vector-icons/AntDesign';
8
8
  import { useIsFocused } from '@react-navigation/native';
9
9
 
10
- import ReactNativeHapticFeedback from "react-native-haptic-feedback";
10
+ import ReactNativeHapticFeedback, { HapticFeedbackTypes } from "react-native-haptic-feedback";
11
11
  import {
12
12
  Checkout as CheckoutController,
13
13
  useOrder,
@@ -15,7 +15,6 @@ import {
15
15
  useApi,
16
16
  useLanguage,
17
17
  useUtils,
18
- useValidationFields,
19
18
  useConfig,
20
19
  useToast,
21
20
  ToastType,
@@ -146,12 +145,11 @@ const CheckoutUI = (props: any) => {
146
145
 
147
146
  const [, { showToast }] = useToast();
148
147
  const [, t] = useLanguage();
149
- const [{ user, token }, { login }] = useSession();
148
+ const [{ user, token, loading: userLoading }, { login }] = useSession();
150
149
  const [ordering] = useApi()
151
150
  const [{ configs }] = useConfig();
152
151
  const [{ parsePrice, parseDate }] = useUtils();
153
152
  const [{ options, carts, loading }, { confirmCart }] = useOrder();
154
- const [validationFields] = useValidationFields();
155
153
  const [events] = useEvent()
156
154
  const [orientationState] = useDeviceOrientation();
157
155
  const [isReadMore, setIsReadMore] = useState(false)
@@ -168,6 +166,7 @@ const CheckoutUI = (props: any) => {
168
166
  const [webviewPaymethod, setWebviewPaymethod] = useState<any>(null)
169
167
  const [isOpen, setIsOpen] = useState(false)
170
168
  const [requiredFields, setRequiredFields] = useState<any>([])
169
+ const [orderTypeValidationFields, setOrderTypeValidationFields] = useState<any>([])
171
170
  const [openModal, setOpenModal] = useState({ login: false, signup: false, isGuest: false })
172
171
  const [allowedGuest, setAllowedGuest] = useState(false)
173
172
  const [placeByMethodPay, setPlaceByMethodPay] = useState(false)
@@ -176,10 +175,20 @@ const CheckoutUI = (props: any) => {
176
175
  const [showTitle, setShowTitle] = useState(false)
177
176
  const [cardList, setCardList] = useState<any>({ cards: [], loading: false, error: null })
178
177
  const [isGiftCardCart, setIsGiftCardCart] = useState(!cart?.business_id)
178
+ const [userHasCards, setUserHasCards] = useState(false)
179
179
  const containerRef = useRef<any>()
180
180
  const cardsMethods = ['credomatic']
181
- const stripePaymethods: any = ['stripe', 'stripe_direct', 'stripe_connect', 'stripe_redirect']
181
+ const stripePaymethods: any = ['stripe', 'stripe_connect', 'stripe_redirect']
182
+ const cardsPaymethods: any = ['stripe', 'stripe_connect']
183
+
182
184
  const notFields = ['coupon', 'driver_tip', 'mobile_phone', 'address', 'zipcode', 'address_notes', 'comments']
185
+
186
+ const checkoutFields = useMemo(() => checkoutFieldsState?.fields?.filter((field: any) => field.order_type_id === options?.type), [checkoutFieldsState, options])
187
+ const guestCheckoutDriveTip = useMemo(() => checkoutFields?.find((field: any) => field.order_type_id === 1 && field?.validation_field?.code === 'driver_tip'), [JSON.stringify(checkoutFields), options])
188
+ const guestCheckoutComment = useMemo(() => checkoutFields?.find((field: any) => field.order_type_id === options?.type && field?.validation_field?.code === 'comments'), [JSON.stringify(checkoutFields), options])
189
+ const guestCheckoutCoupon = useMemo(() => checkoutFields?.find((field: any) => field.order_type_id === options?.type && field?.validation_field?.code === 'coupon'), [JSON.stringify(checkoutFields), options])
190
+ const guestCheckoutZipcode = useMemo(() => checkoutFields?.find((field: any) => field.order_type_id === options?.type && field?.validation_field?.code === 'zipcode'), [JSON.stringify(checkoutFields), options])
191
+
183
192
  const placeSpotTypes = [3, 4, 5]
184
193
  const placeSpotsEnabled = placeSpotTypes.includes(options?.type)
185
194
  const businessConfigs = businessDetails?.business?.configs ?? []
@@ -197,6 +206,7 @@ const CheckoutUI = (props: any) => {
197
206
  const creditPointPlanOnBusiness = creditPointPlan?.businesses?.find((b: any) => b.business_id === cart?.business_id && b.accumulates)
198
207
  const methodsPay = ['google_pay', 'apple_pay']
199
208
 
209
+ const commentDelayTime = 1500
200
210
  const isPreOrder = configs?.preorder_status_enabled?.value === '1'
201
211
  const subtotalWithTaxes = cart?.taxes?.reduce((acc: any, item: any) => {
202
212
  if (item?.type === 1)
@@ -204,27 +214,28 @@ const CheckoutUI = (props: any) => {
204
214
  return acc = acc
205
215
  }, cart?.subtotal)
206
216
 
207
- const validateCommentsCartField = validationFields?.fields?.checkout?.comments?.enabled && validationFields?.fields?.checkout?.comments?.required && (cart?.comment === null || cart?.comment?.trim().length === 0)
208
- const validateZipcodeCard = validationFields?.fields?.card?.zipcode?.enabled &&
209
- validationFields?.fields?.card?.zipcode?.required &&
210
- paymethodSelected?.data?.card &&
211
- !paymethodSelected?.data?.card?.zipcode &&
212
- paymethodSelected?.gateway === 'stripe'
217
+ const validateCommentsCartField = (guestCheckoutComment?.enabled && (user?.guest_id ? guestCheckoutComment?.required_with_guest : guestCheckoutComment?.required)) && (cart?.comment === null || cart?.comment?.trim().length === 0)
218
+ const validateDriverTipField = options.type === 1 && (guestCheckoutDriveTip?.enabled && (user?.guest_id ? guestCheckoutDriveTip?.required_with_guest : guestCheckoutDriveTip?.required)) && (Number(cart?.driver_tip) <= 0)
219
+ const validateCouponField = (guestCheckoutCoupon?.enabled && (user?.guest_id ? guestCheckoutCoupon?.required_with_guest : guestCheckoutCoupon?.required)) && !cart?.offers?.some((offer: any) => offer?.type === 2)
220
+ const validateZipcodeCard = (guestCheckoutZipcode?.enabled && (user?.guest_id ? guestCheckoutZipcode?.required_with_guest : guestCheckoutZipcode?.required)) && paymethodSelected?.gateway === 'stripe' && paymethodSelected?.data?.card && !paymethodSelected?.data?.card?.zipcode
213
221
 
214
222
  const isDisabledButtonPlace = loading || !cart?.valid || (!paymethodSelected && cart?.balance > 0) ||
215
223
  placing || errorCash || subtotalWithTaxes < cart?.minimum ||
216
224
  (cardsMethods.includes(paymethodSelected?.gateway) && cardList?.cards?.length === 0) ||
217
- (options.type === 1 && !isGiftCardCart &&
218
- validationFields?.fields?.checkout?.driver_tip?.enabled &&
219
- validationFields?.fields?.checkout?.driver_tip?.required &&
220
- (Number(cart?.driver_tip) <= 0)) ||
221
225
  (validateCommentsCartField) ||
222
- (validateZipcodeCard)
223
- || (methodsPay.includes(paymethodSelected?.gateway) && (!methodPaySupported.enabled || methodPaySupported.loading))
226
+ (validateDriverTipField && !isGiftCardCart) ||
227
+ (validateZipcodeCard) ||
228
+ (methodsPay.includes(paymethodSelected?.gateway) && (!methodPaySupported.enabled || methodPaySupported.loading)) ||
229
+ validateCommentsCartField ||
230
+ validateDriverTipField ||
231
+ validateCouponField ||
232
+ validateZipcodeCard ||
233
+ (!userHasCards && cardsPaymethods.includes(paymethodSelected?.gateway))
224
234
 
225
235
  const driverTipsOptions = typeof configs?.driver_tip_options?.value === 'string'
226
236
  ? JSON.parse(configs?.driver_tip_options?.value) || []
227
237
  : configs?.driver_tip_options?.value || []
238
+ const driverTipsField = !cartState.loading && cart && cart?.business_id && options.type === 1 && cart?.status !== 2 && (guestCheckoutDriveTip?.enabled) && driverTipsOptions.length > 0
228
239
 
229
240
  const configTypes = configs?.order_types_allowed?.value.split('|').map((value: any) => Number(value)) || []
230
241
 
@@ -245,7 +256,7 @@ const CheckoutUI = (props: any) => {
245
256
  }
246
257
  }
247
258
 
248
- const vibrateApp = (impact?: string) => {
259
+ const vibrateApp = (impact?: HapticFeedbackTypes) => {
249
260
  const options = {
250
261
  enableVibrateFallback: true,
251
262
  ignoreAndroidSystemSettings: false
@@ -253,12 +264,11 @@ const CheckoutUI = (props: any) => {
253
264
  ReactNativeHapticFeedback.trigger(impact || "impactLight", options);
254
265
  }
255
266
 
256
- const handleSuccessSignup = (user: any) => {
257
- login({
267
+ const handleSuccessSignup = async (user: any) => {
268
+ await login({
258
269
  user,
259
270
  token: user?.session?.access_token
260
271
  })
261
- openModal?.isGuest && handlePlaceOrderAsGuest()
262
272
  setOpenModal({ ...openModal, signup: false, isGuest: false })
263
273
  }
264
274
 
@@ -311,53 +321,63 @@ const CheckoutUI = (props: any) => {
311
321
 
312
322
  const checkValidationFields = () => {
313
323
  setUserErrors([])
314
- const errors = []
315
- const _requiredFields: any = []
316
-
317
- Object.values(validationFields?.fields?.checkout).map((field: any) => {
318
- if (field?.required && !notFields.includes(field.code) && field?.enabled) {
319
- if (!user[field?.code]) {
320
- _requiredFields.push(field?.code)
324
+ const errors: Array<string> = []
325
+ const userSelected = user
326
+ const _requiredFields: Array<string> = []
327
+ Object.values(checkoutFieldsState?.fields).map((field: any) => {
328
+ if (options?.type === field?.order_type_id &&
329
+ field?.enabled &&
330
+ field?.required &&
331
+ !notFields.includes(field?.validation_field?.code)
332
+ ) {
333
+ if (userSelected && !userSelected[field?.validation_field?.code]) {
334
+ _requiredFields.push(field?.validation_field?.code)
321
335
  }
322
336
  }
323
337
  })
324
-
338
+ const mobilePhoneField: any = Object.values(checkoutFieldsState?.fields)?.find((field: any) => field?.order_type_id === options?.type && field?.validation_field?.code === 'mobile_phone')
325
339
  if (
326
- !user?.cellphone &&
327
- ((validationFields?.fields?.checkout?.cellphone?.enabled &&
328
- validationFields?.fields?.checkout?.cellphone?.required) ||
340
+ userSelected &&
341
+ !userSelected?.cellphone &&
342
+ ((mobilePhoneField?.enabled &&
343
+ mobilePhoneField?.required) ||
329
344
  configs?.verification_phone_required?.value === '1')
330
345
  ) {
331
346
  _requiredFields.push('cellphone')
332
347
  }
333
348
  setRequiredFields(_requiredFields)
334
349
 
335
- if (phoneUpdate) {
336
- errors.push(t('NECESSARY_UPDATE_COUNTRY_PHONE_CODE', 'It is necessary to update your phone number'))
337
- }
338
-
339
350
  setUserErrors(errors)
340
351
  }
341
352
 
342
353
  const checkGuestValidationFields = () => {
343
354
  const userSelected = user
344
355
  const _requiredFields = checkoutFieldsState?.fields
345
- .filter((field: any) => (field?.order_type_id === options?.type) && field?.enabled && field?.required &&
356
+ .filter((field: any) => (field?.order_type_id === options?.type) && field?.enabled && field?.required_with_guest &&
346
357
  !notFields.includes(field?.validation_field?.code) &&
358
+ field?.validation_field?.code !== 'email' &&
347
359
  userSelected && !userSelected[field?.validation_field?.code])
348
- .map((item: any) => item?.validation_field?.code)
360
+ const requiredFieldsCode = _requiredFields.map((item: any) => item?.validation_field?.code)
349
361
  const guestCheckoutCellPhone = checkoutFieldsState?.fields?.find((field: any) => field.order_type_id === options?.type && field?.validation_field?.code === 'mobile_phone')
350
-
362
+ const guestCheckoutEmail = checkoutFieldsState?.fields?.find((field: any) => field.order_type_id === options?.type && field?.validation_field?.code === 'email')
351
363
  if (
352
364
  userSelected &&
353
- !userSelected?.cellphone &&
365
+ !userSelected?.guest_cellphone &&
354
366
  ((guestCheckoutCellPhone?.enabled &&
355
- guestCheckoutCellPhone?.required) ||
367
+ guestCheckoutCellPhone?.required_with_guest) ||
356
368
  configs?.verification_phone_required?.value === '1')
357
369
  ) {
358
- _requiredFields.push('cellphone')
370
+ requiredFieldsCode.push('cellphone')
359
371
  }
360
- setRequiredFields(_requiredFields)
372
+ if (
373
+ userSelected &&
374
+ !userSelected?.guest_email &&
375
+ guestCheckoutEmail?.enabled &&
376
+ guestCheckoutEmail?.required_with_guest
377
+ ) {
378
+ requiredFieldsCode.push('email')
379
+ }
380
+ setRequiredFields(requiredFieldsCode)
361
381
  }
362
382
 
363
383
  const togglePhoneUpdate = (val: boolean) => {
@@ -368,16 +388,20 @@ const CheckoutUI = (props: any) => {
368
388
  setShowTitle(contentOffset.y > 30)
369
389
  }
370
390
 
391
+ const handleRedirect = () => {
392
+ props.fromProductsList
393
+ ? navigation?.goBack()
394
+ : onNavigationRedirect('BottomTab', { screen: 'Cart' }, !props.fromMulti)
395
+ }
396
+
371
397
  useEffect(() => {
372
- if (validationFields && validationFields?.fields?.checkout && !user?.guest_id) {
398
+ if (checkoutFieldsState?.loading || userLoading) return
399
+ if (user?.guest_id) {
400
+ checkGuestValidationFields()
401
+ } else {
373
402
  checkValidationFields()
374
403
  }
375
- }, [validationFields, user])
376
-
377
- useEffect(() => {
378
- if (checkoutFieldsState?.loading || !user?.guest_id) return
379
- checkGuestValidationFields()
380
- }, [user, checkoutFieldsState])
404
+ }, [checkoutFieldsState, user, options?.type])
381
405
 
382
406
  useEffect(() => {
383
407
  if (errors) {
@@ -387,12 +411,14 @@ const CheckoutUI = (props: any) => {
387
411
  }, [errors])
388
412
 
389
413
  useEffect(() => {
390
- if (cart?.products?.length === 0) {
391
- if (cart?.business_id !== null) {
392
- onNavigationRedirect('Business', { store: cart?.business?.slug, header: null, logo: null, fromMulti: props.fromMulti })
393
- } else if (isGiftCardCart) {
394
- onNavigationRedirect('Wallets')
395
- }
414
+ if (cart?.products?.length === 0 || !userLoading) return
415
+ if (cart?.business_id !== null) {
416
+ onNavigationRedirect('Business', { store: cart?.business?.slug, header: null, logo: null, fromMulti: props.fromMulti })
417
+ return
418
+ }
419
+ if (isGiftCardCart) {
420
+ onNavigationRedirect('Wallets')
421
+ return
396
422
  }
397
423
  }, [cart?.products?.length])
398
424
 
@@ -454,15 +480,6 @@ const CheckoutUI = (props: any) => {
454
480
  }
455
481
  }, [cartState?.error, cartState?.cart, cartState?.loading, isFocused])
456
482
 
457
- useEffect(() => {
458
- const keyboardDidShowListener = Keyboard.addListener('keyboardDidShow', () => {
459
- containerRef?.current?.scrollToEnd && containerRef.current.scrollToEnd({ animated: true })
460
- })
461
- return () => {
462
- keyboardDidShowListener.remove()
463
- }
464
- }, [])
465
-
466
483
  useEffect(() => {
467
484
  const onBackFunction = () => {
468
485
  if (webviewPaymethod?.gateway === 'paypal' && showGateway.open) {
@@ -483,7 +500,7 @@ const CheckoutUI = (props: any) => {
483
500
  <SafeAreaView style={{ backgroundColor: theme.colors.backgroundPage }}>
484
501
  <View style={styles.wrapperNavbar}>
485
502
  <TopHeader>
486
- <TopActions onPress={() => onNavigationRedirect('BottomTab', { screen: 'Cart' }, !props.fromMulti)}>
503
+ <TopActions onPress={() => handleRedirect()}>
487
504
  <IconAntDesign
488
505
  name='arrowleft'
489
506
  size={26}
@@ -509,7 +526,7 @@ const CheckoutUI = (props: any) => {
509
526
  hideArrowLeft
510
527
  title={t('CHECKOUT', 'Checkout')}
511
528
  titleAlign={'center'}
512
- onActionLeft={() => onNavigationRedirect('BottomTab', { screen: 'Cart' }, !props.fromMulti)}
529
+ onActionLeft={() => handleRedirect()}
513
530
  showCall={false}
514
531
  btnStyle={{ paddingLeft: 0, paddingTop: Platform.OS == 'ios' ? 0 : 2 }}
515
532
  titleWrapStyle={{ paddingHorizontal: 0 }}
@@ -675,6 +692,9 @@ const CheckoutUI = (props: any) => {
675
692
  isCheckout
676
693
  phoneUpdate={phoneUpdate}
677
694
  togglePhoneUpdate={togglePhoneUpdate}
695
+ isOrderTypeValidationField
696
+ requiredFields={requiredFields}
697
+ checkoutFields={checkoutFields}
678
698
  />
679
699
  )
680
700
  )}
@@ -772,6 +792,7 @@ const CheckoutUI = (props: any) => {
772
792
  </Placeholder>
773
793
  ) : (
774
794
  <AddressDetails
795
+ cart={cart}
775
796
  navigation={navigation}
776
797
  location={options?.address?.location}
777
798
  businessLogo={businessDetails?.business?.logo}
@@ -787,14 +808,7 @@ const CheckoutUI = (props: any) => {
787
808
  </ChSection>
788
809
  )}
789
810
 
790
- {!cartState.loading &&
791
- cart &&
792
- cart?.valid &&
793
- options.type === 1 &&
794
- cart?.status !== 2 &&
795
- validationFields?.fields?.checkout?.driver_tip?.enabled &&
796
- driverTipsOptions && driverTipsOptions?.length > 0 &&
797
- cart?.business_id &&
811
+ {driverTipsField &&
798
812
  (
799
813
  <ChSection>
800
814
  <ChDriverTips>
@@ -854,6 +868,7 @@ const CheckoutUI = (props: any) => {
854
868
  openUserModal={setIsOpen}
855
869
  paymethodClicked={paymethodClicked}
856
870
  setPaymethodClicked={setPaymethodClicked}
871
+ setUserHasCards={setUserHasCards}
857
872
  />
858
873
  </ChPaymethods>
859
874
  </ChSection>
@@ -932,6 +947,7 @@ const CheckoutUI = (props: any) => {
932
947
  cart={cart}
933
948
  isCartPending={cart?.status === 2}
934
949
  onNavigationRedirect={onNavigationRedirect}
950
+ commentDelayTime={commentDelayTime}
935
951
  placeSpotTypes={placeSpotTypes}
936
952
  businessConfigs={businessConfigs}
937
953
  maxDate={maxDate}
@@ -939,6 +955,8 @@ const CheckoutUI = (props: any) => {
939
955
  creditPointPlanOnBusiness?.accumulation_rate ??
940
956
  (!!creditPointPlanOnBusiness && creditPointPlan?.accumulation_rate) ?? 0
941
957
  }
958
+ hideCommentsByValidationCheckout={!guestCheckoutComment?.enabled}
959
+ hideCouponByValidationCheckout={!guestCheckoutCoupon?.enabled}
942
960
  />
943
961
  </>
944
962
  )}
@@ -985,10 +1003,8 @@ const CheckoutUI = (props: any) => {
985
1003
  {t('INVALID_CART_MOMENT', 'Selected schedule time is invalid, please select a schedule into the business schedule interval.')}
986
1004
  </OText>
987
1005
  )}
988
- {options.type === 1 && !isGiftCardCart &&
989
- validationFields?.fields?.checkout?.driver_tip?.enabled &&
990
- validationFields?.fields?.checkout?.driver_tip?.required &&
991
- (Number(cart?.driver_tip) <= 0) && (
1006
+ {validateDriverTipField && !isGiftCardCart &&
1007
+ (
992
1008
  <OText
993
1009
  color={theme.colors.error}
994
1010
  size={12}
@@ -996,7 +1012,6 @@ const CheckoutUI = (props: any) => {
996
1012
  {t('WARNING_INVALID_DRIVER_TIP', 'Driver Tip is required.')}
997
1013
  </OText>
998
1014
  )}
999
-
1000
1015
  {validateCommentsCartField && (
1001
1016
  <OText
1002
1017
  color={theme.colors.error}
@@ -1014,6 +1029,15 @@ const CheckoutUI = (props: any) => {
1014
1029
  {t('WARNING_CARD_ZIPCODE_REQUIRED', 'Your card selected has not zipcode')}
1015
1030
  </OText>
1016
1031
  )}
1032
+ {validateCouponField &&
1033
+ (
1034
+ <OText
1035
+ color={theme.colors.error}
1036
+ size={12}
1037
+ >
1038
+ {t('WARNING_INVALID_COUPON_FIELD', 'Coupon is required.')}
1039
+ </OText>
1040
+ )}
1017
1041
  </ChErrors>
1018
1042
  </View>
1019
1043
  )}
@@ -1031,20 +1055,23 @@ const CheckoutUI = (props: any) => {
1031
1055
  <OModal
1032
1056
  open={isOpen}
1033
1057
  onClose={() => setIsOpen(false)}
1058
+ showToastInsideModal
1034
1059
  >
1035
1060
  <View style={styles.detailWrapper}>
1036
1061
  <UserDetails
1037
1062
  isUserDetailsEdit
1038
1063
  cartStatus={cart?.status}
1039
1064
  businessId={cart?.business_id}
1040
- useValidationFields
1041
1065
  useDefualtSessionManager
1042
1066
  useSessionUser
1043
1067
  isCheckout
1044
1068
  isEdit
1045
1069
  phoneUpdate={phoneUpdate}
1046
1070
  togglePhoneUpdate={togglePhoneUpdate}
1071
+ isOrderTypeValidationField
1047
1072
  requiredFields={requiredFields}
1073
+ checkoutFields={checkoutFields}
1074
+ isCheckoutPlace
1048
1075
  hideUpdateButton
1049
1076
  handlePlaceOrderAsGuest={handlePlaceOrderAsGuest}
1050
1077
  onClose={() => {
@@ -14,8 +14,7 @@ import {
14
14
 
15
15
  export const Favorite = (props: any) => {
16
16
  const {
17
- navigation,
18
- franchiseId
17
+ navigation
19
18
  } = props
20
19
  const [, t] = useLanguage()
21
20
  const theme = useTheme()
@@ -72,7 +71,6 @@ export const Favorite = (props: any) => {
72
71
  originalURL='business'
73
72
  location={`${orderState.options?.address?.location?.lat},${orderState.options?.address?.location?.lng}`}
74
73
  propsToFetch={['id', 'name', 'header', 'logo', 'location', 'address', 'ribbon', 'timezone', 'schedule', 'open', 'delivery_price', 'distance', 'delivery_time', 'pickup_time', 'reviews', 'featured', 'offers', 'food', 'laundry', 'alcohol', 'groceries', 'slug']}
75
- franchiseId={franchiseId}
76
74
  />
77
75
  )}
78
76
  {tabSelected === 'products' && (
@@ -81,7 +79,6 @@ export const Favorite = (props: any) => {
81
79
  originalURL='products'
82
80
  onNavigationRedirect={onRedirect}
83
81
  isProduct
84
- franchiseId={franchiseId}
85
82
  />
86
83
  )}
87
84
  {tabSelected === 'orders' && (
@@ -90,7 +87,6 @@ export const Favorite = (props: any) => {
90
87
  favoriteURL='favorite_orders'
91
88
  originalURL='orders'
92
89
  isOrder
93
- franchiseId={franchiseId}
94
90
  />
95
91
  )}
96
92
  </Container>
@@ -208,8 +208,7 @@ const ForgotPasswordUI = (props: any) => {
208
208
 
209
209
  <OButton
210
210
  text={emailSent && !formState.result?.error ? t('LINK_SEND_FORGOT_PASSWORD', 'Link Sent') : t('FRONT_RECOVER_PASSWORD', 'Recover Password')}
211
- bgColor={emailSent && !formState.result?.error ? theme.colors.disabled : theme.colors.primary}
212
- borderColor={emailSent && !formState.result?.error ? theme.colors.disabled : theme.colors.primary}
211
+ isDisabled={formState.loading || emailSent && !formState.result?.error}
213
212
  isLoading={formState.loading}
214
213
  imgRightSrc={null}
215
214
  onClick={emailSent && !formState.result?.error ? () => { } : handleSubmit(onSubmit)}
@@ -8,7 +8,6 @@ import Alert from '../../../../../src/providers/AlertProvider'
8
8
  import { OIcon } from '../shared';
9
9
 
10
10
  export const GoogleMap = (props: GoogleMapsParams) => {
11
-
12
11
  const {
13
12
  location,
14
13
  handleChangeAddressMap,
@@ -21,7 +20,10 @@ export const GoogleMap = (props: GoogleMapsParams) => {
21
20
  locations,
22
21
  isIntGeoCoder,
23
22
  businessZones,
24
- delta
23
+ delta,
24
+ autoCompleteAddress,
25
+ setAutoCompleteAddress,
26
+ manualZoom
25
27
  } = props
26
28
 
27
29
  const [, t] = useLanguage()
@@ -59,7 +61,7 @@ export const GoogleMap = (props: GoogleMapsParams) => {
59
61
  strokeWidth: 2
60
62
  }
61
63
 
62
- const geocodePosition = (pos: { latitude: number, longitude: number }, isMovingRegion ?: boolean) => {
64
+ const geocodePosition = (pos: { latitude: number, longitude: number }, isMovingRegion?: boolean) => {
63
65
  Geocoder.from({
64
66
  latitude: pos.latitude,
65
67
  longitude: pos.longitude
@@ -84,7 +86,7 @@ export const GoogleMap = (props: GoogleMapsParams) => {
84
86
  }
85
87
  handleChangeAddressMap && handleChangeAddressMap(address, details)
86
88
  setSaveLocation && setSaveLocation(false)
87
- if(!isMovingRegion){
89
+ if (!isMovingRegion) {
88
90
  handleToggleMap && handleToggleMap()
89
91
  }
90
92
  } else {
@@ -95,7 +97,7 @@ export const GoogleMap = (props: GoogleMapsParams) => {
95
97
  })
96
98
  }
97
99
 
98
- const validateResult = (curPos: { latitude: number, longitude: number }) => {
100
+ const validateResult = (curPos: any) => {
99
101
  const loc1 = center
100
102
  const loc2 = curPos
101
103
  const distance = calculateDistance(loc1, loc2)
@@ -103,25 +105,33 @@ export const GoogleMap = (props: GoogleMapsParams) => {
103
105
  if (!maxLimitLocation) {
104
106
  geocodePosition(curPos)
105
107
  setMarkerPosition(curPos)
106
- setRegion({ ...region, longitude: curPos.longitude, latitude: curPos.latitude })
108
+ if (!autoCompleteAddress) {
109
+ setRegion({ longitude: curPos?.longitude || 0, latitude: curPos?.latitude || 0, latitudeDelta: curPos?.latitudeDelta || 0.0010, longitudeDelta: curPos?.longitudeDelta || (delta ?? 0.0010) * ASPECT_RATIO })
110
+ } else {
111
+ setRegion({ longitude: curPos?.longitude, latitude: curPos?.latitude, latitudeDelta: delta ?? 0.0010, longitudeDelta: (delta ?? 0.0010) * ASPECT_RATIO })
112
+ }
107
113
  return
108
114
  }
109
115
 
110
116
  const _maxLimitLocation = typeof maxLimitLocation === 'string' ? parseInt(maxLimitLocation, 10) : maxLimitLocation
111
117
 
112
118
  if (distance <= _maxLimitLocation) {
113
- if (!aproxEqual(curPos.latitude, center.lat) || !aproxEqual(curPos.longitude, center.lng)){
119
+ if (!aproxEqual(curPos?.latitude, center.lat) || !aproxEqual(curPos?.longitude, center.lng)) {
114
120
  geocodePosition(curPos, true)
115
121
  }
116
122
  setMarkerPosition(curPos)
117
- setRegion({ ...region, longitude: curPos.longitude, latitude: curPos.latitude })
123
+ if (!autoCompleteAddress) {
124
+ setRegion({ longitude: curPos?.longitude || 0, latitude: curPos?.latitude || 0, latitudeDelta: curPos?.latitudeDelta || 0.0010, longitudeDelta: curPos?.longitudeDelta || (delta ?? 0.0010) * ASPECT_RATIO })
125
+ } else {
126
+ setRegion({ longitude: curPos?.longitude, latitude: curPos?.latitude, latitudeDelta: delta ?? 0.0010, longitudeDelta: (delta ?? 0.0010) * ASPECT_RATIO })
127
+ }
118
128
  } else {
119
129
  setMapErrors && setMapErrors('ERROR_MAX_LIMIT_LOCATION')
120
130
  setMarkerPosition({ latitude: center.lat, longitude: center.lng })
121
131
  }
122
132
  }
123
133
 
124
- const aproxEqual = (n1 : number, n2 : number, epsilon = 0.000001) => {
134
+ const aproxEqual = (n1: number, n2: number, epsilon = 0.000001) => {
125
135
  return Math.abs(n1 - n2) < epsilon
126
136
  }
127
137
 
@@ -182,11 +192,21 @@ export const GoogleMap = (props: GoogleMapsParams) => {
182
192
  }, [isIntGeoCoder])
183
193
 
184
194
  useEffect(() => {
185
- mapRef.current.animateToRegion({
186
- ...region,
195
+ const regionConfig = {
187
196
  latitude: location?.lat,
188
197
  longitude: location?.lng,
189
- })
198
+ latitudeDelta: region?.latitudeDelta ?? delta ?? 0.0010,
199
+ longitudeDelta: region?.longitudeDelta ?? (delta ?? 0.0010) * ASPECT_RATIO
200
+ }
201
+
202
+ mapRef.current.animateToRegion(autoCompleteAddress
203
+ ? regionConfig
204
+ : { ...region, ...regionConfig }
205
+ )
206
+
207
+ if (autoCompleteAddress) {
208
+ setAutoCompleteAddress && setAutoCompleteAddress(false)
209
+ }
190
210
  }, [location])
191
211
 
192
212
  useEffect(() => {
@@ -197,11 +217,12 @@ export const GoogleMap = (props: GoogleMapsParams) => {
197
217
 
198
218
  useEffect(() => {
199
219
  const interval = setInterval(() => {
200
- if (mapRef.current && locations) {
220
+ if (mapRef.current && locations && !manualZoom) {
201
221
  fitAllMarkers()
202
222
  }
203
223
  }, 1000)
204
224
  if (locations) {
225
+ fitAllMarkers()
205
226
  SETMARKERS(locations)
206
227
  }
207
228
  return () => clearInterval(interval)
@@ -213,7 +234,7 @@ export const GoogleMap = (props: GoogleMapsParams) => {
213
234
  provider={PROVIDER_GOOGLE}
214
235
  initialRegion={region}
215
236
  style={styles.map}
216
- onRegionChangeComplete={!readOnly ? (coordinates) => handleChangeRegion(coordinates) : () => { }}
237
+ onRegionChangeComplete={!readOnly ? (coordinates) => { handleChangeRegion(coordinates) } : () => { }}
217
238
  zoomTapEnabled
218
239
  zoomEnabled
219
240
  zoomControlEnabled
@@ -249,7 +270,7 @@ export const GoogleMap = (props: GoogleMapsParams) => {
249
270
  <React.Fragment key={i}>
250
271
  {businessZone?.type === 2 && Array.isArray(businessZone?.data) && (
251
272
  <Polygon
252
- coordinates={businessZone?.data.map((item: any) => ({ latitude: item.lat, longitude: item.lng}))}
273
+ coordinates={businessZone?.data.map((item: any) => ({ latitude: item.lat, longitude: item.lng }))}
253
274
  fillColor={fillStyles.fillColor}
254
275
  strokeColor={fillStyles.strokeColor}
255
276
  strokeWidth={fillStyles.strokeWidth}
@@ -257,7 +278,7 @@ export const GoogleMap = (props: GoogleMapsParams) => {
257
278
  )}
258
279
  {(businessZone.type === 1 && businessZone?.data?.center && businessZone?.data?.radio) && (
259
280
  <Circle
260
- center={{ latitude: businessZone?.data?.center.lat, longitude: businessZone?.data?.center.lng}}
281
+ center={{ latitude: businessZone?.data?.center.lat, longitude: businessZone?.data?.center.lng }}
261
282
  radius={businessZone?.data.radio * 1000}
262
283
  fillColor={fillStyles.fillColor}
263
284
  strokeColor={fillStyles.strokeColor}
@@ -266,7 +287,7 @@ export const GoogleMap = (props: GoogleMapsParams) => {
266
287
  )}
267
288
  {(businessZone.type === 5 && businessZone?.data?.distance) && (
268
289
  <Circle
269
- center={{ latitude: center.lat, longitude: center.lng}}
290
+ center={{ latitude: center.lat, longitude: center.lng }}
270
291
  radius={businessZone?.data.distance * units[businessZone?.data?.unit]}
271
292
  fillColor={fillStyles.fillColor}
272
293
  strokeColor={fillStyles.strokeColor}
@@ -275,7 +296,7 @@ export const GoogleMap = (props: GoogleMapsParams) => {
275
296
  )}
276
297
  </React.Fragment>
277
298
  ))}
278
- </MapView>
299
+ </MapView >
279
300
  <Alert
280
301
  open={alertState.open}
281
302
  onAccept={closeAlert}
@@ -162,4 +162,4 @@ export const HighestRatedBusinesses = (props: any) => {
162
162
  };
163
163
 
164
164
  return <BusinessesListingController {...highestRatedBusinessesProps} />;
165
- };
165
+ };