ordering-ui-react-native 0.16.46 → 0.16.47-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/BusinessBasicInformation/index.tsx +11 -19
  6. package/src/components/BusinessInformation/index.tsx +33 -4
  7. package/src/components/BusinessInformation/styles.tsx +2 -2
  8. package/src/components/BusinessProductsList/index.tsx +10 -10
  9. package/src/components/BusinessesListing/index.tsx +1 -1
  10. package/src/components/Checkout/index.tsx +2 -1
  11. package/src/components/LanguageSelector/index.tsx +21 -16
  12. package/src/components/Messages/index.tsx +2 -2
  13. package/src/components/NotificationSetting/index.tsx +85 -0
  14. package/src/components/OrdersOption/index.tsx +54 -56
  15. package/src/components/PaymentOptions/index.tsx +298 -345
  16. package/src/components/PaymentOptionsWebView/index.tsx +120 -121
  17. package/src/components/ReviewDriver/index.tsx +1 -1
  18. package/src/components/ReviewOrder/index.tsx +2 -2
  19. package/src/components/ReviewProducts/index.tsx +11 -0
  20. package/src/components/SingleProductReview/index.tsx +8 -5
  21. package/src/components/StripeElementsForm/index.tsx +25 -16
  22. package/src/components/VerifyPhone/styles.tsx +1 -2
  23. package/src/components/shared/OBottomPopup.tsx +6 -2
  24. package/src/components/shared/OToast.tsx +3 -3
  25. package/src/index.tsx +2 -0
  26. package/src/types/@fatnlazycat/react-native-recaptcha-v3/index.d.ts +1 -0
  27. package/src/utils/index.tsx +2 -1
  28. package/themes/business/src/components/BusinessController/index.tsx +2 -2
  29. package/themes/business/src/components/Chat/index.tsx +40 -32
  30. package/themes/business/src/components/DriverMap/index.tsx +7 -5
  31. package/themes/business/src/components/DriverSchedule/index.tsx +36 -19
  32. package/themes/business/src/components/LoginForm/index.tsx +111 -74
  33. package/themes/business/src/components/MapView/index.tsx +12 -1
  34. package/themes/business/src/components/MessagesOption/index.tsx +11 -1
  35. package/themes/business/src/components/NewOrderNotification/index.tsx +26 -41
  36. package/themes/business/src/components/OrderDetails/Business.tsx +1 -1
  37. package/themes/business/src/components/OrderDetails/OrderContentComponent.tsx +33 -23
  38. package/themes/business/src/components/OrdersListManager/index.tsx +10 -3
  39. package/themes/business/src/components/OrdersOption/index.tsx +65 -21
  40. package/themes/business/src/components/OrdersOption/styles.tsx +5 -1
  41. package/themes/business/src/components/OrdersOptionBusiness/index.tsx +15 -1
  42. package/themes/business/src/components/OrdersOptionCity/index.tsx +15 -1
  43. package/themes/business/src/components/OrdersOptionDate/index.tsx +19 -6
  44. package/themes/business/src/components/OrdersOptionDelivery/index.tsx +15 -1
  45. package/themes/business/src/components/OrdersOptionDriver/index.tsx +15 -1
  46. package/themes/business/src/components/OrdersOptionPaymethod/index.tsx +15 -1
  47. package/themes/business/src/components/OrdersOptionStatus/index.tsx +10 -1
  48. package/themes/business/src/components/PreviousMessages/index.tsx +17 -18
  49. package/themes/business/src/components/PreviousOrders/index.tsx +18 -20
  50. package/themes/business/src/components/ProductItemAccordion/index.tsx +3 -2
  51. package/themes/business/src/components/ReviewCustomer/index.tsx +27 -13
  52. package/themes/business/src/components/ScheduleBlocked/index.tsx +2 -2
  53. package/themes/business/src/components/UserFormDetails/index.tsx +5 -2
  54. package/themes/business/src/components/UserProfileForm/index.tsx +2 -0
  55. package/themes/business/src/components/shared/ODropDown.tsx +42 -8
  56. package/themes/business/src/components/shared/ODropDownCalendar.tsx +36 -7
  57. package/themes/business/src/components/shared/OLink.tsx +24 -12
  58. package/themes/business/src/types/index.tsx +15 -9
  59. package/themes/business/src/utils/index.tsx +10 -0
  60. package/themes/doordash/src/components/BusinessesListing/index.tsx +1 -1
  61. package/themes/doordash/src/components/LoginForm/index.tsx +1 -2
  62. package/themes/instacart/src/components/BusinessesListing/index.tsx +1 -1
  63. package/themes/kiosk/src/components/BusinessesListing/index.tsx +2 -1
  64. package/themes/kiosk/src/components/Checkout/index.tsx +6 -0
  65. package/themes/kiosk/src/components/LoginForm/index.tsx +121 -10
  66. package/themes/kiosk/src/components/LoginForm/styles.tsx +5 -0
  67. package/themes/kiosk/src/components/NavBar/index.tsx +14 -14
  68. package/themes/kiosk/src/components/OptionCard/index.tsx +1 -1
  69. package/themes/kiosk/src/components/OrderTypeCardSelector/index.tsx +8 -10
  70. package/themes/kiosk/src/components/ProductForm/index.tsx +1 -14
  71. package/themes/kiosk/src/components/shared/OButton.tsx +5 -18
  72. package/themes/kiosk/src/types/index.d.ts +2 -0
  73. package/themes/original/index.tsx +4 -0
  74. package/themes/original/src/components/AddressDetails/index.tsx +10 -8
  75. package/themes/original/src/components/AddressForm/index.tsx +157 -140
  76. package/themes/original/src/components/AddressList/index.tsx +1 -1
  77. package/themes/original/src/components/AppleLogin/index.tsx +4 -4
  78. package/themes/original/src/components/BusinessBasicInformation/index.tsx +218 -147
  79. package/themes/original/src/components/BusinessBasicInformation/styles.tsx +2 -2
  80. package/themes/original/src/components/BusinessController/index.tsx +231 -114
  81. package/themes/original/src/components/BusinessController/styles.tsx +14 -9
  82. package/themes/original/src/components/BusinessItemAccordion/index.tsx +12 -6
  83. package/themes/original/src/components/BusinessListingSearch/BusinessControllerSkeletons/index.tsx +57 -0
  84. package/themes/original/src/components/BusinessListingSearch/MaxSectionItem/index.tsx +59 -0
  85. package/themes/original/src/components/BusinessListingSearch/MaxSectionItem/styles.tsx +13 -0
  86. package/themes/original/src/components/BusinessListingSearch/index.tsx +109 -139
  87. package/themes/original/src/components/BusinessListingSearch/styles.tsx +10 -12
  88. package/themes/original/src/components/BusinessProductsList/SubcategoriesComponent/index.tsx +87 -0
  89. package/themes/original/src/components/BusinessProductsList/SubcategoriesComponent/styles.tsx +12 -0
  90. package/themes/original/src/components/BusinessProductsList/index.tsx +59 -60
  91. package/themes/original/src/components/BusinessProductsList/styles.tsx +0 -3
  92. package/themes/original/src/components/BusinessProductsListing/index.tsx +175 -80
  93. package/themes/original/src/components/BusinessProductsListing/styles.tsx +18 -11
  94. package/themes/original/src/components/BusinessTypeFilter/index.tsx +3 -2
  95. package/themes/original/src/components/BusinessesListing/Layout/Appointment/index.tsx +35 -23
  96. package/themes/original/src/components/BusinessesListing/Layout/Appointment/styles.tsx +3 -2
  97. package/themes/original/src/components/BusinessesListing/Layout/Original/index.tsx +275 -120
  98. package/themes/original/src/components/BusinessesListing/Layout/Original/styles.tsx +47 -10
  99. package/themes/original/src/components/BusinessesListing/index.tsx +80 -25
  100. package/themes/original/src/components/Cart/index.tsx +82 -15
  101. package/themes/original/src/components/Cart/styles.tsx +4 -0
  102. package/themes/original/src/components/CartContent/index.tsx +22 -16
  103. package/themes/original/src/components/Checkout/index.tsx +113 -117
  104. package/themes/original/src/components/Checkout/styles.tsx +4 -3
  105. package/themes/original/src/components/CitiesControl/index.tsx +89 -0
  106. package/themes/original/src/components/CitiesControl/styles.tsx +17 -0
  107. package/themes/original/src/components/DriverTips/index.tsx +4 -4
  108. package/themes/original/src/components/DriverTips/styles.tsx +2 -1
  109. package/themes/original/src/components/FavoriteList/index.tsx +69 -45
  110. package/themes/original/src/components/FloatingButton/index.tsx +13 -11
  111. package/themes/original/src/components/FloatingButton/styles.tsx +1 -1
  112. package/themes/original/src/components/GPSButton/index.tsx +20 -19
  113. package/themes/original/src/components/GPSButton/styles.ts +3 -3
  114. package/themes/original/src/components/GoogleMap/index.tsx +20 -12
  115. package/themes/original/src/components/HelpAccountAndPayment/index.tsx +25 -10
  116. package/themes/original/src/components/HelpAccountAndPayment/styles.tsx +4 -0
  117. package/themes/original/src/components/HelpGuide/index.tsx +9 -8
  118. package/themes/original/src/components/HelpOrder/index.tsx +9 -8
  119. package/themes/original/src/components/LanguageSelector/index.tsx +19 -14
  120. package/themes/original/src/components/LoginForm/Otp/index.tsx +89 -73
  121. package/themes/original/src/components/LoginForm/Otp/styles.tsx +0 -1
  122. package/themes/original/src/components/LoginForm/index.tsx +98 -41
  123. package/themes/original/src/components/LottieAnimation/index.tsx +69 -0
  124. package/themes/original/src/components/Messages/index.tsx +35 -20
  125. package/themes/original/src/components/MomentOption/index.tsx +8 -6
  126. package/themes/original/src/components/MultiCart/index.tsx +63 -0
  127. package/themes/original/src/components/MultiCartsPaymethodsAndWallets/index.tsx +92 -93
  128. package/themes/original/src/components/MultiCheckout/index.tsx +10 -2
  129. package/themes/original/src/components/MultiOrdersDetails/index.tsx +34 -16
  130. package/themes/original/src/components/MyOrders/index.tsx +88 -22
  131. package/themes/original/src/components/NavBar/index.tsx +11 -5
  132. package/themes/original/src/components/NetworkError/index.tsx +5 -3
  133. package/themes/original/src/components/NotFoundSource/index.tsx +2 -1
  134. package/themes/original/src/components/Notifications/index.tsx +148 -0
  135. package/themes/original/src/components/Notifications/styles.tsx +17 -0
  136. package/themes/original/src/components/OrderDetails/OrderHistory.tsx +167 -0
  137. package/themes/original/src/components/OrderDetails/index.tsx +200 -39
  138. package/themes/original/src/components/OrderDetails/styles.tsx +15 -2
  139. package/themes/original/src/components/OrderItAgain/index.tsx +75 -0
  140. package/themes/original/src/components/OrderItAgain/styles.tsx +10 -0
  141. package/themes/original/src/components/OrderProgress/index.tsx +77 -66
  142. package/themes/original/src/components/OrderProgress/styles.tsx +5 -0
  143. package/themes/original/src/components/OrderSummary/index.tsx +2 -35
  144. package/themes/original/src/components/OrderTypeSelector/index.tsx +85 -36
  145. package/themes/original/src/components/OrderTypeSelector/styles.tsx +19 -1
  146. package/themes/original/src/components/OrdersOption/PreviousBusinessOrdered/index.tsx +94 -98
  147. package/themes/original/src/components/OrdersOption/PreviousProductsOrdered/index.tsx +3 -0
  148. package/themes/original/src/components/OrdersOption/index.tsx +102 -56
  149. package/themes/original/src/components/PaymentOptionWallet/index.tsx +56 -56
  150. package/themes/original/src/components/PaymentOptions/index.tsx +1 -2
  151. package/themes/original/src/components/PhoneInputNumber/index.tsx +1 -1
  152. package/themes/original/src/components/PlaceSpot/index.tsx +249 -47
  153. package/themes/original/src/components/PlaceSpot/styles.tsx +0 -2
  154. package/themes/original/src/components/PreviousOrders/index.tsx +3 -2
  155. package/themes/original/src/components/ProductForm/index.tsx +639 -664
  156. package/themes/original/src/components/ProductForm/styles.tsx +10 -11
  157. package/themes/original/src/components/ProductItemAccordion/index.tsx +199 -128
  158. package/themes/original/src/components/ProductOption/index.tsx +1 -1
  159. package/themes/original/src/components/ProductOptionSubOption/index.tsx +16 -8
  160. package/themes/original/src/components/ProductOptionSubOption/styles.tsx +0 -1
  161. package/themes/original/src/components/ProfessionalFilter/index.tsx +2 -1
  162. package/themes/original/src/components/ProfessionalProfile/index.tsx +19 -8
  163. package/themes/original/src/components/Promotions/index.tsx +232 -219
  164. package/themes/original/src/components/Promotions/styles.tsx +7 -2
  165. package/themes/original/src/components/ReviewDriver/index.tsx +3 -3
  166. package/themes/original/src/components/ReviewOrder/index.tsx +120 -108
  167. package/themes/original/src/components/ReviewOrder/styles.tsx +5 -7
  168. package/themes/original/src/components/ReviewProducts/index.tsx +8 -5
  169. package/themes/original/src/components/ReviewTrigger/index.tsx +136 -0
  170. package/themes/original/src/components/ReviewTrigger/styles.tsx +41 -0
  171. package/themes/original/src/components/ServiceForm/index.tsx +332 -264
  172. package/themes/original/src/components/SignupForm/index.tsx +160 -113
  173. package/themes/original/src/components/SingleOrderCard/index.tsx +266 -183
  174. package/themes/original/src/components/SingleOrderCard/styles.tsx +10 -8
  175. package/themes/original/src/components/SingleProductCard/index.tsx +198 -112
  176. package/themes/original/src/components/SingleProductCard/styles.tsx +3 -10
  177. package/themes/original/src/components/SingleProductReview/index.tsx +38 -5
  178. package/themes/original/src/components/SingleProductReview/styles.tsx +12 -0
  179. package/themes/original/src/components/StripeElementsForm/index.tsx +13 -2
  180. package/themes/original/src/components/UpsellingProducts/index.tsx +15 -5
  181. package/themes/original/src/components/UserDetails/index.tsx +5 -3
  182. package/themes/original/src/components/UserFormDetails/index.tsx +6 -48
  183. package/themes/original/src/components/UserProfile/index.tsx +56 -31
  184. package/themes/original/src/components/UserProfile/styles.ts +17 -0
  185. package/themes/original/src/components/WalletTransactions/index.tsx +76 -0
  186. package/themes/original/src/components/WalletTransactions/styles.tsx +13 -0
  187. package/themes/original/src/components/Wallets/index.tsx +176 -164
  188. package/themes/original/src/components/Wallets/styles.tsx +12 -8
  189. package/themes/original/src/components/shared/CardAnimation.tsx +47 -0
  190. package/themes/original/src/components/shared/HeaderTitle.tsx +8 -3
  191. package/themes/original/src/components/shared/OBottomPopup.tsx +48 -15
  192. package/themes/original/src/components/shared/OButton.tsx +10 -3
  193. package/themes/original/src/components/shared/OIcon.tsx +8 -1
  194. package/themes/original/src/components/shared/OInput.tsx +10 -1
  195. package/themes/original/src/layouts/Container.tsx +13 -9
  196. package/themes/original/src/layouts/FloatingBottomContainer.tsx +5 -1
  197. package/themes/original/src/types/index.tsx +83 -28
  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,18 +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}`}
234
+ enableIntersection={!isFiltMode && categoryState.products?.length < 80}
242
235
  isSoldOut={product.inventoried && !product.quantity}
243
236
  businessId={businessId}
244
237
  product={product}
245
238
  categoryState={categoryState}
246
239
  onProductClick={onProductClick}
247
240
  handleUpdateProducts={handleUpdateProducts}
241
+ navigation={navigation}
248
242
  productAddedToCartLength={currentCart?.products?.reduce((productsLength: number, Cproduct: any) => { return productsLength + (Cproduct?.id === product?.id ? Cproduct?.quantity : 0) }, 0)}
249
243
  />
250
244
  ))}
@@ -259,19 +253,24 @@ const BusinessProductsListUI = (props: BusinessProductsListParams) => {
259
253
  <>
260
254
  {[...Array(categoryState?.pagination?.nextPageItems).keys()].map(
261
255
  (item, i) => (
262
- <Placeholder key={i} style={{ padding: 5 }} Animation={Fade}>
263
- <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>
264
269
  <PlaceholderLine
265
- width={24}
266
- height={70}
267
- style={{ marginRight: 10, marginBottom: 10 }}
270
+ height={52}
268
271
  />
269
- <Placeholder style={{ paddingVertical: 10 }}>
270
- <PlaceholderLine width={60} style={{ marginBottom: 25 }} />
271
- <PlaceholderLine width={20} />
272
- </Placeholder>
273
- </View>
274
- </Placeholder>
272
+ </Placeholder>
273
+ </View>
275
274
  ),
276
275
  )}
277
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,5 +1,7 @@
1
1
  import React, { useCallback, useEffect, useRef, useState } from 'react'
2
2
  import { View, TouchableOpacity, StyleSheet, SafeAreaView, Dimensions, Platform, KeyboardAvoidingViewBase, KeyboardAvoidingView } from 'react-native'
3
+ import { IOScrollView } from 'react-native-intersection-observer'
4
+ import { useSafeAreaInsets } from 'react-native-safe-area-context'
3
5
  import { useTheme } from 'styled-components/native';
4
6
  import {
5
7
  BusinessAndProductList,
@@ -11,6 +13,7 @@ import {
11
13
  useToast,
12
14
  useConfig
13
15
  } from 'ordering-components/native'
16
+ import { Fade, Placeholder, PlaceholderLine } from 'rn-placeholder';
14
17
  import { OButton, OIcon, OModal, OText } from '../shared'
15
18
  import Alert from '../../providers/AlertProvider'
16
19
  import { BusinessBasicInformation } from '../BusinessBasicInformation'
@@ -19,21 +22,26 @@ import { BusinessProductsCategories } from '../BusinessProductsCategories'
19
22
  import { BusinessProductsList } from '../BusinessProductsList'
20
23
  import { BusinessProductsListingParams } from '../../types'
21
24
  import { _retrieveStoreData, _removeStoreData } from '../../providers/StoreUtil';
25
+ import IconAntDesign from 'react-native-vector-icons/AntDesign';
26
+ import { useIsFocused } from '@react-navigation/native';
27
+
22
28
  import {
23
29
  TopHeader,
24
30
  WrapSearchBar,
25
31
  WrapContent,
26
- BusinessProductsListingContainer,
27
32
  FiltProductsContainer,
28
33
  ContainerSafeAreaView,
29
34
  BackgroundGray,
30
- ProfessionalFilterWrapper
35
+ ProfessionalFilterWrapper,
36
+ NearBusiness,
37
+ TopActions
31
38
  } from './styles'
32
39
  import { FloatingButton } from '../FloatingButton'
33
40
  import { UpsellingRedirect } from './UpsellingRedirect'
34
41
  import Animated from 'react-native-reanimated'
35
42
  import { ProfessionalFilter } from '../ProfessionalFilter';
36
43
  import { ServiceForm } from '../ServiceForm';
44
+ import { BusinessesListing } from '../BusinessesListing/Layout/Original'
37
45
 
38
46
  const PIXELS_TO_SCROLL = 2000
39
47
 
@@ -58,20 +66,28 @@ const BusinessProductsListingUI = (props: BusinessProductsListingParams) => {
58
66
  getNextProducts,
59
67
  handleUpdateProducts,
60
68
  professionalSelected,
61
- handleChangeProfessionalSelected
69
+ handleChangeProfessionalSelected,
70
+ onBusinessClick
62
71
  } = props
63
72
 
73
+ const insets = useSafeAreaInsets()
64
74
  const theme = useTheme();
65
75
  const [, t] = useLanguage()
66
76
  const [{ auth }] = useSession()
67
- const [orderState, { clearCart }] = useOrder()
77
+ const [orderState, { addProduct, updateProduct }] = useOrder()
68
78
  const [{ parsePrice }] = useUtils()
69
79
  const [, { showToast }] = useToast()
70
80
  const [{ configs }] = useConfig()
81
+ const isFocused = useIsFocused();
71
82
  const isPreOrder = configs?.preorder_status_enabled?.value === '1'
83
+
84
+ const isChewLayout = theme?.business_view?.components?.header?.components?.layout?.type === 'chew'
85
+ const showLogo = !theme?.business_view?.components?.header?.components?.business?.components?.logo?.hidden
86
+ const hideBusinessNearCity = theme?.business_view?.components?.near_business?.hidden ?? true
87
+
72
88
  const styles = StyleSheet.create({
73
89
  mainContainer: {
74
- flex: 1,
90
+ flex: 1
75
91
  },
76
92
  BackIcon: {
77
93
  paddingRight: 20,
@@ -93,7 +109,13 @@ const BusinessProductsListingUI = (props: BusinessProductsListingParams) => {
93
109
  padding: 15,
94
110
  justifyContent: 'center',
95
111
  shadowColor: theme.colors.clear,
96
- }
112
+ },
113
+ businessSkeleton: {
114
+ borderRadius: 8,
115
+ marginRight: 20,
116
+ width: 56,
117
+ height: 56
118
+ },
97
119
  })
98
120
 
99
121
  const { business, loading, error } = businessState
@@ -108,26 +130,51 @@ const BusinessProductsListingUI = (props: BusinessProductsListingParams) => {
108
130
  const [subcategoriesSelected, setSubcategoriesSelected] = useState([])
109
131
  const [openService, setOpenService] = useState(false)
110
132
  const [currentProduct, setCurrentProduct] = useState(null)
133
+ const [searchBarHeight, setSearchBarHeight] = useState(60)
111
134
 
112
135
  const isCheckoutMultiBusinessEnabled: Boolean = configs?.checkout_multi_business_enabled?.value === '1'
136
+ const isQuickAddProduct = configs?.add_product_with_one_click?.value === '1'
137
+ 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) || []
138
+
113
139
  const currentCart: any = Object.values(orderState.carts).find((cart: any) => cart?.business?.slug === business?.slug) ?? {}
114
140
  const isOpenFiltProducts = isOpenSearchBar && !!searchValue
115
- const filtProductsHeight = Platform.OS === 'ios' ? 0 : 35
141
+ const filtProductsHeight = Platform.OS === 'ios' ? 0 : 100
116
142
  const onRedirect = (route: string, params?: any) => {
117
143
  navigation.navigate(route, params)
118
144
  }
119
-
120
- const onProductClick = (product: any) => {
121
- if (product?.type === 'service' && professionalSelected) {
122
- setCurrentProduct(product)
123
- setOpenService(true)
124
- return
145
+ const onProductClick = async (product: any) => {
146
+ if (product.extras.length === 0 && !product.inventoried && auth && isQuickAddProduct) {
147
+ const isProductAddedToCart = currentCart?.products?.find((Cproduct: any) => Cproduct.id === product.id)
148
+ const productQuantity = isProductAddedToCart?.quantity
149
+ const addCurrentProduct = {
150
+ ...product,
151
+ quantity: 1
152
+ }
153
+ const updateCurrentProduct = {
154
+ id: product.id,
155
+ code: isProductAddedToCart?.code,
156
+ quantity: productQuantity + 1
157
+ }
158
+ const cartData = currentCart?.business_id ? currentCart : { business_id: business.id }
159
+ if (isProductAddedToCart) {
160
+ await updateProduct(updateCurrentProduct, cartData, isQuickAddProduct)
161
+ } else {
162
+ await addProduct(addCurrentProduct, cartData, isQuickAddProduct)
163
+ }
164
+ } else {
165
+ const productAddedToCartLength = currentCart?.products?.reduce((productsLength: number, Cproduct: any) => { return productsLength + (Cproduct?.id === product?.id ? Cproduct?.quantity : 0) }, 0) || 0
166
+ if (product?.type === 'service' && business?.professionals?.length > 0) {
167
+ setCurrentProduct(product)
168
+ setOpenService(true)
169
+ return
170
+ }
171
+ onRedirect('ProductDetails', {
172
+ product: product,
173
+ businessSlug: business.slug,
174
+ businessId: business.id,
175
+ productAddedToCartLength
176
+ })
125
177
  }
126
- onRedirect('ProductDetails', {
127
- product: product,
128
- businessSlug: business.slug,
129
- businessId: business.id,
130
- })
131
178
  }
132
179
 
133
180
  const handleCancel = () => {
@@ -136,7 +183,7 @@ const BusinessProductsListingUI = (props: BusinessProductsListingParams) => {
136
183
  }
137
184
 
138
185
  const handleUpsellingPage = () => {
139
- if (isCheckoutMultiBusinessEnabled) {
186
+ if (isCheckoutMultiBusinessEnabled && openCarts.length > 1) {
140
187
  onRedirect('CheckoutNavigator', {
141
188
  screen: 'MultiCheckout'
142
189
  })
@@ -221,32 +268,41 @@ const BusinessProductsListingUI = (props: BusinessProductsListingParams) => {
221
268
  removeCartByReOrder()
222
269
  }, [currentCart])
223
270
 
271
+ useEffect(() => {
272
+ if (!isFocused) {
273
+ handleChangeSearch('')
274
+ setIsOpenSearchBar(false)
275
+ }
276
+ }, [isFocused])
277
+
278
+ const subtotalWithTaxes = currentCart?.taxes?.reduce((acc: any, item: any) => {
279
+ if (item?.type === 1)
280
+ return acc = acc + item?.summary?.tax
281
+ return acc = acc
282
+ }, currentCart?.subtotal)
283
+
224
284
  return (
225
285
  <>
226
- <ContainerSafeAreaView
227
- style={{ flex: 1 }}
228
- isOpenFiltProducts={isOpenFiltProducts}
229
- >
286
+ <View style={{ flex: 1 }}>
230
287
  <Animated.View style={{ position: 'relative' }}>
231
- <TopHeader isIos={Platform.OS === 'ios'}>
288
+ <TopHeader
289
+ style={{
290
+ marginTop: Platform.OS === 'ios' ? insets.top : 0
291
+ }}
292
+ onLayout={(event: any) => setSearchBarHeight(event.nativeEvent.layout.height)}
293
+ >
232
294
  {!isOpenSearchBar && (
233
295
  <>
234
- <View style={{ ...styles.headerItem, flex: 1 }}>
235
- <OButton
236
- imgLeftSrc={theme.images.general.arrow_left}
237
- imgRightSrc={null}
238
- style={styles.btnBackArrow}
239
- onClick={() => handleBackNavigation()}
240
- imgLeftStyle={{ tintColor: theme.colors.textNormal, width: 30 }}
241
- />
242
- </View>
296
+ <TopActions onPress={() => handleBackNavigation()}>
297
+ <OIcon src={theme.images.general.arrow_left} color={theme.colors.textNormal} />
298
+ </TopActions>
243
299
  {!errorQuantityProducts && (
244
300
  <View style={{ ...styles.headerItem }}>
245
301
  <TouchableOpacity
246
302
  onPress={() => setIsOpenSearchBar(true)}
247
303
  style={styles.searchIcon}
248
304
  >
249
- <OIcon src={theme.images.general.search} color={theme.colors.textNormal} width={16} />
305
+ <OIcon src={theme.images.general.search} color={theme.colors.textNormal} width={20} />
250
306
  </TouchableOpacity>
251
307
  </View>
252
308
  )}
@@ -266,14 +322,39 @@ const BusinessProductsListingUI = (props: BusinessProductsListingParams) => {
266
322
  </WrapSearchBar>
267
323
  )}
268
324
  </TopHeader>
325
+ {!hideBusinessNearCity && loading && (
326
+ <NearBusiness style={{ paddingBottom: 10 }}>
327
+ <Placeholder Animation={Fade}>
328
+ <View style={{ flexDirection: 'row' }}>
329
+ {[...Array(10).keys()].map(i => (
330
+ <View style={styles.businessSkeleton} key={i}>
331
+ <PlaceholderLine style={{ width: '100%', height: '100%' }} />
332
+ </View>
333
+ ))}
334
+ </View>
335
+ </Placeholder>
336
+ </NearBusiness>
337
+ )}
338
+ {!loading && !hideBusinessNearCity && businessState?.business?.city_id && (
339
+ <NearBusiness>
340
+ <BusinessesListing
341
+ logosLayout
342
+ propsToFetch={['id', 'logo', 'location', 'timezone', 'schedule', 'open', 'slug']}
343
+ cityId={businessState?.business?.city_id}
344
+ onBusinessClick={onBusinessClick}
345
+ actualSlug={businessState?.business?.slug}
346
+ />
347
+ </NearBusiness>
348
+ )}
269
349
  </Animated.View>
270
350
 
271
351
  {business?.categories?.length > 0 && isOpenFiltProducts && (
272
352
  <FiltProductsContainer
273
- isIos={Platform.OS === 'ios'}
274
353
  style={{
275
- height: Dimensions.get('window').height - filtProductsHeight
354
+ height: Dimensions.get('window').height - filtProductsHeight,
355
+ top: Platform.OS === 'ios' ? searchBarHeight + insets.top : searchBarHeight
276
356
  }}
357
+ contentContainerStyle={{ flexGrow: 1 }}
277
358
  >
278
359
  <View style={{ padding: 20, backgroundColor: theme.colors.white }}>
279
360
  <BusinessProductsList
@@ -301,22 +382,28 @@ const BusinessProductsListingUI = (props: BusinessProductsListingParams) => {
301
382
  setSubcategoriesSelected={setSubcategoriesSelected}
302
383
  onClickCategory={handleChangeCategory}
303
384
  handleUpdateProducts={handleUpdateProducts}
385
+ previouslyProducts={business?.previously_products}
386
+ navigation={navigation}
304
387
  isFiltMode
305
388
  />
306
389
  </View>
307
390
  </FiltProductsContainer>
308
391
  )}
309
392
  {isOpenFiltProducts && (
310
- <BackgroundGray />
393
+ <BackgroundGray isIos={Platform.OS === 'ios'} />
311
394
  )}
312
- <BusinessProductsListingContainer
313
- stickyHeaderIndices={[2]}
314
- style={styles.mainContainer}
395
+ <IOScrollView
396
+ stickyHeaderIndices={[business?.professionals?.length > 0 ? 3 : 2]}
397
+ style={{
398
+ ...styles.mainContainer,
399
+ marginBottom: currentCart?.products?.length > 0 && categoryState.products.length !== 0 ?
400
+ 50 : 0
401
+ }}
315
402
  ref={scrollViewRef}
316
- isActiveFloatingButtom={currentCart?.products?.length > 0 && categoryState.products.length !== 0}
317
403
  onScroll={handlePageScroll}
318
404
  onScrollBeginDrag={handleTouchDrag}
319
405
  scrollEventThrottle={16}
406
+ bounces={false}
320
407
  >
321
408
  <BusinessBasicInformation
322
409
  navigation={navigation}
@@ -342,27 +429,28 @@ const BusinessProductsListingUI = (props: BusinessProductsListingParams) => {
342
429
  />
343
430
  </ProfessionalFilterWrapper>
344
431
  )}
345
- <View style={{ height: 8, backgroundColor: theme.colors.backgroundGray100 }} />
346
- {!loading && business?.id && (
347
- <>
348
- {!(business?.categories?.length === 0) && (
349
- <BusinessProductsCategories
350
- categories={[{ id: null, name: t('ALL', 'All') }, { id: 'featured', name: t('FEATURED', 'Featured') }, ...business?.categories.sort((a: any, b: any) => a.rank - b.rank)]}
351
- categorySelected={categorySelected}
352
- onClickCategory={handleChangeCategory}
353
- featured={featuredProducts}
354
- openBusinessInformation={openBusinessInformation}
355
- scrollViewRef={scrollViewRef}
356
- productListLayout={productListLayout}
357
- categoriesLayout={categoriesLayout}
358
- selectedCategoryId={selectedCategoryId}
359
- lazyLoadProductsRecommended={business?.lazy_load_products_recommended}
360
- setSelectedCategoryId={setSelectedCategoryId}
361
- setCategoryClicked={setCategoryClicked}
362
-
363
- />
364
- )}
365
- </>
432
+ <View
433
+ style={{
434
+ height: 8,
435
+ backgroundColor: theme.colors.backgroundGray100,
436
+ marginTop: isChewLayout && showLogo ? 10 : 0
437
+ }}
438
+ />
439
+ {!loading && business?.id && !(business?.categories?.length === 0) && (
440
+ <BusinessProductsCategories
441
+ categories={[{ id: null, name: t('ALL', 'All') }, { id: 'featured', name: t('FEATURED', 'Featured') }, ...business?.categories.sort((a: any, b: any) => a.rank - b.rank)]}
442
+ categorySelected={categorySelected}
443
+ onClickCategory={handleChangeCategory}
444
+ featured={featuredProducts}
445
+ openBusinessInformation={openBusinessInformation}
446
+ scrollViewRef={scrollViewRef}
447
+ productListLayout={productListLayout}
448
+ categoriesLayout={categoriesLayout}
449
+ selectedCategoryId={selectedCategoryId}
450
+ lazyLoadProductsRecommended={business?.lazy_load_products_recommended}
451
+ setSelectedCategoryId={setSelectedCategoryId}
452
+ setCategoryClicked={setCategoryClicked}
453
+ />
366
454
  )}
367
455
  {!loading && business?.id && (
368
456
  <>
@@ -394,6 +482,8 @@ const BusinessProductsListingUI = (props: BusinessProductsListingParams) => {
394
482
  setSubcategoriesSelected={setSubcategoriesSelected}
395
483
  onClickCategory={handleChangeCategory}
396
484
  handleUpdateProducts={handleUpdateProducts}
485
+ navigation={navigation}
486
+ previouslyProducts={business?.previously_products}
397
487
  />
398
488
  </WrapContent>
399
489
  </>
@@ -416,28 +506,32 @@ const BusinessProductsListingUI = (props: BusinessProductsListingParams) => {
416
506
  isBusinessLoading={loading}
417
507
  errorQuantityProducts={errorQuantityProducts}
418
508
  handleUpdateProducts={handleUpdateProducts}
509
+ navigation={navigation}
419
510
  />
420
511
  </WrapContent>
421
512
  </>
422
513
  )}
423
- </BusinessProductsListingContainer>
514
+ </IOScrollView>
424
515
  {!loading && auth && currentCart?.products?.length > 0 && categoryState.products.length !== 0 && (
425
- <FloatingButton
426
- btnText={
427
- openUpselling
428
- ? t('LOADING', 'Loading')
429
- : currentCart?.subtotal >= currentCart?.minimum
430
- ? t('VIEW_ORDER', 'View Order')
431
- : `${t('MINIMUN_SUBTOTAL_ORDER', 'Minimum subtotal order:')} ${parsePrice(currentCart?.minimum)}`
432
- }
433
- isSecondaryBtn={currentCart?.subtotal < currentCart?.minimum || openUpselling}
434
- btnLeftValueShow={currentCart?.subtotal >= currentCart?.minimum && currentCart?.products?.length > 0}
435
- btnRightValueShow={currentCart?.subtotal >= currentCart?.minimum && currentCart?.products?.length > 0}
436
- btnLeftValue={currentCart?.products.reduce((prev: number, product: any) => prev + product.quantity, 0)}
437
- btnRightValue={parsePrice(currentCart?.total)}
438
- disabled={currentCart?.subtotal < currentCart?.minimum || openUpselling}
439
- handleClick={() => setOpenUpselling(true)}
440
- />
516
+ <View style={{ marginBottom: Platform.OS === 'ios' ? 20 : 0 }}>
517
+ <FloatingButton
518
+ btnText={
519
+ openUpselling
520
+ ? t('LOADING', 'Loading')
521
+ : subtotalWithTaxes >= currentCart?.minimum
522
+ ? t('VIEW_ORDER', 'View Order')
523
+ : `${t('MINIMUN_SUBTOTAL_ORDER', 'Minimum subtotal order:')} ${parsePrice(currentCart?.minimum)}`
524
+ }
525
+ isSecondaryBtn={subtotalWithTaxes < currentCart?.minimum || openUpselling}
526
+ btnLeftValueShow={subtotalWithTaxes >= currentCart?.minimum && currentCart?.products?.length > 0}
527
+ btnRightValueShow={subtotalWithTaxes >= currentCart?.minimum && currentCart?.products?.length > 0}
528
+ btnLeftValue={currentCart?.products.reduce((prev: number, product: any) => prev + product.quantity, 0)}
529
+ btnRightValue={parsePrice(currentCart?.total)}
530
+ disabled={subtotalWithTaxes < currentCart?.minimum || openUpselling}
531
+ hideButton={isCheckoutMultiBusinessEnabled}
532
+ handleClick={() => setOpenUpselling(true)}
533
+ />
534
+ </View>
441
535
  )}
442
536
  {openUpselling && (
443
537
  <UpsellingRedirect
@@ -461,7 +555,7 @@ const BusinessProductsListingUI = (props: BusinessProductsListingParams) => {
461
555
  onAccept={() => setAlertState({ open: false, content: [] })}
462
556
  onClose={() => setAlertState({ open: false, content: [] })}
463
557
  />
464
- </ContainerSafeAreaView>
558
+ </View>
465
559
  <OModal
466
560
  open={openService}
467
561
  onClose={() => setOpenService(false)}
@@ -486,6 +580,7 @@ const BusinessProductsListingUI = (props: BusinessProductsListingParams) => {
486
580
  export const BusinessProductsListing = (props: BusinessProductsListingParams) => {
487
581
  const businessProductslistingProps = {
488
582
  ...props,
583
+ isForceSearch: Platform.OS === 'ios',
489
584
  UIComponent: BusinessProductsListingUI
490
585
  }
491
586
  return (