ordering-ui-react-native 0.15.91 → 0.15.94

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 (28) hide show
  1. package/package.json +1 -1
  2. package/src/components/Checkout/index.tsx +23 -2
  3. package/src/components/SingleProductCard/index.tsx +16 -4
  4. package/themes/business/src/components/LoginForm/index.tsx +6 -4
  5. package/themes/business/src/components/NewOrderNotification/index.tsx +24 -13
  6. package/themes/business/src/components/OrderDetails/OrderContentComponent.tsx +1 -0
  7. package/themes/business/src/components/OrdersOption/index.tsx +5 -2
  8. package/themes/kiosk/src/components/BusinessMenu/index.tsx +23 -25
  9. package/themes/kiosk/src/components/BusinessesListing/index.tsx +2 -3
  10. package/themes/kiosk/src/components/Cart/index.tsx +10 -11
  11. package/themes/kiosk/src/components/CategoriesMenu/index.tsx +36 -30
  12. package/themes/kiosk/src/components/Checkout/index.tsx +22 -19
  13. package/themes/kiosk/src/components/OrderTypeCardSelector/index.tsx +1 -1
  14. package/themes/kiosk/src/components/PaymentOptions/index.tsx +54 -52
  15. package/themes/kiosk/src/components/ProductOptionSubOption/index.tsx +3 -1
  16. package/themes/original/src/components/BusinessListingSearch/index.tsx +54 -2
  17. package/themes/original/src/components/BusinessListingSearch/styles.tsx +4 -0
  18. package/themes/original/src/components/BusinessesListing/index.tsx +3 -1
  19. package/themes/original/src/components/Checkout/index.tsx +36 -28
  20. package/themes/original/src/components/DriverTips/index.tsx +6 -6
  21. package/themes/original/src/components/Help/index.tsx +21 -4
  22. package/themes/original/src/components/LastOrders/index.tsx +12 -1
  23. package/themes/original/src/components/LoginForm/index.tsx +40 -7
  24. package/themes/original/src/components/OrderDetails/index.tsx +18 -21
  25. package/themes/original/src/components/PaymentOptionWallet/index.tsx +1 -0
  26. package/themes/original/src/components/Promotions/index.tsx +22 -6
  27. package/themes/original/src/components/Wallets/index.tsx +1 -1
  28. package/themes/original/src/types/index.tsx +2 -0
@@ -24,7 +24,8 @@ import {
24
24
  TagsContainer,
25
25
  SortContainer,
26
26
  BrandContainer,
27
- BrandItem
27
+ BrandItem,
28
+ PriceFilterWrapper
28
29
  } from './styles'
29
30
  import FastImage from 'react-native-fast-image'
30
31
  import { convertHoursToMinutes } from '../../utils'
@@ -67,6 +68,14 @@ export const BusinessListingSearchUI = (props : BusinessSearchParams) => {
67
68
  { text: t('PICKUP_TIME', 'Pickup time'), value: 'pickup_time' }
68
69
  ]
69
70
 
