ordering-ui-react-native 0.16.60 → 0.16.61-release

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 (199) hide show
  1. package/package.json +6 -5
  2. package/src/DeliveryApp.tsx +43 -1
  3. package/src/components/ActiveOrders/index.tsx +61 -63
  4. package/src/components/ActiveOrders/styles.tsx +8 -14
  5. package/src/components/BusinessInformation/index.tsx +19 -4
  6. package/src/components/BusinessInformation/styles.tsx +2 -2
  7. package/src/components/BusinessProductsList/index.tsx +10 -10
  8. package/src/components/BusinessesListing/index.tsx +1 -1
  9. package/src/components/Checkout/index.tsx +2 -1
  10. package/src/components/LanguageSelector/index.tsx +21 -16
  11. package/src/components/Messages/index.tsx +2 -2
  12. package/src/components/NotificationSetting/index.tsx +85 -0
  13. package/src/components/OrdersOption/index.tsx +54 -56
  14. package/src/components/PaymentOptions/index.tsx +298 -345
  15. package/src/components/PaymentOptionsWebView/index.tsx +119 -120
  16. package/src/components/SingleProductReview/index.tsx +7 -4
  17. package/src/components/StripeElementsForm/index.tsx +25 -16
  18. package/src/components/VerifyPhone/styles.tsx +1 -2
  19. package/src/components/shared/OBottomPopup.tsx +6 -2
  20. package/src/components/shared/OToast.tsx +4 -4
  21. package/src/index.tsx +2 -0
  22. package/src/types/@fatnlazycat/react-native-recaptcha-v3/index.d.ts +1 -0
  23. package/src/utils/index.tsx +2 -1
  24. package/themes/business/src/components/AcceptOrRejectOrder/index.tsx +260 -238
  25. package/themes/business/src/components/AcceptOrRejectOrder/styles.tsx +6 -4
  26. package/themes/business/src/components/BusinessController/index.tsx +2 -2
  27. package/themes/business/src/components/Chat/index.tsx +40 -32
  28. package/themes/business/src/components/DriverMap/index.tsx +7 -5
  29. package/themes/business/src/components/LoginForm/index.tsx +111 -74
  30. package/themes/business/src/components/MapView/index.tsx +12 -1
  31. package/themes/business/src/components/MessagesOption/index.tsx +11 -1
  32. package/themes/business/src/components/NewOrderNotification/index.tsx +31 -41
  33. package/themes/business/src/components/OrderDetails/OrderContentComponent.tsx +70 -43
  34. package/themes/business/src/components/OrderDetails/OrderHeaderComponent.tsx +3 -3
  35. package/themes/business/src/components/OrdersListManager/index.tsx +10 -3
  36. package/themes/business/src/components/OrdersOption/index.tsx +76 -77
  37. package/themes/business/src/components/OrdersOption/styles.tsx +5 -1
  38. package/themes/business/src/components/OrdersOptionBusiness/index.tsx +15 -1
  39. package/themes/business/src/components/OrdersOptionCity/index.tsx +15 -1
  40. package/themes/business/src/components/OrdersOptionDate/index.tsx +19 -6
  41. package/themes/business/src/components/OrdersOptionDelivery/index.tsx +15 -1
  42. package/themes/business/src/components/OrdersOptionDriver/index.tsx +15 -1
  43. package/themes/business/src/components/OrdersOptionPaymethod/index.tsx +15 -1
  44. package/themes/business/src/components/OrdersOptionStatus/index.tsx +10 -1
  45. package/themes/business/src/components/PreviousMessages/index.tsx +17 -18
  46. package/themes/business/src/components/PreviousOrders/OrderItem.tsx +250 -0
  47. package/themes/business/src/components/PreviousOrders/OrdersGroupedItem.tsx +115 -0
  48. package/themes/business/src/components/PreviousOrders/index.tsx +440 -245
  49. package/themes/business/src/components/PreviousOrders/styles.tsx +31 -3
  50. package/themes/business/src/components/ProductItemAccordion/index.tsx +3 -2
  51. package/themes/business/src/components/ReviewCustomer/index.tsx +39 -15
  52. package/themes/business/src/components/shared/ODropDown.tsx +42 -8
  53. package/themes/business/src/components/shared/ODropDownCalendar.tsx +36 -7
  54. package/themes/business/src/components/shared/OLink.tsx +33 -13
  55. package/themes/business/src/components/shared/OText.tsx +8 -2
  56. package/themes/business/src/types/index.tsx +24 -11
  57. package/themes/business/src/utils/index.tsx +10 -0
  58. package/themes/doordash/src/components/BusinessesListing/index.tsx +1 -1
  59. package/themes/doordash/src/components/LoginForm/index.tsx +1 -2
  60. package/themes/instacart/src/components/BusinessesListing/index.tsx +1 -1
  61. package/themes/kiosk/src/components/BusinessesListing/index.tsx +2 -1
  62. package/themes/kiosk/src/components/Checkout/index.tsx +6 -0
  63. package/themes/kiosk/src/components/LoginForm/index.tsx +121 -10
  64. package/themes/kiosk/src/components/LoginForm/styles.tsx +5 -0
  65. package/themes/kiosk/src/components/NavBar/index.tsx +14 -14
  66. package/themes/kiosk/src/components/OptionCard/index.tsx +1 -1
  67. package/themes/kiosk/src/components/OrderTypeCardSelector/index.tsx +8 -10
  68. package/themes/kiosk/src/components/ProductForm/index.tsx +1 -14
  69. package/themes/kiosk/src/components/shared/OButton.tsx +5 -18
  70. package/themes/kiosk/src/types/index.d.ts +2 -0
  71. package/themes/original/index.tsx +8 -0
  72. package/themes/original/src/components/AddressDetails/index.tsx +10 -8
  73. package/themes/original/src/components/AddressForm/index.tsx +153 -137
  74. package/themes/original/src/components/AddressList/index.tsx +1 -1
  75. package/themes/original/src/components/AppleLogin/index.tsx +4 -4
  76. package/themes/original/src/components/BusinessBasicInformation/index.tsx +53 -37
  77. package/themes/original/src/components/BusinessController/index.tsx +112 -48
  78. package/themes/original/src/components/BusinessController/styles.tsx +14 -9
  79. package/themes/original/src/components/BusinessInformation/index.tsx +10 -31
  80. package/themes/original/src/components/BusinessItemAccordion/index.tsx +12 -6
  81. package/themes/original/src/components/BusinessListingSearch/BusinessControllerSkeletons/index.tsx +57 -0
  82. package/themes/original/src/components/BusinessListingSearch/MaxSectionItem/index.tsx +59 -0
  83. package/themes/original/src/components/BusinessListingSearch/MaxSectionItem/styles.tsx +13 -0
  84. package/themes/original/src/components/BusinessListingSearch/index.tsx +87 -142
  85. package/themes/original/src/components/BusinessListingSearch/styles.tsx +10 -12
  86. package/themes/original/src/components/BusinessProductsList/SubcategoriesComponent/index.tsx +87 -0
  87. package/themes/original/src/components/BusinessProductsList/SubcategoriesComponent/styles.tsx +12 -0
  88. package/themes/original/src/components/BusinessProductsList/index.tsx +59 -61
  89. package/themes/original/src/components/BusinessProductsList/styles.tsx +0 -3
  90. package/themes/original/src/components/BusinessProductsListing/index.tsx +177 -93
  91. package/themes/original/src/components/BusinessProductsListing/styles.tsx +14 -12
  92. package/themes/original/src/components/BusinessTypeFilter/index.tsx +3 -2
  93. package/themes/original/src/components/BusinessesListing/Layout/Appointment/index.tsx +2 -1
  94. package/themes/original/src/components/BusinessesListing/Layout/Original/index.tsx +112 -107
  95. package/themes/original/src/components/BusinessesListing/Layout/Original/styles.tsx +1 -9
  96. package/themes/original/src/components/BusinessesListing/index.tsx +16 -9
  97. package/themes/original/src/components/Cart/index.tsx +77 -24
  98. package/themes/original/src/components/Cart/styles.tsx +4 -0
  99. package/themes/original/src/components/CartContent/index.tsx +77 -18
  100. package/themes/original/src/components/CartContent/styles.tsx +11 -1
  101. package/themes/original/src/components/Checkout/index.tsx +115 -118
  102. package/themes/original/src/components/Checkout/styles.tsx +4 -3
  103. package/themes/original/src/components/CitiesControl/index.tsx +89 -0
  104. package/themes/original/src/components/CitiesControl/styles.tsx +17 -0
  105. package/themes/original/src/components/DriverTips/index.tsx +4 -4
  106. package/themes/original/src/components/DriverTips/styles.tsx +2 -1
  107. package/themes/original/src/components/FavoriteList/index.tsx +69 -45
  108. package/themes/original/src/components/FloatingButton/index.tsx +0 -1
  109. package/themes/original/src/components/FloatingButton/styles.tsx +1 -1
  110. package/themes/original/src/components/GPSButton/index.tsx +20 -19
  111. package/themes/original/src/components/GPSButton/styles.ts +3 -3
  112. package/themes/original/src/components/GoogleMap/index.tsx +10 -1
  113. package/themes/original/src/components/HelpAccountAndPayment/index.tsx +25 -10
  114. package/themes/original/src/components/HelpAccountAndPayment/styles.tsx +4 -0
  115. package/themes/original/src/components/HelpGuide/index.tsx +9 -8
  116. package/themes/original/src/components/HelpOrder/index.tsx +9 -8
  117. package/themes/original/src/components/LanguageSelector/index.tsx +19 -14
  118. package/themes/original/src/components/LoginForm/Otp/index.tsx +89 -73
  119. package/themes/original/src/components/LoginForm/Otp/styles.tsx +0 -1
  120. package/themes/original/src/components/LoginForm/index.tsx +98 -41
  121. package/themes/original/src/components/LottieAnimation/index.tsx +69 -0
  122. package/themes/original/src/components/Messages/index.tsx +35 -20
  123. package/themes/original/src/components/MomentOption/index.tsx +8 -6
  124. package/themes/original/src/components/MultiCart/index.tsx +50 -0
  125. package/themes/original/src/components/MultiCartsPaymethodsAndWallets/index.tsx +92 -93
  126. package/themes/original/src/components/MultiCheckout/index.tsx +96 -71
  127. package/themes/original/src/components/MultiOrdersDetails/index.tsx +34 -16
  128. package/themes/original/src/components/MyOrders/index.tsx +89 -25
  129. package/themes/original/src/components/NavBar/index.tsx +11 -5
  130. package/themes/original/src/components/NetworkError/index.tsx +5 -3
  131. package/themes/original/src/components/NotFoundSource/index.tsx +2 -1
  132. package/themes/original/src/components/Notifications/index.tsx +148 -0
  133. package/themes/original/src/components/Notifications/styles.tsx +20 -0
  134. package/themes/original/src/components/OrderDetails/index.tsx +114 -15
  135. package/themes/original/src/components/OrderDetails/styles.tsx +15 -2
  136. package/themes/original/src/components/OrderItAgain/index.tsx +75 -0
  137. package/themes/original/src/components/OrderItAgain/styles.tsx +10 -0
  138. package/themes/original/src/components/OrderProgress/index.tsx +77 -66
  139. package/themes/original/src/components/OrderProgress/styles.tsx +5 -0
  140. package/themes/original/src/components/OrderSummary/index.tsx +2 -35
  141. package/themes/original/src/components/OrderTypeSelector/index.tsx +12 -5
  142. package/themes/original/src/components/OrdersOption/PreviousBusinessOrdered/index.tsx +94 -98
  143. package/themes/original/src/components/OrdersOption/PreviousProductsOrdered/index.tsx +3 -0
  144. package/themes/original/src/components/OrdersOption/index.tsx +95 -55
  145. package/themes/original/src/components/PaymentOptionStripe/styles.tsx +1 -1
  146. package/themes/original/src/components/PaymentOptionWallet/index.tsx +56 -56
  147. package/themes/original/src/components/PaymentOptions/index.tsx +1 -2
  148. package/themes/original/src/components/PhoneInputNumber/index.tsx +1 -1
  149. package/themes/original/src/components/PlaceSpot/index.tsx +249 -47
  150. package/themes/original/src/components/PlaceSpot/styles.tsx +0 -2
  151. package/themes/original/src/components/PreviousOrders/index.tsx +3 -2
  152. package/themes/original/src/components/ProductForm/index.tsx +379 -396
  153. package/themes/original/src/components/ProductForm/styles.tsx +7 -12
  154. package/themes/original/src/components/ProductItemAccordion/index.tsx +199 -128
  155. package/themes/original/src/components/ProductOption/index.tsx +1 -1
  156. package/themes/original/src/components/ProductOptionSubOption/index.tsx +16 -8
  157. package/themes/original/src/components/ProductOptionSubOption/styles.tsx +0 -1
  158. package/themes/original/src/components/ProfessionalFilter/index.tsx +2 -1
  159. package/themes/original/src/components/ProfessionalProfile/index.tsx +19 -8
  160. package/themes/original/src/components/Promotions/index.tsx +232 -219
  161. package/themes/original/src/components/Promotions/styles.tsx +7 -2
  162. package/themes/original/src/components/ReviewDriver/index.tsx +3 -3
  163. package/themes/original/src/components/ReviewOrder/index.tsx +43 -11
  164. package/themes/original/src/components/ReviewOrder/styles.tsx +7 -0
  165. package/themes/original/src/components/ReviewProducts/index.tsx +8 -5
  166. package/themes/original/src/components/ReviewTrigger/index.tsx +27 -9
  167. package/themes/original/src/components/ReviewTrigger/styles.tsx +8 -1
  168. package/themes/original/src/components/ScheduleAccordion/index.tsx +68 -0
  169. package/themes/original/src/components/ScheduleAccordion/styles.tsx +14 -0
  170. package/themes/original/src/components/ServiceForm/index.tsx +328 -264
  171. package/themes/original/src/components/SignupForm/index.tsx +134 -89
  172. package/themes/original/src/components/SingleOrderCard/index.tsx +240 -130
  173. package/themes/original/src/components/SingleOrderCard/styles.tsx +10 -8
  174. package/themes/original/src/components/SingleProductCard/index.tsx +116 -72
  175. package/themes/original/src/components/SingleProductCard/styles.tsx +2 -9
  176. package/themes/original/src/components/SingleProductReview/index.tsx +38 -5
  177. package/themes/original/src/components/SingleProductReview/styles.tsx +12 -0
  178. package/themes/original/src/components/StripeCardsList/index.tsx +1 -1
  179. package/themes/original/src/components/StripeElementsForm/index.tsx +13 -2
  180. package/themes/original/src/components/UpsellingProducts/index.tsx +244 -215
  181. package/themes/original/src/components/UpsellingProducts/styles.tsx +12 -1
  182. package/themes/original/src/components/UserDetails/index.tsx +5 -3
  183. package/themes/original/src/components/UserFormDetails/index.tsx +6 -48
  184. package/themes/original/src/components/UserProfile/index.tsx +58 -35
  185. package/themes/original/src/components/UserProfile/styles.ts +17 -0
  186. package/themes/original/src/components/WalletTransactions/index.tsx +76 -0
  187. package/themes/original/src/components/WalletTransactions/styles.tsx +13 -0
  188. package/themes/original/src/components/Wallets/index.tsx +176 -164
  189. package/themes/original/src/components/Wallets/styles.tsx +12 -8
  190. package/themes/original/src/components/shared/CardAnimation.tsx +47 -0
  191. package/themes/original/src/components/shared/HeaderTitle.tsx +8 -3
  192. package/themes/original/src/components/shared/OBottomPopup.tsx +6 -4
  193. package/themes/original/src/components/shared/OButton.tsx +8 -3
  194. package/themes/original/src/components/shared/OIcon.tsx +8 -1
  195. package/themes/original/src/components/shared/OInput.tsx +10 -1
  196. package/themes/original/src/layouts/Container.tsx +13 -9
  197. package/themes/original/src/types/index.tsx +61 -7
  198. package/themes/original/src/utils/index.tsx +103 -58
  199. package/themes/uber-eats/src/components/BusinessesListing/index.tsx +1 -1
