ordering-ui-react-native 0.21.49-test → 0.21.49-test-v2

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 (112) hide show
  1. package/package.json +2 -3
  2. package/themes/business/index.tsx +0 -5
  3. package/themes/business/src/components/AcceptOrRejectOrder/index.tsx +9 -2
  4. package/themes/business/src/components/FloatingButton/index.tsx +34 -31
  5. package/themes/business/src/components/MapView/index.tsx +6 -2
  6. package/themes/business/src/components/MessagesOption/index.tsx +2 -1
  7. package/themes/business/src/components/OrderDetails/Delivery.tsx +11 -6
  8. package/themes/business/src/components/OrderDetails/OrderHeaderComponent.tsx +12 -0
  9. package/themes/business/src/components/OrderDetailsLogistic/index.tsx +6 -1
  10. package/themes/business/src/components/OrderSummary/index.tsx +3 -10
  11. package/themes/business/src/components/OrdersListManager/index.tsx +7 -2
  12. package/themes/business/src/components/OrdersOption/index.tsx +4 -0
  13. package/themes/business/src/components/PreviousOrders/OrderList.tsx +17 -12
  14. package/themes/business/src/components/PreviousOrders/index.tsx +77 -65
  15. package/themes/business/src/components/WebsocketStatus/index.tsx +171 -0
  16. package/themes/business/src/components/WebsocketStatus/styles.tsx +28 -0
  17. package/themes/kiosk/src/components/LoginForm/index.tsx +7 -4
  18. package/themes/original/index.tsx +6 -2
  19. package/themes/original/src/components/AddressForm/index.tsx +2 -2
  20. package/themes/original/src/components/AddressForm/styles.tsx +1 -1
  21. package/themes/original/src/components/AddressList/styles.tsx +4 -4
  22. package/themes/original/src/components/BusinessBasicInformation/index.tsx +2 -2
  23. package/themes/original/src/components/BusinessBasicInformation/styles.tsx +1 -1
  24. package/themes/original/src/components/BusinessInformation/index.tsx +0 -1
  25. package/themes/original/src/components/BusinessInformation/styles.tsx +2 -2
  26. package/themes/original/src/components/BusinessItemAccordion/index.tsx +11 -7
  27. package/themes/original/src/components/BusinessListingSearch/index.tsx +2 -3
  28. package/themes/original/src/components/BusinessListingSearch/styles.tsx +1 -1
  29. package/themes/original/src/components/BusinessPreorder/index.tsx +2 -2
  30. package/themes/original/src/components/BusinessProductsCategories/index.tsx +1 -1
  31. package/themes/original/src/components/BusinessProductsList/index.tsx +2 -2
  32. package/themes/original/src/components/BusinessProductsListing/index.tsx +12 -8
  33. package/themes/original/src/components/BusinessProductsListing/styles.tsx +2 -2
  34. package/themes/original/src/components/BusinessReviews/index.tsx +1 -1
  35. package/themes/original/src/components/BusinessesListing/Layout/Appointment/index.tsx +1 -1
  36. package/themes/original/src/components/BusinessesListing/Layout/Appointment/styles.tsx +5 -5
  37. package/themes/original/src/components/BusinessesListing/Layout/Original/FlatListBusinessListFooter.tsx +69 -0
  38. package/themes/original/src/components/BusinessesListing/Layout/Original/FlatListBusinessListHeader.tsx +406 -0
  39. package/themes/original/src/components/BusinessesListing/Layout/Original/FlatListBusinessListing.tsx +76 -0
  40. package/themes/original/src/components/BusinessesListing/Layout/Original/index.tsx +23 -403
  41. package/themes/original/src/components/BusinessesListing/Layout/Original/styles.tsx +1 -1
  42. package/themes/original/src/components/Cart/index.tsx +15 -4
  43. package/themes/original/src/components/CartContent/index.tsx +59 -38
  44. package/themes/original/src/components/CartStoresListing/styles.tsx +2 -2
  45. package/themes/original/src/components/Checkout/index.tsx +47 -9
  46. package/themes/original/src/components/Checkout/styles.tsx +17 -0
  47. package/themes/original/src/components/CitiesControl/styles.tsx +1 -1
  48. package/themes/original/src/components/DatePicker/index.tsx +17 -0
  49. package/themes/original/src/components/DatePicker/styles.tsx +20 -0
  50. package/themes/original/src/components/Favorite/index.tsx +1 -3
  51. package/themes/original/src/components/Favorite/styles.tsx +0 -2
  52. package/themes/original/src/components/FloatingButton/styles.tsx +1 -1
  53. package/themes/original/src/components/GPSButton/index.tsx +1 -1
  54. package/themes/original/src/components/GiftCard/GiftCardUI/index.tsx +8 -3
  55. package/themes/original/src/components/GiftCard/PurchaseGiftCard/index.tsx +36 -3
  56. package/themes/original/src/components/GiftCard/PurchaseGiftCard/styles.tsx +1 -1
  57. package/themes/original/src/components/GiftCard/RedeemGiftCard/index.tsx +67 -4
  58. package/themes/original/src/components/GiftCard/RedeemGiftCard/styles.tsx +1 -1
  59. package/themes/original/src/components/GiftCard/SendGiftCard/styles.tsx +1 -1
  60. package/themes/original/src/components/HighestRatedBusinesses/index.tsx +1 -1
  61. package/themes/original/src/components/HighestRatedBusinesses/styles.tsx +1 -1
  62. package/themes/original/src/components/Home/index.tsx +1 -1
  63. package/themes/original/src/components/LastOrder/index.tsx +2 -1
  64. package/themes/original/src/components/LastOrders/index.tsx +2 -1
  65. package/themes/original/src/components/Messages/styles.tsx +1 -1
  66. package/themes/original/src/components/MomentOption/index.tsx +3 -3
  67. package/themes/original/src/components/MultiCart/index.tsx +1 -1
  68. package/themes/original/src/components/MultiCheckout/index.tsx +140 -18
  69. package/themes/original/src/components/MultiOrdersDetails/index.tsx +1 -1
  70. package/themes/original/src/components/MyOrders/index.tsx +5 -5
  71. package/themes/original/src/components/NavBar/index.tsx +0 -1
  72. package/themes/original/src/components/NetworkError/styles.tsx +2 -2
  73. package/themes/original/src/components/Notifications/index.tsx +2 -4
  74. package/themes/original/src/components/Notifications/styles.tsx +0 -1
  75. package/themes/original/src/components/OrderDetails/OrderHistory.tsx +1 -1
  76. package/themes/original/src/components/OrderDetails/index.tsx +709 -664
  77. package/themes/original/src/components/OrderDetails/styles.tsx +24 -7
  78. package/themes/original/src/components/OrderProgress/index.tsx +2 -1
  79. package/themes/original/src/components/OrderProgress/styles.tsx +1 -1
  80. package/themes/original/src/components/OrderSummary/index.tsx +3 -1
  81. package/themes/original/src/components/OrdersOption/PreviousBusinessOrdered/styles.tsx +1 -1
  82. package/themes/original/src/components/OrdersOption/PreviousProductsOrdered/styles.tsx +1 -1
  83. package/themes/original/src/components/OrdersOption/index.tsx +1 -1
  84. package/themes/original/src/components/OrdersOption/styles.tsx +1 -1
  85. package/themes/original/src/components/PaymentOptions/index.tsx +3 -1
  86. package/themes/original/src/components/ProductForm/ActionButton.tsx +117 -0
  87. package/themes/original/src/components/ProductForm/ExtraOptions.tsx +56 -0
  88. package/themes/original/src/components/ProductForm/index.tsx +52 -146
  89. package/themes/original/src/components/ProductItemAccordion/index.tsx +5 -0
  90. package/themes/original/src/components/ProductOptionSubOption/index.tsx +1 -1
  91. package/themes/original/src/components/ProfessionalProfile/styles.tsx +3 -3
  92. package/themes/original/src/components/Promotions/index.tsx +2 -3
  93. package/themes/original/src/components/Promotions/styles.tsx +0 -2
  94. package/themes/original/src/components/ReviewDriver/styles.tsx +1 -1
  95. package/themes/original/src/components/ReviewOrder/styles.tsx +1 -1
  96. package/themes/original/src/components/ReviewProducts/styles.tsx +1 -1
  97. package/themes/original/src/components/ServiceForm/index.tsx +1 -1
  98. package/themes/original/src/components/ServiceForm/styles.tsx +4 -4
  99. package/themes/original/src/components/StripeElementsForm/index.tsx +1 -1
  100. package/themes/original/src/components/UpsellingProducts/UpsellingContent.tsx +170 -0
  101. package/themes/original/src/components/UpsellingProducts/UpsellingLayout.tsx +86 -0
  102. package/themes/original/src/components/UpsellingProducts/index.tsx +15 -199
  103. package/themes/original/src/components/UpsellingProducts/styles.tsx +19 -0
  104. package/themes/original/src/components/UserFormDetails/index.tsx +51 -4
  105. package/themes/original/src/components/UserProfile/index.tsx +1 -1
  106. package/themes/original/src/components/WalletTransactions/styles.tsx +1 -0
  107. package/themes/original/src/components/Wallets/index.tsx +1 -0
  108. package/themes/original/src/components/Wallets/styles.tsx +0 -1
  109. package/themes/original/src/components/shared/OModal.tsx +12 -14
  110. package/themes/original/src/layouts/Container.tsx +1 -1
  111. package/themes/business/src/components/StarPrinter/SearchPrinter.tsx +0 -106
  112. package/themes/business/src/components/StarPrinter/index.tsx +0 -235
