ordering-ui-react-native 0.15.49 → 0.15.50
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 +2 -1
- package/themes/original/src/components/LoginForm/index.tsx +73 -2
- package/themes/original/src/components/LoginForm/styles.tsx +6 -1
- package/themes/original/src/components/Promotions/index.tsx +232 -0
- package/themes/original/src/components/Promotions/styles.tsx +80 -0
- package/themes/original/src/components/UserProfile/index.tsx +8 -1
- package/themes/original/src/types/index.tsx +11 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ordering-ui-react-native",
|
|
3
|
-
"version": "0.15.
|
|
3
|
+
"version": "0.15.50",
|
|
4
4
|
"description": "Reusable components made in react native",
|
|
5
5
|
"main": "src/index.tsx",
|
|
6
6
|
"author": "ordering.inc",
|
|
@@ -99,6 +99,7 @@
|
|
|
99
99
|
"react-native-picker-select": "^8.0.4",
|
|
100
100
|
"react-native-print": "^0.9.0",
|
|
101
101
|
"react-native-reanimated": "^1.13.1",
|
|
102
|
+
"react-native-recaptcha-that-works": "^1.2.0",
|
|
102
103
|
"react-native-restart": "^0.0.22",
|
|
103
104
|
"react-native-safe-area-context": "^3.1.8",
|
|
104
105
|
"react-native-screens": "^2.11.0",
|
|
@@ -4,6 +4,7 @@ import Spinner from 'react-native-loading-spinner-overlay';
|
|
|
4
4
|
import { useForm, Controller } from 'react-hook-form';
|
|
5
5
|
import { PhoneInputNumber } from '../PhoneInputNumber';
|
|
6
6
|
import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons';
|
|
7
|
+
import Recaptcha from 'react-native-recaptcha-that-works'
|
|
7
8
|
|
|
8
9
|
import {
|
|
9
10
|
LoginForm as LoginFormController,
|
|
@@ -18,7 +19,6 @@ import { FacebookLogin } from '../FacebookLogin';
|
|
|
18
19
|
import { VerifyPhone } from '../../../../../src/components/VerifyPhone';
|
|
19
20
|
import { OModal } from '../../../../../src/components/shared';
|
|
20
21
|
|
|
21
|
-
|
|
22
22
|
import {
|
|
23
23
|
Container,
|
|
24
24
|
ButtonsWrapper,
|
|
@@ -32,6 +32,7 @@ import {
|
|
|
32
32
|
LineSeparator,
|
|
33
33
|
SkeletonWrapper,
|
|
34
34
|
TabBtn,
|
|
35
|
+
RecaptchaButton
|
|
35
36
|
} from './styles';
|
|
36
37
|
|
|
37
38
|
import NavBar from '../NavBar';
|
|
@@ -60,7 +61,9 @@ const LoginFormUI = (props: LoginParams) => {
|
|
|
60
61
|
handleSendVerifyCode,
|
|
61
62
|
handleCheckPhoneCode,
|
|
62
63
|
onNavigationRedirect,
|
|
63
|
-
notificationState
|
|
64
|
+
notificationState,
|
|
65
|
+
handleReCaptcha,
|
|
66
|
+
enableReCaptcha
|
|
64
67
|
} = props;
|
|
65
68
|
|
|
66
69
|
const [, { showToast }] = useToast();
|
|
@@ -79,6 +82,8 @@ const LoginFormUI = (props: LoginParams) => {
|
|
|
79
82
|
cellphone: null,
|
|
80
83
|
},
|
|
81
84
|
});
|
|
85
|
+
const [recaptchaConfig, setRecaptchaConfig] = useState<any>({})
|
|
86
|
+
const [recaptchaVerified, setRecaptchaVerified] = useState(false)
|
|
82
87
|
|
|
83
88
|
const theme = useTheme();
|
|
84
89
|
|
|
@@ -100,10 +105,15 @@ const LoginFormUI = (props: LoginParams) => {
|
|
|
100
105
|
flexGrow: 1,
|
|
101
106
|
marginBottom: 7,
|
|
102
107
|
},
|
|
108
|
+
recaptchaIcon: {
|
|
109
|
+
width: 100,
|
|
110
|
+
height: 100,
|
|
111
|
+
}
|
|
103
112
|
});
|
|
104
113
|
|
|
105
114
|
const emailRef = useRef<any>({});
|
|
106
115
|
const passwordRef = useRef<any>({});
|
|
116
|
+
const recaptchaRef = useRef<any>({});
|
|
107
117
|
|
|
108
118
|
const handleChangeTab = (val: string) => {
|
|
109
119
|
props.handleChangeTab(val);
|
|
@@ -156,6 +166,33 @@ const LoginFormUI = (props: LoginParams) => {
|
|
|
156
166
|
onChange(value.toLowerCase().replace(/[&,()%";:ç?<>{}\\[\]\s]/g, ''));
|
|
157
167
|
};
|
|
158
168
|
|
|
169
|
+
const handleOpenRecaptcha = () => {
|
|
170
|
+
setRecaptchaVerified(false)
|
|
171
|
+
if (!recaptchaConfig?.siteKey) {
|
|
172
|
+
showToast(ToastType.Error, t('NO_RECAPTCHA_SITE_KEY', 'The config doesn\'t have recaptcha site key'));
|
|
173
|
+
return
|
|
174
|
+
}
|
|
175
|
+
if (!recaptchaConfig?.baseUrl) {
|
|
176
|
+
showToast(ToastType.Error, t('NO_RECAPTCHA_BASE_URL', 'The config doesn\'t have recaptcha base url'));
|
|
177
|
+
return
|
|
178
|
+
}
|
|
179
|
+
recaptchaRef.current.open()
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
const onRecaptchaVerify = (token: any) => {
|
|
183
|
+
setRecaptchaVerified(true)
|
|
184
|
+
handleReCaptcha(token)
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
useEffect(() => {
|
|
188
|
+
if (configs && Object.keys(configs).length > 0 && enableReCaptcha) {
|
|
189
|
+
setRecaptchaConfig({
|
|
190
|
+
siteKey: configs?.security_recaptcha_site_key?.value || null,
|
|
191
|
+
baseUrl: configs?.security_recaptcha_base_url?.value || null
|
|
192
|
+
})
|
|
193
|
+
}
|
|
194
|
+
}, [configs, enableReCaptcha])
|
|
195
|
+
|
|
159
196
|
useEffect(() => {
|
|
160
197
|
if (!formState.loading && formState.result?.error) {
|
|
161
198
|
formState.result?.result &&
|
|
@@ -399,6 +436,39 @@ const LoginFormUI = (props: LoginParams) => {
|
|
|
399
436
|
</OText>
|
|
400
437
|
</TouchableOpacity>
|
|
401
438
|
)}
|
|
439
|
+
|
|
440
|
+
{enableReCaptcha && (
|
|
441
|
+
<>
|
|
442
|
+
<TouchableOpacity
|
|
443
|
+
onPress={handleOpenRecaptcha}
|
|
444
|
+
>
|
|
445
|
+
<RecaptchaButton>
|
|
446
|
+
{recaptchaVerified ? (
|
|
447
|
+
<MaterialCommunityIcons
|
|
448
|
+
name="checkbox-marked"
|
|
449
|
+
size={26}
|
|
450
|
+
color={theme.colors.primary}
|
|
451
|
+
/>
|
|
452
|
+
) : (
|
|
453
|
+
<MaterialCommunityIcons
|
|
454
|
+
name="checkbox-blank-outline"
|
|
455
|
+
size={26}
|
|
456
|
+
color={theme.colors.mediumGray}
|
|
457
|
+
/>
|
|
458
|
+
)}
|
|
459
|
+
<OText size={14} mLeft={8}>{t('VERIFY_ReCAPTCHA', 'Verify reCAPTCHA')}</OText>
|
|
460
|
+
</RecaptchaButton>
|
|
461
|
+
</TouchableOpacity>
|
|
462
|
+
<Recaptcha
|
|
463
|
+
ref={recaptchaRef}
|
|
464
|
+
siteKey={recaptchaConfig?.siteKey}
|
|
465
|
+
baseUrl={recaptchaConfig?.baseUrl}
|
|
466
|
+
onVerify={onRecaptchaVerify}
|
|
467
|
+
onExpire={() => setRecaptchaVerified(false)}
|
|
468
|
+
/>
|
|
469
|
+
</>
|
|
470
|
+
)}
|
|
471
|
+
|
|
402
472
|
<OButton
|
|
403
473
|
onClick={handleSubmit(onSubmit)}
|
|
404
474
|
text={loginButtonText}
|
|
@@ -559,6 +629,7 @@ const LoginFormUI = (props: LoginParams) => {
|
|
|
559
629
|
export const LoginForm = (props: any) => {
|
|
560
630
|
const loginProps = {
|
|
561
631
|
...props,
|
|
632
|
+
isRecaptchaEnable: true,
|
|
562
633
|
UIComponent: LoginFormUI,
|
|
563
634
|
};
|
|
564
635
|
return <LoginFormController {...loginProps} />;
|
|
@@ -36,7 +36,7 @@ export const LoginWith = styled.View`
|
|
|
36
36
|
width: 100%;
|
|
37
37
|
align-items: flex-start;
|
|
38
38
|
border-bottom-width: 1px;
|
|
39
|
-
border-bottom-color: ${(props: any) => props.theme.colors.border}
|
|
39
|
+
border-bottom-color: ${(props: any) => props.theme.colors.border};
|
|
40
40
|
`;
|
|
41
41
|
|
|
42
42
|
export const FormInput = styled.View`
|
|
@@ -80,3 +80,8 @@ export const LineSeparator = styled.View`
|
|
|
80
80
|
export const SkeletonWrapper = styled.View`
|
|
81
81
|
width: 90%;
|
|
82
82
|
`
|
|
83
|
+
export const RecaptchaButton = styled.View`
|
|
84
|
+
flex-direction: row;
|
|
85
|
+
align-items: center;
|
|
86
|
+
margin-bottom: 10px;
|
|
87
|
+
`
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
import React, { useState } from 'react'
|
|
2
|
+
import { PromotionsController, useLanguage, useUtils, useEvent } from 'ordering-components/native'
|
|
3
|
+
import {
|
|
4
|
+
PromotionsContainer,
|
|
5
|
+
SingleOfferContainer,
|
|
6
|
+
OfferInformation,
|
|
7
|
+
SearchBarContainer,
|
|
8
|
+
SingleBusinessOffer,
|
|
9
|
+
AvailableBusinesses,
|
|
10
|
+
OfferData,
|
|
11
|
+
Code,
|
|
12
|
+
BusinessInfo
|
|
13
|
+
} from './styles'
|
|
14
|
+
import { SearchBar } from '../SearchBar'
|
|
15
|
+
import NavBar from '../NavBar'
|
|
16
|
+
import { useTheme } from 'styled-components/native';
|
|
17
|
+
import { OButton, OIcon, OModal, OText } from '../shared'
|
|
18
|
+
import { Placeholder, PlaceholderLine } from 'rn-placeholder'
|
|
19
|
+
import { NotFoundSource } from '../NotFoundSource'
|
|
20
|
+
import { View, StyleSheet, ScrollView } from 'react-native'
|
|
21
|
+
import FastImage from 'react-native-fast-image'
|
|
22
|
+
import { PromotionParams } from '../../types'
|
|
23
|
+
const PromotionsUI = (props : PromotionParams) => {
|
|
24
|
+
const {
|
|
25
|
+
navigation,
|
|
26
|
+
offersState,
|
|
27
|
+
handleSearchValue,
|
|
28
|
+
searchValue,
|
|
29
|
+
offerSelected,
|
|
30
|
+
setOfferSelected
|
|
31
|
+
} = props
|
|
32
|
+
|
|
33
|
+
const theme = useTheme();
|
|
34
|
+
|
|
35
|
+
const styles = StyleSheet.create({
|
|
36
|
+
productStyle: {
|
|
37
|
+
width: 75,
|
|
38
|
+
height: 75,
|
|
39
|
+
borderRadius: 7.6
|
|
40
|
+
},
|
|
41
|
+
buttonStyle: {
|
|
42
|
+
width: 55,
|
|
43
|
+
height: 25,
|
|
44
|
+
paddingLeft: 0,
|
|
45
|
+
paddingRight: 0
|
|
46
|
+
},
|
|
47
|
+
offerTitle: {
|
|
48
|
+
fontSize: 12
|
|
49
|
+
},
|
|
50
|
+
offerDescription: {
|
|
51
|
+
color: '#909BA9',
|
|
52
|
+
fontSize: 10
|
|
53
|
+
},
|
|
54
|
+
offerExtraInfo: {
|
|
55
|
+
fontSize: 10
|
|
56
|
+
},
|
|
57
|
+
modalButtonStyle: {
|
|
58
|
+
width: 100,
|
|
59
|
+
height: 35,
|
|
60
|
+
paddingLeft: 0,
|
|
61
|
+
paddingRight: 0,
|
|
62
|
+
borderRadius: 7.6
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
const [, t] = useLanguage()
|
|
67
|
+
const [{ parseDate, parsePrice, optimizeImage }] = useUtils()
|
|
68
|
+
const [events] = useEvent()
|
|
69
|
+
const [openModal, setOpenModal] = useState(false)
|
|
70
|
+
|
|
71
|
+
const handleClickOffer = (offer : any) => {
|
|
72
|
+
setOpenModal(true)
|
|
73
|
+
setOfferSelected(offer)
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const handleBusinessClick = (business : any) => {
|
|
77
|
+
events.emit('go_to_page', { page: 'business', params: { store: business.slug } })
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
const filteredOffers = offersState?.offers?.filter((offer : any) => offer.name.toLowerCase().includes(searchValue.toLowerCase()))
|
|
81
|
+
|
|
82
|
+
const targetString = offerSelected?.target === 1
|
|
83
|
+
? t('SUBTOTAL', 'Subtotal')
|
|
84
|
+
: offerSelected?.target === 2
|
|
85
|
+
? t('DELIVERY_FEE', 'Delivery fee')
|
|
86
|
+
: t('SERVICE_FEE', 'Service fee')
|
|
87
|
+
|
|
88
|
+
return (
|
|
89
|
+
<PromotionsContainer>
|
|
90
|
+
<NavBar
|
|
91
|
+
onActionLeft={() => navigation.goBack()}
|
|
92
|
+
btnStyle={{ paddingLeft: 0 }}
|
|
93
|
+
paddingTop={20}
|
|
94
|
+
style={{ paddingBottom: 0, flexDirection: 'column', alignItems: 'flex-start' }}
|
|
95
|
+
title={t('PROMOTIONS', 'Promotions')}
|
|
96
|
+
titleAlign={'center'}
|
|
97
|
+
titleStyle={{ fontSize: 16, marginRight: 0, marginLeft: 0, marginBottom: 10 }}
|
|
98
|
+
titleWrapStyle={{ paddingHorizontal: 0 }}
|
|
99
|
+
/>
|
|
100
|
+
<SearchBarContainer>
|
|
101
|
+
<SearchBar
|
|
102
|
+
placeholder={t('SEARCH_OFFERS', 'Search offers')}
|
|
103
|
+
onSearch={handleSearchValue}
|
|
104
|
+
/>
|
|
105
|
+
</SearchBarContainer>
|
|
106
|
+
|
|
107
|
+
{offersState?.loading && (
|
|
108
|
+
<>
|
|
109
|
+
{[...Array(5).keys()].map((key, i) => (
|
|
110
|
+
<Placeholder key={i} style={{ flexDirection: 'row', marginBottom: 20 }}>
|
|
111
|
+
<PlaceholderLine height={10} width={45} />
|
|
112
|
+
<PlaceholderLine height={10} width={60} />
|
|
113
|
+
<PlaceholderLine height={10} width={75} />
|
|
114
|
+
</Placeholder>
|
|
115
|
+
))}
|
|
116
|
+
</>
|
|
117
|
+
)}
|
|
118
|
+
{((!offersState?.loading && filteredOffers?.length === 0) || offersState?.error) && (
|
|
119
|
+
<NotFoundSource
|
|
120
|
+
content={offersState?.error || t('NOT_FOUND_OFFERS', 'Not found offers')}
|
|
121
|
+
/>
|
|
122
|
+
)}
|
|
123
|
+
<ScrollView>
|
|
124
|
+
{!offersState?.loading && offersState.offers?.length > 0 && filteredOffers?.map((offer : any) => (
|
|
125
|
+
<SingleOfferContainer key={offer.id}>
|
|
126
|
+
<OfferInformation>
|
|
127
|
+
<OText style={styles.offerTitle}>{offer?.name}</OText>
|
|
128
|
+
{offer?.description && (
|
|
129
|
+
<OText style={styles.offerDescription}>{offer?.description}</OText>
|
|
130
|
+
)}
|
|
131
|
+
<OText style={styles.offerExtraInfo}>
|
|
132
|
+
{t('EXPIRES', 'Expires')} {parseDate(offer?.end, { outputFormat: 'MMM DD, YYYY' })}
|
|
133
|
+
</OText>
|
|
134
|
+
<AvailableBusinesses>
|
|
135
|
+
<OText style={styles.offerExtraInfo}>{t('APPLY_FOR', 'Apply for')}:</OText>
|
|
136
|
+
{offer.businesses.map((business: any, i: number) => (
|
|
137
|
+
<OText style={styles.offerExtraInfo} key={business?.id}>{' '}{business?.name}{i + 1 < offer.businesses?.length ? ',' : ''}</OText>
|
|
138
|
+
))}
|
|
139
|
+
</AvailableBusinesses>
|
|
140
|
+
</OfferInformation>
|
|
141
|
+
<OButton
|
|
142
|
+
onClick={() => handleClickOffer(offer)}
|
|
143
|
+
text={t('VIEW', 'View')}
|
|
144
|
+
style={styles.buttonStyle}
|
|
145
|
+
textStyle={{ fontSize: 10, color: '#fff', flexWrap: 'nowrap' }}
|
|
146
|
+
/>
|
|
147
|
+
</SingleOfferContainer>
|
|
148
|
+
))}
|
|
149
|
+
</ScrollView>
|
|
150
|
+
<OModal
|
|
151
|
+
open={openModal}
|
|
152
|
+
onClose={() => setOpenModal(false)}
|
|
153
|
+
entireModal
|
|
154
|
+
|
|
155
|
+
title={``}
|
|
156
|
+
>
|
|
157
|
+
<View style={{ padding: 20 }}>
|
|
158
|
+
<OText style={{ alignSelf: 'center', fontWeight: '700' }} mBottom={20}>
|
|
159
|
+
{offerSelected?.name} / {t('VALUE_OF_OFFER', 'Value of offer')}: {offerSelected?.rate_type === 1 ? `${offerSelected?.rate}%` : `${parsePrice(offerSelected?.rate)}`}
|
|
160
|
+
</OText>
|
|
161
|
+
<OfferData>
|
|
162
|
+
{offerSelected?.type === 2 && (
|
|
163
|
+
<Code>
|
|
164
|
+
<OText>{t('YOUR_CODE', 'Your code')}</OText>
|
|
165
|
+
<OText color={theme.colors.primary}>{offerSelected.coupon}</OText>
|
|
166
|
+
</Code>
|
|
167
|
+
)}
|
|
168
|
+
<OText>{t('APPLIES_TO', 'Applies to')}: {targetString}</OText>
|
|
169
|
+
{offerSelected?.auto && (
|
|
170
|
+
<OText>{t('OFFER_AUTOMATIC', 'This offer applies automatic')}</OText>
|
|
171
|
+
)}
|
|
172
|
+
{offerSelected?.minimum && (
|
|
173
|
+
<OText>{t('MINIMUM_PURCHASE_FOR_OFFER', 'Minimum purshase for use this offer')}: {parsePrice(offerSelected?.minimum)}</OText>
|
|
174
|
+
)}
|
|
175
|
+
{offerSelected?.max_discount && (
|
|
176
|
+
<OText>{t('MAX_DISCOUNT_ALLOWED', 'Max discount allowed')}: {parsePrice(offerSelected?.max_discount)}</OText>
|
|
177
|
+
)}
|
|
178
|
+
{offerSelected?.description && (
|
|
179
|
+
<OText>{offerSelected?.description}</OText>
|
|
180
|
+
)}
|
|
181
|
+
</OfferData>
|
|
182
|
+
<OText style={{ marginTop: 10, marginBottom: 10 }}>
|
|
183
|
+
{t('AVAILABLE_BUSINESSES_FOR_OFFER', 'Available businesses for this offer')}:
|
|
184
|
+
</OText>
|
|
185
|
+
<ScrollView style={{height: '75%'}}>
|
|
186
|
+
{offerSelected?.businesses?.map((business : any) => {
|
|
187
|
+
return (
|
|
188
|
+
<SingleBusinessOffer key={business.id}>
|
|
189
|
+
{business?.logo ? (
|
|
190
|
+
<FastImage
|
|
191
|
+
style={styles.productStyle}
|
|
192
|
+
source={{
|
|
193
|
+
uri: optimizeImage(business?.logo, 'h_250,c_limit'),
|
|
194
|
+
priority: FastImage.priority.normal,
|
|
195
|
+
}}
|
|
196
|
+
resizeMode={FastImage.resizeMode.cover}
|
|
197
|
+
/>
|
|
198
|
+
) : (
|
|
199
|
+
<OIcon
|
|
200
|
+
src={theme?.images?.dummies?.product}
|
|
201
|
+
style={styles.productStyle}
|
|
202
|
+
/>
|
|
203
|
+
)}
|
|
204
|
+
<BusinessInfo>
|
|
205
|
+
<OText>{business.name}</OText>
|
|
206
|
+
<OButton
|
|
207
|
+
onClick={() => handleBusinessClick(business)}
|
|
208
|
+
text={t('GO_TO_BUSINESSS', 'Go to business')}
|
|
209
|
+
style={styles.modalButtonStyle}
|
|
210
|
+
textStyle={{ fontSize: 10, color: '#fff' }}
|
|
211
|
+
/>
|
|
212
|
+
</BusinessInfo>
|
|
213
|
+
</SingleBusinessOffer>
|
|
214
|
+
)
|
|
215
|
+
})}
|
|
216
|
+
</ScrollView>
|
|
217
|
+
</View>
|
|
218
|
+
</OModal>
|
|
219
|
+
</PromotionsContainer>
|
|
220
|
+
)
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
export const Promotions = (props : PromotionParams) => {
|
|
224
|
+
const PromotionsProps = {
|
|
225
|
+
...props,
|
|
226
|
+
UIComponent: PromotionsUI
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
return (
|
|
230
|
+
<PromotionsController {...PromotionsProps} />
|
|
231
|
+
)
|
|
232
|
+
}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import styled, { css } from 'styled-components/native'
|
|
2
|
+
|
|
3
|
+
export const PromotionsContainer = styled.View`
|
|
4
|
+
width: 100%;
|
|
5
|
+
`
|
|
6
|
+
|
|
7
|
+
export const SingleOfferContainer = styled.View`
|
|
8
|
+
flex-direction: row;
|
|
9
|
+
width: 100%;
|
|
10
|
+
height: 80px;
|
|
11
|
+
justify-content: space-between;
|
|
12
|
+
align-items: center;
|
|
13
|
+
margin-bottom: 20px;
|
|
14
|
+
|
|
15
|
+
`
|
|
16
|
+
|
|
17
|
+
export const OfferInformation = styled.View`
|
|
18
|
+
justify-content: space-between;
|
|
19
|
+
max-width: 75%;
|
|
20
|
+
`
|
|
21
|
+
|
|
22
|
+
export const SearchBarContainer = styled.View`
|
|
23
|
+
display: flex;
|
|
24
|
+
width: 100%;
|
|
25
|
+
justify-content: flex-start;
|
|
26
|
+
margin-bottom: 20px;
|
|
27
|
+
.search-bar {
|
|
28
|
+
justify-content: flex-start;
|
|
29
|
+
input {
|
|
30
|
+
width: 100%;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
.clear {
|
|
34
|
+
right: 0;
|
|
35
|
+
}
|
|
36
|
+
`
|
|
37
|
+
|
|
38
|
+
export const SingleBusinessOffer = styled.View`
|
|
39
|
+
flex-direction: row;
|
|
40
|
+
`
|
|
41
|
+
|
|
42
|
+
export const AvailableBusinesses = styled.View`
|
|
43
|
+
flex-direction: row;
|
|
44
|
+
overflow: hidden;
|
|
45
|
+
`
|
|
46
|
+
|
|
47
|
+
export const OfferData = styled.View`
|
|
48
|
+
display: flex;
|
|
49
|
+
align-items: center;
|
|
50
|
+
flex-direction: column;
|
|
51
|
+
p{
|
|
52
|
+
color: #909BA9;
|
|
53
|
+
margin: 3px;
|
|
54
|
+
font-size: 14px;
|
|
55
|
+
}
|
|
56
|
+
`
|
|
57
|
+
|
|
58
|
+
export const Code = styled.View`
|
|
59
|
+
display: flex;
|
|
60
|
+
flex-direction: column;
|
|
61
|
+
align-items: center;
|
|
62
|
+
margin-bottom: 10px;
|
|
63
|
+
`
|
|
64
|
+
|
|
65
|
+
export const ValueOfOffer = styled.View`
|
|
66
|
+
p{
|
|
67
|
+
font-size: 16px;
|
|
68
|
+
}
|
|
69
|
+
span{
|
|
70
|
+
font-size: 20px;
|
|
71
|
+
}
|
|
72
|
+
`
|
|
73
|
+
|
|
74
|
+
export const BusinessInfo = styled.View`
|
|
75
|
+
flex: 1;
|
|
76
|
+
flex-direction: row;
|
|
77
|
+
justify-content: space-between;
|
|
78
|
+
align-items: center;
|
|
79
|
+
margin-left: 10px;
|
|
80
|
+
`
|
|
@@ -16,6 +16,7 @@ import { LogoutButton } from '../LogoutButton'
|
|
|
16
16
|
import { LanguageSelector } from '../LanguageSelector'
|
|
17
17
|
import MessageCircle from 'react-native-vector-icons/AntDesign'
|
|
18
18
|
import Ionicons from 'react-native-vector-icons/Ionicons'
|
|
19
|
+
import MaterialIcons from 'react-native-vector-icons/MaterialIcons'
|
|
19
20
|
import FastImage from 'react-native-fast-image'
|
|
20
21
|
|
|
21
22
|
import {
|
|
@@ -101,7 +102,7 @@ const ProfileListUI = (props: ProfileParams) => {
|
|
|
101
102
|
const { top, bottom } = useSafeAreaInsets();
|
|
102
103
|
|
|
103
104
|
const isWalletEnabled = configs?.wallet_enabled?.value === '1' && (configs?.wallet_cash_enabled?.value === '1' || configs?.wallet_credit_point_enabled?.value === '1')
|
|
104
|
-
|
|
105
|
+
const IsPromotionsEnabled = configs?.advanced_offers_module === '1' || configs?.advanced_offers_module === 'true'
|
|
105
106
|
const onRedirect = (route: string, params?: any) => {
|
|
106
107
|
navigation.navigate(route, params)
|
|
107
108
|
}
|
|
@@ -178,6 +179,12 @@ const ProfileListUI = (props: ProfileParams) => {
|
|
|
178
179
|
<OText size={14} lineHeight={24} weight={'400'} color={theme.colors.textNormal}>{t('WALLETS', 'Wallets')}</OText>
|
|
179
180
|
</ListItem>
|
|
180
181
|
)}
|
|
182
|
+
{IsPromotionsEnabled && (
|
|
183
|
+
<ListItem onPress={() => onRedirect('Promotions', { isFromProfile: true, isGoBack: true })} activeOpacity={0.7}>
|
|
184
|
+
<MaterialIcons name='local-offer' style={styles.messageIconStyle} color={theme.colors.textNormal} />
|
|
185
|
+
<OText size={14} lineHeight={24} weight={'400'} color={theme.colors.textNormal}>{t('PROMOTIONS', 'Promotions')}</OText>
|
|
186
|
+
</ListItem>
|
|
187
|
+
)}
|
|
181
188
|
<ListItem onPress={() => navigation.navigate('Help', {})} activeOpacity={0.7}>
|
|
182
189
|
<OIcon src={theme.images.general.ic_help} width={16} color={theme.colors.textNormal} style={{ marginEnd: 14 }} />
|
|
183
190
|
<OText size={14} lineHeight={24} weight={'400'} color={theme.colors.textNormal}>{t('HELP', 'Help')}</OText>
|
|
@@ -17,6 +17,8 @@ export interface LoginParams {
|
|
|
17
17
|
handleSendVerifyCode?: any;
|
|
18
18
|
handleCheckPhoneCode?: any;
|
|
19
19
|
notificationState?: any;
|
|
20
|
+
handleReCaptcha?: any;
|
|
21
|
+
enableReCaptcha?: any;
|
|
20
22
|
}
|
|
21
23
|
export interface ProfileParams {
|
|
22
24
|
navigation?: any;
|
|
@@ -566,3 +568,12 @@ export interface PlaceSpotParams {
|
|
|
566
568
|
getPlacesList?: any,
|
|
567
569
|
setOpenPlaceModal?: any
|
|
568
570
|
}
|
|
571
|
+
|
|
572
|
+
export interface PromotionParams {
|
|
573
|
+
navigation: any,
|
|
574
|
+
offersState: any,
|
|
575
|
+
handleSearchValue: any,
|
|
576
|
+
searchValue: string,
|
|
577
|
+
offerSelected: any,
|
|
578
|
+
setOfferSelected: any,
|
|
579
|
+
}
|