@@ -11,6 +11,8 @@ import { StyleSheet } from 'react-native';
11
11
  import { useTheme } from 'styled-components/native';
12
12
  import { shape } from '../../utils'
13
13
  import { CategoryDescriptionMemoized } from './CategoryDescription';
14
+ import { OrderItAgain } from '../OrderItAgain'
15
+ import { SubcategoriesComponentMemoized } from './SubcategoriesComponent';
14
16
 
15
17
  const BusinessProductsListUI = (props: BusinessProductsListParams) => {
16
18
  const {
@@ -35,7 +37,9 @@ const BusinessProductsListUI = (props: BusinessProductsListParams) => {
35
37
  onClickCategory,
36
38
  lazyLoadProductsRecommended,
37
39
  handleUpdateProducts,
38
- isFiltMode
40
+ previouslyProducts,
41
+ isFiltMode,
42
+ navigation
39
43
  } = props;
40
44
 
41
45
  const [, t] = useLanguage();
@@ -67,51 +71,29 @@ const BusinessProductsListUI = (props: BusinessProductsListParams) => {
67
71
  }
68
72
  }
69
73
 
70
- const SubcategoriesComponent = ({ category }: any) => {
71
- const allsubcategorySelected = !subcategoriesSelected?.some((subcategory: any) => category?.id === subcategory?.parent_category_id)
72
-
73
- return (
74
- <SubCategoriesContainer>
75
- <ContainerButton
76
- isSelected={allsubcategorySelected}
77
- >
78
- <OButton
79
- onClick={() => onClickSubcategory(null, category)}
80
- bgColor={allsubcategorySelected ? theme.colors.primary : theme.colors.backgroundGray}
81
- text={`${t('ALL', 'All')} ${allsubcategorySelected ? 'X' : ''}`}
82
- style={bpStyles.categoryButtonStyle}
83
- textStyle={{ color: allsubcategorySelected ? theme.colors.white : theme.colors.textNormal, fontSize: 12 }}
84
- />
85
- </ContainerButton>
86
- {category?.subcategories?.map((subcategory: any) => {
87
- const isSubcategorySelected = subcategoriesSelected?.find((_subcategory: any) => _subcategory?.id === subcategory?.id)
88
- return (
89
- <ContainerButton
90
- key={subcategory?.id}
91
- isSelected={isSubcategorySelected}
92
- >
93
- <OButton
94
- onClick={() => onClickSubcategory(subcategory, category)}
95
- bgColor={isSubcategorySelected ? theme.colors.primary : theme.colors.backgroundGray}
96
- text={`${subcategory?.name} ${isSubcategorySelected ? 'X' : ''}`}
97
- style={bpStyles.categoryButtonStyle}
98
- textStyle={{ color: isSubcategorySelected ? theme.colors.white : theme.colors.textNormal, fontSize: 12 }}
99
- />
100
- </ContainerButton>
101
- )
102
- }
103
- )}
104
- </SubCategoriesContainer>
105
- )
106
- }
107
-
108
74
  return (
109
75
  <ProductsContainer renderToHardwareTextureAndroid={categoryState.loading || isBusinessLoading}>
110
76
  <HeaderWrapper>
111
77
  {category?.subcategories?.length > 0 && (
112
- <SubcategoriesComponent category={category} />
78
+ <SubcategoriesComponentMemoized
79
+ category={category}
80
+ subcategoriesSelected={subcategoriesSelected}
81
+ onClickSubcategory={onClickSubcategory}
82
+ />
113
83
  )}
114
84
  </HeaderWrapper>
85
+ {previouslyProducts?.length > 0 && (
86
+ <OrderItAgain
87
+ onProductClick={onProductClick}
88
+ productList={previouslyProducts}
89
+ businessId={businessId}
90
+ categoryState={categoryState}
91
+ navigation={navigation}
92
+ handleUpdateProducts={handleUpdateProducts}
93
+ currentCart={currentCart}
94
+ searchValue={searchValue}
95
+ />
96
+ )}
115
97
  {category.id &&
116
98
  categoryState.products
117
99
  ?.filter((product: any) =>
@@ -122,12 +104,14 @@ const BusinessProductsListUI = (props: BusinessProductsListParams) => {
122
104
  <SingleProductCard
123
105
  key={'prod_' + product.id + `_${i}`}
124
106
  isSoldOut={product.inventoried && !product.quantity}
107
+ enableIntersection={!isFiltMode && categoryState.products?.length < 80}
125
108
  product={product}
126
109
  businessId={businessId}
127
110
  categoryState={categoryState}
128
111
  onProductClick={() => onProductClick(product)}
129
112
  productAddedToCartLength={currentCart?.products?.reduce((productsLength: number, Cproduct: any) => { return productsLength + (Cproduct?.id === product?.id ? Cproduct?.quantity : 0) }, 0)}
130
113
  handleUpdateProducts={handleUpdateProducts}
114
+ navigation={navigation}
131
115
  />
132
116
  ))
133
117
  }
@@ -148,11 +132,13 @@ const BusinessProductsListUI = (props: BusinessProductsListParams) => {
148
132
  key={'feat_' + product.id + `_${i}`}
149
133
  isSoldOut={product.inventoried && !product.quantity}
150
134
  product={product}
135
+ enableIntersection={!isFiltMode && categoryState.products?.length < 80}
151
136
  businessId={businessId}
152
137
  categoryState={categoryState}
153
138
  onProductClick={onProductClick}
154
139
  handleUpdateProducts={handleUpdateProducts}
155
140
  productAddedToCartLength={currentCart?.products?.reduce((productsLength: number, Cproduct: any) => { return productsLength + (Cproduct?.id === product?.id ? Cproduct?.quantity : 0) }, 0)}
141
+ navigation={navigation}
156
142
  />
157
143
  ),
158
144
  )}