@@ -10,7 +10,7 @@ export const NavBack = styled.TouchableOpacity`
10
10
 
11
11
 
12
12
  export const Header = styled.View`
13
- padding: 10px 40px;
13
+ padding: 10px 20px;
14
14
  flex: 1;
15
15
  `
16
16
 
@@ -24,7 +24,7 @@ export const OrderContent = styled.View`
24
24
  export const OrderBusiness = styled.View`
25
25
  position: relative;
26
26
  padding-vertical: 10px;
27
- padding-horizontal: 40px;
27
+ padding-horizontal: 20px;
28
28
  background-color: ${(props: any) => props.theme.colors.white};
29
29
  align-items: flex-start;
30
30
  `
@@ -64,7 +64,7 @@ export const SectionTitle = styled.View`
64
64
  `
65
65
 
66
66
  export const OrderCustomer = styled.View`
67
- padding: 20px 40px 10px;
67
+ padding: 20px 20px 10px;
68
68
  background-color: ${(props: any) => props.theme.colors.white};
69
69
  `
70
70
 
@@ -86,7 +86,7 @@ export const InfoBlock = styled.View`
86
86
  export const HeaderInfo = styled.View`
87
87
  flex: 1;
88
88
  background-color: ${(props: any) => props.theme.colors.backgroundGray100};
