ordering-ui-react-native 0.22.56 → 0.22.57-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 (142) 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/RenderMarker.tsx +146 -0
  19. package/themes/business/src/components/MapView/index.tsx +68 -142
  20. package/themes/business/src/components/NewOrderNotification/index.tsx +25 -14
  21. package/themes/business/src/components/OrderDetails/Business.tsx +56 -20
  22. package/themes/business/src/components/OrderDetails/Delivery.tsx +134 -53
  23. package/themes/business/src/components/OrderDetails/OrderContentComponent.tsx +155 -45
  24. package/themes/business/src/components/OrderDetails/OrderHeaderComponent.tsx +51 -28
  25. package/themes/business/src/components/OrderDetails/styles.tsx +39 -3
  26. package/themes/business/src/components/OrderDetails/usePrinterCommands.tsx +17 -16
  27. package/themes/business/src/components/OrderDetailsLogistic/index.tsx +3 -2
  28. package/themes/business/src/components/OrderSummary/index.tsx +271 -176
  29. package/themes/business/src/components/OrdersListManager/index.tsx +13 -1
  30. package/themes/business/src/components/OrdersOption/index.tsx +345 -231
  31. package/themes/business/src/components/OrdersOption/styles.tsx +14 -0
  32. package/themes/business/src/components/PreviousMessages/index.tsx +26 -3
  33. package/themes/business/src/components/PreviousOrders/OrderItem.tsx +30 -18
  34. package/themes/business/src/components/PreviousOrders/index.tsx +74 -66
  35. package/themes/business/src/components/PreviousOrders/styles.tsx +2 -1
  36. package/themes/business/src/components/PrinterEdition/MessageAlert.tsx +33 -0
  37. package/themes/business/src/components/PrinterEdition/index.tsx +143 -75
  38. package/themes/business/src/components/PrinterEdition/printerList.tsx +23 -0
  39. package/themes/business/src/components/PrinterSettings/index.tsx +1 -1
  40. package/themes/business/src/components/ProductItemAccordion/index.tsx +3 -2
  41. package/themes/business/src/components/ReviewCustomer/index.tsx +2 -0
  42. package/themes/business/src/components/StoresList/index.tsx +2 -2
  43. package/themes/business/src/components/UserProfileForm/index.tsx +48 -10
  44. package/themes/business/src/components/UserProfileForm/styles.tsx +7 -0
  45. package/themes/business/src/components/WebsocketStatus/index.tsx +2 -2
  46. package/themes/business/src/config/currency.tsx +1010 -0
  47. package/themes/business/src/hooks/useLocation.tsx +16 -12
  48. package/themes/business/src/layouts/SafeAreaContainer.tsx +35 -19
  49. package/themes/business/src/types/index.tsx +34 -7
  50. package/themes/business/src/utils/index.tsx +28 -3
  51. package/themes/doordash/src/components/BusinessesListing/index.tsx +1 -1
  52. package/themes/doordash/src/components/LoginForm/index.tsx +1 -2
  53. package/themes/instacart/src/components/BusinessesListing/index.tsx +1 -1
  54. package/themes/kiosk/src/components/Checkout/index.tsx +9 -5
  55. package/themes/kiosk/src/components/CustomerName/index.tsx +1 -1
  56. package/themes/kiosk/src/components/NavBar/index.tsx +14 -14
  57. package/themes/kiosk/src/components/OptionCard/index.tsx +1 -1
  58. package/themes/kiosk/src/components/OrderTypeCardSelector/index.tsx +8 -10
  59. package/themes/kiosk/src/components/PaymentOptions/index.tsx +121 -57
  60. package/themes/kiosk/src/components/shared/OButton.tsx +5 -18
  61. package/themes/original/index.tsx +223 -219
  62. package/themes/original/src/components/AddressForm/index.tsx +19 -8
  63. package/themes/original/src/components/AppleLogin/index.tsx +4 -4
  64. package/themes/original/src/components/BusinessBasicInformation/index.tsx +1 -1
  65. package/themes/original/src/components/BusinessController/index.tsx +4 -2
  66. package/themes/original/src/components/BusinessItemAccordion/index.tsx +10 -4
  67. package/themes/original/src/components/BusinessListingSearch/BusinessSearchFooter.tsx +103 -92
  68. package/themes/original/src/components/BusinessListingSearch/BusinessSearchHeader.tsx +7 -3
  69. package/themes/original/src/components/BusinessListingSearch/index.tsx +8 -13
  70. package/themes/original/src/components/BusinessPreorder/index.tsx +34 -15
  71. package/themes/original/src/components/BusinessProductsList/SubcategoriesComponent/index.tsx +73 -70
  72. package/themes/original/src/components/BusinessProductsList/index.tsx +6 -7
  73. package/themes/original/src/components/BusinessProductsList/styles.tsx +0 -3
  74. package/themes/original/src/components/BusinessProductsListing/index.tsx +10 -6
  75. package/themes/original/src/components/BusinessTypeFilter/index.tsx +9 -8
  76. package/themes/original/src/components/BusinessesListing/Layout/Appointment/index.tsx +2 -1
  77. package/themes/original/src/components/BusinessesListing/Layout/Original/styles.tsx +1 -1
  78. package/themes/original/src/components/BusinessesListing/index.tsx +0 -1
  79. package/themes/original/src/components/Cart/index.tsx +48 -13
  80. package/themes/original/src/components/CartContent/index.tsx +2 -3
  81. package/themes/original/src/components/Checkout/index.tsx +130 -89
  82. package/themes/original/src/components/Favorite/index.tsx +1 -5
  83. package/themes/original/src/components/ForgotPasswordForm/index.tsx +1 -2
  84. package/themes/original/src/components/GoogleMap/index.tsx +39 -18
  85. package/themes/original/src/components/Help/functions.tsx +76 -0
  86. package/themes/original/src/components/Help/index.tsx +74 -29
  87. package/themes/original/src/components/Help/styles.tsx +4 -1
  88. package/themes/original/src/components/HelpOptions/index.tsx +44 -0
  89. package/themes/original/src/components/HighestRatedBusinesses/index.tsx +1 -1
  90. package/themes/original/src/components/Home/index.tsx +35 -16
  91. package/themes/original/src/components/LoginForm/index.tsx +12 -5
  92. package/themes/original/src/components/MessageListing/index.tsx +1 -1
  93. package/themes/original/src/components/Messages/index.tsx +20 -13
  94. package/themes/original/src/components/MomentOption/TimeListItem.tsx +56 -0
  95. package/themes/original/src/components/MomentOption/index.tsx +72 -51
  96. package/themes/original/src/components/MomentSelector/index.tsx +5 -2
  97. package/themes/original/src/components/MultiCheckout/index.tsx +76 -35
  98. package/themes/original/src/components/MyOrders/index.tsx +2 -2
  99. package/themes/original/src/components/NavBar/index.tsx +6 -2
  100. package/themes/original/src/components/NotFoundSource/index.tsx +40 -39
  101. package/themes/original/src/components/NotFoundSource/styles.tsx +18 -9
  102. package/themes/original/src/components/OrderDetails/OrderEta.tsx +4 -3
  103. package/themes/original/src/components/OrderDetails/OrderHistory.tsx +11 -4
  104. package/themes/original/src/components/OrderDetails/index.tsx +44 -19
  105. package/themes/original/src/components/OrderDetails/styles.tsx +0 -1
  106. package/themes/original/src/components/OrderProgress/index.tsx +4 -3
  107. package/themes/original/src/components/OrderSummary/index.tsx +32 -11
  108. package/themes/original/src/components/OrderTypeSelector/index.tsx +4 -3
  109. package/themes/original/src/components/OrdersOption/index.tsx +3 -6
  110. package/themes/original/src/components/PaymentOptionWallet/index.tsx +56 -56
  111. package/themes/original/src/components/PaymentOptions/index.tsx +471 -459
  112. package/themes/original/src/components/PhoneInputNumber/index.tsx +92 -7
  113. package/themes/original/src/components/ProductForm/ActionButton.tsx +6 -10
  114. package/themes/original/src/components/ProductItemAccordion/index.tsx +28 -37
  115. package/themes/original/src/components/ProductOptionSubOption/index.tsx +15 -14
  116. package/themes/original/src/components/ServiceForm/index.tsx +1 -1
  117. package/themes/original/src/components/SignupForm/index.tsx +41 -24
  118. package/themes/original/src/components/SingleOrderCard/index.tsx +7 -4
  119. package/themes/original/src/components/SingleProductCard/index.tsx +3 -4
  120. package/themes/original/src/components/SingleProductCard/styles.tsx +0 -3
  121. package/themes/original/src/components/StripeCardsList/index.tsx +9 -4
  122. package/themes/original/src/components/StripeElementsForm/index.tsx +2 -2
  123. package/themes/original/src/components/StripeElementsForm/naked.tsx +1 -1
  124. package/themes/original/src/components/TaxInformation/index.tsx +3 -2
  125. package/themes/original/src/components/UpsellingProducts/UpsellingContent.tsx +7 -2
  126. package/themes/original/src/components/UserDetails/index.tsx +17 -16
  127. package/themes/original/src/components/UserFormDetails/index.tsx +109 -67
  128. package/themes/original/src/components/UserProfile/index.tsx +9 -1
  129. package/themes/original/src/components/UserVerification/index.tsx +18 -5
  130. package/themes/original/src/components/shared/OAlert.tsx +2 -1
  131. package/themes/original/src/components/shared/OButton.tsx +2 -2
  132. package/themes/original/src/components/shared/OInput.tsx +4 -8
  133. package/themes/original/src/components/shared/OModal.tsx +7 -2
  134. package/themes/original/src/types/index.tsx +699 -689
  135. package/themes/original/src/utils/index.tsx +29 -0
  136. package/themes/uber-eats/src/components/BusinessesListing/index.tsx +1 -1
  137. package/themes/original/src/components/HelpAccountAndPayment/index.tsx +0 -62
  138. package/themes/original/src/components/HelpAccountAndPayment/styles.tsx +0 -12
  139. package/themes/original/src/components/HelpGuide/index.tsx +0 -68
  140. package/themes/original/src/components/HelpGuide/styles.tsx +0 -12
  141. package/themes/original/src/components/HelpOrder/index.tsx +0 -71
  142. package/themes/original/src/components/HelpOrder/styles.tsx +0 -13