@@ -180,14 +166,16 @@ const BusinessProductsListUI = (props: BusinessProductsListParams) => {
180
166
  style={bpStyles.catWrap}
181
167
  onLayout={(event: any) => handleOnLayout(event, category.id)}
182
168
  >
183
- <View style={bpStyles.catIcon}>
184
- <OIcon
185
- url={optimizeImage(category.image, 'h_250,c_limit')}
186
- width={41}
187
- height={41}
188
- style={{ borderRadius: 7.6 }}
189
- />
190
- </View>
169
+ {!!category.image && (
170
+ <View style={bpStyles.catIcon}>
171
+ <OIcon
172
+ url={optimizeImage(category.image, 'h_250,c_limit')}
173
+ width={41}
174
+ height={41}
175
+ style={{ borderRadius: 7.6 }}
176
+ />
177
+ </View>
178
+ )}
191
179
  <OText size={16} weight="600">
192
180
  {category.name}
193
181
  </OText>
@@ -233,19 +221,24 @@ const BusinessProductsListUI = (props: BusinessProductsListParams) => {
233
221
  </View>
234
222
  )}
235
223
  {category?.subcategories?.length > 0 && !isFiltMode && (
236
- <SubcategoriesComponent category={category} />
224
+ <SubcategoriesComponentMemoized
225
+ category={category}
226
+ subcategoriesSelected={subcategoriesSelected}
227
+ onClickSubcategory={onClickSubcategory}
228
+ />
237
229
  )}
