ordering-ui-react-native 0.12.33 → 0.12.37

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.
Files changed (30) hide show
  1. package/package.json +1 -1
  2. package/themes/business/src/components/AcceptOrRejectOrder/index.tsx +6 -5
  3. package/themes/business/src/components/OrderDetails/Business.tsx +2 -4
  4. package/themes/business/src/components/OrderDetails/Delivery.tsx +231 -202
  5. package/themes/business/src/components/OrderDetails/OrderContentComponent.tsx +344 -334
  6. package/themes/business/src/components/OrderDetails/OrderHeaderComponent.tsx +83 -69
  7. package/themes/business/src/components/OrdersOption/index.tsx +122 -77
  8. package/themes/business/src/components/PreviousOrders/index.tsx +124 -73
  9. package/themes/business/src/components/PreviousOrders/styles.tsx +7 -0
  10. package/themes/business/src/components/ProductItemAccordion/index.tsx +26 -25
  11. package/themes/business/src/components/shared/OIcon.tsx +2 -0
  12. package/themes/business/src/types/index.tsx +5 -0
  13. package/themes/single-business/src/components/BusinessBasicInformation/index.tsx +1 -1
  14. package/themes/single-business/src/components/BusinessProductsListing/index.tsx +9 -8
  15. package/themes/single-business/src/components/BusinessesListing/index.tsx +307 -296
  16. package/themes/single-business/src/components/BusinessesListing/styles.tsx +41 -14
  17. package/themes/single-business/src/components/HelpAccountAndPayment/index.tsx +7 -6
  18. package/themes/single-business/src/components/HelpGuide/index.tsx +7 -6
  19. package/themes/single-business/src/components/HelpOrder/index.tsx +7 -6
  20. package/themes/single-business/src/components/LanguageSelector/index.tsx +87 -70
  21. package/themes/single-business/src/components/LoginForm/index.tsx +2 -2
  22. package/themes/single-business/src/components/OrderDetails/index.tsx +21 -21
  23. package/themes/single-business/src/components/ProductForm/index.tsx +682 -656
  24. package/themes/single-business/src/components/ProductForm/styles.tsx +1 -1
  25. package/themes/single-business/src/components/UserProfile/index.tsx +2 -2
  26. package/themes/single-business/src/components/shared/OIconButton.tsx +2 -2
  27. package/themes/single-business/src/components/shared/OInput.tsx +1 -0
  28. package/themes/single-business/src/components/shared/OLink.tsx +80 -0
  29. package/themes/single-business/src/components/shared/index.tsx +2 -0
  30. package/themes/single-business/src/types/index.tsx +3 -0
@@ -1,28 +1,36 @@
1
1
  import React from 'react';
2
- import { StyleSheet, TouchableOpacity } from 'react-native';
2
+ import { StyleSheet, TouchableOpacity, View } from 'react-native';
3
3
  import { useTheme } from 'styled-components/native';
4
4
  import { useLanguage, useUtils } from 'ordering-components/native';
5
- import { OIcon, OText } from '../shared';
6
- import { Card, Logo, Information, MyOrderOptions, NotificationIcon } from './styles';
5
+ import { OButton, OIcon, OText } from '../shared';
6
+ import { Card, Logo, Information, MyOrderOptions, NotificationIcon, AcceptOrRejectOrder } from './styles';
7
7
  import EntypoIcon from 'react-native-vector-icons/Entypo'
8
8
 