@@ -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)
@@ -177,10 +175,20 @@ const CheckoutUI = (props: any) => {
177
175
  const [showTitle, setShowTitle] = useState(false)
178
176
  const [cardList, setCardList] = useState<any>({ cards: [], loading: false, error: null })
179
177
  const [isGiftCardCart, setIsGiftCardCart] = useState(!cart?.business_id)
178
+ const [userHasCards, setUserHasCards] = useState(false)
180
179
  const containerRef = useRef<any>()
181
180
  const cardsMethods = ['credomatic']
182
- const stripePaymethods: any = ['stripe', 'stripe_direct', 'stripe_connect', 'stripe_redirect']
183
- const notFields = ['coupon', 'mobile_phone', 'address', 'zipcode', 'address_notes']
181
+ const stripePaymethods: any = ['stripe', 'stripe_connect', 'stripe_redirect']
182
+ const cardsPaymethods: any = ['stripe', 'stripe_connect']
183
+
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
+
184
192
  const placeSpotTypes = [3, 4, 5]
185
193
  const placeSpotsEnabled = placeSpotTypes.includes(options?.type)
186
194
  const businessConfigs = businessDetails?.business?.configs ?? []
@@ -193,11 +201,12 @@ const CheckoutUI = (props: any) => {
193
201
  const hideBusinessDetails = theme?.checkout?.components?.business?.hidden
194
202
  const hideBusinessMap = theme?.checkout?.components?.business?.components?.map?.hidden
195
203
  const hideCustomerDetails = theme?.checkout?.components?.customer?.hidden
196
-
204
+ const isGuestCheckoutEnabled = configs?.guest_checkout_enabled?.value === '1'
197
205
  const creditPointPlan = loyaltyPlansState?.result?.find((loyal: any) => loyal.type === 'credit_point')
198
206
  const creditPointPlanOnBusiness = creditPointPlan?.businesses?.find((b: any) => b.business_id === cart?.business_id && b.accumulates)
199
207
  const methodsPay = ['google_pay', 'apple_pay']
200
208
 
209
+ const commentDelayTime = 1500
201
210
  const isPreOrder = configs?.preorder_status_enabled?.value === '1'
202
211
  const subtotalWithTaxes = cart?.taxes?.reduce((acc: any, item: any) => {
203
212
  if (item?.type === 1)
@@ -205,27 +214,29 @@ const CheckoutUI = (props: any) => {
205
214
  return acc = acc
206
215
  }, cart?.subtotal)
207
216
 
208
- const validateCommentsCartField = validationFields?.fields?.checkout?.comments?.enabled && validationFields?.fields?.checkout?.comments?.required && (cart?.comment === null || cart?.comment?.trim().length === 0)
209
- const validateZipcodeCard = validationFields?.fields?.card?.zipcode?.enabled &&
210
- validationFields?.fields?.card?.zipcode?.required &&
211
- paymethodSelected?.data?.card &&
212
- !paymethodSelected?.data?.card?.zipcode &&
213
- 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
214
221
 
215
222
  const isDisabledButtonPlace = loading || !cart?.valid || (!paymethodSelected && cart?.balance > 0) ||
216
223
  placing || errorCash || subtotalWithTaxes < cart?.minimum ||
217
224
  (cardsMethods.includes(paymethodSelected?.gateway) && cardList?.cards?.length === 0) ||
218
- (options.type === 1 && !isGiftCardCart &&
219
- validationFields?.fields?.checkout?.driver_tip?.enabled &&
220
- validationFields?.fields?.checkout?.driver_tip?.required &&
221
- (Number(cart?.driver_tip) <= 0)) ||
222
225
  (validateCommentsCartField) ||
223
- (validateZipcodeCard)
224
- || (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)) ||
234
+ (!isGuestCheckoutEnabled && !!user?.guest_id)
225
235
 
226
236
  const driverTipsOptions = typeof configs?.driver_tip_options?.value === 'string'
227
237
  ? JSON.parse(configs?.driver_tip_options?.value) || []
228
238
  : configs?.driver_tip_options?.value || []
239
+ const driverTipsField = !cartState.loading && cart && cart?.business_id && options.type === 1 && cart?.status !== 2 && (guestCheckoutDriveTip?.enabled) && driverTipsOptions.length > 0
229
240
 
230
241
  const configTypes = configs?.order_types_allowed?.value.split('|').map((value: any) => Number(value)) || []
231
242
 
@@ -246,7 +257,7 @@ const CheckoutUI = (props: any) => {
246
257
  }
247
258
  }
248
259
 
249
- const vibrateApp = (impact?: string) => {
260
+ const vibrateApp = (impact?: HapticFeedbackTypes) => {
250
261
  const options = {
251
262
  enableVibrateFallback: true,
252
263
  ignoreAndroidSystemSettings: false
@@ -254,12 +265,11 @@ const CheckoutUI = (props: any) => {
254
265
  ReactNativeHapticFeedback.trigger(impact || "impactLight", options);
255
266
  }
256
267
 
257
- const handleSuccessSignup = (user: any) => {
258
- login({
268
+ const handleSuccessSignup = async (user: any) => {
269
+ await login({
259
270
  user,
260
271
  token: user?.session?.access_token
261
272
  })
262
- openModal?.isGuest && handlePlaceOrderAsGuest()
263
273
  setOpenModal({ ...openModal, signup: false, isGuest: false })
264
274
  }
265
275
 
@@ -267,6 +277,10 @@ const CheckoutUI = (props: any) => {
267
277
  if (user) setOpenModal({ ...openModal, login: false })
268
278
  }
269
279
 
280
+ const handleOpenGuestSignup = () => {
281
+ setOpenModal({ ...openModal, signup: true, isGuest: true })
282
+ }
283
+
270
284
  const handlePlaceOrder = (confirmPayment: any, forcePlace: boolean = false) => {
271
285
  if (stripePaymethods.includes(paymethodSelected?.gateway) && user?.guest_id) {
272
286
  setOpenModal({ ...openModal, signup: true, isGuest: true })
@@ -312,31 +326,32 @@ const CheckoutUI = (props: any) => {
312
326
 
313
327
  const checkValidationFields = () => {
314
328
  setUserErrors([])
315
- const errors = []
316
- const _requiredFields: any = []
317
-
318
- Object.values(validationFields?.fields?.checkout).map((field: any) => {
319
- if (field?.required && !notFields.includes(field.code) && field?.enabled) {
320
- if (!user[field?.code]) {
321
- _requiredFields.push(field?.code)
329
+ const errors: Array<string> = []
330
+ const userSelected = user
331
+ const _requiredFields: Array<string> = []
332
+ Object.values(checkoutFieldsState?.fields).map((field: any) => {
333
+ if (options?.type === field?.order_type_id &&
334
+ field?.enabled &&
335
+ field?.required &&
336
+ !notFields.includes(field?.validation_field?.code)
337
+ ) {
338
+ if (userSelected && !userSelected[field?.validation_field?.code]) {
339
+ _requiredFields.push(field?.validation_field?.code)
322
340
  }
323
341
  }
324
342
  })
325
-
343
+ const mobilePhoneField: any = Object.values(checkoutFieldsState?.fields)?.find((field: any) => field?.order_type_id === options?.type && field?.validation_field?.code === 'mobile_phone')
326
344
  if (
327
- !user?.cellphone &&
328
- ((validationFields?.fields?.checkout?.cellphone?.enabled &&
329
- validationFields?.fields?.checkout?.cellphone?.required) ||
345
+ userSelected &&
346
+ !userSelected?.cellphone &&
347
+ ((mobilePhoneField?.enabled &&
348
+ mobilePhoneField?.required) ||
330
349
  configs?.verification_phone_required?.value === '1')
331
350
  ) {
332
351
  _requiredFields.push('cellphone')
333
352
  }
334
353
  setRequiredFields(_requiredFields)
335
354
 
336
- if (phoneUpdate) {
337
- errors.push(t('NECESSARY_UPDATE_COUNTRY_PHONE_CODE', 'It is necessary to update your phone number'))
338
- }
339
-
340
355
  setUserErrors(errors)
341
356
  }
342
357
 
@@ -345,20 +360,29 @@ const CheckoutUI = (props: any) => {
345
360
  const _requiredFields = checkoutFieldsState?.fields
346
361
  .filter((field: any) => (field?.order_type_id === options?.type) && field?.enabled && field?.required_with_guest &&
347
362
  !notFields.includes(field?.validation_field?.code) &&
363
+ field?.validation_field?.code !== 'email' &&
348
364
  userSelected && !userSelected[field?.validation_field?.code])
349
365
  const requiredFieldsCode = _requiredFields.map((item: any) => item?.validation_field?.code)
350
366
  const guestCheckoutCellPhone = checkoutFieldsState?.fields?.find((field: any) => field.order_type_id === options?.type && field?.validation_field?.code === 'mobile_phone')
367
+ const guestCheckoutEmail = checkoutFieldsState?.fields?.find((field: any) => field.order_type_id === options?.type && field?.validation_field?.code === 'email')
351
368
  if (
352
369
  userSelected &&
353
- !userSelected?.cellphone &&
370
+ !userSelected?.guest_cellphone &&
354
371
  ((guestCheckoutCellPhone?.enabled &&
355
372
  guestCheckoutCellPhone?.required_with_guest) ||
356
373
  configs?.verification_phone_required?.value === '1')
357
374
  ) {
358
375
  requiredFieldsCode.push('cellphone')
359
376
  }
377
+ if (
378
+ userSelected &&
379
+ !userSelected?.guest_email &&
380
+ guestCheckoutEmail?.enabled &&
381
+ guestCheckoutEmail?.required_with_guest
382
+ ) {
383
+ requiredFieldsCode.push('email')
384
+ }
360
385
  setRequiredFields(requiredFieldsCode)
361
- setOrderTypeValidationFields(_requiredFields)
362
386
  }
363
387
 
364
388
  const togglePhoneUpdate = (val: boolean) => {
@@ -369,16 +393,20 @@ const CheckoutUI = (props: any) => {
369
393
  setShowTitle(contentOffset.y > 30)
370
394
  }
371
395
 
396
+ const handleRedirect = () => {
397
+ props.fromProductsList
398
+ ? navigation?.goBack()
399
+ : onNavigationRedirect('BottomTab', { screen: 'Cart' }, !props.fromMulti)
400
+ }
401
+
372
402
  useEffect(() => {
373
- if (validationFields && validationFields?.fields?.checkout && !user?.guest_id) {
403
+ if (checkoutFieldsState?.loading || userLoading) return
404
+ if (user?.guest_id) {
405
+ checkGuestValidationFields()
406
+ } else {
374
407
  checkValidationFields()
375
408
  }
376
- }, [validationFields, user])
377
-
378
- useEffect(() => {
379
- if (checkoutFieldsState?.loading || !user?.guest_id) return
380
- checkGuestValidationFields()
381
- }, [user, checkoutFieldsState])
409
+ }, [checkoutFieldsState, user, options?.type])
382
410
 
383
411
  useEffect(() => {
384
412
  if (errors) {
@@ -388,12 +416,14 @@ const CheckoutUI = (props: any) => {
388
416
  }, [errors])
389
417
 
390
418
  useEffect(() => {
391
- if (cart?.products?.length === 0) {
392
- if (cart?.business_id !== null) {
393
- onNavigationRedirect('Business', { store: cart?.business?.slug, header: null, logo: null, fromMulti: props.fromMulti })
394
- } else if (isGiftCardCart) {
395
- onNavigationRedirect('Wallets')
396
- }
419
+ if (cart?.products?.length === 0 || !userLoading) return
420
+ if (cart?.business_id !== null) {
421
+ onNavigationRedirect('Business', { store: cart?.business?.slug, header: null, logo: null, fromMulti: props.fromMulti })
422
+ return
423
+ }
424
+ if (isGiftCardCart) {
425
+ onNavigationRedirect('Wallets')
426
+ return
397
427
  }
398
428
  }, [cart?.products?.length])
399
429
 
@@ -455,15 +485,6 @@ const CheckoutUI = (props: any) => {
455
485
  }
456
486
  }, [cartState?.error, cartState?.cart, cartState?.loading, isFocused])
457
487
 
458
- useEffect(() => {
459
- const keyboardDidShowListener = Keyboard.addListener('keyboardDidShow', () => {
460
- containerRef?.current?.scrollToEnd && containerRef.current.scrollToEnd({ animated: true })
461
- })
462
- return () => {
463
- keyboardDidShowListener.remove()
464
- }
465
- }, [])
466
-
467
488
  useEffect(() => {
468
489
  const onBackFunction = () => {
469
490
  if (webviewPaymethod?.gateway === 'paypal' && showGateway.open) {
@@ -484,7 +505,7 @@ const CheckoutUI = (props: any) => {
484
505
  <SafeAreaView style={{ backgroundColor: theme.colors.backgroundPage }}>
485
506
  <View style={styles.wrapperNavbar}>
486
507
  <TopHeader>
487
- <TopActions onPress={() => onNavigationRedirect('BottomTab', { screen: 'Cart' }, !props.fromMulti)}>
508
+ <TopActions onPress={() => handleRedirect()}>
488
509
  <IconAntDesign
489
510
  name='arrowleft'
490
511
  size={26}
@@ -510,7 +531,7 @@ const CheckoutUI = (props: any) => {
510
531
  hideArrowLeft
511
532
  title={t('CHECKOUT', 'Checkout')}
512
533
  titleAlign={'center'}
513
- onActionLeft={() => onNavigationRedirect('BottomTab', { screen: 'Cart' }, !props.fromMulti)}
534
+ onActionLeft={() => handleRedirect()}
514
535
  showCall={false}
515
536
  btnStyle={{ paddingLeft: 0, paddingTop: Platform.OS == 'ios' ? 0 : 2 }}
516
537
  titleWrapStyle={{ paddingHorizontal: 0 }}
@@ -655,14 +676,16 @@ const CheckoutUI = (props: any) => {
655
676
  style={{ borderRadius: 7.6, marginTop: 20 }}
656
677
  onClick={() => setOpenModal({ ...openModal, login: true })}
657
678
  />
658
- <OButton
659
- text={t('CONTINUE_AS_GUEST', 'Continue as guest')}
660
- textStyle={{ color: theme.colors.black }}
661
- bgColor={theme.colors.white}
662
- borderColor={theme.colors.black}
663
- style={{ borderRadius: 7.6, marginTop: 20 }}
664
- onClick={() => setAllowedGuest(true)}
665
- />
679
+ {isGuestCheckoutEnabled && (
680
+ <OButton
681
+ text={t('CONTINUE_AS_GUEST', 'Continue as guest')}
682
+ textStyle={{ color: theme.colors.black }}
683
+ bgColor={theme.colors.white}
684
+ borderColor={theme.colors.black}
685
+ style={{ borderRadius: 7.6, marginTop: 20 }}
686
+ onClick={() => setAllowedGuest(true)}
687
+ />
688
+ )}
666
689
  </View>
667
690
  ) : (
668
691
  <UserDetails
@@ -676,6 +699,9 @@ const CheckoutUI = (props: any) => {
676
699
  isCheckout
677
700
  phoneUpdate={phoneUpdate}
678
701
  togglePhoneUpdate={togglePhoneUpdate}
702
+ isOrderTypeValidationField
703
+ requiredFields={requiredFields}
704
+ checkoutFields={checkoutFields}
679
705
  />
680
706
  )
681
707
  )}
@@ -773,6 +799,7 @@ const CheckoutUI = (props: any) => {
773
799
  </Placeholder>
774
800
  ) : (
775
801
  <AddressDetails
802
+ cart={cart}
776
803
  navigation={navigation}
777
804
  location={options?.address?.location}
778
805
  businessLogo={businessDetails?.business?.logo}
@@ -788,14 +815,7 @@ const CheckoutUI = (props: any) => {
788
815
  </ChSection>
789
816
  )}
790
817
 
791
- {!cartState.loading &&
792
- cart &&
793
- cart?.valid &&
794
- options.type === 1 &&
795
- cart?.status !== 2 &&
796
- validationFields?.fields?.checkout?.driver_tip?.enabled &&
797
- driverTipsOptions && driverTipsOptions?.length > 0 &&
798
- cart?.business_id &&
818
+ {driverTipsField &&
799
819
  (
800
820
  <ChSection>
801
821
  <ChDriverTips>
@@ -855,6 +875,9 @@ const CheckoutUI = (props: any) => {
855
875
  openUserModal={setIsOpen}
856
876
  paymethodClicked={paymethodClicked}
857
877
  setPaymethodClicked={setPaymethodClicked}
878
+ setUserHasCards={setUserHasCards}
879
+ handleOpenGuestSignup={handleOpenGuestSignup}
880
+ guestDisabledError={(!isGuestCheckoutEnabled && !!user?.guest_id)}
858
881
  />
859
882
  </ChPaymethods>
860
883
  </ChSection>
@@ -933,6 +956,7 @@ const CheckoutUI = (props: any) => {
933
956
  cart={cart}
934
957
  isCartPending={cart?.status === 2}
935
958
  onNavigationRedirect={onNavigationRedirect}
959
+ commentDelayTime={commentDelayTime}
936
960
  placeSpotTypes={placeSpotTypes}
937
961
  businessConfigs={businessConfigs}
938
962
  maxDate={maxDate}
@@ -940,6 +964,8 @@ const CheckoutUI = (props: any) => {
940
964
  creditPointPlanOnBusiness?.accumulation_rate ??
941
965
  (!!creditPointPlanOnBusiness && creditPointPlan?.accumulation_rate) ?? 0
942
966
  }
967
+ hideCommentsByValidationCheckout={!guestCheckoutComment?.enabled}
968
+ hideCouponByValidationCheckout={!guestCheckoutCoupon?.enabled}
943
969
  />
944
970
  </>
945
971
  )}
@@ -986,10 +1012,8 @@ const CheckoutUI = (props: any) => {
986
1012
  {t('INVALID_CART_MOMENT', 'Selected schedule time is invalid, please select a schedule into the business schedule interval.')}
987
1013
  </OText>
988
1014
  )}
989
- {options.type === 1 && !isGiftCardCart &&
990
- validationFields?.fields?.checkout?.driver_tip?.enabled &&
991
- validationFields?.fields?.checkout?.driver_tip?.required &&
992
- (Number(cart?.driver_tip) <= 0) && (
1015
+ {validateDriverTipField && !isGiftCardCart &&
1016
+ (
993
1017
  <OText
994
1018
  color={theme.colors.error}
995
1019
  size={12}
@@ -997,7 +1021,6 @@ const CheckoutUI = (props: any) => {
997
1021
  {t('WARNING_INVALID_DRIVER_TIP', 'Driver Tip is required.')}
998
1022
  </OText>
999
1023
  )}
1000
-
1001
1024
  {validateCommentsCartField && (
1002
1025
  <OText
1003
1026
  color={theme.colors.error}
@@ -1015,6 +1038,23 @@ const CheckoutUI = (props: any) => {
1015
1038
  {t('WARNING_CARD_ZIPCODE_REQUIRED', 'Your card selected has not zipcode')}
1016
1039
  </OText>
1017
1040
  )}
1041
+ {validateCouponField &&
1042
+ (
1043
+ <OText
1044
+ color={theme.colors.error}
1045
+ size={12}
1046
+ >
1047
+ {t('WARNING_INVALID_COUPON_FIELD', 'Coupon is required.')}
1048
+ </OText>
1049
+ )}
1050
+ {(!isGuestCheckoutEnabled && !!user?.guest_id) && (
1051
+ <OText
1052
+ color={theme.colors.error}
1053
+ size={12}
1054
+ >
1055
+ {t('LOGIN_SIGN_UP_COMPLETE_ORDER', 'Login/Sign up to complete your order.')}
1056
+ </OText>
1057
+ )}
1018
1058
  </ChErrors>
1019
1059
  </View>
1020
1060
  )}
@@ -1032,24 +1072,25 @@ const CheckoutUI = (props: any) => {
1032
1072
  <OModal
1033
1073
  open={isOpen}
1034
1074
  onClose={() => setIsOpen(false)}
1075
+ showToastInsideModal
1035
1076
  >
1036
1077
  <View style={styles.detailWrapper}>
1037
1078
  <UserDetails
1038
1079
  isUserDetailsEdit
1039
1080
  cartStatus={cart?.status}
1040
1081
  businessId={cart?.business_id}
1041
- useValidationFields
1042
1082
  useDefualtSessionManager
1043
1083
  useSessionUser
1044
1084
  isCheckout
1045
1085
  isEdit
1046
1086
  phoneUpdate={phoneUpdate}
1047
1087
  togglePhoneUpdate={togglePhoneUpdate}
1088
+ isOrderTypeValidationField
1048
1089
  requiredFields={requiredFields}
1049
- orderTypeValidationFields={orderTypeValidationFields}
1090
+ checkoutFields={checkoutFields}
1091
+ isCheckoutPlace
1050
1092
  hideUpdateButton
1051
1093
  handlePlaceOrderAsGuest={handlePlaceOrderAsGuest}
1052
- isGuest={!!user?.guest_id}
1053
1094
  onClose={() => {
1054
1095
  setIsOpen(false)
1055
1096
  if (paymethodClicked) {
@@ -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}