238
230
  <>
239
231
  {products.sort((a: any, b: any) => a.rank - b.rank).map((product: any, i: any) => (
240
232
  <SingleProductCard
241
233
  key={`${product?.id}_${i}`}
242
- enableIntersection
234
+ enableIntersection={!isFiltMode && categoryState.products?.length < 80}
243
235
  isSoldOut={product.inventoried && !product.quantity}
244
236
  businessId={businessId}
245
237
  product={product}
246
238
  categoryState={categoryState}
247
239
  onProductClick={onProductClick}
248
240
  handleUpdateProducts={handleUpdateProducts}
241
+ navigation={navigation}
249
242
  productAddedToCartLength={currentCart?.products?.reduce((productsLength: number, Cproduct: any) => { return productsLength + (Cproduct?.id === product?.id ? Cproduct?.quantity : 0) }, 0)}
250
243
  />
251
244
  ))}
@@ -260,19 +253,24 @@ const BusinessProductsListUI = (props: BusinessProductsListParams) => {
260
253
  <>
261
254
  {[...Array(categoryState?.pagination?.nextPageItems).keys()].map(
262
255
  (item, i) => (
263
- <Placeholder key={i} style={{ padding: 5 }} Animation={Fade}>
264
- <View style={{ flexDirection: 'row' }}>
256
+ <View style={{ minHeight: 165, marginBottom: 28, padding: 12 }} key={i}>
257
+ <Placeholder style={{ padding: 5 }} Animation={Fade}>
258
+ <View style={{ flexDirection: 'row' }}>
259
+ <Placeholder style={{ paddingVertical: 10, flex: 1 }}>
260
+ <PlaceholderLine width={60} style={{ marginBottom: 15 }} />
261
+ <PlaceholderLine width={20} />
262
+ </Placeholder>
263
+ <PlaceholderLine
264
+ width={24}
265
+ height={70}
266
+ style={{ marginLeft: 10, marginBottom: 10 }}
267
+ />
268
+ </View>
265
269
  <PlaceholderLine
266
- width={24}
267
- height={70}
268
- style={{ marginRight: 10, marginBottom: 10 }}
270
+ height={52}
269
271
  />
270
- <Placeholder style={{ paddingVertical: 10 }}>
271
- <PlaceholderLine width={60} style={{ marginBottom: 25 }} />
272
- <PlaceholderLine width={20} />
273
- </Placeholder>
274
- </View>
275
- </Placeholder>
272
+ </Placeholder>
273
+ </View>
276
274
  ),
277
275
  )}
278
276
  </>
@@ -18,15 +18,12 @@ export const RibbonBox = styled.View`
18
18
  background-color: ${(props: any) => props.theme.colors.primary};
19
19
  padding: 2px 8px;
20
20
  max-width: 180px;
21
-
22
21
  ${(props: any) => props.bgColor && css`
23
22
  background-color: ${props.bgColor};
24
23
  `}
25
-
26
24
  ${(props: any) => props.isRoundRect && css`
27
25
  border-radius: 7.6px;
28
26
  `}
29
-
30
27
  ${(props: any) => props.isCapsule && css`
31
28
  border-radius: 50px;
32
29
  `}
@@ -1,6 +1,7 @@
1
1
  import React, { useCallback, useEffect, useRef, useState } from 'react'
2
- import { View, TouchableOpacity, StyleSheet, SafeAreaView, Dimensions, Platform, KeyboardAvoidingViewBase, KeyboardAvoidingView } from 'react-native'
2
+ import { View, TouchableOpacity, StyleSheet, SafeAreaView, Dimensions, Platform, KeyboardAvoidingViewBase, KeyboardAvoidingView, Vibration } from 'react-native'
3
3
  import { IOScrollView } from 'react-native-intersection-observer'
4
+ import { useSafeAreaInsets } from 'react-native-safe-area-context'
4
5
  import { useTheme } from 'styled-components/native';
5
6
  import {
6
7
  BusinessAndProductList,
@@ -10,9 +11,9 @@ import {
10
11
  useUtils,
11
12
  ToastType,
12
13
  useToast,
13
- useConfig,
14
- useOrderingTheme
14
+ useConfig
15
15
  } from 'ordering-components/native'
16
+ import { Fade, Placeholder, PlaceholderLine } from 'rn-placeholder';
16
17
  import { OButton, OIcon, OModal, OText } from '../shared'
17
18
  import Alert from '../../providers/AlertProvider'
18
19
  import { BusinessBasicInformation } from '../BusinessBasicInformation'
@@ -21,6 +22,9 @@ import { BusinessProductsCategories } from '../BusinessProductsCategories'
21
22
  import { BusinessProductsList } from '../BusinessProductsList'
22
23
  import { BusinessProductsListingParams } from '../../types'
23
24
  import { _retrieveStoreData, _removeStoreData } from '../../providers/StoreUtil';
25
+ import IconAntDesign from 'react-native-vector-icons/AntDesign';
26
+ import { useIsFocused } from '@react-navigation/native';
27
+
24
28
  import {
25
29
  TopHeader,
26
30
  WrapSearchBar,
@@ -29,7 +33,8 @@ import {
29
33
  ContainerSafeAreaView,
30
34
  BackgroundGray,
31
35
  ProfessionalFilterWrapper,
32
- NearBusiness
36
+ NearBusiness,
37
+ TopActions
33
38
  } from './styles'
34
39
  import { FloatingButton } from '../FloatingButton'
35
40
  import { UpsellingRedirect } from './UpsellingRedirect'
@@ -61,23 +66,25 @@ const BusinessProductsListingUI = (props: BusinessProductsListingParams) => {
61
66
  getNextProducts,
62
67
  handleUpdateProducts,
63
68
  professionalSelected,
69
+ handleUpdateProfessionals,
64
70
  handleChangeProfessionalSelected,
65
71
  onBusinessClick
66
72
  } = props
67
73
 
74
+ const insets = useSafeAreaInsets()
68
75
  const theme = useTheme();
69
- const [orderingTheme] = useOrderingTheme()
70
76
  const [, t] = useLanguage()
71
77
  const [{ auth }] = useSession()
72
- const [orderState, { clearCart }] = useOrder()
78
+ const [orderState, { addProduct, updateProduct }] = useOrder()
73
79
  const [{ parsePrice }] = useUtils()
74
80
  const [, { showToast }] = useToast()
75
81
  const [{ configs }] = useConfig()
82
+ const isFocused = useIsFocused();
76
83
  const isPreOrder = configs?.preorder_status_enabled?.value === '1'
77
84
 
78
- const isChewLayout = theme?.layouts?.business_view?.components?.header?.components?.layout?.type === 'chew'
79
- const showLogo = !orderingTheme?.theme?.business_view?.components?.header?.components?.business?.components?.logo?.hidden
80
- const showBusinessNearCity = !theme?.layouts?.business_view?.components?.near_business?.hidden
85
+ const isChewLayout = theme?.header?.components?.layout?.type === 'chew'
86
+ const showLogo = !theme?.business_view?.components?.header?.components?.business?.components?.logo?.hidden
87
+ const hideBusinessNearCity = theme?.business_view?.components?.near_business?.hidden ?? true
81
88
 
82
89
  const styles = StyleSheet.create({
83
90
  mainContainer: {
@@ -103,7 +110,13 @@ const BusinessProductsListingUI = (props: BusinessProductsListingParams) => {
103
110
  padding: 15,
104
111
  justifyContent: 'center',
105
112
  shadowColor: theme.colors.clear,
106
- }
113
+ },
114
+ businessSkeleton: {
115
+ borderRadius: 8,
116
+ marginRight: 20,
117
+ width: 56,
118
+ height: 56
119
+ },
107
120
  })
108
121
 
109
122
  const { business, loading, error } = businessState
@@ -118,26 +131,52 @@ const BusinessProductsListingUI = (props: BusinessProductsListingParams) => {
118
131
  const [subcategoriesSelected, setSubcategoriesSelected] = useState([])
119
132
  const [openService, setOpenService] = useState(false)
120
133
  const [currentProduct, setCurrentProduct] = useState(null)
134
+ const [searchBarHeight, setSearchBarHeight] = useState(60)
121
135
 
122
136
  const isCheckoutMultiBusinessEnabled: Boolean = configs?.checkout_multi_business_enabled?.value === '1'
137
+ const isQuickAddProduct = configs?.add_product_with_one_click?.value === '1'
138
+ const openCarts = (Object.values(orderState?.carts)?.filter((cart: any) => cart?.products && cart?.products?.length && cart?.status !== 2 && cart?.valid_schedule && cart?.valid_products && cart?.valid_address && cart?.valid_maximum && cart?.valid_minimum && !cart?.wallets) || null) || []
139
+
123
140
  const currentCart: any = Object.values(orderState.carts).find((cart: any) => cart?.business?.slug === business?.slug) ?? {}
124
141
  const isOpenFiltProducts = isOpenSearchBar && !!searchValue
125
- const filtProductsHeight = Platform.OS === 'ios' ? 0 : 35
142
+ const filtProductsHeight = Platform.OS === 'ios' ? 0 : 100
126
143
  const onRedirect = (route: string, params?: any) => {
127
144
  navigation.navigate(route, params)
128
145
  }
129
-
130
- const onProductClick = (product: any) => {
131
- if (product?.type === 'service' && professionalSelected) {
132
- setCurrentProduct(product)
133
- setOpenService(true)
134
- return
146
+ const onProductClick = async (product: any) => {
147
+ if (product.extras.length === 0 && !product.inventoried && auth && isQuickAddProduct) {
148
+ const isProductAddedToCart = currentCart?.products?.find((Cproduct: any) => Cproduct.id === product.id)
149
+ const productQuantity = isProductAddedToCart?.quantity
150
+ const addCurrentProduct = {
151
+ ...product,
152
+ quantity: 1
153
+ }
154
+ const updateCurrentProduct = {
155
+ id: product.id,
156
+ code: isProductAddedToCart?.code,
157
+ quantity: productQuantity + 1
158
+ }
159
+ Vibration.vibrate()
160
+ const cartData = currentCart?.business_id ? currentCart : { business_id: business.id }
161
+ if (isProductAddedToCart) {
162
+ await updateProduct(updateCurrentProduct, cartData, isQuickAddProduct)
163
+ } else {
164
+ await addProduct(addCurrentProduct, cartData, isQuickAddProduct)
165
+ }
166
+ } else {
167
+ const productAddedToCartLength = currentCart?.products?.reduce((productsLength: number, Cproduct: any) => { return productsLength + (Cproduct?.id === product?.id ? Cproduct?.quantity : 0) }, 0) || 0
168
+ if (product?.type === 'service' && business?.professionals?.length > 0) {
169
+ setCurrentProduct(product)
170
+ setOpenService(true)
171
+ return
172
+ }
173
+ onRedirect('ProductDetails', {
174
+ product: product,
175
+ businessSlug: business.slug,
176
+ businessId: business.id,
177
+ productAddedToCartLength
178
+ })
135
179
  }
136
- onRedirect('ProductDetails', {
137
- product: product,
138
- businessSlug: business.slug,
139
- businessId: business.id,
140
- })
141
180
  }
142
181
 
143
182
  const handleCancel = () => {
@@ -146,20 +185,37 @@ const BusinessProductsListingUI = (props: BusinessProductsListingParams) => {
146
185
  }
147
186
 
148
187
  const handleUpsellingPage = () => {
149
- if (isCheckoutMultiBusinessEnabled) {
150
- onRedirect('CheckoutNavigator', {
151
- screen: 'MultiCheckout'
152
- })
153
- } else {
154
- onRedirect('CheckoutNavigator', {
155
- screen: 'CheckoutPage',
156
- cartUuid: currentCart?.uuid,
157
- businessLogo: logo,
158
- businessName: business?.name,
159
- cartTotal: currentCart?.total
160
- })
161
- }
162
188
  setOpenUpselling(false)
189
+ setCanOpenUpselling(false)
190
+ const cartsAvailable: any = Object.values(orderState?.carts)?.filter((cart: any) => cart?.valid && cart?.status !== 2)
191
+ if (cartsAvailable.length === 1) {
192
+ props.onNavigationRedirect('CheckoutNavigator', {
193
+ screen: 'CheckoutPage',
194
+ cartUuid: cartsAvailable[0]?.uuid,
195
+ businessLogo: cartsAvailable[0]?.business?.logo,
196
+ businessName: cartsAvailable[0]?.business?.name,
197
+ cartTotal: cartsAvailable[0]?.total
198
+ })
199
+ } else {
200
+ const groupKeys: any = {}
201
+ cartsAvailable.forEach((_cart: any) => {
202
+ groupKeys[_cart?.group?.uuid]
203
+ ? groupKeys[_cart?.group?.uuid] += 1
204
+ : groupKeys[_cart?.group?.uuid ?? 'null'] = 1
205
+ })
206
+
207
+ if (
208
+ (Object.keys(groupKeys).length === 1 && Object.keys(groupKeys)[0] === 'null') ||
209
+ Object.keys(groupKeys).length > 1
210
+ ) {
211
+ props.onNavigationRedirect('CheckoutNavigator', { screen: 'MultiCart' })
212
+ } else {
213
+ props.onNavigationRedirect('CheckoutNavigator', {
214
+ screen: 'MultiCheckout',
215
+ cartUuid: cartsAvailable[0]?.group?.uuid
216
+ })
217
+ }
218
+ }
163
219
  }
164
220
 
165
221
  const handleCloseUpsellingPage = () => {
@@ -231,33 +287,41 @@ const BusinessProductsListingUI = (props: BusinessProductsListingParams) => {
231
287
  removeCartByReOrder()
232
288
  }, [currentCart])
233
289
 
290
+ useEffect(() => {
291
+ if (!isFocused) {
292
+ handleChangeSearch('')
293
+ setIsOpenSearchBar(false)
294
+ }
295
+ }, [isFocused])
296
+
297
+ const subtotalWithTaxes = currentCart?.taxes?.reduce((acc: any, item: any) => {
298
+ if (item?.type === 1)
299
+ return acc = acc + item?.summary?.tax
300
+ return acc = acc
301
+ }, currentCart?.subtotal)
302
+
234
303
  return (
235
304
  <>
236
- <ContainerSafeAreaView
237
- style={{ flex: 1 }}
238
- isOpenFiltProducts={isOpenFiltProducts}
239
- >
305
+ <View style={{ flex: 1 }}>
240
306
  <Animated.View style={{ position: 'relative' }}>
241
- <TopHeader isIos={Platform.OS === 'ios'}>
307
+ <TopHeader
308
+ style={{
309
+ marginTop: Platform.OS === 'ios' ? insets.top : 0
310
+ }}
311
+ onLayout={(event: any) => setSearchBarHeight(event.nativeEvent.layout.height)}
312
+ >
242
313
  {!isOpenSearchBar && (
243
314
  <>
244
- <View style={{ ...styles.headerItem, flex: 1 }}>
245
- <OButton
246
- imgLeftSrc={theme.images.general.arrow_left}
247
- imgRightSrc={null}
248
- style={styles.btnBackArrow}
249
- onClick={() => handleBackNavigation()}
250
- imgLeftStyle={{ tintColor: theme.colors.textNormal, width: 30 }}
251
- />
252
-
253
- </View>
315
+ <TopActions onPress={() => handleBackNavigation()}>
316
+ <OIcon src={theme.images.general.arrow_left} color={theme.colors.textNormal} />
317
+ </TopActions>
254
318
  {!errorQuantityProducts && (
255
319
  <View style={{ ...styles.headerItem }}>
256
320
  <TouchableOpacity
257
321
  onPress={() => setIsOpenSearchBar(true)}
258
322
  style={styles.searchIcon}
259
323
  >
260
- <OIcon src={theme.images.general.search} color={theme.colors.textNormal} width={16} />
324
+ <OIcon src={theme.images.general.search} color={theme.colors.textNormal} width={20} />
261
325
  </TouchableOpacity>
262
326
  </View>
263
327
  )}
@@ -277,7 +341,20 @@ const BusinessProductsListingUI = (props: BusinessProductsListingParams) => {
277
341
  </WrapSearchBar>
278
342
  )}
279
343
  </TopHeader>
280
- {showBusinessNearCity && businessState?.business?.city_id && (
344
+ {!hideBusinessNearCity && loading && (
345
+ <NearBusiness style={{ paddingBottom: 10 }}>
346
+ <Placeholder Animation={Fade}>
347
+ <View style={{ flexDirection: 'row' }}>
348
+ {[...Array(10).keys()].map(i => (
349
+ <View style={styles.businessSkeleton} key={i}>
350
+ <PlaceholderLine style={{ width: '100%', height: '100%' }} />
351
+ </View>
352
+ ))}
353
+ </View>
354
+ </Placeholder>
355
+ </NearBusiness>
356
+ )}
357
+ {!loading && !hideBusinessNearCity && businessState?.business?.city_id && (
281
358
  <NearBusiness>
282
359
  <BusinessesListing
283
360
  logosLayout
@@ -292,10 +369,11 @@ const BusinessProductsListingUI = (props: BusinessProductsListingParams) => {
292
369
 
293
370
  {business?.categories?.length > 0 && isOpenFiltProducts && (
294
371
  <FiltProductsContainer
295
- isIos={Platform.OS === 'ios'}
296
372
  style={{
297
- height: Dimensions.get('window').height - filtProductsHeight
373
+ height: Dimensions.get('window').height - filtProductsHeight,
374
+ top: Platform.OS === 'ios' ? searchBarHeight + insets.top : searchBarHeight
298
375
  }}
376
+ contentContainerStyle={{ flexGrow: 1 }}
299
377
  >
300
378
  <View style={{ padding: 20, backgroundColor: theme.colors.white }}>
301
379
  <BusinessProductsList
@@ -323,16 +401,18 @@ const BusinessProductsListingUI = (props: BusinessProductsListingParams) => {
323
401
  setSubcategoriesSelected={setSubcategoriesSelected}
324
402
  onClickCategory={handleChangeCategory}
325
403
  handleUpdateProducts={handleUpdateProducts}
404
+ previouslyProducts={business?.previously_products}
405
+ navigation={navigation}
326
406
  isFiltMode
327
407
  />
328
408
  </View>
329
409
  </FiltProductsContainer>
330
410
  )}
331
411
  {isOpenFiltProducts && (
332
- <BackgroundGray />
412
+ <BackgroundGray isIos={Platform.OS === 'ios'} />
333
413
  )}
334
414
  <IOScrollView
335
- stickyHeaderIndices={[2]}
415
+ stickyHeaderIndices={[business?.professionals?.length > 0 ? 3 : 2]}
336
416
  style={{
337
417
  ...styles.mainContainer,
338
418
  marginBottom: currentCart?.products?.length > 0 && categoryState.products.length !== 0 ?
@@ -342,6 +422,7 @@ const BusinessProductsListingUI = (props: BusinessProductsListingParams) => {
342
422
  onScroll={handlePageScroll}
343
423
  onScrollBeginDrag={handleTouchDrag}
344
424
  scrollEventThrottle={16}
425
+ bounces={false}
345
426
  >
346
427
  <BusinessBasicInformation
347
428
  navigation={navigation}
@@ -374,31 +455,27 @@ const BusinessProductsListingUI = (props: BusinessProductsListingParams) => {
374
455
  marginTop: isChewLayout && showLogo ? 10 : 0
375
456
  }}
376
457
  />
377
- {!loading && business?.id && (
378
- <>
379
- {!(business?.categories?.length === 0) && (
380
- <BusinessProductsCategories
381
- categories={[{ id: null, name: t('ALL', 'All') }, { id: 'featured', name: t('FEATURED', 'Featured') }, ...business?.categories.sort((a: any, b: any) => a.rank - b.rank)]}
382
- categorySelected={categorySelected}
383
- onClickCategory={handleChangeCategory}
384
- featured={featuredProducts}
385
- openBusinessInformation={openBusinessInformation}
386
- scrollViewRef={scrollViewRef}
387
- productListLayout={productListLayout}
388
- categoriesLayout={categoriesLayout}
389
- selectedCategoryId={selectedCategoryId}
390
- lazyLoadProductsRecommended={business?.lazy_load_products_recommended}
391
- setSelectedCategoryId={setSelectedCategoryId}
392
- setCategoryClicked={setCategoryClicked}
393
-
394
- />
395
- )}
396
- </>
458
+ {!loading && business?.id && !(business?.categories?.length === 0) && (
459
+ <BusinessProductsCategories
460
+ categories={[{ id: null, name: t('ALL', 'All') }, { id: 'featured', name: t('FEATURED', 'Featured') }, ...business?.categories.sort((a: any, b: any) => a.rank - b.rank)]}
461
+ categorySelected={categorySelected}
462
+ onClickCategory={handleChangeCategory}
463
+ featured={featuredProducts}
464
+ openBusinessInformation={openBusinessInformation}
465
+ scrollViewRef={scrollViewRef}
466
+ productListLayout={productListLayout}
467
+ categoriesLayout={categoriesLayout}
468
+ selectedCategoryId={selectedCategoryId}
469
+ lazyLoadProductsRecommended={business?.lazy_load_products_recommended}
470
+ setSelectedCategoryId={setSelectedCategoryId}
471
+ setCategoryClicked={setCategoryClicked}
472
+ />
397
473
  )}
398
474
  {!loading && business?.id && (
399
475
  <>
400
476
  <WrapContent
401
477
  onLayout={(event: any) => setProductListLayout(event.nativeEvent.layout)}
478
+ style={{ paddingHorizontal: isChewLayout ? 20 : 40 }}
402
479
  >
403
480
  <BusinessProductsList
404
481
  categories={[
@@ -425,6 +502,8 @@ const BusinessProductsListingUI = (props: BusinessProductsListingParams) => {
425
502
  setSubcategoriesSelected={setSubcategoriesSelected}
426
503
  onClickCategory={handleChangeCategory}
427
504
  handleUpdateProducts={handleUpdateProducts}
505
+ navigation={navigation}
506
+ previouslyProducts={business?.previously_products}
428
507
  />
429
508
  </WrapContent>
430
509
  </>
@@ -447,28 +526,31 @@ const BusinessProductsListingUI = (props: BusinessProductsListingParams) => {
447
526
  isBusinessLoading={loading}
448
527
  errorQuantityProducts={errorQuantityProducts}
449
528
  handleUpdateProducts={handleUpdateProducts}
529
+ navigation={navigation}
450
530
  />
451
531
  </WrapContent>
452
532
  </>
453
533
  )}
454
534
  </IOScrollView>
455
535
  {!loading && auth && currentCart?.products?.length > 0 && categoryState.products.length !== 0 && (
456
- <FloatingButton
457
- btnText={
458
- openUpselling
459
- ? t('LOADING', 'Loading')
460
- : currentCart?.subtotal >= currentCart?.minimum
461
- ? t('VIEW_ORDER', 'View Order')
462
- : `${t('MINIMUN_SUBTOTAL_ORDER', 'Minimum subtotal order:')} ${parsePrice(currentCart?.minimum)}`
463
- }
464
- isSecondaryBtn={currentCart?.subtotal < currentCart?.minimum || openUpselling}
465
- btnLeftValueShow={currentCart?.subtotal >= currentCart?.minimum && currentCart?.products?.length > 0}
466
- btnRightValueShow={currentCart?.subtotal >= currentCart?.minimum && currentCart?.products?.length > 0}
467
- btnLeftValue={currentCart?.products.reduce((prev: number, product: any) => prev + product.quantity, 0)}
468
- btnRightValue={parsePrice(currentCart?.total)}
469
- disabled={currentCart?.subtotal < currentCart?.minimum || openUpselling}
470
- handleClick={() => setOpenUpselling(true)}
471
- />
536
+ <View style={{ marginBottom: Platform.OS === 'ios' ? 20 : 0 }}>
537
+ <FloatingButton
538
+ btnText={
539
+ openUpselling
540
+ ? t('LOADING', 'Loading')
541
+ : subtotalWithTaxes >= currentCart?.minimum
542
+ ? t('VIEW_ORDER', 'View Order')
543
+ : `${t('MINIMUN_SUBTOTAL_ORDER', 'Minimum subtotal order:')} ${parsePrice(currentCart?.minimum)}`
544
+ }
545
+ isSecondaryBtn={subtotalWithTaxes < currentCart?.minimum || openUpselling}
546
+ btnLeftValueShow={subtotalWithTaxes >= currentCart?.minimum && currentCart?.products?.length > 0}
547
+ btnRightValueShow={subtotalWithTaxes >= currentCart?.minimum && currentCart?.products?.length > 0}
548
+ btnLeftValue={currentCart?.products.reduce((prev: number, product: any) => prev + product.quantity, 0)}
549
+ btnRightValue={parsePrice(currentCart?.total)}
550
+ disabled={subtotalWithTaxes < currentCart?.minimum || openUpselling}
551
+ handleClick={() => setOpenUpselling(true)}
552
+ />
553
+ </View>
472
554
  )}
473
555
  {openUpselling && (
474
556
  <UpsellingRedirect
@@ -492,7 +574,7 @@ const BusinessProductsListingUI = (props: BusinessProductsListingParams) => {
492
574
  onAccept={() => setAlertState({ open: false, content: [] })}
493
575
  onClose={() => setAlertState({ open: false, content: [] })}
494
576
  />
495
- </ContainerSafeAreaView>
577
+ </View>
496
578
  <OModal
497
579
  open={openService}
498
580
  onClose={() => setOpenService(false)}
@@ -506,6 +588,7 @@ const BusinessProductsListingUI = (props: BusinessProductsListingParams) => {
506
588
  professionalList={business?.professionals}
507
589
  professionalSelected={professionalSelected}
508
590
  handleChangeProfessional={handleChangeProfessionalSelected}
591
+ handleUpdateProfessionals={handleUpdateProfessionals}
509
592
  onSave={() => setOpenService(false)}
510
593
  onClose={() => setOpenService(false)}
511
594
  />
@@ -517,6 +600,7 @@ const BusinessProductsListingUI = (props: BusinessProductsListingParams) => {
517
600
  export const BusinessProductsListing = (props: BusinessProductsListingParams) => {
518
601
  const businessProductslistingProps = {
519
602
  ...props,
603
+ isForceSearch: Platform.OS === 'ios',
520
604
  UIComponent: BusinessProductsListingUI
521
605
  }
522
606
  return (