ordering-ui-react-native 0.16.48 → 0.16.49

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.
@@ -0,0 +1,167 @@
1
+ import React from 'react'
2
+ import { useTheme } from 'styled-components/native'
3
+ import { ScrollView, StyleSheet, View } from 'react-native'
4
+ import { useLanguage, useUtils } from 'ordering-components/native'
5
+ import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons'
6
+ import { OText, OButton } from '../shared'
7
+
8
+ export const OrderHistory = (props: any) => {
9
+ const {
10
+ order,
11
+ messages,
12
+ enableReview,
13
+ onClose,
14
+ handleTriggerReview
15
+ } = props
16
+
17
+ const [, t] = useLanguage()
18
+ const [{ parseDate }] = useUtils()
19
+ const theme = useTheme()
20
+
21
+ const styles = StyleSheet.create({
22
+ historyItem: {
23
+ display: 'flex',
24
+ alignItems: 'center',
25
+ flexDirection: 'row',
26
+ borderBottomWidth: 1,
27
+ borderColor: theme.colors.border
28
+ },
29
+ detailWrapper: {
30
+ marginLeft: 20,
31
+ paddingHorizontal: 13,
32
+ paddingVertical: 16
33
+ },
34
+ container: {
35
+ paddingHorizontal: 40,
36
+ paddingVertical: 15
37
+ }
38
+ });
39
+
40
+ const ORDER_STATUS: any = {
41
+ 0: 'ORDER_STATUS_PENDING',
42
+ 1: 'ORDERS_COMPLETED',
43
+ 2: 'ORDER_REJECTED',
44
+ 3: 'ORDER_STATUS_IN_BUSINESS',
45
+ 4: 'ORDER_READY',
46
+ 5: 'ORDER_REJECTED_RESTAURANT',
47
+ 6: 'ORDER_STATUS_CANCELLEDBYDRIVER',
48
+ 7: 'ORDER_STATUS_ACCEPTEDBYRESTAURANT',
49
+ 8: 'ORDER_CONFIRMED_ACCEPTED_BY_DRIVER',
50
+ 9: 'ORDER_PICKUP_COMPLETED_BY_DRIVER',
51
+ 10: 'ORDER_PICKUP_FAILED_BY_DRIVER',
52
+ 11: 'ORDER_DELIVERY_COMPLETED_BY_DRIVER',
53
+ 12: 'ORDER_DELIVERY_FAILED_BY_DRIVER',
54
+ 13: 'PREORDER',
55
+ 14: 'ORDER_NOT_READY',
56
+ 15: 'ORDER_PICKEDUP_COMPLETED_BY_CUSTOMER',
57
+ 16: 'ORDER_STATUS_CANCELLED_BY_CUSTOMER',
58
+ 17: 'ORDER_NOT_PICKEDUP_BY_CUSTOMER',
59
+ 18: 'ORDER_DRIVER_ALMOST_ARRIVED_BUSINESS',
60
+ 19: 'ORDER_DRIVER_ALMOST_ARRIVED_CUSTOMER',
61
+ 20: 'ORDER_CUSTOMER_ALMOST_ARRIVED_BUSINESS',
62
+ 21: 'ORDER_CUSTOMER_ARRIVED_BUSINESS',
63
+ 22: 'ORDER_LOOKING_FOR_DRIVER',
64
+ 23: 'ORDER_DRIVER_ON_WAY'
65
+ }
66
+
67
+ const getLogisticTagStatus = (status: any) => {
68
+ switch (status) {
69
+ case 0:
70
+ return t('PENDING', 'Pending')
71
+ case 1:
72
+ return t('IN_PROGRESS', 'In Progress')
73
+ case 2:
74
+ return t('IN_QUEUE', 'In Queue')
75
+ case 3:
76
+ return t('EXPIRED', 'Logistic expired')
77
+ case 4:
78
+ return t('RESOLVED', 'Resolved')
79
+ default:
80
+ return status
81
+ }
82
+ }
83
+
84
+ const handleReview = () => {
85
+ if (enableReview) handleTriggerReview()
86
+ else onClose()
87
+ }
88
+
89
+ return (
90
+ <ScrollView contentContainerStyle={styles.container}>
91
+ <OText size={20} style={{ alignSelf: 'center', textAlign: 'center' }} mBottom={10}>
92
+ {t('DETAILS_OF_ORDER', 'Details of Order_NUMBER_').replace('_NUMBER_', ` # ${order?.id}`)}
93
+ </OText>
94
+ {!messages?.loading && order && (
95
+ <View style={styles.historyItem}>
96
+ <MaterialCommunityIcons
97
+ name="checkbox-marked-circle"
98
+ size={20}
99
+ color={theme.colors.primary}
100
+ />
101
+ <View style={styles.detailWrapper}>
102
+ <OText
103
+ size={14}
104
+ weight='bold'
105
+ numberOfLines={1}
106
+ ellipsizeMode='tail'
107
+ >
108
+ {t('ORDER_PLACED', 'Order placed')} {' '}
109
+ {t('VIA', 'Via')}{' '}
110
+ {order.app_id ? t(order.app_id.toUpperCase(), order.app_id) : t('OTHER', 'Other')}
111
+ </OText>
112
+ <OText size={12}>{parseDate(order?.created_at, { outputFormat: 'MMM DD, hh:mm A' })}</OText>
113
+ </View>
114
+ </View>
115
+ )}
116
+ {messages && messages?.messages.map((message: any, i: number) => message.type === 1 && (
117
+ <View
118
+ style={styles.historyItem}
119
+ key={i}
120
+ >
121
+ <MaterialCommunityIcons
122
+ name="checkbox-marked-circle"
123
+ size={20}
124
+ color={theme.colors.primary}
125
+ />
126
+ <View style={styles.detailWrapper}>
127
+ {message.change?.attribute !== 'driver_id' ? (
128
+ <OText
129
+ size={14}
130
+ weight='bold'
131
+ numberOfLines={1}
132
+ ellipsizeMode='tail'
133
+ >
134
+ {message.change?.attribute === 'logistic_status'
135
+ ? getLogisticTagStatus(parseInt(message.change.new, 10))
136
+ : t(ORDER_STATUS[parseInt(message.change.new, 10)])
137
+ }
138
+ </OText>
139
+ ) : (
140
+ <OText
141
+ size={14}
142
+ weight='bold'
143
+ numberOfLines={1}
144
+ ellipsizeMode='tail'
145
+ >
146
+ {message.change.new
147
+ ? (`${message.driver?.name} ${!!message.driver?.lastname ? message.driver.lastname : ''} ${t('WAS_ASSIGNED_AS_DRIVER', 'Was assigned as driver')}`)
148
+ : t('DRIVER_UNASSIGNED', 'Driver unassigned')}
149
+ </OText>
150
+ )}
151
+ <OText size={12}>{parseDate(message?.created_at, { outputFormat: 'MMM DD, hh:mm A' })}</OText>
152
+ </View>
153
+ </View>
154
+ ))}
155
+ <OButton
156
+ text={enableReview ? t('REVIEW_ORDER', 'Review order') : t('CONTINUE', 'Continue')}
157
+ textStyle={{ fontSize: 14, color: theme.colors.white }}
158
+ imgRightSrc={theme.images.general.arrow_right}
159
+ imgRightStyle={{ tintColor: theme.colors.white, right: 5, margin: 5 }}
160
+ borderColor='transparent'
161
+ bgColor={theme.colors.primary}
162
+ style={{ borderRadius: 7.6, borderWidth: 1, height: 44, shadowOpacity: 0, marginBottom: 30, marginTop: 20 }}
163
+ onClick={() => handleReview()}
164
+ />
165
+ </ScrollView>
166
+ )
167
+ }
@@ -43,6 +43,7 @@ import AntIcon from 'react-native-vector-icons/AntDesign'
43
43
  import { TaxInformation } from '../TaxInformation';
