ordering-ui-react-native 0.14.77 → 0.14.80
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 +1 -1
- package/src/DeliveryApp.tsx +1 -32
- package/themes/original/src/components/BusinessesListing/index.tsx +26 -6
- package/themes/original/src/components/SignupForm/index.tsx +58 -30
- package/themes/original/src/components/UserDetails/index.tsx +95 -4
- package/themes/original/src/components/UserFormDetails/index.tsx +51 -5
- package/themes/original/src/components/UserProfileForm/index.tsx +114 -36
- package/themes/original/src/components/VerifyPhone/index.tsx +7 -10
- package/themes/original/src/components/VerifyPhone/styles.tsx +1 -2
- package/themes/original/src/types/index.tsx +7 -0
package/package.json
CHANGED
package/src/DeliveryApp.tsx
CHANGED
|
@@ -7,8 +7,7 @@
|
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
import * as React from 'react';
|
|
10
|
-
import { LogBox
|
|
11
|
-
import * as Sentry from "@sentry/react-native";
|
|
10
|
+
import { LogBox } from 'react-native';
|
|
12
11
|
import { OrderingProvider } from 'ordering-components/native';
|
|
13
12
|
import RNBootSplash from "react-native-bootsplash";
|
|
14
13
|
|
|
@@ -23,36 +22,6 @@ import theme from './theme.json';
|
|
|
23
22
|
import AppContainer from './AppContainer';
|
|
24
23
|
import { FacebookPixel } from './components/FacebookPixel';
|
|
25
24
|
|
|
26
|
-
Sentry.init({
|
|
27
|
-
environment: Platform.OS === 'ios' ? 'ios' : 'android',
|
|
28
|
-
dsn: 'https://90197fffe6a1431b8c3eb79e1e36f0ee@o460529.ingest.sentry.io/5722123',
|
|
29
|
-
release: process.env.npm_package_version ? 'ordering-ui-native@' + process.env.npm_package_version : 'ordering-ui-native@' + '0.0.4',
|
|
30
|
-
ignoreErrors: [
|
|
31
|
-
'is not defined',
|
|
32
|
-
'is not a function',
|
|
33
|
-
'can\'t find variable',
|
|
34
|
-
'objects are not valid',
|
|
35
|
-
'element type is invalid',
|
|
36
|
-
'requiring module',
|
|
37
|
-
'has not been registered',
|
|
38
|
-
'failed to connect to debugger!',
|
|
39
|
-
'rendered more hooks than',
|
|
40
|
-
'rendered fewer hooks than',
|
|
41
|
-
'should have a queue',
|
|
42
|
-
'the OS most likely terminated',
|
|
43
|
-
'Connection timed out',
|
|
44
|
-
'java.io.EOFException',
|
|
45
|
-
'Abort',
|
|
46
|
-
'Segfault',
|
|
47
|
-
'Failed to allocate a',
|
|
48
|
-
'Application Not Responding',
|
|
49
|
-
'connection no longer valid',
|
|
50
|
-
'IllegalInstruction',
|
|
51
|
-
'React.Children.only expected to receive a single React element child.',
|
|
52
|
-
'unrecognized selector sent to instance'
|
|
53
|
-
],
|
|
54
|
-
});
|
|
55
|
-
|
|
56
25
|
LogBox.ignoreLogs([
|
|
57
26
|
'Sending \`onAnimatedValueUpdate` with no listeners registered.',
|
|
58
27
|
'Non-serializable values were found in the navigation state.',
|
|
@@ -7,7 +7,8 @@ import {
|
|
|
7
7
|
ScrollView,
|
|
8
8
|
Platform,
|
|
9
9
|
TouchableOpacity,
|
|
10
|
-
RefreshControl
|
|
10
|
+
RefreshControl,
|
|
11
|
+
AppState
|
|
11
12
|
} from 'react-native';
|
|
12
13
|
import {
|
|
13
14
|
BusinessList as BusinessesListingController,
|
|
@@ -63,8 +64,9 @@ const BusinessesListingUI = (props: BusinessesListingParams) => {
|
|
|
63
64
|
|
|
64
65
|
const theme = useTheme();
|
|
65
66
|
const isFocused = useIsFocused();
|
|
67
|
+
const appState = useRef(AppState.currentState)
|
|
68
|
+
const [appStateVisible, setAppStateVisible] = useState(appState.current);
|
|
66
69
|
const [refreshing] = useState(false);
|
|
67
|
-
|
|
68
70
|
const styles = StyleSheet.create({
|
|
69
71
|
container: {
|
|
70
72
|
marginBottom: 0,
|
|
@@ -168,15 +170,13 @@ const BusinessesListingUI = (props: BusinessesListingParams) => {
|
|
|
168
170
|
const resetInactivityTimeout = () => {
|
|
169
171
|
clearTimeout(timerId.current)
|
|
170
172
|
timerId.current = setInterval(() => {
|
|
171
|
-
|
|
172
|
-
getBusinesses(true)
|
|
173
|
-
}
|
|
173
|
+
getBusinesses(true)
|
|
174
174
|
}, 300000)
|
|
175
175
|
}
|
|
176
176
|
|
|
177
177
|
useEffect(() => {
|
|
178
178
|
resetInactivityTimeout()
|
|
179
|
-
}, [])
|
|
179
|
+
}, [businessesList.loading])
|
|
180
180
|
|
|
181
181
|
const handleOnRefresh = () => {
|
|
182
182
|
if (!businessesList.loading) {
|
|
@@ -197,6 +197,26 @@ const BusinessesListingUI = (props: BusinessesListingParams) => {
|
|
|
197
197
|
})
|
|
198
198
|
}, [orderState?.options?.address?.location])
|
|
199
199
|
|
|
200
|
+
useEffect(() => {
|
|
201
|
+
const onFocusApp = (nextAppState : any) => {
|
|
202
|
+
if (
|
|
203
|
+
appState.current.match(/inactive|background/) &&
|
|
204
|
+
nextAppState === "active"
|
|
205
|
+
) {
|
|
206
|
+
if (!businessesList.loading) {
|
|
207
|
+
getBusinesses(true);
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
appState.current = nextAppState;
|
|
211
|
+
setAppStateVisible(appState.current);
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
AppState.addEventListener("change", onFocusApp);
|
|
215
|
+
return () => {
|
|
216
|
+
AppState.removeEventListener('change', onFocusApp);
|
|
217
|
+
};
|
|
218
|
+
}, [])
|
|
219
|
+
|
|
200
220
|
useFocusEffect(
|
|
201
221
|
useCallback(() => {
|
|
202
222
|
getBusinesses(true)
|
|
@@ -62,7 +62,8 @@ const SignupFormUI = (props: SignupParams) => {
|
|
|
62
62
|
setCheckPhoneCodeState,
|
|
63
63
|
handleSendVerifyCode,
|
|
64
64
|
handleCheckPhoneCode,
|
|
65
|
-
notificationState
|
|
65
|
+
notificationState,
|
|
66
|
+
handleChangePromotions
|
|
66
67
|
} = props;
|
|
67
68
|
|
|
68
69
|
const theme = useTheme();
|
|
@@ -92,9 +93,9 @@ const SignupFormUI = (props: SignupParams) => {
|
|
|
92
93
|
marginBottom: 7,
|
|
93
94
|
},
|
|
94
95
|
checkBoxStyle: {
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
96
|
+
width: 25,
|
|
97
|
+
height: 25,
|
|
98
|
+
}
|
|
98
99
|
});
|
|
99
100
|
|
|
100
101
|
const [, { showToast }] = useToast();
|
|
@@ -281,9 +282,9 @@ const SignupFormUI = (props: SignupParams) => {
|
|
|
281
282
|
const supported = await Linking.canOpenURL(url);
|
|
282
283
|
|
|
283
284
|
if (supported) {
|
|
284
|
-
|
|
285
|
+
await Linking.openURL(url);
|
|
285
286
|
} else {
|
|
286
|
-
|
|
287
|
+
showToast(ToastType.Error, t('VALIDATION_ERROR_ACTIVE_URL', 'The _attribute_ is not a valid URL.').replace('_attribute_', t('URL', 'URL')))
|
|
287
288
|
}
|
|
288
289
|
}
|
|
289
290
|
|
|
@@ -470,6 +471,33 @@ const SignupFormUI = (props: SignupParams) => {
|
|
|
470
471
|
</View>
|
|
471
472
|
)}
|
|
472
473
|
|
|
474
|
+
<View style={{ flexDirection: 'row', alignItems: 'center', marginBottom: 20 }}>
|
|
475
|
+
<Controller
|
|
476
|
+
control={control}
|
|
477
|
+
render={({ onChange, value }: any) => (
|
|
478
|
+
<CheckBox
|
|
479
|
+
value={value}
|
|
480
|
+
onValueChange={newValue => {
|
|
481
|
+
onChange(newValue)
|
|
482
|
+
handleChangePromotions()
|
|
483
|
+
}}
|
|
484
|
+
boxType={'square'}
|
|
485
|
+
tintColors={{
|
|
486
|
+
true: theme.colors.primary,
|
|
487
|
+
false: theme.colors.disabled
|
|
488
|
+
}}
|
|
489
|
+
tintColor={theme.colors.disabled}
|
|
490
|
+
onCheckColor={theme.colors.primary}
|
|
491
|
+
onTintColor={theme.colors.primary}
|
|
492
|
+
style={Platform.OS === 'ios' && style.checkBoxStyle}
|
|
493
|
+
/>
|
|
494
|
+
)}
|
|
495
|
+
name='promotions'
|
|
496
|
+
defaultValue={false}
|
|
497
|
+
/>
|
|
498
|
+
<OText style={{ fontSize: 14, paddingHorizontal: 5 }}>{t('RECEIVE_NEWS_EXCLUSIVE_PROMOTIONS', 'Receive newsletters and exclusive promotions')}</OText>
|
|
499
|
+
</View>
|
|
500
|
+
|
|
473
501
|
{configs?.terms_and_conditions?.value === 'true' && (
|
|
474
502
|
<View style={{ flexDirection: 'row', alignItems: 'center', marginBottom: 20 }}>
|
|
475
503
|
<Controller
|
|
@@ -592,25 +620,25 @@ const SignupFormUI = (props: SignupParams) => {
|
|
|
592
620
|
textStyle={{ color: 'white' }}
|
|
593
621
|
imgRightSrc={null}
|
|
594
622
|
isDisabled={formState.loading || validationFields.loading}
|
|
595
|
-
style={{ borderRadius: 7.6, marginTop: 6,shadowOpacity: 0 }}
|
|
623
|
+
style={{ borderRadius: 7.6, marginTop: 6, shadowOpacity: 0 }}
|
|
596
624
|
/>
|
|
597
625
|
)}
|
|
598
626
|
</FormInput>
|
|
599
627
|
|
|
600
628
|
{
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
629
|
+
onNavigationRedirect && loginButtonText && (
|
|
630
|
+
<View style={style.wrappText}>
|
|
631
|
+
<OText size={14} style={{ marginRight: 5 }}>
|
|
632
|
+
{t('MOBILE_FRONT_ALREADY_HAVE_AN_ACCOUNT', 'Already have an account?')}
|
|
633
|
+
</OText>
|
|
634
|
+
<Pressable onPress={() => onNavigationRedirect('Login')}>
|
|
635
|
+
<OText size={14} color={theme.colors.primary}>
|
|
636
|
+
{loginButtonText}
|
|
637
|
+
</OText>
|
|
638
|
+
</Pressable>
|
|
639
|
+
</View>
|
|
640
|
+
)
|
|
641
|
+
}
|
|
614
642
|
<View
|
|
615
643
|
style={{
|
|
616
644
|
flexDirection: 'row',
|
|
@@ -632,23 +660,23 @@ const SignupFormUI = (props: SignupParams) => {
|
|
|
632
660
|
|
|
633
661
|
{configs && Object.keys(configs).length > 0 && (
|
|
634
662
|
(((configs?.facebook_login?.value === 'true' || configs?.facebook_login?.value === '1') && configs?.facebook_id?.value) ||
|
|
635
|
-
|
|
663
|
+
(configs?.google_login_client_id?.value !== '' && configs?.google_login_client_id?.value !== null)) &&
|
|
636
664
|
(
|
|
637
665
|
<ButtonsWrapper>
|
|
638
666
|
<SocialButtons>
|
|
639
667
|
{(configs?.facebook_login?.value === 'true' || configs?.facebook_login?.value === '1') &&
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
668
|
+
configs?.facebook_id?.value && (
|
|
669
|
+
<FacebookLogin
|
|
670
|
+
notificationState={notificationState}
|
|
671
|
+
handleErrors={(err: any) => showToast(ToastType.Error, err)}
|
|
672
|
+
handleLoading={(val: boolean) => setIsFBLoading(val)}
|
|
673
|
+
handleSuccessFacebookLogin={handleSuccessFacebook}
|
|
674
|
+
/>
|
|
675
|
+
)}
|
|
648
676
|
{(configs?.google_login_client_id?.value !== '' && configs?.google_login_client_id?.value !== null) && (
|
|
649
677
|
<GoogleLogin
|
|
650
678
|
notificationState={notificationState}
|
|
651
|
-
|
|
679
|
+
webClientId={configs?.google_login_client_id?.value}
|
|
652
680
|
handleErrors={(err: any) => showToast(ToastType.Error, err)}
|
|
653
681
|
handleLoading={(val: boolean) => setIsFBLoading(val)}
|
|
654
682
|
handleSuccessGoogleLogin={handleSuccessFacebook}
|
|
@@ -3,14 +3,17 @@ import { TouchableOpacity, View } from 'react-native';
|
|
|
3
3
|
import MaterialIcon from 'react-native-vector-icons/MaterialCommunityIcons';
|
|
4
4
|
|
|
5
5
|
import { UDContainer, UDHeader, UDForm, UDInfo, EditBtn } from './styles';
|
|
6
|
-
|
|
7
6
|
import {
|
|
8
7
|
UserFormDetails as UserFormController,
|
|
9
8
|
useLanguage,
|
|
10
9
|
useSession,
|
|
10
|
+
ToastType,
|
|
11
|
+
useToast
|
|
11
12
|
} from 'ordering-components/native';
|
|
12
13
|
import { useTheme } from 'styled-components/native';
|
|
13
|
-
import { OIcon, OText } from '../shared';
|
|
14
|
+
import { OIcon, OText, OModal } from '../shared';
|
|
15
|
+
import { VerifyPhone } from '../VerifyPhone';
|
|
16
|
+
import Spinner from 'react-native-loading-spinner-overlay';
|
|
14
17
|
|
|
15
18
|
import { UserFormDetailsUI } from '../UserFormDetails';
|
|
16
19
|
import { Fade, Placeholder, PlaceholderLine } from 'rn-placeholder';
|
|
@@ -26,15 +29,33 @@ const UserDetailsUI = (props: any) => {
|
|
|
26
29
|
isUserDetailsEdit,
|
|
27
30
|
phoneUpdate,
|
|
28
31
|
togglePhoneUpdate,
|
|
29
|
-
isCheckout
|
|
32
|
+
isCheckout,
|
|
33
|
+
checkPhoneCodeState,
|
|
34
|
+
handleSendVerifyCode,
|
|
35
|
+
handleCheckPhoneCode,
|
|
36
|
+
verifyPhoneState,
|
|
37
|
+
isVerifiedPhone,
|
|
38
|
+
setCheckPhoneCodeState
|
|
30
39
|
} = props
|
|
31
40
|
|
|
32
41
|
const theme = useTheme();
|
|
33
42
|
|
|
34
43
|
const [, t] = useLanguage()
|
|
35
44
|
const [{ user }] = useSession()
|
|
45
|
+
const [, { showToast }] = useToast();
|
|
46
|
+
|
|
36
47
|
const userData = props.userData || (!formState.result.error && formState.result?.result) || user
|
|
37
48
|
|
|
49
|
+
const [isModalVisible, setIsModalVisible] = useState(false);
|
|
50
|
+
const [willVerifyOtpState, setWillVerifyOtpState] = useState(false);
|
|
51
|
+
const [phoneInputData, setPhoneInputData] = useState({
|
|
52
|
+
error: '',
|
|
53
|
+
phone: {
|
|
54
|
+
country_phone_code: null,
|
|
55
|
+
cellphone: null,
|
|
56
|
+
},
|
|
57
|
+
});
|
|
58
|
+
|
|
38
59
|
|
|
39
60
|
useEffect(() => {
|
|
40
61
|
if (isUserDetailsEdit) {
|
|
@@ -55,6 +76,54 @@ const UserDetailsUI = (props: any) => {
|
|
|
55
76
|
}
|
|
56
77
|
}, [user?.country_phone_code])
|
|
57
78
|
|
|
79
|
+
const handleVerifyCodeClick = () => {
|
|
80
|
+
if (formState?.changes?.cellphone && formState?.changes?.country_phone_code) {
|
|
81
|
+
const { cellphone, country_phone_code: countryPhoneCode } = formState?.changes
|
|
82
|
+
|
|
83
|
+
setPhoneInputData({
|
|
84
|
+
error: '',
|
|
85
|
+
phone: {
|
|
86
|
+
country_phone_code: countryPhoneCode,
|
|
87
|
+
cellphone: cellphone,
|
|
88
|
+
},
|
|
89
|
+
});
|
|
90
|
+
handleSendVerifyCode({
|
|
91
|
+
cellphone: cellphone,
|
|
92
|
+
country_phone_code: countryPhoneCode
|
|
93
|
+
})
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
useEffect(() => {
|
|
98
|
+
if (willVerifyOtpState) handleVerifyCodeClick()
|
|
99
|
+
}, [willVerifyOtpState])
|
|
100
|
+
|
|
101
|
+
useEffect(() => {
|
|
102
|
+
if (verifyPhoneState && !verifyPhoneState?.loading) {
|
|
103
|
+
if (verifyPhoneState.result?.error) {
|
|
104
|
+
const message = typeof verifyPhoneState?.result?.result === 'string'
|
|
105
|
+
? verifyPhoneState?.result?.result
|
|
106
|
+
: verifyPhoneState?.result?.result[0]
|
|
107
|
+
verifyPhoneState.result?.result && showToast(
|
|
108
|
+
ToastType.Error,
|
|
109
|
+
message
|
|
110
|
+
)
|
|
111
|
+
setWillVerifyOtpState(false)
|
|
112
|
+
return
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
const okResult = verifyPhoneState.result?.result === 'OK'
|
|
116
|
+
if (okResult) {
|
|
117
|
+
!isModalVisible && setIsModalVisible(true)
|
|
118
|
+
setWillVerifyOtpState(false)
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}, [verifyPhoneState])
|
|
122
|
+
|
|
123
|
+
useEffect(() => {
|
|
124
|
+
if (isVerifiedPhone) setIsModalVisible(false)
|
|
125
|
+
}, [isVerifiedPhone])
|
|
126
|
+
|
|
58
127
|
return (
|
|
59
128
|
<>
|
|
60
129
|
{(validationFields.loading || formState.loading) && (
|
|
@@ -117,10 +186,32 @@ const UserDetailsUI = (props: any) => {
|
|
|
117
186
|
)}
|
|
118
187
|
</UDInfo>
|
|
119
188
|
) : (
|
|
120
|
-
<UserFormDetailsUI
|
|
189
|
+
<UserFormDetailsUI
|
|
190
|
+
{...props}
|
|
191
|
+
phoneUpdate={phoneUpdate}
|
|
192
|
+
togglePhoneUpdate={togglePhoneUpdate}
|
|
193
|
+
isCheckout={isCheckout}
|
|
194
|
+
setWillVerifyOtpState={setWillVerifyOtpState}
|
|
195
|
+
/>
|
|
121
196
|
)}
|
|
122
197
|
</UDContainer>
|
|
123
198
|
)}
|
|
199
|
+
<OModal
|
|
200
|
+
open={isModalVisible}
|
|
201
|
+
onClose={() => setIsModalVisible(false)}
|
|
202
|
+
entireModal
|
|
203
|
+
>
|
|
204
|
+
<VerifyPhone
|
|
205
|
+
phone={phoneInputData.phone}
|
|
206
|
+
verifyPhoneState={verifyPhoneState}
|
|
207
|
+
checkPhoneCodeState={checkPhoneCodeState}
|
|
208
|
+
handleCheckPhoneCode={handleCheckPhoneCode}
|
|
209
|
+
setCheckPhoneCodeState={setCheckPhoneCodeState}
|
|
210
|
+
handleVerifyCodeClick={handleVerifyCodeClick}
|
|
211
|
+
onClose={() => setIsModalVisible(false)}
|
|
212
|
+
/>
|
|
213
|
+
</OModal>
|
|
214
|
+
<Spinner visible={verifyPhoneState?.loading} />
|
|
124
215
|
</>
|
|
125
216
|
)
|
|
126
217
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React, { useEffect, useState } from 'react';
|
|
2
|
-
import { StyleSheet, View } from 'react-native';
|
|
2
|
+
import { Platform, StyleSheet, View } from 'react-native';
|
|
3
3
|
import { useSession, useLanguage, ToastType, useToast, useConfig } from 'ordering-components/native';
|
|
4
4
|
import { useTheme } from 'styled-components/native';
|
|
5
5
|
import { useForm, Controller } from 'react-hook-form';
|
|
@@ -10,6 +10,7 @@ import { OText, OButton, OInput } from '../shared';
|
|
|
10
10
|
|
|
11
11
|
import { PhoneInputNumber } from '../PhoneInputNumber';
|
|
12
12
|
import { sortInputFields } from '../../utils';
|
|
13
|
+
import CheckBox from '@react-native-community/checkbox';
|
|
13
14
|
|
|
14
15
|
export const UserFormDetailsUI = (props: any) => {
|
|
15
16
|
const {
|
|
@@ -24,6 +25,9 @@ export const UserFormDetailsUI = (props: any) => {
|
|
|
24
25
|
handleButtonUpdateClick,
|
|
25
26
|
phoneUpdate,
|
|
26
27
|
hideUpdateButton,
|
|
28
|
+
setWillVerifyOtpState,
|
|
29
|
+
isVerifiedPhone,
|
|
30
|
+
handleChangePromotions
|
|
27
31
|
} = props;
|
|
28
32
|
|
|
29
33
|
const theme = useTheme();
|
|
@@ -58,6 +62,10 @@ export const UserFormDetailsUI = (props: any) => {
|
|
|
58
62
|
paddingStart: 0,
|
|
59
63
|
paddingBottom: 0,
|
|
60
64
|
marginBottom: -0,
|
|
65
|
+
},
|
|
66
|
+
checkBoxStyle: {
|
|
67
|
+
width: 25,
|
|
68
|
+
height: 25,
|
|
61
69
|
}
|
|
62
70
|
});
|
|
63
71
|
|
|
@@ -133,8 +141,8 @@ export const UserFormDetailsUI = (props: any) => {
|
|
|
133
141
|
if (
|
|
134
142
|
formState.changes?.cellphone === null &&
|
|
135
143
|
((validationFields?.fields?.checkout?.cellphone?.enabled &&
|
|
136
|
-
|
|
137
|
-
|
|
144
|
+
validationFields?.fields?.checkout?.cellphone?.required) ||
|
|
145
|
+
configs?.verification_phone_required?.value === '1')
|
|
138
146
|
) {
|
|
139
147
|
showToast(
|
|
140
148
|
ToastType.Error,
|
|
@@ -145,6 +153,9 @@ export const UserFormDetailsUI = (props: any) => {
|
|
|
145
153
|
);
|
|
146
154
|
return;
|
|
147
155
|
}
|
|
156
|
+
if (formState?.changes?.cellphone && !isVerifiedPhone) {
|
|
157
|
+
showToast(ToastType.Error, t('VERIFY_ERROR_PHONE_NUMBER', 'The Phone Number field is not verified'))
|
|
158
|
+
}
|
|
148
159
|
let changes = null;
|
|
149
160
|
if (user?.cellphone && !userPhoneNumber) {
|
|
150
161
|
changes = {
|
|
@@ -205,6 +216,13 @@ export const UserFormDetailsUI = (props: any) => {
|
|
|
205
216
|
}
|
|
206
217
|
}
|
|
207
218
|
}, [user, isEdit]);
|
|
219
|
+
|
|
220
|
+
useEffect(() => {
|
|
221
|
+
if (!phoneInputData.error && phoneInputData?.phone?.country_phone_code && phoneInputData?.phone?.cellphone) {
|
|
222
|
+
setWillVerifyOtpState(true)
|
|
223
|
+
}
|
|
224
|
+
}, [phoneInputData])
|
|
225
|
+
|
|
208
226
|
return (
|
|
209
227
|
<>
|
|
210
228
|
<UDForm>
|
|
@@ -320,7 +338,7 @@ export const UserFormDetailsUI = (props: any) => {
|
|
|
320
338
|
render={() => (
|
|
321
339
|
<>
|
|
322
340
|
<OText size={14} lineHeight={21} color={theme.colors.textNormal} weight={'500'} style={{ textTransform: 'capitalize', alignSelf: 'flex-start' }}>
|
|
323
|
-
|
|
341
|
+
{t('PASSWORD', 'Password')}
|
|
324
342
|
</OText>
|
|
325
343
|
<OInput
|
|
326
344
|
name='password'
|
|
@@ -347,9 +365,37 @@ export const UserFormDetailsUI = (props: any) => {
|
|
|
347
365
|
</>
|
|
348
366
|
)}
|
|
349
367
|
name='password'
|
|
350
|
-
rules={getInputRules({name: 'password', code: 'password'})}
|
|
368
|
+
rules={getInputRules({ name: 'password', code: 'password' })}
|
|
351
369
|
defaultValue=''
|
|
352
370
|
/>
|
|
371
|
+
<View style={{ flexDirection: 'row', alignItems: 'center', marginBottom: 20, width: '100%' }}>
|
|
372
|
+
<Controller
|
|
373
|
+
control={control}
|
|
374
|
+
render={({ onChange, value }: any) => (
|
|
375
|
+
<CheckBox
|
|
376
|
+
value={value}
|
|
377
|
+
onValueChange={newValue => {
|
|
378
|
+
onChange(newValue)
|
|
379
|
+
handleChangePromotions(newValue)
|
|
380
|
+
}}
|
|
381
|
+
boxType={'square'}
|
|
382
|
+
tintColors={{
|
|
383
|
+
true: theme.colors.primary,
|
|
384
|
+
false: theme.colors.disabled
|
|
385
|
+
}}
|
|
386
|
+
tintColor={theme.colors.disabled}
|
|
387
|
+
onCheckColor={theme.colors.primary}
|
|
388
|
+
onTintColor={theme.colors.primary}
|
|
389
|
+
style={Platform.OS === 'ios' && styles.checkBoxStyle}
|
|
390
|
+
/>
|
|
391
|
+
)}
|
|
392
|
+
name='promotions'
|
|
393
|
+
defaultValue={formState?.result?.result
|
|
394
|
+
? !!formState?.result?.result?.settings?.notification?.newsletter
|
|
395
|
+
: !!(formState?.changes?.settings?.notification?.newsletter ?? (user && user?.settings?.notification?.newsletter))}
|
|
396
|
+
/>
|
|
397
|
+
<OText style={{ fontSize: 14, paddingHorizontal: 5 }}>{t('RECEIVE_NEWS_EXCLUSIVE_PROMOTIONS', 'Receive newsletters and exclusive promotions')}</OText>
|
|
398
|
+
</View>
|
|
353
399
|
</UDWrapper>
|
|
354
400
|
)}
|
|
355
401
|
{validationFields?.loading && (
|
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
useLanguage,
|
|
6
6
|
ToastType,
|
|
7
7
|
useToast,
|
|
8
|
-
|
|
8
|
+
useConfig
|
|
9
9
|
} from 'ordering-components/native';
|
|
10
10
|
import { useTheme } from 'styled-components/native';
|
|
11
11
|
import { useForm } from 'react-hook-form';
|
|
@@ -15,10 +15,11 @@ import { KeyboardAvoidingView, Platform, StyleSheet, View } from 'react-native';
|
|
|
15
15
|
import { ProfileParams } from '../../types';
|
|
16
16
|
import { UserFormDetailsUI } from '../UserFormDetails';
|
|
17
17
|
|
|
18
|
-
import { OIcon, OIconButton } from '../shared';
|
|
18
|
+
import { OIcon, OIconButton, OModal } from '../shared';
|
|
19
19
|
import { CenterView } from './styles';
|
|
20
20
|
import NavBar from '../NavBar';
|
|
21
21
|
import { Container } from '../../layouts/Container';
|
|
22
|
+
import { VerifyPhone } from '../VerifyPhone'
|
|
22
23
|
|
|
23
24
|
const ProfileUI = (props: ProfileParams) => {
|
|
24
25
|
const {
|
|
@@ -32,6 +33,12 @@ const ProfileUI = (props: ProfileParams) => {
|
|
|
32
33
|
cleanFormState,
|
|
33
34
|
handleChangeInput,
|
|
34
35
|
handleButtonUpdateClick,
|
|
36
|
+
checkPhoneCodeState,
|
|
37
|
+
handleSendVerifyCode,
|
|
38
|
+
handleCheckPhoneCode,
|
|
39
|
+
verifyPhoneState,
|
|
40
|
+
isVerifiedPhone,
|
|
41
|
+
setCheckPhoneCodeState
|
|
35
42
|
} = props;
|
|
36
43
|
|
|
37
44
|
const theme = useTheme();
|
|
@@ -61,6 +68,8 @@ const ProfileUI = (props: ProfileParams) => {
|
|
|
61
68
|
const [, t] = useLanguage();
|
|
62
69
|
const [, { showToast }] = useToast();
|
|
63
70
|
const { handleSubmit, errors, setValue, control } = useForm();
|
|
71
|
+
const [isModalVisible, setIsModalVisible] = useState(false);
|
|
72
|
+
const [willVerifyOtpState, setWillVerifyOtpState] = useState(false);
|
|
64
73
|
|
|
65
74
|
const [phoneInputData, setPhoneInputData] = useState({
|
|
66
75
|
error: '',
|
|
@@ -79,8 +88,8 @@ const ProfileUI = (props: ProfileParams) => {
|
|
|
79
88
|
if (
|
|
80
89
|
formState.changes.cellphone === '' &&
|
|
81
90
|
((validationFields?.fields?.checkout?.cellphone?.enabled &&
|
|
82
|
-
|
|
83
|
-
|
|
91
|
+
validationFields?.fields?.checkout?.cellphone?.required) ||
|
|
92
|
+
configs?.verification_phone_required?.value === '1')
|
|
84
93
|
) {
|
|
85
94
|
showToast(
|
|
86
95
|
ToastType.Error,
|
|
@@ -182,6 +191,24 @@ const ProfileUI = (props: ProfileParams) => {
|
|
|
182
191
|
return rules;
|
|
183
192
|
};
|
|
184
193
|
|
|
194
|
+
const handleVerifyCodeClick = () => {
|
|
195
|
+
if (formState?.changes?.cellphone && formState?.changes?.country_phone_code) {
|
|
196
|
+
const { cellphone, country_phone_code: countryPhoneCode } = formState?.changes
|
|
197
|
+
|
|
198
|
+
setPhoneInputData({
|
|
199
|
+
error: '',
|
|
200
|
+
phone: {
|
|
201
|
+
country_phone_code: countryPhoneCode,
|
|
202
|
+
cellphone: cellphone,
|
|
203
|
+
},
|
|
204
|
+
});
|
|
205
|
+
handleSendVerifyCode({
|
|
206
|
+
cellphone: cellphone,
|
|
207
|
+
country_phone_code: countryPhoneCode
|
|
208
|
+
})
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
|
|
185
212
|
useEffect(() => {
|
|
186
213
|
if (formState.result.result && !formState.loading) {
|
|
187
214
|
if (formState.result?.error) {
|
|
@@ -216,44 +243,95 @@ const ProfileUI = (props: ProfileParams) => {
|
|
|
216
243
|
}
|
|
217
244
|
}, [user?.country_phone_code]);
|
|
218
245
|
|
|
246
|
+
useEffect(() => {
|
|
247
|
+
if (willVerifyOtpState) handleVerifyCodeClick()
|
|
248
|
+
}, [willVerifyOtpState])
|
|
249
|
+
|
|
250
|
+
useEffect(() => {
|
|
251
|
+
if (verifyPhoneState && !verifyPhoneState?.loading) {
|
|
252
|
+
if (verifyPhoneState.result?.error) {
|
|
253
|
+
const message = typeof verifyPhoneState?.result?.result === 'string'
|
|
254
|
+
? verifyPhoneState?.result?.result
|
|
255
|
+
: verifyPhoneState?.result?.result[0]
|
|
256
|
+
verifyPhoneState.result?.result && showToast(
|
|
257
|
+
ToastType.Error,
|
|
258
|
+
message
|
|
259
|
+
)
|
|
260
|
+
setWillVerifyOtpState(false)
|
|
261
|
+
return
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
const okResult = verifyPhoneState.result?.result === 'OK'
|
|
265
|
+
if (okResult) {
|
|
266
|
+
!isModalVisible && setIsModalVisible(true)
|
|
267
|
+
setWillVerifyOtpState(false)
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
}, [verifyPhoneState])
|
|
271
|
+
|
|
272
|
+
useEffect(() => {
|
|
273
|
+
if (isVerifiedPhone) setIsModalVisible(false)
|
|
274
|
+
}, [isVerifiedPhone])
|
|
275
|
+
|
|
219
276
|
return (
|
|
220
|
-
|
|
221
|
-
<
|
|
222
|
-
<
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
<
|
|
231
|
-
<
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
277
|
+
<>
|
|
278
|
+
<KeyboardAvoidingView behavior={Platform.OS == 'ios' ? 'padding' : 'height'} enabled style={{ flex: 1, flexDirection: 'column', justifyContent: 'center' }}>
|
|
279
|
+
<Container noPadding>
|
|
280
|
+
<NavBar
|
|
281
|
+
onActionLeft={() => navigation.goBack()}
|
|
282
|
+
btnStyle={{ paddingStart: 0 }}
|
|
283
|
+
title={t('ACCOUNT', 'Account')}
|
|
284
|
+
isVertical
|
|
285
|
+
style={styles.navBarStyle}
|
|
286
|
+
/>
|
|
287
|
+
<CenterView style={styles.pagePadding}>
|
|
288
|
+
<View style={styles.photo}>
|
|
289
|
+
<OIcon
|
|
290
|
+
url={user?.photo}
|
|
291
|
+
src={!user?.photo && theme.images.general.user}
|
|
292
|
+
width={79}
|
|
293
|
+
height={79}
|
|
294
|
+
/>
|
|
295
|
+
</View>
|
|
296
|
+
<OIconButton
|
|
297
|
+
icon={theme.images.general.camera}
|
|
298
|
+
borderColor={theme.colors.clear}
|
|
299
|
+
iconStyle={{ width: 16, height: 16 }}
|
|
300
|
+
style={{ maxWidth: 40, position: 'absolute', bottom: -2, alignSelf: 'center' }}
|
|
301
|
+
onClick={() => handleImagePicker()}
|
|
302
|
+
/>
|
|
303
|
+
</CenterView>
|
|
304
|
+
<View style={{ height: 8, marginLeft: -40, marginRight: -40, backgroundColor: theme.colors.backgroundGray100, marginVertical: 32, zIndex: 10 }} />
|
|
305
|
+
<Spinner visible={formState?.loading || verifyPhoneState?.loading} />
|
|
306
|
+
<View style={styles.pagePadding}>
|
|
307
|
+
<UserFormDetailsUI
|
|
308
|
+
{...props}
|
|
309
|
+
isEdit
|
|
310
|
+
setWillVerifyOtpState={setWillVerifyOtpState}
|
|
236
311
|
/>
|
|
237
312
|
</View>
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
313
|
+
</Container>
|
|
314
|
+
</KeyboardAvoidingView>
|
|
315
|
+
<OModal
|
|
316
|
+
open={isModalVisible}
|
|
317
|
+
onClose={() => setIsModalVisible(false)}
|
|
318
|
+
entireModal
|
|
319
|
+
>
|
|
320
|
+
<VerifyPhone
|
|
321
|
+
phone={phoneInputData.phone}
|
|
322
|
+
verifyPhoneState={verifyPhoneState}
|
|
323
|
+
checkPhoneCodeState={checkPhoneCodeState}
|
|
324
|
+
handleCheckPhoneCode={handleCheckPhoneCode}
|
|
325
|
+
setCheckPhoneCodeState={setCheckPhoneCodeState}
|
|
326
|
+
handleVerifyCodeClick={handleVerifyCodeClick}
|
|
327
|
+
onClose={() => setIsModalVisible(false)}
|
|
328
|
+
/>
|
|
329
|
+
</OModal>
|
|
330
|
+
</>
|
|
331
|
+
|
|
253
332
|
);
|
|
254
333
|
};
|
|
255
334
|
|
|
256
|
-
|
|
257
335
|
export const UserProfileForm = (props: any) => {
|
|
258
336
|
const profileProps = {
|
|
259
337
|
...props,
|
|
@@ -37,8 +37,8 @@ export const VerifyPhone = (props: any) => {
|
|
|
37
37
|
height: 75,
|
|
38
38
|
marginBottom: 25,
|
|
39
39
|
borderWidth: 1,
|
|
40
|
-
borderColor: theme.colors.
|
|
41
|
-
borderRadius:
|
|
40
|
+
borderColor: theme.colors.inputBorderColor,
|
|
41
|
+
borderRadius: 8,
|
|
42
42
|
textAlign: 'center',
|
|
43
43
|
fontSize: 40
|
|
44
44
|
}
|
|
@@ -131,11 +131,11 @@ export const VerifyPhone = (props: any) => {
|
|
|
131
131
|
|
|
132
132
|
return (
|
|
133
133
|
<Container>
|
|
134
|
-
<OText size={
|
|
135
|
-
{t('
|
|
134
|
+
<OText size={26} style={{ textAlign: 'left', fontWeight: '600', marginTop: 10, marginBottom: 30 }}>
|
|
135
|
+
{t('ENTER_VERIFICATION_CODE', 'Enter verification code')}
|
|
136
136
|
</OText>
|
|
137
137
|
{lastNumbers && (
|
|
138
|
-
<OText size={
|
|
138
|
+
<OText size={16} color={theme.colors.disabled}>
|
|
139
139
|
{`${t('MESSAGE_ENTER_VERIFY_CODE', 'Please, enter the verification code we sent to your mobile ending with')} **${lastNumbers}`}
|
|
140
140
|
</OText>
|
|
141
141
|
)}
|
|
@@ -174,7 +174,7 @@ export const VerifyPhone = (props: any) => {
|
|
|
174
174
|
).result?.result)?.map((e: any, i: number) => (
|
|
175
175
|
<OText
|
|
176
176
|
key={i}
|
|
177
|
-
size={
|
|
177
|
+
size={16}
|
|
178
178
|
color={theme.colors.error}
|
|
179
179
|
>
|
|
180
180
|
{`* ${t(getTraduction(e))}`}
|
|
@@ -183,12 +183,9 @@ export const VerifyPhone = (props: any) => {
|
|
|
183
183
|
</ErrorSection>
|
|
184
184
|
)}
|
|
185
185
|
<ResendSection>
|
|
186
|
-
<OText size={16} style={{ marginRight: 5 }}>
|
|
187
|
-
{t('ARE_YOU_NOT_SEEING_THE_CODE', 'Are you not seeing the code?')}
|
|
188
|
-
</OText>
|
|
189
186
|
<Pressable onPress={() => handleSendCodeAgain()}>
|
|
190
187
|
<OText size={16} color={theme.colors.primary}>
|
|
191
|
-
{t('
|
|
188
|
+
{t('RESEND_CODE', 'Resend code')}
|
|
192
189
|
</OText>
|
|
193
190
|
</Pressable>
|
|
194
191
|
</ResendSection>
|
|
@@ -19,13 +19,12 @@ export const CountDownContainer = styled.View`
|
|
|
19
19
|
export const ResendSection = styled.View`
|
|
20
20
|
display: flex;
|
|
21
21
|
flex-direction: row;
|
|
22
|
-
justify-content: center;
|
|
23
22
|
margin-bottom: 30px;
|
|
24
23
|
`
|
|
25
24
|
|
|
26
25
|
export const WrappCountdown = styled.View`
|
|
27
26
|
padding-top: 20px;
|
|
28
|
-
padding-bottom:
|
|
27
|
+
padding-bottom: 50px;
|
|
29
28
|
`
|
|
30
29
|
|
|
31
30
|
export const InputsSection = styled.View`
|
|
@@ -31,6 +31,12 @@ export interface ProfileParams {
|
|
|
31
31
|
validationFields?: any;
|
|
32
32
|
showField?: any;
|
|
33
33
|
isRequiredField?: any;
|
|
34
|
+
handleSendVerifyCode?: any;
|
|
35
|
+
handleCheckPhoneCode?: any;
|
|
36
|
+
checkPhoneCodeState?: any;
|
|
37
|
+
verifyPhoneState?: any;
|
|
38
|
+
setCheckPhoneCodeState?: any;
|
|
39
|
+
isVerifiedPhone?: any;
|
|
34
40
|
}
|
|
35
41
|
|
|
36
42
|
export interface AddressListParams {
|
|
@@ -93,6 +99,7 @@ export interface SignupParams {
|
|
|
93
99
|
handleSendVerifyCode?: any;
|
|
94
100
|
handleCheckPhoneCode?: any;
|
|
95
101
|
notificationState?: any;
|
|
102
|
+
handleChangePromotions: () => void;
|
|
96
103
|
}
|
|
97
104
|
|
|
98
105
|
export interface PhoneInputParams {
|