ordering-ui-react-native 0.23.6 → 0.23.7

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ordering-ui-react-native",
3
- "version": "0.23.6",
3
+ "version": "0.23.7",
4
4
  "description": "Reusable components made in react native",
5
5
  "main": "src/index.tsx",
6
6
  "author": "ordering.inc",
@@ -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)
@@ -182,8 +180,11 @@ const CheckoutUI = (props: any) => {
182
180
  const stripePaymethods: any = ['stripe', 'stripe_direct', 'stripe_connect', 'stripe_redirect']
183
181
  const notFields = ['coupon', 'driver_tip', 'mobile_phone', 'address', 'zipcode', 'address_notes', 'comments']
184
182
 
185
- const guestCheckoutDriveTip = checkoutFieldsState?.fields?.find(field => field.order_type_id === 1 && field?.validation_field?.code === 'driver_tip')
186
- const guestCheckoutComment = useMemo(() => checkoutFieldsState?.fields?.find(field => field.order_type_id === options?.type && field?.validation_field?.code === 'comments'), [checkoutFieldsState, options])
183
+ const checkoutFields = useMemo(() => checkoutFieldsState?.fields?.filter((field : any) => field.order_type_id === options?.type), [checkoutFieldsState, options])
184
+ const guestCheckoutDriveTip = useMemo(() => checkoutFields?.find((field : any) => field.order_type_id === 1 && field?.validation_field?.code === 'driver_tip'), [JSON.stringify(checkoutFields), options])
185
+ const guestCheckoutComment = useMemo(() => checkoutFields?.find((field : any) => field.order_type_id === options?.type && field?.validation_field?.code === 'comments'), [JSON.stringify(checkoutFields), options])
186
+ const guestCheckoutCoupon = useMemo(() => checkoutFields?.find((field : any) => field.order_type_id === options?.type && field?.validation_field?.code === 'coupon'), [JSON.stringify(checkoutFields), options])
187
+ const guestCheckoutZipcode = useMemo(() => checkoutFields?.find((field : any) => field.order_type_id === options?.type && field?.validation_field?.code === 'zipcode'), [JSON.stringify(checkoutFields), options])
187
188
 
188
189
  const placeSpotTypes = [3, 4, 5]
189
190
  const placeSpotsEnabled = placeSpotTypes.includes(options?.type)
@@ -209,30 +210,28 @@ const CheckoutUI = (props: any) => {
209
210
  return acc = acc
210
211
  }, cart?.subtotal)
211
212
 
212
- const validateCommentsCartField = (!user?.guest_id ? (validationFields?.fields?.checkout?.comments?.enabled && validationFields?.fields?.checkout?.comments?.required) : (guestCheckoutComment?.enabled && guestCheckoutComment?.required_with_guest)) && (cart?.comment === null || cart?.comment?.trim().length === 0)
213
- const validateDriverTipField = options.type === 1 && (!user?.guest_id ? (validationFields?.fields?.checkout?.driver_tip?.enabled && validationFields?.fields?.checkout?.driver_tip?.required) : (guestCheckoutDriveTip?.enabled && guestCheckoutDriveTip?.required_with_guest)) && (Number(cart?.driver_tip) <= 0)
214
-
215
- const validateZipcodeCard = validationFields?.fields?.card?.zipcode?.enabled &&
216
- validationFields?.fields?.card?.zipcode?.required &&
217
- paymethodSelected?.data?.card &&
218
- !paymethodSelected?.data?.card?.zipcode &&
219
- paymethodSelected?.gateway === 'stripe'
213
+ const validateCommentsCartField = (guestCheckoutComment?.enabled && (user?.guest_id ? guestCheckoutComment?.required_with_guest : guestCheckoutComment?.required)) && (cart?.comment === null || cart?.comment?.trim().length === 0)
214
+ const validateDriverTipField = options.type === 1 && (guestCheckoutDriveTip?.enabled && (user?.guest_id ? guestCheckoutDriveTip?.required_with_guest : guestCheckoutDriveTip?.required)) && (Number(cart?.driver_tip) <= 0)
215
+ const validateCouponField = (guestCheckoutCoupon?.enabled && (user?.guest_id ? guestCheckoutCoupon?.required_with_guest : guestCheckoutCoupon?.required)) && !cart?.offers?.some((offer : any) => offer?.type === 2)
216
+ const validateZipcodeCard = (guestCheckoutZipcode?.enabled && (user?.guest_id ? guestCheckoutZipcode?.required_with_guest : guestCheckoutZipcode?.required)) && paymethodSelected?.gateway === 'stripe' && paymethodSelected?.data?.card && !paymethodSelected?.data?.card?.zipcode
220
217
 