44
44
  import { Placeholder, PlaceholderLine } from 'rn-placeholder';
45
45
  import NavBar from '../NavBar'
46
+ import { OrderHistory } from './OrderHistory';
46
47
  export const OrderDetailsUI = (props: OrderDetailsParams) => {
47
48
  const {
48
49
  navigation,
@@ -85,6 +86,11 @@ export const OrderDetailsUI = (props: OrderDetailsParams) => {
85
86
  width: 30,
86
87
  marginTop: Platform.OS === 'ios' ? 0 : 30
87
88
  },
89
+ linkWrapper: {
90
+ display: 'flex',
91
+ alignItems: 'center',
92
+ flexDirection: 'row'
93
+ }
88
94
  });
89
95
 
90
96
  const [, t] = useLanguage();
@@ -93,6 +99,7 @@ export const OrderDetailsUI = (props: OrderDetailsParams) => {
93
99
  const [{ carts }] = useOrder()
94
100
 
95
101
  const [isReviewed, setIsReviewed] = useState(false)
102
+ const [isOrderHistory, setIsOrderHistory] = useState(false)
96
103
  const [openTaxModal, setOpenTaxModal] = useState<any>({ open: false, tax: null, type: '' })
97
104
  const { order, businessData } = props.order;
98
105
  const mapValidStatuses = [9, 19, 23]
@@ -366,6 +373,14 @@ export const OrderDetailsUI = (props: OrderDetailsParams) => {
366
373
  )
367
374
  }
