ordering-ui-react-native 0.17.98-release → 0.17.99-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 +1 -1
- package/themes/original/src/components/BusinessPreorder/index.tsx +2 -3
- package/themes/original/src/components/BusinessPreorder/styles.tsx +14 -0
- package/themes/original/src/components/BusinessesListing/Layout/Original/index.tsx +1 -1
- package/themes/original/src/components/Cart/index.tsx +49 -10
- package/themes/original/src/components/CartContent/index.tsx +59 -38
- package/themes/original/src/components/Checkout/index.tsx +63 -9
- package/themes/original/src/components/MomentOption/index.tsx +3 -3
- package/themes/original/src/components/MomentOption/styles.tsx +15 -0
- package/themes/original/src/components/OrderSummary/index.tsx +3 -1
- package/themes/original/src/components/ProductForm/ActionButton.tsx +120 -0
- package/themes/original/src/config/constants.tsx +10 -0
- package/themes/original/src/types/index.tsx +8 -1
package/package.json
CHANGED
|
@@ -64,7 +64,7 @@ const BusinessPreorderUI = (props: BusinessPreorderParams) => {
|
|
|
64
64
|
container: {
|
|
65
65
|
height: windowHeight,
|
|
66
66
|
paddingVertical: 30,
|
|
67
|
-
paddingHorizontal:
|
|
67
|
+
paddingHorizontal: 20
|
|
68
68
|
},
|
|
69
69
|
businessLogo: {
|
|
70
70
|
backgroundColor: 'white',
|
|
@@ -319,11 +319,10 @@ const BusinessPreorderUI = (props: BusinessPreorderParams) => {
|
|
|
319
319
|
|
|
320
320
|
return (
|
|
321
321
|
<>
|
|
322
|
-
<PreOrderContainer contentContainerStyle={{ paddingVertical: 32, paddingHorizontal:
|
|
322
|
+
<PreOrderContainer contentContainerStyle={{ paddingVertical: 32, paddingHorizontal: 20 }}>
|
|
323
323
|
<TouchableOpacity onPress={() => goToBack && goToBack()} style={{ marginBottom: 12 }}>
|
|
324
324
|
<IconAntDesign
|
|
325
325
|
name='close'
|
|
326
|
-
color={theme.colors.textThird}
|
|
327
326
|
size={24}
|
|
328
327
|
style={{ marginLeft: -4 }}
|
|
329
328
|
/>
|
|
@@ -21,6 +21,10 @@ export const OrderTimeWrapper = styled.View`
|
|
|
21
21
|
export const TimeListWrapper = styled.ScrollView`
|
|
22
22
|
margin-top: 30px;
|
|
23
23
|
max-height: 160px;
|
|
24
|
+
${({ cateringPreorder }: any) => cateringPreorder && css`
|
|
25
|
+
max-height: 210px;
|
|
26
|
+
height: 210px;
|
|
27
|
+
`}
|
|
24
28
|
`
|
|
25
29
|
|
|
26
30
|
export const TimeContentWrapper = styled.View`
|
|
@@ -38,6 +42,16 @@ export const TimeItem = styled.View`
|
|
|
38
42
|
justify-content: center;
|
|
39
43
|
align-items: center;
|
|
40
44
|
margin: 10px 0px;
|
|
45
|
+
${({ cateringPreorder }: any) => cateringPreorder && css`
|
|
46
|
+
background: #fff;
|
|
47
|
+
width: 100%;
|
|
48
|
+
min-width: 100%;
|
|
49
|
+
height: 50px;
|
|
50
|
+
flex-direction: row;
|
|
51
|
+
justify-content: flex-start;
|
|
52
|
+
padding-left: 10px;
|
|
53
|
+
margin: 0;
|
|
54
|
+
`}
|
|
41
55
|
${({ active }: any) => active && css`
|
|
42
56
|
background: #F5F9FF;
|
|
43
57
|
`}
|
|
@@ -94,7 +94,7 @@ const BusinessesListingUI = (props: BusinessesListingParams) => {
|
|
|
94
94
|
backgroundColor: theme.colors.white,
|
|
95
95
|
borderColor: theme.colors.backgroundGray,
|
|
96
96
|
borderRadius: 8,
|
|
97
|
-
marginHorizontal:
|
|
97
|
+
marginHorizontal: 20,
|
|
98
98
|
minHeight: 45,
|
|
99
99
|
paddingVertical: 5,
|
|
100
100
|
paddingHorizontal: 20,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, { useState } from 'react';
|
|
1
|
+
import React, { useEffect, useState, useRef } from 'react';
|
|
2
2
|
import {
|
|
3
3
|
Cart as CartController,
|
|
4
4
|
useOrder,
|
|
@@ -26,6 +26,7 @@ import { CartStoresListing } from '../CartStoresListing';
|
|
|
26
26
|
import { OAlert } from '../shared'
|
|
27
27
|
import { PlaceSpot } from '../PlaceSpot'
|
|
28
28
|
import { DriverTips } from '../DriverTips'
|
|
29
|
+
import { MomentOption } from '../MomentOption'
|
|
29
30
|
|
|
30
31
|
const CartUI = (props: any) => {
|
|
31
32
|
const {
|
|
@@ -51,7 +52,11 @@ const CartUI = (props: any) => {
|
|
|
51
52
|
preorderMaximumDays,
|
|
52
53
|
preorderMinimumDays,
|
|
53
54
|
cateringTypes,
|
|
54
|
-
isFromUpselling
|
|
55
|
+
isFromUpselling,
|
|
56
|
+
cartsOpened,
|
|
57
|
+
setCartsOpened,
|
|
58
|
+
changeActiveState,
|
|
59
|
+
isActive
|
|
55
60
|
} = props
|
|
56
61
|
|
|
57
62
|
const theme = useTheme();
|
|
@@ -61,13 +66,13 @@ const CartUI = (props: any) => {
|
|
|
61
66
|
const [{ configs }] = useConfig();
|
|
62
67
|
const [{ parsePrice, parseNumber, parseDate }] = useUtils()
|
|
63
68
|
const [validationFields] = useValidationFields()
|
|
64
|
-
|
|
69
|
+
const commentRef = useRef()
|
|
65
70
|
const [openUpselling, setOpenUpselling] = useState(false)
|
|
66
71
|
const [openChangeStore, setOpenChangeStore] = useState(false)
|
|
67
72
|
const [canOpenUpselling, setCanOpenUpselling] = useState(false)
|
|
68
73
|
const [openTaxModal, setOpenTaxModal] = useState<any>({ open: false, data: null, type: '' })
|
|
69
74
|
const [openPlaceModal, setOpenPlaceModal] = useState(false)
|
|
70
|
-
|
|
75
|
+
const [maxDate, setMaxDate] = useState<any>(null)
|
|
71
76
|
const isCartPending = cart?.status === 2
|
|
72
77
|
const isCouponEnabled = validationFields?.fields?.checkout?.coupon?.enabled
|
|
73
78
|
const business: any = (orderState?.carts && Object.values(orderState.carts).find((_cart: any) => _cart?.uuid === props.cartuuid)) ?? {}
|
|
@@ -108,7 +113,7 @@ const CartUI = (props: any) => {
|
|
|
108
113
|
}
|
|
109
114
|
}
|
|
110
115
|
|
|
111
|
-
const handleUpsellingPage = (individualCart
|
|
116
|
+
const handleUpsellingPage = (individualCart: any) => {
|
|
112
117
|
const isProductCartParam = !!individualCart?.products?.length
|
|
113
118
|
setOpenUpselling(false)
|
|
114
119
|
setCanOpenUpselling(false)
|
|
@@ -191,6 +196,19 @@ const CartUI = (props: any) => {
|
|
|
191
196
|
return acc = acc
|
|
192
197
|
}, cart?.subtotal)
|
|
193
198
|
|
|
199
|
+
useEffect(() => {
|
|
200
|
+
const limitDays = parseInt(preorderMaximumDays ?? configs?.max_days_preorder?.value, 10)
|
|
201
|
+
const currentDate = new Date()
|
|
202
|
+
const time = limitDays > 1
|
|
203
|
+
? currentDate.getTime() + ((limitDays - 1) * 24 * 60 * 60 * 1000)
|
|
204
|
+
: limitDays === 1 ? currentDate.getTime() : currentDate.getTime() + (6 * 24 * 60 * 60 * 1000)
|
|
205
|
+
|
|
206
|
+
currentDate.setTime(time)
|
|
207
|
+
currentDate.setHours(23)
|
|
208
|
+
currentDate.setMinutes(59)
|
|
209
|
+
setMaxDate(currentDate)
|
|
210
|
+
}, [preorderMaximumDays, configs?.max_days_preorder?.value])
|
|
211
|
+
|
|
194
212
|
return (
|
|
195
213
|
<CContainer>
|
|
196
214
|
{openUpselling && (
|
|
@@ -218,6 +236,10 @@ const CartUI = (props: any) => {
|
|
|
218
236
|
checkoutButtonDisabled={(openUpselling && !canOpenUpselling) || subtotalWithTaxes < cart?.minimum || !cart?.valid_address}
|
|
219
237
|
isMultiCheckout={isMultiCheckout}
|
|
220
238
|
isFromUpselling={isFromUpselling}
|
|
239
|
+
cartsOpened={cartsOpened}
|
|
240
|
+
setCartsOpened={setCartsOpened}
|
|
241
|
+
changeActiveState={changeActiveState}
|
|
242
|
+
isActive={isActive}
|
|
221
243
|
isGiftCart={!cart?.business_id}
|
|
222
244
|
>
|
|
223
245
|
{cart?.products?.length > 0 && cart?.products.map((product: any, i: number) => (
|
|
@@ -232,6 +254,7 @@ const CartUI = (props: any) => {
|
|
|
232
254
|
offsetDisabled={offsetDisabled}
|
|
233
255
|
onDeleteProduct={handleDeleteClick}
|
|
234
256
|
onEditProduct={handleEditProduct}
|
|
257
|
+
viewString='business_view'
|
|
235
258
|
/>
|
|
236
259
|
))}
|
|
237
260
|
|
|
@@ -243,7 +266,7 @@ const CartUI = (props: any) => {
|
|
|
243
266
|
{parsePrice(cart?.subtotal + getIncludedTaxes())}
|
|
244
267
|
</OText>
|
|
245
268
|
</OSTable>
|
|
246
|
-
{cart?.discount > 0 && cart?.total >= 0 && cart?.offers?.length === 0 && (
|
|
269
|
+
{!hideCartDiscount && cart?.discount > 0 && cart?.total >= 0 && cart?.offers?.length === 0 && (
|
|
247
270
|
<OSTable>
|
|
248
271
|
{cart?.discount_type === 1 ? (
|
|
249
272
|
<OText size={12} lineHeight={18}>
|
|
@@ -257,7 +280,7 @@ const CartUI = (props: any) => {
|
|
|
257
280
|
</OSTable>
|
|
258
281
|
)}
|
|
259
282
|
{
|
|
260
|
-
cart?.offers?.length > 0 && cart?.offers?.filter((offer: any) => offer?.target === 1)?.map((offer: any, i: number) => (
|
|
283
|
+
!hideCartDiscount && cart?.offers?.length > 0 && cart?.offers?.filter((offer: any) => offer?.target === 1)?.map((offer: any, i: number) => (
|
|
261
284
|
<OSTable key={`${offer.id}_${i}`}>
|
|
262
285
|
<OSRow>
|
|
263
286
|
<OText size={12} lineHeight={18}>{offer.name}</OText>
|
|
@@ -278,7 +301,7 @@ const CartUI = (props: any) => {
|
|
|
278
301
|
))
|
|
279
302
|
}
|
|
280
303
|
{/* <Divider /> */}
|
|
281
|
-
{cart?.subtotal_with_discount > 0 && cart?.discount > 0 && cart?.total >= 0 && (
|
|
304
|
+
{!hideCartDiscount && cart?.subtotal_with_discount > 0 && cart?.discount > 0 && cart?.total >= 0 && (
|
|
282
305
|
<OSTable>
|
|
283
306
|
<OText size={12} lineHeight={18} numberOfLines={1}>{t('SUBTOTAL_WITH_DISCOUNT', 'Subtotal with discount')}</OText>
|
|
284
307
|
{cart?.business?.tax_type === 1 ? (
|
|
@@ -458,7 +481,7 @@ const CartUI = (props: any) => {
|
|
|
458
481
|
</TouchableOpacity>
|
|
459
482
|
</OSTable>
|
|
460
483
|
)}
|
|
461
|
-
{cart?.status !== 2 && (
|
|
484
|
+
{cart?.status !== 2 && !hideCartComments && (
|
|
462
485
|
<OSTable>
|
|
463
486
|
<View style={{ width: '100%', marginTop: 20 }}>
|
|
464
487
|
<OText size={16} lineHeight={18}>{t('COMMENTS', 'Comments')}</OText>
|
|
@@ -476,6 +499,7 @@ const CartUI = (props: any) => {
|
|
|
476
499
|
marginTop: 10,
|
|
477
500
|
borderRadius: 7.6
|
|
478
501
|
}}
|
|
502
|
+
forwardRef={commentRef}
|
|
479
503
|
multiline
|
|
480
504
|
/>
|
|
481
505
|
{commentState?.loading && (
|
|
@@ -493,6 +517,21 @@ const CartUI = (props: any) => {
|
|
|
493
517
|
)}
|
|
494
518
|
</OSBill>
|
|
495
519
|
)}
|
|
520
|
+
{cateringTypes.includes(orderState?.options?.type) && maxDate && cart?.valid_products && (
|
|
521
|
+
<View>
|
|
522
|
+
<MomentOption
|
|
523
|
+
maxDate={maxDate}
|
|
524
|
+
cateringPreorder
|
|
525
|
+
isCart
|
|
526
|
+
preorderSlotInterval={preorderSlotInterval}
|
|
527
|
+
preorderLeadTime={preorderLeadTime}
|
|
528
|
+
preorderTimeRange={preorderTimeRange}
|
|
529
|
+
preorderMaximumDays={preorderMaximumDays}
|
|
530
|
+
preorderMinimumDays={preorderMinimumDays}
|
|
531
|
+
business={cart?.business}
|
|
532
|
+
/>
|
|
533
|
+
</View>
|
|
534
|
+
)}
|
|
496
535
|
{!isMultiCheckout && (
|
|
497
536
|
<>
|
|
498
537
|
{cart?.valid_products ? (
|
|
@@ -509,7 +548,7 @@ const CartUI = (props: any) => {
|
|
|
509
548
|
isDisabled={(openUpselling && !canOpenUpselling) || subtotalWithTaxes < cart?.minimum || !cart?.valid_address}
|
|
510
549
|
borderColor={theme.colors.primary}
|
|
511
550
|
imgRightSrc={null}
|
|
512
|
-
textStyle={{ color: '
|
|
551
|
+
textStyle={{ color: '#fff', textAlign: 'center', flex: 1 }}
|
|
513
552
|
onClick={() => setOpenUpselling(true)}
|
|
514
553
|
style={{ width: '100%', flexDirection: 'row', justifyContent: 'center', borderRadius: 7.6, shadowOpacity: 0 }}
|
|
515
554
|
/>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import React, { useState } from 'react';
|
|
1
|
+
import React, { useCallback, useState } from 'react';
|
|
2
2
|
import { View } from 'react-native';
|
|
3
|
-
import { useLanguage, useConfig, useUtils } from 'ordering-components/native';
|
|
3
|
+
import { useLanguage, useConfig, useUtils, useOrder } from 'ordering-components/native';
|
|
4
4
|
import { useTheme } from 'styled-components/native';
|
|
5
5
|
import { CCContainer, CCNotCarts, CCList, CheckoutAction, ChCartsTotal } from './styles';
|
|
6
6
|
|
|
@@ -11,10 +11,9 @@ import { NotFoundSource } from '../NotFoundSource';
|
|
|
11
11
|
|
|
12
12
|
export const CartContent = (props: any) => {
|
|
13
13
|
const {
|
|
14
|
-
carts,
|
|
15
|
-
isOrderStateCarts,
|
|
16
14
|
onNavigationRedirect,
|
|
17
|
-
singleBusiness
|
|
15
|
+
singleBusiness,
|
|
16
|
+
businessSlug
|
|
18
17
|
} = props
|
|
19
18
|
|
|
20
19
|
const theme = useTheme();
|
|
@@ -22,16 +21,22 @@ export const CartContent = (props: any) => {
|
|
|
22
21
|
const [{ configs }] = useConfig()
|
|
23
22
|
const [{ parsePrice }] = useUtils();
|
|
24
23
|
const [isCartsLoading, setIsCartsLoading] = useState(false)
|
|
25
|
-
|
|
26
|
-
const
|
|
24
|
+
const [cartsOpened, setCartsOpened] = useState([])
|
|
25
|
+
const [{ carts: cartsContext }] = useOrder();
|
|
26
|
+
const cartsList =
|
|
27
|
+
(cartsContext &&
|
|
28
|
+
Object.values(cartsContext).filter((cart: any) => cart.products.length > 0)) ??
|
|
29
|
+
[];
|
|
30
|
+
const carts = businessSlug
|
|
31
|
+
? cartsList.filter((cart: any) => cart?.business?.slug === businessSlug || parseInt(businessSlug) === cart?.business_id)
|
|
32
|
+
: cartsList
|
|
33
|
+
const isOrderStateCarts = !!carts
|
|
27
34
|
const isMultiCheckout = configs?.checkout_multi_business_enabled?.value === '1'
|
|
28
|
-
const cartsAvailable: any = Object.values(carts)?.filter((cart: any) => cart?.valid && cart?.status !== 2)
|
|
29
|
-
|
|
35
|
+
const cartsAvailable: any = Object.values(carts || {})?.filter((cart: any) => cart?.valid && cart?.status !== 2)
|
|
30
36
|
const totalCartsPrice = cartsAvailable?.length && cartsAvailable.reduce((total: any, cart: any) => { return total + cart?.total }, 0)
|
|
31
37
|
const totalCartsFee = cartsAvailable?.length && cartsAvailable
|
|
32
38
|
?.filter((cart: any) => cart?.status !== 1 && cart?.valid && cart?.products?.length)
|
|
33
39
|
?.reduce((total: any, cart: any) => { return total + (cart?.delivery_price_with_discount) }, 0)
|
|
34
|
-
|
|
35
40
|
const handleCheckoutRedirect = () => {
|
|
36
41
|
if (cartsAvailable.length === 1) {
|
|
37
42
|
onNavigationRedirect('CheckoutNavigator', {
|
|
@@ -66,9 +71,21 @@ export const CartContent = (props: any) => {
|
|
|
66
71
|
}
|
|
67
72
|
}
|
|
68
73
|
|
|
74
|
+
const changeActiveState = useCallback((isClosed : boolean, uuid : string) => {
|
|
75
|
+
const isActive = cartsOpened?.includes?.(uuid) || !!singleBusiness
|
|
76
|
+
if (isActive || !isClosed) {
|
|
77
|
+
setCartsOpened(cartsOpened?.filter?.((_uuid) => _uuid !== uuid))
|
|
78
|
+
} else {
|
|
79
|
+
setCartsOpened([
|
|
80
|
+
...cartsOpened,
|
|
81
|
+
uuid
|
|
82
|
+
])
|
|
83
|
+
}
|
|
84
|
+
}, [cartsOpened])
|
|
85
|
+
|
|
69
86
|
return (
|
|
70
87
|
<CCContainer
|
|
71
|
-
style={{ paddingHorizontal:
|
|
88
|
+
style={{ paddingHorizontal: 20 }}
|
|
72
89
|
>
|
|
73
90
|
{isOrderStateCarts && carts?.length > 0 && (
|
|
74
91
|
<>
|
|
@@ -88,8 +105,12 @@ export const CartContent = (props: any) => {
|
|
|
88
105
|
hideUpselling
|
|
89
106
|
businessConfigs={cart?.business?.configs}
|
|
90
107
|
hideCouponInput={configs?.multi_business_checkout_coupon_input_style?.value === 'group'}
|
|
91
|
-
|
|
108
|
+
hideDeliveryFee={configs?.multi_business_checkout_show_combined_delivery_fee?.value === '1'}
|
|
92
109
|
hideDriverTip={configs?.multi_business_checkout_show_combined_driver_tip?.value === '1'}
|
|
110
|
+
cartsOpened={cartsOpened}
|
|
111
|
+
setCartsOpened={setCartsOpened}
|
|
112
|
+
changeActiveState={changeActiveState}
|
|
113
|
+
isActive={cartsOpened?.includes?.(cart?.uuid) || !!singleBusiness}
|
|
93
114
|
/>
|
|
94
115
|
<View style={{ height: 8, backgroundColor: theme.colors.backgroundGray100, marginHorizontal: -40, marginTop: 20 }} />
|
|
95
116
|
</>
|
|
@@ -101,32 +122,32 @@ export const CartContent = (props: any) => {
|
|
|
101
122
|
{!!cartsAvailable.length && (
|
|
102
123
|
<ChCartsTotal>
|
|
103
124
|
{!!totalCartsFee && configs?.multi_business_checkout_show_combined_delivery_fee?.value === '1' && (
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
125
|
+
<View style={{ flexDirection: 'row', justifyContent: 'space-between' }}>
|
|
126
|
+
<OText size={14} lineHeight={24} color={theme.colors.textNormal} weight={'400'}>
|
|
127
|
+
{t('TOTAL_DELIVERY_FEE', 'Total delivery fee')}
|
|
128
|
+
</OText>
|
|
129
|
+
<OText size={14} lineHeight={24} color={theme.colors.textNormal} weight={'400'}>
|
|
130
|
+
{parsePrice(totalCartsFee)}
|
|
131
|
+
</OText>
|
|
132
|
+
</View>
|
|
133
|
+
)}
|
|
134
|
+
{cartsAvailable.reduce((sum: any, cart: any) => sum + cart?.driver_tip, 0) > 0 &&
|
|
135
|
+
configs?.multi_business_checkout_show_combined_driver_tip?.value === '1' && (
|
|
136
|
+
<View style={{ flexDirection: 'row', justifyContent: 'space-between' }}>
|
|
137
|
+
<OText size={14} lineHeight={24} color={theme.colors.textNormal} weight={'400'}>
|
|
138
|
+
{t('DRIVER_TIP', 'Driver tip')}
|
|
139
|
+
</OText>
|
|
140
|
+
<OText size={14} lineHeight={24} color={theme.colors.textNormal} weight={'400'}>
|
|
141
|
+
{parsePrice(cartsAvailable.reduce((sum: any, cart: any) => sum + cart?.driver_tip, 0))}
|
|
142
|
+
</OText>
|
|
143
|
+
</View>
|
|
144
|
+
)}
|
|
145
|
+
<View style={{ flexDirection: 'row', justifyContent: 'space-between' }}>
|
|
146
|
+
<OText size={16} lineHeight={24} color={theme.colors.textNormal} weight={'500'}>
|
|
147
|
+
{t('TOTAL_FOR_ALL_CARTS', 'Total for all Carts')}
|
|
148
|
+
</OText>
|
|
149
|
+
<OText size={16} lineHeight={24} color={theme.colors.textNormal} weight={'500'}>{parsePrice(totalCartsPrice)}</OText>
|
|
150
|
+
</View>
|
|
130
151
|
<View style={{ flexDirection: 'row', justifyContent: 'center', marginVertical: 20 }}>
|
|
131
152
|
<OText size={14} color={theme.colors.textNormal} weight={'300'} style={{ textAlign: 'center' }}>
|
|
132
153
|
{t('CART_GROUP_MESSAGE_ALERT', 'Discounts may be applied at the time of payment for this group.')}
|
|
@@ -1,9 +1,11 @@
|
|
|
1
|
-
import React, { useState, useEffect, useCallback } from 'react';
|
|
2
|
-
import { View, StyleSheet, TouchableOpacity, Platform, I18nManager, ScrollView } from 'react-native';
|
|
1
|
+
import React, { useState, useEffect, useCallback, useRef } from 'react';
|
|
2
|
+
import { View, StyleSheet, TouchableOpacity, Platform, I18nManager, ScrollView, Keyboard } from 'react-native';
|
|
3
3
|
import { initStripe, useConfirmPayment } from '@stripe/stripe-react-native';
|
|
4
4
|
import NativeStripeSdk from '@stripe/stripe-react-native/src/NativeStripeSdk'
|
|
5
5
|
import Picker from 'react-native-country-picker-modal';
|
|
6
6
|
import MaterialIcons from 'react-native-vector-icons/MaterialIcons'
|
|
7
|
+
import IconAntDesign from 'react-native-vector-icons/AntDesign';
|
|
8
|
+
|
|
7
9
|
import ReactNativeHapticFeedback from "react-native-haptic-feedback";
|
|
8
10
|
import {
|
|
9
11
|
Checkout as CheckoutController,
|
|
@@ -46,7 +48,9 @@ import {
|
|
|
46
48
|
DeliveryOptionsContainer,
|
|
47
49
|
DeliveryOptionItem,
|
|
48
50
|
WalletPaymentOptionContainer,
|
|
49
|
-
CartHeader
|
|
51
|
+
CartHeader,
|
|
52
|
+
TopHeader,
|
|
53
|
+
TopActions
|
|
50
54
|
} from './styles';
|
|
51
55
|
import { Fade, Placeholder, PlaceholderLine } from 'rn-placeholder';
|
|
52
56
|
import { FloatingButton } from '../FloatingButton';
|
|
@@ -115,7 +119,7 @@ const CheckoutUI = (props: any) => {
|
|
|
115
119
|
padding: 20
|
|
116
120
|
},
|
|
117
121
|
pagePadding: {
|
|
118
|
-
paddingHorizontal:
|
|
122
|
+
paddingHorizontal: 20
|
|
119
123
|
},
|
|
120
124
|
icon: {
|
|
121
125
|
top: 15,
|
|
@@ -124,13 +128,14 @@ const CheckoutUI = (props: any) => {
|
|
|
124
128
|
fontSize: 20
|
|
125
129
|
},
|
|
126
130
|
detailWrapper: {
|
|
127
|
-
paddingHorizontal:
|
|
131
|
+
paddingHorizontal: 20,
|
|
128
132
|
width: '100%'
|
|
129
133
|
},
|
|
130
134
|
wrapperNavbar: {
|
|
131
|
-
paddingVertical:
|
|
132
|
-
paddingHorizontal:
|
|
133
|
-
|
|
135
|
+
paddingVertical: 2,
|
|
136
|
+
paddingHorizontal: 20,
|
|
137
|
+
backgroundColor: theme?.colors?.white,
|
|
138
|
+
borderWidth: 0
|
|
134
139
|
}
|
|
135
140
|
})
|
|
136
141
|
|
|
@@ -163,7 +168,9 @@ const CheckoutUI = (props: any) => {
|
|
|
163
168
|
const [placeByMethodPay, setPlaceByMethodPay] = useState(false)
|
|
164
169
|
const [methodPaySupported, setMethodPaySupported] = useState({ enabled: false, message: null, loading: true })
|
|
165
170
|
const [paymethodClicked, setPaymethodClicked] = useState<any>(null)
|
|
171
|
+
const [showTitle, setShowTitle] = useState(false)
|
|
166
172
|
const [cardList, setCardList] = useState<any>({ cards: [], loading: false, error: null })
|
|
173
|
+
const containerRef = useRef<any>()
|
|
167
174
|
const cardsMethods = ['credomatic']
|
|
168
175
|
const stripePaymethods: any = ['stripe', 'stripe_direct', 'stripe_connect', 'stripe_redirect']
|
|
169
176
|
const placeSpotTypes = [3, 4, 5]
|
|
@@ -331,6 +338,10 @@ const CheckoutUI = (props: any) => {
|
|
|
331
338
|
setPhoneUpdate(val)
|
|
332
339
|
}
|
|
333
340
|
|
|
341
|
+
const handleScroll = ({ nativeEvent: { contentOffset } }: any) => {
|
|
342
|
+
setShowTitle(contentOffset.y > 30)
|
|
343
|
+
}
|
|
344
|
+
|
|
334
345
|
useEffect(() => {
|
|
335
346
|
if (validationFields && validationFields?.fields?.checkout) {
|
|
336
347
|
checkValidationFields()
|
|
@@ -391,11 +402,54 @@ const CheckoutUI = (props: any) => {
|
|
|
391
402
|
setLengthMore((e.nativeEvent.lines.length == 3 && e.nativeEvent.lines[2].width > WIDTH_SCREEN * .76) || e.nativeEvent.lines.length > 3)
|
|
392
403
|
}, [])
|
|
393
404
|
|
|
405
|
+
useEffect(() => {
|
|
406
|
+
if (!cartState?.loading && (cartState?.error || typeof cartState?.cart === 'string')) {
|
|
407
|
+
const error = cartState?.error || typeof cartState.cart === 'string' && cartState.cart
|
|
408
|
+
if (error) {
|
|
409
|
+
showToast(ToastType.Error, cartState?.error || cartState.cart)
|
|
410
|
+
navigation.navigate('BusinessList')
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
}, [cartState?.error, cartState?.cart, cartState?.loading])
|
|
414
|
+
|
|
415
|
+
useEffect(() => {
|
|
416
|
+
const keyboardDidShowListener = Keyboard.addListener('keyboardDidShow', () => {
|
|
417
|
+
containerRef?.current?.scrollToEnd && containerRef.current.scrollToEnd({ animated: true })
|
|
418
|
+
})
|
|
419
|
+
return () => {
|
|
420
|
+
keyboardDidShowListener.remove()
|
|
421
|
+
}
|
|
422
|
+
}, [])
|
|
423
|
+
|
|
394
424
|
return (
|
|
395
425
|
<>
|
|
396
|
-
<
|
|
426
|
+
<View style={styles.wrapperNavbar}>
|
|
427
|
+
<TopHeader>
|
|
428
|
+
<>
|
|
429
|
+
<TopActions onPress={() => onNavigationRedirect('BottomTab', { screen: 'Cart' }, !props.fromMulti)}>
|
|
430
|
+
<IconAntDesign
|
|
431
|
+
name='arrowleft'
|
|
432
|
+
size={26}
|
|
433
|
+
/>
|
|
434
|
+
</TopActions>
|
|
435
|
+
{showTitle && (
|
|
436
|
+
<OText
|
|
437
|
+
size={16}
|
|
438
|
+
style={{ flex: 1, textAlign: 'center', right: 15 }}
|
|
439
|
+
weight={Platform.OS === 'ios' ? '600' : 'bold'}
|
|
440
|
+
numberOfLines={2}
|
|
441
|
+
ellipsizeMode='tail'
|
|
442
|
+
>
|
|
443
|
+
{t('CHECKOUT', 'Checkout')}
|
|
444
|
+
</OText>
|
|
445
|
+
)}
|
|
446
|
+
</>
|
|
447
|
+
</TopHeader>
|
|
448
|
+
</View>
|
|
449
|
+
<Container forwardRef={containerRef} noPadding onScroll={handleScroll}>
|
|
397
450
|
<View style={styles.wrapperNavbar}>
|
|
398
451
|
<NavBar
|
|
452
|
+
hideArrowLeft
|
|
399
453
|
title={t('CHECKOUT', 'Checkout')}
|
|
400
454
|
titleAlign={'center'}
|
|
401
455
|
onActionLeft={() => onNavigationRedirect('BottomTab', { screen: 'Cart' }, !props.fromMulti)}
|
|
@@ -327,8 +327,8 @@ const MomentOptionUI = (props: MomentOptionParams) => {
|
|
|
327
327
|
<>
|
|
328
328
|
<Container
|
|
329
329
|
style={{
|
|
330
|
-
paddingLeft: !cateringPreorder || isPage ?
|
|
331
|
-
paddingRight: !cateringPreorder || isPage ?
|
|
330
|
+
paddingLeft: !cateringPreorder || isPage ? 20 : 0,
|
|
331
|
+
paddingRight: !cateringPreorder || isPage ? 20 : 0
|
|
332
332
|
}}
|
|
333
333
|
nestedScrollEnabled
|
|
334
334
|
>
|
|
@@ -467,7 +467,7 @@ const MomentOptionUI = (props: MomentOptionParams) => {
|
|
|
467
467
|
<Spinner visible={momentState.isLoading === 1} />
|
|
468
468
|
</Container>
|
|
469
469
|
{!isCart && !cateringPreorder && (
|
|
470
|
-
<View style={{ position: 'absolute', bottom: bottom, paddingBottom: 20, paddingHorizontal:
|
|
470
|
+
<View style={{ position: 'absolute', bottom: bottom, paddingBottom: 20, paddingHorizontal: 20, backgroundColor: 'white', width: '100%' }}>
|
|
471
471
|
<OButton onClick={() => handleChangeMoment()} isDisabled={!selectedTime} text={t('CONTINUE', 'Continue')} style={{ borderRadius: 7.6, height: 44, shadowOpacity: 0 }} textStyle={{ color: 'white', fontSize: 14 }} showNextIcon />
|
|
472
472
|
</View>
|
|
473
473
|
)}
|
|
@@ -19,6 +19,10 @@ export const OrderTimeWrapper = styled.View`
|
|
|
19
19
|
export const TimeListWrapper = styled.ScrollView`
|
|
20
20
|
margin-top: 30px;
|
|
21
21
|
max-height: 210px;
|
|
22
|
+
${({ cateringPreorder }: any) => cateringPreorder && css`
|
|
23
|
+
max-height: 250px;
|
|
24
|
+
height: 250px;
|
|
25
|
+
`}
|
|
22
26
|
`
|
|
23
27
|
|
|
24
28
|
export const TimeContentWrapper = styled.View`
|
|
@@ -26,6 +30,7 @@ export const TimeContentWrapper = styled.View`
|
|
|
26
30
|
flex-wrap: wrap;
|
|
27
31
|
flex-direction: row;
|
|
28
32
|
justify-content: space-between;
|
|
33
|
+
|
|
29
34
|
`
|
|
30
35
|
|
|
31
36
|
export const TimeItem = styled.View`
|
|
@@ -36,6 +41,16 @@ export const TimeItem = styled.View`
|
|
|
36
41
|
justify-content: center;
|
|
37
42
|
align-items: center;
|
|
38
43
|
margin: 10px 0px;
|
|
44
|
+
${({ cateringPreorder }: any) => cateringPreorder && css`
|
|
45
|
+
background: #fff;
|
|
46
|
+
width: 100%;
|
|
47
|
+
min-width: 100%;
|
|
48
|
+
height: 50px;
|
|
49
|
+
flex-direction: row;
|
|
50
|
+
justify-content: flex-start;
|
|
51
|
+
padding-left: 10px;
|
|
52
|
+
margin: 0;
|
|
53
|
+
`}
|
|
39
54
|
${({ active }: any) => active && css`
|
|
40
55
|
background: #F5F9FF;
|
|
41
56
|
`}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, { useState } from 'react';
|
|
1
|
+
import React, { useState, useRef } from 'react';
|
|
2
2
|
import { ActivityIndicator, View } from 'react-native'
|
|
3
3
|
import {
|
|
4
4
|
Cart,
|
|
@@ -56,6 +56,7 @@ const OrderSummaryUI = (props: any) => {
|
|
|
56
56
|
const [orderState] = useOrder();
|
|
57
57
|
const [{ parsePrice, parseNumber }] = useUtils();
|
|
58
58
|
const [validationFields] = useValidationFields();
|
|
59
|
+
const commentRef = useRef()
|
|
59
60
|
const [openTaxModal, setOpenTaxModal] = useState<any>({ open: false, data: null, type: '' })
|
|
60
61
|
const isCouponEnabled = validationFields?.fields?.checkout?.coupon?.enabled;
|
|
61
62
|
const hideCartComments = !validationFields?.fields?.checkout?.comments?.enabled
|
|
@@ -341,6 +342,7 @@ const OrderSummaryUI = (props: any) => {
|
|
|
341
342
|
marginTop: 10,
|
|
342
343
|
borderRadius: 8
|
|
343
344
|
}}
|
|
345
|
+
forwardRef={commentRef}
|
|
344
346
|
multiline
|
|
345
347
|
/>
|
|
346
348
|
{commentState?.loading && (
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { useSession, useOrder, useLanguage, useConfig } from 'ordering-components/native'
|
|
3
|
+
import { useTheme } from 'styled-components/native'
|
|
4
|
+
import { TouchableOpacity, View } from 'react-native'
|
|
5
|
+
import { OButton, OText } from '../shared';
|
|
6
|
+
import { Placeholder, PlaceholderLine, Fade } from 'rn-placeholder';
|
|
7
|
+
|
|
8
|
+
export const ActionButton = (props : any) => {
|
|
9
|
+
const {
|
|
10
|
+
navigation,
|
|
11
|
+
isHaveWeight,
|
|
12
|
+
isSoldOut,
|
|
13
|
+
maxProductQuantity,
|
|
14
|
+
productCart,
|
|
15
|
+
handleSaveProduct,
|
|
16
|
+
editMode,
|
|
17
|
+
product,
|
|
18
|
+
errors,
|
|
19
|
+
productAddedToCartLength,
|
|
20
|
+
handleRedirectLogin,
|
|
21
|
+
guestCheckoutEnabled,
|
|
22
|
+
orderTypeEnabled,
|
|
23
|
+
handleUpdateGuest,
|
|
24
|
+
actionStatus
|
|
25
|
+
} = props
|
|
26
|
+
const [,t] = useLanguage()
|
|
27
|
+
const [{ auth }] = useSession()
|
|
28
|
+
const [orderState] = useOrder()
|
|
29
|
+
const theme = useTheme()
|
|
30
|
+
const [{ configs }] = useConfig()
|
|
31
|
+
const unaddressedTypes = configs?.unaddressed_order_types_allowed?.value.split('|').map((value: any) => Number(value)) || []
|
|
32
|
+
const isAllowUnaddressOrderType = unaddressedTypes.includes(orderState?.options?.type)
|
|
33
|
+
|
|
34
|
+
const saveErrors =
|
|
35
|
+
orderState.loading ||
|
|
36
|
+
maxProductQuantity === 0 ||
|
|
37
|
+
Object.keys(errors)?.length > 0;
|
|
38
|
+
|
|
39
|
+
return (
|
|
40
|
+
<View
|
|
41
|
+
style={{
|
|
42
|
+
width: isHaveWeight ? '100%' : ((isSoldOut || maxProductQuantity <= 0) ? '60%' : '40%'),
|
|
43
|
+
}}>
|
|
44
|
+
{((productCart &&
|
|
45
|
+
auth &&
|
|
46
|
+
(orderState.options?.address_id || isAllowUnaddressOrderType)) || (isSoldOut || maxProductQuantity <= 0)) && (
|
|
47
|
+
<OButton
|
|
48
|
+
onClick={() => handleSaveProduct()}
|
|
49
|
+
imgRightSrc=""
|
|
50
|
+
text={`${orderState.loading
|
|
51
|
+
? t('LOADING', 'Loading')
|
|
52
|
+
: (isSoldOut || maxProductQuantity <= 0)
|
|
53
|
+
? t('SOLD_OUT', 'Sold out')
|
|
54
|
+
: editMode
|
|
55
|
+
? t('UPDATE', 'Update')
|
|
56
|
+
: t('ADD', 'Add')
|
|
57
|
+
}`}
|
|
58
|
+
isDisabled={isSoldOut || maxProductQuantity <= 0 || (product?.minimum_per_order && ((productCart?.quantity + productAddedToCartLength) < product?.minimum_per_order)) || (product?.maximum_per_order && ((productCart?.quantity + productAddedToCartLength) > product?.maximum_per_order))}
|
|
59
|
+
textStyle={{
|
|
60
|
+
color: saveErrors || isSoldOut || maxProductQuantity <= 0 ? theme.colors.primary : theme.colors.white,
|
|
61
|
+
fontSize: orderState.loading || editMode ? 10 : 14
|
|
62
|
+
}}
|
|
63
|
+
style={{
|
|
64
|
+
backgroundColor: saveErrors || isSoldOut || maxProductQuantity <= 0 || (product?.minimum_per_order && ((productCart?.quantity + productAddedToCartLength) < product?.minimum_per_order)) || (product?.maximum_per_order && ((productCart?.quantity + productAddedToCartLength) > product?.maximum_per_order)) ? theme.colors.lightGray : theme.colors.primary,
|
|
65
|
+
borderColor: saveErrors || isSoldOut || maxProductQuantity <= 0 || (product?.minimum_per_order && ((productCart?.quantity + productAddedToCartLength) < product?.minimum_per_order)) || (product?.maximum_per_order && ((productCart?.quantity + productAddedToCartLength) > product?.maximum_per_order)) ? theme.colors.white : theme.colors.primary,
|
|
66
|
+
opacity: saveErrors || isSoldOut || maxProductQuantity <= 0 ? 0.3 : 1,
|
|
67
|
+
borderRadius: 7.6,
|
|
68
|
+
height: 44,
|
|
69
|
+
shadowOpacity: 0,
|
|
70
|
+
borderWidth: 1,
|
|
71
|
+
marginTop: isHaveWeight ? 10 : 0
|
|
72
|
+
}}
|
|
73
|
+
/>
|
|
74
|
+
)}
|
|
75
|
+
{auth &&
|
|
76
|
+
!orderState.options?.address_id && !isAllowUnaddressOrderType &&
|
|
77
|
+
(orderState.loading ? (
|
|
78
|
+
<OButton
|
|
79
|
+
isDisabled
|
|
80
|
+
text={t('LOADING', 'Loading')}
|
|
81
|
+
imgRightSrc=""
|
|
82
|
+
textStyle={{ fontSize: 10 }}
|
|
83
|
+
/>
|
|
84
|
+
) : (
|
|
85
|
+
<OButton onClick={navigation.navigate('AddressList')} />
|
|
86
|
+
))}
|
|
87
|
+
{!auth && (
|
|
88
|
+
<OButton
|
|
89
|
+
isDisabled={isSoldOut || maxProductQuantity <= 0}
|
|
90
|
+
onClick={() => handleRedirectLogin()}
|
|
91
|
+
text={
|
|
92
|
+
isSoldOut || maxProductQuantity <= 0
|
|
93
|
+
? t('SOLD_OUT', 'Sold out')
|
|
94
|
+
: t('LOGIN_SIGNUP', 'Login / Sign Up')
|
|
95
|
+
}
|
|
96
|
+
imgRightSrc=""
|
|
97
|
+
textStyle={{ color: theme.colors.primary, fontSize: 13, textAlign: 'center' }}
|
|
98
|
+
style={{
|
|
99
|
+
height: 42,
|
|
100
|
+
borderColor: theme.colors.primary,
|
|
101
|
+
backgroundColor: theme.colors.white,
|
|
102
|
+
paddingLeft: 0,
|
|
103
|
+
paddingRight: 0
|
|
104
|
+
}}
|
|
105
|
+
/>
|
|
106
|
+
)}
|
|
107
|
+
{!auth && guestCheckoutEnabled && orderTypeEnabled && (
|
|
108
|
+
<TouchableOpacity style={{ marginTop: 10 }} onPress={handleUpdateGuest}>
|
|
109
|
+
{actionStatus?.loading ? (
|
|
110
|
+
<Placeholder Animation={Fade}>
|
|
111
|
+
<PlaceholderLine height={20} />
|
|
112
|
+
</Placeholder>
|
|
113
|
+
) : (
|
|
114
|
+
<OText color={theme.colors.primary} size={13} style={{ textAlign: 'center' }}>{t('AS_GUEST_USER', 'As guest user')}</OText>
|
|
115
|
+
)}
|
|
116
|
+
</TouchableOpacity>
|
|
117
|
+
)}
|
|
118
|
+
</View>
|
|
119
|
+
)
|
|
120
|
+
}
|
|
@@ -29,5 +29,15 @@ export const ORDER_TYPES = [
|
|
|
29
29
|
value: 5,
|
|
30
30
|
content: 'DRIVE_THRU',
|
|
31
31
|
description: 'ORDERTYPE_DESCRIPTION_DRIVETHRU',
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
value: 7,
|
|
35
|
+
content: 'CATERING_DELIVERY',
|
|
36
|
+
description: 'ORDERTYPE_DESCRIPTION_CATERING_DELIVERY',
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
value: 8,
|
|
40
|
+
content: 'CATERING_PICKUP',
|
|
41
|
+
description: 'ORDERTYPE_DESCRIPTION_CATERING_PICKUP',
|
|
32
42
|
}
|
|
33
43
|
]
|
|
@@ -550,13 +550,20 @@ export interface FloatingButtonParams {
|
|
|
550
550
|
}
|
|
551
551
|
export interface MomentOptionParams {
|
|
552
552
|
navigation: any;
|
|
553
|
-
isCart?: any;
|
|
554
553
|
nopadding?: boolean;
|
|
555
554
|
datesList: Array<any>;
|
|
556
555
|
hoursList: Array<any>;
|
|
557
556
|
dateSelected?: any;
|
|
558
557
|
timeSelected?: any;
|
|
559
558
|
isAsap?: boolean;
|
|
559
|
+
cateringPreorder?: boolean,
|
|
560
|
+
isCart?: boolean,
|
|
561
|
+
preorderLeadTime?: number,
|
|
562
|
+
business?: any,
|
|
563
|
+
getActualSchedule?: any,
|
|
564
|
+
preorderMaximumDays?: number,
|
|
565
|
+
preorderMinimumDays?: number,
|
|
566
|
+
isPage?: boolean,
|
|
560
567
|
handleAsap: () => {};
|
|
561
568
|
handleChangeDate: (value: any) => {};
|
|
562
569
|
handleChangeTime: (value: any) => {};
|