89
- padding: 20px 40px;
89
+ padding: 20px 20px;
90
90
  `
91
91
 
92
92
  export const OrderProducts = styled(OrderCustomer)``
@@ -100,7 +100,7 @@ export const Table = styled.View`
100
100
  `
101
101
 
102
102
  export const OrderBill = styled.View`
103
- padding-horizontal: 40px;
103
+ padding-horizontal: 20px;
104
104
  padding-vertical: 10px;
105
105
  flex: 1;
106
106
  background-color: ${(props: any) => props.theme.colors.white};
@@ -130,7 +130,7 @@ export const OrderAction = styled.View`
130
130
  `
131
131
 
132
132
  export const PlaceSpotWrapper = styled.View`
133
- padding-horizontal: 40px;
133
+ padding-horizontal: 20px;
134
134
  `
135
135
 
136
136
  export const ProfessionalPhoto = styled.ImageBackground`
@@ -141,4 +141,21 @@ export const ProfessionalPhoto = styled.ImageBackground`
141
141
  width: 80px;
142
142
  resize-mode: cover;
143
143
  margin-right: 10px;
144
- `;
144
+ `;
145
+
146
+ export const TopActions = styled.TouchableOpacity`
147
+ height: 60px;
148
+ justify-content: center;
149
+ min-width: 30px;
150
+ padding-right: 15px;
151
+ `;
152
+
153
+ export const TopHeader = styled.View`
154
+ width: 100%;
155
+ flex-direction: row;
156
+ align-items: center;
157
+ justify-content: space-between;
158
+ z-index: 1;
159
+ height: 60px;
160
+ min-height: 60px;
161
+ `
@@ -208,7 +208,8 @@ export const OrderProgress = (props: any) => {
208
208
  initialPage: 1,
209
209
  pageSize: 10,
210
210
  controlType: 'infinity'
211
- }
211
+ },
212
+ noGiftCardOrders: true
212
213
  }
213
214
 
214
215
  return <OrderList {...orderProgressProps} />
@@ -32,5 +32,5 @@ export const OrderInfoWrapper = styled.View`
32
32
  export const OrderProgressWrapper = styled.View`
33
33
  margin-top: 37px;
34
34
  margin-bottom: 20px;
35
- padding-horizontal: 40px;
35
+ padding-horizontal: 20px;
36
36
  `
@@ -1,4 +1,4 @@
1
- import React, { useState } from 'react';
1
+ import React, { useState, useRef } from 'react';
2
2
  import { ActivityIndicator, View } from 'react-native'
3
3
  import {
4
4
  Cart,
@@ -56,6 +56,7 @@ const OrderSummaryUI = (props: any) => {
56
56
  const [orderState] = useOrder();
57
57
  const [{ parsePrice, parseNumber }] = useUtils();
58
58
  const [validationFields] = useValidationFields();
59
+ const commentRef = useRef()
59
60
  const [openTaxModal, setOpenTaxModal] = useState<any>({ open: false, data: null, type: '' })
60
61
  const isCouponEnabled = validationFields?.fields?.checkout?.coupon?.enabled;
61
62
  const hideCartComments = !validationFields?.fields?.checkout?.comments?.enabled
@@ -341,6 +342,7 @@ const OrderSummaryUI = (props: any) => {
341
342
  marginTop: 10,
342
343
  borderRadius: 8
343
344
  }}
345
+ forwardRef={commentRef}
344
346
  multiline
345
347
  />
346
348
  {commentState?.loading && (
@@ -2,5 +2,5 @@ import styled, { css } from 'styled-components/native'
2
2
 
3
3
  export const ListWrapper = styled.View`
4
4
  background-color: ${(props: any) => props.theme.colors.backgroundLight};
5
- padding-horizontal: ${(props : any) => props.isBusinessesSearchList ? '0' : '40px'};
5
+ padding-horizontal: ${(props : any) => props.isBusinessesSearchList ? '0' : '20px'};
6
6
  `;
@@ -2,5 +2,5 @@ import styled from 'styled-components/native'
2
2
 
3
3
  export const ListWrapper = styled.View`
4
4
  background-color: ${(props: any) => props.theme.colors.backgroundLight};
