ordering-ui-react-native 0.20.7-release → 0.20.9-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/business/index.tsx +2 -0
- package/themes/business/src/components/NewOrderNotification/index.tsx +9 -2
- package/themes/business/src/components/OrderDetails/Delivery.tsx +5 -4
- package/themes/business/src/components/OrdersOption/index.tsx +44 -13
- package/themes/business/src/components/PreviousOrders/OrderItem.tsx +3 -4
- package/themes/business/src/components/Sessions/index.tsx +187 -0
- package/themes/business/src/components/Sessions/styles.tsx +20 -0
- package/themes/business/src/components/UserProfileForm/index.tsx +11 -0
- package/themes/business/src/hooks/useLocation.tsx +5 -4
- package/themes/business/src/types/index.tsx +9 -0
- package/themes/original/src/components/Cart/index.tsx +5 -1
- package/themes/original/src/components/CartContent/index.tsx +41 -39
- package/themes/original/src/components/Checkout/index.tsx +9 -4
- package/themes/original/src/components/MultiCheckout/index.tsx +86 -62
- package/themes/original/src/components/MultiOrdersDetails/index.tsx +1 -1
- package/themes/original/src/components/PaymentOptions/index.tsx +3 -0
- package/themes/original/src/components/ProductItemAccordion/index.tsx +7 -7
- package/themes/original/src/components/StripeElementsForm/index.tsx +3 -2
package/package.json
CHANGED
|
@@ -43,6 +43,7 @@ import { NewOrderNotification } from './src/components/NewOrderNotification';
|
|
|
43
43
|
import { DriverSchedule } from './src/components/DriverSchedule';
|
|
44
44
|
import { ScheduleBlocked } from './src/components/ScheduleBlocked';
|
|
45
45
|
import { OrderDetailsLogistic } from './src/components/OrderDetailsLogistic'
|
|
46
|
+
import { Sessions } from './src/components/Sessions';
|
|
46
47
|
//OComponents
|
|
47
48
|
import {
|
|
48
49
|
OText,
|
|
@@ -106,6 +107,7 @@ export {
|
|
|
106
107
|
ReviewCustomer,
|
|
107
108
|
SafeAreaContainerLayout,
|
|
108
109
|
SearchBar,
|
|
110
|
+
Sessions,
|
|
109
111
|
SignupForm,
|
|
110
112
|
StoresList,
|
|
111
113
|
UserFormDetailsUI,
|
|
@@ -20,7 +20,9 @@ import {
|
|
|
20
20
|
useEvent,
|
|
21
21
|
useLanguage,
|
|
22
22
|
useSession,
|
|
23
|
-
useConfig
|
|
23
|
+
useConfig,
|
|
24
|
+
useToast,
|
|
25
|
+
ToastType
|
|
24
26
|
} from 'ordering-components/native'
|
|
25
27
|
|
|
26
28
|
import { OIcon, OText } from '../shared'
|
|
@@ -108,11 +110,12 @@ const SoundPlayerComponent = (props: any) => {
|
|
|
108
110
|
|
|
109
111
|
const NewOrderNotificationUI = (props: any) => {
|
|
110
112
|
const { isBusinessApp, evtList } = props
|
|
111
|
-
|
|
113
|
+
const [, t] = useLanguage()
|
|
112
114
|
const [events] = useEvent()
|
|
113
115
|
const [{ user, token }] = useSession()
|
|
114
116
|
const [ordering] = useApi()
|
|
115
117
|
const [{ configs }] = useConfig()
|
|
118
|
+
const [, { showToast }] = useToast()
|
|
116
119
|
const { getCurrentLocation } = useLocation()
|
|
117
120
|
const [currentEvent, setCurrentEvent] = useState<any>(null)
|
|
118
121
|
|
|
@@ -124,6 +127,10 @@ const NewOrderNotificationUI = (props: any) => {
|
|
|
124
127
|
if (value?.driver) {
|
|
125
128
|
try {
|
|
126
129
|
const location = await getCurrentLocation()
|
|
130
|
+
if (!location?.latitude || !location?.longitude) {
|
|
131
|
+
showToast(t('ERROR_UPDATING_COORDS', 'Error updating coords'), ToastType.Error)
|
|
132
|
+
return
|
|
133
|
+
}
|
|
127
134
|
await fetch(`${ordering.root}/users/${user.id}/locations`, {
|
|
128
135
|
method: 'POST',
|
|
129
136
|
body: JSON.stringify({
|
|
@@ -64,6 +64,7 @@ export const OrderDetailsUI = (props: OrderDetailsParams) => {
|
|
|
64
64
|
|
|
65
65
|
const { order } = props.order
|
|
66
66
|
|
|
67
|
+
const hideTimer = configs?.hidden_driver_eta_time?.value === '1'
|
|
67
68
|
const isAllowedDriverRejectOrder = configs?.allow_driver_reject_order?.value === '1'
|
|
68
69
|
const isHideRejectButtons = configs?.reject_orders_enabled && configs?.reject_orders_enabled?.value !== '1'
|
|
69
70
|
const theme = useTheme();
|
|
@@ -583,7 +584,7 @@ export const OrderDetailsUI = (props: OrderDetailsParams) => {
|
|
|
583
584
|
secondButton={true}
|
|
584
585
|
firstColorCustom={theme.colors.red}
|
|
585
586
|
secondColorCustom={theme.colors.green}
|
|
586
|
-
widthButton={isHideRejectButtons ? '100%': '45%'}
|
|
587
|
+
widthButton={isHideRejectButtons ? '100%' : '45%'}
|
|
587
588
|
isHideRejectButtons={isHideRejectButtons}
|
|
588
589
|
/>
|
|
589
590
|
)}
|
|
@@ -603,7 +604,7 @@ export const OrderDetailsUI = (props: OrderDetailsParams) => {
|
|
|
603
604
|
secondButton={true}
|
|
604
605
|
firstColorCustom={theme.colors.red}
|
|
605
606
|
secondColorCustom={theme.colors.green}
|
|
606
|
-
widthButton={isHideRejectButtons ? '100%': '45%'}
|
|
607
|
+
widthButton={isHideRejectButtons ? '100%' : '45%'}
|
|
607
608
|
isHideRejectButtons={isHideRejectButtons}
|
|
608
609
|
/>
|
|
609
610
|
</>
|
|
@@ -612,13 +613,13 @@ export const OrderDetailsUI = (props: OrderDetailsParams) => {
|
|
|
612
613
|
<FloatingButton
|
|
613
614
|
btnText={t('REJECT', 'Reject')}
|
|
614
615
|
isSecondaryBtn={false}
|
|
615
|
-
secondButtonClick={() => (order?.isLogistic && (order?.order_group || logisticOrderStatus.includes(order?.status))) ? handleAcceptLogisticOrder(order) : handleViewActionOrder('accept')}
|
|
616
|
+
secondButtonClick={() => hideTimer ? handleChangeOrderStatus && handleChangeOrderStatus(8) : (order?.isLogistic && (order?.order_group || logisticOrderStatus.includes(order?.status))) ? handleAcceptLogisticOrder(order) : handleViewActionOrder('accept')}
|
|
616
617
|
firstButtonClick={() => order?.isLogistic && (order?.order_group || logisticOrderStatus.includes(order?.status)) ? handleRejectLogisticOrder() : handleViewActionOrder('reject')}
|
|
617
618
|
secondBtnText={t('ACCEPT', 'Accept')}
|
|
618
619
|
secondButton={true}
|
|
619
620
|
firstColorCustom={theme.colors.red}
|
|
620
621
|
secondColorCustom={theme.colors.green}
|
|
621
|
-
widthButton={isHideRejectButtons ? '100%': '45%'}
|
|
622
|
+
widthButton={isHideRejectButtons ? '100%' : '45%'}
|
|
622
623
|
isHideRejectButtons={isHideRejectButtons}
|
|
623
624
|
/>
|
|
624
625
|
)}
|
|
@@ -50,6 +50,7 @@ const { useDeviceOrientation, PORTRAIT } = DeviceOrientationMethods
|
|
|
50
50
|
|
|
51
51
|
const OrdersOptionUI = (props: OrdersOptionParams) => {
|
|
52
52
|
const {
|
|
53
|
+
navigation,
|
|
53
54
|
setCurrentFilters,
|
|
54
55
|
tabs,
|
|
55
56
|
currentTabSelected,
|
|
@@ -123,6 +124,7 @@ const OrdersOptionUI = (props: OrdersOptionParams) => {
|
|
|
123
124
|
backColor: '#E63757'
|
|
124
125
|
}
|
|
125
126
|
]
|
|
127
|
+
const combineTabs = configState?.configs?.combine_pending_and_progress_orders?.value === '1'
|
|
126
128
|
const [selectedTabStatus, setSelectedTabStatus] = useState<any>(deliveryStatus)
|
|
127
129
|
const [openedSelect, setOpenedSelect] = useState('')
|
|
128
130
|
|
|
@@ -384,6 +386,13 @@ const OrdersOptionUI = (props: OrdersOptionParams) => {
|
|
|
384
386
|
setTags({ values: [] })
|
|
385
387
|
}, [currentTabSelected])
|
|
386
388
|
|
|
389
|
+
useEffect(() => {
|
|
390
|
+
const unsubcribe = navigation.addListener('focus', () => {
|
|
391
|
+
currentTabSelected === 'logisticOrders' ? loadLogisticOrders() : loadOrders && loadOrders({ newFetch: true })
|
|
392
|
+
})
|
|
393
|
+
return unsubcribe
|
|
394
|
+
}, [navigation, loadOrders, loadLogisticOrders])
|
|
395
|
+
|
|
387
396
|
return (
|
|
388
397
|
<>
|
|
389
398
|
<View style={styles.header}>
|
|
@@ -467,7 +476,7 @@ const OrdersOptionUI = (props: OrdersOptionParams) => {
|
|
|
467
476
|
nestedScrollEnabled={true}
|
|
468
477
|
>
|
|
469
478
|
<TabsContainer>
|
|
470
|
-
{(isLogisticActivated && !isBusinessApp) && (
|
|
479
|
+
{(isLogisticActivated && !isBusinessApp && !combineTabs) && (
|
|
471
480
|
<Pressable
|
|
472
481
|
style={styles.pressable}
|
|
473
482
|
onPress={() => setCurrentTabSelected('logisticOrders')}>
|
|
@@ -974,7 +983,9 @@ export const Timer = () => {
|
|
|
974
983
|
|
|
975
984
|
export const OrdersOption = (props: OrdersOptionParams) => {
|
|
976
985
|
const [, t] = useLanguage();
|
|
986
|
+
const [configState] = useConfig()
|
|
977
987
|
const [checkNotificationStatus, setCheckNotificationStatus] = useState({ open: false, checked: false })
|
|
988
|
+
const combineTabs = configState?.configs?.combine_pending_and_progress_orders?.value === '1'
|
|
978
989
|
const ordersProps = {
|
|
979
990
|
...props,
|
|
980
991
|
UIComponent: OrdersOptionUI,
|
|
@@ -1061,32 +1072,52 @@ export const OrdersOption = (props: OrdersOptionParams) => {
|
|
|
1061
1072
|
text: t('ORDER_DRIVER_ON_WAY', 'Driver on way')
|
|
1062
1073
|
}
|
|
1063
1074
|
],
|
|
1064
|
-
tabs: [
|
|
1075
|
+
tabs: combineTabs ? [
|
|
1065
1076
|
{
|
|
1066
1077
|
key: 0,
|
|
1067
|
-
text: t('
|
|
1068
|
-
tags: props?.orderGroupStatusCustom?.
|
|
1069
|
-
title: '
|
|
1078
|
+
text: t('ACTIVE', 'Active'),
|
|
1079
|
+
tags: props?.orderGroupStatusCustom?.active ?? [0, 3, 4, 7, 8, 9, 13, 14, 18, 19, 20, 21, 22, 23],
|
|
1080
|
+
title: 'active',
|
|
1070
1081
|
},
|
|
1071
1082
|
{
|
|
1072
1083
|
key: 1,
|
|
1073
|
-
text: t('IN_PROGRESS', 'In Progress'),
|
|
1074
|
-
tags: props?.orderGroupStatusCustom?.inProgress ?? [3, 4, 7, 8, 9, 14, 18, 19, 20, 21, 22, 23],
|
|
1075
|
-
title: 'inProgress',
|
|
1076
|
-
},
|
|
1077
|
-
{
|
|
1078
|
-
key: 2,
|
|
1079
1084
|
text: t('COMPLETED', 'Completed'),
|
|
1080
1085
|
tags: props?.orderGroupStatusCustom?.completed ?? [1, 11, 15],
|
|
1081
1086
|
title: 'completed',
|
|
1082
1087
|
},
|
|
1083
1088
|
{
|
|
1084
|
-
key:
|
|
1089
|
+
key: 2,
|
|
1085
1090
|
text: t('CANCELLED', 'Cancelled'),
|
|
1086
1091
|
tags: props?.orderGroupStatusCustom?.cancelled ?? [2, 5, 6, 10, 12, 16, 17],
|
|
1087
1092
|
title: 'cancelled',
|
|
1088
1093
|
},
|
|
1089
|
-
]
|
|
1094
|
+
] :
|
|
1095
|
+
[
|
|
1096
|
+
{
|
|
1097
|
+
key: 0,
|
|
1098
|
+
text: t('PENDING', 'Pending'),
|
|
1099
|
+
tags: props?.orderGroupStatusCustom?.pending ?? [0, 13],
|
|
1100
|
+
title: 'pending'
|
|
1101
|
+
},
|
|
1102
|
+
{
|
|
1103
|
+
key: 1,
|
|
1104
|
+
text: t('IN_PROGRESS', 'In Progress'),
|
|
1105
|
+
tags: props?.orderGroupStatusCustom?.inProgress ?? [3, 4, 7, 8, 9, 14, 18, 19, 20, 21, 22, 23],
|
|
1106
|
+
title: 'inProgress',
|
|
1107
|
+
},
|
|
1108
|
+
{
|
|
1109
|
+
key: 2,
|
|
1110
|
+
text: t('COMPLETED', 'Completed'),
|
|
1111
|
+
tags: props?.orderGroupStatusCustom?.completed ?? [1, 11, 15],
|
|
1112
|
+
title: 'completed',
|
|
1113
|
+
},
|
|
1114
|
+
{
|
|
1115
|
+
key: 3,
|
|
1116
|
+
text: t('CANCELLED', 'Cancelled'),
|
|
1117
|
+
tags: props?.orderGroupStatusCustom?.cancelled ?? [2, 5, 6, 10, 12, 16, 17],
|
|
1118
|
+
title: 'cancelled',
|
|
1119
|
+
},
|
|
1120
|
+
]
|
|
1090
1121
|
};
|
|
1091
1122
|
|
|
1092
1123
|
return (<>
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React, { useEffect, useState } from 'react';
|
|
2
|
-
import { Platform, PlatformIOSStatic,
|
|
2
|
+
import { Platform, PlatformIOSStatic, Pressable, StyleSheet, View } from 'react-native';
|
|
3
3
|
import DeviceInfo from 'react-native-device-info';
|
|
4
4
|
import { useTheme } from 'styled-components/native';
|
|
5
5
|
import { useLanguage, useUtils, useConfig } from 'ordering-components/native';
|
|
@@ -138,8 +138,7 @@ export const OrderItem = React.memo((props: any) => {
|
|
|
138
138
|
}, [configState.loading])
|
|
139
139
|
|
|
140
140
|
return (
|
|
141
|
-
<
|
|
142
|
-
activeOpacity={1}
|
|
141
|
+
<Pressable
|
|
143
142
|
disabled={order?.locked && isLogisticOrder}
|
|
144
143
|
style={styles.cardButton}
|
|
145
144
|
onPress={() => handlePressOrder({ ...order, logistic_order_id: _order?.id })}
|
|
@@ -237,6 +236,6 @@ export const OrderItem = React.memo((props: any) => {
|
|
|
237
236
|
)}
|
|
238
237
|
</Information>
|
|
239
238
|
</Card>
|
|
240
|
-
</
|
|
239
|
+
</Pressable>
|
|
241
240
|
)
|
|
242
241
|
}, OrderItemPropsAreEqual)
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
import React, { useState } from 'react'
|
|
2
|
+
import { View, TouchableOpacity, Platform, StyleSheet } from 'react-native'
|
|
3
|
+
import { useLanguage, useSession, useUtils, Sessions as SessionsController } from 'ordering-components/native'
|
|
4
|
+
import { SessionsParams } from '../../types'
|
|
5
|
+
import { OAlert } from '../../../../../src/components/shared'
|
|
6
|
+
import { OButton, OIcon, OText } from '../shared'
|
|
7
|
+
import { useTheme } from 'styled-components/native'
|
|
8
|
+
import { Fade, Placeholder, PlaceholderLine } from 'rn-placeholder'
|
|
9
|
+
import AntIcon from 'react-native-vector-icons/AntDesign'
|
|
10
|
+
|
|
11
|
+
import {
|
|
12
|
+
SessionsWrapper,
|
|
13
|
+
SessionItem,
|
|
14
|
+
DurationWrapper,
|
|
15
|
+
Container
|
|
16
|
+
} from './styles'
|
|
17
|
+
|
|
18
|
+
export const SessionsUI = (props: SessionsParams) => {
|
|
19
|
+
const {
|
|
20
|
+
navigation,
|
|
21
|
+
sessionsList,
|
|
22
|
+
actionState,
|
|
23
|
+
handleDeleteSession,
|
|
24
|
+
handleDeleteAllSessions
|
|
25
|
+
} = props
|
|
26
|
+
|
|
27
|
+
const [, t] = useLanguage()
|
|
28
|
+
const [{ user }] = useSession()
|
|
29
|
+
const [{ parseDate }] = useUtils()
|
|
30
|
+
const theme = useTheme()
|
|
31
|
+
const [confirm, setConfirm] = useState<any>({ open: false, content: null, handleOnAccept: null, id: null, title: null })
|
|
32
|
+
const goToBack = () => navigation?.canGoBack() && navigation.goBack()
|
|
33
|
+
|
|
34
|
+
const onDeleteSession = (session: any) => {
|
|
35
|
+
setConfirm({
|
|
36
|
+
open: true,
|
|
37
|
+
title: t('WEB_APPNAME', 'Ordering'),
|
|
38
|
+
content: [t('QUESTION_DELETE_SESSION', 'Are you sure to delete this session?')],
|
|
39
|
+
handleOnAccept: () => {
|
|
40
|
+
handleDeleteSession(session)
|
|
41
|
+
setConfirm({ ...confirm, open: false })
|
|
42
|
+
}
|
|
43
|
+
})
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const onDeleteAllSessions = (isOldUser: any, deleteCurrent: any) => {
|
|
47
|
+
setConfirm({
|
|
48
|
+
open: true,
|
|
49
|
+
title: t('WEB_APPNAME', 'Ordering'),
|
|
50
|
+
content:
|
|
51
|
+
isOldUser
|
|
52
|
+
? [t('QUESTION_ENABLE_ALL_SESSIONS', 'Are you sure to enable all sessions?')]
|
|
53
|
+
: deleteCurrent
|
|
54
|
+
? [t('QUESTION_DELETE_ALL_SESSIONS', 'Are you sure that you want to delete all sessions?')]
|
|
55
|
+
: [t('QUESTION_DELETE_ALL_SESSIONS_EXCEPT_CURRENT', 'Are you sure that you want to delete all sessions except current?')],
|
|
56
|
+
handleOnAccept: () => {
|
|
57
|
+
handleDeleteAllSessions(deleteCurrent)
|
|
58
|
+
setConfirm({ ...confirm, open: false })
|
|
59
|
+
}
|
|
60
|
+
})
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const styles = StyleSheet.create({
|
|
64
|
+
titleGroups: {
|
|
65
|
+
alignItems: 'center',
|
|
66
|
+
flexDirection: 'row',
|
|
67
|
+
minHeight: 33,
|
|
68
|
+
},
|
|
69
|
+
btnBackArrow: {
|
|
70
|
+
borderWidth: 0,
|
|
71
|
+
width: 32,
|
|
72
|
+
height: 32,
|
|
73
|
+
tintColor: theme.colors.textGray,
|
|
74
|
+
backgroundColor: theme.colors.clear,
|
|
75
|
+
borderColor: theme.colors.clear,
|
|
76
|
+
shadowColor: theme.colors.clear,
|
|
77
|
+
paddingLeft: 0,
|
|
78
|
+
paddingRight: 0,
|
|
79
|
+
marginTop: Platform.OS === 'ios' ? 30 : 10
|
|
80
|
+
},
|
|
81
|
+
innerPadding: {
|
|
82
|
+
paddingLeft: 10,
|
|
83
|
+
paddingRight: 10
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
return (
|
|
88
|
+
<Container
|
|
89
|
+
pdng={Platform.OS === 'ios' ? '10px' : '8px'}
|
|
90
|
+
style={styles.innerPadding}
|
|
91
|
+
>
|
|
92
|
+
<View style={styles.titleGroups}>
|
|
93
|
+
<TouchableOpacity onPress={() => goToBack()} style={styles.btnBackArrow}>
|
|
94
|
+
<OIcon src={theme.images.general.arrow_left} color={theme.colors.textGray} />
|
|
95
|
+
</TouchableOpacity>
|
|
96
|
+
</View>
|
|
97
|
+
<OText size={24} style={{ paddingTop: 12 }}>
|
|
98
|
+
{t('SESSIONS', 'Sessions')}
|
|
99
|
+
</OText>
|
|
100
|
+
{user?.session_strategy === 'jwt_session' ? (
|
|
101
|
+
<>
|
|
102
|
+
{sessionsList.loading ? (
|
|
103
|
+
[...Array(5).keys()].map(i => (
|
|
104
|
+
<SessionItem key={i}>
|
|
105
|
+
<Placeholder Animation={Fade}>
|
|
106
|
+
<View style={{ flexDirection: 'row', alignItems: 'center' }}>
|
|
107
|
+
<View style={{ flex: 1 }}>
|
|
108
|
+
<PlaceholderLine width={40} />
|
|
109
|
+
<PlaceholderLine width={40} />
|
|
110
|
+
</View>
|
|
111
|
+
<PlaceholderLine width={5} />
|
|
112
|
+
</View>
|
|
113
|
+
</Placeholder>
|
|
114
|
+
</SessionItem>
|
|
115
|
+
))
|
|
116
|
+
) : (
|
|
117
|
+
sessionsList.sessions.length > 0 ? (
|
|
118
|
+
<SessionsWrapper>
|
|
119
|
+
{sessionsList.sessions.reverse().map((session: any) => (
|
|
120
|
+
<SessionItem key={session.id}>
|
|
121
|
+
<DurationWrapper>
|
|
122
|
+
<OText>{parseDate(session.created_at)}</OText>
|
|
123
|
+
<OText>{parseDate(session.valid_thru)}</OText>
|
|
124
|
+
</DurationWrapper>
|
|
125
|
+
{session.current && (
|
|
126
|
+
<OText mLeft={15} style={{ flex: 1 }}>({t('CURRENT', 'Current')})</OText>
|
|
127
|
+
)}
|
|
128
|
+
<TouchableOpacity
|
|
129
|
+
onPress={() => onDeleteSession(session)}
|
|
130
|
+
>
|
|
131
|
+
<AntIcon name='close' size={16} color={theme.colors.red} />
|
|
132
|
+
</TouchableOpacity>
|
|
133
|
+
</SessionItem>
|
|
134
|
+
))}
|
|
135
|
+
<OButton
|
|
136
|
+
text={t('DELETE_ALL_SESSIONS', 'Delete all sessions')}
|
|
137
|
+
isDisabled={actionState.loading}
|
|
138
|
+
textStyle={{ color: theme.colors.white, fontSize: 14 }}
|
|
139
|
+
onClick={() => onDeleteAllSessions(false, true)}
|
|
140
|
+
style={{ borderRadius: 7.6, marginTop: 30 }}
|
|
141
|
+
/>
|
|
142
|
+
<OButton
|
|
143
|
+
text={t('DELETE_ALL_SESSIONS_EXCEPT_CURRENT', 'Delete all sessions except current')}
|
|
144
|
+
isDisabled={actionState.loading}
|
|
145
|
+
textStyle={{ color: theme.colors.white, fontSize: 14 }}
|
|
146
|
+
onClick={() => onDeleteAllSessions(false, false)}
|
|
147
|
+
style={{ borderRadius: 7.6, marginTop: 20 }}
|
|
148
|
+
/>
|
|
149
|
+
</SessionsWrapper>
|
|
150
|
+
) : (
|
|
151
|
+
<OText>{t('YOU_DONT_HAVE_ANY_SESSIONS', 'You don\'t have any sessions')}</OText>
|
|
152
|
+
)
|
|
153
|
+
)}
|
|
154
|
+
</>
|
|
155
|
+
) : (
|
|
156
|
+
<View>
|
|
157
|
+
<OText>
|
|
158
|
+
{t('YOU_DONT_HAVE_ENABLED_THE_SESSIONS', 'You don\'t have enabled the sessions, please active them to have a better control of your sessions.')}
|
|
159
|
+
</OText>
|
|
160
|
+
<OButton
|
|
161
|
+
text={t('ACTIVE_SESSIONS', 'Active sessions')}
|
|
162
|
+
isDisabled={actionState.loading}
|
|
163
|
+
textStyle={{ color: theme.colors.white, fontSize: 14 }}
|
|
164
|
+
onClick={() => onDeleteAllSessions(true, false)}
|
|
165
|
+
style={{ borderRadius: 7.6, marginTop: 20 }}
|
|
166
|
+
/>
|
|
167
|
+
</View>
|
|
168
|
+
)}
|
|
169
|
+
<OAlert
|
|
170
|
+
open={confirm.open}
|
|
171
|
+
title={confirm.title}
|
|
172
|
+
content={confirm.content}
|
|
173
|
+
onAccept={confirm.handleOnAccept}
|
|
174
|
+
onCancel={() => setConfirm({ ...confirm, open: false, title: null })}
|
|
175
|
+
onClose={() => setConfirm({ ...confirm, open: false, title: null })}
|
|
176
|
+
/>
|
|
177
|
+
</Container>
|
|
178
|
+
)
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
export const Sessions = (props: SessionsParams) => {
|
|
182
|
+
const sessionsProps = {
|
|
183
|
+
...props,
|
|
184
|
+
UIComponent: SessionsUI
|
|
185
|
+
}
|
|
186
|
+
return <SessionsController {...sessionsProps} />
|
|
187
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import styled from 'styled-components/native'
|
|
2
|
+
|
|
3
|
+
export const SessionsWrapper = styled.View`
|
|
4
|
+
`
|
|
5
|
+
export const SessionItem = styled.View`
|
|
6
|
+
flex-direction: row;
|
|
7
|
+
align-items: center;
|
|
8
|
+
justify-content: space-between;
|
|
9
|
+
padding-vertical: 15px;
|
|
10
|
+
border-bottom-color: ${(props: any) => props.theme.colors.lightGray};
|
|
11
|
+
border-bottom-width: 1px;
|
|
12
|
+
`
|
|
13
|
+
export const DurationWrapper = styled.View`
|
|
14
|
+
/* flex-direction: row; */
|
|
15
|
+
`
|
|
16
|
+
|
|
17
|
+
export const Container = styled.View`
|
|
18
|
+
padding-top: ${(props: any) => props.pdng};
|
|
19
|
+
margin-bottom: 50px;
|
|
20
|
+
`
|
|
@@ -513,6 +513,17 @@ const ProfileUI = (props: ProfileParams) => {
|
|
|
513
513
|
marginTop: 10
|
|
514
514
|
}} />
|
|
515
515
|
</Pressable>
|
|
516
|
+
<Pressable style={{ marginBottom: 10 }} onPress={() => navigation.navigate('Sessions')}>
|
|
517
|
+
<View style={{ flexDirection: 'row', justifyContent: 'space-between' }}>
|
|
518
|
+
<OText size={16}>{t('SESSIONS', 'Sessions')}</OText>
|
|
519
|
+
<AntDesignIcon size={18} name='right' />
|
|
520
|
+
</View>
|
|
521
|
+
<View style={{
|
|
522
|
+
borderBottomColor: theme.colors.tabBar,
|
|
523
|
+
borderBottomWidth: 1,
|
|
524
|
+
marginTop: 10
|
|
525
|
+
}} />
|
|
526
|
+
</Pressable>
|
|
516
527
|
<Actions>
|
|
517
528
|
<LanguageSelector />
|
|
518
529
|
|
|
@@ -48,8 +48,8 @@ export const useLocation = () => {
|
|
|
48
48
|
GeoLocation.getCurrentPosition(
|
|
49
49
|
({ coords }) => {
|
|
50
50
|
resolve({
|
|
51
|
-
latitude: coords.latitude,
|
|
52
|
-
longitude: coords.longitude,
|
|
51
|
+
latitude: typeof coords.latitude !== 'number' && !Number.isNaN(coords.latitude) ? coords.latitude : 0,
|
|
52
|
+
longitude: typeof coords.longitude !== 'number' && !Number.isNaN(coords.longitude) ? coords.longitude : 0,
|
|
53
53
|
speed: coords.speed,
|
|
54
54
|
});
|
|
55
55
|
},
|
|
@@ -63,9 +63,10 @@ export const useLocation = () => {
|
|
|
63
63
|
watchId.current = GeoLocation.watchPosition(
|
|
64
64
|
({ coords }) => {
|
|
65
65
|
if (!isMounted.current) return;
|
|
66
|
+
if (typeof coords.latitude !== 'number' || typeof coords.longitude !== 'number') return
|
|
66
67
|
const location: Location = {
|
|
67
|
-
latitude: coords.latitude,
|
|
68
|
-
longitude: coords.longitude,
|
|
68
|
+
latitude: coords.latitude || 0,
|
|
69
|
+
longitude: coords.longitude || 0,
|
|
69
70
|
speed: coords.speed,
|
|
70
71
|
};
|
|
71
72
|
setUserLocation(location);
|
|
@@ -303,6 +303,7 @@ export interface OrdersOptionParams {
|
|
|
303
303
|
filtered?: any;
|
|
304
304
|
handleClickOrder?: any;
|
|
305
305
|
orderGroupStatusCustom?: {
|
|
306
|
+
active?: Array<number>;
|
|
306
307
|
pending?: Array<number>;
|
|
307
308
|
inProgress?: Array<number>;
|
|
308
309
|
completed?: Array<number>;
|
|
@@ -629,3 +630,11 @@ export interface OrderDetailsLogisticParams {
|
|
|
629
630
|
orderAssingId: number,
|
|
630
631
|
order: any
|
|
631
632
|
}
|
|
633
|
+
|
|
634
|
+
export interface SessionsParams {
|
|
635
|
+
navigation: any,
|
|
636
|
+
sessionsList: any,
|
|
637
|
+
actionState: any,
|
|
638
|
+
handleDeleteSession: any,
|
|
639
|
+
handleDeleteAllSessions: any
|
|
640
|
+
}
|
|
@@ -200,7 +200,11 @@ const CartUI = (props: any) => {
|
|
|
200
200
|
if (cart?.business_id) {
|
|
201
201
|
setOpenUpselling(true)
|
|
202
202
|
} else {
|
|
203
|
-
|
|
203
|
+
onNavigationRedirect('CheckoutNavigator', {
|
|
204
|
+
screen: 'CheckoutPage',
|
|
205
|
+
cartUuid: cart?.uuid,
|
|
206
|
+
cartTotal: cart?.total
|
|
207
|
+
}, true)
|
|
204
208
|
}
|
|
205
209
|
}
|
|
206
210
|
|
|
@@ -135,53 +135,55 @@ export const CartContent = (props: any) => {
|
|
|
135
135
|
{isMultiCheckout && (
|
|
136
136
|
<>
|
|
137
137
|
{!!cartsAvailable.length && (
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
<OText size={14} lineHeight={24} color={theme.colors.textNormal} weight={'400'}>
|
|
142
|
-
{t('TOTAL_DELIVERY_FEE', 'Total delivery fee')}
|
|
143
|
-
</OText>
|
|
144
|
-
<OText size={14} lineHeight={24} color={theme.colors.textNormal} weight={'400'}>
|
|
145
|
-
{parsePrice(totalCartsFee)}
|
|
146
|
-
</OText>
|
|
147
|
-
</View>
|
|
148
|
-
)}
|
|
149
|
-
{cartsAvailable.reduce((sum: any, cart: any) => sum + cart?.driver_tip, 0) > 0 &&
|
|
150
|
-
configs?.multi_business_checkout_show_combined_driver_tip?.value === '1' && (
|
|
138
|
+
<>
|
|
139
|
+
<ChCartsTotal>
|
|
140
|
+
{!!totalCartsFee && configs?.multi_business_checkout_show_combined_delivery_fee?.value === '1' && (
|
|
151
141
|
<View style={{ flexDirection: 'row', justifyContent: 'space-between' }}>
|
|
152
142
|
<OText size={14} lineHeight={24} color={theme.colors.textNormal} weight={'400'}>
|
|
153
|
-
{t('
|
|
143
|
+
{t('TOTAL_DELIVERY_FEE', 'Total delivery fee')}
|
|
154
144
|
</OText>
|
|
155
145
|
<OText size={14} lineHeight={24} color={theme.colors.textNormal} weight={'400'}>
|
|
156
|
-
{parsePrice(
|
|
146
|
+
{parsePrice(totalCartsFee)}
|
|
157
147
|
</OText>
|
|
158
148
|
</View>
|
|
159
149
|
)}
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
150
|
+
{cartsAvailable.reduce((sum: any, cart: any) => sum + cart?.driver_tip, 0) > 0 &&
|
|
151
|
+
configs?.multi_business_checkout_show_combined_driver_tip?.value === '1' && (
|
|
152
|
+
<View style={{ flexDirection: 'row', justifyContent: 'space-between' }}>
|
|
153
|
+
<OText size={14} lineHeight={24} color={theme.colors.textNormal} weight={'400'}>
|
|
154
|
+
{t('DRIVER_TIP', 'Driver tip')}
|
|
155
|
+
</OText>
|
|
156
|
+
<OText size={14} lineHeight={24} color={theme.colors.textNormal} weight={'400'}>
|
|
157
|
+
{parsePrice(cartsAvailable.reduce((sum: any, cart: any) => sum + cart?.driver_tip, 0))}
|
|
158
|
+
</OText>
|
|
159
|
+
</View>
|
|
160
|
+
)}
|
|
161
|
+
<View style={{ flexDirection: 'row', justifyContent: 'space-between' }}>
|
|
162
|
+
<OText size={16} lineHeight={24} color={theme.colors.textNormal} weight={'500'}>
|
|
163
|
+
{t('TOTAL_FOR_ALL_CARTS', 'Total for all Carts')}
|
|
164
|
+
</OText>
|
|
165
|
+
<OText size={16} lineHeight={24} color={theme.colors.textNormal} weight={'500'}>{parsePrice(totalCartsPrice)}</OText>
|
|
166
|
+
</View>
|
|
167
|
+
<View style={{ flexDirection: 'row', justifyContent: 'center', marginVertical: 20 }}>
|
|
168
|
+
<OText size={14} color={theme.colors.textNormal} weight={'300'} style={{ textAlign: 'center' }}>
|
|
169
|
+
{t('CART_GROUP_MESSAGE_ALERT', 'Discounts may be applied at the time of payment for this group.')}
|
|
170
|
+
</OText>
|
|
171
|
+
</View>
|
|
172
|
+
</ChCartsTotal>
|
|
173
|
+
<CheckoutAction style={{ marginTop: 0 }}>
|
|
174
|
+
<OButton
|
|
175
|
+
text={t('CHECKOUT', 'Checkout')}
|
|
176
|
+
bgColor={!cartsAvailable.length ? theme.colors.secundary : theme.colors.primary}
|
|
177
|
+
isDisabled={!cartsAvailable.length}
|
|
178
|
+
borderColor={theme.colors.primary}
|
|
179
|
+
imgRightSrc={null}
|
|
180
|
+
textStyle={{ color: 'white', textAlign: 'center', flex: 1 }}
|
|
181
|
+
onClick={() => handleCheckoutRedirect()}
|
|
182
|
+
style={{ width: '100%', flexDirection: 'row', justifyContent: 'center', borderRadius: 7.6, shadowOpacity: 0 }}
|
|
183
|
+
/>
|
|
184
|
+
</CheckoutAction>
|
|
185
|
+
</>
|
|
172
186
|
)}
|
|
173
|
-
<CheckoutAction style={{ marginTop: 0 }}>
|
|
174
|
-
<OButton
|
|
175
|
-
text={t('CHECKOUT', 'Checkout')}
|
|
176
|
-
bgColor={!cartsAvailable.length ? theme.colors.secundary : theme.colors.primary}
|
|
177
|
-
isDisabled={!cartsAvailable.length}
|
|
178
|
-
borderColor={theme.colors.primary}
|
|
179
|
-
imgRightSrc={null}
|
|
180
|
-
textStyle={{ color: 'white', textAlign: 'center', flex: 1 }}
|
|
181
|
-
onClick={() => handleCheckoutRedirect()}
|
|
182
|
-
style={{ width: '100%', flexDirection: 'row', justifyContent: 'center', borderRadius: 7.6, shadowOpacity: 0 }}
|
|
183
|
-
/>
|
|
184
|
-
</CheckoutAction>
|
|
185
187
|
</>
|
|
186
188
|
)}
|
|
187
189
|
</>
|
|
@@ -5,6 +5,7 @@ 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
7
|
import IconAntDesign from 'react-native-vector-icons/AntDesign';
|
|
8
|
+
import { useIsFocused } from '@react-navigation/native';
|
|
8
9
|
|
|
9
10
|
import ReactNativeHapticFeedback from "react-native-haptic-feedback";
|
|
10
11
|
import {
|
|
@@ -100,10 +101,12 @@ const CheckoutUI = (props: any) => {
|
|
|
100
101
|
currency,
|
|
101
102
|
merchantId,
|
|
102
103
|
setPlaceSpotNumber,
|
|
103
|
-
maxDate
|
|
104
|
+
maxDate,
|
|
105
|
+
urlscheme
|
|
104
106
|
} = props
|
|
105
107
|
|
|
106
108
|
const theme = useTheme();
|
|
109
|
+
const isFocused = useIsFocused();
|
|
107
110
|
|
|
108
111
|
const styles = StyleSheet.create({
|
|
109
112
|
btnBackArrow: {
|
|
@@ -208,7 +211,7 @@ const CheckoutUI = (props: any) => {
|
|
|
208
211
|
const isDisabledButtonPlace = loading || !cart?.valid || (!paymethodSelected && cart?.balance > 0) ||
|
|
209
212
|
placing || errorCash || subtotalWithTaxes < cart?.minimum ||
|
|
210
213
|
(cardsMethods.includes(paymethodSelected?.gateway) && cardList?.cards?.length === 0) ||
|
|
211
|
-
(options.type === 1 &&
|
|
214
|
+
(options.type === 1 && !isGiftCardCart &&
|
|
212
215
|
validationFields?.fields?.checkout?.driver_tip?.enabled &&
|
|
213
216
|
validationFields?.fields?.checkout?.driver_tip?.required &&
|
|
214
217
|
(Number(cart?.driver_tip) <= 0)) ||
|
|
@@ -413,6 +416,7 @@ const CheckoutUI = (props: any) => {
|
|
|
413
416
|
}, [])
|
|
414
417
|
|
|
415
418
|
useEffect(() => {
|
|
419
|
+
if (!isFocused) return
|
|
416
420
|
if (!cartState?.loading && (cartState?.error || typeof cartState?.cart === 'string')) {
|
|
417
421
|
const error = cartState?.error || typeof cartState.cart === 'string' && cartState.cart
|
|
418
422
|
if (error) {
|
|
@@ -420,7 +424,7 @@ const CheckoutUI = (props: any) => {
|
|
|
420
424
|
navigation.navigate('BusinessList')
|
|
421
425
|
}
|
|
422
426
|
}
|
|
423
|
-
}, [cartState?.error, cartState?.cart, cartState?.loading])
|
|
427
|
+
}, [cartState?.error, cartState?.cart, cartState?.loading, isFocused])
|
|
424
428
|
|
|
425
429
|
useEffect(() => {
|
|
426
430
|
const keyboardDidShowListener = Keyboard.addListener('keyboardDidShow', () => {
|
|
@@ -814,6 +818,7 @@ const CheckoutUI = (props: any) => {
|
|
|
814
818
|
handlePaymentMethodClickCustom={handlePaymentMethodClick}
|
|
815
819
|
handlePlaceOrder={handlePlaceOrder}
|
|
816
820
|
merchantId={merchantId}
|
|
821
|
+
urlscheme={urlscheme}
|
|
817
822
|
setMethodPaySupported={setMethodPaySupported}
|
|
818
823
|
methodPaySupported={methodPaySupported}
|
|
819
824
|
placeByMethodPay={placeByMethodPay}
|
|
@@ -955,7 +960,7 @@ const CheckoutUI = (props: any) => {
|
|
|
955
960
|
{t('INVALID_CART_MOMENT', 'Selected schedule time is invalid, please select a schedule into the business schedule interval.')}
|
|
956
961
|
</OText>
|
|
957
962
|
)}
|
|
958
|
-
{options.type === 1 &&
|
|
963
|
+
{options.type === 1 && !isGiftCardCart &&
|
|
959
964
|
validationFields?.fields?.checkout?.driver_tip?.enabled &&
|
|
960
965
|
validationFields?.fields?.checkout?.driver_tip?.required &&
|
|
961
966
|
(Number(cart?.driver_tip) <= 0) && (
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, { useState, useEffect } from 'react'
|
|
1
|
+
import React, { useState, useEffect, useCallback } from 'react'
|
|
2
2
|
import {
|
|
3
3
|
useLanguage,
|
|
4
4
|
useConfig,
|
|
@@ -82,12 +82,12 @@ const MultiCheckoutUI = (props: any) => {
|
|
|
82
82
|
wrapperNavbar: {
|
|
83
83
|
paddingHorizontal: 20,
|
|
84
84
|
backgroundColor: theme?.colors?.white,
|
|
85
|
-
|
|
85
|
+
borderWidth: 0
|
|
86
86
|
},
|
|
87
87
|
detailWrapper: {
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
88
|
+
paddingHorizontal: 20,
|
|
89
|
+
width: '100%'
|
|
90
|
+
},
|
|
91
91
|
})
|
|
92
92
|
|
|
93
93
|
const [, { showToast }] = useToast();
|
|
@@ -143,16 +143,17 @@ const MultiCheckoutUI = (props: any) => {
|
|
|
143
143
|
?.reduce((sum: any, cart: any) => sum + clearAmount((cart?.subtotal + getIncludedTaxes(cart)) * accumulationRateBusiness(cart?.business_id)), 0)
|
|
144
144
|
?.toFixed(configs.format_number_decimal_length?.value ?? 2)
|
|
145
145
|
|
|
146
|
-
|
|
146
|
+
const [showTitle, setShowTitle] = useState(false)
|
|
147
147
|
const [isUserDetailsEdit, setIsUserDetailsEdit] = useState(false);
|
|
148
148
|
const [phoneUpdate, setPhoneUpdate] = useState(false);
|
|
149
149
|
const [userErrors, setUserErrors] = useState<any>([]);
|
|
150
|
+
const [cartsOpened, setCartsOpened] = useState([])
|
|
150
151
|
const [placeByMethodPay, setPlaceByMethodPay] = useState(false)
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
152
|
+
const [allowedGuest, setAllowedGuest] = useState(false)
|
|
153
|
+
const [isOpen, setIsOpen] = useState(false)
|
|
154
|
+
const [requiredFields, setRequiredFields] = useState<any>([])
|
|
155
|
+
const stripePaymethods: any = ['stripe', 'stripe_direct', 'stripe_connect', 'stripe_redirect']
|
|
156
|
+
const [openModal, setOpenModal] = useState({ login: false, signup: false, isGuest: false })
|
|
156
157
|
const [methodPaySupported, setMethodPaySupported] = useState({ enabled: false, message: null, loading: true })
|
|
157
158
|
const methodsPay = ['global_google_pay', 'global_apple_pay']
|
|
158
159
|
const isDisablePlaceOrderButton = cartGroup?.loading || placing || (!(paymethodSelected?.paymethod_id || paymethodSelected?.wallet_id) && cartGroup?.result?.balance > 0) ||
|
|
@@ -170,7 +171,7 @@ const MultiCheckoutUI = (props: any) => {
|
|
|
170
171
|
setUserErrors([])
|
|
171
172
|
const errors = []
|
|
172
173
|
const notFields = ['coupon', 'driver_tip', 'mobile_phone', 'address', 'zipcode', 'address_notes']
|
|
173
|
-
|
|
174
|
+
const _requiredFields: any = []
|
|
174
175
|
|
|
175
176
|
Object.values(validationFields?.fields?.checkout).map((field: any) => {
|
|
176
177
|
if (field?.required && !notFields.includes(field.code)) {
|
|
@@ -188,7 +189,7 @@ const MultiCheckoutUI = (props: any) => {
|
|
|
188
189
|
) {
|
|
189
190
|
_requiredFields.push('cellphone')
|
|
190
191
|
}
|
|
191
|
-
|
|
192
|
+
setRequiredFields(_requiredFields)
|
|
192
193
|
|
|
193
194
|
if (phoneUpdate) {
|
|
194
195
|
errors.push(t('NECESSARY_UPDATE_COUNTRY_PHONE_CODE', 'It is necessary to update your phone number'))
|
|
@@ -203,18 +204,18 @@ const MultiCheckoutUI = (props: any) => {
|
|
|
203
204
|
|
|
204
205
|
const handlePlaceOrder = (confirmPayment?: any) => {
|
|
205
206
|
if (stripePaymethods.includes(paymethodSelected?.gateway) && user?.guest_id) {
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
207
|
+
setOpenModal({ ...openModal, signup: true, isGuest: true })
|
|
208
|
+
return
|
|
209
|
+
}
|
|
209
210
|
|
|
210
211
|
if (!userErrors.length && (!requiredFields?.length || allowedGuest)) {
|
|
211
212
|
handleGroupPlaceOrder && handleGroupPlaceOrder(confirmPayment)
|
|
212
213
|
return
|
|
213
214
|
}
|
|
214
215
|
if (requiredFields?.length) {
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
216
|
+
setIsOpen(true)
|
|
217
|
+
return
|
|
218
|
+
}
|
|
218
219
|
let stringError = ''
|
|
219
220
|
Object.values(userErrors).map((item: any, i: number) => {
|
|
220
221
|
stringError += (i + 1) === userErrors.length ? `- ${item?.message || item}` : `- ${item?.message || item}\n`
|
|
@@ -224,26 +225,34 @@ const MultiCheckoutUI = (props: any) => {
|
|
|
224
225
|
}
|
|
225
226
|
|
|
226
227
|
const handlePlaceOrderAsGuest = () => {
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
228
|
+
setIsOpen(false)
|
|
229
|
+
handleGroupPlaceOrder && handleGroupPlaceOrder()
|
|
230
|
+
}
|
|
230
231
|
|
|
231
232
|
const handleSuccessSignup = (user: any) => {
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
233
|
+
login({
|
|
234
|
+
user,
|
|
235
|
+
token: user?.session?.access_token
|
|
236
|
+
})
|
|
237
|
+
openModal?.isGuest && handlePlaceOrderAsGuest()
|
|
238
|
+
setOpenModal({ ...openModal, signup: false, isGuest: false })
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
const handleSuccessLogin = (user: any) => {
|
|
242
|
+
if (user) setOpenModal({ ...openModal, login: false })
|
|
243
|
+
}
|
|
243
244
|
|
|
244
245
|
const handleScroll = ({ nativeEvent: { contentOffset } }: any) => {
|
|
245
|
-
|
|
246
|
-
|
|
246
|
+
setShowTitle(contentOffset.y > 30)
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
const handleGoBack = () => {
|
|
250
|
+
if (navigation?.canGoBack()) {
|
|
251
|
+
navigation.goBack()
|
|
252
|
+
} else {
|
|
253
|
+
navigation.navigate('BottomTab', { screen: 'Cart' })
|
|
254
|
+
}
|
|
255
|
+
}
|
|
247
256
|
|
|
248
257
|
useEffect(() => {
|
|
249
258
|
if (validationFields && validationFields?.fields?.checkout) {
|
|
@@ -283,13 +292,25 @@ const MultiCheckoutUI = (props: any) => {
|
|
|
283
292
|
}
|
|
284
293
|
}, [paymethodSelected])
|
|
285
294
|
|
|
295
|
+
const changeActiveState = useCallback((isClosed: boolean, uuid: string) => {
|
|
296
|
+
const isActive = cartsOpened?.includes?.(uuid)
|
|
297
|
+
if (isActive || !isClosed) {
|
|
298
|
+
setCartsOpened(cartsOpened?.filter?.((_uuid) => _uuid !== uuid))
|
|
299
|
+
} else {
|
|
300
|
+
setCartsOpened([
|
|
301
|
+
...cartsOpened,
|
|
302
|
+
uuid
|
|
303
|
+
])
|
|
304
|
+
}
|
|
305
|
+
}, [cartsOpened])
|
|
306
|
+
|
|
286
307
|
return (
|
|
287
308
|
<>
|
|
288
309
|
<SafeAreaView style={{ backgroundColor: theme.colors.backgroundPage }}>
|
|
289
310
|
<View style={styles.wrapperNavbar}>
|
|
290
311
|
<TopHeader>
|
|
291
312
|
<>
|
|
292
|
-
<TopActions onPress={() =>
|
|
313
|
+
<TopActions onPress={() => handleGoBack()}>
|
|
293
314
|
<IconAntDesign
|
|
294
315
|
name='arrowleft'
|
|
295
316
|
size={26}
|
|
@@ -321,8 +342,8 @@ const MultiCheckoutUI = (props: any) => {
|
|
|
321
342
|
paddingTop={Platform.OS === 'ios' ? 0 : 4}
|
|
322
343
|
btnStyle={{ paddingLeft: 0 }}
|
|
323
344
|
titleWrapStyle={{ paddingHorizontal: 0 }}
|
|
324
|
-
|
|
325
|
-
|
|
345
|
+
titleStyle={{ marginRight: 0, marginLeft: 0 }}
|
|
346
|
+
style={{ marginTop: 20 }}
|
|
326
347
|
/>
|
|
327
348
|
</View>
|
|
328
349
|
<ChContainer style={styles.pagePadding}>
|
|
@@ -514,6 +535,9 @@ const MultiCheckoutUI = (props: any) => {
|
|
|
514
535
|
hideDriverTip={configs?.multi_business_checkout_show_combined_driver_tip?.value === '1'}
|
|
515
536
|
onNavigationRedirect={(route: string, params: any) => props.navigation.navigate(route, params)}
|
|
516
537
|
businessConfigs={cart?.business?.configs}
|
|
538
|
+
cartsOpened={cartsOpened}
|
|
539
|
+
changeActiveState={changeActiveState}
|
|
540
|
+
isActive={cartsOpened?.includes?.(cart?.uuid)}
|
|
517
541
|
/>
|
|
518
542
|
{openCarts.length > 1 && (
|
|
519
543
|
<View style={{ height: 8, backgroundColor: theme.colors.backgroundGray100, marginTop: 13, marginHorizontal: -40 }} />
|
|
@@ -623,30 +647,30 @@ const MultiCheckoutUI = (props: any) => {
|
|
|
623
647
|
</ScrollView>
|
|
624
648
|
</OModal>
|
|
625
649
|
<OModal
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
+
open={isOpen}
|
|
651
|
+
onClose={() => setIsOpen(false)}
|
|
652
|
+
>
|
|
653
|
+
<View style={styles.detailWrapper}>
|
|
654
|
+
<UserDetails
|
|
655
|
+
isUserDetailsEdit
|
|
656
|
+
useValidationFields
|
|
657
|
+
useDefualtSessionManager
|
|
658
|
+
useSessionUser
|
|
659
|
+
isCheckout
|
|
660
|
+
isEdit
|
|
661
|
+
phoneUpdate={phoneUpdate}
|
|
662
|
+
togglePhoneUpdate={togglePhoneUpdate}
|
|
663
|
+
requiredFields={requiredFields}
|
|
664
|
+
hideUpdateButton
|
|
665
|
+
handlePlaceOrderAsGuest={handlePlaceOrderAsGuest}
|
|
666
|
+
onClose={() => {
|
|
667
|
+
setIsOpen(false)
|
|
668
|
+
handlePlaceOrder()
|
|
669
|
+
}}
|
|
670
|
+
setIsOpen={setIsOpen}
|
|
671
|
+
/>
|
|
672
|
+
</View>
|
|
673
|
+
</OModal>
|
|
650
674
|
</Container>
|
|
651
675
|
|
|
652
676
|
<FloatingButton
|
|
@@ -65,6 +65,7 @@ const PaymentOptionsUI = (props: any) => {
|
|
|
65
65
|
handlePaymentMethodClickCustom,
|
|
66
66
|
handlePlaceOrder,
|
|
67
67
|
merchantId,
|
|
68
|
+
urlscheme,
|
|
68
69
|
setMethodPaySupported,
|
|
69
70
|
placeByMethodPay,
|
|
70
71
|
methodPaySupported,
|
|
@@ -360,6 +361,7 @@ const PaymentOptionsUI = (props: any) => {
|
|
|
360
361
|
handleSource={handlePaymethodDataChange}
|
|
361
362
|
onCancel={() => handlePaymethodClick(null)}
|
|
362
363
|
merchantId={merchantId}
|
|
364
|
+
urlscheme={urlscheme}
|
|
363
365
|
setMethodPaySupported={setMethodPaySupported}
|
|
364
366
|
methodPaySupported={methodPaySupported}
|
|
365
367
|
placeByMethodPay={placeByMethodPay}
|
|
@@ -407,6 +409,7 @@ const PaymentOptionsUI = (props: any) => {
|
|
|
407
409
|
handleSource={handlePaymethodDataChange}
|
|
408
410
|
onCancel={() => handlePaymethodClick(null)}
|
|
409
411
|
merchantId={merchantId}
|
|
412
|
+
urlscheme={urlscheme}
|
|
410
413
|
publicKeyAddCard={isOpenMethod?.paymethod?.credentials?.stripe?.publishable}
|
|
411
414
|
/>
|
|
412
415
|
</KeyboardAvoidingView>
|
|
@@ -74,9 +74,9 @@ export const ProductItemAccordion = (props: ProductItemAccordionParams) => {
|
|
|
74
74
|
|
|
75
75
|
const [isActive, setActiveState] = useState(false)
|
|
76
76
|
const [isServiceOpen, setIsServiceOpen] = useState(false)
|
|
77
|
+
const [productQuantityState, setProductQuantityState] = useState(product.quantity.toString())
|
|
77
78
|
// const [setHeight, setHeightState] = useState({ height: new Animated.Value(0) })
|
|
78
79
|
// const [setRotate, setRotateState] = useState({ angle: new Animated.Value(0) })
|
|
79
|
-
let productQuantity = product.quantity.toString()
|
|
80
80
|
|
|
81
81
|
const productInfo = () => {
|
|
82
82
|
if (isCartProduct) {
|
|
@@ -120,7 +120,7 @@ export const ProductItemAccordion = (props: ProductItemAccordionParams) => {
|
|
|
120
120
|
|
|
121
121
|
const handleChangeQuantity = (value: string) => {
|
|
122
122
|
if (!orderState.loading) {
|
|
123
|
-
|
|
123
|
+
setProductQuantityState(value)
|
|
124
124
|
if (parseInt(value) === 0) {
|
|
125
125
|
onDeleteProduct && onDeleteProduct(product)
|
|
126
126
|
} else {
|
|
@@ -210,7 +210,7 @@ export const ProductItemAccordion = (props: ProductItemAccordionParams) => {
|
|
|
210
210
|
<RNPickerSelect
|
|
211
211
|
items={productOptions}
|
|
212
212
|
onValueChange={handleChangeQuantity}
|
|
213
|
-
value={
|
|
213
|
+
value={productQuantityState}
|
|
214
214
|
style={pickerStyle}
|
|
215
215
|
useNativeAndroidPickerStyle={false}
|
|
216
216
|
placeholder={{}}
|
|
@@ -286,15 +286,15 @@ export const ProductItemAccordion = (props: ProductItemAccordionParams) => {
|
|
|
286
286
|
{productInfo().ingredients.length > 0 && productInfo().ingredients.some((ingredient: any) => !ingredient.selected) && (
|
|
287
287
|
<ProductOptionsList>
|
|
288
288
|
<OText size={10} color={theme.colors.textSecondary}>{t('INGREDIENTS', 'Ingredients')}</OText>
|
|
289
|
-
{productInfo().ingredients.map((ingredient: any) => !ingredient.selected && (
|
|
290
|
-
<OText size={10} color={theme.colors.textThird} key={ingredient.id} style={{ marginLeft: 10 }}>{t('NO', 'No')} {ingredient.name}</OText>
|
|
289
|
+
{productInfo().ingredients.map((ingredient: any, i) => !ingredient.selected && (
|
|
290
|
+
<OText size={10} color={theme.colors.textThird} key={ingredient.id + i} style={{ marginLeft: 10 }}>{t('NO', 'No')} {ingredient.name}</OText>
|
|
291
291
|
))}
|
|
292
292
|
</ProductOptionsList>
|
|
293
293
|
)}
|
|
294
294
|
{productInfo().options.length > 0 && (
|
|
295
295
|
<ProductOptionsList>
|
|
296
|
-
{productInfo().options.sort((a: any, b: any) => a.rank - b.rank).map((option: any
|
|
297
|
-
<ProductOption key={option.id
|
|
296
|
+
{productInfo().options.sort((a: any, b: any) => a.rank - b.rank).map((option: any) => (
|
|
297
|
+
<ProductOption key={option.id}>
|
|
298
298
|
<OText size={10} color={theme.colors.textSecondary}>{option.name}</OText>
|
|
299
299
|
{option.suboptions.map((suboption: any) => (
|
|
300
300
|
<ProductSubOption key={suboption.id}>
|
|
@@ -34,7 +34,8 @@ const StripeElementsFormUI = (props: any) => {
|
|
|
34
34
|
methodPaySupported,
|
|
35
35
|
setPlaceByMethodPay,
|
|
36
36
|
cartTotal,
|
|
37
|
-
publicKeyAddCard
|
|
37
|
+
publicKeyAddCard,
|
|
38
|
+
urlScheme
|
|
38
39
|
} = props;
|
|
39
40
|
|
|
40
41
|
const theme = useTheme();
|
|
@@ -204,7 +205,7 @@ const StripeElementsFormUI = (props: any) => {
|
|
|
204
205
|
<StripeProvider
|
|
205
206
|
publishableKey={isToSave}
|
|
206
207
|
merchantIdentifier={merchantId}
|
|
207
|
-
urlScheme={
|
|
208
|
+
urlScheme={`${urlScheme}://checkout/${cart?.uuid}`}
|
|
208
209
|
>
|
|
209
210
|
{methodsPay?.includes(paymethod) ? (
|
|
210
211
|
<StripeMethodForm
|