221
218
  const isDisabledButtonPlace = loading || !cart?.valid || (!paymethodSelected && cart?.balance > 0) ||
222
219
  placing || errorCash || subtotalWithTaxes < cart?.minimum ||
223
220
  (cardsMethods.includes(paymethodSelected?.gateway) && cardList?.cards?.length === 0) ||
224
- (options.type === 1 && !isGiftCardCart &&
225
- validationFields?.fields?.checkout?.driver_tip?.enabled &&
226
- validationFields?.fields?.checkout?.driver_tip?.required &&
227
- (Number(cart?.driver_tip) <= 0)) ||
228
221
  (validateCommentsCartField) ||
229
222
  (validateDriverTipField && !isGiftCardCart) ||
230
223
  (validateZipcodeCard) ||
231
- (methodsPay.includes(paymethodSelected?.gateway) && (!methodPaySupported.enabled || methodPaySupported.loading))
224
+ (methodsPay.includes(paymethodSelected?.gateway) && (!methodPaySupported.enabled || methodPaySupported.loading)) ||
225
+ validateCommentsCartField ||
226
+ validateDriverTipField ||
227
+ validateCouponField ||
228
+ validateZipcodeCard
229
+
232
230
 
233
231
  const driverTipsOptions = typeof configs?.driver_tip_options?.value === 'string'
234
232
  ? JSON.parse(configs?.driver_tip_options?.value) || []
235
233
  : configs?.driver_tip_options?.value || []
234
+ const driverTipsField = !cartState.loading && cart && cart?.business_id && options.type === 1 && cart?.status !== 2 && (guestCheckoutDriveTip?.enabled) && driverTipsOptions.length > 0
236
235
 
237
236
  const configTypes = configs?.order_types_allowed?.value.split('|').map((value: any) => Number(value)) || []
238
237
 
@@ -253,7 +252,7 @@ const CheckoutUI = (props: any) => {
253
252
  }
254
253
  }
255
254
 
