ordering-ui-react-native 0.22.56-test → 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 +14 -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 +6 -5
  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 +68 -50
  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 -691
  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,
@@ -23,7 +22,8 @@ export const GoogleMap = (props: GoogleMapsParams) => {
23
22
  businessZones,
24
23
  delta,
25
24
  autoCompleteAddress,
26
- setAutoCompleteAddress
25
+ setAutoCompleteAddress,
26
+ manualZoom
27
27
  } = props
28
28
 
29
29
  const [, t] = useLanguage()
@@ -195,8 +195,8 @@ export const GoogleMap = (props: GoogleMapsParams) => {
195
195
  const regionConfig = {
196
196
  latitude: location?.lat,
197
197
  longitude: location?.lng,
198
- latitudeDelta: delta ?? 0.0010,
199
- longitudeDelta: (delta ?? 0.0010) * ASPECT_RATIO
198
+ latitudeDelta: region?.latitudeDelta ?? delta ?? 0.0010,
199
+ longitudeDelta: region?.longitudeDelta ?? (delta ?? 0.0010) * ASPECT_RATIO
200
200
  }
201
201
 
202
202
  mapRef.current.animateToRegion(autoCompleteAddress
@@ -217,11 +217,12 @@ export const GoogleMap = (props: GoogleMapsParams) => {
217
217
 
218
218
  useEffect(() => {
219
219
  const interval = setInterval(() => {
220
- if (mapRef.current && locations) {
220
+ if (mapRef.current && locations && !manualZoom) {
221
221
  fitAllMarkers()
222
222
  }
223
223
  }, 1000)
224
224
  if (locations) {
225
+ fitAllMarkers()
225
226
  SETMARKERS(locations)
226
227
  }
227
228
  return () => clearInterval(interval)
@@ -0,0 +1,76 @@
1
+ import React, { useState, useEffect } from 'react'
2
+ import PropTypes from 'prop-types'
3
+ import { useApi } from 'ordering-components/native'
4
+
5
+ /**
6
+ * Component to manage login behavior without UI component
7
+ */
8
+ export const CmsContent = (props: any) => {
9
+ const { UIComponent } = props
10
+
11
+ /**
12
+ * Array to save the body of the page
13
+ */
14
+ const [ordering] = useApi()
15
+ const [cmsState, setCmsState] = useState({ items: [], pages: [], loading: true, error: null })
16
+
17
+ /**
18
+ * Method used to get the page by slug
19
+ */
20
+ const getPages = async () => {
21
+ setCmsState({ ...cmsState, loading: true })
22
+ try {
23
+ const propsToFetch = ['name', 'enabled']
24
+ let pages: any = []
25
+ const { content: { error, result } } = await ordering.pages().select(propsToFetch).get()
26
+ if (!error) {
27
+ const promises = result.map((item: any) => getPage(item.id));
28
+ pages = await Promise.all(promises)
29
+ }
30
+ setCmsState({
31
+ ...cmsState,
32
+ loading: false,
33
+ error: error ? typeof result === 'string' ? result : result[0] : null,
34
+ items: error ? [] : result.filter((i: any) => i.enabled).map((item: any) => ({ id: item.id, name: item.name })),
35
+ pages
36
+ })
37
+ } catch (err: any) {
38
+ setCmsState({
39
+ ...cmsState,
40
+ loading: false,
41
+ error: err?.message ?? err
42
+ })
43
+ }
44
+ }
45
+
46
+ const getPage = async (id: number) => {
47
+ try {
48
+ const { content: { error, result } } = await ordering.pages(id).get()
49
+ return error ? null : { id, body: result?.body }
50
+ } catch {
51
+ return null
52
+ }
53
+ }
54
+
55
+ useEffect(() => {
56
+ getPages()
57
+ }, [])
58
+
59
+ return (
60
+ <>
61
+ {UIComponent && (
62
+ <UIComponent
63
+ {...props}
64
+ cmsState={cmsState}
65
+ />
66
+ )}
67
+ </>
68
+ )
69
+ }
70
+
71
+ CmsContent.propTypes = {
72
+ /**
73
+ * UI Component, this must be containt all graphic elements and use parent props
74
+ */
75
+ UIComponent: PropTypes.elementType
76
+ }