ordering-ui-react-native 0.14.41 → 0.14.42-release
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 -2
- package/src/components/BusinessItemAccordion/index.tsx +2 -2
- package/src/components/Cart/index.tsx +135 -42
- package/src/components/Cart/styles.tsx +7 -0
- package/src/components/Checkout/index.tsx +28 -166
- package/src/components/OrderDetails/index.tsx +102 -34
- package/src/components/OrderDetails/styles.tsx +7 -0
- package/src/components/OrderSummary/index.tsx +140 -37
- package/src/components/OrderSummary/styles.tsx +10 -2
- package/src/components/PaymentOptions/index.tsx +3 -1
- package/src/components/PaymentOptionsWebView/index.tsx +150 -0
- package/src/components/ProductForm/index.tsx +6 -6
- package/src/components/SingleProductCard/index.tsx +1 -1
- package/src/components/StripeElementsForm/index.tsx +28 -13
- package/src/components/TaxInformation/index.tsx +58 -26
- package/src/components/VerifyPhone/styles.tsx +1 -2
- package/src/components/shared/OIcon.tsx +4 -1
- package/src/index.tsx +2 -0
- package/src/navigators/HomeNavigator.tsx +6 -0
- package/src/pages/ProductDetails.tsx +55 -0
- package/themes/doordash/src/components/LoginForm/index.tsx +1 -2
- package/themes/kiosk/src/components/Cart/index.tsx +14 -21
- package/themes/kiosk/src/components/CartItem/index.tsx +9 -7
- package/themes/kiosk/src/components/CustomerName/index.tsx +2 -1
- package/themes/kiosk/src/components/Intro/index.tsx +4 -4
- package/themes/kiosk/src/components/OptionCard/index.tsx +11 -6
- package/themes/kiosk/src/components/PaymentOptions/index.tsx +46 -44
- package/themes/original/src/components/BusinessController/index.tsx +3 -3
- package/themes/original/src/components/BusinessFeaturedController/index.tsx +2 -2
- package/themes/original/src/components/BusinessItemAccordion/index.tsx +12 -9
- package/themes/original/src/components/BusinessItemAccordion/styles.tsx +3 -2
- package/themes/original/src/components/BusinessProductsListing/index.tsx +8 -4
- package/themes/original/src/components/BusinessesListing/index.tsx +129 -94
- package/themes/original/src/components/Cart/index.tsx +122 -24
- package/themes/original/src/components/Cart/styles.tsx +8 -1
- package/themes/original/src/components/Checkout/index.tsx +37 -3
- package/themes/original/src/components/Help/index.tsx +1 -1
- package/themes/original/src/components/HighestRatedBusinesses/index.tsx +1 -0
- package/themes/original/src/components/MessageListing/index.tsx +4 -2
- package/themes/original/src/components/MomentOption/index.tsx +150 -158
- package/themes/original/src/components/OrderDetails/index.tsx +114 -42
- package/themes/original/src/components/OrderDetails/styles.tsx +8 -1
- package/themes/original/src/components/OrderProgress/index.tsx +2 -1
- package/themes/original/src/components/OrderSummary/index.tsx +132 -23
- package/themes/original/src/components/OrderSummary/styles.tsx +7 -0
- package/themes/original/src/components/PaymentOptions/index.tsx +8 -2
- package/themes/original/src/components/ProductForm/index.tsx +63 -56
- package/themes/original/src/components/ProductOptionSubOption/index.tsx +54 -51
- package/themes/original/src/components/ProductOptionSubOption/styles.tsx +8 -1
- package/themes/original/src/components/SingleProductCard/index.tsx +36 -19
- package/themes/original/src/components/SingleProductCard/styles.tsx +4 -0
- package/themes/original/src/components/StripeElementsForm/index.tsx +28 -13
- package/themes/original/src/components/TaxInformation/index.tsx +59 -27
- package/themes/original/src/components/UpsellingProducts/index.tsx +26 -18
- package/themes/original/src/types/index.tsx +2 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, { useEffect, useState } from 'react';
|
|
1
|
+
import React, { useCallback, useEffect, useRef, useState } from 'react';
|
|
2
2
|
import { Fade, Placeholder, PlaceholderLine } from 'rn-placeholder';
|
|
3
3
|
import Geolocation from '@react-native-community/geolocation'
|
|
4
4
|
import {
|
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
ScrollView,
|
|
8
8
|
Platform,
|
|
9
9
|
TouchableOpacity,
|
|
10
|
+
RefreshControl
|
|
10
11
|
} from 'react-native';
|
|
11
12
|
import {
|
|
12
13
|
BusinessList as BusinessesListingController,
|
|
@@ -43,7 +44,7 @@ import { BusinessFeaturedController } from '../BusinessFeaturedController';
|
|
|
43
44
|
import { HighestRatedBusinesses } from '../HighestRatedBusinesses';
|
|
44
45
|
import { getTypesText, convertToRadian } from '../../utils';
|
|
45
46
|
import { OrderProgress } from '../OrderProgress';
|
|
46
|
-
import { useIsFocused } from '@react-navigation/native';
|
|
47
|
+
import { useFocusEffect, useIsFocused } from '@react-navigation/native';
|
|
47
48
|
|
|
48
49
|
const PIXELS_TO_SCROLL = 1000;
|
|
49
50
|
|
|
@@ -57,11 +58,12 @@ const BusinessesListingUI = (props: BusinessesListingParams) => {
|
|
|
57
58
|
handleBusinessClick,
|
|
58
59
|
paginationProps,
|
|
59
60
|
handleChangeSearch,
|
|
60
|
-
|
|
61
|
+
businessId
|
|
61
62
|
} = props;
|
|
62
63
|
|
|
63
64
|
const theme = useTheme();
|
|
64
65
|
const isFocused = useIsFocused();
|
|
66
|
+
const [refreshing] = useState(false);
|
|
65
67
|
|
|
66
68
|
const styles = StyleSheet.create({
|
|
67
69
|
container: {
|
|
@@ -113,15 +115,15 @@ const BusinessesListingUI = (props: BusinessesListingParams) => {
|
|
|
113
115
|
const [featuredBusiness, setFeaturedBusinesses] = useState(Array);
|
|
114
116
|
const [isFarAway, setIsFarAway] = useState(false)
|
|
115
117
|
|
|
116
|
-
|
|
118
|
+
const timerId = useRef<any>(false)
|
|
117
119
|
// const panResponder = useRef(
|
|
118
|
-
//
|
|
119
|
-
//
|
|
120
|
-
//
|
|
121
|
-
//
|
|
122
|
-
//
|
|
123
|
-
//
|
|
124
|
-
//
|
|
120
|
+
// PanResponder.create({
|
|
121
|
+
// onMoveShouldSetPanResponder: (e, gestureState) => {
|
|
122
|
+
// const { dx, dy } = gestureState;
|
|
123
|
+
// resetInactivityTimeout()
|
|
124
|
+
// return (Math.abs(dx) > 20) || (Math.abs(dy) > 20);
|
|
125
|
+
// },
|
|
126
|
+
// })
|
|
125
127
|
// ).current
|
|
126
128
|
|
|
127
129
|
const configTypes =
|
|
@@ -142,15 +144,15 @@ const BusinessesListingUI = (props: BusinessesListingParams) => {
|
|
|
142
144
|
};
|
|
143
145
|
|
|
144
146
|
const getDistance = (lat1: any, lon1: any, lat2: any, lon2: any) => {
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
147
|
+
const R = 6371 // km
|
|
148
|
+
const dLat = convertToRadian(lat2 - lat1)
|
|
149
|
+
const dLon = convertToRadian(lon2 - lon1)
|
|
150
|
+
const curLat1 = convertToRadian(lat1)
|
|
151
|
+
const curLat2 = convertToRadian(lat2)
|
|
152
|
+
const a = Math.sin(dLat / 2) * Math.sin(dLat / 2) + Math.sin(dLon / 2) * Math.sin(dLon / 2) * Math.cos(curLat1) * Math.cos(curLat2)
|
|
153
|
+
const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a))
|
|
154
|
+
return R * c
|
|
155
|
+
}
|
|
154
156
|
|
|
155
157
|
useEffect(() => {
|
|
156
158
|
if (businessesList.businesses.length > 0) {
|
|
@@ -162,32 +164,56 @@ const BusinessesListingUI = (props: BusinessesListingParams) => {
|
|
|
162
164
|
setFeaturedBusinesses(ary);
|
|
163
165
|
}
|
|
164
166
|
}, [businessesList.businesses]);
|
|
165
|
-
// const resetInactivityTimeout = () => {
|
|
166
|
-
// clearTimeout(timerId.current)
|
|
167
|
-
// timerId.current = setInterval(() => {
|
|
168
|
-
// getBusinesses(true)
|
|
169
|
-
// }, 600000)
|
|
170
|
-
// }
|
|
171
167
|
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
168
|
+
const resetInactivityTimeout = () => {
|
|
169
|
+
clearTimeout(timerId.current)
|
|
170
|
+
timerId.current = setInterval(() => {
|
|
171
|
+
if (!businessesList.loading) {
|
|
172
|
+
getBusinesses(true)
|
|
173
|
+
}
|
|
174
|
+
}, 300000)
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
useEffect(() => {
|
|
178
|
+
resetInactivityTimeout()
|
|
179
|
+
}, [])
|
|
180
|
+
|
|
181
|
+
const handleOnRefresh = () => {
|
|
182
|
+
if (!businessesList.loading) {
|
|
183
|
+
getBusinesses(true);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
175
186
|
|
|
176
187
|
useEffect(() => {
|
|
177
188
|
Geolocation.getCurrentPosition((pos) => {
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
189
|
+
const crd = pos.coords
|
|
190
|
+
const distance = getDistance(crd.latitude, crd.longitude, orderState?.options?.address?.location?.lat, orderState?.options?.address?.location?.lng)
|
|
191
|
+
if (distance > 20) setIsFarAway(true)
|
|
181
192
|
else setIsFarAway(false)
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
193
|
+
}, (err) => {
|
|
194
|
+
console.log(`ERROR(${err.code}): ${err.message}`)
|
|
195
|
+
}, {
|
|
196
|
+
enableHighAccuracy: true, timeout: 15000, maximumAge: 10000
|
|
197
|
+
})
|
|
198
|
+
}, [orderState?.options?.address?.location])
|
|
199
|
+
|
|
200
|
+
useFocusEffect(
|
|
201
|
+
useCallback(() => {
|
|
202
|
+
getBusinesses(true)
|
|
203
|
+
resetInactivityTimeout()
|
|
204
|
+
return () => clearTimeout(timerId.current)
|
|
205
|
+
}, [navigation])
|
|
206
|
+
)
|
|
188
207
|
|
|
189
208
|
return (
|
|
190
|
-
<ScrollView style={styles.container} onScroll={(e) => handleScroll(e)} showsVerticalScrollIndicator={false}
|
|
209
|
+
<ScrollView style={styles.container} onScroll={(e) => handleScroll(e)} showsVerticalScrollIndicator={false}
|
|
210
|
+
refreshControl={
|
|
211
|
+
<RefreshControl
|
|
212
|
+
refreshing={refreshing}
|
|
213
|
+
onRefresh={() => handleOnRefresh()}
|
|
214
|
+
/>
|
|
215
|
+
}
|
|
216
|
+
>
|
|
191
217
|
<HeaderWrapper
|
|
192
218
|
source={theme.images.backgrounds.business_list_header}
|
|
193
219
|
style={{ paddingTop: top + 20 }}>
|
|
@@ -257,72 +283,80 @@ const BusinessesListingUI = (props: BusinessesListingParams) => {
|
|
|
257
283
|
/>
|
|
258
284
|
</WrapMomentOption>
|
|
259
285
|
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
286
|
+
{!businessId && (
|
|
287
|
+
<SearchBar
|
|
288
|
+
onSearch={handleChangeSearch}
|
|
289
|
+
searchValue={searchValue}
|
|
290
|
+
lazyLoad
|
|
291
|
+
isCancelXButtonShow={!!searchValue}
|
|
292
|
+
borderStyle={styles.borderStyle}
|
|
293
|
+
onCancel={() => handleChangeSearch('')}
|
|
294
|
+
placeholder={t('SEARCH', 'Search')}
|
|
295
|
+
height={26}
|
|
296
|
+
inputStyle={{ ...styles.searchInput, ...Platform.OS === 'ios' ? {} : { paddingBottom: 4 } }}
|
|
297
|
+
/>
|
|
298
|
+
)}
|
|
273
299
|
|
|
274
300
|
</View>
|
|
275
301
|
</OrderControlContainer>
|
|
276
302
|
</HeaderWrapper>
|
|
277
|
-
{
|
|
278
|
-
|
|
279
|
-
<
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
handleCustomClick={handleBusinessClick}
|
|
297
|
-
orderType={orderState?.options?.type}
|
|
298
|
-
/>
|
|
299
|
-
{bAry.length > 1 && (
|
|
303
|
+
{
|
|
304
|
+
isFocused && (
|
|
305
|
+
<OrderProgressWrapper>
|
|
306
|
+
<OrderProgress
|
|
307
|
+
{...props}
|
|
308
|
+
/>
|
|
309
|
+
</OrderProgressWrapper>
|
|
310
|
+
)
|
|
311
|
+
}
|
|
312
|
+
{
|
|
313
|
+
!businessId && !props.franchiseId && featuredBusiness && featuredBusiness.length > 0 && (
|
|
314
|
+
<FeaturedWrapper>
|
|
315
|
+
<OText size={16} style={{ marginLeft: 40 }} weight={Platform.OS === 'ios' ? '600' : 'bold'}>{t('FEATURED_BUSINESS', 'Featured business')}</OText>
|
|
316
|
+
<ScrollView
|
|
317
|
+
showsHorizontalScrollIndicator={false}
|
|
318
|
+
nestedScrollEnabled
|
|
319
|
+
horizontal contentContainerStyle={{ paddingHorizontal: 40 }}>
|
|
320
|
+
{featuredBusiness.map((bAry: any, idx) => (
|
|
321
|
+
<View key={'f-listing_' + idx}>
|
|
300
322
|
<BusinessFeaturedController
|
|
301
|
-
key={bAry[
|
|
302
|
-
business={bAry[
|
|
323
|
+
key={bAry[0].id}
|
|
324
|
+
business={bAry[0]}
|
|
325
|
+
isBusinessOpen={bAry[0]?.open}
|
|
303
326
|
handleCustomClick={handleBusinessClick}
|
|
304
327
|
orderType={orderState?.options?.type}
|
|
305
328
|
/>
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
329
|
+
{bAry.length > 1 && (
|
|
330
|
+
<BusinessFeaturedController
|
|
331
|
+
key={bAry[1].id}
|
|
332
|
+
business={bAry[1]}
|
|
333
|
+
isBusinessOpen={bAry[1]?.open}
|
|
334
|
+
handleCustomClick={handleBusinessClick}
|
|
335
|
+
orderType={orderState?.options?.type}
|
|
336
|
+
/>
|
|
337
|
+
)}
|
|
338
|
+
</View>
|
|
339
|
+
))}
|
|
340
|
+
</ScrollView>
|
|
341
|
+
</FeaturedWrapper>
|
|
342
|
+
)
|
|
343
|
+
}
|
|
312
344
|
<View style={{ height: 8, backgroundColor: theme.colors.backgroundGray100 }} />
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
345
|
+
{
|
|
346
|
+
!businessId && !props.franchiseId && (
|
|
347
|
+
<HighestRatedBusinesses onBusinessClick={handleBusinessClick} navigation={navigation} />
|
|
348
|
+
)
|
|
349
|
+
}
|
|
316
350
|
<View style={{ height: 8, backgroundColor: theme.colors.backgroundGray100 }} />
|
|
317
351
|
<ListWrapper>
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
352
|
+
{!businessId && (
|
|
353
|
+
<BusinessTypeFilter
|
|
354
|
+
images={props.images}
|
|
355
|
+
businessTypes={props.businessTypes}
|
|
356
|
+
defaultBusinessType={props.defaultBusinessType}
|
|
357
|
+
handleChangeBusinessType={handleChangeBusinessType}
|
|
358
|
+
/>
|
|
359
|
+
)}
|
|
326
360
|
{!businessesList.loading && businessesList.businesses.length === 0 && (
|
|
327
361
|
<NotFoundSource
|
|
328
362
|
content={t(
|
|
@@ -336,6 +370,7 @@ const BusinessesListingUI = (props: BusinessesListingParams) => {
|
|
|
336
370
|
<BusinessController
|
|
337
371
|
key={business.id}
|
|
338
372
|
business={business}
|
|
373
|
+
isBusinessOpen={business.open}
|
|
339
374
|
handleCustomClick={handleBusinessClick}
|
|
340
375
|
orderType={orderState?.options?.type}
|
|
341
376
|
navigation={navigation}
|
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
useValidationFields,
|
|
9
9
|
} from 'ordering-components/native';
|
|
10
10
|
import { useTheme } from 'styled-components/native';
|
|
11
|
-
import { CContainer, CheckoutAction } from './styles';
|
|
11
|
+
import { CContainer, CheckoutAction, Divider } from './styles';
|
|
12
12
|
|
|
13
13
|
import { OSBill, OSTable, OSCoupon, OSTotal, OSRow } from '../OrderSummary/styles';
|
|
14
14
|
|
|
@@ -23,6 +23,7 @@ import { ActivityIndicator, TouchableOpacity, View } from 'react-native';
|
|
|
23
23
|
import AntIcon from 'react-native-vector-icons/AntDesign'
|
|
24
24
|
import { TaxInformation } from '../TaxInformation';
|
|
25
25
|
import { CartStoresListing } from '../CartStoresListing';
|
|
26
|
+
import { OAlert } from '../../../../../src/components/shared'
|
|
26
27
|
|
|
27
28
|
const CartUI = (props: any) => {
|
|
28
29
|
const {
|
|
@@ -36,7 +37,8 @@ const CartUI = (props: any) => {
|
|
|
36
37
|
setIsCartsLoading,
|
|
37
38
|
handleChangeComment,
|
|
38
39
|
commentState,
|
|
39
|
-
onNavigationRedirect
|
|
40
|
+
onNavigationRedirect,
|
|
41
|
+
handleRemoveOfferClick
|
|
40
42
|
} = props
|
|
41
43
|
|
|
42
44
|
const theme = useTheme();
|
|
@@ -50,7 +52,8 @@ const CartUI = (props: any) => {
|
|
|
50
52
|
const [openUpselling, setOpenUpselling] = useState(false)
|
|
51
53
|
const [openChangeStore, setOpenChangeStore] = useState(false)
|
|
52
54
|
const [canOpenUpselling, setCanOpenUpselling] = useState(false)
|
|
53
|
-
const [openTaxModal, setOpenTaxModal] = useState<any>({ open: false, data: null })
|
|
55
|
+
const [openTaxModal, setOpenTaxModal] = useState<any>({ open: false, data: null, type: '' })
|
|
56
|
+
const [confirm, setConfirm] = useState<any>({ open: false, content: null, handleOnAccept: null, id: null, title: null })
|
|
54
57
|
|
|
55
58
|
const isCartPending = cart?.status === 2
|
|
56
59
|
const isCouponEnabled = validationFields?.fields?.checkout?.coupon?.enabled
|
|
@@ -69,12 +72,12 @@ const CartUI = (props: any) => {
|
|
|
69
72
|
const handleEditProduct = (product: any) => {
|
|
70
73
|
onNavigationRedirect('ProductDetails', {
|
|
71
74
|
businessId,
|
|
72
|
-
|
|
75
|
+
isCartProduct: true,
|
|
73
76
|
productCart: product,
|
|
74
77
|
businessSlug: cart?.business?.slug,
|
|
75
78
|
categoryId: product?.category_id,
|
|
76
79
|
productId: product?.id,
|
|
77
|
-
|
|
80
|
+
})
|
|
78
81
|
}
|
|
79
82
|
|
|
80
83
|
const handleClearProducts = async () => {
|
|
@@ -109,6 +112,22 @@ const CartUI = (props: any) => {
|
|
|
109
112
|
}
|
|
110
113
|
}
|
|
111
114
|
|
|
115
|
+
const getIncludedTaxesDiscounts = () => {
|
|
116
|
+
return cart?.taxes?.filter((tax: any) => tax?.type === 1)?.reduce((carry: number, tax: any) => carry + (tax?.summary?.tax_after_discount ?? tax?.summary?.tax), 0)
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
const onRemoveOffer = (id: number) => {
|
|
120
|
+
setConfirm({
|
|
121
|
+
open: true,
|
|
122
|
+
content: [t('QUESTION_DELETE_OFFER', 'Are you sure that you want to delete the offer?')],
|
|
123
|
+
title: t('OFFER', 'Offer'),
|
|
124
|
+
handleOnAccept: () => {
|
|
125
|
+
setConfirm({ ...confirm, open: false })
|
|
126
|
+
handleRemoveOfferClick(id)
|
|
127
|
+
}
|
|
128
|
+
})
|
|
129
|
+
}
|
|
130
|
+
|
|
112
131
|
const walletName: any = {
|
|
113
132
|
cash: {
|
|
114
133
|
name: t('PAY_WITH_CASH_WALLET', 'Pay with Cash Wallet'),
|
|
@@ -166,7 +185,7 @@ const CartUI = (props: any) => {
|
|
|
166
185
|
{parsePrice(cart?.subtotal + getIncludedTaxes())}
|
|
167
186
|
</OText>
|
|
168
187
|
</OSTable>
|
|
169
|
-
{cart?.discount > 0 && cart?.total >= 0 && (
|
|
188
|
+
{cart?.discount > 0 && cart?.total >= 0 && cart?.offers?.length === 0 && (
|
|
170
189
|
<OSTable>
|
|
171
190
|
{cart?.discount_type === 1 ? (
|
|
172
191
|
<OText size={12} lineHeight={18}>
|
|
@@ -179,19 +198,51 @@ const CartUI = (props: any) => {
|
|
|
179
198
|
<OText size={12} lineHeight={18}>- {parsePrice(cart?.discount || 0)}</OText>
|
|
180
199
|
</OSTable>
|
|
181
200
|
)}
|
|
201
|
+
{
|
|
202
|
+
cart?.offers?.length > 0 && cart?.offers?.filter((offer: any) => offer?.target === 1)?.map((offer: any) => (
|
|
203
|
+
<OSTable key={offer.id}>
|
|
204
|
+
<OSRow>
|
|
205
|
+
<OText size={12} lineHeight={18}>{offer.name}</OText>
|
|
206
|
+
{offer.rate_type === 1 && (
|
|
207
|
+
<OText size={12} lineHeight={18}>{`(${verifyDecimals(offer?.rate, parsePrice)}%)`}</OText>
|
|
208
|
+
)}
|
|
209
|
+
<TouchableOpacity style={{ marginLeft: 3 }} onPress={() => setOpenTaxModal({ open: true, data: offer, type: 'offer_target_1' })}>
|
|
210
|
+
<AntIcon name='exclamationcircleo' size={18} color={theme.colors.primary} />
|
|
211
|
+
</TouchableOpacity>
|
|
212
|
+
<TouchableOpacity style={{ marginLeft: 3 }} onPress={() => onRemoveOffer(offer?.id)}>
|
|
213
|
+
<AntIcon name='closecircle' size={18} color={theme.colors.primary} />
|
|
214
|
+
</TouchableOpacity>
|
|
215
|
+
</OSRow>
|
|
216
|
+
<OText size={12} lineHeight={18}>
|
|
217
|
+
- {parsePrice(offer?.summary?.discount)}
|
|
218
|
+
</OText>
|
|
219
|
+
</OSTable>
|
|
220
|
+
))
|
|
221
|
+
}
|
|
222
|
+
<Divider />
|
|
223
|
+
{cart?.subtotal_with_discount > 0 && cart?.discount > 0 && cart?.total >= 0 && (
|
|
224
|
+
<OSTable>
|
|
225
|
+
<OText size={12} lineHeight={18} numberOfLines={1}>{t('SUBTOTAL_WITH_DISCOUNT', 'Subtotal with discount')}</OText>
|
|
226
|
+
{cart?.business?.tax_type === 1 ? (
|
|
227
|
+
<OText size={12} lineHeight={18}>{parsePrice(cart?.subtotal_with_discount + getIncludedTaxesDiscounts() ?? 0)}</OText>
|
|
228
|
+
) : (
|
|
229
|
+
<OText size={12} lineHeight={18}>{parsePrice(cart?.subtotal_with_discount ?? 0)}</OText>
|
|
230
|
+
)}
|
|
231
|
+
</OSTable>
|
|
232
|
+
)}
|
|
182
233
|
{
|
|
183
234
|
cart.taxes?.length > 0 && cart.taxes.filter((tax: any) => tax.type === 2 && tax?.rate !== 0).map((tax: any) => (
|
|
184
235
|
<OSTable key={tax.id}>
|
|
185
236
|
<OSRow>
|
|
186
|
-
<OText numberOfLines={1} >
|
|
237
|
+
<OText size={12} lineHeight={18} numberOfLines={1} >
|
|
187
238
|
{tax.name || t('INHERIT_FROM_BUSINESS', 'Inherit from business')}{' '}
|
|
188
239
|
{`(${verifyDecimals(tax?.rate, parseNumber)}%)`}{' '}
|
|
189
240
|
</OText>
|
|
190
|
-
<TouchableOpacity onPress={() => setOpenTaxModal({ open: true, data: tax })} >
|
|
241
|
+
<TouchableOpacity onPress={() => setOpenTaxModal({ open: true, data: tax, type: 'tax' })} >
|
|
191
242
|
<AntIcon name='exclamationcircleo' size={18} color={theme.colors.primary} />
|
|
192
243
|
</TouchableOpacity>
|
|
193
244
|
</OSRow>
|
|
194
|
-
<OText>{parsePrice(tax?.summary?.tax
|
|
245
|
+
<OText size={12} lineHeight={18}>{parsePrice(tax?.summary?.tax_after_discount ?? tax?.summary?.tax ?? 0)}</OText>
|
|
195
246
|
</OSTable>
|
|
196
247
|
))
|
|
197
248
|
}
|
|
@@ -199,33 +250,66 @@ const CartUI = (props: any) => {
|
|
|
199
250
|
cart?.fees?.length > 0 && cart?.fees?.filter((fee: any) => !(fee.fixed === 0 && fee.percentage === 0)).map((fee: any) => (
|
|
200
251
|
<OSTable key={fee?.id}>
|
|
201
252
|
<OSRow>
|
|
202
|
-
<OText
|
|
253
|
+
<OText size={12} lineHeight={18} numberOfLines={1}>
|
|
203
254
|
{fee.name || t('INHERIT_FROM_BUSINESS', 'Inherit from business')}{' '}
|
|
204
255
|
({parsePrice(fee?.fixed)} + {fee?.percentage}%){' '}
|
|
205
256
|
</OText>
|
|
206
|
-
<TouchableOpacity onPress={() => setOpenTaxModal({ open: true, data: fee })} >
|
|
257
|
+
<TouchableOpacity onPress={() => setOpenTaxModal({ open: true, data: fee, type: 'fee' })} >
|
|
207
258
|
<AntIcon name='exclamationcircleo' size={18} color={theme.colors.primary} />
|
|
208
259
|
</TouchableOpacity>
|
|
209
260
|
</OSRow>
|
|
210
|
-
<OText>{parsePrice(fee?.summary?.fixed + fee?.summary?.percentage
|
|
261
|
+
<OText size={12} lineHeight={18}>{parsePrice(fee?.summary?.fixed + (fee?.summary?.percentage_after_discount ?? fee?.summary?.percentage) ?? 0)}</OText>
|
|
262
|
+
</OSTable>
|
|
263
|
+
))
|
|
264
|
+
}
|
|
265
|
+
{
|
|
266
|
+
cart?.offers?.length > 0 && cart?.offers?.filter((offer: any) => offer?.target === 3)?.map((offer: any) => (
|
|
267
|
+
<OSTable key={offer.id}>
|
|
268
|
+
<OSRow>
|
|
269
|
+
<OText size={12} lineHeight={18}>{offer.name}</OText>
|
|
270
|
+
{offer.rate_type === 1 && (
|
|
271
|
+
<OText size={12} lineHeight={18}>{`(${verifyDecimals(offer?.rate, parsePrice)}%)`}</OText>
|
|
272
|
+
)}
|
|
273
|
+
<TouchableOpacity style={{ marginLeft: 3 }} onPress={() => setOpenTaxModal({ open: true, data: offer, type: 'offer_target_3' })}>
|
|
274
|
+
<AntIcon name='exclamationcircleo' size={18} color={theme.colors.primary} />
|
|
275
|
+
</TouchableOpacity>
|
|
276
|
+
<TouchableOpacity style={{ marginLeft: 3 }} onPress={() => onRemoveOffer(offer?.id)}>
|
|
277
|
+
<AntIcon name='closecircle' size={18} color={theme.colors.primary} />
|
|
278
|
+
</TouchableOpacity>
|
|
279
|
+
</OSRow>
|
|
280
|
+
<OText size={12} lineHeight={18}>
|
|
281
|
+
- {parsePrice(offer?.summary?.discount)}
|
|
282
|
+
</OText>
|
|
211
283
|
</OSTable>
|
|
212
284
|
))
|
|
213
285
|
}
|
|
214
|
-
{cart?.service_fee > 0 && !cart?.fees?.length && (
|
|
215
|
-
<OSTable>
|
|
216
|
-
<OText size={12} lineHeight={18}>
|
|
217
|
-
{t('SERVICE_FEE', 'Service Fee')}
|
|
218
|
-
{`(${verifyDecimals(cart?.business?.service_fee, parseNumber)}%)`}
|
|
219
|
-
</OText>
|
|
220
|
-
<OText size={12} lineHeight={18}>{parsePrice(cart?.service_fee)}</OText>
|
|
221
|
-
</OSTable>
|
|
222
|
-
)}
|
|
223
286
|
{orderState?.options?.type === 1 && cart?.delivery_price > 0 && (
|
|
224
287
|
<OSTable>
|
|
225
288
|
<OText size={12} lineHeight={18}>{t('DELIVERY_FEE', 'Delivery Fee')}</OText>
|
|
226
289
|
<OText size={12} lineHeight={18}>{parsePrice(cart?.delivery_price)}</OText>
|
|
227
290
|
</OSTable>
|
|
228
291
|
)}
|
|
292
|
+
{
|
|
293
|
+
cart?.offers?.length > 0 && cart?.offers?.filter((offer: any) => offer?.target === 2)?.map((offer: any) => (
|
|
294
|
+
<OSTable key={offer.id}>
|
|
295
|
+
<OSRow>
|
|
296
|
+
<OText size={12} lineHeight={18}>{offer.name}</OText>
|
|
297
|
+
{offer.rate_type === 1 && (
|
|
298
|
+
<OText size={12} lineHeight={18}>{`(${verifyDecimals(offer?.rate, parsePrice)}%)`}</OText>
|
|
299
|
+
)}
|
|
300
|
+
<TouchableOpacity style={{ marginLeft: 3 }} onPress={() => setOpenTaxModal({ open: true, data: offer, type: 'offer_target_2' })}>
|
|
301
|
+
<AntIcon name='exclamationcircleo' size={18} color={theme.colors.primary} />
|
|
302
|
+
</TouchableOpacity>
|
|
303
|
+
<TouchableOpacity style={{ marginLeft: 3 }} onPress={() => onRemoveOffer(offer?.id)}>
|
|
304
|
+
<AntIcon name='closecircle' size={18} color={theme.colors.primary} />
|
|
305
|
+
</TouchableOpacity>
|
|
306
|
+
</OSRow>
|
|
307
|
+
<OText size={12} lineHeight={18}>
|
|
308
|
+
- {parsePrice(offer?.summary?.discount)}
|
|
309
|
+
</OText>
|
|
310
|
+
</OSTable>
|
|
311
|
+
))
|
|
312
|
+
}
|
|
229
313
|
{cart?.driver_tip > 0 && (
|
|
230
314
|
<OSTable>
|
|
231
315
|
<OText size={12} lineHeight={18}>
|
|
@@ -265,7 +349,7 @@ const CartUI = (props: any) => {
|
|
|
265
349
|
{t('TOTAL', 'Total')}
|
|
266
350
|
</OText>
|
|
267
351
|
<OText size={14} lineHeight={21} weight={'600'}>
|
|
268
|
-
{parsePrice(cart?.
|
|
352
|
+
{parsePrice(cart?.total >= 0 ? cart?.total : 0)}
|
|
269
353
|
</OText>
|
|
270
354
|
</OSTable>
|
|
271
355
|
</OSTotal>
|
|
@@ -339,11 +423,25 @@ const CartUI = (props: any) => {
|
|
|
339
423
|
</OModal>
|
|
340
424
|
<OModal
|
|
341
425
|
open={openTaxModal.open}
|
|
342
|
-
onClose={() => setOpenTaxModal({ open: false, data: null })}
|
|
426
|
+
onClose={() => setOpenTaxModal({ open: false, data: null, type: '' })}
|
|
343
427
|
entireModal
|
|
428
|
+
title={`${openTaxModal.data?.name ||
|
|
429
|
+
t('INHERIT_FROM_BUSINESS', 'Inherit from business')} ${openTaxModal.data?.rate_type !== 2 ? `(${typeof openTaxModal.data?.rate === 'number' ? `${openTaxModal.data?.rate}%` : `${parsePrice(openTaxModal.data?.fixed ?? 0)} + ${openTaxModal.data?.percentage}%`})` : ''} `}
|
|
344
430
|
>
|
|
345
|
-
<TaxInformation
|
|
431
|
+
<TaxInformation
|
|
432
|
+
type={openTaxModal.type}
|
|
433
|
+
data={openTaxModal.data}
|
|
434
|
+
products={cart?.products}
|
|
435
|
+
/>
|
|
346
436
|
</OModal>
|
|
437
|
+
<OAlert
|
|
438
|
+
open={confirm.open}
|
|
439
|
+
title={confirm.title}
|
|
440
|
+
content={confirm.content}
|
|
441
|
+
onAccept={confirm.handleOnAccept}
|
|
442
|
+
onCancel={() => setConfirm({ ...confirm, open: false, title: null })}
|
|
443
|
+
onClose={() => setConfirm({ ...confirm, open: false, title: null })}
|
|
444
|
+
/>
|
|
347
445
|
</CContainer>
|
|
348
446
|
)
|
|
349
447
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import styled
|
|
1
|
+
import styled from 'styled-components/native';
|
|
2
2
|
|
|
3
3
|
export const CContainer = styled.View`
|
|
4
4
|
/* border-bottom: 1px solid #F0F0F0; */
|
|
@@ -26,3 +26,10 @@ export const CheckoutAction = styled.View`
|
|
|
26
26
|
margin-top: 10px;
|
|
27
27
|
margin-bottom: 10px;
|
|
28
28
|
`
|
|
29
|
+
|
|
30
|
+
export const Divider = styled.View`
|
|
31
|
+
border-color: #EAEAEA;
|
|
32
|
+
border-width: 1px;
|
|
33
|
+
margin-top: 5px;
|
|
34
|
+
margin-bottom: 10px;
|
|
35
|
+
`
|
|
@@ -49,6 +49,7 @@ import NavBar from '../NavBar';
|
|
|
49
49
|
import { OrderSummary } from '../OrderSummary';
|
|
50
50
|
import { getTypesText } from '../../utils';
|
|
51
51
|
import { CartStoresListing } from '../CartStoresListing';
|
|
52
|
+
import { PaymentOptionsWebView } from '../../../../../src/components/PaymentOptionsWebView';
|
|
52
53
|
|
|
53
54
|
const mapConfigs = {
|
|
54
55
|
mapZoom: 16,
|
|
@@ -83,6 +84,7 @@ const CheckoutUI = (props: any) => {
|
|
|
83
84
|
deliveryOptionSelected,
|
|
84
85
|
instructionsOptions,
|
|
85
86
|
handleChangeDeliveryOption,
|
|
87
|
+
currency
|
|
86
88
|
} = props
|
|
87
89
|
|
|
88
90
|
const theme = useTheme();
|
|
@@ -114,10 +116,11 @@ const CheckoutUI = (props: any) => {
|
|
|
114
116
|
|
|
115
117
|
const [, { showToast }] = useToast();
|
|
116
118
|
const [, t] = useLanguage();
|
|
117
|
-
const [{ user }] = useSession();
|
|
119
|
+
const [{ user, token }] = useSession();
|
|
120
|
+
const [ordering] = useApi()
|
|
118
121
|
const [{ configs }] = useConfig();
|
|
119
122
|
const [{ parsePrice, parseDate }] = useUtils();
|
|
120
|
-
const [{ options, carts, loading }] = useOrder();
|
|
123
|
+
const [{ options, carts, loading }, { confirmCart }] = useOrder();
|
|
121
124
|
const [validationFields] = useValidationFields();
|
|
122
125
|
|
|
123
126
|
const [errorCash, setErrorCash] = useState(false);
|
|
@@ -126,6 +129,10 @@ const CheckoutUI = (props: any) => {
|
|
|
126
129
|
const [phoneUpdate, setPhoneUpdate] = useState(false);
|
|
127
130
|
const [openChangeStore, setOpenChangeStore] = useState(false)
|
|
128
131
|
const [isDeliveryOptionModalVisible, setIsDeliveryOptionModalVisible] = useState(false)
|
|
132
|
+
const [showGateway, setShowGateway] = useState<any>({ closedByUsed: false, open: false });
|
|
133
|
+
const [webviewPaymethod, setWebviewPaymethod] = useState<any>(null)
|
|
134
|
+
|
|
135
|
+
const isWalletEnabled = configs?.wallet_enabled?.value === '1' && (configs?.wallet_cash_enabled?.value === '1' || configs?.wallet_credit_point_enabled?.value === '1')
|
|
129
136
|
|
|
130
137
|
const driverTipsOptions = typeof configs?.driver_tip_options?.value === 'string'
|
|
131
138
|
? JSON.parse(configs?.driver_tip_options?.value) || []
|
|
@@ -154,6 +161,16 @@ const CheckoutUI = (props: any) => {
|
|
|
154
161
|
setIsUserDetailsEdit(true)
|
|
155
162
|
}
|
|
156
163
|
|
|
164
|
+
const handlePaymentMethodClick = (paymethod: any) => {
|
|
165
|
+
setShowGateway({ closedByUser: false, open: true })
|
|
166
|
+
setWebviewPaymethod(paymethod)
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
const onFailPaypal = async () => {
|
|
170
|
+
if (showGateway.closedByUser === true) {
|
|
171
|
+
await confirmCart(cart.uuid)
|
|
172
|
+
}
|
|
173
|
+
}
|
|
157
174
|
const changeDeliveryOption = (option: any) => {
|
|
158
175
|
handleChangeDeliveryOption(option)
|
|
159
176
|
setIsDeliveryOptionModalVisible(false)
|
|
@@ -214,6 +231,10 @@ const CheckoutUI = (props: any) => {
|
|
|
214
231
|
}
|
|
215
232
|
}, [cart?.products])
|
|
216
233
|
|
|
234
|
+
useEffect(() => {
|
|
235
|
+
onFailPaypal()
|
|
236
|
+
}, [showGateway.closedByUser])
|
|
237
|
+
|
|
217
238
|
return (
|
|
218
239
|
<>
|
|
219
240
|
<Container noPadding>
|
|
@@ -501,6 +522,7 @@ const CheckoutUI = (props: any) => {
|
|
|
501
522
|
setErrorCash={setErrorCash}
|
|
502
523
|
onNavigationRedirect={onNavigationRedirect}
|
|
503
524
|
paySelected={paymethodSelected}
|
|
525
|
+
handlePaymentMethodClickCustom={handlePaymentMethodClick}
|
|
504
526
|
/>
|
|
505
527
|
</ChPaymethods>
|
|
506
528
|
</ChSection>
|
|
@@ -547,7 +569,7 @@ const CheckoutUI = (props: any) => {
|
|
|
547
569
|
<OrderSummary
|
|
548
570
|
cart={cart}
|
|
549
571
|
isCartPending={cart?.status === 2}
|
|
550
|
-
|
|
572
|
+
onNavigationRedirect={onNavigationRedirect}
|
|
551
573
|
/>
|
|
552
574
|
</>
|
|
553
575
|
)}
|
|
@@ -620,6 +642,18 @@ const CheckoutUI = (props: any) => {
|
|
|
620
642
|
iosBottom={20}
|
|
621
643
|
/>
|
|
622
644
|
)}
|
|
645
|
+
{webviewPaymethod?.gateway === 'paypal' && showGateway.open && (
|
|
646
|
+
<PaymentOptionsWebView
|
|
647
|
+
onNavigationRedirect={onNavigationRedirect}
|
|
648
|
+
uri={`${ordering.root}/html/paypal_react_native`}
|
|
649
|
+
user={user}
|
|
650
|
+
token={token}
|
|
651
|
+
cart={cart}
|
|
652
|
+
currency={currency}
|
|
653
|
+
webviewPaymethod={webviewPaymethod}
|
|
654
|
+
setShowGateway={setShowGateway}
|
|
655
|
+
/>
|
|
656
|
+
)}
|
|
623
657
|
</>
|
|
624
658
|
)
|
|
625
659
|
}
|