5
- padding-horizontal: ${(props : any) => props.isBusinessesSearchList ? '0' : '40px'};
5
+ padding-horizontal: ${(props : any) => props.isBusinessesSearchList ? '0' : '20px'};
6
6
  `;
@@ -312,7 +312,7 @@ const OrdersOptionUI = (props: OrdersOptionParams) => {
312
312
  />
313
313
  )
314
314
  )}
315
- {loading && !hideOrders && (
315
+ {loading && !hideOrders && !preOrders && (
316
316
  <>
317
317
  {!activeOrders ? (
318
318
  <Placeholder style={{ marginTop: 30 }} Animation={Fade}>
@@ -3,7 +3,7 @@ import styled, { css } from 'styled-components/native'
3
3
  export const OptionTitle = styled.View`
4
4
  margin-top: 24px;
5
5
  ${(props : any) => props.titleContent && css`
6
- margin-left: ${() => props.isBusinessesSearchList ? '0' : '40px'};
6
+ margin-left: ${() => props.isBusinessesSearchList ? '0' : '20px'};
7
7
  `}
8
8
  `
9
9
 
@@ -11,6 +11,7 @@ import {
11
11
  useLanguage,
12
12
  ToastType,
13
13
  useToast,
14
+ useSession
14
15
  } from 'ordering-components/native';
15
16
  import { useTheme } from 'styled-components/native';
16
17
  import { PaymentOptionCash } from '../PaymentOptionCash';
@@ -78,6 +79,7 @@ const PaymentOptionsUI = (props: any) => {
78
79
 
79
80
  const theme = useTheme();
80
81
  const [, { showToast }] = useToast();
82
+ const [{ user }] = useSession()
81
83
  const { confirmApplePayPayment } = useApplePay()
82
84
 
83
85
  const getPayIcon = (method: string) => {
@@ -120,7 +122,7 @@ const PaymentOptionsUI = (props: any) => {
120
122
  const paymethodsFieldRequired = ['paypal', 'apple_pay', 'global_apple_pay']
121
123
 
122
124
  const handlePaymentMethodClick = (paymethod: any) => {
123
- if (cart?.balance > 0) {
125
+ if (cart?.balance > 0 || !!user?.guest_id) {
124
126
  if (paymethodsFieldRequired.includes(paymethod?.gateway) && requiredFields.length > 0) {
125
127
  openUserModal && openUserModal(true)
126
128
  setPaymethodClicked({
@@ -0,0 +1,117 @@
1
+ import React from 'react'
2
+ import { useSession, useOrder, useLanguage } from 'ordering-components/native'
3
+ import { useTheme } from 'styled-components/native'
4
+ import { TouchableOpacity, View } from 'react-native'
5
+ import { OButton, OText } from '../shared';
6
+ import { Placeholder, PlaceholderLine, Fade } from 'rn-placeholder';
7
+
8
+ export const ActionButton = (props : any) => {
9
+ const {
10
+ navigation,
11
+ isHaveWeight,
12
+ isSoldOut,
13
+ maxProductQuantity,
14
+ productCart,
15
+ handleSaveProduct,
16
+ editMode,
17
+ product,
18
+ errors,
19
+ productAddedToCartLength,
20
+ handleRedirectLogin,
21
+ guestCheckoutEnabled,
22
+ orderTypeEnabled,
23
+ handleUpdateGuest,
24
+ actionStatus
25
+ } = props
26
+ const [,t] = useLanguage()
27
+ const [{ auth }] = useSession()
28
+ const [orderState] = useOrder()
29
+ const theme = useTheme()
30
+
31
+ const saveErrors =
32
+ orderState.loading ||
33
+ maxProductQuantity === 0 ||
34
+ Object.keys(errors)?.length > 0;
35
+
36
+ return (
37
+ <View
38
+ style={{
39
+ width: isHaveWeight ? '100%' : ((isSoldOut || maxProductQuantity <= 0) ? '60%' : '40%'),
40
+ }}>
41
+ {((productCart &&
42
+ auth &&
43
+ orderState.options?.address_id) || (isSoldOut || maxProductQuantity <= 0)) && (
44
+ <OButton
45
+ onClick={() => handleSaveProduct()}
46
+ imgRightSrc=""
47
+ text={`${orderState.loading
48
+ ? t('LOADING', 'Loading')
49
+ : (isSoldOut || maxProductQuantity <= 0)
50
+ ? t('SOLD_OUT', 'Sold out')
51
+ : editMode
52
+ ? t('UPDATE', 'Update')
53
+ : t('ADD', 'Add')
54
+ }`}
55
+ isDisabled={isSoldOut || maxProductQuantity <= 0 || (product?.minimum_per_order && ((productCart?.quantity + productAddedToCartLength) < product?.minimum_per_order)) || (product?.maximum_per_order && ((productCart?.quantity + productAddedToCartLength) > product?.maximum_per_order))}
56
+ textStyle={{
57
+ color: saveErrors || isSoldOut || maxProductQuantity <= 0 ? theme.colors.primary : theme.colors.white,
58
+ fontSize: orderState.loading || editMode ? 10 : 14
59
+ }}
60
+ style={{
61
+ backgroundColor: saveErrors || isSoldOut || maxProductQuantity <= 0 || (product?.minimum_per_order && ((productCart?.quantity + productAddedToCartLength) < product?.minimum_per_order)) || (product?.maximum_per_order && ((productCart?.quantity + productAddedToCartLength) > product?.maximum_per_order)) ? theme.colors.lightGray : theme.colors.primary,
62
+ borderColor: saveErrors || isSoldOut || maxProductQuantity <= 0 || (product?.minimum_per_order && ((productCart?.quantity + productAddedToCartLength) < product?.minimum_per_order)) || (product?.maximum_per_order && ((productCart?.quantity + productAddedToCartLength) > product?.maximum_per_order)) ? theme.colors.white : theme.colors.primary,
63
+ opacity: saveErrors || isSoldOut || maxProductQuantity <= 0 ? 0.3 : 1,
64
+ borderRadius: 7.6,
65
+ height: 44,
66
+ shadowOpacity: 0,
67
+ borderWidth: 1,
68
+ marginTop: isHaveWeight ? 10 : 0
69
+ }}
70
+ />
71
+ )}
72
+ {auth &&
73
+ !orderState.options?.address_id &&
74
+ (orderState.loading ? (
75
+ <OButton
76
+ isDisabled
77
+ text={t('LOADING', 'Loading')}
78
+ imgRightSrc=""
79
+ textStyle={{ fontSize: 10 }}
80
+ />
81
+ ) : (
82
+ <OButton onClick={navigation.navigate('AddressList')} />
83
+ ))}
84
+ {!auth && (
85
+ <OButton
86
+ isDisabled={isSoldOut || maxProductQuantity <= 0}
87
+ onClick={() => handleRedirectLogin()}
88
+ text={
89
+ isSoldOut || maxProductQuantity <= 0
90
+ ? t('SOLD_OUT', 'Sold out')
91
+ : t('LOGIN_SIGNUP', 'Login / Sign Up')
92
+ }
93
+ imgRightSrc=""
94
+ textStyle={{ color: theme.colors.primary, fontSize: 13, textAlign: 'center' }}
95
+ style={{
96
+ height: 42,
97
+ borderColor: theme.colors.primary,
98
+ backgroundColor: theme.colors.white,
99
+ paddingLeft: 0,
100
+ paddingRight: 0
101
+ }}
102
+ />
103
+ )}
104
+ {!auth && guestCheckoutEnabled && orderTypeEnabled && (
105
+ <TouchableOpacity style={{ marginTop: 10 }} onPress={handleUpdateGuest}>
106
+ {actionStatus?.loading ? (
107
+ <Placeholder Animation={Fade}>
108
+ <PlaceholderLine height={20} />
109
+ </Placeholder>
110
+ ) : (
111
+ <OText color={theme.colors.primary} size={13} style={{ textAlign: 'center' }}>{t('AS_GUEST_USER', 'As guest user')}</OText>
112
+ )}
113
+ </TouchableOpacity>
114
+ )}
115
+ </View>
116
+ )
117
+ }
@@ -0,0 +1,56 @@
1
+ import React from 'react'
2
+ import { TouchableOpacity } from 'react-native';
3
+ import { useTheme } from 'styled-components/native';
4
+ import { OText } from '../shared';
5
+
6
+ export const ExtraOptions = (props : any) => {
7
+ const {
8
+ options,
9
+ setSelectedOpt,
10
+ scrollViewRef,
11
+ optionLayout,
12
+ editionsLayoutY,
13
+ styles,
14
+ selOpt
15
+ } = props
16
+
17
+ const theme = useTheme()
18
+
19
+ return (
20
+ <>
21
+ {options.map(({ id, name, respect_to, suboptions }: any) => (
22
+ <React.Fragment key={`cont_key_${id}`}>
23
+ {respect_to == null && suboptions?.length > 0 && (
24
+ <TouchableOpacity
25
+ key={`eopt_key_${id}`}
26
+ onPress={() => {
27
+ setSelectedOpt(id)
28
+ scrollViewRef?.current?.scrollTo && scrollViewRef.current.scrollTo({
29
+ y: optionLayout[`id:${id}`]?.y + editionsLayoutY - 50,
30
+ animated: true
31
+ })
32
+ }}
33
+ style={[
34
+ styles.extraItem,
35
+ {
36
+ borderBottomColor:
37
+ selOpt == id ? theme.colors.textNormal : theme.colors.backgroundPage,
38
+ },
39
+ ]}>
40
+ <OText
41
+ color={
42
+ selOpt == id ? theme.colors.textNormal : theme.colors.textSecondary
43
+ }
44
+ size={12}
45
+ weight={selOpt == id ? '600' : 'normal'}
46
+ style={{ maxWidth: 150 }}
47
+ numberOfLines={1}>
48
+ {name}
49
+ </OText>
50
+ </TouchableOpacity>
51
+ )}
52
+ </React.Fragment>
53
+ ))}
54
+ </>
55
+ )
56
+ }
@@ -56,8 +56,12 @@ import { NotFoundSource } from '../NotFoundSource';
56
56
  import { Placeholder, PlaceholderLine, Fade } from 'rn-placeholder';
57
57
  import NavBar from '../NavBar';
58
58
  import { orderTypeList } from '../../utils';
59
+ import { ActionButton } from './ActionButton'
60
+ import { ExtraOptions } from './ExtraOptions'
59
61
  const windowWidth = Dimensions.get('window').width;
60
62
 
63
+
64
+
61
65
  export const ProductOptionsUI = (props: any) => {
62
66
  const {
63
67
  navigation,
@@ -79,11 +83,10 @@ export const ProductOptionsUI = (props: any) => {
79
83
  actionStatus,
80
84
  handleCreateGuestUser
81
85
  } = props;
82
-
83
86
  const theme = useTheme();
84
87
  const [, { showToast }] = useToast()
85
88
  const [events] = useEvent()
86
-
89
+ const commentRef = useRef()
87
90
  const isChewLayout = theme?.header?.components?.layout?.type?.toLowerCase() === 'chew'
88
91
 
89
92
  const styles = StyleSheet.create({
@@ -138,8 +141,7 @@ export const ProductOptionsUI = (props: any) => {
138
141
  slide1: {
139
142
  flex: 1,
140
143
  alignItems: 'center',
141
- width: '100%',
142
- marginLeft: 32
144
+ width: '100%'
143
145
  },
144
146
  mainSwiper: {
145
147
  height: 258,
@@ -178,7 +180,7 @@ export const ProductOptionsUI = (props: any) => {
178
180
  marginTop: 10
179
181
  },
180
182
  wrapperNavbar: {
181
- paddingHorizontal: 30,
183
+ paddingHorizontal: 20,
182
184
  paddingTop: 0,
183
185
  }
184
186
  });
@@ -209,7 +211,7 @@ export const ProductOptionsUI = (props: any) => {
209
211
  const [editionsLayoutY, setEditionsLayoutY] = useState(null)
210
212
  const [viewedProduct, setViewedProduct] = useState<any>(null)
211
213
  const [showTitle, setShowTitle] = useState(false)
212
-
214
+ const productOptionsMounted = useRef(false)
213
215
  const guestCheckoutEnabled = configs?.guest_checkout_enabled?.value === '1'
214
216
  const orderTypeEnabled = !orderTypeList[orderState?.options?.type - 1] || configs?.allowed_order_types_guest_checkout?.value?.includes(orderTypeList[orderState?.options?.type - 1])
215
217
 
@@ -321,58 +323,18 @@ export const ProductOptionsUI = (props: any) => {
321
323
  const guestToken = uuid.v4()
322
324
  if (guestToken) handleCreateGuestUser({ guest_token: guestToken })
323
325
  }
326
+
327
+ let _optionLayout : any = {}
324
328
 
325
- const handleOnLayout = (event: any, optionId: any) => {
326
- const _optionLayout = { ...optionLayout }
329
+ const handleOnLayout = (event: any, optionId: any, lastMounts: boolean) => {
330
+ _optionLayout = { ..._optionLayout }
327
331
  const optionKey = 'id:' + optionId
328
332
  _optionLayout[optionKey] = { y: event.nativeEvent.layout?.y }
329
- setOptionLayout(_optionLayout)
333
+ if (lastMounts) {
334
+ setOptionLayout(_optionLayout)
335
+ }
330
336
  }
331
337
 
332
- const saveErrors =
333
- orderState.loading ||
334
- maxProductQuantity === 0 ||
335
- Object.keys(errors)?.length > 0;
336
-
337
-
338
- const ExtraOptions = ({ eID, options }: any) => (
339
- <>
340
- {options.map(({ id, name, respect_to, suboptions }: any) => (
341
- <React.Fragment key={`cont_key_${id}`}>
342
- {respect_to == null && suboptions?.length > 0 && (
343
- <TouchableOpacity
344
- key={`eopt_key_${id}`}
345
- onPress={() => {
346
- setSelectedOpt(id)
347
- scrollViewRef?.current?.scrollTo && scrollViewRef.current.scrollTo({
348
- y: optionLayout[`id:${id}`]?.y + editionsLayoutY - 50,
349
- animated: true
350
- })
351
- }}
352
- style={[
353
- styles.extraItem,
354
- {
355
- borderBottomColor:
356
- selOpt == id ? theme.colors.textNormal : theme.colors.backgroundPage,
357
- },
358
- ]}>
359
- <OText
360
- color={
361
- selOpt == id ? theme.colors.textNormal : theme.colors.textSecondary
362
- }
363
- size={12}
364
- weight={selOpt == id ? '600' : 'normal'}
365
- style={{ maxWidth: 150 }}
366
- numberOfLines={1}>
367
- {name}
368
- </OText>
369
- </TouchableOpacity>
370
- )}
371
- </React.Fragment>
372
- ))}
373
- </>
374
- );
375
-
376
338
  const handleScroll = ({ nativeEvent: { contentOffset } }: any) => {
377
339
  setShowTitle(contentOffset.y > 30)
378
340
  }
@@ -432,90 +394,6 @@ export const ProductOptionsUI = (props: any) => {
432
394
  }
433
395
  }, [product])
434
396
 
435
- const ActionButton = () => {
436
- return (
437
- <View
438
- style={{
439
- width: isHaveWeight ? '100%' : ((isSoldOut || maxProductQuantity <= 0) ? '60%' : '40%'),
440
- }}>
441
- {((productCart &&
442
- auth &&
443
- orderState.options?.address_id) || (isSoldOut || maxProductQuantity <= 0)) && (
444
- <OButton
445
- onClick={() => handleSaveProduct()}
446
- imgRightSrc=""
447
- text={`${orderState.loading
448
- ? t('LOADING', 'Loading')
449
- : (isSoldOut || maxProductQuantity <= 0)
450
- ? t('SOLD_OUT', 'Sold out')
451
- : editMode
452
- ? t('UPDATE', 'Update')
453
- : t('ADD', 'Add')
454
- }`}
455
- isDisabled={isSoldOut || maxProductQuantity <= 0 || (product?.minimum_per_order && ((productCart?.quantity + productAddedToCartLength) < product?.minimum_per_order)) || (product?.maximum_per_order && ((productCart?.quantity + productAddedToCartLength) > product?.maximum_per_order))}
456
- textStyle={{
457
- color: saveErrors || isSoldOut || maxProductQuantity <= 0 ? theme.colors.primary : theme.colors.white,
458
- fontSize: orderState.loading || editMode ? 10 : 14
459
- }}
460
- style={{
461
- backgroundColor: saveErrors || isSoldOut || maxProductQuantity <= 0 || (product?.minimum_per_order && ((productCart?.quantity + productAddedToCartLength) < product?.minimum_per_order)) || (product?.maximum_per_order && ((productCart?.quantity + productAddedToCartLength) > product?.maximum_per_order)) ? theme.colors.lightGray : theme.colors.primary,
462
- borderColor: saveErrors || isSoldOut || maxProductQuantity <= 0 || (product?.minimum_per_order && ((productCart?.quantity + productAddedToCartLength) < product?.minimum_per_order)) || (product?.maximum_per_order && ((productCart?.quantity + productAddedToCartLength) > product?.maximum_per_order)) ? theme.colors.white : theme.colors.primary,
463
- opacity: saveErrors || isSoldOut || maxProductQuantity <= 0 ? 0.3 : 1,
464
- borderRadius: 7.6,
465
- height: 44,
466
- shadowOpacity: 0,
467
- borderWidth: 1,
468
- marginTop: isHaveWeight ? 10 : 0
469
- }}
470
- />
471
- )}
472
- {auth &&
473
- !orderState.options?.address_id &&
474
- (orderState.loading ? (
475
- <OButton
476
- isDisabled
477
- text={t('LOADING', 'Loading')}
478
- imgRightSrc=""
479
- textStyle={{ fontSize: 10 }}
480
- />
481
- ) : (
482
- <OButton onClick={navigation.navigate('AddressList')} />
483
- ))}
484
- {!auth && (
485
- <OButton
486
- isDisabled={isSoldOut || maxProductQuantity <= 0}
487
- onClick={() => handleRedirectLogin()}
488
- text={
489
- isSoldOut || maxProductQuantity <= 0
490
- ? t('SOLD_OUT', 'Sold out')
491
- : t('LOGIN_SIGNUP', 'Login / Sign Up')
492
- }
493
- imgRightSrc=""
494
- textStyle={{ color: theme.colors.primary, fontSize: 13, textAlign: 'center' }}
495
- style={{
496
- height: 42,
497
- borderColor: theme.colors.primary,
498
- backgroundColor: theme.colors.white,
499
- paddingLeft: 0,
500
- paddingRight: 0
501
- }}
502
- />
503
- )}
504
- {!auth && guestCheckoutEnabled && orderTypeEnabled && (
505
- <TouchableOpacity style={{ marginTop: 10 }} onPress={handleUpdateGuest}>
506
- {actionStatus?.loading ? (
507
- <Placeholder Animation={Fade}>
508
- <PlaceholderLine width={60} height={20} />
509
- </Placeholder>
510
- ) : (
511
- <OText color={theme.colors.primary} size={13} style={{ textAlign: 'center' }}>{t('AS_GUEST_USER', 'As guest user')}</OText>
512
- )}
513
- </TouchableOpacity>
514
- )}
515
- </View>
516
- )
517
- }
518
-
519
397
  useEffect(() => {
520
398
  const keyboardDidShowListener = Keyboard.addListener('keyboardDidShow', () => {
521
399
  scrollViewRef.current.scrollToEnd({ animated: true })
@@ -531,6 +409,33 @@ export const ProductOptionsUI = (props: any) => {
531
409
  events.emit('product_viewed', product)
532
410
  }, [product?.id, viewedProduct])
533
411
 
412
+ const actionButtonProps = {
413
+ navigation,
414
+ isHaveWeight,
415
+ isSoldOut,
416
+ maxProductQuantity,
417
+ productCart,
418
+ handleSaveProduct,
419
+ editMode,
420
+ product,
421
+ errors,
422
+ productAddedToCartLength,
423
+ handleRedirectLogin,
424
+ guestCheckoutEnabled,
425
+ orderTypeEnabled,
426
+ handleUpdateGuest,
427
+ actionStatus
428
+ }
429
+
430
+ const extraOptionsProps = {
431
+ setSelectedOpt,
432
+ scrollViewRef,
433
+ optionLayout,
434
+ editionsLayoutY,
435
+ styles,
436
+ selOpt
437
+ }
438
+
534
439
  return (
535
440
  <SafeAreaView style={{ flex: 1 }}>
536
441
  <View style={styles.wrapperNavbar}>
@@ -636,7 +541,7 @@ export const ProductOptionsUI = (props: any) => {
636
541
  <ScrollView
637
542
  horizontal
638
543
  contentContainerStyle={{
639
- paddingHorizontal: 30,
544
+ paddingHorizontal: 20,
640
545
  paddingVertical: 15
641
546
  }}
642
547
  >
@@ -689,7 +594,7 @@ export const ProductOptionsUI = (props: any) => {
689
594
  )}
690
595
  </WrapHeader>
691
596
  <ProductSummary
692
- ph={isChewLayout ? 20 : 30}
597
+ ph={20}
693
598
  onLayout={(event: any) => setSummaryRefHeight(event.nativeEvent.layout?.height)}
694
599
  >
695
600
  <ProductTitle>
@@ -823,7 +728,7 @@ export const ProductOptionsUI = (props: any) => {
823
728
  </TouchableOpacity>
824
729
  )}
825
730
  {product?.extras?.map((extra: any) =>
826
- <ExtraOptions key={extra.id} options={extra.options} />
731
+ <ExtraOptions key={extra.id} options={extra.options} {...extraOptionsProps} />
827
732
  )}
828
733
  </ExtraOptionWrap>
829
734
  )}
@@ -867,14 +772,14 @@ export const ProductOptionsUI = (props: any) => {
867
772
  </>
868
773
  ) : (
869
774
  <ProductEditions
870
- style={{ paddingHorizontal: isChewLayout ? 20 : 30 }}
775
+ style={{ paddingHorizontal: 20 }}
871
776
  onLayout={(event: any) => {
872
777
  setEditionsLayoutY(event.nativeEvent.layout?.y)
873
778
  }}
874
779
  >
875
780
  <>
876
781
  {product?.ingredients?.length > 0 && (
877
- <View style={styles.optionContainer} onLayout={(event: any) => handleOnLayout(event, 0)}>
782
+ <View style={styles.optionContainer} onLayout={(event: any) => handleOnLayout(event, 0, true)}>
878
783
  <SectionTitle>
879
784
  <OText size={16}>
880
785
  {t('INGREDIENTS', 'Ingredients')}
@@ -896,13 +801,13 @@ export const ProductOptionsUI = (props: any) => {
896
801
  </View>
897
802
  )}
898
803
  {product?.extras?.sort((a: any, b: any) => a.rank - b.rank).map((extra: any) =>
899
- extra.options?.sort((a: any, b: any) => a.rank - b.rank).map((option: any) => {
804
+ extra.options?.sort((a: any, b: any) => a.rank - b.rank).map((option: any, i: number) => {
900
805
  const currentState =
901
806
  productCart.options[`id:${option.id}`] || {};
902
807
  return (
903
808
  <React.Fragment key={`popt_${option.id}`}>
904
809
  {showOption(option) && (
905
- <View style={styles.optionContainer} onLayout={(event: any) => handleOnLayout(event, option?.id)}>
810
+ <View style={styles.optionContainer} onLayout={(event: any) => handleOnLayout(event, option?.id, extra.options?.length <= i + 2)}>
906
811
  <ProductOption
907
812
  option={option}
908
813
  currentState={currentState}
@@ -968,6 +873,7 @@ export const ProductOptionsUI = (props: any) => {
968
873
  !(productCart && !isSoldOut && maxProductQuantity)
969
874
  }
970
875
  style={styles.comment}
876
+ forwardRef={commentRef}
971
877
  />
972
878
  </ProductComment>
973
879
  )}
@@ -1087,9 +993,9 @@ export const ProductOptionsUI = (props: any) => {
1087
993
  )}
1088
994
  </>
1089
995
  )}
1090
- {!isHaveWeight && <ActionButton />}
996
+ {!isHaveWeight && <ActionButton {...actionButtonProps} />}
1091
997
  </View>
1092
- {isHaveWeight && <ActionButton />}
998
+ {isHaveWeight && <ActionButton {...actionButtonProps} />}
1093
999
  </ProductActions>
1094
1000
  )}
1095
1001
  </SafeAreaView>
@@ -215,6 +215,11 @@ export const ProductItemAccordion = (props: ProductItemAccordionParams) => {
215
215
  style={pickerStyle}
216
216
  useNativeAndroidPickerStyle={false}
217
217
  placeholder={{}}
218
+ touchableWrapperProps={{
219
+ style: {
220
+ width: 40,
221
+ }
222
+ }}
218
223
  Icon={() => <View style={pickerStyle.icon}><OIcon src={theme.images.general.arrow_down} color={theme.colors.textNormal} width={8} /></View>}
219
224
  disabled={orderState.loading}
220
225
  />