368
375
 
376
+ const handleTriggerReview = () => {
377
+ setIsOrderHistory(false);
378
+ (
379
+ parseInt(order?.status) === 1 ||
380
+ parseInt(order?.status) === 11 ||
381
+ parseInt(order?.status) === 15
382
+ ) && !order.review && !isReviewed && handleClickOrderReview(order)
383
+ }
369
384
 
370
385
  useEffect(() => {
371
386
  const _businessId = 'businessId:' + businessData?.id
@@ -377,7 +392,7 @@ export const OrderDetailsUI = (props: OrderDetailsParams) => {
377
392
  }
378
393
  if (!reorderState?.error && reorderState.loading === false && businessData?.id) {
379
394
  const products = carts?.[_businessId]?.products
380
- const available = products.every((product: any) => product.valid === true)
395
+ const available = products?.every((product: any) => product.valid === true)
381
396
 
382
397
  if (available && reorderState?.result?.uuid && (products?.length === order?.products.length)) {
383
398
  onNavigationRedirect && onNavigationRedirect('CheckoutNavigator', { cartUuid: reorderState?.result.uuid })
@@ -507,7 +522,8 @@ export const OrderDetailsUI = (props: OrderDetailsParams) => {
507
522
  />
508
523
  <OrderInfo>
509
524
  <OrderData>
510
- {
525
+ <View style={styles.linkWrapper}>
526
+ {
511
527
  (
512
528
  parseInt(order?.status) === 1 ||
513
529
  parseInt(order?.status) === 11 ||
@@ -515,20 +531,36 @@ export const OrderDetailsUI = (props: OrderDetailsParams) => {
515
531
  ) && !order.review && !isReviewed && (
516
532
  <TouchableOpacity
517
533
  activeOpacity={0.7}
518
- style={{ marginTop: 6 }}
534
+ style={{ marginTop: 6, marginRight: 10 }}
519
535
  onPress={() => handleClickOrderReview(order)}
520
-
521
536
  >
522
537
  <OText
523
538
  size={10}
524
539
  lineHeight={15}
525
- color={theme.colors.textSecondary}
540
+ color={theme.colors.primary}
526
541
  style={{ textDecorationLine: 'underline' }}
527
542
  >
528
543
  {t('REVIEW_YOUR_ORDER', 'Review your order')}
529
544
  </OText>
530
545
  </TouchableOpacity>
531
546
  )}
547
+ <TouchableOpacity
548
+ activeOpacity={0.7}
549
+ style={{ marginTop: 6 }}
550
+ onPress={() => setIsOrderHistory(true)}
551
+
552
+ >
553
+ <OText
554
+ size={10}
555
+ lineHeight={15}
556
+ color={theme.colors.primary}
557
+ style={{ textDecorationLine: 'underline', textTransform: 'capitalize' }}
558
+ >
559
+ {t('VIEW_DETAILS', 'View Details')}
560
+ </OText>
561
+ </TouchableOpacity>
562
+ </View>
563
+
532
564
  <StaturBar>
533
565
  <LinearGradient
534
566
  start={{ x: 0.0, y: 0.0 }}
@@ -1056,6 +1088,23 @@ export const OrderDetailsUI = (props: OrderDetailsParams) => {
1056
1088
  products={order?.products}
1057
1089
  />
1058
1090
  </OModal>
1091
+ <OModal
1092
+ open={isOrderHistory}
1093
+ onClose={() => setIsOrderHistory(false)}
1094
+ entireModal
1095
+ >
1096
+ <OrderHistory
1097
+ order={order}
1098
+ messages={messages}
1099
+ enableReview={(
1100
+ parseInt(order?.status) === 1 ||
1101
+ parseInt(order?.status) === 11 ||
1102
+ parseInt(order?.status) === 15
1103
+ ) && !order.review && !isReviewed}
1104
+ onClose={() => setIsOrderHistory(false)}
1105
+ handleTriggerReview={handleTriggerReview}
1106
+ />
1107
+ </OModal>
1059
1108
  </OrderDetailsContainer>
1060
1109
  );
1061
1110
  };
@@ -98,11 +98,18 @@ const OrdersOptionUI = (props: OrdersOptionParams) => {
98
98
  }
99
99
 
100
100
  const onProductClick = (product: any) => {
101
- if (product?.product_id && product?.category_id && product?.businessId) {
101
+ if (product?.product_id && product?.category_id && product?.businessId &&
102
+ product?.business.slug && product?.business.header && product?.business.logo) {
102
103
  onNavigationRedirect('ProductDetails', {
103
- productId: product?.product_id,
104
- categoryId: product?.category_id,
104
+ isRedirect: 'business',
105
105
  businessId: product?.businessId,
106
+ categoryId: product?.category_id,
107
+ productId: product?.product_id,
108
+ business: {
109
+ store: product?.business.slug,
110
+ header: product?.business.header,
111
+ logo: product?.business.logo,
112
+ }
106
113
  })
107
114
  } else {
108
115
  showToast(ToastType.Error, t('ERROR_FAILED_REDIRECT_IDS', 'Failed to redirect product for ids'))
@@ -1,5 +1,4 @@
1
1
  import React, { useState } from 'react';
2
- import moment from 'moment';
3
2
  import {
4
3
  SingleOrderCard as SingleOrderCardController,
5
4
  useUtils,
@@ -36,20 +35,20 @@ const SingleOrderCardUI = (props: SingleOrderCardParams) => {
36
35
  handleClickOrder
37
36
  } = props;
38
37
 
39
- const [{ parsePrice, optimizeImage }] = useUtils();
38
+ const [{ parsePrice, optimizeImage, parseDate }] = useUtils();
40
39
  const [, t] = useLanguage();
41
- const theme = useTheme();
40
+ const theme = useTheme();
42
41
 
43
- const [reorderSelected, setReorderSelected] = useState<number | null>(null);
42
+ const [reorderSelected, setReorderSelected] = useState<number | null>(null);
44
43
 
45
- const allowedOrderStatus = [1, 2, 5, 6, 10, 11, 12];
44
+ const allowedOrderStatus = [1, 2, 5, 6, 10, 11, 12];
46
45
 
47
46
  const styles = StyleSheet.create({
48
- logo: {
49
- borderRadius: 8,
50
- width: 64,
51
- height: 64
52
- },
47
+ logo: {
48
+ borderRadius: 8,
49
+ width: 64,
50
+ height: 64
51
+ },
53
52
  logoWrapper: {
54
53
  overflow: 'hidden',
55
54
  backgroundColor: 'white',
@@ -62,79 +61,75 @@ const SingleOrderCardUI = (props: SingleOrderCardParams) => {
62
61
  },
63
62
  buttonText: {
64
63
  color: theme.colors.primary,
65
- fontSize: 10,
66
- marginLeft: 2,
67
- marginRight: 2,
64
+ fontSize: 10,
65
+ marginLeft: 2,
66
+ marginRight: 2,
68
67
  },
69
68
  reorderLoading: {
70
69
  width: 80,
71
- height: 40,
72
- borderRadius: 10,
70
+ height: 40,
71
+ borderRadius: 10,
73
72
  },
74
73
  reorderbutton: {
75
- height: 23,
76
- paddingLeft: 10,
77
- paddingRight: 10,
78
- borderRadius: 23,
79
- shadowOpacity: 0,
80
- backgroundColor: theme.colors.primaryContrast,
81
- borderWidth: 0,
82
- },
74
+ height: 23,
75
+ paddingLeft: 10,
76
+ paddingRight: 10,
77
+ borderRadius: 23,
78
+ shadowOpacity: 0,
79
+ backgroundColor: theme.colors.primaryContrast,
80
+ borderWidth: 0,
81
+ },
83
82
  reviewButton: {
84
- height: 23,
85
- maxHeight: 23,
86
- backgroundColor: theme.colors.white,
87
- alignItems: 'center',
88
- justifyContent: 'center',
89
- paddingHorizontal: 10,
90
- borderRadius: 23,
91
- borderWidth: 1,
92
- borderColor: theme.colors.primaryContrast,
83
+ height: 23,
84
+ maxHeight: 23,
85
+ backgroundColor: theme.colors.white,
86
+ alignItems: 'center',
87
+ justifyContent: 'center',
88
+ paddingHorizontal: 10,
89
+ borderRadius: 23,
90
+ borderWidth: 1,
91
+ borderColor: theme.colors.primaryContrast,
93
92
  marginRight: 2
94
- },
93
+ },
95
94
  infoText: {
96
95
  flexDirection: 'row',
97
96
  alignItems: 'center'
98
97
  }
99
- });
98
+ });
100
99
 
101
100
  const handleReorderClick = (id: number) => {
102
- setReorderSelected(id);
103
- handleReorder && handleReorder(id);
104
- };
101
+ setReorderSelected(id);
102
+ handleReorder && handleReorder(id);
103
+ };
105
104
 
106
105
  const handleClickOrderReview = (order: any) => {
107
106
  if (pastOrders) {
108
107
  onNavigationRedirect &&
109
- onNavigationRedirect('ReviewOrder', {
110
- order: {
111
- id: order?.id,
112
- business_id: order?.business_id,
113
- logo: order?.business?.logo,
114
- driver: order?.driver,
115
- products: order?.products,
116
- review: order?.review,
117
- user_review: order?.user_review
118
- },
119
- });
108
+ onNavigationRedirect('ReviewOrder', {
109
+ order: {
110
+ id: order?.id,
111
+ business_id: order?.business_id,
112
+ logo: order?.business?.logo,
113
+ driver: order?.driver,
114
+ products: order?.products,
115
+ review: order?.review,
116
+ user_review: order?.user_review
117
+ },
118
+ });
120
119
  return
121
120
  }
122
121
  if (isMessageView) {
123
- handleClickOrder(order?.uuid)
124
- return
125
- }
126
- onNavigationRedirect &&
127
- onNavigationRedirect('OrderDetails', { orderId: order?.uuid });
128
- };
122
+ handleClickOrder(order?.uuid)
123
+ return
124
+ }
125
+ onNavigationRedirect &&
126
+ onNavigationRedirect('OrderDetails', { orderId: order?.uuid });
127
+ };
129
128
 
130
129
  const handleClickViewOrder = (uuid: string) => {
131
- onNavigationRedirect &&
132
- onNavigationRedirect('OrderDetails', { orderId: uuid });
133
- };
134
-
135
- const formatDate = (date: string, option?: any) => {
136
- return option?.utc ? moment.utc(date).format('DD/MM/YY \u2022 h:m a') : moment(date).format('DD/MM/YY \u2022 h:m a');
137
- };
130
+ onNavigationRedirect &&
131
+ onNavigationRedirect('OrderDetails', { orderId: uuid });
132
+ };
138
133
 
139
134
  const handleChangeFavorite = () => {
140
135
  handleFavoriteOrder && handleFavoriteOrder(!order?.favorite)
@@ -143,7 +138,7 @@ const SingleOrderCardUI = (props: SingleOrderCardParams) => {
143
138
  return (
144
139
  <Container
145
140
  onPress={() => handleClickViewOrder(order?.uuid)}
146
- activeOpacity={0.7}
141
+ activeOpacity={0.7}
147
142
  >
148
143
  <InnerContainer>
149
144
  {!!order.business?.logo && (
@@ -164,22 +159,22 @@ const SingleOrderCardUI = (props: SingleOrderCardParams) => {
164
159
  {!!!pastOrders && (
165
160
  <>
166
161
  {isMessageView ? (
167
- <>
168
- {order?.unread_count > 0 && (
169
- <UnreadMessageCounter>
170
- <OText size={12} color={theme.colors.primary} lineHeight={18} >
171
- {order?.unread_count}
172
- </OText>
173
- </UnreadMessageCounter>
174
- )}
175
- </>
176
- ) : (
177
- <Price>
178
- <OText size={12} lineHeight={18}>
179
- {parsePrice(order?.summary?.total || order?.total)}
180
- </OText>
181
- </Price>
182
- )}
162
+ <>
163
+ {order?.unread_count > 0 && (
164
+ <UnreadMessageCounter>
165
+ <OText size={12} color={theme.colors.primary} lineHeight={18} >
166
+ {order?.unread_count}
167
+ </OText>
168
+ </UnreadMessageCounter>
169
+ )}
170
+ </>
171
+ ) : (
172
+ <Price>
173
+ <OText size={12} lineHeight={18}>
174
+ {parsePrice(order?.summary?.total || order?.total)}
175
+ </OText>
176
+ </Price>
177
+ )}
183
178
  </>
184
179
  )}
185
180
  {!!pastOrders && (
@@ -243,29 +238,27 @@ const SingleOrderCardUI = (props: SingleOrderCardParams) => {
243
238
  color={theme.colors.textSecondary}
244
239
  style={{ marginVertical: 3 }}
245
240
  numberOfLines={1}>
246
- {order?.delivery_datetime_utc
247
- ? formatDate(order?.delivery_datetime_utc)
248
- : formatDate(order?.delivery_datetime, { utc: false })}
241
+ {order?.delivery_datetime_utc ? parseDate(order?.delivery_datetime_utc) : parseDate(order?.delivery_datetime, { utc: false })}
249
242
  </OText>
250
243
  </View>
251
- <OText
252
- color={theme.colors.primary}
253
- size={10}
254
- lineHeight={15}
255
- numberOfLines={1}>
256
- {getOrderStatus(order.status)?.value}
257
- </OText>
244
+ <OText
245
+ color={theme.colors.primary}
246
+ size={10}
247
+ lineHeight={15}
248
+ numberOfLines={1}>
249
+ {getOrderStatus(order.status)?.value}
250
+ </OText>
258
251
  </View>
259
252
  <TouchableOpacity
260
- onPress={handleChangeFavorite}
253
+ onPress={handleChangeFavorite}
261
254
  style={{ marginTop: 5 }}
262
- >
263
- <IconAntDesign
264
- name={order?.favorite ? 'heart' : 'hearto'}
265
- color={theme.colors.danger5}
266
- size={16}
267
- />
268
- </TouchableOpacity>
255
+ >
256
+ <IconAntDesign
257
+ name={order?.favorite ? 'heart' : 'hearto'}
258
+ color={theme.colors.danger5}
259
+ size={16}
260
+ />
261
+ </TouchableOpacity>
269
262
  </ContentFooter>
270
263
  </CardInfoWrapper>
271
264
  </InnerContainer>