ordering-ui-react-native 0.18.0 → 0.18.2
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/OrderDetails/OrderContentComponent.tsx +29 -9
- package/themes/business/src/components/OrderDetails/OrderHeaderComponent.tsx +56 -59
- package/themes/business/src/components/OrderDetailsLogistic/index.tsx +195 -0
- package/themes/business/src/components/OrderDetailsLogistic/styles.tsx +5 -0
- package/themes/business/src/components/OrderMessage/index.tsx +18 -17
- package/themes/business/src/components/OrdersOption/index.tsx +17 -15
- package/themes/business/src/components/PreviousOrders/index.tsx +7 -2
- package/themes/business/src/components/ProductItemAccordion/index.tsx +7 -1
- package/themes/business/src/components/ReviewCustomer/index.tsx +15 -12
- package/themes/business/src/types/index.tsx +17 -10
- package/themes/business/src/utils/index.tsx +27 -0
- package/themes/original/src/components/BusinessProductsListing/index.tsx +1 -1
- package/themes/original/src/components/DriverTips/index.tsx +6 -1
- package/themes/original/src/components/MomentOption/index.tsx +37 -31
- package/themes/original/src/components/ProductForm/index.tsx +3 -3
- package/themes/original/src/components/ProfessionalProfile/index.tsx +35 -6
- package/themes/original/src/components/ServiceForm/index.tsx +34 -22
package/package.json
CHANGED
|
@@ -41,6 +41,7 @@ import { MapViewUI as MapView } from './src/components/MapView'
|
|
|
41
41
|
import { NewOrderNotification } from './src/components/NewOrderNotification';
|
|
42
42
|
import { DriverSchedule } from './src/components/DriverSchedule';
|
|
43
43
|
import { ScheduleBlocked } from './src/components/ScheduleBlocked';
|
|
44
|
+
import { OrderDetailsLogistic } from './src/components/OrderDetailsLogistic'
|
|
44
45
|
//OComponents
|
|
45
46
|
import {
|
|
46
47
|
OText,
|
|
@@ -110,6 +111,7 @@ export {
|
|
|
110
111
|
VerifyPhone,
|
|
111
112
|
DriverSchedule,
|
|
112
113
|
ScheduleBlocked,
|
|
114
|
+
OrderDetailsLogistic,
|
|
113
115
|
//OComponents
|
|
114
116
|
OAlert,
|
|
115
117
|
OButton,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React, { useState, useCallback } from 'react'
|
|
2
2
|
|
|
3
|
-
import { Platform, StyleSheet, View, TouchableOpacity } from 'react-native';
|
|
3
|
+
import { Platform, StyleSheet, View, TouchableOpacity, ScrollView } from 'react-native';
|
|
4
4
|
|
|
5
5
|
import { OButton, OText, OLink, OModal } from '../shared'
|
|
6
6
|
import {
|
|
@@ -16,18 +16,23 @@ import {
|
|
|
16
16
|
|
|
17
17
|
import { ProductItemAccordion } from '../ProductItemAccordion';
|
|
18
18
|
|
|
19
|
-
import { verifyDecimals } from '../../utils';
|
|
19
|
+
import { verifyDecimals, calculateDistance, transformDistance } from '../../utils';
|
|
20
20
|
|
|
21
21
|
import {
|
|
22
22
|
useLanguage,
|
|
23
23
|
useUtils,
|
|
24
24
|
useConfig,
|
|
25
|
+
useSession
|
|
25
26
|
} from 'ordering-components/native';
|
|
26
27
|
import { useTheme } from 'styled-components/native';
|
|
27
28
|
import { ReviewCustomer } from '../ReviewCustomer'
|
|
28
29
|
|
|
29
30
|
import MaterialIcon from 'react-native-vector-icons/MaterialCommunityIcons'
|
|
30
31
|
|
|
32
|
+
import { DeviceOrientationMethods } from '../../../../../src/hooks/DeviceOrientation'
|
|
33
|
+
|
|
34
|
+
const { useDeviceOrientation } = DeviceOrientationMethods
|
|
35
|
+
|
|
31
36
|
interface OrderContent {
|
|
32
37
|
order: any,
|
|
33
38
|
logisticOrderStatus?: Array<number>,
|
|
@@ -38,10 +43,15 @@ interface OrderContent {
|
|
|
38
43
|
export const OrderContentComponent = (props: OrderContent) => {
|
|
39
44
|
const [, t] = useLanguage();
|
|
40
45
|
const theme = useTheme()
|
|
41
|
-
|
|
46
|
+
const [{user}] = useSession()
|
|
47
|
+
console.log(user)
|
|
42
48
|
const { order, logisticOrderStatus, isOrderGroup, lastOrder } = props;
|
|
43
49
|
const [{ parsePrice, parseNumber }] = useUtils();
|
|
44
50
|
const [{ configs }] = useConfig();
|
|
51
|
+
const [orientationState] = useDeviceOrientation();
|
|
52
|
+
|
|
53
|
+
const WIDTH_SCREEN = orientationState?.dimensions?.width
|
|
54
|
+
|
|
45
55
|
const [openReviewModal, setOpenReviewModal] = useState(false)
|
|
46
56
|
|
|
47
57
|
const [isReadMore, setIsReadMore] = useState(false)
|
|
@@ -99,13 +109,13 @@ export const OrderContentComponent = (props: OrderContent) => {
|
|
|
99
109
|
}
|
|
100
110
|
|
|
101
111
|
const onTextLayout = useCallback((e: any) => {
|
|
102
|
-
setLengthMore(e.nativeEvent.lines.length
|
|
112
|
+
setLengthMore((e.nativeEvent.lines.length == 2 && e.nativeEvent.lines[1].width > WIDTH_SCREEN * .76) || e.nativeEvent.lines.length > 2); //to check the text is more than 2 lines or not
|
|
103
113
|
},[]);
|
|
104
114
|
|
|
105
115
|
return (
|
|
106
116
|
<OrderContent isOrderGroup={isOrderGroup} lastOrder={lastOrder}>
|
|
107
117
|
{isOrderGroup && (
|
|
108
|
-
<OText size={18}>{t('ORDER', 'Order')} #{
|
|
118
|
+
<OText size={18}>{t('ORDER', 'Order')} #{order?.id}</OText>
|
|
109
119
|
)}
|
|
110
120
|
|
|
111
121
|
{order?.metafields?.length > 0 && (
|
|
@@ -193,7 +203,11 @@ export const OrderContentComponent = (props: OrderContent) => {
|
|
|
193
203
|
/>
|
|
194
204
|
</View>
|
|
195
205
|
)}
|
|
196
|
-
|
|
206
|
+
{!!order?.business?.location && (
|
|
207
|
+
<OText>
|
|
208
|
+
{t('DISTANCE_TO_THE_BUSINESS', 'Distance to the business')}: {transformDistance(calculateDistance(order?.business?.location, user?.location), distanceUnit)} {t(distanceUnit.toUpperCase(), distanceUnit)}
|
|
209
|
+
</OText>
|
|
210
|
+
)}
|
|
197
211
|
{!!order?.business?.address_notes && (
|
|
198
212
|
<View style={styles.linkWithIcons}>
|
|
199
213
|
<OLink
|
|
@@ -334,9 +348,15 @@ export const OrderContentComponent = (props: OrderContent) => {
|
|
|
334
348
|
)}
|
|
335
349
|
|
|
336
350
|
{!!order?.customer?.address_notes && (
|
|
337
|
-
<
|
|
338
|
-
{
|
|
339
|
-
|
|
351
|
+
<ScrollView
|
|
352
|
+
showsVerticalScrollIndicator={false}
|
|
353
|
+
showsHorizontalScrollIndicator={false}
|
|
354
|
+
horizontal
|
|
355
|
+
>
|
|
356
|
+
<OText numberOfLines={1} mBottom={4} ellipsizeMode="tail">
|
|
357
|
+
{order?.customer?.address_notes}
|
|
358
|
+
</OText>
|
|
359
|
+
</ScrollView>
|
|
340
360
|
)}
|
|
341
361
|
|
|
342
362
|
{!!order?.customer?.zipcode && (
|
|
@@ -9,12 +9,15 @@ import {
|
|
|
9
9
|
|
|
10
10
|
//Components
|
|
11
11
|
import {
|
|
12
|
+
OIcon,
|
|
12
13
|
OIconButton,
|
|
13
14
|
OText,
|
|
14
15
|
} from '../shared'
|
|
15
16
|
|
|
16
17
|
import { useTheme } from 'styled-components/native';
|
|
17
|
-
import { StyleSheet, View } from 'react-native';
|
|
18
|
+
import { StyleSheet, TouchableOpacity, View } from 'react-native';
|
|
19
|
+
import SimpleLineIcons from 'react-native-vector-icons/SimpleLineIcons'
|
|
20
|
+
import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons'
|
|
18
21
|
|
|
19
22
|
import {
|
|
20
23
|
useLanguage,
|
|
@@ -54,6 +57,19 @@ export const OrderHeaderComponent = (props: OrderHeader) => {
|
|
|
54
57
|
height: 40,
|
|
55
58
|
padding: 10,
|
|
56
59
|
alignItems: 'flex-end',
|
|
60
|
+
color: theme.colors.textGray,
|
|
61
|
+
},
|
|
62
|
+
btnBackArrow: {
|
|
63
|
+
borderWidth: 0,
|
|
64
|
+
width: 32,
|
|
65
|
+
height: 32,
|
|
66
|
+
tintColor: theme.colors.textGray,
|
|
67
|
+
backgroundColor: theme.colors.clear,
|
|
68
|
+
borderColor: theme.colors.clear,
|
|
69
|
+
shadowColor: theme.colors.clear,
|
|
70
|
+
paddingLeft: 0,
|
|
71
|
+
paddingRight: 0,
|
|
72
|
+
marginTop: 10
|
|
57
73
|
},
|
|
58
74
|
})
|
|
59
75
|
|
|
@@ -108,42 +124,30 @@ export const OrderHeaderComponent = (props: OrderHeader) => {
|
|
|
108
124
|
<>
|
|
109
125
|
{!props.isCustomView && (
|
|
110
126
|
<Header>
|
|
111
|
-
<
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
borderColor={theme.colors.clear}
|
|
115
|
-
style={{ ...styles.icons, justifyContent: 'flex-end' }}
|
|
116
|
-
onClick={() => handleArrowBack()}
|
|
117
|
-
/>
|
|
118
|
-
|
|
127
|
+
<TouchableOpacity onPress={() => handleArrowBack()} style={styles.btnBackArrow}>
|
|
128
|
+
<OIcon src={theme.images.general.arrow_left} color={theme.colors.textGray} />
|
|
129
|
+
</TouchableOpacity>
|
|
119
130
|
{(!order?.isLogistic || (!logisticOrderStatus?.includes(order?.status) && !order?.order_group)) && (
|
|
120
131
|
<Actions>
|
|
121
132
|
{getOrderStatus(order?.status, t)?.value !==
|
|
122
133
|
t('PENDING', 'Pending') && (
|
|
123
134
|
<>
|
|
124
|
-
<
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
height: 22,
|
|
141
|
-
tintColor: theme.colors.backArrow,
|
|
142
|
-
}}
|
|
143
|
-
borderColor={theme.colors.clear}
|
|
144
|
-
style={styles.icons}
|
|
145
|
-
onClick={() => handleViewSummaryOrder?.()}
|
|
146
|
-
/>
|
|
135
|
+
<TouchableOpacity onPress={() => handleCopyClipboard?.()}>
|
|
136
|
+
<MaterialCommunityIcons
|
|
137
|
+
name='content-copy'
|
|
138
|
+
color={theme.colors.textGray}
|
|
139
|
+
size={20}
|
|
140
|
+
style={styles.icons}
|
|
141
|
+
/>
|
|
142
|
+
</TouchableOpacity>
|
|
143
|
+
<TouchableOpacity onPress={() => handleViewSummaryOrder?.()}>
|
|
144
|
+
<SimpleLineIcons
|
|
145
|
+
name='printer'
|
|
146
|
+
color={theme.colors.textGray}
|
|
147
|
+
size={20}
|
|
148
|
+
style={styles.icons}
|
|
149
|
+
/>
|
|
150
|
+
</TouchableOpacity>
|
|
147
151
|
</>
|
|
148
152
|
)}
|
|
149
153
|
<OIconButton
|
|
@@ -151,7 +155,7 @@ export const OrderHeaderComponent = (props: OrderHeader) => {
|
|
|
151
155
|
iconStyle={{
|
|
152
156
|
width: 20,
|
|
153
157
|
height: 20,
|
|
154
|
-
tintColor: theme.colors.
|
|
158
|
+
tintColor: theme.colors.textGray,
|
|
155
159
|
}}
|
|
156
160
|
borderColor={theme.colors.clear}
|
|
157
161
|
style={styles.icons}
|
|
@@ -163,7 +167,7 @@ export const OrderHeaderComponent = (props: OrderHeader) => {
|
|
|
163
167
|
iconStyle={{
|
|
164
168
|
width: 20,
|
|
165
169
|
height: 20,
|
|
166
|
-
tintColor: theme.colors.
|
|
170
|
+
tintColor: theme.colors.textGray,
|
|
167
171
|
}}
|
|
168
172
|
borderColor={theme.colors.clear}
|
|
169
173
|
style={styles.icons}
|
|
@@ -193,29 +197,22 @@ export const OrderHeaderComponent = (props: OrderHeader) => {
|
|
|
193
197
|
{getOrderStatus(order?.status, t)?.value !==
|
|
194
198
|
t('PENDING', 'Pending') && (
|
|
195
199
|
<>
|
|
196
|
-
<
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
height: 22,
|
|
213
|
-
tintColor: theme.colors.backArrow,
|
|
214
|
-
}}
|
|
215
|
-
borderColor={theme.colors.clear}
|
|
216
|
-
style={styles.icons}
|
|
217
|
-
onClick={() => handleViewSummaryOrder?.()}
|
|
218
|
-
/>
|
|
200
|
+
<TouchableOpacity onPress={() => handleCopyClipboard?.()}>
|
|
201
|
+
<MaterialCommunityIcons
|
|
202
|
+
name='content-copy'
|
|
203
|
+
color={theme.colors.textGray}
|
|
204
|
+
size={20}
|
|
205
|
+
style={styles.icons}
|
|
206
|
+
/>
|
|
207
|
+
</TouchableOpacity>
|
|
208
|
+
<TouchableOpacity onPress={() => handleViewSummaryOrder?.()}>
|
|
209
|
+
<SimpleLineIcons
|
|
210
|
+
name='printer'
|
|
211
|
+
color={theme.colors.textGray}
|
|
212
|
+
size={20}
|
|
213
|
+
style={styles.icons}
|
|
214
|
+
/>
|
|
215
|
+
</TouchableOpacity>
|
|
219
216
|
</>
|
|
220
217
|
)}
|
|
221
218
|
<OIconButton
|
|
@@ -223,7 +220,7 @@ export const OrderHeaderComponent = (props: OrderHeader) => {
|
|
|
223
220
|
iconStyle={{
|
|
224
221
|
width: 20,
|
|
225
222
|
height: 20,
|
|
226
|
-
tintColor: theme.colors.
|
|
223
|
+
tintColor: theme.colors.textGray,
|
|
227
224
|
}}
|
|
228
225
|
borderColor={theme.colors.clear}
|
|
229
226
|
style={styles.icons}
|
|
@@ -235,7 +232,7 @@ export const OrderHeaderComponent = (props: OrderHeader) => {
|
|
|
235
232
|
iconStyle={{
|
|
236
233
|
width: 20,
|
|
237
234
|
height: 20,
|
|
238
|
-
tintColor: theme.colors.
|
|
235
|
+
tintColor: theme.colors.textGray,
|
|
239
236
|
}}
|
|
240
237
|
borderColor={theme.colors.clear}
|
|
241
238
|
style={styles.icons}
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
//React & React Native
|
|
2
|
+
import React, { useState, useEffect } from 'react';
|
|
3
|
+
import { View } from 'react-native';
|
|
4
|
+
|
|
5
|
+
// Thirds
|
|
6
|
+
import { Placeholder, PlaceholderLine, Fade } from 'rn-placeholder';
|
|
7
|
+
|
|
8
|
+
//OrderingComponent
|
|
9
|
+
import {
|
|
10
|
+
useLanguage,
|
|
11
|
+
OrderDetails as OrderDetailsConTableoller,
|
|
12
|
+
useSession,
|
|
13
|
+
} from 'ordering-components/native';
|
|
14
|
+
|
|
15
|
+
//Components
|
|
16
|
+
import Alert from '../../providers/AlertProvider';
|
|
17
|
+
import { FloatingButton } from '../FloatingButton';
|
|
18
|
+
import { OrderDetailsLogisticParams } from '../../types';
|
|
19
|
+
import { useTheme } from 'styled-components/native';
|
|
20
|
+
import { NotFoundSource } from '../NotFoundSource';
|
|
21
|
+
import { getOrderStatus } from '../../utils';
|
|
22
|
+
import { OrderHeaderComponent } from '../OrderDetails/OrderHeaderComponent';
|
|
23
|
+
import { OrderContentComponent } from '../OrderDetails/OrderContentComponent';
|
|
24
|
+
//Styles
|
|
25
|
+
import { OrderDetailsContainer } from './styles';
|
|
26
|
+
|
|
27
|
+
export const OrderDetailsLogisticUI = (props: OrderDetailsLogisticParams) => {
|
|
28
|
+
const {
|
|
29
|
+
navigation,
|
|
30
|
+
handleClickLogisticOrder,
|
|
31
|
+
orderAssingId,
|
|
32
|
+
} = props;
|
|
33
|
+
const { order } = props.order
|
|
34
|
+
const theme = useTheme();
|
|
35
|
+
const [, t] = useLanguage();
|
|
36
|
+
const [session] = useSession();
|
|
37
|
+
const [alertState, setAlertState] = useState<{
|
|
38
|
+
open: boolean;
|
|
39
|
+
content: Array<string>;
|
|
40
|
+
key?: string | null;
|
|
41
|
+
}>({ open: false, content: [], key: null });
|
|
42
|
+
|
|
43
|
+
const logisticOrderStatus = [4, 6, 7]
|
|
44
|
+
|
|
45
|
+
const showFloatButtonsAcceptOrReject: any = {
|
|
46
|
+
0: true,
|
|
47
|
+
4: true,
|
|
48
|
+
7: true,
|
|
49
|
+
14: true
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
const handleArrowBack: any = () => {
|
|
53
|
+
navigation?.canGoBack() && navigation.goBack();
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
const handleRejectLogisticOrder = (order: any) => {
|
|
57
|
+
handleClickLogisticOrder?.(2, orderAssingId || order?.logistic_order_id)
|
|
58
|
+
handleArrowBack()
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const handleAcceptLogisticOrder = (order: any) => {
|
|
62
|
+
handleClickLogisticOrder?.(1, orderAssingId || order?.logistic_order_id)
|
|
63
|
+
handleArrowBack()
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
useEffect(() => {
|
|
67
|
+
if (order?.driver === null && session?.user?.level === 4) {
|
|
68
|
+
setAlertState({
|
|
69
|
+
open: true,
|
|
70
|
+
content: [
|
|
71
|
+
t(
|
|
72
|
+
'YOU_HAVE_BEEN_REMOVED_FROM_THE_ORDER',
|
|
73
|
+
'You have been removed from the order',
|
|
74
|
+
),
|
|
75
|
+
],
|
|
76
|
+
key: null,
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
}, [order?.driver]);
|
|
80
|
+
|
|
81
|
+
const OrderDetailsInformation = (props: { order: any, isOrderGroup?: boolean, lastOrder?: boolean }) => {
|
|
82
|
+
const {
|
|
83
|
+
order,
|
|
84
|
+
isOrderGroup,
|
|
85
|
+
lastOrder,
|
|
86
|
+
} = props
|
|
87
|
+
return (
|
|
88
|
+
<>
|
|
89
|
+
<OrderContentComponent
|
|
90
|
+
order={order}
|
|
91
|
+
logisticOrderStatus={logisticOrderStatus}
|
|
92
|
+
isOrderGroup={isOrderGroup}
|
|
93
|
+
lastOrder={lastOrder}
|
|
94
|
+
/>
|
|
95
|
+
<View
|
|
96
|
+
style={{
|
|
97
|
+
height:
|
|
98
|
+
order?.status === 8 && order?.delivery_type === 1 ? 50 : 35,
|
|
99
|
+
}}
|
|
100
|
+
/>
|
|
101
|
+
|
|
102
|
+
</>
|
|
103
|
+
)
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
return (
|
|
107
|
+
<>
|
|
108
|
+
{(!order || Object.keys(order).length === 0) &&
|
|
109
|
+
(props.order?.error?.length < 1 || !props.order?.error) && (
|
|
110
|
+
<View style={{ flex: 1 }}>
|
|
111
|
+
{[...Array(6)].map((item, i) => (
|
|
112
|
+
<Placeholder key={i} Animation={Fade}>
|
|
113
|
+
<View style={{ flexDirection: 'row', paddingVertical: 20 }}>
|
|
114
|
+
<Placeholder>
|
|
115
|
+
<PlaceholderLine width={100} />
|
|
116
|
+
<PlaceholderLine width={70} />
|
|
117
|
+
<PlaceholderLine width={30} />
|
|
118
|
+
<PlaceholderLine width={20} />
|
|
119
|
+
</Placeholder>
|
|
120
|
+
</View>
|
|
121
|
+
</Placeholder>
|
|
122
|
+
))}
|
|
123
|
+
</View>
|
|
124
|
+
)}
|
|
125
|
+
|
|
126
|
+
{(!!props.order?.error || props.order?.error) && (
|
|
127
|
+
<NotFoundSource
|
|
128
|
+
btnTitle={t('GO_TO_MY_ORDERS', 'Go to my orders')}
|
|
129
|
+
content={
|
|
130
|
+
props.order.error[0] ||
|
|
131
|
+
props.order.error ||
|
|
132
|
+
t('NETWORK_ERROR', 'Network Error')
|
|
133
|
+
}
|
|
134
|
+
onClickButton={() => navigation.navigate('Orders')}
|
|
135
|
+
/>
|
|
136
|
+
)}
|
|
137
|
+
{!((!order || Object.keys(order).length === 0) &&
|
|
138
|
+
(props.order?.error?.length < 1 || !props.order?.error)) && (
|
|
139
|
+
<View style={{ flex: 1 }}>
|
|
140
|
+
<OrderHeaderComponent
|
|
141
|
+
order={order}
|
|
142
|
+
getOrderStatus={getOrderStatus}
|
|
143
|
+
handleArrowBack={handleArrowBack}
|
|
144
|
+
logisticOrderStatus={logisticOrderStatus}
|
|
145
|
+
/>
|
|
146
|
+
{order && Object.keys(order).length > 0 && (props.order?.error?.length < 1 || !props.order?.error) && (
|
|
147
|
+
<>
|
|
148
|
+
<OrderDetailsContainer
|
|
149
|
+
keyboardShouldPersistTaps="handled"
|
|
150
|
+
showsVerticalScrollIndicator={false}
|
|
151
|
+
>
|
|
152
|
+
{order?.order_group && order?.order_group_id && order?.isLogistic ? order?.order_group?.orders.map((order: any, i: number, hash: any) => (
|
|
153
|
+
<OrderDetailsInformation key={order?.id} order={order} isOrderGroup lastOrder={hash?.length === i + 1} />
|
|
154
|
+
)) : (
|
|
155
|
+
<OrderDetailsInformation order={order} />
|
|
156
|
+
)}
|
|
157
|
+
</OrderDetailsContainer>
|
|
158
|
+
|
|
159
|
+
{showFloatButtonsAcceptOrReject[order?.status] && (
|
|
160
|
+
<FloatingButton
|
|
161
|
+
btnText={t('REJECT', 'Reject')}
|
|
162
|
+
isSecondaryBtn={false}
|
|
163
|
+
secondButtonClick={() => handleAcceptLogisticOrder(order)}
|
|
164
|
+
firstButtonClick={() => handleRejectLogisticOrder(order)}
|
|
165
|
+
secondBtnText={t('ACCEPT', 'Accept')}
|
|
166
|
+
secondButton={true}
|
|
167
|
+
firstColorCustom={theme.colors.red}
|
|
168
|
+
secondColorCustom={theme.colors.green}
|
|
169
|
+
widthButton={'45%'}
|
|
170
|
+
/>
|
|
171
|
+
)}
|
|
172
|
+
</>
|
|
173
|
+
)}
|
|
174
|
+
</View>
|
|
175
|
+
)}
|
|
176
|
+
{alertState?.open && (
|
|
177
|
+
<Alert
|
|
178
|
+
open={alertState.open}
|
|
179
|
+
onAccept={handleArrowBack}
|
|
180
|
+
onClose={handleArrowBack}
|
|
181
|
+
content={alertState.content}
|
|
182
|
+
title={t('WARNING', 'Warning')}
|
|
183
|
+
/>
|
|
184
|
+
)}
|
|
185
|
+
</>
|
|
186
|
+
);
|
|
187
|
+
};
|
|
188
|
+
|
|
189
|
+
export const OrderDetailsLogistic = (props: OrderDetailsLogisticParams) => {
|
|
190
|
+
const orderDetailsProps = {
|
|
191
|
+
...props,
|
|
192
|
+
UIComponent: OrderDetailsLogisticUI,
|
|
193
|
+
};
|
|
194
|
+
return <OrderDetailsConTableoller {...orderDetailsProps} />;
|
|
195
|
+
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React, { useState, useEffect } from 'react';
|
|
2
2
|
import { Placeholder, PlaceholderLine, Fade } from 'rn-placeholder';
|
|
3
3
|
import { Chat } from '../Chat';
|
|
4
|
-
import { StyleSheet, View, BackHandler } from 'react-native';
|
|
4
|
+
import { StyleSheet, View, BackHandler, TouchableOpacity } from 'react-native';
|
|
5
5
|
import {
|
|
6
6
|
useLanguage,
|
|
7
7
|
OrderDetails as OrderDetailsController,
|
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
} from 'ordering-components/native';
|
|
10
10
|
import { useUtils } from 'ordering-components/native';
|
|
11
11
|
|
|
12
|
-
import { OIcon,
|
|
12
|
+
import { OIcon, OText } from '../shared';
|
|
13
13
|
import { OrderDetailsParams } from '../../types';
|
|
14
14
|
import { USER_TYPE } from '../../config/constants';
|
|
15
15
|
import { useTheme } from 'styled-components/native';
|
|
@@ -146,13 +146,6 @@ export const OrderMessageUI = (props: OrderDetailsParams) => {
|
|
|
146
146
|
shadowRadius: 3.84,
|
|
147
147
|
elevation: 3,
|
|
148
148
|
},
|
|
149
|
-
cancelBtn: {
|
|
150
|
-
marginRight: 5,
|
|
151
|
-
zIndex: 10000,
|
|
152
|
-
height: 30,
|
|
153
|
-
width: 20,
|
|
154
|
-
justifyContent: 'flex-end',
|
|
155
|
-
},
|
|
156
149
|
modalText: {
|
|
157
150
|
fontFamily: 'Poppins',
|
|
158
151
|
fontStyle: 'normal',
|
|
@@ -161,6 +154,18 @@ export const OrderMessageUI = (props: OrderDetailsParams) => {
|
|
|
161
154
|
textAlign: 'center',
|
|
162
155
|
zIndex: 10,
|
|
163
156
|
},
|
|
157
|
+
btnBackArrow: {
|
|
158
|
+
borderWidth: 0,
|
|
159
|
+
width: 32,
|
|
160
|
+
height: 32,
|
|
161
|
+
tintColor: theme.colors.textGray,
|
|
162
|
+
backgroundColor: theme.colors.clear,
|
|
163
|
+
borderColor: theme.colors.clear,
|
|
164
|
+
shadowColor: theme.colors.clear,
|
|
165
|
+
paddingLeft: 0,
|
|
166
|
+
paddingRight: 0,
|
|
167
|
+
marginTop: 10
|
|
168
|
+
},
|
|
164
169
|
});
|
|
165
170
|
|
|
166
171
|
return (
|
|
@@ -260,13 +265,9 @@ export const OrderMessageUI = (props: OrderDetailsParams) => {
|
|
|
260
265
|
<>
|
|
261
266
|
<View style={styles.titleSection}>
|
|
262
267
|
<View style={styles.titleGroups}>
|
|
263
|
-
<
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
borderColor={theme.colors.clear}
|
|
267
|
-
style={styles.cancelBtn}
|
|
268
|
-
onClick={handleArrowBack}
|
|
269
|
-
/>
|
|
268
|
+
<TouchableOpacity onPress={() => handleArrowBack()} style={styles.btnBackArrow}>
|
|
269
|
+
<OIcon src={theme.images.general.arrow_left} color={theme.colors.textGray} />
|
|
270
|
+
</TouchableOpacity>
|
|
270
271
|
|
|
271
272
|
<OText size={16} style={styles.modalText} adjustsFontSizeToFit>
|
|
272
273
|
{`${t('INVOICE_ORDER_NO', 'Order No.')} ${order?.id}`}
|
|
@@ -292,7 +293,7 @@ export const OrderMessageUI = (props: OrderDetailsParams) => {
|
|
|
292
293
|
<OIcon
|
|
293
294
|
url={optimizeImage(
|
|
294
295
|
order?.customer?.photo ||
|
|
295
|
-
|
|
296
|
+
theme?.images?.dummies?.customerPhoto,
|
|
296
297
|
'h_300,c_limit',
|
|
297
298
|
)}
|
|
298
299
|
style={styles.titleIcons}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React, { useEffect, useState, useRef } from 'react';
|
|
2
|
-
import { View, Pressable, StyleSheet, ScrollView, RefreshControl, Platform } from 'react-native';
|
|
2
|
+
import { View, Pressable, StyleSheet, ScrollView, RefreshControl, Platform, TouchableOpacity } from 'react-native';
|
|
3
3
|
import { useLanguage, useUtils, useToast, OrderListGroups, useConfig } from 'ordering-components/native';
|
|
4
4
|
import SelectDropdown from 'react-native-select-dropdown'
|
|
5
5
|
import { Placeholder, PlaceholderLine, Fade } from 'rn-placeholder';
|
|
@@ -239,6 +239,19 @@ const OrdersOptionUI = (props: OrdersOptionParams) => {
|
|
|
239
239
|
overflow: 'hidden',
|
|
240
240
|
minHeight: 155
|
|
241
241
|
},
|
|
242
|
+
btnBackArrow: {
|
|
243
|
+
borderWidth: 0,
|
|
244
|
+
width: 32,
|
|
245
|
+
height: 32,
|
|
246
|
+
tintColor: theme.colors.textGray,
|
|
247
|
+
backgroundColor: theme.colors.clear,
|
|
248
|
+
borderColor: theme.colors.clear,
|
|
249
|
+
shadowColor: theme.colors.clear,
|
|
250
|
+
paddingLeft: 0,
|
|
251
|
+
paddingRight: 0,
|
|
252
|
+
marginBottom: 30,
|
|
253
|
+
marginTop: 30
|
|
254
|
+
},
|
|
242
255
|
rowStyle: {
|
|
243
256
|
display: 'flex',
|
|
244
257
|
borderBottomWidth: 0,
|
|
@@ -696,20 +709,9 @@ const OrdersOptionUI = (props: OrdersOptionParams) => {
|
|
|
696
709
|
<ModalContainer
|
|
697
710
|
nestedScrollEnabled={true}
|
|
698
711
|
>
|
|
699
|
-
<
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
iconColor={theme.colors.backArrow}
|
|
703
|
-
iconStyle={{ width: 20, height: 13 }}
|
|
704
|
-
style={{
|
|
705
|
-
maxWidth: 40,
|
|
706
|
-
height: 35,
|
|
707
|
-
justifyContent: 'flex-end',
|
|
708
|
-
marginBottom: 30,
|
|
709
|
-
marginTop: 30
|
|
710
|
-
}}
|
|
711
|
-
onClick={() => handleClose()}
|
|
712
|
-
/>
|
|
712
|
+
<TouchableOpacity onPress={() => handleClose()} style={styles.btnBackArrow}>
|
|
713
|
+
<OIcon src={theme.images.general.arrow_left} color={theme.colors.textGray} />
|
|
714
|
+
</TouchableOpacity>
|
|
713
715
|
{openSearchModal && (
|
|
714
716
|
<SearchModalContent>
|
|
715
717
|
<ModalTitle>{t('SEARCH_ORDERS', 'Search orders')}</ModalTitle>
|
|
@@ -48,8 +48,13 @@ export const PreviousOrders = (props: any) => {
|
|
|
48
48
|
if (props.handleClickEvent) {
|
|
49
49
|
props.handleClickEvent({ ...order, isLogistic: isLogisticOrder })
|
|
50
50
|
} else {
|
|
51
|
-
|
|
52
|
-
onNavigationRedirect
|
|
51
|
+
if (isLogisticOrder){
|
|
52
|
+
onNavigationRedirect &&
|
|
53
|
+
onNavigationRedirect('OrderDetailsLogistic', { order: { ...order, isLogistic: isLogisticOrder }, handleClickLogisticOrder });
|
|
54
|
+
} else {
|
|
55
|
+
onNavigationRedirect &&
|
|
56
|
+
onNavigationRedirect('OrderDetails', { order });
|
|
57
|
+
}
|
|
53
58
|
}
|
|
54
59
|
};
|
|
55
60
|
|
|
@@ -3,6 +3,10 @@ import { View, Animated, TouchableOpacity } from 'react-native';
|
|
|
3
3
|
import MaterialCommunityIcon from 'react-native-vector-icons/MaterialCommunityIcons';
|
|
4
4
|
import { useUtils, useLanguage } from 'ordering-components/native';
|
|
5
5
|
import { useTheme } from 'styled-components/native';
|
|
6
|
+
import { DeviceOrientationMethods } from '../../../../../src/hooks/DeviceOrientation'
|
|
7
|
+
|
|
8
|
+
const { useDeviceOrientation } = DeviceOrientationMethods
|
|
9
|
+
|
|
6
10
|
import {
|
|
7
11
|
Accordion,
|
|
8
12
|
AccordionSection,
|
|
@@ -34,6 +38,8 @@ export const ProductItemAccordion = (props: ProductItemAccordionParams) => {
|
|
|
34
38
|
const [, t] = useLanguage();
|
|
35
39
|
const theme = useTheme();
|
|
36
40
|
const [{ parsePrice }] = useUtils();
|
|
41
|
+
const [orientationState] = useDeviceOrientation();
|
|
42
|
+
const WIDTH_SCREEN = orientationState?.dimensions?.width
|
|
37
43
|
|
|
38
44
|
const [isActive, setActiveState] = useState(false);
|
|
39
45
|
const [isReadMore, setIsReadMore] = useState(false);
|
|
@@ -111,7 +117,7 @@ export const ProductItemAccordion = (props: ProductItemAccordionParams) => {
|
|
|
111
117
|
}, []);
|
|
112
118
|
|
|
113
119
|
const onTextLayout = useCallback((e: any) => {
|
|
114
|
-
setLengthMore(e.nativeEvent.lines.length
|
|
120
|
+
setLengthMore((e.nativeEvent.lines.length == 2 && e.nativeEvent.lines[1].width > WIDTH_SCREEN * .76) || e.nativeEvent.lines.length > 2); //to check the text is more than 2 lines or not
|
|
115
121
|
},[]);
|
|
116
122
|
|
|
117
123
|
return (
|
|
@@ -86,6 +86,18 @@ const ReviewCustomerUI = (props: ReviewCustomerParams) => {
|
|
|
86
86
|
marginBottom: 10,
|
|
87
87
|
backgroundColor: theme.colors.lightGray
|
|
88
88
|
},
|
|
89
|
+
btnBackArrow: {
|
|
90
|
+
borderWidth: 0,
|
|
91
|
+
width: 32,
|
|
92
|
+
height: 32,
|
|
93
|
+
tintColor: theme.colors.textGray,
|
|
94
|
+
backgroundColor: theme.colors.clear,
|
|
95
|
+
borderColor: theme.colors.clear,
|
|
96
|
+
shadowColor: theme.colors.clear,
|
|
97
|
+
paddingLeft: 0,
|
|
98
|
+
paddingRight: 0,
|
|
99
|
+
marginBottom: 20
|
|
100
|
+
},
|
|
89
101
|
inputTextArea: {
|
|
90
102
|
borderColor: theme.colors.lightGray,
|
|
91
103
|
borderRadius: 8,
|
|
@@ -177,18 +189,9 @@ const ReviewCustomerUI = (props: ReviewCustomerParams) => {
|
|
|
177
189
|
}}
|
|
178
190
|
>
|
|
179
191
|
<View>
|
|
180
|
-
<
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
iconStyle={{ width: 20, height: 16 }}
|
|
184
|
-
style={{
|
|
185
|
-
maxWidth: 40,
|
|
186
|
-
height: 20,
|
|
187
|
-
justifyContent: 'flex-end',
|
|
188
|
-
marginBottom: 20,
|
|
189
|
-
}}
|
|
190
|
-
onClick={() => closeModal()}
|
|
191
|
-
/>
|
|
192
|
+
<TouchableOpacity onPress={() => closeModal()} style={styles.btnBackArrow}>
|
|
193
|
+
<OIcon src={theme.images.general.arrow_left} color={theme.colors.textGray} />
|
|
194
|
+
</TouchableOpacity>
|
|
192
195
|
<OText
|
|
193
196
|
size={20}
|
|
194
197
|
weight="600"
|
|
@@ -25,18 +25,18 @@ export interface LoginParams {
|
|
|
25
25
|
enableReCaptcha?: any;
|
|
26
26
|
|
|
27
27
|
otpType?: string,
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
28
|
+
setOtpType: (type: string) => void,
|
|
29
|
+
generateOtpCode: (values?: any) => void,
|
|
30
|
+
useLoginOtpEmail?: boolean,
|
|
31
|
+
useLoginOtpCellphone?: boolean,
|
|
32
|
+
useLoginOtp?: boolean
|
|
33
33
|
}
|
|
34
34
|
export interface otpParams {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
35
|
+
willVerifyOtpState: boolean,
|
|
36
|
+
setWillVerifyOtpState: (val: boolean) => void,
|
|
37
|
+
onSubmit: () => void,
|
|
38
|
+
handleLoginOtp: (code: string) => void,
|
|
39
|
+
setAlertState: any,
|
|
40
40
|
formState?: any
|
|
41
41
|
}
|
|
42
42
|
export interface ProfileParams {
|
|
@@ -612,3 +612,10 @@ export interface ReviewCustomerParams {
|
|
|
612
612
|
export interface NoNetworkParams {
|
|
613
613
|
image?: any;
|
|
614
614
|
}
|
|
615
|
+
|
|
616
|
+
export interface OrderDetailsLogisticParams {
|
|
617
|
+
navigation: any,
|
|
618
|
+
handleClickLogisticOrder: any,
|
|
619
|
+
orderAssingId: number,
|
|
620
|
+
order: any
|
|
621
|
+
}
|
|
@@ -369,3 +369,30 @@ export const formatSeconds = (seconds : number) => {
|
|
|
369
369
|
ret += '' + secs
|
|
370
370
|
return ret
|
|
371
371
|
}
|
|
372
|
+
|
|
373
|
+
export const calculateDistance = (
|
|
374
|
+
pointA: { lat: number; lng: number },
|
|
375
|
+
pointB: { latitude: number; longitude: number },
|
|
376
|
+
) => {
|
|
377
|
+
const lat1 = pointA.lat;
|
|
378
|
+
const lon1 = pointA.lng;
|
|
379
|
+
|
|
380
|
+
const lat2 = pointB.latitude;
|
|
381
|
+
const lon2 = pointB.longitude;
|
|
382
|
+
|
|
383
|
+
const R = 6371e3;
|
|
384
|
+
const φ1 = lat1 * (Math.PI / 180);
|
|
385
|
+
const φ2 = lat2 * (Math.PI / 180);
|
|
386
|
+
const Δφ = (lat2 - lat1) * (Math.PI / 180);
|
|
387
|
+
const Δλ = (lon2 - lon1) * (Math.PI / 180);
|
|
388
|
+
|
|
389
|
+
const a =
|
|
390
|
+
Math.sin(Δφ / 2) * Math.sin(Δφ / 2) +
|
|
391
|
+
Math.cos(φ1) * Math.cos(φ2) * (Math.sin(Δλ / 2) * Math.sin(Δλ / 2));
|
|
392
|
+
|
|
393
|
+
const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
|
|
394
|
+
|
|
395
|
+
const distance = R * c;
|
|
396
|
+
const distanceInKm = distance / 1000;
|
|
397
|
+
return distanceInKm;
|
|
398
|
+
};
|
|
@@ -415,7 +415,7 @@ const BusinessProductsListingUI = (props: BusinessProductsListingParams) => {
|
|
|
415
415
|
<BackgroundGray isIos={Platform.OS === 'ios'} />
|
|
416
416
|
)}
|
|
417
417
|
<IOScrollView
|
|
418
|
-
stickyHeaderIndices={[business?.professionals?.length > 0 ?
|
|
418
|
+
stickyHeaderIndices={[business?.professionals?.length > 0 ? 3 : 2]}
|
|
419
419
|
style={{
|
|
420
420
|
...styles.mainContainer,
|
|
421
421
|
marginBottom: currentCart?.products?.length > 0 && categoryState.products.length !== 0 ?
|
|
@@ -24,6 +24,7 @@ const DriverTipsUI = (props: any) => {
|
|
|
24
24
|
driverTipsOptions,
|
|
25
25
|
isMulti,
|
|
26
26
|
cart,
|
|
27
|
+
carts,
|
|
27
28
|
isDriverTipUseCustom,
|
|
28
29
|
handlerChangeOption,
|
|
29
30
|
isFixedPrice
|
|
@@ -64,6 +65,10 @@ const DriverTipsUI = (props: any) => {
|
|
|
64
65
|
setvalue(val)
|
|
65
66
|
}
|
|
66
67
|
|
|
68
|
+
const multiCartTipsAmmout = carts?.reduce((total: any, cart: any) => {
|
|
69
|
+
return total + parseFloat(cart?.driver_tip || 0)
|
|
70
|
+
}, 0)
|
|
71
|
+
|
|
67
72
|
return (
|
|
68
73
|
<DTContainer>
|
|
69
74
|
<DTLabel>
|
|
@@ -138,7 +143,7 @@ const DriverTipsUI = (props: any) => {
|
|
|
138
143
|
style={{ marginTop: 10, textAlign: 'center' }}
|
|
139
144
|
>
|
|
140
145
|
{t('CURRENT_DRIVER_TIP_AMOUNT', 'Current driver tip amount')}{!isFixedPrice &&
|
|
141
|
-
` (${driverTip}%)`}: {isFixedPrice ? parsePrice(driverTip) : parsePrice(cart?.driver_tip)}
|
|
146
|
+
` (${driverTip}%)`}: {isFixedPrice ? parsePrice(multiCartTipsAmmout ?? driverTip) : parsePrice(multiCartTipsAmmout ?? cart?.driver_tip)}
|
|
142
147
|
</OText>
|
|
143
148
|
)}
|
|
144
149
|
</DTContainer>
|
|
@@ -383,39 +383,45 @@ const MomentOptionUI = (props: MomentOptionParams) => {
|
|
|
383
383
|
)}
|
|
384
384
|
<OText color={optionSelected.isSchedule ? theme.colors.textNormal : theme.colors.disabled}>{t('SCHEDULE_FOR_LATER', 'Schedule for later')}</OText>
|
|
385
385
|
</WrapSelectOption>
|
|
386
|
-
|
|
387
386
|
{optionSelected.isSchedule && (
|
|
388
387
|
<OrderTimeWrapper>
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
388
|
+
{datesWhitelist?.length <= 1 && (
|
|
389
|
+
<OText>
|
|
390
|
+
{moment(selectDate).format('Do MMMM, YYYY')}
|
|
391
|
+
</OText>
|
|
392
|
+
)}
|
|
393
|
+
{datesWhitelist > 1 && (
|
|
394
|
+
<View style={{ flex: 1 }}>
|
|
395
|
+
{selectDate && datesWhitelist[0]?.start !== null && (
|
|
396
|
+
<CalendarStrip
|
|
397
|
+
scrollable
|
|
398
|
+
locale={locale}
|
|
399
|
+
style={styles.calendar}
|
|
400
|
+
calendarHeaderContainerStyle={styles.calendarHeaderContainer}
|
|
401
|
+
calendarHeaderStyle={styles.calendarHeader}
|
|
402
|
+
dateNumberStyle={styles.dateNumber}
|
|
403
|
+
dateNameStyle={styles.dateName}
|
|
404
|
+
iconContainer={{ flex: 0.1 }}
|
|
405
|
+
highlightDateNameStyle={styles.highlightDateName}
|
|
406
|
+
highlightDateNumberStyle={styles.highlightDateNumber}
|
|
407
|
+
dayContainerStyle={{ height: '100%' }}
|
|
408
|
+
highlightDateContainerStyle={{ height: '100%' }}
|
|
409
|
+
calendarHeaderFormat='MMMM, YYYY'
|
|
410
|
+
iconStyle={{ borderWidth: 1 }}
|
|
411
|
+
selectedDate={dateSelected}
|
|
412
|
+
datesWhitelist={datesWhitelist}
|
|
413
|
+
minDate={moment()}
|
|
414
|
+
maxDate={cateringPreorder ? moment().add(preorderMaximumDays, 'days') : undefined}
|
|
415
|
+
disabledDateNameStyle={styles.disabledDateName}
|
|
416
|
+
disabledDateNumberStyle={styles.disabledDateNumber}
|
|
417
|
+
disabledDateOpacity={0.6}
|
|
418
|
+
onDateSelected={(date) => onSelectDate(date)}
|
|
419
|
+
leftSelector={<LeftSelector />}
|
|
420
|
+
rightSelector={<RightSelector />}
|
|
421
|
+
/>
|
|
422
|
+
)}
|
|
423
|
+
</View>
|
|
424
|
+
)}
|
|
419
425
|
<TimeListWrapper nestedScrollEnabled={true} cateringPreorder={cateringPreorder}>
|
|
420
426
|
<TimeContentWrapper>
|
|
421
427
|
{timeList.map((time: any, i: number) => (
|
|
@@ -481,9 +481,9 @@ export const ProductOptionsUI = (props: any) => {
|
|
|
481
481
|
: t('LOGIN_SIGNUP', 'Login / Sign Up')
|
|
482
482
|
}
|
|
483
483
|
imgRightSrc=""
|
|
484
|
-
textStyle={{ color: theme.colors.primary, fontSize:
|
|
484
|
+
textStyle={{ color: theme.colors.primary, fontSize: 13, textAlign: 'center' }}
|
|
485
485
|
style={{
|
|
486
|
-
height:
|
|
486
|
+
height: 42,
|
|
487
487
|
borderColor: theme.colors.primary,
|
|
488
488
|
backgroundColor: theme.colors.white,
|
|
489
489
|
paddingLeft: 0,
|
|
@@ -498,7 +498,7 @@ export const ProductOptionsUI = (props: any) => {
|
|
|
498
498
|
<PlaceholderLine width={60} height={20} />
|
|
499
499
|
</Placeholder>
|
|
500
500
|
) : (
|
|
501
|
-
<OText color={theme.colors.primary} size={13}>{t('WITH_GUEST_USER', 'With Guest user')}</OText>
|
|
501
|
+
<OText color={theme.colors.primary} size={13} style={{ textAlign: 'center' }}>{t('WITH_GUEST_USER', 'With Guest user')}</OText>
|
|
502
502
|
)}
|
|
503
503
|
</TouchableOpacity>
|
|
504
504
|
)}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React, { useState, useEffect, useRef } from 'react'
|
|
2
|
-
import { StyleSheet, Platform, View, Dimensions } from 'react-native'
|
|
2
|
+
import { StyleSheet, Platform, View, Dimensions, Text } from 'react-native'
|
|
3
3
|
import { useUtils, useLanguage, useConfig } from 'ordering-components/native'
|
|
4
4
|
import { useTheme } from 'styled-components/native'
|
|
5
5
|
import CalendarPicker from 'react-native-calendar-picker'
|
|
@@ -60,7 +60,12 @@ export const ProfessionalProfile = (props: ProfessionalProfileParams) => {
|
|
|
60
60
|
},
|
|
61
61
|
photoStyle: {
|
|
62
62
|
alignSelf: 'center'
|
|
63
|
-
}
|
|
63
|
+
},
|
|
64
|
+
dropDownRow: {
|
|
65
|
+
color: theme.colors.primary,
|
|
66
|
+
fontSize: 14,
|
|
67
|
+
marginHorizontal: 0
|
|
68
|
+
},
|
|
64
69
|
})
|
|
65
70
|
|
|
66
71
|
const onDateChange = (date: any) => {
|
|
@@ -92,6 +97,28 @@ export const ProfessionalProfile = (props: ProfessionalProfileParams) => {
|
|
|
92
97
|
setIsEnabled(menu?.schedule?.[day]?.enabled || false)
|
|
93
98
|
}
|
|
94
99
|
|
|
100
|
+
const getMomentTime = (time) => {
|
|
101
|
+
const _moment = moment(`${moment(selectDate).format('YYYY-MM-DD')} ${time}`, 'YYYY-MM-DD HH:mm').toDate()
|
|
102
|
+
return _moment
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
const isBusyTime = (professional, selectedMoment) => {
|
|
106
|
+
if (!selectedMoment) return false
|
|
107
|
+
const startDay = moment(selectedMoment).utc().format('d')
|
|
108
|
+
const isStartScheduleEnabled = professional?.schedule?.[startDay]?.enabled
|
|
109
|
+
if (!isStartScheduleEnabled) return true
|
|
110
|
+
|
|
111
|
+
if (professional?.busy_times?.length === 0) return false
|
|
112
|
+
|
|
113
|
+
const busyTimes = professional?.busy_times
|
|
114
|
+
|
|
115
|
+
const valid = busyTimes.some(item => {
|
|
116
|
+
return (moment.utc(item?.start).local().valueOf() <= moment(selectedMoment).valueOf() &&
|
|
117
|
+
moment(selectedMoment).valueOf() < moment.utc(item?.end).local().valueOf())
|
|
118
|
+
})
|
|
119
|
+
return valid
|
|
120
|
+
}
|
|
121
|
+
|
|
95
122
|
const getTimes = (curdate: any, menu: any) => {
|
|
96
123
|
validateSelectedDate(curdate, menu)
|
|
97
124
|
const date = new Date()
|
|
@@ -238,10 +265,12 @@ export const ProfessionalProfile = (props: ProfessionalProfileParams) => {
|
|
|
238
265
|
paddingTop: 8,
|
|
239
266
|
paddingHorizontal: 12
|
|
240
267
|
}}
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
268
|
+
renderCustomizedRowChild={(item, index) => {
|
|
269
|
+
return (
|
|
270
|
+
<Text style={[styles.dropDownRow, { color: isBusyTime(professional, getMomentTime(item.value)) ? theme.colors.lightGray : theme.colors.primary } ]}>
|
|
271
|
+
{item.text}
|
|
272
|
+
</Text>
|
|
273
|
+
)
|
|
245
274
|
}}
|
|
246
275
|
renderDropdownIcon={() => dropDownIcon()}
|
|
247
276
|
dropdownOverlayColor='transparent'
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React, { useState, useEffect, useRef } from 'react'
|
|
2
2
|
import { useTheme } from 'styled-components/native'
|
|
3
|
-
import { Platform, View, StyleSheet, Dimensions, ScrollView, TouchableOpacity } from 'react-native'
|
|
3
|
+
import { Platform, View, StyleSheet, Dimensions, ScrollView, TouchableOpacity, Text } from 'react-native'
|
|
4
4
|
import { OText, OButton, OModal, OIcon } from '../shared'
|
|
5
5
|
import FastImage from 'react-native-fast-image'
|
|
6
6
|
import IconAntDesign from 'react-native-vector-icons/AntDesign'
|
|
@@ -110,31 +110,41 @@ const ServiceFormUI = (props: ServiceFormParams) => {
|
|
|
110
110
|
height: 40,
|
|
111
111
|
marginBottom: 30
|
|
112
112
|
},
|
|
113
|
+
dropDownRow: {
|
|
114
|
+
color: theme.colors.primary,
|
|
115
|
+
fontSize: 14,
|
|
116
|
+
marginHorizontal: 0
|
|
117
|
+
},
|
|
113
118
|
professionalList: {
|
|
114
119
|
paddingHorizontal: 40,
|
|
115
|
-
paddingVertical: 30
|
|
120
|
+
paddingVertical: 30,
|
|
116
121
|
}
|
|
117
122
|
})
|
|
118
123
|
|
|
119
|
-
const
|
|
120
|
-
|
|
121
|
-
|
|
124
|
+
const getMomentTime = (time) => {
|
|
125
|
+
const _moment = moment(`${moment(selectDate).format('YYYY-MM-DD')} ${time}`, 'YYYY-MM-DD HH:mm').toDate()
|
|
126
|
+
return _moment
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
const isBusyTime = (professional, selectedMoment) => {
|
|
130
|
+
if (!selectedMoment) return false
|
|
131
|
+
const startDay = moment(selectedMoment).utc().format('d')
|
|
122
132
|
const isStartScheduleEnabled = professional?.schedule?.[startDay]?.enabled
|
|
123
133
|
const duration = product?.duration ?? 0
|
|
124
|
-
const endDay = moment(
|
|
134
|
+
const endDay = moment(selectedMoment).add(duration - 1, 'minutes').utc().format('d')
|
|
125
135
|
const isEndScheduleEnabled = professional?.schedule?.[endDay]?.enabled
|
|
126
136
|
if (!isStartScheduleEnabled || !isEndScheduleEnabled) return true
|
|
127
137
|
|
|
128
138
|
if (professional?.busy_times?.length === 0) return false
|
|
129
|
-
|
|
139
|
+
|
|
130
140
|
const busyTimes = isCartProduct
|
|
131
|
-
? professional?.busy_times.filter(
|
|
141
|
+
? professional?.busy_times.filter(item => !(item.start === productCart?.calendar_event?.start && item.end === productCart?.calendar_event?.end))
|
|
132
142
|
: [...professional?.busy_times]
|
|
133
|
-
const valid = busyTimes.some(
|
|
134
|
-
return (moment.utc(item?.start).local().valueOf() <= moment(
|
|
135
|
-
moment(
|
|
136
|
-
(moment.utc(item?.start).local().valueOf()
|
|
137
|
-
moment(
|
|
143
|
+
const valid = busyTimes.some(item => {
|
|
144
|
+
return (moment.utc(item?.start).local().valueOf() <= moment(selectedMoment).valueOf() &&
|
|
145
|
+
moment(selectedMoment).valueOf() < moment.utc(item?.end).local().valueOf()) ||
|
|
146
|
+
(moment.utc(item?.start).local().valueOf() < moment(selectedMoment).add(duration, 'minutes').valueOf() &&
|
|
147
|
+
moment(selectedMoment).add(duration, 'minutes').valueOf() < moment.utc(item?.end).local().valueOf())
|
|
138
148
|
})
|
|
139
149
|
return valid
|
|
140
150
|
}
|
|
@@ -391,9 +401,9 @@ const ServiceFormUI = (props: ServiceFormParams) => {
|
|
|
391
401
|
size={12}
|
|
392
402
|
weight={'400'}
|
|
393
403
|
lineHeight={17}
|
|
394
|
-
color={isBusyTime(currentProfessional) ? theme.colors.danger5 : theme.colors.success500}
|
|
404
|
+
color={isBusyTime(currentProfessional, dateSelected) ? theme.colors.danger5 : theme.colors.success500}
|
|
395
405
|
>
|
|
396
|
-
{isBusyTime(currentProfessional)
|
|
406
|
+
{isBusyTime(currentProfessional, dateSelected)
|
|
397
407
|
? t('BUSY_ON_SELECTED_TIME', 'Busy on selected time')
|
|
398
408
|
: t('AVAILABLE', 'Available')
|
|
399
409
|
}
|
|
@@ -473,10 +483,12 @@ const ServiceFormUI = (props: ServiceFormParams) => {
|
|
|
473
483
|
paddingTop: 8,
|
|
474
484
|
paddingHorizontal: 12
|
|
475
485
|
}}
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
486
|
+
renderCustomizedRowChild={(item, index) => {
|
|
487
|
+
return (
|
|
488
|
+
<Text style={[styles.dropDownRow, { color: isBusyTime(currentProfessional, getMomentTime(item.value)) ? theme.colors.lightGray : theme.colors.primary } ]}>
|
|
489
|
+
{item.text}
|
|
490
|
+
</Text>
|
|
491
|
+
)
|
|
480
492
|
}}
|
|
481
493
|
renderDropdownIcon={() => dropDownIcon()}
|
|
482
494
|
dropdownOverlayColor='transparent'
|
|
@@ -549,7 +561,7 @@ const ServiceFormUI = (props: ServiceFormParams) => {
|
|
|
549
561
|
? t('SOLD_OUT', 'Sold out')
|
|
550
562
|
: t('BOOK', 'Book'))}
|
|
551
563
|
style={styles.buttonStyle}
|
|
552
|
-
isDisabled={isSoldOut || maxProductQuantity <= 0 || !currentProfessional?.id || !dateSelected || isBusyTime(currentProfessional)}
|
|
564
|
+
isDisabled={isSoldOut || maxProductQuantity <= 0 || !currentProfessional?.id || !dateSelected || isBusyTime(currentProfessional, dateSelected)}
|
|
553
565
|
textStyle={{ fontSize: 14, color: theme.colors.white }}
|
|
554
566
|
/>
|
|
555
567
|
)}
|
|
@@ -647,9 +659,9 @@ const ServiceFormUI = (props: ServiceFormParams) => {
|
|
|
647
659
|
size={12}
|
|
648
660
|
weight={'400'}
|
|
649
661
|
lineHeight={17}
|
|
650
|
-
color={isBusyTime(professional) ? theme.colors.danger5 : theme.colors.success500}
|
|
662
|
+
color={isBusyTime(professional, dateSelected) ? theme.colors.danger5 : theme.colors.success500}
|
|
651
663
|
>
|
|
652
|
-
{isBusyTime(professional)
|
|
664
|
+
{isBusyTime(professional, dateSelected)
|
|
653
665
|
? t('BUSY_ON_SELECTED_TIME', 'Busy on selected time')
|
|
654
666
|
: t('AVAILABLE', 'Available')
|
|
655
667
|
}
|