256
- const vibrateApp = (impact?: string) => {
255
+ const vibrateApp = (impact?: HapticFeedbackTypes) => {
257
256
  const options = {
258
257
  enableVibrateFallback: true,
259
258
  ignoreAndroidSystemSettings: false
@@ -319,42 +318,43 @@ const CheckoutUI = (props: any) => {
319
318
 
320
319
  const checkValidationFields = () => {
321
320
  setUserErrors([])
322
- const errors = []
323
- const _requiredFields: any = []
324
-
325
- Object.values(validationFields?.fields?.checkout).map((field: any) => {
326
- if (field?.required && !notFields.includes(field.code) && field?.enabled) {
327
- if (!user[field?.code]) {
328
- _requiredFields.push(field?.code)
321
+ const errors: Array<string> = []
322
+ const userSelected = user
323
+ const _requiredFields: Array<string> = []
324
+ Object.values(checkoutFieldsState?.fields).map((field: any) => {
325
+ if (options?.type === field?.order_type_id &&
326
+ field?.enabled &&
327
+ field?.required &&
328
+ !notFields.includes(field?.validation_field?.code)
329
+ ) {
330
+ if (userSelected && !userSelected[field?.validation_field?.code]) {
331
+ _requiredFields.push(field?.validation_field?.code)
329
332
  }
330
333
  }
331
334
  })
332
-
335
+ const mobilePhoneField: any = Object.values(checkoutFieldsState?.fields)?.find((field: any) => field?.order_type_id === options?.type && field?.validation_field?.code === 'mobile_phone')
333
336
  if (
334
- !user?.cellphone &&
335
- ((validationFields?.fields?.checkout?.cellphone?.enabled &&
336
- validationFields?.fields?.checkout?.cellphone?.required) ||
337
+ userSelected &&
338
+ !userSelected?.cellphone &&
339
+ ((mobilePhoneField?.enabled &&
340
+ mobilePhoneField?.required) ||
337
341
  configs?.verification_phone_required?.value === '1')
338
342
  ) {
339
343
  _requiredFields.push('cellphone')
340
344
  }
341
345
  setRequiredFields(_requiredFields)
342
346
 
343
- if (phoneUpdate) {
344
- errors.push(t('NECESSARY_UPDATE_COUNTRY_PHONE_CODE', 'It is necessary to update your phone number'))
345
- }
346
-
347
347
  setUserErrors(errors)
348
348
  }
349
349
 
350
350
  const checkGuestValidationFields = () => {
351
351
  const userSelected = user
352
352
  const _requiredFields = checkoutFieldsState?.fields
353
- .filter((field: any) => (field?.order_type_id === options?.type) && field?.enabled && field?.required_with_guest &&
353
+ .filter((field) => (field?.order_type_id === options?.type) && field?.enabled && field?.required_with_guest &&
354
354
  !notFields.includes(field?.validation_field?.code) &&
355
355
  userSelected && !userSelected[field?.validation_field?.code])
356
- const requiredFieldsCode = _requiredFields.map((item: any) => item?.validation_field?.code)
357
- const guestCheckoutCellPhone = checkoutFieldsState?.fields?.find((field: any) => field.order_type_id === options?.type && field?.validation_field?.code === 'mobile_phone')
356
+ const requiredFieldsCode = _requiredFields.map((item) => item?.validation_field?.code)
357
+ const guestCheckoutCellPhone = checkoutFieldsState?.fields?.find((field) => field.order_type_id === options?.type && field?.validation_field?.code === 'mobile_phone')
358
358
  if (
359
359
  userSelected &&
360
360
  !userSelected?.cellphone &&
@@ -365,7 +365,6 @@ const CheckoutUI = (props: any) => {
365
365
  requiredFieldsCode.push('cellphone')
366
366
  }
367
367
  setRequiredFields(requiredFieldsCode)
368
- setOrderTypeValidationFields(_requiredFields)
369
368
  }
370
369
 
371
370
  const togglePhoneUpdate = (val: boolean) => {
@@ -383,15 +382,13 @@ const CheckoutUI = (props: any) => {
383
382
  }
384
383
 
385
384
  useEffect(() => {
386
- if (validationFields && validationFields?.fields?.checkout && !user?.guest_id) {
385
+ if (checkoutFieldsState?.loading || userLoading) return
386
+ if (user?.guest_id) {
387
+ checkGuestValidationFields()
388
+ } else {
387
389
  checkValidationFields()
388
390
  }
389
- }, [validationFields, user])
390
-
391
- useEffect(() => {
392
- if (checkoutFieldsState?.loading || !user?.guest_id) return
393
- checkGuestValidationFields()
394
- }, [user, checkoutFieldsState])
391
+ }, [checkoutFieldsState, user, options?.type])
395
392
 
396
393
  useEffect(() => {
397
394
  if (errors) {
@@ -689,6 +686,9 @@ const CheckoutUI = (props: any) => {
689
686
  isCheckout
690
687
  phoneUpdate={phoneUpdate}
691
688
  togglePhoneUpdate={togglePhoneUpdate}
689
+ isOrderTypeValidationField
690
+ requiredFields={requiredFields}
691
+ checkoutFields={checkoutFields}
692
692
  />
693
693
  )
694
694
  )}
@@ -802,14 +802,7 @@ const CheckoutUI = (props: any) => {
802
802
  </ChSection>
803
803
  )}
804
804
 
805
- {!cartState.loading &&
806
- cart &&
807
- cart?.valid &&
808
- options.type === 1 &&
809
- cart?.status !== 2 &&
810
- validationFields?.fields?.checkout?.driver_tip?.enabled &&
811
- driverTipsOptions && driverTipsOptions?.length > 0 &&
812
- cart?.business_id &&
805
+ {driverTipsField &&
813
806
  (
814
807
  <ChSection>
815
808
  <ChDriverTips>
@@ -954,6 +947,8 @@ const CheckoutUI = (props: any) => {
954
947
  creditPointPlanOnBusiness?.accumulation_rate ??
955
948
  (!!creditPointPlanOnBusiness && creditPointPlan?.accumulation_rate) ?? 0
956
949
  }
950
+ hideCommentsByValidationCheckout={!guestCheckoutComment?.enabled}
951
+ hideCouponByValidationCheckout={!guestCheckoutCoupon?.enabled}
957
952
  />
958
953
  </>
959
954
  )}
@@ -1000,17 +995,6 @@ const CheckoutUI = (props: any) => {
1000
995
  {t('INVALID_CART_MOMENT', 'Selected schedule time is invalid, please select a schedule into the business schedule interval.')}
1001
996
  </OText>
1002
997
  )}
1003
- {options.type === 1 && !isGiftCardCart &&
1004
- validationFields?.fields?.checkout?.driver_tip?.enabled &&
1005
- validationFields?.fields?.checkout?.driver_tip?.required &&
1006
- (Number(cart?.driver_tip) <= 0) && (
1007
- <OText
1008
- color={theme.colors.error}
1009
- size={12}
1010
- >
1011
- {t('WARNING_INVALID_DRIVER_TIP', 'Driver Tip is required.')}
1012
- </OText>
1013
- )}
1014
998
  {validateDriverTipField && !isGiftCardCart &&
1015
999
  (
1016
1000
  <OText
@@ -1037,6 +1021,15 @@ const CheckoutUI = (props: any) => {
1037
1021
  {t('WARNING_CARD_ZIPCODE_REQUIRED', 'Your card selected has not zipcode')}
1038
1022
  </OText>
1039
1023
  )}
1024
+ {validateCouponField &&
1025
+ (
1026
+ <OText
1027
+ color={theme.colors.error}
1028
+ size={12}
1029
+ >
1030
+ {t('WARNING_INVALID_COUPON_FIELD', 'Coupon is required.')}
1031
+ </OText>
1032
+ )}
1040
1033
  </ChErrors>
1041
1034
  </View>
1042
1035
  )}
@@ -1060,18 +1053,18 @@ const CheckoutUI = (props: any) => {
1060
1053
  isUserDetailsEdit
1061
1054
  cartStatus={cart?.status}
1062
1055
  businessId={cart?.business_id}
1063
- useValidationFields
1064
1056
  useDefualtSessionManager
1065
1057
  useSessionUser
1066
1058
  isCheckout
1067
1059
  isEdit
1068
1060
  phoneUpdate={phoneUpdate}
1069
1061
  togglePhoneUpdate={togglePhoneUpdate}
1062
+ isOrderTypeValidationField
1070
1063
  requiredFields={requiredFields}
1071
- orderTypeValidationFields={orderTypeValidationFields}
1064
+ checkoutFields={checkoutFields}
1065
+ isCheckoutPlace
1072
1066
  hideUpdateButton
1073
1067
  handlePlaceOrderAsGuest={handlePlaceOrderAsGuest}
1074
- isGuest={!!user?.guest_id}
1075
1068
  onClose={() => {
1076
1069
  setIsOpen(false)
1077
1070
  if (paymethodClicked) {
@@ -1,4 +1,4 @@
1
- import React, { useState, useEffect, useCallback } from 'react'
1
+ import React, { useState, useEffect, useCallback, useMemo } from 'react'
2
2
  import {
3
3
  useLanguage,
4
4
  useConfig,
@@ -70,7 +70,8 @@ const MultiCheckoutUI = (props: any) => {
70
70
  walletState,
71
71
  onNavigationRedirectReplace,
72
72
  merchantId,
73
- cartsInvalid
73
+ cartsInvalid,
74
+ checkoutFieldsState
74
75
  } = props
75
76
 
76
77
  const theme = useTheme();
@@ -96,8 +97,9 @@ const MultiCheckoutUI = (props: any) => {
96
97
  const [{ parsePrice, parseDate }] = useUtils();
97
98
  const [{ options, carts, loading }, { confirmCart }] = useOrder();
98
99
  const [validationFields] = useValidationFields();
99
- const [{ user }, { login }] = useSession()
100
+ const [{ user, loading: userLoading }, { login }] = useSession()
100
101
 
102
+ const notFields = ['coupon', 'driver_tip', 'mobile_phone', 'address', 'zipcode', 'address_notes', 'comments']
101
103
  const configTypes = configs?.order_types_allowed?.value.split('|').map((value: any) => Number(value)) || []
102
104
  const isPreOrder = configs?.preorder_status_enabled?.value === '1'
103
105
  const isMultiDriverTips = configs?.checkout_multi_business_enabled?.value === '1'
@@ -121,6 +123,7 @@ const MultiCheckoutUI = (props: any) => {
121
123
 
122
124
  const creditPointGeneralPlan = loyaltyPlansState?.result?.find((loyal: any) => loyal.type === 'credit_point')
123
125
  const loyalBusinessAvailable = creditPointGeneralPlan?.businesses?.filter((b: any) => b.accumulates) ?? []
126
+ const checkoutFields = useMemo(() => checkoutFieldsState?.fields?.filter((field : any) => field.order_type_id === options?.type), [checkoutFieldsState, options])
124
127
 
125
128
  const accumulationRateBusiness = (businessId: number) => {
126
129
  const value = loyalBusinessAvailable?.find((loyal: any) => loyal.business_id === businessId)?.accumulation_rate ?? 0
@@ -169,35 +172,55 @@ const MultiCheckoutUI = (props: any) => {
169
172
 
170
173
  const checkValidationFields = () => {
171
174
  setUserErrors([])
172
- const errors = []
173
- const notFields = ['coupon', 'driver_tip', 'mobile_phone', 'address', 'zipcode', 'address_notes']
174
- const _requiredFields: any = []
175
-
176
- Object.values(validationFields?.fields?.checkout).map((field: any) => {
177
- if (field?.required && !notFields.includes(field.code)) {
178
- if (!user[field?.code]) {
179
- _requiredFields.push(field?.code)
175
+ const errors: Array<string> = []
176
+ const userSelected = user
177
+ const _requiredFields: Array<string> = []
178
+ Object.values(checkoutFieldsState?.fields).map((field: any) => {
179
+ if (options?.type === field?.order_type_id &&
180
+ field?.enabled &&
181
+ field?.required &&
182
+ !notFields.includes(field?.validation_field?.code)
183
+ ) {
184
+ if (userSelected && !userSelected[field?.validation_field?.code]) {
185
+ _requiredFields.push(field?.validation_field?.code)
180
186
  }
181
187
  }
182
188
  })
183
-
189
+ const mobilePhoneField: any = Object.values(checkoutFieldsState?.fields)?.find((field: any) => field?.order_type_id === options?.type && field?.validation_field?.code === 'mobile_phone')
184
190
  if (
185
- !user?.cellphone &&
186
- ((validationFields?.fields?.checkout?.cellphone?.enabled &&
187
- validationFields?.fields?.checkout?.cellphone?.required) ||
191
+ userSelected &&
192
+ !userSelected?.cellphone &&
193
+ ((mobilePhoneField?.enabled &&
194
+ mobilePhoneField?.required) ||
188
195
  configs?.verification_phone_required?.value === '1')
189
196
  ) {
190
197
  _requiredFields.push('cellphone')
191
198
  }
192
199
  setRequiredFields(_requiredFields)
193
200
 
194
- if (phoneUpdate) {
195
- errors.push(t('NECESSARY_UPDATE_COUNTRY_PHONE_CODE', 'It is necessary to update your phone number'))
196
- }
197
-
198
201
  setUserErrors(errors)
199
202
  }
200
203
 
204
+ const checkGuestValidationFields = () => {
205
+ const userSelected = user
206
+ const _requiredFields = checkoutFieldsState?.fields
207
+ .filter((field) => (field?.order_type_id === options?.type) && field?.enabled && field?.required_with_guest &&
208
+ !notFields.includes(field?.validation_field?.code) &&
209
+ userSelected && !userSelected[field?.validation_field?.code])
210
+ const requiredFieldsCode = _requiredFields.map((item) => item?.validation_field?.code)
211
+ const guestCheckoutCellPhone = checkoutFieldsState?.fields?.find((field) => field.order_type_id === options?.type && field?.validation_field?.code === 'mobile_phone')
212
+ if (
213
+ userSelected &&
214
+ !userSelected?.cellphone &&
215
+ ((guestCheckoutCellPhone?.enabled &&
216
+ guestCheckoutCellPhone?.required_with_guest) ||
217
+ configs?.verification_phone_required?.value === '1')
218
+ ) {
219
+ requiredFieldsCode.push('cellphone')
220
+ }
221
+ setRequiredFields(requiredFieldsCode)
222
+ }
223
+
201
224
  const togglePhoneUpdate = (val: boolean) => {
202
225
  setPhoneUpdate(val)
203
226
  }
@@ -208,7 +231,7 @@ const MultiCheckoutUI = (props: any) => {
208
231
  return
209
232
  }
210
233
 
211
- if (!userErrors.length && (!requiredFields?.length || allowedGuest)) {
234
+ if (!userErrors.length && !requiredFields?.length) {
212
235
  handleGroupPlaceOrder && handleGroupPlaceOrder(confirmPayment)
213
236
  return
214
237
  }
@@ -255,10 +278,13 @@ const MultiCheckoutUI = (props: any) => {
255
278
  }
256
279
 
257
280
  useEffect(() => {
258
- if (validationFields && validationFields?.fields?.checkout) {
281
+ if (checkoutFieldsState?.loading || userLoading) return
282
+ if (user?.guest_id) {
283
+ checkGuestValidationFields()
284
+ } else {
259
285
  checkValidationFields()
260
286
  }
261
- }, [validationFields, user])
287
+ }, [checkoutFieldsState, user, options?.type])
262
288
 
263
289
  useEffect(() => {
264
290
  if (cartsToShow?.length === 1) {
@@ -420,6 +446,9 @@ const MultiCheckoutUI = (props: any) => {
420
446
  isCheckout
421
447
  phoneUpdate={phoneUpdate}
422
448
  togglePhoneUpdate={togglePhoneUpdate}
449
+ isOrderTypeValidationField
450
+ requiredFields={requiredFields}
451
+ checkoutFields={checkoutFields}
423
452
  />
424
453
  )}
425
454
  </ChUserDetails>
@@ -656,9 +685,12 @@ const MultiCheckoutUI = (props: any) => {
656
685
  isEdit
657
686
  phoneUpdate={phoneUpdate}
658
687
  togglePhoneUpdate={togglePhoneUpdate}
659
- requiredFields={requiredFields}
660
688
  hideUpdateButton
661
689
  handlePlaceOrderAsGuest={handlePlaceOrderAsGuest}
690
+ isCheckoutPlace
691
+ isOrderTypeValidationField
692
+ requiredFields={requiredFields}
693
+ checkoutFields={checkoutFields}
662
694
  onClose={() => {
663
695
  setIsOpen(false)
664
696
  handlePlaceOrder()
@@ -47,7 +47,9 @@ const OrderSummaryUI = (props: any) => {
47
47
  cateringTypes,
48
48
  hideDeliveryFee,
49
49
  loyaltyRewardRate,
50
- maxDate
50
+ maxDate,
51
+ hideCommentsByValidationCheckout,
52
+ hideCouponByValidationCheckout
51
53
  } = props;
52
54
 
53
55
  const theme = useTheme()
@@ -55,11 +57,10 @@ const OrderSummaryUI = (props: any) => {
55
57
  const [{ configs }] = useConfig();
56
58
  const [orderState] = useOrder();
57
59
  const [{ parsePrice, parseNumber }] = useUtils();
58
- const [validationFields] = useValidationFields();
59
60
  const commentRef = useRef()
60
61
  const [openTaxModal, setOpenTaxModal] = useState<any>({ open: false, data: null, type: '' })
61
- const isCouponEnabled = validationFields?.fields?.checkout?.coupon?.enabled;
62
- const hideCartComments = !validationFields?.fields?.checkout?.comments?.enabled
62
+ const isCouponEnabled = hideCouponByValidationCheckout
63
+ const hideCartComments = hideCommentsByValidationCheckout
63
64
 
64
65
  const cart = orderState?.carts?.[`businessId:${props.cart.business_id}`]
65
66
 
@@ -35,7 +35,8 @@ const UserDetailsUI = (props: any) => {
35
35
  handleSendVerifyCode,
36
36
  verifyPhoneState,
37
37
  setFormState,
38
- setIsOpen
38
+ setIsOpen,
39
+ isCheckoutPlace
39
40
  } = props
40
41
 
41
42
  const theme = useTheme();
@@ -158,7 +159,7 @@ const UserDetailsUI = (props: any) => {
158
159
  {t('CUSTOMER_DETAILS', 'Customer Details')}
159
160
  </OText>
160
161
  )}
161
- {cartStatus !== 2 && !requiredFields && (
162
+ {cartStatus !== 2 && !isCheckoutPlace && (
162
163
  !isEdit ? (
163
164
  <EditBtn onPress={() => toggleIsEdit()} activeOpacity={0.7}>
164
165
  <OIcon
@@ -40,7 +40,9 @@ export const UserFormDetailsUI = (props: any) => {
40
40
  handleRemoveAccount,
41
41
  isProfile,
42
42
  isGuest,
43
- orderTypeValidationFields
43
+ isOrderTypeValidationField,
44
+ checkoutFields,
45
+ isCheckoutPlace
44
46
  } = props;
45
47
 
46
48
  const theme = useTheme();
@@ -99,8 +101,8 @@ export const UserFormDetailsUI = (props: any) => {
99
101
  const [confirm, setConfirm] = useState<any>({ open: false, content: null, handleOnAccept: null, id: null, title: null })
100
102
 
101
103
  const isAdmin = user?.level === 0
102
- const showInputPhoneNumber = (validationFields?.fields?.checkout?.cellphone?.enabled ?? false) || configs?.verification_phone_required?.value === '1'
103
- const showInputBirthday = validationFields?.fields?.checkout?.birthdate?.enabled ?? false
104
+ const showInputPhoneNumber = isOrderTypeValidationField ? checkoutFields?.find(field => field?.validation_field?.code === 'mobile_phone')?.enabled : (validationFields?.fields?.checkout?.cellphone?.enabled ?? false)
105
+ const showInputBirthday = isOrderTypeValidationField ? checkoutFields?.find(field => field?.validation_field?.code === 'birthdate')?.enabled : (validationFields?.fields?.checkout?.birthdate?.enabled ?? false)
104
106
 
105
107
  const handleSuccessSignup = (user: any) => {
106
108
  login({
@@ -121,7 +123,7 @@ export const UserFormDetailsUI = (props: any) => {
121
123
  };
122
124
  if (field.code && field.code === 'email') {
123
125
  rules.pattern = {
124
- value: /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}$/i,
126
+ value: /[&,()%";:ç?<>{}\\[\]\s]/g,
125
127
  message: t('INVALID_ERROR_EMAIL', 'Invalid email address').replace(
126
128
  '_attribute_',
127
129
  t('EMAIL', 'Email'),
@@ -131,7 +133,7 @@ export const UserFormDetailsUI = (props: any) => {
131
133
  return rules;
132
134
  };
133
135
 
134
- const cellphoneValue = () => {
136
+ const cellphoneValue = () => {
135
137
  let cellphone = user?.cellphone || null
136
138
  if (cellphone && CONDITIONAL_CODES.includes(user?.country_code)) {
137
139
  if (user?.country_code === 'PR') {
@@ -167,8 +169,13 @@ export const UserFormDetailsUI = (props: any) => {
167
169
  };
168
170
 
169
171
  const onSubmit = () => {
172
+ let content = ''
173
+ if (requiredFields?.includes?.('birthdate') && !birthdate) {
174
+ content = content + `${t('VALIDATION_ERROR_BIRTHDATE_REQUIRED', 'Birthdate is required')}\n`
175
+ }
170
176
  if (phoneInputData.error) {
171
- showToast(ToastType.Error, phoneInputData.error);
177
+ content = content + `${phoneInputData.error}\n`
178
+ showToast(ToastType.Error, content);
172
179
  return;
173
180
  }
174
181
  if (Object.keys(formState.changes).length > 0) {
@@ -178,15 +185,14 @@ export const UserFormDetailsUI = (props: any) => {
178
185
  validationFields?.fields?.checkout?.cellphone?.required) ||
179
186
  configs?.verification_phone_required?.value === '1')
180
187
  ) {
181
- showToast(
182
- ToastType.Error,
183
- t(
184
- 'VALIDATION_ERROR_MOBILE_PHONE_REQUIRED',
185
- 'The field Phone Number is required.',
186
- ),
187
- );
188
+ content = content + `${t('VALIDATION_ERROR_MOBILE_PHONE_REQUIRED', 'The field Phone Number is required.',)}\n`
189
+ showToast(ToastType.Error, content);
188
190
  return;
189
191
  }
192
+ if (content.length > 0) {
193
+ showToast(ToastType.Error, content);
194
+ return
195
+ }
190
196
  let changes = null;
191
197
  if (user?.cellphone && !userPhoneNumber) {
192
198
  changes = {
@@ -312,16 +318,16 @@ export const UserFormDetailsUI = (props: any) => {
312
318
  <>
313
319
  <UDForm>
314
320
  {!validationFields?.loading &&
315
- sortInputFields({ values: isGuest ? orderTypeValidationFields : validationFields?.fields?.checkout })
321
+ sortInputFields({ values: isOrderTypeValidationField ? checkoutFields : validationFields?.fields?.checkout })
316
322
  .length > 0 && (
317
323
  <UDWrapper>
318
324
  {sortInputFields({
319
- values: isGuest ? orderTypeValidationFields : validationFields?.fields?.checkout,
325
+ values: isOrderTypeValidationField ? checkoutFields : validationFields?.fields?.checkout,
320
326
  }).map(
321
327
  (item: any) => {
322
328
  const field = item?.validation_field || item
323
329
  return (
324
- (isGuest ? item?.enabled : showField && showField(field.code)) && ((requiredFields && requiredFields?.includes?.(field.code)) || !requiredFields) && (
330
+ ((isOrderTypeValidationField ? item?.enabled : (showField && showField(field.code))) && ((requiredFields && requiredFields?.includes?.(field.code)) || !requiredFields || !isCheckoutPlace)) && (
325
331
  <React.Fragment key={field.id}>
326
332
  <Controller
327
333
  key={field.id}
@@ -395,46 +401,51 @@ export const UserFormDetailsUI = (props: any) => {
395
401
  ))
396
402
  },
397
403
  )}
398
- {showInputBirthday && ((requiredFields && requiredFields?.includes?.('birthdate')) || !requiredFields) && (
399
- <>
400
- <WrapperBirthdate>
401
- <OText size={14} lineHeight={21} color={theme.colors.textNormal} weight={'500'} style={{ textTransform: 'capitalize', alignSelf: 'flex-start' }}>
402
- {t('BIRTHDATE', 'Birthdate')}
403
- </OText>
404
- <TouchableOpacity onPress={() => setShowDatePicker(!showDatePicker)}>
405
- <OText size={14} lineHeight={21} color={theme.colors.textNormal} weight={'500'} style={{ marginTop: 6 }}>
406
- {birthdate ? moment(birthdate).format('YYYY-MM-DD') : ''}
404
+ {((!user?.guest_id && showInputBirthday) || (isOrderTypeValidationField || user?.guest_id)) &&
405
+ showInputBirthday &&
406
+ ((requiredFields && requiredFields?.includes?.('birthdate')) || !requiredFields || !isCheckoutPlace) &&
407
+ (
408
+ <>
409
+ <WrapperBirthdate>
410
+ <OText size={14} lineHeight={21} color={theme.colors.textNormal} weight={'500'} style={{ textTransform: 'capitalize', alignSelf: 'flex-start' }}>
411
+ {t('BIRTHDATE', 'Birthdate')}
407
412
  </OText>
408
- </TouchableOpacity>
409
- </WrapperBirthdate>
410
- <DatePickerUI open={showDatePicker} birthdate={birthdate} onConfirm={_handleChangeDate} onCancel={() => setShowDatePicker(false)} />
411
- </>
412
- )}
413
- {!!showInputPhoneNumber && ((requiredFields && requiredFields?.includes?.('cellphone')) || !requiredFields) && (
414
- <WrapperPhone>
415
- <OText size={14} lineHeight={21} weight={'500'} color={theme.colors.textNormal}>{t('PHONE', 'Phone')}</OText>
416
- <PhoneInputNumber
417
- data={phoneInputData}
418
- handleData={(val: any) => handleChangePhoneNumber(val)}
419
- changeCountry={(val: any) => changeCountry(val)}
420
- defaultValue={phoneUpdate ? '' : cellphoneValue()}
421
- defaultCode={user?.country_code ?? user?.country_phone_code ?? null}
422
- boxStyle={styles.phoneSelect}
423
- inputStyle={styles.phoneInputStyle}
424
- textStyle={{ color: theme.colors.textNormal, fontSize: 12, padding: 0 }}
425
- noDropIcon
426
- />
427
- {phoneUpdate && (
428
- <OText
429
- size={10}
430
- color={theme.colors.error}
431
- style={{ marginHorizontal: 10, textAlign: 'center' }}>
432
- {t('YOUR_PREVIOUS_CELLPHONE', 'Your previous cellphone')}:{' '}
433
- {cellphoneValue()}
434
- </OText>
435
- )}
436
- </WrapperPhone>
437
- )}
413
+ <TouchableOpacity onPress={() => setShowDatePicker(!showDatePicker)}>
414
+ <OText size={14} lineHeight={21} color={theme.colors.textNormal} weight={'500'} style={{ marginTop: 6 }}>
415
+ {birthdate ? moment(birthdate).format('YYYY-MM-DD') : ''}
416
+ </OText>
417
+ </TouchableOpacity>
418
+ </WrapperBirthdate>
419
+ <DatePickerUI open={showDatePicker} birthdate={birthdate} onConfirm={_handleChangeDate} onCancel={() => setShowDatePicker(false)} />
420
+ </>
421
+ )}
422
+ {((!user?.guest_id && !!showInputPhoneNumber) || (isOrderTypeValidationField || user?.guest_id)) &&
423
+ ((requiredFields && requiredFields?.includes?.('cellphone')) || !requiredFields || !isCheckoutPlace) &&
424
+ (
425
+ <WrapperPhone>
426
+ <OText size={14} lineHeight={21} weight={'500'} color={theme.colors.textNormal}>{t('PHONE', 'Phone')}</OText>
427
+ <PhoneInputNumber
428
+ data={phoneInputData}
429
+ handleData={(val: any) => handleChangePhoneNumber(val)}
430
+ changeCountry={(val: any) => changeCountry(val)}
431
+ defaultValue={phoneUpdate ? '' : cellphoneValue()}
432
+ defaultCode={user?.country_code ?? user?.country_phone_code ?? null}
433
+ boxStyle={styles.phoneSelect}
434
+ inputStyle={styles.phoneInputStyle}
435
+ textStyle={{ color: theme.colors.textNormal, fontSize: 12, padding: 0 }}
436
+ noDropIcon
437
+ />
438
+ {phoneUpdate && (
439
+ <OText
440
+ size={10}
441
+ color={theme.colors.error}
442
+ style={{ marginHorizontal: 10, textAlign: 'center' }}>
443
+ {t('YOUR_PREVIOUS_CELLPHONE', 'Your previous cellphone')}:{' '}
444
+ {cellphoneValue()}
445
+ </OText>
446
+ )}
447
+ </WrapperPhone>
448
+ )}
438
449
  {!requiredFields && (
439
450
  <Controller
440
451
  control={control}
@@ -507,7 +518,7 @@ export const UserFormDetailsUI = (props: any) => {
507
518
  )}
508
519
  </>
509
520
  )}
510
- {requiredFields && (
521
+ {isCheckoutPlace && (
511
522
  <OButton
512
523
  text={
513
524
  formState.loading