ordering-ui-react-native 0.12.10 → 0.12.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +2 -1
- package/src/assets/images/business_list_banner.jpg +0 -0
- package/src/components/Account/index.tsx +2 -2
- package/src/components/GoogleMap/index.tsx +12 -1
- package/src/components/OrderDetails/index.tsx +3 -4
- package/src/config.json +2 -2
- package/themes/business/src/components/AcceptOrRejectOrder/index.tsx +10 -4
- package/themes/business/src/components/MapView/index.tsx +4 -4
- package/themes/business/src/components/NewOrderNotification/index.tsx +20 -6
- package/themes/business/src/components/OrderDetails/Delivery.tsx +8 -7
- package/themes/business/src/components/OrderDetails/OrderContentComponent.tsx +13 -0
- package/themes/business/src/components/OrdersOption/index.tsx +103 -102
- package/themes/business/src/types/index.tsx +1 -0
- package/themes/original/index.tsx +2 -0
- package/themes/original/src/components/BusinessesListing/index.tsx +7 -0
- package/themes/original/src/components/BusinessesListing/styles.tsx +6 -1
- package/themes/original/src/components/OrderProgress/index.tsx +208 -0
- package/themes/original/src/components/OrderProgress/styles.tsx +30 -0
- package/themes/original/src/components/ProductForm/index.tsx +159 -56
- package/themes/original/src/components/ProductForm/styles.tsx +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ordering-ui-react-native",
|
|
3
|
-
"version": "0.12.
|
|
3
|
+
"version": "0.12.14",
|
|
4
4
|
"description": "Reusable components made in react native",
|
|
5
5
|
"main": "src/index.tsx",
|
|
6
6
|
"author": "ordering.inc",
|
|
@@ -100,6 +100,7 @@
|
|
|
100
100
|
"react-native-snap-carousel": "^3.9.1",
|
|
101
101
|
"react-native-sound": "^0.11.1",
|
|
102
102
|
"react-native-swipe-gestures": "^1.0.5",
|
|
103
|
+
"react-native-swiper": "^1.6.0",
|
|
103
104
|
"react-native-uuid": "^2.0.1",
|
|
104
105
|
"react-native-vector-icons": "^7.1.0",
|
|
105
106
|
"react-native-webview": "^11.6.4",
|
|
Binary file
|
|
@@ -73,8 +73,8 @@ const AccountUI = (props: AccountParams) => {
|
|
|
73
73
|
console.log('ImagePicker Error: ', response.errorMessage);
|
|
74
74
|
showToast(ToastType.Error, response.errorMessage);
|
|
75
75
|
} else {
|
|
76
|
-
if (response
|
|
77
|
-
const url = `data:${response.type};base64,${response.base64}`
|
|
76
|
+
if (response?.assets) {
|
|
77
|
+
const url = `data:${response.assets[0].type};base64,${response.assets[0].base64}`
|
|
78
78
|
handleButtonUpdateClick(null, true, url);
|
|
79
79
|
} else {
|
|
80
80
|
showToast(ToastType.Error, t('IMAGE_NOT_FOUND', 'Image not found'));
|
|
@@ -41,7 +41,7 @@ export const GoogleMap = (props: GoogleMapsParams) => {
|
|
|
41
41
|
ERROR_NOT_FOUND_ADDRESS: 'Sorry, we couldn\'t find an address',
|
|
42
42
|
ERROR_MAX_LIMIT_LOCATION_TO: 'Sorry, You can only set the position to'
|
|
43
43
|
}
|
|
44
|
-
|
|
44
|
+
let MARKERS = locations && locations.map((location: { lat: number, lng: number }) => {
|
|
45
45
|
return {
|
|
46
46
|
latitude: location.lat,
|
|
47
47
|
longitude: location.lng
|
|
@@ -176,6 +176,17 @@ export const GoogleMap = (props: GoogleMapsParams) => {
|
|
|
176
176
|
return () => clearInterval(interval)
|
|
177
177
|
}, [locations])
|
|
178
178
|
|
|
179
|
+
useEffect(() => {
|
|
180
|
+
if(!locations) return
|
|
181
|
+
locations[0] = {...locations[0], lat: location.lat, lng: location.lng}
|
|
182
|
+
MARKERS = locations && locations.map((location: { lat: number, lng: number }) => {
|
|
183
|
+
return {
|
|
184
|
+
latitude: location.lat,
|
|
185
|
+
longitude: location.lng
|
|
186
|
+
}
|
|
187
|
+
})
|
|
188
|
+
}, [location])
|
|
189
|
+
|
|
179
190
|
return (
|
|
180
191
|
<>
|
|
181
192
|
<MapView
|
|
@@ -208,7 +208,7 @@ export const OrderDetailsUI = (props: OrderDetailsParams) => {
|
|
|
208
208
|
}
|
|
209
209
|
}, [messagesReadList])
|
|
210
210
|
|
|
211
|
-
|
|
211
|
+
let locations = [
|
|
212
212
|
{ ...order?.driver?.location, title: t('DRIVER', 'Driver'), icon: order?.driver?.photo || 'https://res.cloudinary.com/demo/image/fetch/c_thumb,g_face,r_max/https://www.freeiconspng.com/thumbs/driver-icon/driver-icon-14.png' },
|
|
213
213
|
{ ...order?.business?.location, title: order?.business?.name, icon: order?.business?.logo || theme.images.dummies.businessLogo },
|
|
214
214
|
{ ...order?.customer?.location, title: t('YOUR_LOCATION', 'Your Location'), icon: order?.customer?.photo || 'https://res.cloudinary.com/demo/image/upload/c_thumb,g_face,r_max/d_avatar.png/non_existing_id.png' }
|
|
@@ -216,7 +216,7 @@ export const OrderDetailsUI = (props: OrderDetailsParams) => {
|
|
|
216
216
|
|
|
217
217
|
useEffect(() => {
|
|
218
218
|
if (driverLocation) {
|
|
219
|
-
locations[0] = driverLocation
|
|
219
|
+
locations[0] = {...locations[0], lat: driverLocation.lat, lng: driverLocation.lng}
|
|
220
220
|
}
|
|
221
221
|
}, [driverLocation])
|
|
222
222
|
|
|
@@ -361,9 +361,8 @@ export const OrderDetailsUI = (props: OrderDetailsParams) => {
|
|
|
361
361
|
{order?.driver?.location && parseInt(order?.status) === 9 && (
|
|
362
362
|
<Map>
|
|
363
363
|
<GoogleMap
|
|
364
|
-
location={order?.driver?.location}
|
|
364
|
+
location={driverLocation ?? order?.driver?.location}
|
|
365
365
|
locations={locations}
|
|
366
|
-
readOnly
|
|
367
366
|
/>
|
|
368
367
|
</Map>
|
|
369
368
|
)}
|
package/src/config.json
CHANGED
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
"app_id": "react-native-app",
|
|
3
3
|
"notification_app": "orderingapp",
|
|
4
4
|
"app_name": "Ordering",
|
|
5
|
-
"project": "
|
|
5
|
+
"project": "jorgev4",
|
|
6
6
|
"api": {
|
|
7
|
-
"url": "https://apiv4.ordering.co",
|
|
7
|
+
"url": "https://apiv4-staging.ordering.co",
|
|
8
8
|
"language": "en",
|
|
9
9
|
"version": "v400"
|
|
10
10
|
},
|
|
@@ -111,7 +111,7 @@ export const AcceptOrRejectOrder = (props: AcceptOrRejectOrderParams) => {
|
|
|
111
111
|
openTimerIOnput();
|
|
112
112
|
}
|
|
113
113
|
|
|
114
|
-
if (actions && action === 'reject') {
|
|
114
|
+
if (actions && (action === 'reject' || action === 'failed')) {
|
|
115
115
|
openTextTareaOInput();
|
|
116
116
|
}
|
|
117
117
|
}, []);
|
|
@@ -178,6 +178,10 @@ export const AcceptOrRejectOrder = (props: AcceptOrRejectOrderParams) => {
|
|
|
178
178
|
comment: comments,
|
|
179
179
|
status: 6,
|
|
180
180
|
},
|
|
181
|
+
failedByDriver: {
|
|
182
|
+
comment: comments,
|
|
183
|
+
status: 12
|
|
184
|
+
}
|
|
181
185
|
};
|
|
182
186
|
|
|
183
187
|
if (actions && action === 'accept') {
|
|
@@ -186,6 +190,9 @@ export const AcceptOrRejectOrder = (props: AcceptOrRejectOrderParams) => {
|
|
|
186
190
|
if (actions && action === 'reject') {
|
|
187
191
|
bodyToSend = orderStatus[actions.reject];
|
|
188
192
|
}
|
|
193
|
+
if(actions && action === 'failed'){
|
|
194
|
+
bodyToSend = orderStatus[actions.failed]
|
|
195
|
+
}
|
|
189
196
|
|
|
190
197
|
bodyToSend.id = orderId;
|
|
191
198
|
|
|
@@ -330,7 +337,6 @@ export const AcceptOrRejectOrder = (props: AcceptOrRejectOrderParams) => {
|
|
|
330
337
|
</Timer>
|
|
331
338
|
</View>
|
|
332
339
|
)}
|
|
333
|
-
|
|
334
340
|
<TimeField
|
|
335
341
|
ref={timerRef}
|
|
336
342
|
keyboardType="numeric"
|
|
@@ -346,11 +352,11 @@ export const AcceptOrRejectOrder = (props: AcceptOrRejectOrderParams) => {
|
|
|
346
352
|
onEndEditing={handleFixTime}
|
|
347
353
|
/>
|
|
348
354
|
|
|
349
|
-
{action === 'reject' && (
|
|
355
|
+
{(action === 'reject' || action === 'failed') && (
|
|
350
356
|
<Comments ref={viewRef}>
|
|
351
357
|
<OTextarea
|
|
352
358
|
textTareaRef={textTareaRef}
|
|
353
|
-
autoFocus={actions && action === 'reject'}
|
|
359
|
+
autoFocus={actions && (action === 'reject' || action === 'failed')}
|
|
354
360
|
onFocus={handleFocus}
|
|
355
361
|
placeholder={t(
|
|
356
362
|
'PLEASE_TYPE_YOUR_COMMENTS_IN_HERE',
|
|
@@ -42,7 +42,7 @@ const MapViewComponent = (props: MapViewParams) => {
|
|
|
42
42
|
} = useLocation();
|
|
43
43
|
|
|
44
44
|
const location = { lat: userLocation.latitude, lng: userLocation.longitude }
|
|
45
|
-
|
|
45
|
+
const haveOrders = Object.values(markerGroups)?.length > 0 && Object.values(customerMarkerGroups)?.length > 0
|
|
46
46
|
const closeAlert = () => {
|
|
47
47
|
setAlertState({
|
|
48
48
|
open: false,
|
|
@@ -222,8 +222,8 @@ const MapViewComponent = (props: MapViewParams) => {
|
|
|
222
222
|
initialRegion={{
|
|
223
223
|
latitude: initialPosition.latitude,
|
|
224
224
|
longitude: initialPosition.longitude,
|
|
225
|
-
latitudeDelta: 0.
|
|
226
|
-
longitudeDelta: 0.
|
|
225
|
+
latitudeDelta: haveOrders ? 0.01 : 0.1,
|
|
226
|
+
longitudeDelta: haveOrders ? 0.01 * ASPECT_RATIO : 0.1 * ASPECT_RATIO,
|
|
227
227
|
}}
|
|
228
228
|
style={{ flex: 1 }}
|
|
229
229
|
zoomTapEnabled
|
|
@@ -241,7 +241,7 @@ const MapViewComponent = (props: MapViewParams) => {
|
|
|
241
241
|
orderIds={marker.map((order: any) => order.id).join(', ')}
|
|
242
242
|
/>
|
|
243
243
|
))}
|
|
244
|
-
{Object.values(customerMarkerGroups).map((marker: any) =>
|
|
244
|
+
{Object.values(customerMarkerGroups).map((marker: any) => (
|
|
245
245
|
<RenderMarker
|
|
246
246
|
key={marker[0]?.customer_id}
|
|
247
247
|
marker={marker[0]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React, { useState, useEffect, useCallback } from 'react'
|
|
2
|
-
import { useEvent, useLanguage, useUtils, useSession } from 'ordering-components/native'
|
|
2
|
+
import { useEvent, useLanguage, useUtils, useSession, useApi } from 'ordering-components/native'
|
|
3
3
|
import { View, Modal, StyleSheet, TouchableOpacity, Dimensions } from 'react-native'
|
|
4
4
|
import { OText, OIcon } from '../shared'
|
|
5
5
|
import { useTheme } from 'styled-components/native'
|
|
@@ -7,7 +7,7 @@ import Icon from 'react-native-vector-icons/Feather'
|
|
|
7
7
|
import { NotificationContainer } from './styles'
|
|
8
8
|
import Sound from 'react-native-sound'
|
|
9
9
|
import moment from 'moment'
|
|
10
|
-
|
|
10
|
+
import { useLocation } from '../../hooks/useLocation'
|
|
11
11
|
Sound.setCategory('Playback')
|
|
12
12
|
|
|
13
13
|
const windowWidth = Dimensions.get('screen').width
|
|
@@ -16,9 +16,10 @@ export const NewOrderNotification = (props: any) => {
|
|
|
16
16
|
const [events] = useEvent()
|
|
17
17
|
const theme = useTheme()
|
|
18
18
|
const [, t] = useLanguage()
|
|
19
|
-
const [{ user }] = useSession()
|
|
19
|
+
const [{ user, token }] = useSession()
|
|
20
|
+
const [ordering] = useApi()
|
|
20
21
|
const [{ getTimeAgo }] = useUtils()
|
|
21
|
-
|
|
22
|
+
const { getCurrentLocation } = useLocation();
|
|
22
23
|
const [modalOpen, setModalOpen] = useState(false)
|
|
23
24
|
const [newOrderId, setNewOrderId] = useState(null)
|
|
24
25
|
const [soundTimeout, setSoundTimeout] = useState<any>(null)
|
|
@@ -33,15 +34,21 @@ export const NewOrderNotification = (props: any) => {
|
|
|
33
34
|
|
|
34
35
|
|
|
35
36
|
const handlePlayNotificationSound = () => {
|
|
37
|
+
let times = 0
|
|
36
38
|
const _timeout = setInterval(function () {
|
|
37
39
|
notificationSound.play(success => {
|
|
38
40
|
if (success) {
|
|
39
41
|
console.log('successfully finished playing');
|
|
42
|
+
times = times + 1
|
|
40
43
|
} else {
|
|
41
44
|
console.log('playback failed due to audio decoding errors');
|
|
42
45
|
}
|
|
43
46
|
})
|
|
44
47
|
setSoundTimeout(_timeout)
|
|
48
|
+
if (times === 3) {
|
|
49
|
+
clearInterval(_timeout)
|
|
50
|
+
clearInterval(soundTimeout)
|
|
51
|
+
}
|
|
45
52
|
}, 2500)
|
|
46
53
|
}
|
|
47
54
|
|
|
@@ -64,9 +71,16 @@ export const NewOrderNotification = (props: any) => {
|
|
|
64
71
|
}
|
|
65
72
|
}, [handleNotification])
|
|
66
73
|
|
|
67
|
-
|
|
68
|
-
const handleUpdateOrder = useCallback((order: any) => {
|
|
74
|
+
const handleUpdateOrder = useCallback(async (order: any) => {
|
|
69
75
|
if (order?.driver) {
|
|
76
|
+
const location = await getCurrentLocation()
|
|
77
|
+
await fetch(`${ordering.root}/users/${user.id}/locations`, {
|
|
78
|
+
method: 'POST',
|
|
79
|
+
body: JSON.stringify({
|
|
80
|
+
location: JSON.stringify({location: `{lat: ${location.latitude}, lng: ${location.longitude}}`})
|
|
81
|
+
}),
|
|
82
|
+
headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${token}` }
|
|
83
|
+
})
|
|
70
84
|
const assignedTimeDiff = moment.utc(order?.driver?.last_order_assigned_at).local().fromNow()
|
|
71
85
|
if (assignedTimeDiff === 'a few seconds ago') {
|
|
72
86
|
clearInterval(soundTimeout)
|
|
@@ -75,13 +75,14 @@ export const OrderDetailsUI = (props: OrderDetailsParams) => {
|
|
|
75
75
|
const showFloatButtonsPickUp: any = {
|
|
76
76
|
8: true,
|
|
77
77
|
3: true,
|
|
78
|
-
|
|
79
|
-
18: true
|
|
78
|
+
18: true,
|
|
80
79
|
};
|
|
81
80
|
|
|
82
81
|
const showFloatButtonsAcceptOrReject: any = {
|
|
83
82
|
0: true,
|
|
83
|
+
4: true,
|
|
84
84
|
7: true,
|
|
85
|
+
14: true
|
|
85
86
|
};
|
|
86
87
|
|
|
87
88
|
const marginContainer: any = {
|
|
@@ -295,7 +296,7 @@ export const OrderDetailsUI = (props: OrderDetailsParams) => {
|
|
|
295
296
|
</Pickup>
|
|
296
297
|
)}
|
|
297
298
|
{(order?.status === 3) && order?.delivery_type === 1 && (
|
|
298
|
-
<View style={{paddingVertical: 20, marginBottom: 20}}>
|
|
299
|
+
<View style={{ paddingVertical: 20, marginBottom: 20 }}>
|
|
299
300
|
<OButton
|
|
300
301
|
style={styles.btnPickUp}
|
|
301
302
|
textStyle={{ color: theme.colors.white }}
|
|
@@ -382,13 +383,13 @@ export const OrderDetailsUI = (props: OrderDetailsParams) => {
|
|
|
382
383
|
{showFloatButtonsPickUp[order?.status] && (
|
|
383
384
|
<FloatingButton
|
|
384
385
|
disabled={loading}
|
|
385
|
-
btnText={t('
|
|
386
|
+
btnText={t('PICKUP_FAILED', 'Pickup failed')}
|
|
386
387
|
isSecondaryBtn={false}
|
|
387
388
|
secondButtonClick={() =>
|
|
388
389
|
handleChangeOrderStatus && handleChangeOrderStatus(9)
|
|
389
390
|
}
|
|
390
391
|
firstButtonClick={() =>
|
|
391
|
-
|
|
392
|
+
handleViewActionOrder && handleViewActionOrder('failed')
|
|
392
393
|
}
|
|
393
394
|
secondBtnText={t('PICKUP_COMPLETE', 'Pickup complete')}
|
|
394
395
|
secondButton={true}
|
|
@@ -401,13 +402,13 @@ export const OrderDetailsUI = (props: OrderDetailsParams) => {
|
|
|
401
402
|
<>
|
|
402
403
|
<FloatingButton
|
|
403
404
|
disabled={loading}
|
|
404
|
-
btnText={t('
|
|
405
|
+
btnText={t('DELIVERY_FAILED', 'Delivery Failed')}
|
|
405
406
|
isSecondaryBtn={false}
|
|
406
407
|
secondButtonClick={() =>
|
|
407
408
|
handleChangeOrderStatus && handleChangeOrderStatus(11)
|
|
408
409
|
}
|
|
409
410
|
firstButtonClick={() =>
|
|
410
|
-
|
|
411
|
+
handleViewActionOrder && handleViewActionOrder('failed')
|
|
411
412
|
}
|
|
412
413
|
secondBtnText={t('DELIVERY_COMPLETE', 'Delivery complete')}
|
|
413
414
|
secondButton={true}
|
|
@@ -49,6 +49,9 @@ export const OrderContentComponent = (props: OrderContent) => {
|
|
|
49
49
|
textBold: {
|
|
50
50
|
fontWeight: '600',
|
|
51
51
|
},
|
|
52
|
+
textLink: {
|
|
53
|
+
color: '#365CC7'
|
|
54
|
+
}
|
|
52
55
|
})
|
|
53
56
|
return (
|
|
54
57
|
<OrderContent>
|
|
@@ -67,6 +70,7 @@ export const OrderContentComponent = (props: OrderContent) => {
|
|
|
67
70
|
PressStyle={styles.linkWithIcons}
|
|
68
71
|
url={`mailto:${order?.business?.email}`}
|
|
69
72
|
shorcut={order?.business?.email}
|
|
73
|
+
TextStyle={styles.textLink}
|
|
70
74
|
/>
|
|
71
75
|
</View>
|
|
72
76
|
)}
|
|
@@ -77,6 +81,7 @@ export const OrderContentComponent = (props: OrderContent) => {
|
|
|
77
81
|
PressStyle={styles.linkWithIcons}
|
|
78
82
|
url={`tel:${order?.business?.cellphone}`}
|
|
79
83
|
shorcut={`${order?.business?.cellphone}`}
|
|
84
|
+
TextStyle={styles.textLink}
|
|
80
85
|
/>
|
|
81
86
|
</View>
|
|
82
87
|
)}
|
|
@@ -87,6 +92,7 @@ export const OrderContentComponent = (props: OrderContent) => {
|
|
|
87
92
|
PressStyle={styles.linkWithIcons}
|
|
88
93
|
url={`tel:${order?.business?.phone}`}
|
|
89
94
|
shorcut={order?.business?.phone}
|
|
95
|
+
TextStyle={styles.textLink}
|
|
90
96
|
/>
|
|
91
97
|
</View>
|
|
92
98
|
)}
|
|
@@ -100,6 +106,7 @@ export const OrderContentComponent = (props: OrderContent) => {
|
|
|
100
106
|
android: `geo:0,0?q=${order?.business?.address}`,
|
|
101
107
|
})}
|
|
102
108
|
shorcut={order?.business?.address}
|
|
109
|
+
TextStyle={styles.textLink}
|
|
103
110
|
/>
|
|
104
111
|
</View>
|
|
105
112
|
)}
|
|
@@ -113,6 +120,7 @@ export const OrderContentComponent = (props: OrderContent) => {
|
|
|
113
120
|
android: `geo:0,0?q=${order?.business?.address_notes}`,
|
|
114
121
|
})}
|
|
115
122
|
shorcut={order?.business?.address_notes}
|
|
123
|
+
TextStyle={styles.textLink}
|
|
116
124
|
/>
|
|
117
125
|
</View>
|
|
118
126
|
)}
|
|
@@ -165,6 +173,8 @@ export const OrderContentComponent = (props: OrderContent) => {
|
|
|
165
173
|
PressStyle={styles.linkWithIcons}
|
|
166
174
|
url={`mailto:${order?.customer?.email}`}
|
|
167
175
|
shorcut={order?.customer?.email}
|
|
176
|
+
TextStyle={styles.textLink}
|
|
177
|
+
|
|
168
178
|
/>
|
|
169
179
|
</View>
|
|
170
180
|
)}
|
|
@@ -175,6 +185,7 @@ export const OrderContentComponent = (props: OrderContent) => {
|
|
|
175
185
|
PressStyle={styles.linkWithIcons}
|
|
176
186
|
url={`tel:${order?.customer?.cellphone}`}
|
|
177
187
|
shorcut={order?.customer?.cellphone}
|
|
188
|
+
TextStyle={styles.textLink}
|
|
178
189
|
/>
|
|
179
190
|
</View>
|
|
180
191
|
)}
|
|
@@ -185,6 +196,7 @@ export const OrderContentComponent = (props: OrderContent) => {
|
|
|
185
196
|
PressStyle={styles.linkWithIcons}
|
|
186
197
|
url={`tel:${order?.customer?.phone}`}
|
|
187
198
|
shorcut={order?.customer?.phone}
|
|
199
|
+
TextStyle={styles.textLink}
|
|
188
200
|
/>
|
|
189
201
|
</View>
|
|
190
202
|
)}
|
|
@@ -198,6 +210,7 @@ export const OrderContentComponent = (props: OrderContent) => {
|
|
|
198
210
|
android: `geo:0,0?q=${order?.customer?.address}`,
|
|
199
211
|
})}
|
|
200
212
|
shorcut={order?.customer?.address}
|
|
213
|
+
TextStyle={styles.textLink}
|
|
201
214
|
/>
|
|
202
215
|
</View>
|
|
203
216
|
)}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React, { useEffect, useState, useRef } from 'react';
|
|
2
|
-
import { View, Pressable, StyleSheet, ScrollView, RefreshControl, Linking } from 'react-native';
|
|
2
|
+
import { View, Pressable, StyleSheet, ScrollView, RefreshControl, Linking, Platform } from 'react-native';
|
|
3
3
|
import { useLanguage, useUtils, OrderListGroups } from 'ordering-components/native';
|
|
4
4
|
import { Placeholder, PlaceholderLine, Fade } from 'rn-placeholder';
|
|
5
5
|
import FeatherIcon from 'react-native-vector-icons/Feather';
|
|
@@ -167,7 +167,7 @@ const OrdersOptionUI = (props: OrdersOptionParams) => {
|
|
|
167
167
|
|
|
168
168
|
const [tagsState, setTags] = useState<any>({ values: [] })
|
|
169
169
|
|
|
170
|
-
const tagsList = ordersGroup[currentTabSelected]
|
|
170
|
+
const tagsList = ordersGroup[currentTabSelected]?.defaultFilter ?? []
|
|
171
171
|
const currentOrdersGroup = ordersGroup[currentTabSelected]
|
|
172
172
|
|
|
173
173
|
const isEqual = (array1: any, array2: any) => {
|
|
@@ -191,7 +191,7 @@ const OrdersOptionUI = (props: OrdersOptionParams) => {
|
|
|
191
191
|
}
|
|
192
192
|
})
|
|
193
193
|
const dateRange = calculateDate(search.date.type, search.date.from, search.date.to)
|
|
194
|
-
onFiltered && onFiltered({...search, date: {...dateRange}})
|
|
194
|
+
onFiltered && onFiltered({ ...search, date: { ...dateRange } })
|
|
195
195
|
setOpenModal(false)
|
|
196
196
|
}
|
|
197
197
|
|
|
@@ -248,29 +248,29 @@ const OrdersOptionUI = (props: OrdersOptionParams) => {
|
|
|
248
248
|
switch (type) {
|
|
249
249
|
case 'today':
|
|
250
250
|
const date = parseDate(new Date(), { outputFormat: 'MM/DD/YYYY' })
|
|
251
|
-
return {from: `${date} 00:00:00`, to: `${date} 23:59:59`}
|
|
251
|
+
return { from: `${date} 00:00:00`, to: `${date} 23:59:59` }
|
|
252
252
|
case 'yesterday':
|
|
253
253
|
const yesterday = new Date()
|
|
254
254
|
yesterday.setDate(yesterday.getDate() - 1)
|
|
255
255
|
const start1 = parseDate(yesterday, { outputFormat: 'MM/DD/YYYY' })
|
|
256
256
|
const end1 = parseDate(new Date(), { outputFormat: 'MM/DD/YYYY' })
|
|
257
|
-
return {from: `${start1} 00:00:00`, to: `${end1} 23:59:59`}
|
|
257
|
+
return { from: `${start1} 00:00:00`, to: `${end1} 23:59:59` }
|
|
258
258
|
case 'last_7days':
|
|
259
259
|
const last_7days = new Date()
|
|
260
260
|
last_7days.setDate(last_7days.getDate() - 6)
|
|
261
261
|
const start7 = parseDate(last_7days, { outputFormat: 'MM/DD/YYYY' })
|
|
262
262
|
const end7 = parseDate(new Date(), { outputFormat: 'MM/DD/YYYY' })
|
|
263
|
-
return {from: `${start7} 00:00:00`, to: `${end7} 23:59:59`}
|
|
263
|
+
return { from: `${start7} 00:00:00`, to: `${end7} 23:59:59` }
|
|
264
264
|
case 'last_30days':
|
|
265
265
|
const last_30days = new Date()
|
|
266
266
|
last_30days.setDate(last_30days.getDate() - 29)
|
|
267
267
|
const start30 = parseDate(last_30days, { outputFormat: 'MM/DD/YYYY' })
|
|
268
268
|
const end30 = parseDate(new Date(), { outputFormat: 'MM/DD/YYYY' })
|
|
269
|
-
return {from: `${start30} 00:00:00`, to: `${end30} 23:59:59`}
|
|
269
|
+
return { from: `${start30} 00:00:00`, to: `${end30} 23:59:59` }
|
|
270
270
|
default:
|
|
271
271
|
const start = from ? `${parseDate(from, { outputFormat: 'MM/DD/YYYY' })} 00:00:00` : ''
|
|
272
272
|
const end = to ? `${parseDate(to, { outputFormat: 'MM/DD/YYYY' })} 23:59:59` : ''
|
|
273
|
-
return {from: start, to: end}
|
|
273
|
+
return { from: start, to: end }
|
|
274
274
|
}
|
|
275
275
|
}
|
|
276
276
|
|
|
@@ -310,22 +310,22 @@ const OrdersOptionUI = (props: OrdersOptionParams) => {
|
|
|
310
310
|
</IconWrapper>
|
|
311
311
|
</View>
|
|
312
312
|
{isBusinessApp && (
|
|
313
|
-
<View style={{ flex: 1, flexDirection: 'row', justifyContent: 'flex-start', maxHeight:40}}>
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
313
|
+
<View style={{ flex: 1, flexDirection: 'row', justifyContent: 'flex-start', maxHeight: 40 }}>
|
|
314
|
+
<OIcon
|
|
315
|
+
src={theme.images.general.information}
|
|
316
|
+
width={12}
|
|
317
|
+
height={12}
|
|
318
|
+
color={theme.colors.skyBlue}
|
|
319
|
+
style={{ marginRight: 5 }}
|
|
320
|
+
/>
|
|
321
|
+
<OText size={12}>
|
|
322
|
+
{t('MORE_SETTINGS_GO_TO', 'For more settings go to ')}
|
|
323
|
+
</OText>
|
|
324
|
+
<TouchableOpacity onPress={() => { Linking.openURL('https://new-admin.tryordering.com/') }}>
|
|
325
|
+
<OText size={12} color={theme.colors.skyBlue}>
|
|
326
|
+
{t('LINK_MORE_SETTINGS_GO_TO', 'new-admin.ordering.co')}
|
|
323
327
|
</OText>
|
|
324
|
-
|
|
325
|
-
<OText size={12} color={theme.colors.skyBlue}>
|
|
326
|
-
{t('LINK_MORE_SETTINGS_GO_TO', 'new-admin.ordering.co')}
|
|
327
|
-
</OText>
|
|
328
|
-
</TouchableOpacity>
|
|
328
|
+
</TouchableOpacity>
|
|
329
329
|
</View>
|
|
330
330
|
)}
|
|
331
331
|
<FiltersTab>
|
|
@@ -405,7 +405,7 @@ const OrdersOptionUI = (props: OrdersOptionParams) => {
|
|
|
405
405
|
onPress={() => !currentOrdersGroup.loading && handleTagSelected(key)}
|
|
406
406
|
isSelected={
|
|
407
407
|
currentOrdersGroup.currentFilter.includes(key) &&
|
|
408
|
-
|
|
408
|
+
!isEqual(currentOrdersGroup.currentFilter, tagsList)
|
|
409
409
|
? theme.colors.primary
|
|
410
410
|
: theme.colors.tabBar
|
|
411
411
|
}>
|
|
@@ -413,7 +413,7 @@ const OrdersOptionUI = (props: OrdersOptionParams) => {
|
|
|
413
413
|
style={styles.tag}
|
|
414
414
|
color={
|
|
415
415
|
currentOrdersGroup.currentFilter.includes(key) &&
|
|
416
|
-
|
|
416
|
+
!isEqual(currentOrdersGroup.currentFilter, tagsList)
|
|
417
417
|
? theme.colors.white
|
|
418
418
|
: theme.colors.black
|
|
419
419
|
}>
|
|
@@ -443,86 +443,86 @@ const OrdersOptionUI = (props: OrdersOptionParams) => {
|
|
|
443
443
|
>
|
|
444
444
|
{!currentOrdersGroup.error?.length &&
|
|
445
445
|
currentOrdersGroup.orders?.length > 0 &&
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
{(currentOrdersGroup
|
|
456
|
-
currentOrdersGroup
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
style={{
|
|
464
|
-
width: '100%',
|
|
465
|
-
flexDirection: 'row',
|
|
466
|
-
marginBottom: 10,
|
|
467
|
-
}}>
|
|
468
|
-
<PlaceholderLine
|
|
469
|
-
width={IS_PORTRAIT ? 22 : 11}
|
|
470
|
-
height={74}
|
|
446
|
+
(
|
|
447
|
+
<PreviousOrders
|
|
448
|
+
orders={currentOrdersGroup.orders}
|
|
449
|
+
onNavigationRedirect={onNavigationRedirect}
|
|
450
|
+
getOrderStatus={getOrderStatus}
|
|
451
|
+
handleClickOrder={handleClickOrder}
|
|
452
|
+
/>
|
|
453
|
+
)}
|
|
454
|
+
|
|
455
|
+
{(currentOrdersGroup?.loading ||
|
|
456
|
+
currentOrdersGroup?.pagination?.total === null) &&
|
|
457
|
+
(
|
|
458
|
+
<>
|
|
459
|
+
<View>
|
|
460
|
+
{[...Array(5)].map((_, i) => (
|
|
461
|
+
<Placeholder key={i} Animation={Fade}>
|
|
462
|
+
<View
|
|
471
463
|
style={{
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
}}
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
464
|
+
width: '100%',
|
|
465
|
+
flexDirection: 'row',
|
|
466
|
+
marginBottom: 10,
|
|
467
|
+
}}>
|
|
468
|
+
<PlaceholderLine
|
|
469
|
+
width={IS_PORTRAIT ? 22 : 11}
|
|
470
|
+
height={74}
|
|
471
|
+
style={{
|
|
472
|
+
marginRight: 20,
|
|
473
|
+
marginBottom: 20,
|
|
474
|
+
borderRadius: 7.6,
|
|
475
|
+
}}
|
|
476
|
+
/>
|
|
477
|
+
<Placeholder>
|
|
478
|
+
<PlaceholderLine width={30} style={{ marginTop: 5 }} />
|
|
479
|
+
<PlaceholderLine width={50} />
|
|
480
|
+
<PlaceholderLine width={20} />
|
|
481
|
+
</Placeholder>
|
|
482
|
+
</View>
|
|
483
|
+
</Placeholder>
|
|
484
|
+
))}
|
|
485
|
+
</View>
|
|
486
|
+
</>
|
|
487
|
+
)}
|
|
488
|
+
|
|
489
|
+
{!currentOrdersGroup?.error?.length &&
|
|
490
|
+
!currentOrdersGroup?.loading &&
|
|
491
|
+
currentOrdersGroup?.pagination?.totalPages &&
|
|
492
|
+
currentOrdersGroup?.pagination?.currentPage < currentOrdersGroup?.pagination?.totalPages &&
|
|
493
|
+
currentOrdersGroup?.orders?.length > 0 &&
|
|
494
|
+
(
|
|
495
|
+
<OButton
|
|
496
|
+
onClick={handleLoadMore}
|
|
497
|
+
text={t('LOAD_MORE_ORDERS', 'Load more orders')}
|
|
498
|
+
imgRightSrc={null}
|
|
499
|
+
textStyle={styles.loadButtonText}
|
|
500
|
+
style={styles.loadButton}
|
|
501
|
+
bgColor={theme.colors.primary}
|
|
502
|
+
borderColor={theme.colors.primary}
|
|
503
|
+
/>
|
|
504
|
+
)}
|
|
505
|
+
|
|
506
|
+
{!currentOrdersGroup?.loading &&
|
|
507
|
+
(currentOrdersGroup?.error?.length ||
|
|
508
|
+
currentOrdersGroup?.orders?.length === 0) &&
|
|
509
|
+
(
|
|
510
|
+
<NotFoundSource
|
|
511
|
+
content={
|
|
512
|
+
!currentOrdersGroup?.error?.length
|
|
513
|
+
? t('NO_RESULTS_FOUND', 'Sorry, no results found')
|
|
514
|
+
: currentOrdersGroup?.error[0]?.message ||
|
|
515
515
|
currentOrdersGroup?.error[0] ||
|
|
516
516
|
t('NETWORK_ERROR', 'Network Error')
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
517
|
+
}
|
|
518
|
+
image={theme.images.general.notFound}
|
|
519
|
+
conditioned={false}
|
|
520
|
+
/>
|
|
521
|
+
)}
|
|
522
522
|
</ScrollView>
|
|
523
523
|
</View>
|
|
524
|
-
|
|
525
|
-
|
|
524
|
+
{/* </GestureRecognizer> */}
|
|
525
|
+
|
|
526
526
|
<NewOrderNotification />
|
|
527
527
|
<OModal open={openModal} entireModal customClose>
|
|
528
528
|
<ModalContainer
|
|
@@ -545,7 +545,7 @@ const OrdersOptionUI = (props: OrdersOptionParams) => {
|
|
|
545
545
|
<ModalTitle>{t('SEARCH_ORDERS', 'Search orders')}</ModalTitle>
|
|
546
546
|
<OInput
|
|
547
547
|
value={search.id}
|
|
548
|
-
onChange={(value: any) => setSearch({...search, id: value})}
|
|
548
|
+
onChange={(value: any) => setSearch({ ...search, id: value })}
|
|
549
549
|
style={styles.inputStyle}
|
|
550
550
|
placeholder={t('ORDER_NUMBER', 'Order number')}
|
|
551
551
|
autoCorrect={false}
|
|
@@ -611,6 +611,7 @@ export const OrdersOption = (props: OrdersOptionParams) => {
|
|
|
611
611
|
UIComponent: OrdersOptionUI,
|
|
612
612
|
useDefualtSessionManager: true,
|
|
613
613
|
asDashboard: true,
|
|
614
|
+
isIos: Platform.OS === 'ios',
|
|
614
615
|
orderStatus: [
|
|
615
616
|
{ key: 0, text: t('PENDING', 'Pending') },
|
|
616
617
|
{ key: 1, text: t('COMPLETED', 'Completed') },
|
|
@@ -687,7 +688,7 @@ export const OrdersOption = (props: OrdersOptionParams) => {
|
|
|
687
688
|
{
|
|
688
689
|
key: 0,
|
|
689
690
|
text: t('PENDING', 'Pending'),
|
|
690
|
-
tags: props?.orderGroupStatusCustom?.
|
|
691
|
+
tags: props?.orderGroupStatusCustom?.pending ?? [0, 13],
|
|
691
692
|
title: 'pending'
|
|
692
693
|
},
|
|
693
694
|
{
|
|
@@ -14,6 +14,7 @@ import { ForgotPasswordForm } from './src/components/ForgotPasswordForm';
|
|
|
14
14
|
import { MomentOption } from './src/components/MomentOption';
|
|
15
15
|
import { OrdersOption } from './src/components/OrdersOption';
|
|
16
16
|
import { OrderDetails } from './src/components/OrderDetails';
|
|
17
|
+
import { OrderProgress } from './src/components/OrderProgress';
|
|
17
18
|
import { UserProfileForm } from './src/components/UserProfileForm';
|
|
18
19
|
import { ReviewOrder } from './src/components/ReviewOrder';
|
|
19
20
|
import { UserProfile } from './src/components/UserProfile';
|
|
@@ -67,6 +68,7 @@ export {
|
|
|
67
68
|
MomentOption,
|
|
68
69
|
OrdersOption,
|
|
69
70
|
OrderDetails,
|
|
71
|
+
OrderProgress,
|
|
70
72
|
UserProfileForm,
|
|
71
73
|
ReviewOrder,
|
|
72
74
|
UserProfile,
|
|
@@ -25,6 +25,7 @@ import {
|
|
|
25
25
|
HeaderWrapper,
|
|
26
26
|
ListWrapper,
|
|
27
27
|
FeaturedWrapper,
|
|
28
|
+
OrderProgressWrapper
|
|
28
29
|
} from './styles';
|
|
29
30
|
|
|
30
31
|
import { SearchBar } from '../SearchBar';
|
|
@@ -38,6 +39,7 @@ import { useSafeAreaInsets } from 'react-native-safe-area-context';
|
|
|
38
39
|
import { BusinessFeaturedController } from '../BusinessFeaturedController';
|
|
39
40
|
import { HighestRatedBusinesses } from '../HighestRatedBusinesses';
|
|
40
41
|
import { getTypesText } from '../../utils';
|
|
42
|
+
import { OrderProgress } from '../OrderProgress';
|
|
41
43
|
|
|
42
44
|
const PIXELS_TO_SCROLL = 1000;
|
|
43
45
|
|
|
@@ -224,6 +226,11 @@ const BusinessesListingUI = (props: BusinessesListingParams) => {
|
|
|
224
226
|
</View>
|
|
225
227
|
</OrderControlContainer>
|
|
226
228
|
</HeaderWrapper>
|
|
229
|
+
<OrderProgressWrapper>
|
|
230
|
+
<OrderProgress
|
|
231
|
+
{...props}
|
|
232
|
+
/>
|
|
233
|
+
</OrderProgressWrapper>
|
|
227
234
|
{featuredBusiness && featuredBusiness.length > 0 && (
|
|
228
235
|
<FeaturedWrapper>
|
|
229
236
|
<OText size={16} style={{ marginLeft: 40 }} weight={Platform.OS === 'ios' ? '600' : 'bold'}>{t('FEATURED_BUSINESS', 'Featured business')}</OText>
|
|
@@ -67,4 +67,9 @@ export const FeaturedWrapper = styled.View`
|
|
|
67
67
|
background-color: ${(props: any) => props.theme.colors.backgroundLight};
|
|
68
68
|
height: 220px;
|
|
69
69
|
paddingVertical: 30px;
|
|
70
|
-
`;
|
|
70
|
+
`;
|
|
71
|
+
|
|
72
|
+
export const OrderProgressWrapper = styled.View`
|
|
73
|
+
margin-top: 37px;
|
|
74
|
+
padding-horizontal: 40px;
|
|
75
|
+
`
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import {
|
|
3
|
+
OrderList,
|
|
4
|
+
useLanguage,
|
|
5
|
+
useUtils
|
|
6
|
+
} from 'ordering-components/native'
|
|
7
|
+
import { useTheme } from 'styled-components/native';
|
|
8
|
+
import IconAntDesign from 'react-native-vector-icons/AntDesign'
|
|
9
|
+
import moment from 'moment';
|
|
10
|
+
import { OText } from '../shared'
|
|
11
|
+
import { NotFoundSource } from '../NotFoundSource'
|
|
12
|
+
import { View, StyleSheet, TouchableOpacity } from 'react-native'
|
|
13
|
+
import { Placeholder, Fade } from "rn-placeholder";
|
|
14
|
+
import FastImage from 'react-native-fast-image'
|
|
15
|
+
import {
|
|
16
|
+
ProgressContentWrapper,
|
|
17
|
+
ProgressBar,
|
|
18
|
+
TimeWrapper,
|
|
19
|
+
ProgressTextWrapper,
|
|
20
|
+
OrderInfoWrapper
|
|
21
|
+
} from './styles'
|
|
22
|
+
|
|
23
|
+
const OrderProgressUI = (props: any) => {
|
|
24
|
+
const {
|
|
25
|
+
orderList,
|
|
26
|
+
navigation
|
|
27
|
+
} = props
|
|
28
|
+
|
|
29
|
+
const theme = useTheme();
|
|
30
|
+
|
|
31
|
+
const [, t] = useLanguage()
|
|
32
|
+
const { loading, error, orders: values } = orderList
|
|
33
|
+
const [{ optimizeImage, parseDate, parseTime }] = useUtils()
|
|
34
|
+
const imageFails = theme.images.general.emptyActiveOrders
|
|
35
|
+
|
|
36
|
+
const styles = StyleSheet.create({
|
|
37
|
+
main: {
|
|
38
|
+
flexDirection: 'column',
|
|
39
|
+
backgroundColor: '#FFFFFF',
|
|
40
|
+
flex: 1,
|
|
41
|
+
padding: 15,
|
|
42
|
+
borderRadius: 8,
|
|
43
|
+
shadowOffset: {
|
|
44
|
+
width: 1,
|
|
45
|
+
height: 1
|
|
46
|
+
},
|
|
47
|
+
shadowColor: '#000',
|
|
48
|
+
shadowOpacity: 0.1,
|
|
49
|
+
shadowRadius: 1,
|
|
50
|
+
elevation: 2
|
|
51
|
+
},
|
|
52
|
+
logoWrapper: {
|
|
53
|
+
overflow: 'hidden',
|
|
54
|
+
backgroundColor: 'white',
|
|
55
|
+
borderRadius: 8,
|
|
56
|
+
shadowColor: '#000000',
|
|
57
|
+
shadowOffset: { width: 1, height: 1 },
|
|
58
|
+
shadowOpacity: 0.1,
|
|
59
|
+
shadowRadius: 1,
|
|
60
|
+
elevation: 3
|
|
61
|
+
},
|
|
62
|
+
logo: {
|
|
63
|
+
width: 50,
|
|
64
|
+
height: 50,
|
|
65
|
+
borderRadius: 8,
|
|
66
|
+
resizeMode: 'stretch',
|
|
67
|
+
},
|
|
68
|
+
navigationButton: {
|
|
69
|
+
flexDirection: 'row',
|
|
70
|
+
alignItems: 'center'
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
const getOrderStatus = (s: any) => {
|
|
75
|
+
const status = parseInt(s)
|
|
76
|
+
const orderStatus = [
|
|
77
|
+
{ key: 0, value: t('PENDING', theme?.defaultLanguages?.PENDING || 'Pending'), slug: 'PENDING', percentage: 25 },
|
|
78
|
+
{ key: 1, value: t('COMPLETED', theme?.defaultLanguages?.COMPLETED || 'Completed'), slug: 'COMPLETED', percentage: 100 },
|
|
79
|
+
{ key: 2, value: t('REJECTED', theme?.defaultLanguages?.REJECTED || 'Rejected'), slug: 'REJECTED', percentage: 0 },
|
|
80
|
+
{ key: 3, value: t('DRIVER_IN_BUSINESS', theme?.defaultLanguages?.DRIVER_IN_BUSINESS || 'Driver in business'), slug: 'DRIVER_IN_BUSINESS', percentage: 60 },
|
|
81
|
+
{ key: 4, value: t('PREPARATION_COMPLETED', theme?.defaultLanguages?.PREPARATION_COMPLETED || 'Preparation Completed'), slug: 'PREPARATION_COMPLETED', percentage: 70 },
|
|
82
|
+
{ key: 5, value: t('REJECTED_BY_BUSINESS', theme?.defaultLanguages?.REJECTED_BY_BUSINESS || 'Rejected by business'), slug: 'REJECTED_BY_BUSINESS', percentage: 0 },
|
|
83
|
+
{ key: 6, value: t('REJECTED_BY_DRIVER', theme?.defaultLanguages?.REJECTED_BY_DRIVER || 'Rejected by Driver'), slug: 'REJECTED_BY_DRIVER', percentage: 0 },
|
|
84
|
+
{ key: 7, value: t('ACCEPTED_BY_BUSINESS', theme?.defaultLanguages?.ACCEPTED_BY_BUSINESS || 'Accepted by business'), slug: 'ACCEPTED_BY_BUSINESS', percentage: 35 },
|
|
85
|
+
{ key: 8, value: t('ACCEPTED_BY_DRIVER', theme?.defaultLanguages?.ACCEPTED_BY_DRIVER || 'Accepted by driver'), slug: 'ACCEPTED_BY_DRIVER', percentage: 45 },
|
|
86
|
+
{ key: 9, value: t('PICK_UP_COMPLETED_BY_DRIVER', theme?.defaultLanguages?.PICK_UP_COMPLETED_BY_DRIVER || 'Pick up completed by driver'), slug: 'PICK_UP_COMPLETED_BY_DRIVER', percentage: 80 },
|
|
87
|
+
{ key: 10, value: t('PICK_UP_FAILED_BY_DRIVER', theme?.defaultLanguages?.PICK_UP_FAILED_BY_DRIVER || 'Pick up Failed by driver'), slug: 'PICK_UP_FAILED_BY_DRIVER', percentage: 0 },
|
|
88
|
+
{ key: 11, value: t('DELIVERY_COMPLETED_BY_DRIVER', theme?.defaultLanguages?.DELIVERY_COMPLETED_BY_DRIVER || 'Delivery completed by driver'), slug: 'DELIVERY_COMPLETED_BY_DRIVER', percentage: 100 },
|
|
89
|
+
{ key: 12, value: t('DELIVERY_FAILED_BY_DRIVER', theme?.defaultLanguages?.DELIVERY_FAILED_BY_DRIVER || 'Delivery Failed by driver'), slug: 'DELIVERY_FAILED_BY_DRIVER', percentage: 0 },
|
|
90
|
+
{ key: 13, value: t('PREORDER', theme?.defaultLanguages?.PREORDER || 'PreOrder'), slug: 'PREORDER', percentage: 0 },
|
|
91
|
+
{ key: 14, value: t('ORDER_NOT_READY', theme?.defaultLanguages?.ORDER_NOT_READY || 'Order not ready'), slug: 'ORDER_NOT_READY', percentage: 65 },
|
|
92
|
+
{ key: 15, value: t('ORDER_PICKEDUP_COMPLETED_BY_CUSTOMER', theme?.defaultLanguages?.ORDER_PICKEDUP_COMPLETED_BY_CUSTOMER || 'Order picked up completed by customer'), slug: 'ORDER_PICKEDUP_COMPLETED_BY_CUSTOMER', percentage: 100 },
|
|
93
|
+
{ key: 16, value: t('ORDER_STATUS_CANCELLED_BY_CUSTOMER', theme?.defaultLanguages?.ORDER_STATUS_CANCELLED_BY_CUSTOMER || 'Order cancelled by customer'), slug: 'ORDER_STATUS_CANCELLED_BY_CUSTOMER', percentage: 0 },
|
|
94
|
+
{ key: 17, value: t('ORDER_NOT_PICKEDUP_BY_CUSTOMER', theme?.defaultLanguages?.ORDER_NOT_PICKEDUP_BY_CUSTOMER || 'Order not picked up by customer'), slug: 'ORDER_NOT_PICKEDUP_BY_CUSTOMER', percentage: 0 },
|
|
95
|
+
{ key: 18, value: t('ORDER_DRIVER_ALMOST_ARRIVED_BUSINESS', theme?.defaultLanguages?.ORDER_DRIVER_ALMOST_ARRIVED_BUSINESS || 'Driver almost arrived to business'), slug: 'ORDER_DRIVER_ALMOST_ARRIVED_BUSINESS', percentage: 55 },
|
|
96
|
+
{ key: 19, value: t('ORDER_DRIVER_ALMOST_ARRIVED_CUSTOMER', theme?.defaultLanguages?.ORDER_DRIVER_ALMOST_ARRIVED_CUSTOMER || 'Driver almost arrived to customer'), slug: 'ORDER_DRIVER_ALMOST_ARRIVED_CUSTOMER', percentage: 90 },
|
|
97
|
+
{ key: 20, value: t('ORDER_CUSTOMER_ALMOST_ARRIVED_BUSINESS', theme?.defaultLanguages?.ORDER_CUSTOMER_ALMOST_ARRIVED_BUSINESS || 'Customer almost arrived to business'), slug: 'ORDER_CUSTOMER_ALMOST_ARRIVED_BUSINESS', percentage: 90 },
|
|
98
|
+
{ key: 21, value: t('ORDER_CUSTOMER_ARRIVED_BUSINESS', theme?.defaultLanguages?.ORDER_CUSTOMER_ARRIVED_BUSINESS || 'Customer arrived to business'), slug: 'ORDER_CUSTOMER_ARRIVED_BUSINESS', percentage: 95 }
|
|
99
|
+
]
|
|
100
|
+
|
|
101
|
+
const objectStatus = orderStatus.find((o) => o.key === status)
|
|
102
|
+
|
|
103
|
+
return objectStatus && objectStatus
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
const convertDiffToHours = (time: any, order: any) => {
|
|
107
|
+
const deliveryTime = order?.delivery_datetime_utc
|
|
108
|
+
? parseDate(order?.delivery_datetime_utc, { outputFormat: 'YYYY-MM-DD hh:mm A' })
|
|
109
|
+
: parseDate(order?.delivery_datetime, { utc: false, outputFormat: 'YYYY-MM-DD hh:mm A' })
|
|
110
|
+
const [hour, minute] = time.split(':')
|
|
111
|
+
const result = time ? (parseInt(hour, 10) * 60) + parseInt(minute, 10) : 0
|
|
112
|
+
const returnedDate = moment(new Date(deliveryTime)).add(result, 'minutes').format('hh:mm A')
|
|
113
|
+
return returnedDate
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
const handleGoToOrder = (index: string) => {
|
|
117
|
+
navigation && navigation.navigate(index)
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
return (
|
|
121
|
+
<>
|
|
122
|
+
{orderList?.loading && <Placeholder height={150} Animation={Fade} />}
|
|
123
|
+
{!orderList?.loading && orderList?.orders?.length > 0 && orderList?.orders.map((order: any) => (
|
|
124
|
+
<View style={styles.main} key={order.id}>
|
|
125
|
+
<OrderInfoWrapper style={{ flex: 1 }}>
|
|
126
|
+
<View style={styles.logoWrapper}>
|
|
127
|
+
<FastImage
|
|
128
|
+
style={{ width: 50, height: 50 }}
|
|
129
|
+
source={{
|
|
130
|
+
uri: optimizeImage(order?.business?.logo, 'h_50,c_limit'),
|
|
131
|
+
priority: FastImage.priority.normal,
|
|
132
|
+
}}
|
|
133
|
+
resizeMode={FastImage.resizeMode.cover}
|
|
134
|
+
/>
|
|
135
|
+
</View>
|
|
136
|
+
<View style={{
|
|
137
|
+
paddingHorizontal: 10,
|
|
138
|
+
flex: 1
|
|
139
|
+
}}
|
|
140
|
+
>
|
|
141
|
+
<OText
|
|
142
|
+
size={13}
|
|
143
|
+
style={{
|
|
144
|
+
fontWeight: 'bold',
|
|
145
|
+
marginBottom: 3
|
|
146
|
+
}}
|
|
147
|
+
>{t('ORDER_IN_PROGRESS', 'Order in progress')}</OText>
|
|
148
|
+
<OText size={11} numberOfLines={1} ellipsizeMode='tail'>{t('RESTAURANT_PREPARING_YOUR_ORDER', 'The restaurant is preparing your order')}</OText>
|
|
149
|
+
<TouchableOpacity onPress={() => handleGoToOrder('MyOrders')}>
|
|
150
|
+
<View style={styles.navigationButton}>
|
|
151
|
+
<OText size={11} color={theme.colors.primary}>{t('GO_TO_MY_ORDERS', 'Go to my orders')}</OText>
|
|
152
|
+
<IconAntDesign
|
|
153
|
+
name='arrowright'
|
|
154
|
+
color={theme.colors.primary}
|
|
155
|
+
size={13}
|
|
156
|
+
style={{ marginHorizontal: 5 }}
|
|
157
|
+
/>
|
|
158
|
+
</View>
|
|
159
|
+
</TouchableOpacity>
|
|
160
|
+
</View>
|
|
161
|
+
</OrderInfoWrapper>
|
|
162
|
+
<View style={{ flex: 1 }}>
|
|
163
|
+
<ProgressContentWrapper>
|
|
164
|
+
<ProgressBar style={{ width: getOrderStatus(order.status)?.percentage ? `${getOrderStatus(order.status)?.percentage}%` : '0%' }} />
|
|
165
|
+
</ProgressContentWrapper>
|
|
166
|
+
<ProgressTextWrapper>
|
|
167
|
+
<OText size={12}>{getOrderStatus(order.status)?.value}</OText>
|
|
168
|
+
<TimeWrapper>
|
|
169
|
+
<OText size={11}>{t('ESTIMATED_DELIVERY', 'Estimated delivery')}</OText>
|
|
170
|
+
<OText size={11}>
|
|
171
|
+
{order?.delivery_datetime_utc
|
|
172
|
+
? parseTime(order?.delivery_datetime_utc, { outputFormat: 'hh:mm A' })
|
|
173
|
+
: parseTime(order?.delivery_datetime, { utc: false })}
|
|
174
|
+
-
|
|
175
|
+
{convertDiffToHours(order.delivery_type === 1 ? order?.business?.delivery_time : order?.business?.pickup_time, order)}
|
|
176
|
+
</OText>
|
|
177
|
+
</TimeWrapper>
|
|
178
|
+
</ProgressTextWrapper>
|
|
179
|
+
</View>
|
|
180
|
+
</View>
|
|
181
|
+
))}
|
|
182
|
+
{!orderList?.loading && orderList?.orders?.length === 0 && (
|
|
183
|
+
<NotFoundSource
|
|
184
|
+
image={imageFails}
|
|
185
|
+
content={t('NO_RESULTS_FOUND', 'Sorry, no results found')}
|
|
186
|
+
conditioned
|
|
187
|
+
/>
|
|
188
|
+
)}
|
|
189
|
+
</>
|
|
190
|
+
)
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
export const OrderProgress = (props: any) => {
|
|
194
|
+
const orderProgressProps = {
|
|
195
|
+
...props,
|
|
196
|
+
UIComponent: OrderProgressUI,
|
|
197
|
+
orderStatus: [0, 3, 4, 7, 8, 9, 13, 14, 15, 18, 19, 20, 21],
|
|
198
|
+
useDefualtSessionManager: true,
|
|
199
|
+
paginationSettings: {
|
|
200
|
+
initialPage: 1,
|
|
201
|
+
pageSize: 1,
|
|
202
|
+
controlType: 'infinity'
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
return <OrderList {...orderProgressProps} />
|
|
207
|
+
|
|
208
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import styled from 'styled-components/native'
|
|
2
|
+
|
|
3
|
+
export const ProgressContentWrapper = styled.View`
|
|
4
|
+
height: 12px;
|
|
5
|
+
background: #F8F9FA;
|
|
6
|
+
flex: 1;
|
|
7
|
+
`
|
|
8
|
+
|
|
9
|
+
export const ProgressBar = styled.View`
|
|
10
|
+
height: 12px;
|
|
11
|
+
background: ${(props: any) => props.theme.colors.primary};
|
|
12
|
+
`
|
|
13
|
+
|
|
14
|
+
export const TimeWrapper = styled.View`
|
|
15
|
+
flex-direction: column;
|
|
16
|
+
`
|
|
17
|
+
|
|
18
|
+
export const ProgressTextWrapper = styled.View`
|
|
19
|
+
margin-top: 7px;
|
|
20
|
+
flex-direction: row;
|
|
21
|
+
justify-content: space-between;
|
|
22
|
+
align-items: center;
|
|
23
|
+
`
|
|
24
|
+
|
|
25
|
+
export const OrderInfoWrapper = styled.View`
|
|
26
|
+
flex-direction: row;
|
|
27
|
+
width: 100%;
|
|
28
|
+
align-items: center;
|
|
29
|
+
margin-bottom: 15px;
|
|
30
|
+
`
|
|
@@ -1,16 +1,19 @@
|
|
|
1
|
-
import React from 'react';
|
|
1
|
+
import React, { useEffect } from 'react';
|
|
2
2
|
import {
|
|
3
3
|
ProductForm as ProductOptions,
|
|
4
4
|
useSession,
|
|
5
5
|
useLanguage,
|
|
6
6
|
useOrder,
|
|
7
|
-
useUtils
|
|
7
|
+
useUtils
|
|
8
8
|
} from 'ordering-components/native';
|
|
9
9
|
import { useTheme } from 'styled-components/native';
|
|
10
10
|
import { ProductIngredient } from '../ProductIngredient';
|
|
11
11
|
import { ProductOption } from '../ProductOption';
|
|
12
|
+
import Swiper from 'react-native-swiper'
|
|
13
|
+
import FastImage from 'react-native-fast-image';
|
|
14
|
+
import IconAntDesign from 'react-native-vector-icons/AntDesign';
|
|
12
15
|
|
|
13
|
-
import { View, TouchableOpacity, StyleSheet, Dimensions, Platform } from 'react-native';
|
|
16
|
+
import { View, TouchableOpacity, StyleSheet, Dimensions, Platform, AppRegistry } from 'react-native';
|
|
14
17
|
|
|
15
18
|
import {
|
|
16
19
|
ProductHeader,
|
|
@@ -25,7 +28,7 @@ import {
|
|
|
25
28
|
WrapperSubOption,
|
|
26
29
|
ProductComment,
|
|
27
30
|
ProductActions,
|
|
28
|
-
ExtraOptionWrap
|
|
31
|
+
ExtraOptionWrap
|
|
29
32
|
} from './styles';
|
|
30
33
|
import { OButton, OIcon, OInput, OText } from '../shared';
|
|
31
34
|
import { ScrollView } from 'react-native-gesture-handler';
|
|
@@ -110,13 +113,30 @@ export const ProductOptionsUI = (props: any) => {
|
|
|
110
113
|
borderBottomColor: theme.colors.border,
|
|
111
114
|
justifyContent: 'center',
|
|
112
115
|
},
|
|
116
|
+
slide1: {
|
|
117
|
+
flex: 1,
|
|
118
|
+
},
|
|
119
|
+
mainSwiper : {
|
|
120
|
+
height: 258,
|
|
121
|
+
},
|
|
122
|
+
swiperButton: {
|
|
123
|
+
marginHorizontal: 30,
|
|
124
|
+
alignItems: 'center',
|
|
125
|
+
justifyContent: 'center',
|
|
126
|
+
width: 32,
|
|
127
|
+
height: 32,
|
|
128
|
+
borderRadius: 16,
|
|
129
|
+
backgroundColor: 'rgba(255,255,255,0.3)'
|
|
130
|
+
}
|
|
113
131
|
});
|
|
114
132
|
|
|
115
|
-
const [{ parsePrice }] = useUtils();
|
|
133
|
+
const [{ parsePrice, optimizeImage }] = useUtils();
|
|
116
134
|
const [, t] = useLanguage();
|
|
117
135
|
const [orderState] = useOrder();
|
|
118
136
|
const [{ auth }] = useSession();
|
|
119
137
|
const { product, loading, error } = productObject;
|
|
138
|
+
const [gallery, setGallery] = useState([])
|
|
139
|
+
const [thumbsSwiper, setThumbsSwiper] = useState(0)
|
|
120
140
|
|
|
121
141
|
const { top, bottom } = useSafeAreaInsets();
|
|
122
142
|
const { height } = useWindowDimensions();
|
|
@@ -154,63 +174,76 @@ export const ProductOptionsUI = (props: any) => {
|
|
|
154
174
|
return sel[0]?.id !== undefined;
|
|
155
175
|
};
|
|
156
176
|
|
|
177
|
+
const handleChangeMainIndex = (index: number) => {
|
|
178
|
+
setThumbsSwiper(index)
|
|
179
|
+
}
|
|
180
|
+
|
|
157
181
|
const handleRedirectLogin = () => {
|
|
158
182
|
onClose();
|
|
159
183
|
navigation.navigate('Login');
|
|
160
184
|
};
|
|
161
185
|
|
|
186
|
+
useEffect(() => {
|
|
187
|
+
const productImgList: any = []
|
|
188
|
+
product?.images && productImgList.push(product.images)
|
|
189
|
+
for (const img of product?.gallery) {
|
|
190
|
+
productImgList.push(img.file)
|
|
191
|
+
}
|
|
192
|
+
setGallery(productImgList)
|
|
193
|
+
}, [product])
|
|
194
|
+
|
|
162
195
|
const saveErrors =
|
|
163
196
|
orderState.loading ||
|
|
164
197
|
maxProductQuantity === 0 ||
|
|
165
198
|
Object.keys(errors).length > 0;
|
|
166
199
|
|
|
167
200
|
const ExtraOptions = ({ eID, options }: any) => (
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
201
|
+
<>
|
|
202
|
+
{product?.ingredients.length > 0 && (
|
|
203
|
+
<TouchableOpacity
|
|
204
|
+
key={`eopt_all_00`}
|
|
205
|
+
onPress={() => setSelectedOpt(-1)}
|
|
206
|
+
style={[
|
|
207
|
+
styles.extraItem,
|
|
208
|
+
{
|
|
209
|
+
borderBottomColor:
|
|
210
|
+
selOpt == -1 ? theme.colors.textNormal : theme.colors.border,
|
|
211
|
+
},
|
|
212
|
+
]}>
|
|
213
|
+
<OText
|
|
214
|
+
color={selOpt == -1 ? theme.colors.textNormal : theme.colors.textSecondary}
|
|
215
|
+
size={selOpt == -1 ? 14 : 12}
|
|
216
|
+
weight={selOpt == -1 ? '600' : 'normal'}>
|
|
217
|
+
{t('INGREDIENTS', 'Ingredients')}
|
|
218
|
+
</OText>
|
|
219
|
+
</TouchableOpacity>
|
|
220
|
+
)}
|
|
221
|
+
{options.map(({ id, name, respect_to }: any) => (
|
|
222
|
+
<React.Fragment key={`cont_key_${id}`}>
|
|
223
|
+
{respect_to == null && (
|
|
224
|
+
<TouchableOpacity
|
|
225
|
+
key={`eopt_key_${id}`}
|
|
226
|
+
onPress={() => setSelectedOpt(id)}
|
|
227
|
+
style={[
|
|
228
|
+
styles.extraItem,
|
|
229
|
+
{
|
|
230
|
+
borderBottomColor:
|
|
231
|
+
selOpt == id ? theme.colors.textNormal : theme.colors.border,
|
|
232
|
+
},
|
|
233
|
+
]}>
|
|
234
|
+
<OText
|
|
235
|
+
color={
|
|
236
|
+
selOpt == id ? theme.colors.textNormal : theme.colors.textSecondary
|
|
237
|
+
}
|
|
238
|
+
size={selOpt == id ? 14 : 12}
|
|
239
|
+
weight={selOpt == id ? '600' : 'normal'}>
|
|
240
|
+
{name}
|
|
241
|
+
</OText>
|
|
242
|
+
</TouchableOpacity>
|
|
243
|
+
)}
|
|
244
|
+
</React.Fragment>
|
|
245
|
+
))}
|
|
246
|
+
</>
|
|
214
247
|
);
|
|
215
248
|
|
|
216
249
|
return (
|
|
@@ -238,11 +271,81 @@ export const ProductOptionsUI = (props: any) => {
|
|
|
238
271
|
</View>
|
|
239
272
|
) : (
|
|
240
273
|
<>
|
|
241
|
-
<
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
274
|
+
<Swiper
|
|
275
|
+
loop={false}
|
|
276
|
+
showsButtons={true}
|
|
277
|
+
style={styles.mainSwiper}
|
|
278
|
+
// index={thumbsSwiper}
|
|
279
|
+
onIndexChanged={(index) => handleChangeMainIndex(index)}
|
|
280
|
+
prevButton={
|
|
281
|
+
<View style={styles.swiperButton}>
|
|
282
|
+
<IconAntDesign
|
|
283
|
+
name="caretleft"
|
|
284
|
+
color={theme.colors.white}
|
|
285
|
+
size={13}
|
|
286
|
+
// style={styles.starIcon}
|
|
287
|
+
/>
|
|
288
|
+
</View>
|
|
289
|
+
}
|
|
290
|
+
nextButton={
|
|
291
|
+
<View style={styles.swiperButton}>
|
|
292
|
+
<IconAntDesign
|
|
293
|
+
name="caretright"
|
|
294
|
+
color={theme.colors.white}
|
|
295
|
+
size={13}
|
|
296
|
+
// style={styles.starIcon}
|
|
297
|
+
/>
|
|
298
|
+
</View>
|
|
299
|
+
}
|
|
300
|
+
>
|
|
301
|
+
{gallery.length > 0 && gallery.map((img, i) => (
|
|
302
|
+
<View
|
|
303
|
+
style={styles.slide1}
|
|
304
|
+
key={i}
|
|
305
|
+
>
|
|
306
|
+
<FastImage
|
|
307
|
+
style={{ height: '100%' }}
|
|
308
|
+
source={{
|
|
309
|
+
uri: optimizeImage(img, 'h_258,c_limit'),
|
|
310
|
+
priority: FastImage.priority.normal,
|
|
311
|
+
}}
|
|
312
|
+
/>
|
|
313
|
+
</View>
|
|
314
|
+
))}
|
|
315
|
+
</Swiper>
|
|
316
|
+
<ScrollView
|
|
317
|
+
horizontal
|
|
318
|
+
contentContainerStyle={{
|
|
319
|
+
paddingHorizontal: 30,
|
|
320
|
+
paddingVertical: 15
|
|
321
|
+
}}
|
|
322
|
+
>
|
|
323
|
+
{gallery.length > 0 && gallery.map((img, index) => (
|
|
324
|
+
<View
|
|
325
|
+
key={index}
|
|
326
|
+
style={{
|
|
327
|
+
height: 56,
|
|
328
|
+
borderRadius: 8,
|
|
329
|
+
margin: 8,
|
|
330
|
+
opacity: index === thumbsSwiper ? 1 : 0.8
|
|
331
|
+
}}
|
|
332
|
+
>
|
|
333
|
+
<OIcon
|
|
334
|
+
url={img}
|
|
335
|
+
style={{
|
|
336
|
+
borderColor: theme.colors.lightGray,
|
|
337
|
+
borderRadius: 8,
|
|
338
|
+
minHeight: '100%'
|
|
339
|
+
}}
|
|
340
|
+
width={56}
|
|
341
|
+
height={56}
|
|
342
|
+
cover
|
|
343
|
+
/>
|
|
344
|
+
{/* {thumbsSwiper === 2 && <OText color='red'>{index.toString()}</OText>}
|
|
345
|
+
{thumbsSwiper === 3 && <OText color='red'>{index.toString()}</OText>} */}
|
|
346
|
+
</View>
|
|
347
|
+
))}
|
|
348
|
+
</ScrollView>
|
|
246
349
|
</>
|
|
247
350
|
)}
|
|
248
351
|
</WrapHeader>
|