ordering-ui-react-native 0.16.57 → 0.16.58-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 +33 -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 +26 -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/UserFormDetails/index.tsx +5 -2
  53. package/themes/business/src/components/UserProfileForm/index.tsx +2 -0
  54. package/themes/business/src/components/shared/ODropDown.tsx +42 -8
  55. package/themes/business/src/components/shared/ODropDownCalendar.tsx +36 -7
  56. package/themes/business/src/components/shared/OLink.tsx +33 -13
  57. package/themes/business/src/components/shared/OText.tsx +8 -2
  58. package/themes/business/src/types/index.tsx +25 -11
  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 +8 -0
  74. package/themes/original/src/components/AddressDetails/index.tsx +10 -8
  75. package/themes/original/src/components/AddressForm/index.tsx +153 -137
  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 +53 -37
  79. package/themes/original/src/components/BusinessController/index.tsx +112 -48
  80. package/themes/original/src/components/BusinessController/styles.tsx +14 -9
  81. package/themes/original/src/components/BusinessInformation/index.tsx +10 -31
  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 +80 -138
  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 -61
  91. package/themes/original/src/components/BusinessProductsList/styles.tsx +0 -3
  92. package/themes/original/src/components/BusinessProductsListing/index.tsx +177 -81
  93. package/themes/original/src/components/BusinessProductsListing/styles.tsx +14 -12
  94. package/themes/original/src/components/BusinessTypeFilter/index.tsx +3 -2
  95. package/themes/original/src/components/BusinessesListing/Layout/Appointment/index.tsx +2 -1
  96. package/themes/original/src/components/BusinessesListing/Layout/Original/index.tsx +112 -107
  97. package/themes/original/src/components/BusinessesListing/Layout/Original/styles.tsx +1 -9
  98. package/themes/original/src/components/BusinessesListing/index.tsx +16 -9
  99. package/themes/original/src/components/Cart/index.tsx +108 -18
  100. package/themes/original/src/components/Cart/styles.tsx +4 -0
  101. package/themes/original/src/components/CartContent/index.tsx +31 -17
  102. package/themes/original/src/components/CartContent/styles.tsx +1 -1
  103. package/themes/original/src/components/Checkout/index.tsx +114 -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 +0 -1
  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 +10 -1
  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 +96 -65
  129. package/themes/original/src/components/MultiOrdersDetails/index.tsx +34 -16
  130. package/themes/original/src/components/MyOrders/index.tsx +89 -25
  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 +20 -0
  136. package/themes/original/src/components/OrderDetails/index.tsx +114 -15
  137. package/themes/original/src/components/OrderDetails/styles.tsx +15 -2
  138. package/themes/original/src/components/OrderItAgain/index.tsx +75 -0
  139. package/themes/original/src/components/OrderItAgain/styles.tsx +10 -0
  140. package/themes/original/src/components/OrderProgress/index.tsx +77 -66
  141. package/themes/original/src/components/OrderProgress/styles.tsx +5 -0
  142. package/themes/original/src/components/OrderSummary/index.tsx +2 -35
  143. package/themes/original/src/components/OrderTypeSelector/index.tsx +85 -36
  144. package/themes/original/src/components/OrderTypeSelector/styles.tsx +19 -1
  145. package/themes/original/src/components/OrdersOption/PreviousBusinessOrdered/index.tsx +94 -98
  146. package/themes/original/src/components/OrdersOption/PreviousProductsOrdered/index.tsx +3 -0
  147. package/themes/original/src/components/OrdersOption/index.tsx +95 -55
  148. package/themes/original/src/components/PaymentOptionWallet/index.tsx +56 -56
  149. package/themes/original/src/components/PaymentOptions/index.tsx +1 -2
  150. package/themes/original/src/components/PhoneInputNumber/index.tsx +1 -1
  151. package/themes/original/src/components/PlaceSpot/index.tsx +249 -47
  152. package/themes/original/src/components/PlaceSpot/styles.tsx +0 -2
  153. package/themes/original/src/components/PreviousOrders/index.tsx +3 -2
  154. package/themes/original/src/components/ProductForm/index.tsx +367 -384
  155. package/themes/original/src/components/ProductForm/styles.tsx +7 -12
  156. package/themes/original/src/components/ProductItemAccordion/index.tsx +199 -128
  157. package/themes/original/src/components/ProductOption/index.tsx +1 -1
  158. package/themes/original/src/components/ProductOptionSubOption/index.tsx +16 -8
  159. package/themes/original/src/components/ProductOptionSubOption/styles.tsx +0 -1
  160. package/themes/original/src/components/ProfessionalFilter/index.tsx +2 -1
  161. package/themes/original/src/components/ProfessionalProfile/index.tsx +19 -8
  162. package/themes/original/src/components/Promotions/index.tsx +232 -219
  163. package/themes/original/src/components/Promotions/styles.tsx +7 -2
  164. package/themes/original/src/components/ReviewDriver/index.tsx +3 -3
  165. package/themes/original/src/components/ReviewOrder/index.tsx +43 -11
  166. package/themes/original/src/components/ReviewOrder/styles.tsx +7 -0
  167. package/themes/original/src/components/ReviewProducts/index.tsx +8 -5
  168. package/themes/original/src/components/ReviewTrigger/index.tsx +27 -9
  169. package/themes/original/src/components/ReviewTrigger/styles.tsx +8 -1
  170. package/themes/original/src/components/ScheduleAccordion/index.tsx +68 -0
  171. package/themes/original/src/components/ScheduleAccordion/styles.tsx +14 -0
  172. package/themes/original/src/components/ServiceForm/index.tsx +330 -266
  173. package/themes/original/src/components/SignupForm/index.tsx +134 -89
  174. package/themes/original/src/components/SingleOrderCard/index.tsx +224 -132
  175. package/themes/original/src/components/SingleOrderCard/styles.tsx +10 -8
  176. package/themes/original/src/components/SingleProductCard/index.tsx +116 -72
  177. package/themes/original/src/components/SingleProductCard/styles.tsx +2 -9
  178. package/themes/original/src/components/SingleProductReview/index.tsx +38 -5
  179. package/themes/original/src/components/SingleProductReview/styles.tsx +12 -0
  180. package/themes/original/src/components/StripeElementsForm/index.tsx +13 -2
  181. package/themes/original/src/components/UpsellingProducts/index.tsx +15 -5
  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 +11 -7
  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 +63 -8
  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,7 +185,36 @@ const BusinessProductsListingUI = (props: BusinessProductsListingParams) => {
146
185
  }
