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