9
9
  export const PreviousOrders = (props: any) => {
10
- const { orders, onNavigationRedirect, getOrderStatus, handleClickOrder } = props;
10
+ const {
11
+ orders,
12
+ onNavigationRedirect,
13
+ getOrderStatus,
14
+ handleClickOrder,
15
+ isLogisticOrder,
16
+ handleClickLogisticOrder
17
+ } = props;
11
18
  const [, t] = useLanguage();
12
19
  const [{ parseDate, optimizeImage }] = useUtils();
13
20
  const theme = useTheme();
14
21
 
15
22
  const handlePressOrder = (order: any) => {
23
+ if (order?.locked && isLogisticOrder) return
16
24
  handleClickOrder && handleClickOrder(order)
17
25
  onNavigationRedirect &&
18
- onNavigationRedirect('OrderDetails', { order: order });
26
+ onNavigationRedirect('OrderDetails', { order: { ...order, isLogistic: isLogisticOrder }, handleClickLogisticOrder });
19
27
  };
20
28
 
21
29
  const styles = StyleSheet.create({
22
30
  cardButton: {
23
31
  flex: 1,
24
- minHeight: 64,
25
- marginBottom: 30,
32
+ minHeight: isLogisticOrder ? 50 : 64,
33
+ marginBottom: isLogisticOrder ? 0 : 30,
26
34
  marginLeft: 3,
27
35
  },
28
36
  icon: {
@@ -78,74 +86,117 @@ export const PreviousOrders = (props: any) => {
78
86
  {orders && orders?.length > 0 &&
79
87
  orders
80
88
  .filter((order: any) => hash[order?.id] ? false : (hash[order?.id] = true))
81
- .map((order: any) =>
82
- (
83
- <React.Fragment key={order.id}>
84
- <TouchableOpacity
85
- onPress={() => handlePressOrder(order)}
86
- style={styles.cardButton}
87
- activeOpacity={1}
88
- >
89
- <Card key={order.id}>
90
- {!!order.business?.logo && (
91
- <Logo style={styles.logo}>
92
- <OIcon
93
- url={optimizeImage(
94
- order.business?.logo,
95
- 'h_300,c_limit',
96
- )}
97
- style={styles.icon}
98
- />
99
- </Logo>
100
- )}
101
- <Information>
102
- <OText numberOfLines={1} style={styles.title}>
103
- {order.business?.name}
104
- </OText>
105
- {order?.showNotification && (
106
- <NotificationIcon>
107
- <EntypoIcon
108
- name="dot-single"
109
- size={32}
110
- color={theme.colors.primary}
89
+ .map((_order: any) => {
90
+ const order = _order?.isLogistic && !_order?.order_group ? _order?.order : _order
91
+ return (
92
+ <View
93
+ style={{
94
+ backgroundColor: order?.locked && isLogisticOrder ? '#ccc' : '#fff',
95
+ marginBottom: isLogisticOrder ? 10 : 0
96
+ }}
97
+ key={order.id}
98
+ >
99
+ <TouchableOpacity
100
+ onPress={() => handlePressOrder({ ...order, logistic_order_id: _order?.id })}
101
+ style={styles.cardButton}
102
+ disabled={order?.locked && isLogisticOrder}
103
+ activeOpacity={1}
104
+ >
105
+ <Card key={order.id}>
106
+ {
107
+ order.business?.logo && (
108
+ <Logo style={styles.logo}>
109
+ <OIcon
110
+ url={optimizeImage(
111
+ order.business?.logo,
112
+ 'h_300,c_limit',
113
+ )}
114
+ style={styles.icon}
115
+ />
116
+ </Logo>
117
+ )}
118
+ <Information>
119
+ {order?.order_group && order?.order_group_id && (
120
+ <OText>
121
+ <OText>{order?.order_group?.orders?.length} {t('ORDERS', 'Orders')}</OText>
122
+ </OText>
123
+ )}
124
+ {order.business?.name && (
125
+ <OText numberOfLines={1} style={styles.title}>
126
+ {order.business?.name}
127
+ </OText>
128
+ )}
129
+ {order?.showNotification && (
130
+ <NotificationIcon>
131
+ <EntypoIcon
132
+ name="dot-single"
133
+ size={32}
134
+ color={theme.colors.primary}
135
+ />
136
+ </NotificationIcon>
137
+ )}
138
+ <OText
139
+ style={styles.date}
140
+ numberOfLines={1}
141
+ adjustsFontSizeToFit
142
+ size={20}>
143
+ {(order?.order_group && order?.order_group_id ? (t('INVOICE_GROUP_NO', 'Group No.') + order?.order_group_id) : (t('INVOICE_ORDER_NO', 'Order No.') + order.id)) + ' · '}
144
+ {order?.delivery_datetime_utc
145
+ ? parseDate(order?.delivery_datetime_utc)
146
+ : parseDate(order?.delivery_datetime, { utc: false })}
147
+ </OText>
148
+ {!isLogisticOrder && (
149
+ <MyOrderOptions>
150
+ <OText
151
+ style={styles.orderType}
152
+ mRight={5}
153
+ numberOfLines={1}
154
+ adjustsFontSizeToFit
155
+ >
156
+ {order.delivery_type === 1
157
+ ? t('DELIVERY', 'Delivery')
158
+ : order.delivery_type === 2
159
+ ? t('PICKUP', 'Pickup')
160
+ : order.delivery_type === 3
161
+ ? t('EAT_IN', 'Eat in')
162
+ : order.delivery_type === 4
163
+ ? t('CURBSIDE', 'Curbside')
164
+ : t('DRIVER_THRU', 'Driver thru')}
165
+ {` · ${getOrderStatus(order.status)}`}
166
+ </OText>
167
+ </MyOrderOptions>
168
+ )}
169
+ </Information>
170
+ </Card>
171
+ </TouchableOpacity>
172
+ {isLogisticOrder && (
173
+ <AcceptOrRejectOrder>
174
+ <OButton
175
+ text={t('REJECT', 'Reject')}
176
+ onClick={() => handleClickLogisticOrder(2, _order?.id)}
177
+ bgColor={theme.colors.danger}
178
+ borderColor={theme.colors.danger}
179
+ imgRightSrc={null}
180
+ style={{ borderRadius: 7, height: 40 }}
181
+ parentStyle={{ width: '45%' }}
182
+ textStyle={{ color: theme.colors.dangerText }}
111
183
  />
112
- </NotificationIcon>
184
+ <OButton
185
+ text={t('ACCEPT', 'Accept')}
186
+ onClick={() => handleClickLogisticOrder(1, _order?.id)}
187
+ bgColor={theme.colors.successOrder}
188
+ borderColor={theme.colors.successOrder}
189
+ imgRightSrc={null}
190
+ style={{ borderRadius: 7, height: 40 }}
191
+ parentStyle={{ width: '45%' }}
192
+ textStyle={{ color: theme.colors.successText }}
193
+ />
194
+ </AcceptOrRejectOrder>
113
195
  )}
114
- <OText
115
- style={styles.date}
116
- numberOfLines={1}
117
- adjustsFontSizeToFit
118
- size={20}>
119
- {t('INVOICE_ORDER_NO', 'Order No.') + order.id + ' · '}
120
- {order?.delivery_datetime_utc
121
- ? parseDate(order?.delivery_datetime_utc)
122
- : parseDate(order?.delivery_datetime, { utc: false })}
123
- </OText>
124
-
125
- <MyOrderOptions>
126
- <OText
127
- style={styles.orderType}
128
- mRight={5}
129
- numberOfLines={1}
130
- adjustsFontSizeToFit
131
- >
132
- {order.delivery_type === 1
133
- ? t('DELIVERY', 'Delivery')
134
- : order.delivery_type === 2
135
- ? t('PICKUP', 'Pickup')
136
- : order.delivery_type === 3
137
- ? t('EAT_IN', 'Eat in')
138
- : order.delivery_type === 4
139
- ? t('CURBSIDE', 'Curbside')
140
- : t('DRIVER_THRU', 'Driver thru')}
141
- {` · ${getOrderStatus(order.status)}`}
142
- </OText>
143
- </MyOrderOptions>
144
- </Information>
145
- </Card>
146
- </TouchableOpacity>
147
- </React.Fragment>
148
- ))}
196
+ </View>
197
+ )
198
+ }
199
+ )}
149
200
  </>
150
201
  );
151
202
  };
@@ -29,3 +29,10 @@ export const NotificationIcon = styled.View`
29
29
  position: absolute;
30
30
  left: 90%;
31
31
  `
32
+
33
+ export const AcceptOrRejectOrder = styled.View`
34
+ flex-direction: row;
35
+ justify-content: space-between;
36
+ flex: 1;
37
+ margin: 10px;
38
+ `
@@ -49,7 +49,6 @@ export const ProductItemAccordion = (props: ProductItemAccordionParams) => {
49
49
  option.suboptions = Object.values(option.suboptions ?? {});
50
50
  return option;
51
51
  });
52
-
53
52
  return {
54
53
  ...productInfo,
55
54
  ingredients,
@@ -60,11 +59,13 @@ export const ProductItemAccordion = (props: ProductItemAccordionParams) => {
60
59
  return product;
61
60
  };
62
61
 
62
+ const parseOptions = typeof productInfo().options === 'string' ? JSON.parse(productInfo().options) : productInfo().options
63
+
63
64
  const getProductPrice = (product: any) => {
64
65
  let subOptionPrice = 0;
65
- if (product.options.length > 0) {
66
- for (const option of product.options) {
67
- for (const suboption of option.suboptions) {
66
+ if (product?.options?.length > 0 && product?.options?.suboptions?.length > 0) {
67
+ for (const option of product?.options) {
68
+ for (const suboption of option?.suboptions) {
68
69
  subOptionPrice += suboption.quantity * suboption.price;
69
70
  }
70
71
  }
@@ -98,8 +99,8 @@ export const ProductItemAccordion = (props: ProductItemAccordionParams) => {
98
99
 
99
100
  useEffect(() => {
100
101
  if (
101
- productInfo().ingredients.length > 0 ||
102
- productInfo().options.length > 0 ||
102
+ productInfo?.()?.ingredients?.length > 0 ||
103
+ productInfo?.()?.options?.length > 0 ||
103
104
  product.comment !== ''
104
105
  ) {
105
106
  setActiveState(true);
@@ -150,12 +151,12 @@ export const ProductItemAccordion = (props: ProductItemAccordionParams) => {
150
151
  </OText>
151
152
 
152
153
  {(
153
- productInfo().ingredients.length > 0 ||
154
- productInfo().options.length > 0 ||
154
+ productInfo?.()?.ingredients?.length > 0 ||
155
+ productInfo?.()?.options?.length > 0 ||
155
156
  product.comment
156
157
  ) && !isClickableEvent && (
157
- <MaterialCommunityIcon name="chevron-down" size={12} />
158
- )}
158
+ <MaterialCommunityIcon name="chevron-down" size={12} />
159
+ )}
159
160
  </View>
160
161
 
161
162
  <View
@@ -201,20 +202,20 @@ export const ProductItemAccordion = (props: ProductItemAccordionParams) => {
201
202
  product?.valid_menu &&
202
203
  !product?.valid_quantity) ||
203
204
  (!product?.valid_menu && isCartProduct && !isCartPending)) && (
204
- <OText
205
- size={24}
206
- color={theme.colors.red}
207
- style={{ textAlign: 'center', marginTop: 10 }}>
208
- {t('NOT_AVAILABLE', 'Not available')}
209
- </OText>
210
- )}
205
+ <OText
206
+ size={24}
207
+ color={theme.colors.red}
208
+ style={{ textAlign: 'center', marginTop: 10 }}>
209
+ {t('NOT_AVAILABLE', 'Not available')}
210
+ </OText>
211
+ )}
211
212
  </Accordion>
212
213
 
213
214
  <View style={{ display: isActive ? 'flex' : 'none' }}>
214
215
  <Animated.View>
215
216
  <AccordionContent>
216
- {productInfo().ingredients.length > 0 &&
217
- productInfo().ingredients.some(
217
+ {productInfo?.()?.ingredients?.length > 0 &&
218
+ productInfo?.()?.ingredients?.some(
218
219
  (ingredient: any) => !ingredient.selected,
219
220
  ) && (
220
221
  <ProductOptionsList>
@@ -225,7 +226,7 @@ export const ProductItemAccordion = (props: ProductItemAccordionParams) => {
225
226
  {t('INGREDIENTS', 'Ingredients')}:
226
227
  </OText>
227
228
 
228
- {productInfo().ingredients.map(
229
+ {productInfo?.()?.ingredients?.map(
229
230
  (ingredient: any) =>
230
231
  !ingredient.selected && (
231
232
  <OText
@@ -240,9 +241,9 @@ export const ProductItemAccordion = (props: ProductItemAccordionParams) => {
240
241
  </ProductOptionsList>
241
242
  )}
242
243
 
243
- {productInfo().options.length > 0 && (
244
+ {parseOptions?.length > 0 && (
244
245
  <ProductOptionsList>
245
- {productInfo().options.map((option: any, i: number) => (
246
+ {parseOptions?.map((option: any, i: number) => (
246
247
  <ProductOption key={option.id + i}>
247
248
  <OText
248
249
  size={12}
@@ -263,9 +264,9 @@ export const ProductItemAccordion = (props: ProductItemAccordionParams) => {
263
264
  position:
264
265
  suboption.position !== 'whole'
265
266
  ? t(
266
- suboption.position.toUpperCase(),
267
- suboption.position,
268
- )
267
+ suboption.position.toUpperCase(),
268
+ suboption.position,
269
+ )
269
270
  : '',
270
271
  price: parsePrice(suboption.price),
271
272
  })}
@@ -20,6 +20,7 @@ interface Props {
20
20
  cover?: boolean;
21
21
  children?: any;
22
22
  borderRadius?: number;
23
+ borderBottomWidth?: number
23
24
  }
24
25
 
25
26
  const OImage = (props: Props): React.ReactElement => {
@@ -30,6 +31,7 @@ const OImage = (props: Props): React.ReactElement => {
30
31
  borderRadius: props.style?.borderRadius,
31
32
  overflow: 'hidden',
32
33
  marginHorizontal: props.style?.marginHorizontal,
34
+ borderBottomWidth: props.borderBottomWidth
33
35
  }}>
34
36
  <SImage
35
37
  source={
@@ -285,6 +285,10 @@ export interface OrdersOptionParams {
285
285
  cancelled?: Array<number>;
286
286
  };
287
287
  isBusinessApp?: boolean;
288
+ handleClickLogisticOrder: (status: number, orderId: number) => void,
289
+ logisticOrders: {orders: Array<any>, loading: boolean, error: Array<string> | string},
290
+ loadLogisticOrders: () => void;
291
+ isLogisticActivated?: boolean
288
292
  }
289
293
  export interface ActiveOrdersParams {
290
294
  orders?: any;
@@ -365,6 +369,7 @@ export interface OrderDetailsParams {
365
369
  updateDriverPosition?: any;
366
370
  driverUpdateLocation?: any;
367
371
  setDriverUpdateLocation?: any;
372
+ handleClickLogisticOrder?: (status: number, orderId: number) => void;
368
373
  orderTitle?: any
369
374
  }
370
375
  export interface ProductItemAccordionParams {
@@ -79,7 +79,7 @@ export const BusinessBasicInformation = (
79
79
  onPress={() => auth
80
80
  ? navigation.navigate('AddressList', { isGoBack: true, isFromProductsList: true })
81
81
  : navigation.navigate('AddressForm', { address: orderState.options?.address })}
82
- style={{marginTop: !auth ? 36 : top > 0 ? 0 : 20}}
82
+ style={{marginTop: (!auth || props.isFranchiseApp) ? 36 : top > 0 ? 0 : 20}}
83
83
  activeOpacity={0.8}
84
84
  >
85
85
  <OIcon src={theme.images.general.pin} width={16} color={theme.colors.textSecondary} />
@@ -28,6 +28,7 @@ import { ProductForm } from '../ProductForm'
28
28
  // import { UpsellingProducts } from '../UpsellingProducts'
29
29
  import { useSafeAreaInsets } from 'react-native-safe-area-context';
30
30
  import { _setStoreData } from '../../providers/StoreUtil';
31
+ import NavBar from '../NavBar';
31
32
 
32
33
  const PIXELS_TO_SCROLL = 1000
33
34
 
@@ -180,15 +181,14 @@ const BusinessProductsListingUI = (props: BusinessProductsListingParams) => {
180
181
  scrollEventThrottle={16}
181
182
  >
182
183
  <WrapHeader>
183
- {!auth &&
184
+ {(!auth || props.isFranchiseApp) && !loading &&
184
185
  <TopHeader style={{top: top}}>
185
- <OButton
186
- imgLeftSrc={theme.images.general.arrow_left}
187
- imgRightSrc={null}
188
- style={styles.btnBackArrow}
189
- onClick={() => navigation?.canGoBack() && navigation.goBack()}
190
- imgLeftStyle={{ tintColor: theme.colors.white }}
191
- />
186
+ <NavBar
187
+ style={{ paddingBottom: 0, marginLeft: 20, backgroundColor: 'transparent' }}
188
+ btnStyle={{ backgroundColor: 'transparent' }}
189
+ leftImageStyle={{ tintColor: theme.colors.white }}
190
+ onActionLeft={() => navigation?.canGoBack() && navigation.goBack()}
191
+ />
192
192
  </TopHeader>
193
193
  }
194
194
  <BusinessBasicInformation
@@ -197,6 +197,7 @@ const BusinessProductsListingUI = (props: BusinessProductsListingParams) => {
197
197
  openBusinessInformation={openBusinessInformation}
198
198
  header={header}
199
199
  logo={logo}
200
+ isFranchiseApp={props.isFranchiseApp}
200
201
  />
201
202
  </WrapHeader>
202
203
  <View style={{ height: 8, backgroundColor: theme.colors.backgroundGray100 }} />