ordering-ui-react-native 0.12.43 → 0.12.47

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 (60) hide show
  1. package/package.json +1 -1
  2. package/src/components/AppleLogin/index.tsx +145 -0
  3. package/src/components/AppleLogin/styles.tsx +22 -0
  4. package/src/components/BusinessesListing/index.tsx +1 -1
  5. package/src/components/Cart/index.tsx +56 -23
  6. package/src/components/LoginForm/index.tsx +34 -17
  7. package/src/components/OrderDetails/index.tsx +90 -35
  8. package/src/components/OrderSummary/index.tsx +59 -27
  9. package/src/components/OrderSummary/styles.tsx +6 -0
  10. package/src/components/ProductForm/index.tsx +1 -1
  11. package/src/components/SignupForm/index.tsx +52 -35
  12. package/src/components/SingleProductCard/index.tsx +1 -1
  13. package/src/components/TaxInformation/index.tsx +51 -0
  14. package/src/components/TaxInformation/styles.tsx +9 -0
  15. package/src/components/UserFormDetails/index.tsx +0 -2
  16. package/src/navigators/BottomNavigator.tsx +1 -1
  17. package/src/types/index.tsx +7 -1
  18. package/themes/business/src/components/AcceptOrRejectOrder/index.tsx +12 -7
  19. package/themes/doordash/src/components/Cart/index.tsx +55 -22
  20. package/themes/doordash/src/components/OrderDetails/index.tsx +444 -386
  21. package/themes/doordash/src/components/OrderSummary/index.tsx +252 -221
  22. package/themes/doordash/src/components/OrderSummary/styles.tsx +6 -0
  23. package/themes/doordash/src/components/SingleProductCard/index.tsx +1 -1
  24. package/themes/doordash/src/components/TaxInformation/index.tsx +51 -0
  25. package/themes/doordash/src/components/TaxInformation/styles.tsx +9 -0
  26. package/themes/franchises/src/components/Cart/index.tsx +55 -23
  27. package/themes/franchises/src/components/OrderDetails/index.tsx +77 -23
  28. package/themes/franchises/src/components/OrderSummary/index.tsx +58 -24
  29. package/themes/franchises/src/components/OrderSummary/styles.tsx +6 -0
  30. package/themes/franchises/src/components/SingleProductCard/index.tsx +1 -1
  31. package/themes/franchises/src/components/TaxInformation/index.tsx +51 -0
  32. package/themes/franchises/src/components/TaxInformation/styles.tsx +9 -0
  33. package/themes/instacart/src/components/Cart/index.tsx +57 -17
  34. package/themes/instacart/src/components/OrderDetails/index.tsx +490 -433
  35. package/themes/instacart/src/components/OrderSummary/index.tsx +236 -194
  36. package/themes/instacart/src/components/OrderSummary/styles.tsx +6 -0
  37. package/themes/instacart/src/components/SingleProductCard/index.tsx +2 -2
  38. package/themes/instacart/src/components/TaxInformation/index.tsx +51 -0
  39. package/themes/instacart/src/components/TaxInformation/styles.tsx +9 -0
  40. package/themes/original/src/components/Cart/index.tsx +55 -13
  41. package/themes/original/src/components/OrderDetails/index.tsx +76 -23
  42. package/themes/original/src/components/OrderSummary/index.tsx +208 -173
  43. package/themes/original/src/components/OrderSummary/styles.tsx +6 -0
  44. package/themes/original/src/components/SingleProductCard/index.tsx +1 -1
  45. package/themes/original/src/components/TaxInformation/index.tsx +51 -0
  46. package/themes/original/src/components/TaxInformation/styles.tsx +9 -0
  47. package/themes/single-business/src/components/Cart/index.tsx +57 -24
  48. package/themes/single-business/src/components/OrderDetails/index.tsx +77 -23
  49. package/themes/single-business/src/components/OrderSummary/index.tsx +58 -24
  50. package/themes/single-business/src/components/OrderSummary/styles.tsx +6 -0
  51. package/themes/single-business/src/components/SingleProductCard/index.tsx +1 -1
  52. package/themes/single-business/src/components/TaxInformation/index.tsx +51 -0
  53. package/themes/single-business/src/components/TaxInformation/styles.tsx +9 -0
  54. package/themes/uber-eats/src/components/Cart/index.tsx +56 -14
  55. package/themes/uber-eats/src/components/OrderDetails/index.tsx +81 -22
  56. package/themes/uber-eats/src/components/OrderSummary/index.tsx +56 -23
  57. package/themes/uber-eats/src/components/OrderSummary/styles.tsx +6 -0
  58. package/themes/uber-eats/src/components/SingleProductCard/index.tsx +1 -1
  59. package/themes/uber-eats/src/components/TaxInformation/index.tsx +51 -0
  60. package/themes/uber-eats/src/components/TaxInformation/styles.tsx +9 -0