71
+ const priceList = [
72
+ { level: '1', content: '$' },
73
+ { level: '2', content: '$$' },
74
+ { level: '3', content: '$$$' },
75
+ { level: '4', content: '$$$$' },
76
+ { level: '5', content: '$$$$$' }
77
+ ]
78
+
70
79
  const styles = StyleSheet.create({
71
80
  container: {
72
81
  paddingHorizontal: 40,
@@ -93,6 +102,12 @@ export const BusinessListingSearchUI = (props : BusinessSearchParams) => {
93
102
  flexWrap: 'wrap',
94
103
  justifyContent: 'center'
95
104
  },
105
+ priceContainer: {
106
+ width: '100%',
107
+ flexDirection: 'row',
108
+ flexWrap: 'wrap',
109
+ justifyContent: 'space-between'
110
+ },
96
111
  categoryStyle: {
97
112
  marginRight: 10,
98
113
  marginTop: 10,
@@ -104,6 +119,16 @@ export const BusinessListingSearchUI = (props : BusinessSearchParams) => {
104
119
  height: 28,
105
120
  borderWidth: 0
106
121
  },
122
+ priceItem: {
123
+ marginRight: 10,
124
+ marginTop: 10,
125
+ borderRadius: 50,
126
+ paddingVertical: 4,
127
+ paddingLeft: 5,
128
+ paddingRight: 5,
129
+ height: 27,
130
+ borderWidth: 0
131
+ },
107
132
  applyButton: {
108
133
  paddingHorizontal: 40,
109
134
  width: '100%',
@@ -116,7 +141,7 @@ export const BusinessListingSearchUI = (props : BusinessSearchParams) => {
116
141
  }
117
142
 
118
143
  const handleCloseFilters = () => {
119
- setFilters({ business_types: [], orderBy: 'default', franchise_ids: [] })
144
+ setFilters({ business_types: [], orderBy: 'default', franchise_ids: [], price_level: null })
120
145
  setOpenFilters(false)
121
146
  }
122
147
 
@@ -142,6 +167,11 @@ export const BusinessListingSearchUI = (props : BusinessSearchParams) => {
142
167
  handleChangeFilters && handleChangeFilters('franchise_ids', franchiseIds)
143
168
  }
144
169
 
170
+ const handleChangePriceRange = (value: string) => {
171
+ if (value === filters?.price_level) handleChangeFilters('price_level', null)
172
+ else handleChangeFilters('price_level', value)
173
+ }
174
+
145
175
  const handleApplyFilters = () => {
146
176
  handleSearchbusinessAndProducts(true)
147
177
  setOpenFilters(false)
@@ -473,6 +503,28 @@ export const BusinessListingSearchUI = (props : BusinessSearchParams) => {
473
503
  <OText size={14} weight='400'>{t('NO_RESULTS_FOUND', 'Sorry, no results found')}</OText>
474
504
  )}
475
505
  </BrandContainer>
506
+ <PriceFilterWrapper>
507
+ <OText
508
+ size={16}
509
+ weight='bold'
510
+ lineHeight={24}
511
+ style={{ marginBottom: 5 }}
512
+ >
513
+ {t('PRICE_RANGE', 'Price range')}
514
+ </OText>
515
+ <View style={styles.priceContainer}>
516
+ {priceList.map((price: any, i: number) => (
517
+ <OButton
518
+ key={i}
519
+ bgColor={(filters?.price_level === price?.level) ? theme.colors.primary : theme.colors.backgroundGray200}
520
+ onClick={() => handleChangePriceRange(price?.level)}
521
+ text={`${price.content} ${(filters?.price_level === price?.level) ? ' X' : ''}`}
522
+ style={styles.priceItem}
523
+ textStyle={{ fontSize: 10, color: (filters?.price_level === price?.level) ? theme.colors.backgroundLight : theme.colors.textNormal }}
524
+ />
525
+ ))}
526
+ </View>
527
+ </PriceFilterWrapper>
476
528
  {orderState?.options?.type === 1 && (
477
529
  <MaxSectionItem
478
530
  title={t('MAX_DELIVERY_FEE', 'Max delivery fee')}
@@ -83,3 +83,7 @@ export const BrandItem = styled.TouchableOpacity`
83
83
  margin-bottom: 4px;
84
84
  align-items: center;
85
85
  `
86
+
87
+ export const PriceFilterWrapper = styled.View`
88
+ margin-bottom: 20px;
89
+ `
@@ -59,7 +59,8 @@ const BusinessesListingUI = (props: BusinessesListingParams) => {
59
59
  handleBusinessClick,
60
60
  paginationProps,
61
61
  handleChangeSearch,
62
- businessId
62
+ businessId,
63
+ isGuestUser
63
64
  } = props;
64
65
  const theme = useTheme();
65
66
  const isFocused = useIsFocused();
@@ -242,6 +243,7 @@ const BusinessesListingUI = (props: BusinessesListingParams) => {
242
243
  : navigation.navigate('AddressForm', {
243
244
  address: orderState.options?.address,
244
245
  isFromBusinesses: true,
246
+ isGuestUser: isGuestUser
245
247
  })
246
248
  }>
247
249
  <OIcon
@@ -113,7 +113,10 @@ const CheckoutUI = (props: any) => {
113
113
  right: Platform.OS === 'ios' ? 5 : (I18nManager.isRTL ? 30 : 0),
114
114
  position: 'absolute',
115
115
  fontSize: 20
116
- }
116
+ },
117
+ wrapperNavbar: Platform.OS === 'ios'
118
+ ? { paddingVertical: 0, paddingHorizontal: 40 }
119
+ : { paddingVertical: 20, paddingHorizontal: 40 }
117
120
  })
118
121
 
119
122
  const [, { showToast }] = useToast();
@@ -133,20 +136,20 @@ const CheckoutUI = (props: any) => {
133
136
  const [isDeliveryOptionModalVisible, setIsDeliveryOptionModalVisible] = useState(false)
134
137
  const [showGateway, setShowGateway] = useState<any>({ closedByUsed: false, open: false });
135
138
  const [webviewPaymethod, setWebviewPaymethod] = useState<any>(null)
136
-
139
+
137
140
  const placeSpotTypes = [3, 4]
138
- const businessConfigs = businessDetails?.business?.configs ?? []
139
- const isWalletCashEnabled = businessConfigs.find((config: any) => config.key === 'wallet_cash_enabled')?.value === '1'
140
- const isWalletCreditPointsEnabled = businessConfigs.find((config: any) => config.key === 'wallet_credit_point_enabled')?.value === '1'
141
- const isWalletEnabled = configs?.cash_wallet?.value && configs?.wallet_enabled?.value === '1' && (isWalletCashEnabled || isWalletCreditPointsEnabled)
141
+ const businessConfigs = businessDetails?.business?.configs ?? []
142
+ const isWalletCashEnabled = businessConfigs.find((config: any) => config.key === 'wallet_cash_enabled')?.value === '1'
143
+ const isWalletCreditPointsEnabled = businessConfigs.find((config: any) => config.key === 'wallet_credit_point_enabled')?.value === '1'
144
+ const isWalletEnabled = configs?.cash_wallet?.value && configs?.wallet_enabled?.value === '1' && (isWalletCashEnabled || isWalletCreditPointsEnabled)
142
145
 
143
146
  const isPreOrder = configs?.preorder_status_enabled?.value === '1'
144
147
  const isDisabledButtonPlace = loading || !cart?.valid || (!paymethodSelected && cart?.balance > 0) || placing || errorCash ||
145
- cart?.subtotal < cart?.minimum || (placeSpotTypes.includes(options?.type) && !cart?.place) ||
146
- (options.type === 1 &&
147
- validationFields?.fields?.checkout?.driver_tip?.enabled &&
148
- validationFields?.fields?.checkout?.driver_tip?.required &&
149
- (Number(cart?.driver_tip) <= 0))
148
+ cart?.subtotal < cart?.minimum || (placeSpotTypes.includes(options?.type) && !cart?.place) ||
149
+ (options.type === 1 &&
150
+ validationFields?.fields?.checkout?.driver_tip?.enabled &&
151
+ validationFields?.fields?.checkout?.driver_tip?.required &&
152
+ (Number(cart?.driver_tip) <= 0))
150
153
 
151
154
  const driverTipsOptions = typeof configs?.driver_tip_options?.value === 'string'
152
155
  ? JSON.parse(configs?.driver_tip_options?.value) || []
@@ -259,13 +262,18 @@ const CheckoutUI = (props: any) => {
259
262
  return (
260
263
  <>
261
264
  <Container noPadding>
262
- <NavBar
263
- isVertical
264
- onActionLeft={() => navigation?.canGoBack() && navigation.goBack()}
265
- title={t('CHECKOUT', 'Checkout')}
266
- titleStyle={{ marginLeft: 0, marginRight: 0, paddingLeft: 40 }}
267
- btnStyle={{ marginLeft: 40, padding: 40 }}
268
- />
265
+ <View style={styles.wrapperNavbar}>
266
+ <NavBar
267
+ title={t('CHECKOUT', 'Checkout')}
268
+ titleAlign={'center'}
269
+ onActionLeft={() => navigation?.canGoBack() && navigation.goBack()}
270
+ showCall={false}
271
+ btnStyle={{ paddingLeft: 0 }}
272
+ style={{ flexDirection: 'column', alignItems: 'flex-start', marginTop: Platform.OS === 'ios' ? 0 : 20 }}
273
+ titleWrapStyle={{ paddingHorizontal: 0 }}
274
+ titleStyle={{ marginRight: 0, marginLeft: 0 }}
275
+ />
276
+ </View>
269
277
  <ChContainer style={styles.pagePadding}>
270
278
  <ChSection style={{ paddingTop: 0 }}>
271
279
  <ChHeader>
@@ -668,16 +676,16 @@ const CheckoutUI = (props: any) => {
668
676
  </OText>
669
677
  )}
670
678
  {options.type === 1 &&
671
- validationFields?.fields?.checkout?.driver_tip?.enabled &&
672
- validationFields?.fields?.checkout?.driver_tip?.required &&
673
- (Number(cart?.driver_tip) <= 0) && (
674
- <OText
675
- color={theme.colors.error}
676
- size={12}
677
- >
678
- {t('WARNING_INVALID_DRIVER_TIP', 'Driver Tip is required.')}
679
- </OText>
680
- )}
679
+ validationFields?.fields?.checkout?.driver_tip?.enabled &&
680
+ validationFields?.fields?.checkout?.driver_tip?.required &&
681
+ (Number(cart?.driver_tip) <= 0) && (
682
+ <OText
683
+ color={theme.colors.error}
684
+ size={12}
685
+ >
686
+ {t('WARNING_INVALID_DRIVER_TIP', 'Driver Tip is required.')}
687
+ </OText>
688
+ )}
681
689
  </ChErrors>
682
690
  </View>
683
691
  )}
@@ -59,11 +59,14 @@ const DriverTipsUI = (props: any) => {
59
59
  tip = isNaN(tip) ? 0 : tip
60
60
  setvalue(tip)
61
61
  }
62
-
62
+
63
63
  return (
64
64
  <DTContainer>
65
+ <DTLabel>
66
+ {t('CUSTOM_DRIVER_TIP_MESSAGE', '100% of these tips go directly to your driver')}
67
+ </DTLabel>
65
68
  <DTWrapperTips>
66
- {driverTipsOptions.map((option: any, i: number) => (
69
+ {!isDriverTipUseCustom && driverTipsOptions.map((option: any, i: number) => (
67
70
  <TouchableOpacity
68
71
  key={i}
69
72
  onPress={() => handlerChangeOption(option)}
@@ -79,7 +82,7 @@ const DriverTipsUI = (props: any) => {
79
82
  </TouchableOpacity>
80
83
  ))}
81
84
  </DTWrapperTips>
82
- {!driverTipsOptions.includes(driverTip) && driverTip > 0 && (
85
+ {(!isDriverTipUseCustom && !driverTipsOptions.includes(driverTip) && driverTip > 0) && (
83
86
  <OText
84
87
  color={theme.colors.error}
85
88
  size={16}
@@ -90,9 +93,6 @@ const DriverTipsUI = (props: any) => {
90
93
  )}
91
94
  {isDriverTipUseCustom && (
92
95
  <DTForm>
93
- <DTLabel>
94
- {t('CUSTOM_DRIVER_TIP_MESSAGE', '100% of these tips go directly to your driver')}
95
- </DTLabel>
96
96
  <DTWrapperInput>
97
97
  <OInput
98
98
  placeholder={placeholderCurrency}
@@ -1,9 +1,11 @@
1
- import React from 'react'
1
+ import React, { useState } from 'react'
2
+ import { RefreshControl } from 'react-native'
2
3
  import { HelpParams } from '../../types'
3
4
  import { useLanguage } from 'ordering-components/native'
4
5
  import NavBar from '../NavBar'
5
6
  import { OText } from '../shared'
6
7
  import { LastOrders } from '../LastOrders'
8
+ import { Container } from '../../layouts/Container'
7
9
 
8
10
  import {
9
11
  HelpSubItem,
@@ -15,13 +17,28 @@ export const Help = (props: HelpParams) => {
15
17
  navigation
16
18
  } = props
17
19
  const [, t] = useLanguage()
20
+ const [refreshing] = useState(false);
21
+ const [refresh, setRefresh] = useState(false)
18
22
 
19
23
  const goToBack = () => navigation?.canGoBack() && navigation.goBack()
20
24
  const onRedirect = (route: string, params?: any) => {
21
25
  navigation.navigate(route, params)
22
26
  }
27
+
28
+ const handleOnRefresh = () => {
29
+ setRefresh(true)
30
+ }
31
+
23
32
  return (
24
- <>
33
+ <Container
34
+ noPadding
35
+ refreshControl={
36
+ <RefreshControl
37
+ refreshing={refreshing}
38
+ onRefresh={() => handleOnRefresh()}
39
+ />
40
+ }
41
+ >
25
42
  <NavBar
26
43
  title={t('HELP', 'Help')}
27
44
  titleAlign={'center'}
@@ -48,8 +65,8 @@ export const Help = (props: HelpParams) => {
48
65
 
49
66
  <LastOrdersContainer>
50
67
  <OText size={18} weight={600}>{t('LAST_ORDERS', 'Last Orders')}</OText>
51
- <LastOrders {...props} onRedirect={onRedirect} />
68
+ <LastOrders {...props} onRedirect={onRedirect} refresh={refresh} setRefresh={setRefresh} />
52
69
  </LastOrdersContainer>
53
- </>
70
+ </Container>
54
71
  )
55
72
  }
@@ -18,11 +18,15 @@ import {
18
18
  OrderContainer,
19
19
  OrderInfo
20
20
  } from './styles'
21
+ import { useEffect } from 'react'
21
22
 
22
23
  const LastOrdersUI = (props: LastOrdersParams) => {
23
24
  const {
24
25
  orderList,
25
- onRedirect
26
+ onRedirect,
27
+ loadOrders,
28
+ refresh,
29
+ setRefresh
26
30
  } = props
27
31
  const { loading, error, orders } = orderList
28
32
 
@@ -46,6 +50,13 @@ const LastOrdersUI = (props: LastOrdersParams) => {
46
50
  onRedirect && onRedirect('OrderDetails', { orderId: uuid })
47
51
  }
48
52
 
53
+ useEffect(() => {
54
+ if(refresh){
55
+ loadOrders(false, false, false, true)
56
+ setRefresh && setRefresh(false)
57
+ }
58
+ }, [refresh])
59
+
49
60
  return (
50
61
  <>
51
62
  {loading ? (
@@ -93,6 +93,8 @@ const LoginFormUI = (props: LoginParams) => {
93
93
  const [recaptchaConfig, setRecaptchaConfig] = useState<any>({})
94
94
  const [recaptchaVerified, setRecaptchaVerified] = useState(false)
95
95
  const [alertState, setAlertState] = useState({ open: false, title: '', content: [] })
96
+ const [tabLayouts, setTabLayouts] = useState<any>({})
97
+ const tabsRef = useRef<any>(null)
96
98
 
97
99
  const theme = useTheme();
98
100
  const isOtpEmail = loginTab === 'otp' && otpType === 'email'
@@ -146,9 +148,10 @@ const LoginFormUI = (props: LoginParams) => {
146
148
  const passwordRef = useRef<any>({});
147
149
  const recaptchaRef = useRef<any>({});
148
150
 
149
- const handleChangeTab = (val: string) => {
151
+ const handleChangeTab = (val: string, otpType?: string) => {
150
152
  props.handleChangeTab(val);
151
153
  setPasswordSee(false);
154
+ handleCategoryScroll(otpType ? `${val}_${otpType}` : val)
152
155
  };
153
156
 
154
157
  const onSubmit = (values?: any) => {
@@ -231,7 +234,7 @@ const LoginFormUI = (props: LoginParams) => {
231
234
  }
232
235
 
233
236
  const handleChangeOtpType = (type: string) => {
234
- handleChangeTab('otp')
237
+ handleChangeTab('otp', type)
235
238
  setOtpType(type)
236
239
  }
237
240
 
@@ -248,6 +251,20 @@ const LoginFormUI = (props: LoginParams) => {
248
251
  })
249
252
  }
250
253
 
254
+ const handleCategoryScroll = (opc : string) => {
255
+ tabsRef.current.scrollTo({
256
+ x: tabLayouts?.[opc]?.x - 40,
257
+ animated: true
258
+ })
259
+ }
260
+
261
+ const handleOnLayout = (event: any, opc: string) => {
262
+ const _tabLayouts = { ...tabLayouts }
263
+ const categoryKey = opc
264
+ _tabLayouts[categoryKey] = event.nativeEvent.layout
265
+ setTabLayouts(_tabLayouts)
266
+ }
267
+
251
268
  useEffect(() => {
252
269
  if (configs && Object.keys(configs).length > 0 && enableReCaptcha) {
253
270
  setRecaptchaConfig({
@@ -331,9 +348,16 @@ const LoginFormUI = (props: LoginParams) => {
331
348
  <FormSide>
332
349
  {((useLoginByEmail && useLoginByCellphone) || useLoginOtp) && (
333
350
  <LoginWith>
334
- <OTabs horizontal>
351
+ <OTabs
352
+ horizontal
353
+ showsHorizontalScrollIndicator={false}
354
+ ref={tabsRef}
355
+ >
335
356
  {useLoginByEmail && (
336
- <TabBtn onPress={() => handleChangeTab('email')}>
357
+ <TabBtn
358
+ onPress={() => handleChangeTab('email')}
359
+ onLayout={(event: any) => handleOnLayout(event, 'email')}
360
+ >
337
361
  <OTab
338
362
  style={{
339
363
  borderBottomColor:
@@ -355,7 +379,10 @@ const LoginFormUI = (props: LoginParams) => {
355
379
  </TabBtn>
356
380
  )}
357
381
  {useLoginByCellphone && (
358
- <TabBtn onPress={() => handleChangeTab('cellphone')}>
382
+ <TabBtn
383
+ onPress={() => handleChangeTab('cellphone')}
384
+ onLayout={(event: any) => handleOnLayout(event, 'cellphone')}
385
+ >
359
386
  <OTab
360
387
  style={{
361
388
  borderBottomColor:
@@ -377,7 +404,10 @@ const LoginFormUI = (props: LoginParams) => {
377
404
  </TabBtn>
378
405
  )}
379
406
  {useLoginOtpEmail && (
380
- <TabBtn onPress={() => handleChangeOtpType('email')}>
407
+ <TabBtn
408
+ onPress={() => handleChangeOtpType('email')}
409
+ onLayout={(event: any) => handleOnLayout(event, 'otp_email')}
410
+ >
381
411
  <OTab
382
412
  style={{
383
413
  borderBottomColor:
@@ -399,7 +429,10 @@ const LoginFormUI = (props: LoginParams) => {
399
429
  </TabBtn>
400
430
  )}
401
431
  {useLoginOtpCellphone && (
402
- <TabBtn onPress={() => handleChangeOtpType('cellphone')}>
432
+ <TabBtn
433
+ onPress={() => handleChangeOtpType('cellphone')}
434
+ onLayout={(event: any) => handleOnLayout(event, 'otp_cellphone')}
435
+ >
403
436
  <OTab
404
437
  style={{
405
438
  borderBottomColor:
@@ -42,7 +42,7 @@ import { OSRow } from '../OrderSummary/styles';
42
42
  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
46
  export const OrderDetailsUI = (props: OrderDetailsParams) => {
47
47
  const {
48
48
  navigation,
@@ -82,7 +82,8 @@ export const OrderDetailsUI = (props: OrderDetailsParams) => {
82
82
  justifyContent: 'flex-start',
83
83
  paddingLeft: 0,
84
84
  height: 30,
85
- width: 40,
85
+ width: 30,
86
+ marginTop: Platform.OS === 'ios' ? 0 : 30
86
87
  },
87
88
  });
88
89
 
@@ -364,7 +365,7 @@ export const OrderDetailsUI = (props: OrderDetailsParams) => {
364
365
  }
365
366
 
366
367
  const RenderGoogleMap = () => {
367
- const driverLocationString = typeof order?.driver?.location?.location === 'string' && order?.driver?.location?.location?.split(',').map((l : string) => l.replace(/[^-.0-9]/g, ''))
368
+ const driverLocationString = typeof order?.driver?.location?.location === 'string' && order?.driver?.location?.location?.split(',').map((l: string) => l.replace(/[^-.0-9]/g, ''))
368
369
  const parsedLocations = locations.map(location => typeof location?.location === 'string' ? {
369
370
  ...location,
370
371
  lat: parseFloat(location?.location?.split(',')[0].replace(/[^-.0-9]/g, '')),
@@ -498,27 +499,23 @@ export const OrderDetailsUI = (props: OrderDetailsParams) => {
498
499
  {order && Object.keys(order).length > 0 && (
499
500
  <>
500
501
  <Header>
501
- <OButton
502
- imgLeftSrc={theme.images.general.arrow_left}
503
- imgRightSrc={null}
504
- style={styles.btnBackArrow}
505
- onClick={() => handleArrowBack()}
506
- imgLeftStyle={{ tintColor: theme.colors.disabled }}
502
+ <NavBar
503
+ title={`${t('ORDER', 'Order')} #${order?.id}`}
504
+ titleAlign={'center'}
505
+ onActionLeft={handleArrowBack}
506
+ showCall={false}
507
+ btnStyle={{ paddingLeft: 0 }}
508
+ style={{ flexDirection: 'column', alignItems: 'flex-start', marginTop: Platform.OS === 'ios' ? 0 : 20 }}
509
+ titleWrapStyle={{ paddingHorizontal: 0 }}
510
+ titleStyle={{ marginRight: 0, marginLeft: 0 }}
511
+ subTitle={<OText size={12} lineHeight={18} color={theme.colors.textNormal}>
512
+ {order?.delivery_datetime_utc
513
+ ? parseDate(order?.delivery_datetime_utc)
514
+ : parseDate(order?.delivery_datetime, { utc: false })}
515
+ </OText>}
507
516
  />
508
517
  <OrderInfo>
509
518
  <OrderData>
510
- <OText
511
- size={20}
512
- lineHeight={30}
513
- weight={'600'}
514
- color={theme.colors.textNormal}>
515
- {t('ORDER', 'Order')} #{order?.id}
516
- </OText>
517
- <OText size={12} lineHeight={18} color={theme.colors.textNormal}>
518
- {order?.delivery_datetime_utc
519
- ? parseDate(order?.delivery_datetime_utc)
520
- : parseDate(order?.delivery_datetime, { utc: false })}
521
- </OText>
522
519
  {
523
520
  (
524
521
  parseInt(order?.status) === 1 ||
@@ -112,6 +112,7 @@ const PaymentOptionWalletUI = (props: any) => {
112
112
  true: theme.colors.primary,
113
113
  false: theme.colors.disabled
114
114
  }}
115
+ onChange={() => handleOnChange(idx, wallet)}
115
116
  tintColor={theme.colors.disabled}
116
117
  onCheckColor={theme.colors.primary}
117
118
  onTintColor={theme.colors.primary}
@@ -17,7 +17,7 @@ import { useTheme } from 'styled-components/native';
17
17
  import { OButton, OIcon, OModal, OText } from '../shared'
18
18
  import { Placeholder, PlaceholderLine } from 'rn-placeholder'
19
19
  import { NotFoundSource } from '../NotFoundSource'
20
- import { View, StyleSheet, ScrollView, Platform } from 'react-native'
20
+ import { View, StyleSheet, ScrollView, Platform, RefreshControl } from 'react-native'
21
21
  import FastImage from 'react-native-fast-image'
22
22
  import { PromotionParams } from '../../types'
23
23
  import { Container } from '../../layouts/Container'
@@ -28,6 +28,7 @@ const PromotionsUI = (props: PromotionParams) => {
28
28
  offersState,
29
29
  handleSearchValue,
30
30
  searchValue,
31
+ loadOffers,
31
32
  offerSelected,
32
33
  setOfferSelected
33
34
  } = props
@@ -68,6 +69,7 @@ const PromotionsUI = (props: PromotionParams) => {
68
69
  const [, t] = useLanguage()
69
70
  const [{ parseDate, parsePrice, optimizeImage }] = useUtils()
70
71
  const [openModal, setOpenModal] = useState(false)
72
+ const [refreshing] = useState(false);
71
73
 
72
74
  const handleClickOffer = (offer: any) => {
73
75
  setOpenModal(true)
@@ -79,6 +81,12 @@ const PromotionsUI = (props: PromotionParams) => {
79
81
  navigation.navigate('Business', { store: store.slug })
80
82
  }
81
83
 
84
+ const handleOnRefresh = () => {
85
+ if (!offersState.loading) {
86
+ loadOffers();
87
+ }
88
+ }
89
+
82
90
  const filteredOffers = offersState?.offers?.filter((offer: any) => offer.name.toLowerCase().includes(searchValue.toLowerCase()))
83
91
  const targetString = offerSelected?.target === 1
84
92
  ? t('SUBTOTAL', 'Subtotal')
@@ -87,7 +95,15 @@ const PromotionsUI = (props: PromotionParams) => {
87
95
  : t('SERVICE_FEE', 'Service fee')
88
96
 
89
97
  return (
90
- <Container noPadding>
98
+ <Container
99
+ noPadding
100
+ refreshControl={
101
+ <RefreshControl
102
+ refreshing={refreshing}
103
+ onRefresh={() => handleOnRefresh()}
104
+ />
105
+ }
106
+ >
91
107
  <NavBar
92
108
  title={t('PROMOTIONS', 'Promotions')}
93
109
  titleAlign={'center'}
@@ -124,7 +140,7 @@ const PromotionsUI = (props: PromotionParams) => {
124
140
  <SingleOfferContainer key={offer.id}>
125
141
  <OfferInformation>
126
142
  <OText style={styles.offerTitle} numberOfLines={2}>{offer?.name}</OText>
127
- {offer?.description && (
143
+ {!!offer?.description && (
128
144
  <OText style={styles.offerDescription} numberOfLines={2}>{offer?.description}</OText>
129
145
  )}
130
146
  <OText style={styles.offerExtraInfo}>
@@ -170,13 +186,13 @@ const PromotionsUI = (props: PromotionParams) => {
170
186
  {offerSelected?.auto && (
171
187
  <OText>{t('OFFER_AUTOMATIC', 'This offer applies automatic')}</OText>
172
188
  )}
173
- {offerSelected?.minimum && (
189
+ {!!offerSelected?.minimum && (
174
190
  <OText>{t('MINIMUM_PURCHASE_FOR_OFFER', 'Minimum purchase for use this offer')}: {parsePrice(offerSelected?.minimum)}</OText>
175
191
  )}
176
- {offerSelected?.max_discount && (
192
+ {!!offerSelected?.max_discount && (
177
193
  <OText>{t('MAX_DISCOUNT_ALLOWED', 'Max discount allowed')}: {parsePrice(offerSelected?.max_discount)}</OText>
178
194
  )}
179
- {offerSelected?.description && (
195
+ {!!offerSelected?.description && (
180
196
  <OText>{offerSelected?.description}</OText>
181
197
  )}
182
198
  </OfferData>
@@ -140,7 +140,7 @@ const WalletsUI = (props: any) => {
140
140
  </OTabs>
141
141
 
142
142
  <SectionContent>
143
- {!!loyaltyLevel && (
143
+ {!!loyaltyLevel && tabSelected === 'credit_point' && (
144
144
  <LoyaltyContent>
145
145
  <LoyaltyWrapp>
146
146
  <OText size={20}>
@@ -153,6 +153,7 @@ export interface BusinessesListingParams {
153
153
  defaultBusinessType?: any;
154
154
  franchiseId?: any;
155
155
  businessId?: any;
156
+ isGuestUser?: any;
156
157
  }
157
158
  export interface HighestRatedBusinessesParams {
158
159
  businessesList: { businesses: Array<any>, loading: boolean, error: null | string };
@@ -600,6 +601,7 @@ export interface PromotionParams {
600
601
  searchValue: string,
601
602
  offerSelected: any,
602
603
  setOfferSelected: any,
604
+ loadOffers: any
603
605
  }
604
606
  export interface SessionsParams {
605
607
  navigation: any,