ordering-ui-react-native 0.18.39 → 0.18.40

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ordering-ui-react-native",
3
- "version": "0.18.39",
3
+ "version": "0.18.40",
4
4
  "description": "Reusable components made in react native",
5
5
  "main": "src/index.tsx",
6
6
  "author": "ordering.inc",
@@ -453,7 +453,7 @@ export const DriverMap = (props: GoogleMapsParams) => {
453
453
  {order?.delivery_datetime_utc
454
454
  ? parseDate(order?.delivery_datetime_utc)
455
455
  : parseDate(order?.delivery_datetime, { utc: false })}
456
- {` - ${order?.paymethod?.name}`}
456
+ {` - ${t(order?.paymethod?.name?.replace(/\s+/g, '_')?.toUpperCase(), order?.paymethod?.name)}`}
457
457
  </OText>
458
458
  <OText weight="bold">
459
459
  {t('INVOICE_ORDER_NO', 'Order No.')} {order?.id}
@@ -1,5 +1,5 @@
1
1
  import React, { useState, useEffect } from 'react';
2
- import { StyleSheet, View, TouchableOpacity, Linking, Pressable } from 'react-native';
2
+ import { StyleSheet, View, TouchableOpacity, Linking, Pressable, Image } from 'react-native';
3
3
  import FastImage from 'react-native-fast-image'
4
4
  import { useUtils, useOrder, useLanguage } from 'ordering-components/native';
5
5
  import { useTheme } from 'styled-components/native';
@@ -45,6 +45,7 @@ export const BusinessBasicInformation = (
45
45
  const [openBusinessReviews, setOpenBusinessReviews] = useState(false);
46
46
  const [businessInformationObtained, setBusinessInformationObtained] = useState(false)
47
47
  const [businessReviewsObtained, setBusinessReviewsObtainedbtained] = useState(false)
48
+ const [imageRealSize, setImageRealSize] = useState({ width: 16, height: 9, loading: true })
48
49
  const isChewLayout = theme?.header?.components?.layout?.type?.toLowerCase() === 'chew'
49
50
  const hideLogo = theme?.business_view?.components?.header?.components?.business?.components?.logo?.hidden
50
51
  const hideDeliveryFee = theme?.business_view?.components?.header?.components?.business?.components?.fee?.hidden
@@ -61,7 +62,7 @@ export const BusinessBasicInformation = (
61
62
  height: 150,
62
63
  },
63
64
  headerStyle: {
64
- height: isChewLayout ? 170 : 260,
65
+ aspectRatio: imageRealSize?.width / imageRealSize?.height
65
66
  },
66
67
  logoStyle: {
67
68
  width: 72,
@@ -195,6 +196,20 @@ export const BusinessBasicInformation = (
195
196
  }
196
197
  }, [businessState?.business])
197
198
 
199
+ useEffect(() => {
200
+ const bannerImage = header || businessState?.business?.header
201
+ if (!bannerImage) {
202
+ setImageRealSize({ width: 16, height: 9, loading: false })
203
+ return
204
+ }
205
+ Image.getSize(bannerImage, (width: number, height: number) => {
206
+ setImageRealSize({ width: width, height: height, loading: false });
207
+ }, (error: any) => {
208
+ setImageRealSize({ ...imageRealSize, loading: false });
209
+ console.log(error);
210
+ });
211
+ }, [header, businessState?.business?.header])
212
+
198
213
  const SocialIcons = () => {
199
214
  return (
200
215
  <>
@@ -283,7 +298,7 @@ export const BusinessBasicInformation = (
283
298
  ? styles.businesInfoheaderStyle
284
299
  : { ...styles.headerStyle, backgroundColor: theme.colors.backgroundGray }
285
300
  }
286
- {...(!loading && {
301
+ {...(!loading && !imageRealSize?.loading && {
287
302
  source: (header || businessState?.business?.header || typeof theme?.images?.dummies?.businessHeader === 'string') ? {
288
303
  uri: optimizeImage(businessState?.business?.header, 'h_250,c_limit') || header || theme?.images?.dummies?.businessHeader
289
304
  } : theme?.images?.dummies?.businessHeader
@@ -8,9 +8,6 @@ export const BusinessContainer = styled.View`
8
8
  export const BusinessHeader = styled.ImageBackground`
9
9
  width: 100%;
10
10
  position: relative;
11
- max-height: 258px;
12
- height: 258px;
13
- resize-mode: cover;
14
11
  `;
15
12
  export const BusinessLogo = styled.View`
16
13
  position: absolute;
@@ -95,6 +95,7 @@ export const BusinessListingSearchUI = (props: BusinessSearchParams) => {
95
95
  },
96
96
  searchInput: {
97
97
  fontSize: 12,
98
+ height: 44
98
99
  },
99
100
  productsContainer: {
100
101
  marginTop: 20
@@ -249,7 +250,7 @@ export const BusinessListingSearchUI = (props: BusinessSearchParams) => {
249
250
  display: 'flex',
250
251
  flexDirection: 'row',
251
252
  alignItems: 'center',
252
- paddingHorizontal: isChewLayout ? 20 : 40,
253
+ paddingHorizontal: hideBrowse && !isChewLayout ? 40 : 20,
253
254
  }}>
254
255
  {hideBrowse && !isChewLayout && (
255
256
  <OButton
@@ -275,6 +276,7 @@ export const BusinessListingSearchUI = (props: BusinessSearchParams) => {
275
276
  />
276
277
  )}
277
278
  <HeaderTitle ph={20} text={t('SEARCH', 'Search')} />
279
+ <AntDesignIcon name='filter' size={18} style={{ marginLeft: 'auto', marginTop: 55, paddingHorizontal: 20 }} onPress={() => handleOpenfilters()} />
278
280
  </View>
279
281
  <BContainer
280
282
  style={{ paddingHorizontal: isChewLayout ? 20 : 40 }}
@@ -287,7 +289,6 @@ export const BusinessListingSearchUI = (props: BusinessSearchParams) => {
287
289
  placeholder={t('SEARCH_BUSINESSES', 'Search Businesses')}
288
290
  onSearch={(val: string) => handleChangeTermValue(val)}
289
291
  value={termValue}
290
- iconCustomRight={<AntDesignIcon name='filter' size={16} style={{ bottom: 2 }} onPress={() => handleOpenfilters()} />}
291
292
  />
292
293
  </SearchWrapper>
293
294
  <OText size={12} lineHeight={20} color={theme.colors.textThird} mLeft={5}>
@@ -13,7 +13,7 @@ const UpsellingRedirectUI = (props: any) => {
13
13
  if (!upsellingProducts.loading) {
14
14
  if (upsellingProducts?.products?.length) {
15
15
  onRedirect &&
16
- onRedirect('UpsellingPage', props)
16
+ onRedirect('UpsellingPage', {...props, products: upsellingProducts?.products })
17
17
  } else {
18
18
  handleUpsellingPage && handleUpsellingPage()
19
19
  }
@@ -139,6 +139,7 @@ const BusinessProductsListingUI = (props: BusinessProductsListingParams) => {
139
139
  const [searchBarHeight, setSearchBarHeight] = useState(60)
140
140
  const [keyboardHeight, setKeyboardHeight] = useState(0);
141
141
  const [viewedCategory, setViewedCategory] = useState<any>(null)
142
+ const [showTitle, setShowTitle] = useState(false)
142
143
 
143
144
  const isCheckoutMultiBusinessEnabled: Boolean = configs?.checkout_multi_business_enabled?.value === '1'
144
145
  const isQuickAddProduct = configs?.add_product_with_one_click?.value === '1'
@@ -244,6 +245,8 @@ const BusinessProductsListingUI = (props: BusinessProductsListingParams) => {
244
245
 
245
246
  const handlePageScroll = useCallback(({ nativeEvent }: any) => {
246
247
  const scrollOffset = nativeEvent.contentOffset.y
248
+ setShowTitle(scrollOffset > 30)
249
+
247
250
  if (businessState?.business?.lazy_load_products_recommended) {
248
251
  const height = nativeEvent.contentSize.height
249
252
  const hasMore = !(categoryState.pagination.totalPages === categoryState.pagination.currentPage)
@@ -398,6 +401,17 @@ const BusinessProductsListingUI = (props: BusinessProductsListingParams) => {
398
401
  />
399
402
  </TopActions>
400
403
  )}
404
+ {showTitle && (
405
+ <OText
406
+ size={16}
407
+ style={{ flex: 1, textAlign: 'center' }}
408
+ weight={Platform.OS === 'ios' ? '600' : 'bold'}
409
+ numberOfLines={2}
410
+ ellipsizeMode='tail'
411
+ >
412
+ {business?.name}
413
+ </OText>
414
+ )}
401
415
  {!errorQuantityProducts && (
402
416
  <View style={{ ...styles.headerItem }}>
403
417
  <TouchableOpacity
@@ -1,8 +1,8 @@
1
1
  import React, { useState } from 'react';
2
2
  import { View } from 'react-native';
3
- import { useLanguage, useConfig } from 'ordering-components/native';
3
+ import { useLanguage, useConfig, useUtils } from 'ordering-components/native';
4
4
  import { useTheme } from 'styled-components/native';
5
- import { CCContainer, CCNotCarts, CCList, CheckoutAction } from './styles';
5
+ import { CCContainer, CCNotCarts, CCList, CheckoutAction, ChCartsTotal } from './styles';
6
6
 
7
7
  import { Cart } from '../Cart';
8
8
  import { OButton, OText } from '../shared';
@@ -19,12 +19,18 @@ export const CartContent = (props: any) => {
19
19
  const theme = useTheme();
20
20
  const [, t] = useLanguage()
21
21
  const [{ configs }] = useConfig()
22
+ const [{ parsePrice }] = useUtils();
22
23
  const [isCartsLoading, setIsCartsLoading] = useState(false)
23
24
 
24
25
  const isChewLayout = theme?.header?.components?.layout?.type === 'chew'
25
26
  const isMultiCheckout = configs?.checkout_multi_business_enabled?.value === '1'
26
27
  const cartsAvailable: any = Object.values(carts)?.filter((cart: any) => cart?.valid && cart?.status !== 2)
27
28
 
29
+ const totalCartsPrice = cartsAvailable?.length && cartsAvailable.reduce((total: any, cart: any) => { return total + cart?.total }, 0)
30
+ const totalCartsFee = cartsAvailable?.length && cartsAvailable
31
+ ?.filter((cart: any) => cart?.status !== 1 && cart?.valid && cart?.products?.length)
32
+ ?.reduce((total: any, cart: any) => { return total + (cart?.delivery_price_with_discount) }, 0)
33
+
28
34
  const handleCheckoutRedirect = () => {
29
35
  if (cartsAvailable.length === 1) {
30
36
  onNavigationRedirect('CheckoutNavigator', {
@@ -80,6 +86,9 @@ export const CartContent = (props: any) => {
80
86
  isMultiCheckout={isMultiCheckout}
81
87
  hideUpselling
82
88
  businessConfigs={cart?.business?.configs}
89
+ hideCouponInput={configs?.multi_business_checkout_coupon_input_style?.value === 'group'}
90
+ hideDeliveryFee={configs?.multi_business_checkout_show_combined_delivery_fee?.value === '1'}
91
+ hideDriverTip={configs?.multi_business_checkout_show_combined_driver_tip?.value === '1'}
83
92
  />
84
93
  <View style={{ height: 8, backgroundColor: theme.colors.backgroundGray100, marginHorizontal: -40, marginTop: 20 }} />
85
94
  </>
@@ -87,18 +96,51 @@ export const CartContent = (props: any) => {
87
96
  </CCList>
88
97
  ))}
89
98
  {isMultiCheckout && (
90
- <CheckoutAction style={{ marginTop: 0 }}>
91
- <OButton
92
- text={t('CHECKOUT', 'Checkout')}
93
- bgColor={!cartsAvailable.length ? theme.colors.secundary : theme.colors.primary}
94
- isDisabled={!cartsAvailable.length}
95
- borderColor={theme.colors.primary}
96
- imgRightSrc={null}
97
- textStyle={{ color: 'white', textAlign: 'center', flex: 1 }}
98
- onClick={() => handleCheckoutRedirect()}
99
- style={{ width: '100%', flexDirection: 'row', justifyContent: 'center', borderRadius: 7.6, shadowOpacity: 0 }}
100
- />
101
- </CheckoutAction>
99
+ <>
100
+ {!!cartsAvailable.length && (
101
+ <ChCartsTotal>
102
+ {!!totalCartsFee && configs?.multi_business_checkout_show_combined_delivery_fee?.value === '1' && (
103
+ <View style={{ flexDirection: 'row', justifyContent: 'space-between' }}>
104
+ <OText size={14} lineHeight={24} color={theme.colors.textNormal} weight={'400'}>
105
+ {t('TOTAL_DELIVERY_FEE', 'Total delivery fee')}
106
+ </OText>
107
+ <OText size={14} lineHeight={24} color={theme.colors.textNormal} weight={'400'}>
108
+ {parsePrice(totalCartsFee)}
109
+ </OText>
110
+ </View>
111
+ )}
112
+ {cartsAvailable.reduce((sum: any, cart: any) => sum + cart?.driver_tip, 0) > 0 &&
113
+ configs?.multi_business_checkout_show_combined_driver_tip?.value === '1' && (
114
+ <View style={{ flexDirection: 'row', justifyContent: 'space-between' }}>
115
+ <OText size={14} lineHeight={24} color={theme.colors.textNormal} weight={'400'}>
116
+ {t('DRIVER_TIP', 'Driver tip')}
117
+ </OText>
118
+ <OText size={14} lineHeight={24} color={theme.colors.textNormal} weight={'400'}>
119
+ {parsePrice(cartsAvailable.reduce((sum: any, cart: any) => sum + cart?.driver_tip, 0))}
120
+ </OText>
121
+ </View>
122
+ )}
123
+ <View style={{ flexDirection: 'row', justifyContent: 'space-between' }}>
124
+ <OText size={16} lineHeight={24} color={theme.colors.textNormal} weight={'500'}>
125
+ {t('TOTAL_FOR_ALL_CARTS', 'Total for all Carts')}
126
+ </OText>
127
+ <OText size={16} lineHeight={24} color={theme.colors.textNormal} weight={'500'}>{parsePrice(totalCartsPrice)}</OText>
128
+ </View>
129
+ </ChCartsTotal>
130
+ )}
131
+ <CheckoutAction style={{ marginTop: 0 }}>
132
+ <OButton
133
+ text={t('CHECKOUT', 'Checkout')}
134
+ bgColor={!cartsAvailable.length ? theme.colors.secundary : theme.colors.primary}
135
+ isDisabled={!cartsAvailable.length}
136
+ borderColor={theme.colors.primary}
137
+ imgRightSrc={null}
138
+ textStyle={{ color: 'white', textAlign: 'center', flex: 1 }}
139
+ onClick={() => handleCheckoutRedirect()}
140
+ style={{ width: '100%', flexDirection: 'row', justifyContent: 'center', borderRadius: 7.6, shadowOpacity: 0 }}
141
+ />
142
+ </CheckoutAction>
143
+ </>
102
144
  )}
103
145
  </>
104
146
  )}
@@ -23,3 +23,7 @@ export const CheckoutAction = styled.View`
23
23
  margin-top: 10px;
24
24
  margin-bottom: 10px;
25
25
  `
26
+
27
+ export const ChCartsTotal = styled.View`
28
+ margin-bottom: 16px;
29
+ `
@@ -115,11 +115,12 @@ const MultiCheckoutUI = (props: any) => {
115
115
  }
116
116
  }
117
117
 
118
- const loyaltyRewardValue = creditPointPlanOnBusiness?.accumulation_rate
119
- ? Math.round(
120
- openCarts.reduce((sum: any, cart: any) => sum + cart?.subtotal + getIncludedTaxes(cart), 0) /
121
- creditPointPlanOnBusiness?.accumulation_rate
122
- ) : 0
118
+ const subtotalAmount = openCarts.reduce((sum: any, cart: any) => sum + (cart?.subtotal + getIncludedTaxes(cart)), 0) *
119
+ creditPointPlanOnBusiness?.accumulation_rate
120
+
121
+ const loyaltyRewardValue = (creditPointPlanOnBusiness?.accumulation_rate
122
+ ? (Math.trunc(subtotalAmount * 100) / 100).toFixed(configs.format_number_decimal_length?.value ?? 2)
123
+ : 0)
123
124
 
124
125
  const handleMomentClick = () => {
125
126
  if (isPreOrder) {
@@ -75,7 +75,7 @@ const OrderSummaryUI = (props: any) => {
75
75
 
76
76
  const getIncludedTaxes = () => {
77
77
  if (cart?.taxes === null || !cart?.taxes) {
78
- return cart.business.tax_type === 1 ? cart?.tax : 0
78
+ return cart?.business?.tax_type === 1 ? cart?.tax : 0
79
79
  } else {
80
80
  return cart?.taxes.reduce((taxIncluded: number, tax: any) => {
81
81
  return taxIncluded + (tax.type === 1 ? tax.summary?.tax : 0)
@@ -83,7 +83,9 @@ const OrderSummaryUI = (props: any) => {
83
83
  }
84
84
  }
85
85
 
86
- const loyaltyRewardValue = Math.round((cart?.subtotal + getIncludedTaxes()) / loyaltyRewardRate)
86
+ const loyaltyRewardValue = ((
87
+ Math.trunc(((cart?.subtotal + getIncludedTaxes()) * loyaltyRewardRate) * 100) / 100
88
+ ).toFixed(configs.format_number_decimal_length?.value ?? 2), 10)
87
89
 
88
90
  const handleDeleteClick = (product: any) => {
89
91
  removeProduct(product, cart)
@@ -205,6 +205,7 @@ export const ProductOptionsUI = (props: any) => {
205
205
  const [isScrollAvailable, setIsScrollAvailable] = useState(null)
206
206
  const [editionsLayoutY, setEditionsLayoutY] = useState(null)
207
207
  const [viewedProduct, setViewedProduct] = useState<any>(null)
208
+ const [showTitle, setShowTitle] = useState(false)
208
209
 
209
210
  const guestCheckoutEnabled = configs?.guest_checkout_enabled?.value === '1'
210
211
  const orderTypeEnabled = !orderTypeList[orderState?.options?.type - 1] || configs?.allowed_order_types_guest_checkout?.value?.includes(orderTypeList[orderState?.options?.type - 1])
@@ -362,7 +363,7 @@ export const ProductOptionsUI = (props: any) => {
362
363
  );
363
364
 
364
365
  const handleScroll = ({ nativeEvent: { contentOffset, layoutMeasurement } }: any) => {
365
-
366
+ setShowTitle(contentOffset.y > 30)
366
367
  const _topOption = Object.keys(optionLayout).find(((option: any) => Math.abs(contentOffset?.y - layoutMeasurement?.height - optionLayout[option]?.y) < 20))
367
368
  if (_topOption) {
368
369
  const _topOptionId = Number(_topOption.replace('id:', ''))
@@ -526,12 +527,24 @@ export const ProductOptionsUI = (props: any) => {
526
527
  return (
527
528
  <SafeAreaView style={{ flex: 1 }}>
528
529
  <View style={styles.wrapperNavbar}>
529
- <NavBar
530
- onActionLeft={() => handleGoBack()}
531
- showCall={false}
532
- btnStyle={{ paddingLeft: 0 }}
533
- paddingTop={4}
534
- />
530
+ <TopHeader>
531
+ <>
532
+ <TopActions onPress={() => handleGoBack()}>
533
+ <OIcon src={theme.images.general.arrow_left} color={theme.colors.textNormal} />
534
+ </TopActions>
535
+ {showTitle && (
536
+ <OText
537
+ size={16}
538
+ style={{ flex: 1, textAlign: 'center' }}
539
+ weight={Platform.OS === 'ios' ? '600' : 'bold'}
540
+ numberOfLines={2}
541
+ ellipsizeMode='tail'
542
+ >
543
+ {product?.name}
544
+ </OText>
545
+ )}
546
+ </>
547
+ </TopHeader>
535
548
  </View>
536
549
  {!error && (
537
550
  <ScrollView
@@ -1,4 +1,4 @@
1
- import React, { useState } from 'react';
1
+ import React, { useState, useEffect } from 'react';
2
2
  import {
3
3
  SingleOrderCard as SingleOrderCardController,
4
4
  useUtils,
@@ -11,6 +11,7 @@ import { OIcon, OText, OButton } from '../shared';
11
11
  import { SingleOrderCardParams } from '../../types';
12
12
  import { OAlert } from '../../../../../src/components/shared'
13
13
  import { OrderEta } from '../OrderDetails/OrderEta'
14
+ import { useIsFocused } from '@react-navigation/native';
14
15
  import {
15
16
  InnerContainer,
16
17
  Logo,
@@ -44,6 +45,7 @@ const SingleOrderCardUI = (props: SingleOrderCardParams) => {
44
45
  const [, t] = useLanguage();
45
46
  const [{ carts }] = useOrder()
46
47
  const theme = useTheme();
48
+ const isFocused = useIsFocused();
47
49
 
48
50
  const [reorderSelected, setReorderSelected] = useState<number | null>(null);
49
51
  const [confirm, setConfirm] = useState<any>({ open: false, content: null, handleOnAccept: null, id: null, title: null })
@@ -198,6 +200,10 @@ const SingleOrderCardUI = (props: SingleOrderCardParams) => {
198
200
  const hideFavorite = theme?.orders?.components?.favorite?.hidden
199
201
  const hideOrderStatus = theme?.orders?.components?.order_status?.hidden
200
202
 
203
+ useEffect(() => {
204
+ if (isFocused) setReorderSelected(null)
205
+ }, [isFocused])
206
+
201
207
  return (
202
208
  <>
203
209
  <CardAnimation
@@ -288,7 +288,11 @@ const ProfileUI = (props: ProfileParams) => {
288
288
  showCall={false}
289
289
  btnStyle={{ paddingLeft: 0 }}
290
290
  />
291
- <KeyboardAvoidingView behavior={Platform.OS == 'ios' ? 'padding' : 'height'} enabled style={{ flex: 1, flexDirection: 'column', justifyContent: 'center' }}>
291
+ <KeyboardAvoidingView
292
+ behavior={Platform.OS == 'ios' ? 'padding' : 'height'}
293
+ enabled={Platform.OS === 'ios' ? true : false}
294
+ style={{ flex: 1, flexDirection: 'column', justifyContent: 'center' }}
295
+ >
292
296
  <CenterView>
293
297
  <View style={styles.photo}>
294
298
  {user?.photo ? (
@@ -63,12 +63,12 @@ export const WalletTransactions = (props: any) => {
63
63
  (transactionsList?.error ||
64
64
  !transactionsList.list?.[`wallet:${currentWalletSelected?.id}`]?.length) &&
65
65
  (
66
- <NotFoundSource
67
- content={transactionsList?.error
66
+ <OText color={theme.colors.disabled} size={16} style={{ textAlign: 'center' }}>
67
+ {transactionsList?.error
68
68
  ? t('ERROR_NOT_FOUND_TRANSACTIONS', 'Sorry, an error has occurred')
69
69
  : t('NOT_FOUND_TRANSACTIONS', 'No transactions to show at this time.')
70
70
  }
71
- />
71
+ </OText>
72
72
  )}
73
73
  </View>
74
74
  </Container>
@@ -213,9 +213,9 @@ const WalletsUI = (props: any) => {
213
213
  <LoyaltyContent>
214
214
  <LoyaltyWrapp>
215
215
  <OText size={20}>
216
- {`${t('LOYALTY_LEVEL_TITLE', 'Your level is')}:`}
216
+ {`${t('LOYALTY_LEVEL_TITLE', 'Your level is')}`}
217
217
  </OText>
218
- {/* {loyaltyLevel.image ? (
218
+ {loyaltyLevel.image ? (
219
219
  <FastImage
220
220
  style={styles.logoStyle}
221
221
  source={{
@@ -230,7 +230,7 @@ const WalletsUI = (props: any) => {
230
230
  source={theme.images.dummies.loyaltyLevel}
231
231
  resizeMode='contain'
232
232
  />
233
- )} */}
233
+ )}
234
234
  <OText
235
235
  size={22}
236
236
  weight='bold'