@@ -1,5 +1,5 @@
1
1
  import React, { useState } from 'react';
2
- import { View } from 'react-native'
2
+ import { TouchableOpacity, View } from 'react-native'
3
3
  import {
4
4
  Cart,
5
5
  useOrder,
@@ -13,7 +13,8 @@ import {
13
13
  OSContainer,
14
14
  OSProductList,
15
15
  OSBill,
16
- OSTable
16
+ OSTable,
17
+ OSRow
17
18
  } from './styles';
18
19
 
19
20
  import { ProductItemAccordion } from '../ProductItemAccordion';
@@ -22,7 +23,8 @@ import { OModal, OText } from '../shared';
22
23
  import { ProductForm } from '../ProductForm';
23
24
  import { verifyDecimals } from '../../utils';
24
25
  import { useTheme } from 'styled-components/native';
25
-
26
+ import { TaxInformation } from '../TaxInformation';
27
+ import AntIcon from 'react-native-vector-icons/AntDesign'
26
28
  const OrderSummaryUI = (props: any) => {
27
29
  const {
28
30
  cart,
@@ -42,6 +44,7 @@ const OrderSummaryUI = (props: any) => {
42
44
  const [validationFields] = useValidationFields();
43
45
  const [openProduct, setModalIsOpen] = useState(false)
44
46
  const [curProduct, setCurProduct] = useState<any>(null)
47
+ const [openTaxModal, setOpenTaxModal] = useState<any>({ open: false, data: null })
45
48
 
46
49
  const isCouponEnabled = validationFields?.fields?.checkout?.coupon?.enabled;
47
50
 
@@ -60,6 +63,16 @@ const OrderSummaryUI = (props: any) => {
60
63
  }
61
64
  }
62
65
 
66
+ const getIncludedTaxes = () => {
67
+ if (cart?.taxes === null) {
68
+ return cart.business.tax_type === 1 ? cart?.tax : 0
69
+ } else {
70
+ return cart?.taxes.reduce((taxIncluded: number, tax: any) => {
71
+ return taxIncluded + (tax.type === 1 ? tax.summary?.tax : 0)
72
+ }, 0)
73
+ }
74
+ }
75
+
63
76
  return (
64
77
  <OSContainer>
65
78
  {cart?.products?.length > 0 && (
@@ -84,9 +97,7 @@ const OrderSummaryUI = (props: any) => {
84
97
  <OSBill>
85
98
  <OSTable>
86
99
  <OText size={18}>{t('SUBTOTAL', 'Subtotal')}</OText>
87
- <OText size={18}>{cart.business.tax_type === 1
88
- ? parsePrice((cart?.subtotal + cart?.tax) || 0)
89
- : parsePrice(cart?.subtotal || 0)}</OText>
100
+ <OText size={18}>{parsePrice(cart?.subtotal + getIncludedTaxes())}</OText>
90
101
  </OSTable>
91
102
  {cart?.discount > 0 && cart?.total >= 0 && (
92
103
  <OSTable>
@@ -101,15 +112,38 @@ const OrderSummaryUI = (props: any) => {
101
112
  <OText size={18}>- {parsePrice(cart?.discount || 0)}</OText>
102
113
  </OSTable>
103
114
  )}
104
- {cart.business.tax_type !== 1 && (
105
- <OSTable>
106
- <OText size={18}>
107
- {t('TAX', 'Tax')}
108
- {`(${verifyDecimals(cart?.business?.tax, parseNumber)}%)`}
109
- </OText>
110
- <OText size={18}>{parsePrice(cart?.tax || 0)}</OText>
111
- </OSTable>
112
- )}
115
+ {
116
+ cart?.taxes?.length > 0 && cart?.taxes?.filter((tax: any) => tax?.type === 2 && tax?.rate !== 0).map((tax: any) => (
117
+ <OSTable key={tax?.id}>
118
+ <OSRow>
119
+ <OText size={18} numberOfLines={1}>
120
+ {tax?.name || t('INHERIT_FROM_BUSINESS', 'Inherit from business')}{' '}
121
+ {`(${verifyDecimals(tax?.rate, parseNumber)}%)`}{' '}
122
+ </OText>
123
+ <TouchableOpacity onPress={() => setOpenTaxModal({ open: true, data: tax })} >
124
+ <AntIcon name='exclamationcircleo' size={20} color={theme.colors.primary} />
125
+ </TouchableOpacity>
126
+ </OSRow>
127
+ <OText size={18}>{parsePrice(tax?.summary?.tax || 0)}</OText>
128
+ </OSTable>
129
+ ))
130
+ }
131
+ {
132
+ cart?.fees?.length > 0 && cart?.fees?.filter((fee: any) => !(fee.fixed === 0 && fee.percentage === 0))?.map((fee: any) => (
133
+ <OSTable key={fee.id}>
134
+ <OSRow>
135
+ <OText size={18} numberOfLines={1}>
136
+ {fee.name || t('INHERIT_FROM_BUSINESS', 'Inherit from business')}{' '}
137
+ ({parsePrice(fee?.fixed)} + {fee.percentage}%){' '}
138
+ </OText>
139
+ <TouchableOpacity onPress={() => setOpenTaxModal({ open: true, data: fee })} >
140
+ <AntIcon name='exclamationcircleo' size={20} color={theme.colors.primary} />
141
+ </TouchableOpacity>
142
+ </OSRow>
143
+ <OText size={18}>{parsePrice(fee?.summary?.fixed + fee?.summary?.percentage || 0)}</OText>
144
+ </OSTable>
145
+ ))
146
+ }
113
147
  {orderState?.options?.type === 1 && cart?.delivery_price > 0 && (
114
148
  <OSTable>
115
149
  <OText size={18}>{t('DELIVERY_FEE', 'Delivery Fee')}</OText>
@@ -123,22 +157,13 @@ const OrderSummaryUI = (props: any) => {
123
157
  {cart?.driver_tip_rate > 0 &&
124
158
  parseInt(configs?.driver_tip_type?.value, 10) === 2 &&
125
159
  !parseInt(configs?.driver_tip_use_custom?.value, 10) &&
126
- (
127
- `(${verifyDecimals(cart?.driver_tip_rate, parseNumber)}%)`
128
- )}
160
+ (
161
+ `(${verifyDecimals(cart?.driver_tip_rate, parseNumber)}%)`
162
+ )}
129
163
  </OText>
130
164
  <OText size={18}>{parsePrice(cart?.driver_tip)}</OText>
131
165
  </OSTable>
132
166
  )}
133
- {cart?.service_fee > 0 && (
134
- <OSTable>
135
- <OText size={18}>
136
- {t('SERVICE_FEE', 'Service Fee')}
137
- {`(${verifyDecimals(cart?.business?.service_fee, parseNumber)}%)`}
138
- </OText>
139
- <OText size={18}>{parsePrice(cart?.service_fee)}</OText>
140
- </OSTable>
141
- )}
142
167
  {isCouponEnabled && !isCartPending && (
143
168
  <View>
144
169
  <View style={{ paddingVertical: 5 }}>
@@ -182,6 +207,13 @@ const OrderSummaryUI = (props: any) => {
182
207
  isFromCheckout={isFromCheckout}
183
208
  />
184
209
  </OModal>
210
+ <OModal
211
+ open={openTaxModal.open}
212
+ onClose={() => setOpenTaxModal({ open: false, data: null })}
213
+ entireModal
214
+ >
215
+ <TaxInformation data={openTaxModal.data} products={cart.products} />
216
+ </OModal>
185
217
  </>
186
218
  )}
187
219
  </OSContainer>
@@ -29,3 +29,9 @@ export const OSCoupon = styled.View`
29
29
  width: 100%;
30
30
  padding: 5px 0px;
31
31
  `
32
+
33
+ export const OSRow = styled.View`
34
+ flex-direction: row;
35
+ overflow: hidden;
36
+ width: 80%;
37
+ `
@@ -132,7 +132,7 @@ export const ProductOptionsUI = (props: any) => {
132
132
  ) : (
133
133
  <>
134
134
  <View style={{ flexDirection: 'column', width: '100%' }}>
135
- <OText size={20} style={{ flex: I18nManager.isRTL ? 0 : 1, marginBottom: 10 }}>{product?.name || productCart.name}{'price'}</OText>
135
+ <OText size={20} style={{ flex: I18nManager.isRTL ? 0 : 1, marginBottom: 10 }}>{product?.name || productCart.name}</OText>
136
136
  <View style={{ flexDirection: 'row', justifyContent: 'space-between', marginBottom: 10 }}>
137
137
  <OText size={16} style={{ flex: I18nManager.isRTL ? 1 : 0 }} color={theme.colors.primary}>{productCart.price ? parsePrice(productCart.price) : ''}</OText>
138
138
  <OText size={14} style={{ flex: I18nManager.isRTL ? 1 : 0 }} color={'#909BA9'}>
@@ -34,6 +34,7 @@ import CheckBox from '@react-native-community/checkbox';
34
34
  import { SignupParams } from '../../types';
35
35
  import { sortInputFields } from '../../utils';
36
36
  import { useTheme } from 'styled-components/native';
37
+ import { AppleLogin } from '../AppleLogin';
37
38
 
38
39
  const notValidationFields = ['coupon', 'driver_tip', 'mobile_phone', 'address', 'address_notes']
39
40
 
@@ -97,7 +98,7 @@ const SignupFormUI = (props: SignupParams) => {
97
98
  const [isModalVisible, setIsModalVisible] = useState(false);
98
99
  const [isLoadingVerifyModal, setIsLoadingVerifyModal] = useState(false);
99
100
  const [signupTab, setSignupTab] = useState(useSignupByCellphone && !useSignupByEmail ? 'cellphone' : 'email')
100
- const [isFBLoading, setIsFBLoading] = useState(false)
101
+ const [isLoadingSocialButton, setIsLoadingSocialButton] = useState(false);
101
102
  const [phoneInputData, setPhoneInputData] = useState({
102
103
  error: '',
103
104
  phone: {
@@ -114,8 +115,12 @@ const SignupFormUI = (props: SignupParams) => {
114
115
  const phoneRef = useRef<any>(null)
115
116
  const passwordRef = useRef<any>(null)
116
117
 
117
- const handleRefs = (ref : any, code : string) => {
118
- switch(code){
118
+ const anySocialButtonActivated = ((configs?.facebook_login?.value === 'true' || configs?.facebook_login?.value === '1') && configs?.facebook_id?.value) ||
119
+ (configs?.google_login_client_id?.value !== '' && configs?.google_login_client_id?.value !== null) ||
120
+ (configs?.apple_login_client_id?.value !== '' && configs?.apple_login_client_id?.value !== null)
121
+
122
+ const handleRefs = (ref: any, code: string) => {
123
+ switch (code) {
119
124
  case 'name': {
120
125
  nameRef.current = ref
121
126
  break
@@ -138,8 +143,8 @@ const SignupFormUI = (props: SignupParams) => {
138
143
  }
139
144
  }
140
145
 
141
- const handleFocusRef = (code : string) => {
142
- switch(code) {
146
+ const handleFocusRef = (code: string) => {
147
+ switch (code) {
143
148
  case 'name': {
144
149
  nameRef?.current?.focus()
145
150
  break
@@ -163,8 +168,8 @@ const SignupFormUI = (props: SignupParams) => {
163
168
  }
164
169
  }
165
170
 
166
- const getNextFieldCode = (index : number) => {
167
- const fields = sortInputFields({ values: validationFields?.fields?.checkout })?.filter((field : any) => !notValidationFields.includes(field.code) && showField(field.code))
171
+ const getNextFieldCode = (index: number) => {
172
+ const fields = sortInputFields({ values: validationFields?.fields?.checkout })?.filter((field: any) => !notValidationFields.includes(field.code) && showField(field.code))
168
173
  return fields[index + 1]?.code
169
174
  }
170
175
 
@@ -176,6 +181,14 @@ const SignupFormUI = (props: SignupParams) => {
176
181
  })
177
182
  }
178
183
 
184
+ const handleSuccessApple = (user: any) => {
185
+ _removeStoreData('isGuestUser')
186
+ login({
187
+ user,
188
+ token: user?.session?.access_token
189
+ })
190
+ }
191
+
179
192
  const handleChangeTab = (val: string) => {
180
193
  setSignupTab(val);
181
194
  setPasswordSee(false);
@@ -347,7 +360,7 @@ const SignupFormUI = (props: SignupParams) => {
347
360
  <FormInput>
348
361
  {!(useChekoutFileds && validationFields?.loading && validationFields?.fields?.checkout) ? (
349
362
  <>
350
- {sortInputFields({ values: validationFields?.fields?.checkout }).map((field: any, i : number) =>
363
+ {sortInputFields({ values: validationFields?.fields?.checkout }).map((field: any, i: number) =>
351
364
  !notValidationFields.includes(field.code) &&
352
365
  (
353
366
  showField && showField(field.code) && (
@@ -367,7 +380,7 @@ const SignupFormUI = (props: SignupParams) => {
367
380
  autoCompleteType={field.code === 'email' ? 'email' : 'off'}
368
381
  returnKeyType='next'
369
382
  blurOnSubmit={false}
370
- forwardRef={(ref : any) => handleRefs(ref,field.code)}
383
+ forwardRef={(ref: any) => handleRefs(ref, field.code)}
371
384
  onSubmitEditing={() => field.code === 'email' ? phoneRef?.current?.focus?.() : handleFocusRef(getNextFieldCode(i))}
372
385
  />
373
386
  )}
@@ -462,17 +475,17 @@ const SignupFormUI = (props: SignupParams) => {
462
475
  }}
463
476
  defaultValue={false}
464
477
  />
465
- <ScrollView
466
- horizontal
467
- showsVerticalScrollIndicator={false}
468
- showsHorizontalScrollIndicator={false}
478
+ <ScrollView
479
+ horizontal
480
+ showsVerticalScrollIndicator={false}
481
+ showsHorizontalScrollIndicator={false}
469
482
  >
470
- <OText size={16} style={{ paddingHorizontal: 5 }}>{t('TERMS_AND_CONDITIONS_TEXT', 'I’m agree with')}</OText>
471
- <TouchableOpacity onPress={() => handleOpenTermsUrl(configs?.terms_and_conditions_url?.value)}>
472
- <OText size={16} color={theme.colors.primary}>
473
- {t('TERMS_AND_CONDITIONS', 'Terms & Conditions')}
474
- </OText>
475
- </TouchableOpacity>
483
+ <OText size={16} style={{ paddingHorizontal: 5 }}>{t('TERMS_AND_CONDITIONS_TEXT', 'I’m agree with')}</OText>
484
+ <TouchableOpacity onPress={() => handleOpenTermsUrl(configs?.terms_and_conditions_url?.value)}>
485
+ <OText size={16} color={theme.colors.primary}>
486
+ {t('TERMS_AND_CONDITIONS', 'Terms & Conditions')}
487
+ </OText>
488
+ </TouchableOpacity>
476
489
  </ScrollView>
477
490
  </View>
478
491
  )}
@@ -515,10 +528,7 @@ const SignupFormUI = (props: SignupParams) => {
515
528
  )
516
529
  }
517
530
 
518
- {configs && Object.keys(configs).length > 0 && (
519
- (((configs?.facebook_login?.value === 'true' || configs?.facebook_login?.value === '1') && configs?.facebook_id?.value) ||
520
- (configs?.google_login_client_id?.value !== '' && configs?.google_login_client_id?.value !== null)) &&
521
- (
531
+ {configs && Object.keys(configs).length > 0 && anySocialButtonActivated && (
522
532
  <ButtonsSection>
523
533
  <OText size={18} mBottom={10} color={theme.colors.disabled}>
524
534
  {t('SELECT_AN_OPTION_TO_LOGIN', 'Select an option to login')}
@@ -526,27 +536,34 @@ const SignupFormUI = (props: SignupParams) => {
526
536
  <SocialButtons>
527
537
  {(configs?.facebook_login?.value === 'true' || configs?.facebook_login?.value === '1') &&
528
538
  configs?.facebook_id?.value && (
529
- <FacebookLogin
530
- notificationState={notificationState}
531
- handleErrors={(err: any) => showToast(ToastType.Error, err)}
532
- handleLoading={(val: boolean) => setIsFBLoading(val)}
533
- handleSuccessFacebookLogin={handleSuccessFacebook}
534
- />
535
- )}
539
+ <FacebookLogin
540
+ notificationState={notificationState}
541
+ handleErrors={(err: any) => showToast(ToastType.Error, err)}
542
+ handleLoading={(val: boolean) => setIsLoadingSocialButton(val)}
543
+ handleSuccessFacebookLogin={handleSuccessFacebook}
544
+ />
545
+ )}
536
546
  {(configs?.google_login_client_id?.value !== '' && configs?.google_login_client_id?.value !== null) && (
537
547
  <GoogleLogin
538
548
  notificationState={notificationState}
539
549
  webClientId={configs?.google_login_client_id?.value}
540
550
  handleErrors={(err: any) => showToast(ToastType.Error, err)}
541
- handleLoading={(val: boolean) => setIsFBLoading(val)}
551
+ handleLoading={(val: boolean) => setIsLoadingSocialButton(val)}
542
552
  handleSuccessGoogleLogin={handleSuccessFacebook}
543
553
  />
544
554
  )}
555
+ {(configs?.apple_login_client_id?.value !== '' && configs?.apple_login_client_id?.value !== null) && (
556
+ <AppleLogin
557
+ notificationState={notificationState}
558
+ handleErrors={(err: any) => showToast(ToastType.Error, err)}
559
+ handleLoading={(val: boolean) => setIsLoadingSocialButton(val)}
560
+ handleSuccessApple={handleSuccessApple}
561
+ />
562
+ )}
545
563
  </SocialButtons>
546
564
  </ButtonsSection>
547
- )
548
- )}
549
- </FormSide >
565
+ )}
566
+ </FormSide>
550
567
  <OModal
551
568
  open={isModalVisible}
552
569
  onClose={() => setIsModalVisible(false)}
@@ -561,7 +578,7 @@ const SignupFormUI = (props: SignupParams) => {
561
578
  handleVerifyCodeClick={onSubmit}
562
579
  />
563
580
  </OModal>
564
- <Spinner visible={formState.loading || isFBLoading} />
581
+ <Spinner visible={formState.loading || isLoadingSocialButton} />
565
582
  </View >
566
583
  );
567
584
  };
@@ -67,7 +67,7 @@ export const SingleProductCard = (props: SingleProductCardParams) => {
67
67
  <CardContainer
68
68
  style={[styles.container, (isSoldOut || maxProductQuantity <= 0) && styles.soldOutBackgroundStyle]}
69
69
  activeOpacity={1}
70
- onPress={() => onProductClick(product)}
70
+ onPress={() => onProductClick?.(product)}
71
71
  >
72
72
  <OIcon
73
73
  url={optimizeImage(product?.images, 'h_200,c_limit')}
@@ -0,0 +1,51 @@
1
+ import React from 'react'
2
+ import { useLanguage, useUtils } from 'ordering-components/native'
3
+ import { SingleProductCard } from '../SingleProductCard'
4
+ import { TaxInformationContainer, ProductContainer } from './styles'
5
+ import { OText } from '../shared'
6
+
7
+ interface taxInformationParams {
8
+ data: { name: string, description?: string, rate: string | number, type: number, fixed?: number, percentage?: number, id: number },
9
+ products: Array<any>
10
+ }
11
+
12
+ export const TaxInformation = (props: taxInformationParams) => {
13
+ const {
14
+ data,
15
+ products
16
+ } = props
17
+
18
+ const [, t] = useLanguage()
19
+ const [{ parsePrice }] = useUtils()
20
+
21
+ const isTax = typeof data?.rate === 'number'
22
+ const TaxFeeString = isTax ? 'tax' : 'fee'
23
+ const includedOnPriceString = data?.type === 1 ? `(${t('INCLUDED_ON_PRICE', 'Included on price')})` : `(${t('NOT_INCLUDED_ON_PRICE', 'Not included on price')})`
24
+
25
+ return (
26
+ <TaxInformationContainer>
27
+ <OText size={24} style={{ alignSelf: 'center', textAlign: 'center' }} mBottom={10}>
28
+ {`${data?.name ||
29
+ t('INHERIT_FROM_BUSINESS', 'Inherit from business')} (${typeof data?.rate === 'number' ? `${data?.rate}%` : `${parsePrice(data?.fixed ?? 0)} + ${data?.percentage}%`})`}
30
+ </OText>
31
+ {data?.description && (
32
+ <OText mBottom={10} size={18} style={{ alignSelf: 'center', textAlign: 'center' }}>
33
+ {t('DESCRIPTION', 'Description')}: {data?.description} {data?.type && includedOnPriceString}
34
+ </OText>
35
+ )}
36
+ <OText>{t(`OTHER_PRODUCTS_WITH_THIS_${TaxFeeString.toUpperCase()}`, `Other products with this ${TaxFeeString}`)}:</OText>
37
+ <ProductContainer>
38
+ {
39
+ products.filter((product: any) => isTax ? (product.tax?.id ? product.tax?.id === data?.id : product.tax?.id === null && data?.id === null) : (product.fee?.id ? product.fee?.id === data?.id : (product.fee?.id === null && data?.id === null))).map(product => (
40
+ <SingleProductCard
41
+ key={product.id}
42
+ product={product}
43
+ isSoldOut={false}
44
+ businessId={product?.business_id}
45
+ />
46
+ ))
47
+ }
48
+ </ProductContainer>
49
+ </TaxInformationContainer>
50
+ )
51
+ }
@@ -0,0 +1,9 @@
1
+ import styled from 'styled-components/native'
2
+
3
+ export const TaxInformationContainer = styled.ScrollView`
4
+ padding: 10px;
5
+ `
6
+
7
+ export const ProductContainer = styled.View`
8
+ flex: 1
9
+ `
@@ -23,9 +23,7 @@ export const UserFormDetailsUI = (props: any) => {
23
23
  handleChangeInput,
24
24
  handleButtonUpdateClick,
25
25
  phoneUpdate,
26
- hideUpdateButton,
27
26
  handleCancelEdit,
28
- toggleIsEdit,
29
27
  isCheckout
30
28
  } = props
31
29
 
@@ -39,7 +39,7 @@ const BottomNavigator = () => {
39
39
  : {height: 40, position: 'relative', bottom: 15}
40
40
  return (
41
41
  <Tab.Navigator
42
- initialRouteName='BusinessList'
42
+ initialRouteName="BusinessList"
43
43
  activeColor={theme.colors.primary}
44
44
  barStyle={{ backgroundColor: theme.colors.white, ...androidStyles }}
45
45
  labeled={false}
@@ -202,7 +202,7 @@ export interface SingleProductCardParams {
202
202
  businessId: any,
203
203
  product: any;
204
204
  isSoldOut: boolean;
205
- onProductClick: any;
205
+ onProductClick?: any;
206
206
  }
207
207
  export interface BusinessInformationParams {
208
208
  navigation?: any,
@@ -430,6 +430,12 @@ export interface GoogleMapsParams {
430
430
  handleToggleMap?: () => void
431
431
  }
432
432
 
433
+ export interface AppleLoginParams {
434
+ handleErrors?: (error: string) => {},
435
+ handleLoading?: (val: boolean) => void,
436
+ handleSuccessApple?: (result: any) => void,
437
+ notificationState?: any,
438
+ }
433
439
  export interface ShareComponentParams {
434
440
  orderId?: number;
435
441
  hashkey?: string;
@@ -136,11 +136,6 @@ export const AcceptOrRejectOrder = (props: AcceptOrRejectOrderParams) => {
136
136
  timerRef.current.blur();
137
137
  }
138
138
 
139
- if (!isFocus) {
140
- if (time.length > 1) timerRef.current.clear();
141
- timerRef?.current?.focus?.();
142
- handleFocusTimer();
143
- }
144
139
  };
145
140
 
146
141
  const openTextTareaOInput = () => {
@@ -163,7 +158,7 @@ export const AcceptOrRejectOrder = (props: AcceptOrRejectOrderParams) => {
163
158
 
164
159
  const time = parseInt(hour || '0') * 60 + (parseInt(minsToSend) || 0);
165
160
 
166
- let bodyToSend : any = {};
161
+ let bodyToSend: any = {};
167
162
  const orderStatus: any = {
168
163
  acceptByBusiness: {
169
164
  prepared_in: time,
@@ -215,6 +210,17 @@ export const AcceptOrRejectOrder = (props: AcceptOrRejectOrderParams) => {
215
210
  handleUpdateOrder && handleUpdateOrder(bodyToSend.status, bodyToSend);
216
211
  };
217
212
 
213
+ useEffect(() => {
214
+ if (actions && action === 'accept') {
215
+ const interval = setTimeout(() => {
216
+ timerRef?.current?.focus?.()
217
+ }, 250)
218
+ return () => {
219
+ clearTimeout(interval)
220
+ }
221
+ }
222
+ }, [timerRef?.current])
223
+
218
224
  return (
219
225
  <KeyboardAvoidingView
220
226
  enabled
@@ -359,7 +365,6 @@ export const AcceptOrRejectOrder = (props: AcceptOrRejectOrderParams) => {
359
365
  onChangeText={handleTime}
360
366
  onPressOut={() => handleFixTime()}
361
367
  editable={true}
362
- autoFocus={actions && action === 'accept'}
363
368
  selectionColor={theme.colors.primary}
364
369
  placeholderTextColor={theme.colors.textGray}
365
370
  color={theme.colors.textGray}
@@ -10,7 +10,7 @@ import {
10
10
 
11
11
  import { CContainer, CheckoutAction } from './styles';
12
12
 
13
- import { OSBill, OSTable, OSCoupon, OSTotal } from '../OrderSummary/styles';
13
+ import { OSBill, OSTable, OSCoupon, OSTotal, OSRow } from '../OrderSummary/styles';
14
14
 
15
15
  import { ProductItemAccordion } from '../ProductItemAccordion';
16
16
  import { BusinessItemAccordion } from '../BusinessItemAccordion';
@@ -22,6 +22,9 @@ import { ProductForm } from '../ProductForm';
22
22
  import { UpsellingProducts } from '../UpsellingProducts';
23
23
  import { verifyDecimals } from '../../utils';
24
24
  import { Platform } from 'react-native';
25
+ import { TaxInformation } from '../TaxInformation';
26
+ import { TouchableOpacity } from 'react-native';
27
+ import AntIcon from 'react-native-vector-icons/AntDesign'
25
28
 
26
29
  const CartUI = (props: any) => {
27
30
  const {
@@ -47,6 +50,7 @@ const CartUI = (props: any) => {
47
50
  const [curProduct, setCurProduct] = useState<any>(null)
48
51
  const [openUpselling, setOpenUpselling] = useState(false)
49
52
  const [canOpenUpselling, setCanOpenUpselling] = useState(false)
53
+ const [openTaxModal, setOpenTaxModal] = useState<any>({ open: false, data: null })
50
54
 
51
55
  const isCartPending = cart?.status === 2
52
56
  const isCouponEnabled = validationFields?.fields?.checkout?.coupon?.enabled
@@ -92,6 +96,16 @@ const CartUI = (props: any) => {
92
96
  })
93
97
  }
94
98
 
99
+ const getIncludedTaxes = () => {
100
+ if (cart?.taxes === null) {
101
+ return cart.business.tax_type === 1 ? cart?.tax : 0
102
+ } else {
103
+ return cart?.taxes.reduce((taxIncluded: number, tax: any) => {
104
+ return taxIncluded + (tax.type === 1 ? tax.summary?.tax : 0)
105
+ }, 0)
106
+ }
107
+ }
108
+
95
109
  return (
96
110
  <CContainer>
97
111
  <BusinessItemAccordion
@@ -120,9 +134,7 @@ const CartUI = (props: any) => {
120
134
  <OSTable>
121
135
  <OText>{t('SUBTOTAL', 'Subtotal')}</OText>
122
136
  <OText>
123
- {cart.business.tax_type === 1
124
- ? parsePrice((cart?.subtotal + cart?.tax) || 0)
125
- : parsePrice(cart?.subtotal || 0)}
137
+ {parsePrice(cart?.subtotal + getIncludedTaxes())}
126
138
  </OText>
127
139
  </OSTable>
128
140
  {cart?.discount > 0 && cart?.total >= 0 && (
@@ -138,15 +150,38 @@ const CartUI = (props: any) => {
138
150
  <OText>- {parsePrice(cart?.discount || 0)}</OText>
139
151
  </OSTable>
140
152
  )}
141
- {cart.business.tax_type !== 1 && (
142
- <OSTable>
143
- <OText>
144
- {t('TAX', 'Tax')}
145
- {`(${verifyDecimals(cart?.business?.tax, parseNumber)}%)`}
146
- </OText>
147
- <OText>{parsePrice(cart?.tax || 0)}</OText>
148
- </OSTable>
149
- )}
153
+ {
154
+ cart.taxes?.length > 0 && cart.taxes.filter((tax: any) => tax.type === 2 && tax?.rate !== 0).map((tax: any) => (
155
+ <OSTable key={tax.id}>
156
+ <OSRow>
157
+ <OText numberOfLines={1} >
158
+ {tax.name || t('INHERIT_FROM_BUSINESS', 'Inherit from business')}{' '}
159
+ {`(${verifyDecimals(tax?.rate, parseNumber)}%)`}{' '}
160
+ </OText>
161
+ <TouchableOpacity onPress={() => setOpenTaxModal({ open: true, data: tax })} >
162
+ <AntIcon name='exclamationcircleo' size={18} color={theme.colors.primary} />
163
+ </TouchableOpacity>
164
+ </OSRow>
165
+ <OText>{parsePrice(tax?.summary?.tax || 0)}</OText>
166
+ </OSTable>
167
+ ))
168
+ }
169
+ {
170
+ cart?.fees?.length > 0 && cart?.fees?.filter((fee: any) => !(fee.fixed === 0 && fee.percentage === 0)).map((fee: any) => (
171
+ <OSTable key={fee?.id}>
172
+ <OSRow>
173
+ <OText numberOfLines={1}>
174
+ {fee.name || t('INHERIT_FROM_BUSINESS', 'Inherit from business')}{' '}
175
+ ({parsePrice(fee?.fixed)} + {fee?.percentage}%){' '}
176
+ </OText>
177
+ <TouchableOpacity onPress={() => setOpenTaxModal({ open: true, data: fee })} >
178
+ <AntIcon name='exclamationcircleo' size={18} color={theme.colors.primary} />
179
+ </TouchableOpacity>
180
+ </OSRow>
181
+ <OText>{parsePrice(fee?.summary?.fixed + fee?.summary?.percentage || 0)}</OText>
182
+ </OSTable>
183
+ ))
184
+ }
150
185
  {orderState?.options?.type === 1 && cart?.delivery_price > 0 && (
151
186
  <OSTable>
152
187
  <OText>{t('DELIVERY_FEE', 'Delivery Fee')}</OText>
@@ -167,15 +202,6 @@ const CartUI = (props: any) => {
167
202
  <OText>{parsePrice(cart?.driver_tip)}</OText>
168
203
  </OSTable>
169
204
  )}
170
- {cart?.service_fee > 0 && (
171
- <OSTable>
172
- <OText>
173
- {t('SERVICE_FEE', 'Service Fee')}
174
- {`(${verifyDecimals(cart?.business?.service_fee, parseNumber)}%)`}
175
- </OText>
176
- <OText>{parsePrice(cart?.service_fee)}</OText>
177
- </OSTable>
178
- )}
179
205
  {isCouponEnabled && !isCartPending && (
180
206
  <OSTable>
181
207
  <OSCoupon>
@@ -249,6 +275,13 @@ const CartUI = (props: any) => {
249
275
  setCanOpenUpselling={setCanOpenUpselling}
250
276
  />
251
277
  )}
278
+ <OModal
279
+ open={openTaxModal.open}
280
+ onClose={() => setOpenTaxModal({ open: false, data: null })}
281
+ entireModal
282
+ >
283
+ <TaxInformation data={openTaxModal.data} products={cart.products} />
284
+ </OModal>
252
285
  </CContainer>
253
286
  )
254
287
  }