147
186
 
148
187
  const handleUpsellingPage = () => {
149
- if (isCheckoutMultiBusinessEnabled) {
188
+ setOpenUpselling(false)
189
+ setCanOpenUpselling(false)
190
+ const cartSelectedHasGroup = currentCart?.group?.uuid
191
+ const cartFilterValidation = (cart: any) => cart?.valid && cart?.status !== 2
192
+ const cartsGroupLength = cartSelectedHasGroup ? Object.values(orderState.carts).filter((_cart: any) => _cart?.group?.uuid === cartSelectedHasGroup && cartFilterValidation(_cart))?.length : 0
193
+ if (cartsGroupLength > 1 && isCheckoutMultiBusinessEnabled) {
194
+ props.onNavigationRedirect('CheckoutNavigator', {
195
+ screen: 'MultiCheckout',
196
+ cartUuid: currentCart?.group?.uuid
197
+ })
198
+ return
199
+ }
200
+ const cartGroupsCount: any = {}
201
+ Object.values(orderState.carts).filter(_cart => cartFilterValidation(_cart))?.forEach((_cart: any) => {
202
+ if (cartGroupsCount[_cart?.group?.uuid]) {
203
+ cartGroupsCount[_cart?.group?.uuid] += 1
204
+ } else {
205
+ cartGroupsCount[_cart?.group?.uuid] = 1
206
+ }
207
+ })
208
+ let groupForTheCart
209
+ const groupForAddCartArray = Object.keys(cartGroupsCount).filter(cartGroupUuid => cartGroupsCount[cartGroupUuid] > 0 && cartGroupsCount[cartGroupUuid] < 5)
210
+ const max = Math.max(...groupForAddCartArray.map(uuid => cartGroupsCount[uuid]))
211
+ const indexes = groupForAddCartArray.filter(uuid => cartGroupsCount[uuid] === max)
212
+ if (indexes?.length > 1) {
213
+ groupForTheCart = indexes.find(uuid => uuid !== 'undefined')
214
+ } else {
215
+ groupForTheCart = indexes[0]
216
+ }
217
+ if (isCheckoutMultiBusinessEnabled && openCarts.length > 1) {
150
218
  onRedirect('CheckoutNavigator', {
151
219
  screen: 'MultiCheckout'
152
220
  })
@@ -231,33 +299,41 @@ const BusinessProductsListingUI = (props: BusinessProductsListingParams) => {
231
299
  removeCartByReOrder()
232
300
  }, [currentCart])
233
301
 
302
+ useEffect(() => {
303
+ if (!isFocused) {
304
+ handleChangeSearch('')
305
+ setIsOpenSearchBar(false)
306
+ }
307
+ }, [isFocused])
308
+
309
+ const subtotalWithTaxes = currentCart?.taxes?.reduce((acc: any, item: any) => {
310
+ if (item?.type === 1)
311
+ return acc = acc + item?.summary?.tax
312
+ return acc = acc
313
+ }, currentCart?.subtotal)
314
+
234
315
  return (
235
316
  <>
236
- <ContainerSafeAreaView
237
- style={{ flex: 1 }}
238
- isOpenFiltProducts={isOpenFiltProducts}
239
- >
317
+ <View style={{ flex: 1 }}>
240
318
  <Animated.View style={{ position: 'relative' }}>
241
- <TopHeader isIos={Platform.OS === 'ios'}>
319
+ <TopHeader
320
+ style={{
321
+ marginTop: Platform.OS === 'ios' ? insets.top : 0
322
+ }}
323
+ onLayout={(event: any) => setSearchBarHeight(event.nativeEvent.layout.height)}
324
+ >
242
325
  {!isOpenSearchBar && (
243
326
  <>
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>
327
+ <TopActions onPress={() => handleBackNavigation()}>
328
+ <OIcon src={theme.images.general.arrow_left} color={theme.colors.textNormal} />
329
+ </TopActions>
254
330
  {!errorQuantityProducts && (
255
331
  <View style={{ ...styles.headerItem }}>
256
332
  <TouchableOpacity
257
333
  onPress={() => setIsOpenSearchBar(true)}
258
334
  style={styles.searchIcon}
259
335
  >
260
- <OIcon src={theme.images.general.search} color={theme.colors.textNormal} width={16} />
336
+ <OIcon src={theme.images.general.search} color={theme.colors.textNormal} width={20} />
261
337
  </TouchableOpacity>
262
338
  </View>
263
339
  )}
@@ -277,7 +353,20 @@ const BusinessProductsListingUI = (props: BusinessProductsListingParams) => {
277
353
  </WrapSearchBar>
278
354
  )}
279
355
  </TopHeader>
280
- {showBusinessNearCity && (
356
+ {!hideBusinessNearCity && loading && (
357
+ <NearBusiness style={{ paddingBottom: 10 }}>
358
+ <Placeholder Animation={Fade}>
359
+ <View style={{ flexDirection: 'row' }}>
360
+ {[...Array(10).keys()].map(i => (
361
+ <View style={styles.businessSkeleton} key={i}>
362
+ <PlaceholderLine style={{ width: '100%', height: '100%' }} />
363
+ </View>
364
+ ))}
365
+ </View>
366
+ </Placeholder>
367
+ </NearBusiness>
368
+ )}
369
+ {!loading && !hideBusinessNearCity && businessState?.business?.city_id && (
281
370
  <NearBusiness>
282
371
  <BusinessesListing
283
372
  logosLayout
@@ -292,10 +381,11 @@ const BusinessProductsListingUI = (props: BusinessProductsListingParams) => {
292
381
 
293
382
  {business?.categories?.length > 0 && isOpenFiltProducts && (
294
383
  <FiltProductsContainer
295
- isIos={Platform.OS === 'ios'}
296
384
  style={{
297
- height: Dimensions.get('window').height - filtProductsHeight
385
+ height: Dimensions.get('window').height - filtProductsHeight,
386
+ top: Platform.OS === 'ios' ? searchBarHeight + insets.top : searchBarHeight
298
387
  }}
388
+ contentContainerStyle={{ flexGrow: 1 }}
299
389
  >
300
390
  <View style={{ padding: 20, backgroundColor: theme.colors.white }}>
301
391
  <BusinessProductsList
@@ -323,16 +413,18 @@ const BusinessProductsListingUI = (props: BusinessProductsListingParams) => {
323
413
  setSubcategoriesSelected={setSubcategoriesSelected}
324
414
  onClickCategory={handleChangeCategory}
325
415
  handleUpdateProducts={handleUpdateProducts}
416
+ previouslyProducts={business?.previously_products}
417
+ navigation={navigation}
326
418
  isFiltMode
327
419
  />
328
420
  </View>
329
421
  </FiltProductsContainer>
330
422
  )}
331
423
  {isOpenFiltProducts && (
332
- <BackgroundGray />
424
+ <BackgroundGray isIos={Platform.OS === 'ios'} />
333
425
  )}
334
426
  <IOScrollView
335
- stickyHeaderIndices={[2]}
427
+ stickyHeaderIndices={[business?.professionals?.length > 0 ? 3 : 2]}
336
428
  style={{
337
429
  ...styles.mainContainer,
338
430
  marginBottom: currentCart?.products?.length > 0 && categoryState.products.length !== 0 ?
@@ -342,6 +434,7 @@ const BusinessProductsListingUI = (props: BusinessProductsListingParams) => {
342
434
  onScroll={handlePageScroll}
343
435
  onScrollBeginDrag={handleTouchDrag}
344
436
  scrollEventThrottle={16}
437
+ bounces={false}
345
438
  >
346
439
  <BusinessBasicInformation
347
440
  navigation={navigation}
@@ -374,31 +467,27 @@ const BusinessProductsListingUI = (props: BusinessProductsListingParams) => {
374
467
  marginTop: isChewLayout && showLogo ? 10 : 0
375
468
  }}
376
469
  />
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
- </>
470
+ {!loading && business?.id && !(business?.categories?.length === 0) && (
471
+ <BusinessProductsCategories
472
+ categories={[{ id: null, name: t('ALL', 'All') }, { id: 'featured', name: t('FEATURED', 'Featured') }, ...business?.categories.sort((a: any, b: any) => a.rank - b.rank)]}
473
+ categorySelected={categorySelected}
474
+ onClickCategory={handleChangeCategory}
475
+ featured={featuredProducts}
476
+ openBusinessInformation={openBusinessInformation}
477
+ scrollViewRef={scrollViewRef}
478
+ productListLayout={productListLayout}
479
+ categoriesLayout={categoriesLayout}
480
+ selectedCategoryId={selectedCategoryId}
481
+ lazyLoadProductsRecommended={business?.lazy_load_products_recommended}
482
+ setSelectedCategoryId={setSelectedCategoryId}
483
+ setCategoryClicked={setCategoryClicked}
484
+ />
397
485
  )}
398
486
  {!loading && business?.id && (
399
487
  <>
400
488
  <WrapContent
401
489
  onLayout={(event: any) => setProductListLayout(event.nativeEvent.layout)}
490
+ style={{ paddingHorizontal: isChewLayout ? 20 : 40 }}
402
491
  >
403
492
  <BusinessProductsList
404
493
  categories={[
@@ -425,6 +514,8 @@ const BusinessProductsListingUI = (props: BusinessProductsListingParams) => {
425
514
  setSubcategoriesSelected={setSubcategoriesSelected}
426
515
  onClickCategory={handleChangeCategory}
427
516
  handleUpdateProducts={handleUpdateProducts}
517
+ navigation={navigation}
518
+ previouslyProducts={business?.previously_products}
428
519
  />
429
520
  </WrapContent>
430
521
  </>
@@ -447,28 +538,31 @@ const BusinessProductsListingUI = (props: BusinessProductsListingParams) => {
447
538
  isBusinessLoading={loading}
448
539
  errorQuantityProducts={errorQuantityProducts}
449
540
  handleUpdateProducts={handleUpdateProducts}
541
+ navigation={navigation}
450
542
  />
451
543
  </WrapContent>
452
544
  </>
453
545
  )}
454
546
  </IOScrollView>
455
547
  {!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
- />
548
+ <View style={{ marginBottom: Platform.OS === 'ios' ? 20 : 0 }}>
549
+ <FloatingButton
550
+ btnText={
551
+ openUpselling
552
+ ? t('LOADING', 'Loading')
553
+ : subtotalWithTaxes >= currentCart?.minimum
554
+ ? t('VIEW_ORDER', 'View Order')
555
+ : `${t('MINIMUN_SUBTOTAL_ORDER', 'Minimum subtotal order:')} ${parsePrice(currentCart?.minimum)}`
556
+ }
557
+ isSecondaryBtn={subtotalWithTaxes < currentCart?.minimum || openUpselling}
558
+ btnLeftValueShow={subtotalWithTaxes >= currentCart?.minimum && currentCart?.products?.length > 0}
559
+ btnRightValueShow={subtotalWithTaxes >= currentCart?.minimum && currentCart?.products?.length > 0}
560
+ btnLeftValue={currentCart?.products.reduce((prev: number, product: any) => prev + product.quantity, 0)}
561
+ btnRightValue={parsePrice(currentCart?.total)}
562
+ disabled={subtotalWithTaxes < currentCart?.minimum || openUpselling}
563
+ handleClick={() => setOpenUpselling(true)}
564
+ />
565
+ </View>
472
566
  )}
473
567
  {openUpselling && (
474
568
  <UpsellingRedirect
@@ -492,7 +586,7 @@ const BusinessProductsListingUI = (props: BusinessProductsListingParams) => {
492
586
  onAccept={() => setAlertState({ open: false, content: [] })}
493
587
  onClose={() => setAlertState({ open: false, content: [] })}
494
588
  />
495
- </ContainerSafeAreaView>
589
+ </View>
496
590
  <OModal
497
591
  open={openService}
498
592
  onClose={() => setOpenService(false)}
@@ -506,6 +600,7 @@ const BusinessProductsListingUI = (props: BusinessProductsListingParams) => {
506
600
  professionalList={business?.professionals}
507
601
  professionalSelected={professionalSelected}
508
602
  handleChangeProfessional={handleChangeProfessionalSelected}
603
+ handleUpdateProfessionals={handleUpdateProfessionals}
509
604
  onSave={() => setOpenService(false)}
510
605
  onClose={() => setOpenService(false)}
511
606
  />
@@ -517,6 +612,7 @@ const BusinessProductsListingUI = (props: BusinessProductsListingParams) => {
517
612
  export const BusinessProductsListing = (props: BusinessProductsListingParams) => {
518
613
  const businessProductslistingProps = {
519
614
  ...props,
615
+ isForceSearch: Platform.OS === 'ios',
520
616
  UIComponent: BusinessProductsListingUI
521
617
  }
522
618
  return (