ordering-ui-react-native 0.22.57 → 0.22.58-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 +5 -3
  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 +123 -54
  23. package/themes/business/src/components/OrderDetails/OrderContentComponent.tsx +146 -36
  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 +33 -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 +50 -14
  80. package/themes/original/src/components/CartContent/index.tsx +2 -3
  81. package/themes/original/src/components/Checkout/index.tsx +133 -90
  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 +72 -51
  96. package/themes/original/src/components/MomentSelector/index.tsx +5 -2
  97. package/themes/original/src/components/MultiCheckout/index.tsx +78 -36
  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,
@@ -72,6 +71,8 @@ const mapConfigs = {
72
71
  }
73
72
  };
74
73
 
74
+ const driverTipsTypes = [1, 2]
75
+
75
76
  const manageErrorsToShow = (array = []) => {
76
77
  let stringError = ''
77
78
  const list = Array.isArray(array) ? array : Object.values(array)
@@ -146,12 +147,11 @@ const CheckoutUI = (props: any) => {
146
147
 
147
148
  const [, { showToast }] = useToast();
148
149
  const [, t] = useLanguage();
149
- const [{ user, token }, { login }] = useSession();
150
+ const [{ user, token, loading: userLoading }, { login }] = useSession();
150
151
  const [ordering] = useApi()
151
152
  const [{ configs }] = useConfig();
152
153
  const [{ parsePrice, parseDate }] = useUtils();
153
154
  const [{ options, carts, loading }, { confirmCart }] = useOrder();
154
- const [validationFields] = useValidationFields();
155
155
  const [events] = useEvent()
156
156
  const [orientationState] = useDeviceOrientation();
157
157
  const [isReadMore, setIsReadMore] = useState(false)
@@ -177,10 +177,20 @@ const CheckoutUI = (props: any) => {
177
177
  const [showTitle, setShowTitle] = useState(false)
178
178
  const [cardList, setCardList] = useState<any>({ cards: [], loading: false, error: null })
179
179
  const [isGiftCardCart, setIsGiftCardCart] = useState(!cart?.business_id)
180
+ const [userHasCards, setUserHasCards] = useState(false)
180
181
  const containerRef = useRef<any>()
181
182
  const cardsMethods = ['credomatic']
182
- const stripePaymethods: any = ['stripe', 'stripe_direct', 'stripe_connect', 'stripe_redirect']
183
- const notFields = ['coupon', 'mobile_phone', 'address', 'zipcode', 'address_notes']
183
+ const stripePaymethods: any = ['stripe', 'stripe_connect', 'stripe_redirect']
184
+ const cardsPaymethods: any = ['stripe', 'stripe_connect']
185
+
186
+ const notFields = ['coupon', 'driver_tip', 'mobile_phone', 'address', 'zipcode', 'address_notes', 'comments']
187
+
188
+ const checkoutFields = useMemo(() => checkoutFieldsState?.fields?.filter((field: any) => field.order_type_id === options?.type), [checkoutFieldsState, options])
189
+ const guestCheckoutDriveTip = useMemo(() => checkoutFields?.find((field: any) => driverTipsTypes.includes(field.order_type_id) && field?.validation_field?.code === 'driver_tip'), [JSON.stringify(checkoutFields), options])
190
+ const guestCheckoutComment = useMemo(() => checkoutFields?.find((field: any) => field.order_type_id === options?.type && field?.validation_field?.code === 'comments'), [JSON.stringify(checkoutFields), options])
191
+ const guestCheckoutCoupon = useMemo(() => checkoutFields?.find((field: any) => field.order_type_id === options?.type && field?.validation_field?.code === 'coupon'), [JSON.stringify(checkoutFields), options])
192
+ const guestCheckoutZipcode = useMemo(() => checkoutFields?.find((field: any) => field.order_type_id === options?.type && field?.validation_field?.code === 'zipcode'), [JSON.stringify(checkoutFields), options])
193
+
184
194
  const placeSpotTypes = [3, 4, 5]
185
195
  const placeSpotsEnabled = placeSpotTypes.includes(options?.type)
186
196
  const businessConfigs = businessDetails?.business?.configs ?? []
@@ -193,39 +203,42 @@ const CheckoutUI = (props: any) => {
193
203
  const hideBusinessDetails = theme?.checkout?.components?.business?.hidden
194
204
  const hideBusinessMap = theme?.checkout?.components?.business?.components?.map?.hidden
195
205
  const hideCustomerDetails = theme?.checkout?.components?.customer?.hidden
196
-
206
+ const isGuestCheckoutEnabled = configs?.guest_checkout_enabled?.value === '1'
197
207
  const creditPointPlan = loyaltyPlansState?.result?.find((loyal: any) => loyal.type === 'credit_point')
198
208
  const creditPointPlanOnBusiness = creditPointPlan?.businesses?.find((b: any) => b.business_id === cart?.business_id && b.accumulates)
199
209
  const methodsPay = ['google_pay', 'apple_pay']
200
210
 
211
+ const commentDelayTime = 1500
201
212
  const isPreOrder = configs?.preorder_status_enabled?.value === '1'
202
213
  const subtotalWithTaxes = cart?.taxes?.reduce((acc: any, item: any) => {
203
214
  if (item?.type === 1)
204
215
  return acc = acc + item?.summary?.tax
205
216
  return acc = acc
206
217
  }, cart?.subtotal)
207
-
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'
218
+ const allowDriverTipPickup = configs?.driver_tip_allowed_at_pickup?.value === '1' && options?.type === 2
219
+ const validateCommentsCartField = (guestCheckoutComment?.enabled && (user?.guest_id ? guestCheckoutComment?.required_with_guest : guestCheckoutComment?.required)) && (cart?.comment === null || cart?.comment?.trim().length === 0)
220
+ const validateDriverTipField = (options.type === 1 || allowDriverTipPickup) && (guestCheckoutDriveTip?.enabled && (user?.guest_id ? guestCheckoutDriveTip?.required_with_guest : guestCheckoutDriveTip?.required)) && (Number(cart?.driver_tip) <= 0)
221
+ const validateCouponField = (guestCheckoutCoupon?.enabled && (user?.guest_id ? guestCheckoutCoupon?.required_with_guest : guestCheckoutCoupon?.required)) && !cart?.offers?.some((offer: any) => offer?.type === 2)
222
+ const validateZipcodeCard = (guestCheckoutZipcode?.enabled && (user?.guest_id ? guestCheckoutZipcode?.required_with_guest : guestCheckoutZipcode?.required)) && paymethodSelected?.gateway === 'stripe' && paymethodSelected?.data?.card && !paymethodSelected?.data?.card?.zipcode
214
223
 
215
224
  const isDisabledButtonPlace = loading || !cart?.valid || (!paymethodSelected && cart?.balance > 0) ||
216
225
  placing || errorCash || subtotalWithTaxes < cart?.minimum ||
217
226
  (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
227
  (validateCommentsCartField) ||
223
- (validateZipcodeCard)
224
- || (methodsPay.includes(paymethodSelected?.gateway) && (!methodPaySupported.enabled || methodPaySupported.loading))
228
+ (validateDriverTipField && !isGiftCardCart) ||
229
+ (validateZipcodeCard) ||
230
+ (methodsPay.includes(paymethodSelected?.gateway) && (!methodPaySupported.enabled || methodPaySupported.loading)) ||
231
+ validateCommentsCartField ||
232
+ validateDriverTipField ||
233
+ validateCouponField ||
234
+ validateZipcodeCard ||
235
+ (!userHasCards && cardsPaymethods.includes(paymethodSelected?.gateway)) ||
236
+ (!isGuestCheckoutEnabled && !!user?.guest_id)
225
237
 
226
238
  const driverTipsOptions = typeof configs?.driver_tip_options?.value === 'string'
227
239
  ? JSON.parse(configs?.driver_tip_options?.value) || []
228
240
  : configs?.driver_tip_options?.value || []
241
+ const driverTipsField = !cartState.loading && cart && cart?.business_id && (options.type === 1 || allowDriverTipPickup) && cart?.status !== 2 && (guestCheckoutDriveTip?.enabled) && driverTipsOptions.length > 0
229
242
 
230
243
  const configTypes = configs?.order_types_allowed?.value.split('|').map((value: any) => Number(value)) || []
231
244
 
@@ -246,7 +259,7 @@ const CheckoutUI = (props: any) => {
246
259
  }
247
260
  }
248
261
 
249
- const vibrateApp = (impact?: string) => {
262
+ const vibrateApp = (impact?: HapticFeedbackTypes) => {
250
263
  const options = {
251
264
  enableVibrateFallback: true,
252
265
  ignoreAndroidSystemSettings: false
@@ -254,12 +267,11 @@ const CheckoutUI = (props: any) => {
254
267
  ReactNativeHapticFeedback.trigger(impact || "impactLight", options);
255
268
  }
256
269
 
257
- const handleSuccessSignup = (user: any) => {
258
- login({
270
+ const handleSuccessSignup = async (user: any) => {
271
+ await login({
259
272
  user,
260
273
  token: user?.session?.access_token
261
274
  })
262
- openModal?.isGuest && handlePlaceOrderAsGuest()
263
275
  setOpenModal({ ...openModal, signup: false, isGuest: false })
264
276
  }
265
277
 
@@ -267,6 +279,10 @@ const CheckoutUI = (props: any) => {
267
279
  if (user) setOpenModal({ ...openModal, login: false })
268
280
  }
269
281
 
282
+ const handleOpenGuestSignup = () => {
283
+ setOpenModal({ ...openModal, signup: true, isGuest: true })
284
+ }
285
+
270
286
  const handlePlaceOrder = (confirmPayment: any, forcePlace: boolean = false) => {
271
287
  if (stripePaymethods.includes(paymethodSelected?.gateway) && user?.guest_id) {
272
288
  setOpenModal({ ...openModal, signup: true, isGuest: true })
@@ -312,31 +328,32 @@ const CheckoutUI = (props: any) => {
312
328
 
313
329
  const checkValidationFields = () => {
314
330
  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)
331
+ const errors: Array<string> = []
332
+ const userSelected = user
333
+ const _requiredFields: Array<string> = []
334
+ Object.values(checkoutFieldsState?.fields).map((field: any) => {
335
+ if (options?.type === field?.order_type_id &&
336
+ field?.enabled &&
337
+ field?.required &&
338
+ !notFields.includes(field?.validation_field?.code)
339
+ ) {
340
+ if (userSelected && !userSelected[field?.validation_field?.code]) {
341
+ _requiredFields.push(field?.validation_field?.code)
322
342
  }
323
343
  }
324
344
  })
325
-
345
+ const mobilePhoneField: any = Object.values(checkoutFieldsState?.fields)?.find((field: any) => field?.order_type_id === options?.type && field?.validation_field?.code === 'mobile_phone')
326
346
  if (
327
- !user?.cellphone &&
328
- ((validationFields?.fields?.checkout?.cellphone?.enabled &&
329
- validationFields?.fields?.checkout?.cellphone?.required) ||
347
+ userSelected &&
348
+ !userSelected?.cellphone &&
349
+ ((mobilePhoneField?.enabled &&
350
+ mobilePhoneField?.required) ||
330
351
  configs?.verification_phone_required?.value === '1')
331
352
  ) {
332
353
  _requiredFields.push('cellphone')
333
354
  }
334
355
  setRequiredFields(_requiredFields)
335
356
 
336
- if (phoneUpdate) {
337
- errors.push(t('NECESSARY_UPDATE_COUNTRY_PHONE_CODE', 'It is necessary to update your phone number'))
338
- }
339
-
340
357
  setUserErrors(errors)
341
358
  }
342
359
 
@@ -345,20 +362,29 @@ const CheckoutUI = (props: any) => {
345
362
  const _requiredFields = checkoutFieldsState?.fields
346
363
  .filter((field: any) => (field?.order_type_id === options?.type) && field?.enabled && field?.required_with_guest &&
347
364
  !notFields.includes(field?.validation_field?.code) &&
365
+ field?.validation_field?.code !== 'email' &&
348
366
  userSelected && !userSelected[field?.validation_field?.code])
349
367
  const requiredFieldsCode = _requiredFields.map((item: any) => item?.validation_field?.code)
350
368
  const guestCheckoutCellPhone = checkoutFieldsState?.fields?.find((field: any) => field.order_type_id === options?.type && field?.validation_field?.code === 'mobile_phone')
369
+ const guestCheckoutEmail = checkoutFieldsState?.fields?.find((field: any) => field.order_type_id === options?.type && field?.validation_field?.code === 'email')
351
370
  if (
352
371
  userSelected &&
353
- !userSelected?.cellphone &&
372
+ !userSelected?.guest_cellphone &&
354
373
  ((guestCheckoutCellPhone?.enabled &&
355
374
  guestCheckoutCellPhone?.required_with_guest) ||
356
375
  configs?.verification_phone_required?.value === '1')
357
376
  ) {
358
377
  requiredFieldsCode.push('cellphone')
359
378
  }
379
+ if (
380
+ userSelected &&
381
+ !userSelected?.guest_email &&
382
+ guestCheckoutEmail?.enabled &&
383
+ guestCheckoutEmail?.required_with_guest
384
+ ) {
385
+ requiredFieldsCode.push('email')
386
+ }
360
387
  setRequiredFields(requiredFieldsCode)
361
- setOrderTypeValidationFields(_requiredFields)
362
388
  }
363
389
 
364
390
  const togglePhoneUpdate = (val: boolean) => {
@@ -369,16 +395,20 @@ const CheckoutUI = (props: any) => {
369
395
  setShowTitle(contentOffset.y > 30)
370
396
  }
371
397
 
398
+ const handleRedirect = () => {
399
+ props.fromProductsList
400
+ ? navigation?.goBack()
401
+ : onNavigationRedirect('BottomTab', { screen: 'Cart' }, !props.fromMulti)
402
+ }
403
+
372
404
  useEffect(() => {
373
- if (validationFields && validationFields?.fields?.checkout && !user?.guest_id) {
405
+ if (checkoutFieldsState?.loading || userLoading) return
406
+ if (user?.guest_id) {
407
+ checkGuestValidationFields()
408
+ } else {
374
409
  checkValidationFields()
375
410
  }
376
- }, [validationFields, user])
377
-
378
- useEffect(() => {
379
- if (checkoutFieldsState?.loading || !user?.guest_id) return
380
- checkGuestValidationFields()
381
- }, [user, checkoutFieldsState])
411
+ }, [checkoutFieldsState, user, options?.type])
382
412
 
383
413
  useEffect(() => {
384
414
  if (errors) {
@@ -388,12 +418,14 @@ const CheckoutUI = (props: any) => {
388
418
  }, [errors])
389
419
 
390
420
  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
- }
421
+ if (cart?.products?.length === 0 || !userLoading) return
422
+ if (cart?.business_id !== null) {
423
+ onNavigationRedirect('Business', { store: cart?.business?.slug, header: null, logo: null, fromMulti: props.fromMulti })
424
+ return
425
+ }
426
+ if (isGiftCardCart) {
427
+ onNavigationRedirect('Wallets')
428
+ return
397
429
  }
398
430
  }, [cart?.products?.length])
399
431
 
@@ -455,15 +487,6 @@ const CheckoutUI = (props: any) => {
455
487
  }
456
488
  }, [cartState?.error, cartState?.cart, cartState?.loading, isFocused])
457
489
 
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
490
  useEffect(() => {
468
491
  const onBackFunction = () => {
469
492
  if (webviewPaymethod?.gateway === 'paypal' && showGateway.open) {
@@ -484,7 +507,7 @@ const CheckoutUI = (props: any) => {
484
507
  <SafeAreaView style={{ backgroundColor: theme.colors.backgroundPage }}>
485
508
  <View style={styles.wrapperNavbar}>
486
509
  <TopHeader>
487
- <TopActions onPress={() => onNavigationRedirect('BottomTab', { screen: 'Cart' }, !props.fromMulti)}>
510
+ <TopActions onPress={() => handleRedirect()}>
488
511
  <IconAntDesign
489
512
  name='arrowleft'
490
513
  size={26}
@@ -510,7 +533,7 @@ const CheckoutUI = (props: any) => {
510
533
  hideArrowLeft
511
534
  title={t('CHECKOUT', 'Checkout')}
512
535
  titleAlign={'center'}
513
- onActionLeft={() => onNavigationRedirect('BottomTab', { screen: 'Cart' }, !props.fromMulti)}
536
+ onActionLeft={() => handleRedirect()}
514
537
  showCall={false}
515
538
  btnStyle={{ paddingLeft: 0, paddingTop: Platform.OS == 'ios' ? 0 : 2 }}
516
539
  titleWrapStyle={{ paddingHorizontal: 0 }}
@@ -655,14 +678,16 @@ const CheckoutUI = (props: any) => {
655
678
  style={{ borderRadius: 7.6, marginTop: 20 }}
656
679
  onClick={() => setOpenModal({ ...openModal, login: true })}
657
680
  />
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
- />
681
+ {isGuestCheckoutEnabled && (
682
+ <OButton
683
+ text={t('CONTINUE_AS_GUEST', 'Continue as guest')}
684
+ textStyle={{ color: theme.colors.black }}
685
+ bgColor={theme.colors.white}
686
+ borderColor={theme.colors.black}
687
+ style={{ borderRadius: 7.6, marginTop: 20 }}
688
+ onClick={() => setAllowedGuest(true)}
689
+ />
690
+ )}
666
691
  </View>
667
692
  ) : (
668
693
  <UserDetails
@@ -676,6 +701,9 @@ const CheckoutUI = (props: any) => {
676
701
  isCheckout
677
702
  phoneUpdate={phoneUpdate}
678
703
  togglePhoneUpdate={togglePhoneUpdate}
704
+ isOrderTypeValidationField
705
+ requiredFields={requiredFields}
706
+ checkoutFields={checkoutFields}
679
707
  />
680
708
  )
681
709
  )}
@@ -773,6 +801,7 @@ const CheckoutUI = (props: any) => {
773
801
  </Placeholder>
774
802
  ) : (
775
803
  <AddressDetails
804
+ cart={cart}
776
805
  navigation={navigation}
777
806
  location={options?.address?.location}
778
807
  businessLogo={businessDetails?.business?.logo}
@@ -788,14 +817,7 @@ const CheckoutUI = (props: any) => {
788
817
  </ChSection>
789
818
  )}
790
819
 
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 &&
820
+ {driverTipsField &&
799
821
  (
800
822
  <ChSection>
801
823
  <ChDriverTips>
@@ -855,6 +877,9 @@ const CheckoutUI = (props: any) => {
855
877
  openUserModal={setIsOpen}
856
878
  paymethodClicked={paymethodClicked}
857
879
  setPaymethodClicked={setPaymethodClicked}
880
+ setUserHasCards={setUserHasCards}
881
+ handleOpenGuestSignup={handleOpenGuestSignup}
882
+ guestDisabledError={(!isGuestCheckoutEnabled && !!user?.guest_id)}
858
883
  />
859
884
  </ChPaymethods>
860
885
  </ChSection>
@@ -933,6 +958,7 @@ const CheckoutUI = (props: any) => {
933
958
  cart={cart}
934
959
  isCartPending={cart?.status === 2}
935
960
  onNavigationRedirect={onNavigationRedirect}
961
+ commentDelayTime={commentDelayTime}
936
962
  placeSpotTypes={placeSpotTypes}
937
963
  businessConfigs={businessConfigs}
938
964
  maxDate={maxDate}
@@ -940,6 +966,8 @@ const CheckoutUI = (props: any) => {
940
966
  creditPointPlanOnBusiness?.accumulation_rate ??
941
967
  (!!creditPointPlanOnBusiness && creditPointPlan?.accumulation_rate) ?? 0
942
968
  }
969
+ hideCommentsByValidationCheckout={!guestCheckoutComment?.enabled}
970
+ hideCouponByValidationCheckout={!guestCheckoutCoupon?.enabled}
943
971
  />
944
972
  </>
945
973
  )}
@@ -986,10 +1014,8 @@ const CheckoutUI = (props: any) => {
986
1014
  {t('INVALID_CART_MOMENT', 'Selected schedule time is invalid, please select a schedule into the business schedule interval.')}
987
1015
  </OText>
988
1016
  )}
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) && (
1017
+ {validateDriverTipField && !isGiftCardCart &&
1018
+ (
993
1019
  <OText
994
1020
  color={theme.colors.error}
995
1021
  size={12}
@@ -997,7 +1023,6 @@ const CheckoutUI = (props: any) => {
997
1023
  {t('WARNING_INVALID_DRIVER_TIP', 'Driver Tip is required.')}
998
1024
  </OText>
999
1025
  )}
1000
-
1001
1026
  {validateCommentsCartField && (
1002
1027
  <OText
1003
1028
  color={theme.colors.error}
@@ -1015,6 +1040,23 @@ const CheckoutUI = (props: any) => {
1015
1040
  {t('WARNING_CARD_ZIPCODE_REQUIRED', 'Your card selected has not zipcode')}
1016
1041
  </OText>
1017
1042
  )}
1043
+ {validateCouponField &&
1044
+ (
1045
+ <OText
1046
+ color={theme.colors.error}
1047
+ size={12}
1048
+ >
1049
+ {t('WARNING_INVALID_COUPON_FIELD', 'Coupon is required.')}
1050
+ </OText>
1051
+ )}
1052
+ {(!isGuestCheckoutEnabled && !!user?.guest_id) && (
1053
+ <OText
1054
+ color={theme.colors.error}
1055
+ size={12}
1056
+ >
1057
+ {t('LOGIN_SIGN_UP_COMPLETE_ORDER', 'Login/Sign up to complete your order.')}
1058
+ </OText>
1059
+ )}
1018
1060
  </ChErrors>
1019
1061
  </View>
1020
1062
  )}
@@ -1032,24 +1074,25 @@ const CheckoutUI = (props: any) => {
1032
1074
  <OModal
1033
1075
  open={isOpen}
1034
1076
  onClose={() => setIsOpen(false)}
1077
+ showToastInsideModal
1035
1078
  >
1036
1079
  <View style={styles.detailWrapper}>
1037
1080
  <UserDetails
1038
1081
  isUserDetailsEdit
1039
1082
  cartStatus={cart?.status}
1040
1083
  businessId={cart?.business_id}
1041
- useValidationFields
1042
1084
  useDefualtSessionManager
1043
1085
  useSessionUser
1044
1086
  isCheckout
1045
1087
  isEdit
1046
1088
  phoneUpdate={phoneUpdate}
1047
1089
  togglePhoneUpdate={togglePhoneUpdate}
1090
+ isOrderTypeValidationField
1048
1091
  requiredFields={requiredFields}
1049
- orderTypeValidationFields={orderTypeValidationFields}
1092
+ checkoutFields={checkoutFields}
1093
+ isCheckoutPlace
1050
1094
  hideUpdateButton
1051
1095
  handlePlaceOrderAsGuest={handlePlaceOrderAsGuest}
1052
- isGuest={!!user?.guest_id}
1053
1096
  onClose={() => {
1054
1097
  setIsOpen(false)
1055
1098
  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
+ }