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 +1 -1
- package/themes/business/index.tsx +4 -0
- package/themes/business/src/components/DriverSchedule/index.tsx +54 -0
- package/themes/business/src/components/DriverSchedule/styles.tsx +6 -0
- package/themes/business/src/components/ScheduleBlocked/index.tsx +53 -0
- package/themes/business/src/components/UserProfileForm/index.tsx +26 -4
- package/themes/business/src/components/shared/OModal.tsx +40 -37
- package/themes/original/src/components/Checkout/index.tsx +37 -3
- package/themes/original/src/components/UserDetails/index.tsx +31 -17
- package/themes/original/src/components/UserFormDetails/index.tsx +107 -72
- package/themes/original/src/components/UserProfileForm/index.tsx +14 -9
package/package.json
CHANGED
|
@@ -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,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
|
-
|
|
223
|
-
<View style={styles.shadow}>
|
|
224
|
-
{order?.business?.logo ? (
|
|
242
|
+
<View style={styles.shadow}>
|
|
225
243
|
<OIcon
|
|
226
244
|
url={optimizeImage(
|
|
227
|
-
order?.
|
|
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
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
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 &&
|
|
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
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
{
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
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
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
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
|
-
|
|
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
|
-
|
|
276
|
-
|
|
277
|
-
|
|
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={
|
|
335
|
-
setCheckPhoneCodeState={setCheckPhoneCodeState}
|
|
340
|
+
handleCheckPhoneCode={handleSendPhoneCode}
|
|
336
341
|
handleVerifyCodeClick={handleVerifyCodeClick}
|
|
337
342
|
onClose={() => setIsModalVisible(false)}
|
|
338
343
|
/>
|