ordering-ui-react-native 0.16.33 → 0.16.36

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.16.33",
3
+ "version": "0.16.36",
4
4
  "description": "Reusable components made in react native",
5
5
  "main": "src/index.tsx",
6
6
  "author": "ordering.inc",
@@ -39,6 +39,8 @@ import { VerifyPhone } from './src/components/VerifyPhone';
39
39
  import { DriverMap } from './src/components/DriverMap';
40
40
  import { MapViewUI as MapView } from './src/components/MapView'
41
41
  import { NewOrderNotification } from './src/components/NewOrderNotification';
42
+ import { DriverSchedule } from './src/components/DriverSchedule';
43
+ import { ScheduleBlocked } from './src/components/ScheduleBlocked';
42
44
  //OComponents
43
45
  import {
44
46
  OText,
@@ -106,6 +108,8 @@ export {
106
108
  UserFormDetailsUI,
107
109
  UserProfileForm,
108
110
  VerifyPhone,
111
+ DriverSchedule,
112
+ ScheduleBlocked,
109
113
  //OComponents
110
114
  OAlert,
111
115
  OButton,
@@ -0,0 +1,54 @@
1
+ import React from 'react'
2
+ import { View } from 'react-native'
3
+ import { OText } from '../shared'
4
+ import { useLanguage } from 'ordering-components/native'
5
+ import { DayContainer } from './styles'
6
+ import { useTheme } from 'styled-components/native'
7
+ export const DriverSchedule = (props : any) => {
8
+ const { schedule } = props
9
+ const [, t] = useLanguage()
10
+ const theme = useTheme()
11
+
12
+ const daysOfWeek = [
13
+ t('SUNDAY_ABBREVIATION', 'Sun'),
14
+ t('MONDAY_ABBREVIATION', 'Mon'),
15
+ t('TUESDAY_ABBREVIATION', 'Tues'),
16
+ t('WEDNESDAY_ABBREVIATION', 'Wed'),
17
+ t('THURSDAY_ABBREVIATION', 'Thur'),
18
+ t('FRIDAY_ABBREVIATION', 'Fri'),
19
+ t('SATURDAY_ABBREVIATION', 'Sat')
20
+ ]
21
+
22
+ const scheduleFormatted = ({ hour, minute }: any) => {
23
+ const checkTime = (val: number) => val < 10 ? `0${val}` : val
24
+ return `${checkTime(hour)}:${checkTime(minute)}`
25
+ }
26
+
27
+ return (
28
+ <View >
29
+ <OText size={24} style={{paddingLeft: 30}}>
30
+ {t('SCHEDULE', 'Schedule')}
31
+ </OText>
32
+ <View style={{padding: 30}}>
33
+ {schedule.map((item: any, i: number) => (
34
+ <DayContainer key={daysOfWeek[i]}>
35
+ <OText style={{width: '20%'}} size={22} weight={700}>{daysOfWeek[i]}</OText>
36
+ <View style={{width: '80%', alignItems: 'center'}}>
37
+ <>
38
+ {item?.enabled ? (
39
+ <>
40
+ {item?.lapses.map((lapse: any, i: number) => (
41
+ <OText size={18} style={{marginTop: 3, marginBottom: 20}} key={`${daysOfWeek[i]}_${i}`}>{scheduleFormatted(lapse.open)} - {scheduleFormatted(lapse.close)}</OText>
42
+ ))}
43
+ </>
44
+ ) : (
45
+ <OText size={18} style={{marginTop: 3, marginBottom: 10}} color={theme.colors.red}>{t('NOT_AVAILABLE', 'Not available')}</OText>
46
+ )}
47
+ </>
48
+ </View>
49
+ </DayContainer>
50
+ ))}
51
+ </View>
52
+ </View>
53
+ )
54
+ }
@@ -0,0 +1,6 @@
1
+ import styled from "styled-components/native";
2
+
3
+ export const DayContainer = styled.View`
4
+ flex-direction: row;
5
+ width: 100%;
6
+ `
@@ -0,0 +1,53 @@
1
+ import React from 'react'
2
+ import { Dimensions, View } from 'react-native'
3
+ import { OButton, OIcon, OText } from '../shared'
4
+ import { useLanguage, useSession } from 'ordering-components/native'
5
+ import { useTheme } from 'styled-components/native'
6
+
7
+ export const ScheduleBlocked = (props : any) => {
8
+ const { nextSchedule } = props
9
+ const [, t] = useLanguage()
10
+ const [, {logout}] = useSession()
11
+ const theme = useTheme()
12
+ const deviceWidth = Dimensions.get('screen').width
13
+
14
+ const daysOfWeek = [
15
+ t('MONDAY', 'Monday'),
16
+ t('TUESDAY', 'Tuesday'),
17
+ t('WEDNESDAY', 'Wednesday'),
18
+ t('THURSDAY', 'Thurday'),
19
+ t('FRIDAY', 'Friday'),
20
+ t('SATURDAY', 'Saturday'),
21
+ t('SUNDAY', 'Sunday')
22
+ ]
23
+
24
+ const scheduleFormatted = ({ hour, minute }: any) => {
25
+ const checkTime = (val: number) => val < 10 ? `0${val}` : val
26
+ return `${checkTime(hour)}:${checkTime(minute)}`
27
+ }
28
+
29
+ const goBack = () => {
30
+ logout()
31
+ }
32
+
33
+ return (
34
+ <View style={{ alignItems: 'center', padding: 40 }}>
35
+ <OText size={20}>{t('YOU_CANT_LOGIN', 'You can\'t login')}</OText>
36
+ <OIcon
37
+ src={theme.images?.general?.deliveryWaiting}
38
+ width={(deviceWidth - 80) * 0.9}
39
+ height={(deviceWidth - 80) * 0.8}
40
+ />
41
+ <OText>{t('OUTSIDE_ESTABLISHED_SCHEDULE', 'You are outside the established schedule')}</OText>
42
+ <View style={{ flexDirection: 'row', marginBottom: 20 }}>
43
+ <OText color={theme.colors.primary}>{t('NEXT_TIME', 'Next time')}: </OText>
44
+ <OText>{daysOfWeek[nextSchedule?.day - 1]} {scheduleFormatted(nextSchedule?.schedule?.open)}</OText>
45
+ </View>
46
+ <OButton
47
+ text={t('GO_BACK', 'Go back')}
48
+ textStyle={{ color: theme.colors.white }}
49
+ onClick={goBack}
50
+ />
51
+ </View>
52
+ )
53
+ }
@@ -1,5 +1,5 @@
1
1
  import React, { useEffect, useState } from 'react';
2
- import { View, StyleSheet, ScrollView, ActivityIndicator } from 'react-native';
2
+ import { View, StyleSheet, ScrollView, ActivityIndicator, Pressable } from 'react-native';
3
3
  import { useForm } from 'react-hook-form';
4
4
  import { launchImageLibrary } from 'react-native-image-picker';
5
5
  import { Placeholder, PlaceholderLine, Fade } from 'rn-placeholder';
@@ -22,6 +22,7 @@ import {
22
22
  import { LogoutButton } from '../LogoutButton';
23
23
  import { LanguageSelector } from '../LanguageSelector';
24
24
  import { UserFormDetailsUI } from '../UserFormDetails';
25
+ import { DriverSchedule } from '../DriverSchedule'
25
26
  import ToggleSwitch from 'toggle-switch-react-native';
26
27
  import { UDWrapper } from '../UserFormDetails/styles';
27
28
  import {
@@ -30,11 +31,12 @@ import {
30
31
  OText,
31
32
  OButton,
32
33
  OInput,
34
+ OModal,
33
35
  } from '../../components/shared';
34
36
  import { sortInputFields, getTraduction } from '../../utils';
35
37
  import { ProfileParams } from '../../types';
36
38
  import { NotFoundSource } from '../NotFoundSource';
37
-
39
+ import AntDesignIcon from 'react-native-vector-icons/AntDesign'
38
40
  const ProfileUI = (props: ProfileParams) => {
39
41
  const {
40
42
  navigation,
@@ -66,6 +68,7 @@ const ProfileUI = (props: ProfileParams) => {
66
68
  const [phoneUpdate, setPhoneUpdate] = useState(false);
67
69
  const [userPhoneNumber, setUserPhoneNumber] = useState<any>(null);
68
70
  const [phoneToShow, setPhoneToShow] = useState('');
71
+ const [openModal, setOpenModal] = useState(false)
69
72
 
70
73
  useEffect(() => {
71
74
  if (phoneInputData.phone.cellphone) {
@@ -459,7 +462,6 @@ const ProfileUI = (props: ProfileParams) => {
459
462
  />
460
463
  </View>
461
464
  )}
462
-
463
465
  {!validationFields.loading && !isEdit && (
464
466
  <EditButton>
465
467
  <OButton
@@ -474,12 +476,32 @@ const ProfileUI = (props: ProfileParams) => {
474
476
  />
475
477
  </EditButton>
476
478
  )}
477
-
479
+ {!!user?.schedule && (
480
+ <Pressable style={{ marginBottom: 10 }} onPress={() => setOpenModal(true)}>
481
+ <View style={{ flexDirection: 'row', justifyContent: 'space-between' }}>
482
+ <OText size={16}>{t('SCHEDULE', 'Schedule')}</OText>
483
+ <AntDesignIcon size={18} name='right' />
484
+ </View>
485
+ <View style={{
486
+ borderBottomColor: theme.colors.tabBar,
487
+ borderBottomWidth: 1,
488
+ marginTop: 10
489
+ }} />
490
+ </Pressable>
491
+ )}
478
492
  <Actions>
479
493
  <LanguageSelector />
480
494
 
481
495
  <LogoutButton />
482
496
  </Actions>
497
+ <OModal
498
+ open={openModal}
499
+ onClose={() => setOpenModal(false)}
500
+ entireModal
501
+ hideIcons
502
+ >
503
+ <DriverSchedule schedule={user?.schedule} />
504
+ </OModal>
483
505
  </ScrollView>
484
506
  )}
485
507
  </>
@@ -26,6 +26,7 @@ interface Props {
26
26
  isNotDecoration?: boolean;
27
27
  styleCloseButton?: any;
28
28
  order?: any;
29
+ hideIcons?: boolean
29
30
  }
30
31
 
31
32
  const OModal = (props: Props): React.ReactElement => {
@@ -47,6 +48,7 @@ const OModal = (props: Props): React.ReactElement => {
47
48
  style,
48
49
  styleCloseButton,
49
50
  order,
51
+ hideIcons
50
52
  } = props;
51
53
 
52
54
  const theme = useTheme();
@@ -70,8 +72,8 @@ const OModal = (props: Props): React.ReactElement => {
70
72
  alignItems: 'center',
71
73
  paddingHorizontal: 30,
72
74
  paddingTop: 30,
73
- paddingBottom: 25,
74
- borderBottomWidth: 2,
75
+ paddingBottom: !hideIcons ? 25 : 15,
76
+ borderBottomWidth: !hideIcons ? 2 : 0,
75
77
  borderBottomColor: '#e6e6e6',
76
78
  },
77
79
  titleGroups: {
@@ -218,50 +220,51 @@ const OModal = (props: Props): React.ReactElement => {
218
220
  {title}
219
221
  </OText>
220
222
  </View>
223
+ {!hideIcons && (
224
+ <View style={styles.titleGroups}>
225
+ <View style={styles.shadow}>
226
+ {order?.business?.logo ? (
227
+ <OIcon
228
+ url={optimizeImage(
229
+ order?.business?.logo,
230
+ 'h_300,c_limit',
231
+ )}
232
+ style={styles.titleIcons}
233
+ />
234
+ ) : (
235
+ <OIcon
236
+ src={theme.images.dummies.businessLogo}
237
+ style={styles.titleIcons}
238
+ />
239
+ )}
240
+ </View>
221
241
 
222
- <View style={styles.titleGroups}>
223
- <View style={styles.shadow}>
224
- {order?.business?.logo ? (
242
+ <View style={styles.shadow}>
225
243
  <OIcon
226
244
  url={optimizeImage(
227
- order?.business?.logo,
245
+ order?.customer?.photo ||
246
+ theme?.images?.dummies?.customerPhoto,
228
247
  'h_300,c_limit',
229
248
  )}
230
249
  style={styles.titleIcons}
231
250
  />
232
- ) : (
233
- <OIcon
234
- src={theme.images.dummies.businessLogo}
235
- style={styles.titleIcons}
236
- />
237
- )}
238
- </View>
251
+ </View>
239
252
 
240
- <View style={styles.shadow}>
241
- <OIcon
242
- url={optimizeImage(
243
- order?.customer?.photo ||
244
- theme?.images?.dummies?.customerPhoto,
245
- 'h_300,c_limit',
246
- )}
247
- style={styles.titleIcons}
248
- />
253
+ {order?.driver && (
254
+ <View style={styles.shadow}>
255
+ <OIcon
256
+ url={
257
+ optimizeImage(
258
+ order?.driver?.photo,
259
+ 'h_300,c_limit',
260
+ ) || theme?.images?.dummies?.driverPhoto
261
+ }
262
+ style={styles.titleIcons}
263
+ />
264
+ </View>
265
+ )}
249
266
  </View>
250
-
251
- {order?.driver && (
252
- <View style={styles.shadow}>
253
- <OIcon
254
- url={
255
- optimizeImage(
256
- order?.driver?.photo,
257
- 'h_300,c_limit',
258
- ) || theme?.images?.dummies?.driverPhoto
259
- }
260
- style={styles.titleIcons}
261
- />
262
- </View>
263
- )}
264
- </View>
267
+ )}
265
268
  </View>
266
269
  )}
267
270
  {children}
@@ -114,6 +114,10 @@ const CheckoutUI = (props: any) => {
114
114
  position: 'absolute',
115
115
  fontSize: 20
116
116
  },
117
+ detailWrapper: {
118
+ paddingHorizontal: 40,
119
+ width: '100%'
120
+ },
117
121
  wrapperNavbar: Platform.OS === 'ios'
118
122
  ? { paddingVertical: 0, paddingHorizontal: 40 }
119
123
  : { paddingVertical: 20, paddingHorizontal: 40 }
@@ -136,6 +140,8 @@ const CheckoutUI = (props: any) => {
136
140
  const [isDeliveryOptionModalVisible, setIsDeliveryOptionModalVisible] = useState(false)
137
141
  const [showGateway, setShowGateway] = useState<any>({ closedByUsed: false, open: false });
138
142
  const [webviewPaymethod, setWebviewPaymethod] = useState<any>(null)
143
+ const [isOpen, setIsOpen] = useState(false)
144
+ const [requiredFields, setRequiredFields] = useState<any>([])
139
145
 
140
146
  const placeSpotTypes = [3, 4]
141
147
  const businessConfigs = businessDetails?.business?.configs ?? []
@@ -173,10 +179,14 @@ const CheckoutUI = (props: any) => {
173
179
  }
174
180
 
175
181
  const handlePlaceOrder = (confirmPayment) => {
176
- if (!userErrors.length) {
182
+ if (!userErrors.length && !requiredFields?.length) {
177
183
  handlerClickPlaceOrder && handlerClickPlaceOrder(null, null, confirmPayment)
178
184
  return
179
185
  }
186
+ if (requiredFields?.length) {
187
+ setIsOpen(true)
188
+ return
189
+ }
180
190
  let stringError = ''
181
191
  Object.values(userErrors).map((item: any, i: number) => {
182
192
  stringError += (i + 1) === userErrors.length ? `- ${item?.message || item}` : `- ${item?.message || item}\n`
@@ -204,11 +214,12 @@ const CheckoutUI = (props: any) => {
204
214
  setUserErrors([])
205
215
  const errors = []
206
216
  const notFields = ['coupon', 'driver_tip', 'mobile_phone', 'address', 'zipcode', 'address_notes']
217
+ const _requiredFields: any = []
207
218
 
208
219
  Object.values(validationFields?.fields?.checkout).map((field: any) => {
209
220
  if (field?.required && !notFields.includes(field.code)) {
210
221
  if (!user[field?.code]) {
211
- errors.push(t(`VALIDATION_ERROR_${field.code.toUpperCase()}_REQUIRED`, `The field ${field?.name} is required`))
222
+ _requiredFields.push(field?.code)
212
223
  }
213
224
  }
214
225
  })
@@ -219,8 +230,9 @@ const CheckoutUI = (props: any) => {
219
230
  validationFields?.fields?.checkout?.cellphone?.required) ||
220
231
  configs?.verification_phone_required?.value === '1')
221
232
  ) {
222
- errors.push(t('VALIDATION_ERROR_MOBILE_PHONE_REQUIRED', 'The field Phone number is required'))
233
+ _requiredFields.push('cellphone')
223
234
  }
235
+ setRequiredFields(_requiredFields)
224
236
 
225
237
  if (phoneUpdate) {
226
238
  errors.push(t('NECESSARY_UPDATE_COUNTRY_PHONE_CODE', 'It is necessary to update your phone number'))
@@ -703,6 +715,28 @@ const CheckoutUI = (props: any) => {
703
715
  onClose={() => setOpenChangeStore(false)}
704
716
  />
705
717
  </OModal>
718
+ <OModal
719
+ open={isOpen}
720
+ onClose={() => setIsOpen(false)}
721
+ >
722
+ <View style={styles.detailWrapper}>
723
+ <UserDetails
724
+ isUserDetailsEdit
725
+ cartStatus={cart?.status}
726
+ businessId={cart?.business_id}
727
+ useValidationFields
728
+ useDefualtSessionManager
729
+ useSessionUser
730
+ isCheckout
731
+ isEdit
732
+ phoneUpdate={phoneUpdate}
733
+ togglePhoneUpdate={togglePhoneUpdate}
734
+ requiredFields={requiredFields}
735
+ hideUpdateButton
736
+ onClose={() => setIsOpen(false)}
737
+ />
738
+ </View>
739
+ </OModal>
706
740
  </ChContainer>
707
741
  </Container>
708
742
  {!cartState.loading && cart && cart?.status !== 2 && (
@@ -23,6 +23,8 @@ const UserDetailsUI = (props: any) => {
23
23
  isEdit,
24
24
  formState,
25
25
  cleanFormState,
26
+ requiredFields,
27
+ onClose,
26
28
  cartStatus,
27
29
  toggleIsEdit,
28
30
  validationFields,
@@ -30,12 +32,9 @@ const UserDetailsUI = (props: any) => {
30
32
  phoneUpdate,
31
33
  togglePhoneUpdate,
32
34
  isCheckout,
33
- checkPhoneCodeState,
34
35
  handleSendVerifyCode,
35
- handleCheckPhoneCode,
36
36
  verifyPhoneState,
37
- isVerifiedPhone,
38
- setCheckPhoneCodeState
37
+ setFormState
39
38
  } = props
40
39
 
41
40
  const theme = useTheme();
@@ -47,7 +46,9 @@ const UserDetailsUI = (props: any) => {
47
46
  const userData = props.userData || (!formState.result.error && formState.result?.result) || user
48
47
 
49
48
  const [isModalVisible, setIsModalVisible] = useState(false);
49
+ const [isSubmit, setIsSubmit] = useState(false)
50
50
  const [willVerifyOtpState, setWillVerifyOtpState] = useState(false);
51
+ const [checkPhoneCodeState, setCheckPhoneCodeState] = useState({ loading: false, result: { error: false } })
51
52
  const [phoneInputData, setPhoneInputData] = useState({
52
53
  error: '',
53
54
  phone: {
@@ -56,7 +57,6 @@ const UserDetailsUI = (props: any) => {
56
57
  },
57
58
  });
58
59
 
59
-
60
60
  useEffect(() => {
61
61
  if (isUserDetailsEdit) {
62
62
  !isEdit && toggleIsEdit()
@@ -68,6 +68,12 @@ const UserDetailsUI = (props: any) => {
68
68
  cleanFormState({ changes: {} })
69
69
  }
70
70
 
71
+ useEffect(() => {
72
+ if (isSubmit && !isEdit && requiredFields) {
73
+ onClose && onClose()
74
+ }
75
+ }, [isSubmit, requiredFields, isEdit])
76
+
71
77
  useEffect(() => {
72
78
  if (user?.cellphone && !user?.country_phone_code) {
73
79
  togglePhoneUpdate(true)
@@ -94,6 +100,18 @@ const UserDetailsUI = (props: any) => {
94
100
  }
95
101
  }
96
102
 
103
+ const handleSendPhoneCode = (values: any) => {
104
+ setWillVerifyOtpState(false)
105
+ setIsModalVisible(false)
106
+ setFormState({
107
+ ...formState,
108
+ changes: {
109
+ ...formState?.changes,
110
+ verification_code: values?.code
111
+ }
112
+ })
113
+ }
114
+
97
115
  useEffect(() => {
98
116
  if (willVerifyOtpState) handleVerifyCodeClick()
99
117
  }, [willVerifyOtpState])
@@ -120,10 +138,6 @@ const UserDetailsUI = (props: any) => {
120
138
  }
121
139
  }, [verifyPhoneState])
122
140
 
123
- useEffect(() => {
124
- if (isVerifiedPhone) setIsModalVisible(false)
125
- }, [isVerifiedPhone])
126
-
127
141
  return (
128
142
  <>
129
143
  {(validationFields.loading || formState.loading) && (
@@ -141,7 +155,7 @@ const UserDetailsUI = (props: any) => {
141
155
  <OText size={16} lineHeight={24} weight={'500'} color={theme.colors.textNormal}>
142
156
  {t('CUSTOMER_DETAILS', 'Customer Details')}
143
157
  </OText>
144
- {cartStatus !== 2 && (
158
+ {cartStatus !== 2 && !requiredFields && (
145
159
  !isEdit ? (
146
160
  <EditBtn onPress={() => toggleIsEdit()} activeOpacity={0.7}>
147
161
  <OIcon
@@ -192,6 +206,7 @@ const UserDetailsUI = (props: any) => {
192
206
  togglePhoneUpdate={togglePhoneUpdate}
193
207
  isCheckout={isCheckout}
194
208
  setWillVerifyOtpState={setWillVerifyOtpState}
209
+ setIsSubmit={setIsSubmit}
195
210
  />
196
211
  )}
197
212
  </UDContainer>
@@ -202,13 +217,12 @@ const UserDetailsUI = (props: any) => {
202
217
  entireModal
203
218
  >
204
219
  <VerifyPhone
205
- phone={phoneInputData.phone}
206
- verifyPhoneState={verifyPhoneState}
207
- checkPhoneCodeState={checkPhoneCodeState}
208
- handleCheckPhoneCode={handleCheckPhoneCode}
209
- setCheckPhoneCodeState={setCheckPhoneCodeState}
210
- handleVerifyCodeClick={handleVerifyCodeClick}
211
- onClose={() => setIsModalVisible(false)}
220
+ phone={phoneInputData.phone}
221
+ verifyPhoneState={verifyPhoneState}
222
+ checkPhoneCodeState={checkPhoneCodeState}
223
+ handleCheckPhoneCode={handleSendPhoneCode}
224
+ handleVerifyCodeClick={handleVerifyCodeClick}
225
+ onClose={() => setIsModalVisible(false)}
212
226
  />
213
227
  </OModal>
214
228
  <Spinner visible={verifyPhoneState?.loading} />
@@ -17,6 +17,9 @@ export const UserFormDetailsUI = (props: any) => {
17
17
  isEdit,
18
18
  formState,
19
19
  showField,
20
+ requiredFields,
21
+ onClose,
22
+ setIsSubmit,
20
23
  cleanFormState,
21
24
  onCloseProfile,
22
25
  isRequiredField,
@@ -26,7 +29,6 @@ export const UserFormDetailsUI = (props: any) => {
26
29
  phoneUpdate,
27
30
  hideUpdateButton,
28
31
  setWillVerifyOtpState,
29
- isVerifiedPhone,
30
32
  handleChangePromotions,
31
33
  } = props;
32
34
 
@@ -76,6 +78,8 @@ export const UserFormDetailsUI = (props: any) => {
76
78
 
77
79
  const [{ user }] = useSession();
78
80
  const [userPhoneNumber, setUserPhoneNumber] = useState<any>(null);
81
+ const [isValid, setIsValid] = useState(false)
82
+ const [isChanged, setIsChanged] = useState(false)
79
83
  const [phoneInputData, setPhoneInputData] = useState({
80
84
  error: '',
81
85
  phone: {
@@ -153,9 +157,6 @@ export const UserFormDetailsUI = (props: any) => {
153
157
  );
154
158
  return;
155
159
  }
156
- if (formState?.changes?.cellphone && !isVerifiedPhone) {
157
- showToast(ToastType.Error, t('VERIFY_ERROR_PHONE_NUMBER', 'The Phone Number field is not verified'))
158
- }
159
160
  let changes = null;
160
161
  if (user?.cellphone && !userPhoneNumber) {
161
162
  changes = {
@@ -163,12 +164,14 @@ export const UserFormDetailsUI = (props: any) => {
163
164
  cellphone: '',
164
165
  };
165
166
  }
167
+ setIsSubmit && setIsSubmit(true)
166
168
  handleButtonUpdateClick(changes);
167
169
  }
168
170
  };
169
171
 
170
172
  const handleChangePhoneNumber = (number: any) => {
171
173
  setPhoneInputData(number);
174
+ setIsChanged(true)
172
175
  let phoneNumber = {
173
176
  country_phone_code: {
174
177
  name: 'country_phone_code',
@@ -228,11 +231,22 @@ export const UserFormDetailsUI = (props: any) => {
228
231
  }, [user, isEdit]);
229
232
 
230
233
  useEffect(() => {
231
- if (!phoneInputData.error && phoneInputData?.phone?.country_phone_code && phoneInputData?.phone?.cellphone) {
234
+ if (!phoneInputData.error &&
235
+ phoneInputData?.phone?.country_phone_code &&
236
+ phoneInputData?.phone?.cellphone &&
237
+ configs?.verification_phone_required?.value === '1' &&
238
+ formState?.changes?.cellphone &&
239
+ isChanged) {
232
240
  setWillVerifyOtpState?.(true)
233
241
  }
234
- }, [phoneInputData])
242
+ }, [phoneInputData, configs?.verification_phone_required?.value, isChanged])
235
243
 
244
+ useEffect(() => {
245
+ if (!requiredFields || formState?.changes?.length === 0) return
246
+ const _isValid = requiredFields.every((key: any) => formState?.changes[key])
247
+ setIsValid(_isValid)
248
+ }, [formState?.changes, requiredFields])
249
+
236
250
  return (
237
251
  <>
238
252
  <UDForm>
@@ -245,7 +259,7 @@ export const UserFormDetailsUI = (props: any) => {
245
259
  }).map(
246
260
  (field: any) =>
247
261
  showField &&
248
- showField(field.code) && (
262
+ showField(field.code) && ((requiredFields && requiredFields.includes(field.code)) || !requiredFields) && (
249
263
  <React.Fragment key={field.id}>
250
264
  <Controller
251
265
  key={field.id}
@@ -319,7 +333,7 @@ export const UserFormDetailsUI = (props: any) => {
319
333
  ),
320
334
  )}
321
335
 
322
- {!!showInputPhoneNumber && (
336
+ {!!showInputPhoneNumber &&((requiredFields && requiredFields.includes('cellphone')) || !requiredFields) && (
323
337
  <WrapperPhone>
324
338
  <OText size={14} lineHeight={21} weight={'500'} color={theme.colors.textNormal}>{t('PHONE', 'Phone')}</OText>
325
339
  <PhoneInputNumber
@@ -344,71 +358,76 @@ export const UserFormDetailsUI = (props: any) => {
344
358
  )}
345
359
  </WrapperPhone>
346
360
  )}
347
- <Controller
348
- control={control}
349
- render={() => (
350
- <>
351
- <OText size={14} lineHeight={21} color={theme.colors.textNormal} weight={'500'} style={{ textTransform: 'capitalize', alignSelf: 'flex-start' }}>
352
- {t('PASSWORD', 'Password')}
353
- </OText>
354
- <OInput
355
- name='password'
356
- placeholder={t('FRONT_VISUALS_PASSWORD', 'Password')}
357
- inputStyle={styles.inputStyle}
358
- style={{ paddingLeft: 0, paddingRight: 0, marginTop: 6, height: 44, minHeight: 44 }}
359
- autoCapitalize='none'
360
- isDisabled={false}
361
- value={
362
- formState?.changes['password'] ??
363
- (user && user['password']) ??
364
- ''
365
- }
366
- onChange={(val: any) => {
367
- setValue('password', val.target.value)
368
- handleChangeInput(val)
369
- }}
370
- autoCorrect
371
- type='default'
372
- returnKeyType="done"
373
- autoCompleteType='off'
374
- isSecured
375
- />
376
- </>
377
- )}
378
- name='password'
379
- rules={getInputRules({ name: 'password', code: 'password' })}
380
- defaultValue=''
381
- />
382
- <Controller
383
- control={control}
384
- render={({ onChange, value }: any) => (
385
- <TouchableOpacity
386
- style={{ flexDirection: 'row', alignItems: 'center', marginBottom: 20, width: '100%' }}
387
- onPress={() => {
388
- onChange(!value)
389
- handleChangePromotions(!value)
390
- }}
391
- >
392
- <CheckBox
393
- value={value}
394
- boxType={'square'}
395
- tintColors={{
396
- true: theme.colors.primary,
397
- false: theme.colors.disabled
361
+ {!requiredFields && (
362
+ <Controller
363
+ control={control}
364
+ render={() => (
365
+ <>
366
+ <OText size={14} lineHeight={21} color={theme.colors.textNormal} weight={'500'} style={{ textTransform: 'capitalize', alignSelf: 'flex-start' }}>
367
+ {t('PASSWORD', 'Password')}
368
+ </OText>
369
+ <OInput
370
+ name='password'
371
+ placeholder={t('FRONT_VISUALS_PASSWORD', 'Password')}
372
+ inputStyle={styles.inputStyle}
373
+ style={{ paddingLeft: 0, paddingRight: 0, marginTop: 6, height: 44, minHeight: 44 }}
374
+ autoCapitalize='none'
375
+ isDisabled={false}
376
+ value={
377
+ formState?.changes['password'] ??
378
+ (user && user['password']) ??
379
+ ''
380
+ }
381
+ onChange={(val: any) => {
382
+ setValue('password', val.target.value)
383
+ handleChangeInput(val)
384
+ }}
385
+ autoCorrect
386
+ type='default'
387
+ returnKeyType="done"
388
+ autoCompleteType='off'
389
+ isSecured
390
+ />
391
+ </>
392
+ )}
393
+ name='password'
394
+ rules={getInputRules({ name: 'password', code: 'password' })}
395
+ defaultValue=''
396
+ />
397
+ )}
398
+ {!requiredFields && (
399
+ <Controller
400
+ control={control}
401
+ render={({ onChange, value }: any) => (
402
+ <TouchableOpacity
403
+ style={{ flexDirection: 'row', alignItems: 'center', marginBottom: 20, width: '100%' }}
404
+ onPress={() => {
405
+ onChange(!value)
406
+ handleChangePromotions(!value)
398
407
  }}
399
- tintColor={theme.colors.disabled}
400
- onCheckColor={theme.colors.primary}
401
- onTintColor={theme.colors.primary}
402
- style={Platform.OS === 'ios' && styles.checkBoxStyle}
403
- />
404
- <OText style={{ fontSize: 14, paddingHorizontal: 5, paddingLeft: 10 }}>{t('RECEIVE_NEWS_EXCLUSIVE_PROMOTIONS', 'Receive newsletters and exclusive promotions')}</OText>
405
- </TouchableOpacity>
406
- )}
407
- name='promotions'
408
- defaultValue={formState?.result?.result
409
- ? !!formState?.result?.result?.settings?.notification?.newsletter
410
- : !!(formState?.changes?.settings?.notification?.newsletter ?? (user && user?.settings?.notification?.newsletter))}
411
- />
408
+ >
409
+ <CheckBox
410
+ value={value}
411
+ boxType={'square'}
412
+ tintColors={{
413
+ true: theme.colors.primary,
414
+ false: theme.colors.disabled
415
+ }}
416
+ tintColor={theme.colors.disabled}
417
+ onCheckColor={theme.colors.primary}
418
+ onTintColor={theme.colors.primary}
419
+ style={Platform.OS === 'ios' && styles.checkBoxStyle}
420
+ />
421
+ <OText style={{ fontSize: 14, paddingHorizontal: 5, paddingLeft: 10 }}>{t('RECEIVE_NEWS_EXCLUSIVE_PROMOTIONS', 'Receive newsletters and exclusive promotions')}</OText>
422
+ </TouchableOpacity>
423
+ )}
424
+ name='promotions'
425
+ defaultValue={formState?.result?.result
426
+ ? !!formState?.result?.result?.settings?.notification?.newsletter
427
+ : !!(formState?.changes?.settings?.notification?.newsletter ?? (user && user?.settings?.notification?.newsletter))}
428
+ />
429
+ )}
430
+
412
431
  </UDWrapper>
413
432
  )}
414
433
  {validationFields?.loading && (
@@ -440,6 +459,22 @@ export const UserFormDetailsUI = (props: any) => {
440
459
  )}
441
460
  </>
442
461
  )}
462
+ {requiredFields && (
463
+ <OButton
464
+ text={
465
+ formState.loading
466
+ ? t('UPDATING', 'Updating...')
467
+ : t('CONTINUE', 'Continue')
468
+ }
469
+ bgColor={theme.colors.white}
470
+ textStyle={{ color: theme.colors.primary, fontSize: 14 }}
471
+ borderColor={theme.colors.primary}
472
+ isDisabled={formState.loading || !isValid}
473
+ imgRightSrc={null}
474
+ style={{ borderRadius: 7.6, shadowOpacity: 0, width: '100%', borderWidth: 1, marginTop: 20, marginBottom: 20 }}
475
+ onClick={handleSubmit(onSubmit)}
476
+ />
477
+ )}
443
478
  </>
444
479
  );
445
480
  };
@@ -35,12 +35,9 @@ const ProfileUI = (props: ProfileParams) => {
35
35
  cleanFormState,
36
36
  handleChangeInput,
37
37
  handleButtonUpdateClick,
38
- checkPhoneCodeState,
39
38
  handleSendVerifyCode,
40
- handleCheckPhoneCode,
41
39
  verifyPhoneState,
42
- isVerifiedPhone,
43
- setCheckPhoneCodeState
40
+ setFormState
44
41
  } = props;
45
42
 
46
43
  const theme = useTheme();
@@ -73,6 +70,7 @@ const ProfileUI = (props: ProfileParams) => {
73
70
  const { handleSubmit, errors, setValue, control } = useForm();
74
71
  const [isModalVisible, setIsModalVisible] = useState(false);
75
72
  const [willVerifyOtpState, setWillVerifyOtpState] = useState(false);
73
+ const [checkPhoneCodeState, setCheckPhoneCodeState] = useState({ loading: false, result: { error: false } })
76
74
 
77
75
  const [phoneInputData, setPhoneInputData] = useState({
78
76
  error: '',
@@ -272,9 +270,17 @@ const ProfileUI = (props: ProfileParams) => {
272
270
  }
273
271
  }, [verifyPhoneState])
274
272
 
275
- useEffect(() => {
276
- if (isVerifiedPhone) setIsModalVisible(false)
277
- }, [isVerifiedPhone])
273
+ const handleSendPhoneCode = (values: any) => {
274
+ setWillVerifyOtpState(false)
275
+ setIsModalVisible(false)
276
+ setFormState({
277
+ ...formState,
278
+ changes: {
279
+ ...formState?.changes,
280
+ verification_code: values?.code
281
+ }
282
+ })
283
+ }
278
284
 
279
285
  return (
280
286
  <>
@@ -331,8 +337,7 @@ const ProfileUI = (props: ProfileParams) => {
331
337
  phone={phoneInputData.phone}
332
338
  verifyPhoneState={verifyPhoneState}
333
339
  checkPhoneCodeState={checkPhoneCodeState}
334
- handleCheckPhoneCode={handleCheckPhoneCode}
335
- setCheckPhoneCodeState={setCheckPhoneCodeState}
340
+ handleCheckPhoneCode={handleSendPhoneCode}
336
341
  handleVerifyCodeClick={handleVerifyCodeClick}
337
342
  onClose={() => setIsModalVisible(false)}
338
343
  />