ordering-ui-react-native 0.15.44 → 0.15.45-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 (191) hide show
  1. package/package.json +6 -3
  2. package/src/DeliveryApp.tsx +43 -1
  3. package/src/components/AddressForm/index.tsx +18 -2
  4. package/src/components/BusinessController/index.tsx +16 -8
  5. package/src/components/BusinessTypeFilter/index.tsx +3 -1
  6. package/src/components/BusinessesListing/index.tsx +1 -1
  7. package/src/components/Checkout/index.tsx +23 -2
  8. package/src/components/DriverTips/index.tsx +11 -6
  9. package/src/components/LanguageSelector/index.tsx +7 -2
  10. package/src/components/LoginForm/index.tsx +3 -1
  11. package/src/components/OrderDetails/index.tsx +9 -23
  12. package/src/components/PaymentOptions/index.tsx +1 -1
  13. package/src/components/PaymentOptionsWebView/index.tsx +123 -124
  14. package/src/components/SignupForm/index.tsx +3 -1
  15. package/src/components/SingleProductCard/index.tsx +16 -4
  16. package/src/components/StripeMethodForm/index.tsx +1 -2
  17. package/src/components/UpsellingProducts/index.tsx +1 -1
  18. package/src/components/UserProfileForm/index.tsx +63 -6
  19. package/src/components/UserProfileForm/styles.tsx +8 -0
  20. package/src/components/VerifyPhone/styles.tsx +1 -2
  21. package/src/components/shared/OModal.tsx +1 -1
  22. package/src/hooks/useCountdownTimer.tsx +26 -0
  23. package/src/navigators/CheckoutNavigator.tsx +6 -0
  24. package/src/navigators/HomeNavigator.tsx +12 -0
  25. package/src/pages/BusinessesListing.tsx +1 -1
  26. package/src/pages/MultiCheckout.tsx +31 -0
  27. package/src/pages/MultiOrdersDetails.tsx +27 -0
  28. package/src/pages/Sessions.tsx +22 -0
  29. package/src/theme.json +0 -1
  30. package/src/types/index.tsx +5 -2
  31. package/src/utils/index.tsx +68 -1
  32. package/themes/business/src/components/AcceptOrRejectOrder/index.tsx +103 -15
  33. package/themes/business/src/components/AcceptOrRejectOrder/styles.tsx +6 -0
  34. package/themes/business/src/components/Chat/index.tsx +42 -90
  35. package/themes/business/src/components/DriverMap/index.tsx +6 -5
  36. package/themes/business/src/components/Home/index.tsx +128 -55
  37. package/themes/business/src/components/Home/styles.tsx +8 -1
  38. package/themes/business/src/components/LoginForm/index.tsx +89 -2
  39. package/themes/business/src/components/LoginForm/styles.tsx +6 -0
  40. package/themes/business/src/components/LogoutButton/index.tsx +1 -1
  41. package/themes/business/src/components/NewOrderNotification/index.tsx +79 -105
  42. package/themes/business/src/components/OrderDetails/Business.tsx +1 -1
  43. package/themes/business/src/components/OrderDetails/Delivery.tsx +35 -18
  44. package/themes/business/src/components/OrderDetails/OrderContentComponent.tsx +159 -91
  45. package/themes/business/src/components/OrderDetails/OrderHeaderComponent.tsx +6 -0
  46. package/themes/business/src/components/OrderDetails/styles.tsx +7 -0
  47. package/themes/business/src/components/OrdersListManager/index.tsx +1 -1
  48. package/themes/business/src/components/OrdersOption/index.tsx +5 -2
  49. package/themes/business/src/components/PreviousOrders/index.tsx +10 -9
  50. package/themes/business/src/components/ProductItemAccordion/index.tsx +2 -2
  51. package/themes/business/src/components/shared/OModal.tsx +1 -1
  52. package/themes/business/src/types/index.tsx +5 -1
  53. package/themes/doordash/src/components/BusinessesListing/index.tsx +1 -1
  54. package/themes/doordash/src/components/LoginForm/index.tsx +1 -2
  55. package/themes/instacart/src/components/BusinessesListing/index.tsx +1 -1
  56. package/themes/kiosk/src/components/BusinessMenu/index.tsx +39 -28
  57. package/themes/kiosk/src/components/BusinessesListing/index.tsx +2 -3
  58. package/themes/kiosk/src/components/Cart/index.tsx +99 -26
  59. package/themes/kiosk/src/components/Cart/styles.tsx +6 -0
  60. package/themes/kiosk/src/components/CartBottomSheet/index.tsx +9 -2
  61. package/themes/kiosk/src/components/CartContent/index.tsx +0 -11
  62. package/themes/kiosk/src/components/CartItem/index.tsx +4 -3
  63. package/themes/kiosk/src/components/CategoriesMenu/index.tsx +107 -62
  64. package/themes/kiosk/src/components/Checkout/index.tsx +40 -22
  65. package/themes/kiosk/src/components/CustomerName/index.tsx +0 -6
  66. package/themes/kiosk/src/components/DrawerView/index.tsx +1 -0
  67. package/themes/kiosk/src/components/DrawerView/styles.tsx +2 -2
  68. package/themes/kiosk/src/components/NavBar/index.tsx +29 -20
  69. package/themes/kiosk/src/components/OptionCard/index.tsx +1 -1
  70. package/themes/kiosk/src/components/OrderDetails/index.tsx +165 -65
  71. package/themes/kiosk/src/components/OrderDetails/styles.tsx +5 -0
  72. package/themes/kiosk/src/components/OrderTypeCardSelector/index.tsx +9 -11
  73. package/themes/kiosk/src/components/PaymentOptions/index.tsx +56 -54
  74. package/themes/kiosk/src/components/ProductForm/index.tsx +8 -9
  75. package/themes/kiosk/src/components/ProductItemAccordion/index.tsx +2 -2
  76. package/themes/kiosk/src/components/ProductOption/index.tsx +1 -1
  77. package/themes/kiosk/src/components/ProductOptionSubOption/index.tsx +3 -1
  78. package/themes/kiosk/src/components/UpsellingProducts/index.tsx +16 -5
  79. package/themes/kiosk/src/components/shared/OButton.tsx +5 -18
  80. package/themes/kiosk/src/types/index.d.ts +3 -0
  81. package/themes/original/index.tsx +180 -3
  82. package/themes/original/src/components/ActiveOrders/index.tsx +15 -132
  83. package/themes/original/src/components/ActiveOrders/styles.tsx +0 -54
  84. package/themes/original/src/components/AddressForm/index.tsx +1 -1
  85. package/themes/original/src/components/AddressList/index.tsx +30 -18
  86. package/themes/original/src/components/AppleLogin/index.tsx +117 -78
  87. package/themes/original/src/components/BusinessBasicInformation/index.tsx +70 -41
  88. package/themes/original/src/components/BusinessController/index.tsx +48 -11
  89. package/themes/original/src/components/BusinessController/styles.tsx +27 -0
  90. package/themes/original/src/components/BusinessFeaturedController/index.tsx +20 -1
  91. package/themes/original/src/components/BusinessFeaturedController/styles.tsx +23 -0
  92. package/themes/original/src/components/BusinessItemAccordion/index.tsx +8 -5
  93. package/themes/original/src/components/BusinessItemAccordion/styles.tsx +3 -1
  94. package/themes/original/src/components/BusinessListingSearch/index.tsx +196 -58
  95. package/themes/original/src/components/BusinessListingSearch/styles.tsx +22 -2
  96. package/themes/original/src/components/BusinessPreorder/index.tsx +2 -2
  97. package/themes/original/src/components/BusinessProductsCategories/index.tsx +8 -6
  98. package/themes/original/src/components/BusinessProductsList/CategoryDescription/index.tsx +44 -0
  99. package/themes/original/src/components/BusinessProductsList/index.tsx +120 -36
  100. package/themes/original/src/components/BusinessProductsList/styles.tsx +12 -4
  101. package/themes/original/src/components/BusinessProductsListing/index.tsx +116 -26
  102. package/themes/original/src/components/BusinessProductsListing/styles.tsx +22 -0
  103. package/themes/original/src/components/BusinessReviews/index.tsx +4 -25
  104. package/themes/original/src/components/BusinessTypeFilter/index.tsx +1 -2
  105. package/themes/original/src/components/BusinessesListing/index.tsx +127 -66
  106. package/themes/original/src/components/BusinessesListing/styles.tsx +11 -3
  107. package/themes/original/src/components/Cart/index.tsx +60 -43
  108. package/themes/original/src/components/Checkout/index.tsx +50 -33
  109. package/themes/original/src/components/DriverTips/index.tsx +17 -12
  110. package/themes/original/src/components/Favorite/index.tsx +91 -0
  111. package/themes/original/src/components/Favorite/styles.tsx +22 -0
  112. package/themes/original/src/components/FavoriteList/index.tsx +287 -0
  113. package/themes/original/src/components/FavoriteList/styles.tsx +5 -0
  114. package/themes/original/src/components/ForgotPasswordForm/index.tsx +84 -4
  115. package/themes/original/src/components/GPSButton/index.tsx +15 -8
  116. package/themes/original/src/components/GoogleMap/index.tsx +1 -0
  117. package/themes/original/src/components/Help/index.tsx +21 -4
  118. package/themes/original/src/components/HighestRatedBusinesses/index.tsx +18 -1
  119. package/themes/original/src/components/Home/index.tsx +1 -1
  120. package/themes/original/src/components/LastOrders/index.tsx +12 -1
  121. package/themes/original/src/components/LoginForm/Otp/index.tsx +90 -0
  122. package/themes/original/src/components/LoginForm/Otp/styles.tsx +7 -0
  123. package/themes/original/src/components/LoginForm/index.tsx +394 -155
  124. package/themes/original/src/components/LoginForm/styles.tsx +7 -4
  125. package/themes/original/src/components/LogoutButton/index.tsx +7 -1
  126. package/themes/original/src/components/MessageListing/index.tsx +10 -1
  127. package/themes/original/src/components/Messages/index.tsx +1 -1
  128. package/themes/original/src/components/MomentOption/index.tsx +10 -1
  129. package/themes/original/src/components/MomentOption/styles.tsx +1 -1
  130. package/themes/original/src/components/MultiCartsPaymethodsAndWallets/index.tsx +243 -0
  131. package/themes/original/src/components/MultiCartsPaymethodsAndWallets/styles.tsx +46 -0
  132. package/themes/original/src/components/MultiCheckout/index.tsx +298 -0
  133. package/themes/original/src/components/MultiCheckout/styles.tsx +59 -0
  134. package/themes/original/src/components/MultiOrdersDetails/SingleOrderCard.tsx +372 -0
  135. package/themes/original/src/components/MultiOrdersDetails/index.tsx +258 -0
  136. package/themes/original/src/components/MultiOrdersDetails/styles.tsx +50 -0
  137. package/themes/original/src/components/MyOrders/index.tsx +120 -32
  138. package/themes/original/src/components/MyOrders/styles.tsx +8 -1
  139. package/themes/original/src/components/OrderDetails/index.tsx +64 -44
  140. package/themes/original/src/components/OrderDetails/styles.tsx +1 -2
  141. package/themes/original/src/components/OrderProgress/index.tsx +3 -3
  142. package/themes/original/src/components/OrderProgress/styles.tsx +1 -0
  143. package/themes/original/src/components/OrderSummary/index.tsx +3 -3
  144. package/themes/original/src/components/OrderTypeSelector/index.tsx +4 -2
  145. package/themes/original/src/components/OrdersOption/PreviousBusinessOrdered/index.tsx +153 -0
  146. package/themes/original/src/components/OrdersOption/PreviousBusinessOrdered/styles.tsx +6 -0
  147. package/themes/original/src/components/OrdersOption/PreviousProductsOrdered/index.tsx +53 -0
  148. package/themes/original/src/components/OrdersOption/PreviousProductsOrdered/styles.tsx +6 -0
  149. package/themes/original/src/components/OrdersOption/index.tsx +133 -41
  150. package/themes/original/src/components/OrdersOption/styles.tsx +4 -7
  151. package/themes/original/src/components/PaymentOptionCash/index.tsx +2 -2
  152. package/themes/original/src/components/PaymentOptionWallet/index.tsx +22 -24
  153. package/themes/original/src/components/PaymentOptionWallet/styles.tsx +1 -1
  154. package/themes/original/src/components/PaymentOptions/index.tsx +19 -15
  155. package/themes/original/src/components/PhoneInputNumber/index.tsx +1 -1
  156. package/themes/original/src/components/PreviousOrders/index.tsx +18 -145
  157. package/themes/original/src/components/ProductForm/index.tsx +74 -66
  158. package/themes/original/src/components/ProductForm/styles.tsx +0 -1
  159. package/themes/original/src/components/ProductItemAccordion/index.tsx +2 -2
  160. package/themes/original/src/components/ProductOptionSubOption/index.tsx +18 -12
  161. package/themes/original/src/components/Promotions/index.tsx +250 -0
  162. package/themes/original/src/components/Promotions/styles.tsx +60 -0
  163. package/themes/original/src/components/SearchBar/index.tsx +10 -4
  164. package/themes/original/src/components/Sessions/index.tsx +160 -0
  165. package/themes/original/src/components/Sessions/styles.tsx +15 -0
  166. package/themes/original/src/components/SignupForm/index.tsx +79 -6
  167. package/themes/original/src/components/SingleOrderCard/index.tsx +282 -0
  168. package/themes/original/src/components/SingleOrderCard/styles.tsx +54 -0
  169. package/themes/original/src/components/SingleProductCard/index.tsx +59 -17
  170. package/themes/original/src/components/StripeElementsForm/index.tsx +10 -2
  171. package/themes/original/src/components/StripeElementsForm/naked.tsx +2 -2
  172. package/themes/original/src/components/TaxInformation/index.tsx +10 -4
  173. package/themes/original/src/components/UpsellingProducts/index.tsx +86 -74
  174. package/themes/original/src/components/UserDetails/index.tsx +5 -96
  175. package/themes/original/src/components/UserFormDetails/index.tsx +34 -24
  176. package/themes/original/src/components/UserProfile/index.tsx +59 -5
  177. package/themes/original/src/components/UserProfileForm/index.tsx +20 -18
  178. package/themes/original/src/components/UserVerification/index.tsx +178 -192
  179. package/themes/original/src/components/VerifyPhone/index.tsx +10 -7
  180. package/themes/original/src/components/VerifyPhone/styles.tsx +2 -1
  181. package/themes/original/src/components/Wallets/index.tsx +76 -9
  182. package/themes/original/src/components/Wallets/styles.tsx +21 -0
  183. package/themes/original/src/components/shared/HeaderTitle.tsx +2 -1
  184. package/themes/original/src/components/shared/OModal.tsx +4 -2
  185. package/themes/original/src/config/constants.tsx +6 -6
  186. package/themes/original/src/types/index.tsx +132 -9
  187. package/themes/original/src/utils/index.tsx +19 -2
  188. package/themes/single-business/src/components/AddressList/index.tsx +1 -1
  189. package/themes/single-business/src/components/OrderTypeSelector/index.tsx +1 -1
  190. package/themes/single-business/src/components/UserProfile/index.tsx +1 -1
  191. package/themes/uber-eats/src/components/BusinessesListing/index.tsx +1 -1
@@ -4,12 +4,13 @@ import { SingleProductCard } from '../SingleProductCard';
4
4
  import { NotFoundSource } from '../NotFoundSource';
5
5
  import { BusinessProductsListParams } from '../../types';
6
6
  import { OButton, OIcon, OModal, OText } from '../shared';
7
- import { ProductsContainer, ErrorMessage, WrapperNotFound, RibbonBox } from './styles';
7
+ import { ProductsContainer, ErrorMessage, WrapperNotFound, RibbonBox, SubCategoriesContainer, ContainerButton, HeaderWrapper } from './styles';
8
8
  import { Fade, Placeholder, PlaceholderLine } from 'rn-placeholder';
9
9
  import { View, ScrollView } from 'react-native';
10
10
  import { StyleSheet } from 'react-native';
11
11
  import { useTheme } from 'styled-components/native';
12
12
  import { shape } from '../../utils'
13
+ import { CategoryDescriptionMemoized } from './CategoryDescription';
13
14
 
14
15
  const BusinessProductsListUI = (props: BusinessProductsListParams) => {
15
16
  const {
@@ -28,7 +29,13 @@ const BusinessProductsListUI = (props: BusinessProductsListParams) => {
28
29
  handleCancelSearch,
29
30
  categoriesLayout,
30
31
  setCategoriesLayout,
31
- currentCart
32
+ currentCart,
33
+ setSubcategoriesSelected,
34
+ subcategoriesSelected,
35
+ onClickCategory,
36
+ lazyLoadProductsRecommended,
37
+ handleUpdateProducts,
38
+ isFiltMode
32
39
  } = props;
33
40
 
34
41
  const [, t] = useLanguage();
@@ -44,20 +51,86 @@ const BusinessProductsListUI = (props: BusinessProductsListParams) => {
44
51
  setCategoriesLayout(_categoriesLayout)
45
52
  }
46
53
 
47
- return (
48
- <ProductsContainer>
49
- {category.id &&
50
- categoryState.products?.sort((a: any, b: any) => a.rank - b.rank).map((product: any) => (
51
- <SingleProductCard
52
- key={'prod_' + product.id}
53
- isSoldOut={product.inventoried && !product.quantity}
54
- product={product}
55
- businessId={businessId}
56
- onProductClick={() => onProductClick(product)}
57
- productAddedToCartLength={currentCart?.products?.reduce((productsLength: number, Cproduct: any) => { return productsLength + (Cproduct?.id === product?.id ? Cproduct?.quantity : 0) }, 0)}
54
+ const onClickSubcategory = (subCategory: any, parentCategory: any) => {
55
+ if (parentCategory && lazyLoadProductsRecommended) {
56
+ onClickCategory(parentCategory)
57
+ }
58
+ if (!subCategory) {
59
+ setSubcategoriesSelected?.(subcategoriesSelected.filter((_subcategory: any) => _subcategory?.parent_category_id !== parentCategory?.id))
60
+ return
61
+ }
62
+ const categoryFounded = subcategoriesSelected.find((_subcategory: any) => subCategory?.id === _subcategory?.id)
63
+ if (categoryFounded) {
64
+ setSubcategoriesSelected?.(subcategoriesSelected.filter((_subcategory: any) => subCategory?.id !== _subcategory?.id))
65
+ } else {
66
+ setSubcategoriesSelected?.([...subcategoriesSelected, subCategory])
67
+ }
68
+ }
69
+
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 }}
58
84
  />
59
- ))}
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
+ }
60
107
 
108
+ return (
109
+ <ProductsContainer renderToHardwareTextureAndroid={categoryState.loading || isBusinessLoading}>
110
+ <HeaderWrapper>
111
+ {category?.subcategories?.length > 0 && (
112
+ <SubcategoriesComponent category={category} />
113
+ )}
114
+ </HeaderWrapper>
115
+ {category.id &&
116
+ categoryState.products
117
+ ?.filter((product: any) =>
118
+ !subcategoriesSelected.find((subcategory: any) => subcategory?.parent_category_id === category?.id) ||
119
+ subcategoriesSelected?.some((subcategory: any) => subcategory.id === product?.category_id))
120
+ ?.sort((a: any, b: any) => a.rank - b.rank)
121
+ ?.map((product: any, i: number) => (
122
+ <SingleProductCard
123
+ key={'prod_' + product.id + `_${i}`}
124
+ isSoldOut={product.inventoried && !product.quantity}
125
+ product={product}
126
+ businessId={businessId}
127
+ categoryState={categoryState}
128
+ onProductClick={() => onProductClick(product)}
129
+ productAddedToCartLength={currentCart?.products?.reduce((productsLength: number, Cproduct: any) => { return productsLength + (Cproduct?.id === product?.id ? Cproduct?.quantity : 0) }, 0)}
130
+ handleUpdateProducts={handleUpdateProducts}
131
+ />
132
+ ))
133
+ }
61
134
  {!category.id &&
62
135
  featured &&
63
136
  categoryState?.products?.find((product: any) => product.featured) && (
@@ -72,11 +145,13 @@ const BusinessProductsListUI = (props: BusinessProductsListParams) => {
72
145
  (product: any, i: any) =>
73
146
  product.featured && (
74
147
  <SingleProductCard
75
- key={i}
148
+ key={'feat_' + product.id + `_${i}`}
76
149
  isSoldOut={product.inventoried && !product.quantity}
77
150
  product={product}
78
151
  businessId={businessId}
152
+ categoryState={categoryState}
79
153
  onProductClick={onProductClick}
154
+ handleUpdateProducts={handleUpdateProducts}
80
155
  productAddedToCartLength={currentCart?.products?.reduce((productsLength: number, Cproduct: any) => { return productsLength + (Cproduct?.id === product?.id ? Cproduct?.quantity : 0) }, 0)}
81
156
  />
82
157
  ),
@@ -86,9 +161,14 @@ const BusinessProductsListUI = (props: BusinessProductsListParams) => {
86
161
  )}
87
162
 
88
163
  {!category?.id && categories.filter(category => category?.id !== null).map((category, i, _categories) => {
89
- const products = !isUseParentCategory
164
+ const _products = !isUseParentCategory
90
165
  ? categoryState?.products?.filter((product: any) => product?.category_id === category?.id) ?? []
91
166
  : categoryState?.products?.filter((product: any) => category?.children?.some((cat: any) => cat.category_id === product?.category_id)) ?? []
167
+ const products = subcategoriesSelected?.length > 0
168
+ ? _products?.filter((product: any) =>
169
+ !subcategoriesSelected.find((subcategory: any) => subcategory?.parent_category_id === category?.id) ||
170
+ subcategoriesSelected?.some((subcategory: any) => subcategory.id === product?.category_id))
171
+ : _products
92
172
 
93
173
  const shortCategoryDescription = category?.description?.length > 80 ? `${category?.description?.substring(0, 80)}...` : category?.description
94
174
 
@@ -132,12 +212,12 @@ const BusinessProductsListUI = (props: BusinessProductsListParams) => {
132
212
  </View>
133
213
  {!!category?.description && (
134
214
  <View style={{ position: 'relative' }}>
135
- <OText size={12} weight={'500'} mBottom={5}>
215
+ <OText size={12} weight={'500'} mBottom={10} color='#909BA9'>
136
216
  {shortCategoryDescription}
137
217
  {category?.description?.length > 80 && (
138
218
  <OButton
139
219
  style={{ height: 15, paddingRight: 0, paddingLeft: 0, borderWidth: 0 }}
140
- text={t('SEE_MORE', 'See more')}
220
+ text={t('VIEW_MORE', 'View more')}
141
221
  parentStyle={{ padding: 0 }}
142
222
  onClick={() => setOpenDescription(category)}
143
223
  bgColor='transparent'
@@ -152,14 +232,19 @@ const BusinessProductsListUI = (props: BusinessProductsListParams) => {
152
232
  </OText>
153
233
  </View>
154
234
  )}
235
+ {category?.subcategories?.length > 0 && !isFiltMode && (
236
+ <SubcategoriesComponent category={category} />
237
+ )}
155
238
  <>
156
239
  {products.sort((a: any, b: any) => a.rank - b.rank).map((product: any, i: any) => (
157
240
  <SingleProductCard
158
- key={i}
241
+ key={`${product?.id}_${i}`}
159
242
  isSoldOut={product.inventoried && !product.quantity}
160
243
  businessId={businessId}
161
244
  product={product}
245
+ categoryState={categoryState}
162
246
  onProductClick={onProductClick}
247
+ handleUpdateProducts={handleUpdateProducts}
163
248
  productAddedToCartLength={currentCart?.products?.reduce((productsLength: number, Cproduct: any) => { return productsLength + (Cproduct?.id === product?.id ? Cproduct?.quantity : 0) }, 0)}
164
249
  />
165
250
  ))}
@@ -195,6 +280,7 @@ const BusinessProductsListUI = (props: BusinessProductsListParams) => {
195
280
  !isBusinessLoading &&
196
281
  categoryState.products.length === 0 &&
197
282
  !errors &&
283
+ !isFiltMode &&
198
284
  !(
199
285
  (searchValue && errorQuantityProducts) ||
200
286
  (!searchValue && !errorQuantityProducts)
@@ -234,23 +320,12 @@ const BusinessProductsListUI = (props: BusinessProductsListParams) => {
234
320
  <OText>{e}</OText>
235
321
  </ErrorMessage>
236
322
  ))}
237
- <OModal
238
- open={!!openDescription}
239
- title={openDescription?.name}
240
- onClose={() => setOpenDescription(null)}
241
- >
242
- <ScrollView style={{ padding: 20 }}>
243
- {!!openDescription?.image && (
244
- <OIcon
245
- url={optimizeImage(openDescription?.image, 'h_100,c_limit')}
246
- width={240}
247
- height={240}
248
- style={{ borderRadius: 7.6 }}
249
- />
250
- )}
251
- <OText>{openDescription?.description}</OText>
252
- </ScrollView>
253
- </OModal>
323
+ {!!openDescription && (
324
+ <CategoryDescriptionMemoized
325
+ openDescription={openDescription}
326
+ setOpenDescription={setOpenDescription}
327
+ />
328
+ )}
254
329
  </ProductsContainer>
255
330
  );
256
331
  };
@@ -265,6 +340,15 @@ const bpStyles = StyleSheet.create({
265
340
  shadowRadius: 1,
266
341
  marginEnd: 13,
267
342
  },
343
+ categoryButtonStyle: {
344
+ borderWidth: 0,
345
+ marginLeft: 5,
346
+ marginRight: 5,
347
+ marginBottom: 10,
348
+ height: 35,
349
+ paddingLeft: 3,
350
+ paddingRight: 3,
351
+ }
268
352
  });
269
353
 
270
354
  export const BusinessProductsList = (props: BusinessProductsListParams) => {
@@ -18,16 +18,24 @@ 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
  `}
33
- `
30
+ `
31
+
32
+ export const SubCategoriesContainer = styled.View`
33
+ flex-direction: row;
34
+ flex-wrap: wrap;
35
+ margin-bottom: 10px;
36
+ `
37
+
38
+ export const ContainerButton = styled.View`
39
+ `
40
+
41
+ export const HeaderWrapper = styled.View``
@@ -1,5 +1,5 @@
1
1
  import React, { useCallback, useEffect, useRef, useState } from 'react'
2
- import { View, TouchableOpacity, StyleSheet, SafeAreaView } from 'react-native'
2
+ import { View, TouchableOpacity, StyleSheet, SafeAreaView, Dimensions, Platform, KeyboardAvoidingViewBase, KeyboardAvoidingView } from 'react-native'
3
3
  import { useTheme } from 'styled-components/native';
4
4
  import {
5
5
  BusinessAndProductList,
@@ -12,6 +12,7 @@ import {
12
12
  useConfig
13
13
  } from 'ordering-components/native'
14
14
  import { OButton, OIcon, OModal, OText } from '../shared'
15
+ import Alert from '../../providers/AlertProvider'
15
16
  import { BusinessBasicInformation } from '../BusinessBasicInformation'
16
17
  import { SearchBar } from '../SearchBar'
17
18
  import { BusinessProductsCategories } from '../BusinessProductsCategories'
@@ -22,13 +23,16 @@ import {
22
23
  TopHeader,
23
24
  WrapSearchBar,
24
25
  WrapContent,
25
- BusinessProductsListingContainer
26
+ BusinessProductsListingContainer,
27
+ FiltProductsContainer,
28
+ ContainerSafeAreaView,
29
+ BackgroundGray
26
30
  } from './styles'
27
31
  import { FloatingButton } from '../FloatingButton'
28
32
  import { UpsellingRedirect } from './UpsellingRedirect'
29
33
  import Animated from 'react-native-reanimated'
30
34
 
31
- const PIXELS_TO_SCROLL = 1000
35
+ const PIXELS_TO_SCROLL = 2000
32
36
 
33
37
  const BusinessProductsListingUI = (props: BusinessProductsListingParams) => {
34
38
  const {
@@ -45,7 +49,11 @@ const BusinessProductsListingUI = (props: BusinessProductsListingParams) => {
45
49
  errorQuantityProducts,
46
50
  header,
47
51
  logo,
52
+ alertState,
53
+ setAlertState,
54
+ multiRemoveProducts,
48
55
  getNextProducts,
56
+ handleUpdateProducts
49
57
  } = props
50
58
 
51
59
  const theme = useTheme();
@@ -92,9 +100,12 @@ const BusinessProductsListingUI = (props: BusinessProductsListingParams) => {
92
100
  const [categoriesLayout, setCategoriesLayout] = useState<any>({})
93
101
  const [productListLayout, setProductListLayout] = useState<any>(null)
94
102
  const [isCategoryClicked, setCategoryClicked] = useState(false)
103
+ const [subcategoriesSelected, setSubcategoriesSelected] = useState([])
95
104
 
105
+ const isCheckoutMultiBusinessEnabled: Boolean = configs?.checkout_multi_business_enabled?.value === '1'
96
106
  const currentCart: any = Object.values(orderState.carts).find((cart: any) => cart?.business?.slug === business?.slug) ?? {}
97
-
107
+ const isOpenFiltProducts = isOpenSearchBar && !!searchValue
108
+ const filtProductsHeight = Platform.OS === 'ios' ? 0 : 35
98
109
  const onRedirect = (route: string, params?: any) => {
99
110
  navigation.navigate(route, params)
100
111
  }
@@ -113,13 +124,19 @@ const BusinessProductsListingUI = (props: BusinessProductsListingParams) => {
113
124
  }
114
125
 
115
126
  const handleUpsellingPage = () => {
116
- onRedirect('CheckoutNavigator', {
117
- screen: 'CheckoutPage',
118
- cartUuid: currentCart?.uuid,
119
- businessLogo: logo,
120
- businessName: business?.name,
121
- cartTotal: currentCart?.total
122
- })
127
+ if (isCheckoutMultiBusinessEnabled) {
128
+ onRedirect('CheckoutNavigator', {
129
+ screen: 'MultiCheckout'
130
+ })
131
+ } else {
132
+ onRedirect('CheckoutNavigator', {
133
+ screen: 'CheckoutPage',
134
+ cartUuid: currentCart?.uuid,
135
+ businessLogo: logo,
136
+ businessName: business?.name,
137
+ cartTotal: currentCart?.total
138
+ })
139
+ }
123
140
  setOpenUpselling(false)
124
141
  }
125
142
 
@@ -164,25 +181,41 @@ const BusinessProductsListingUI = (props: BusinessProductsListingParams) => {
164
181
  navigation?.canGoBack() ? navigation.goBack() : navigation.navigate('BottomTab')
165
182
  }
166
183
 
184
+ const adjustBusiness = async (adjustBusinessId: number) => {
185
+ const _carts = orderState?.carts?.[adjustBusinessId]
186
+ const products = _carts?.products
187
+ const unavailableProducts = products.filter((product: any) => product.valid !== true)
188
+ const alreadyRemoved = await _retrieveStoreData('already-removed')
189
+ _removeStoreData('already-removed')
190
+ if (unavailableProducts.length > 0) {
191
+ multiRemoveProducts && await multiRemoveProducts(unavailableProducts, _carts)
192
+ return
193
+ }
194
+
195
+ if (alreadyRemoved === 'removed') {
196
+ setAlertState({ open: true, content: [t('NOT_AVAILABLE_PRODUCT', 'This product is not available.')] })
197
+ }
198
+ }
199
+
167
200
  const removeCartByReOrder = async () => {
168
- const removeCardId = await _retrieveStoreData('remove-cartId')
169
- if (currentCart && removeCardId) {
170
- clearCart(removeCardId)
171
- _removeStoreData('remove-cartId')
172
- showToast(ToastType.Info, t('PRODUCT_REMOVED', 'Products removed from cart'))
201
+ const adjustBusinessId = await _retrieveStoreData('adjust-cart-products')
202
+ if (currentCart && adjustBusinessId) {
203
+ _removeStoreData('adjust-cart-products')
204
+ adjustBusiness(adjustBusinessId)
173
205
  }
174
206
  }
175
207
 
176
208
  useEffect(() => {
177
209
  removeCartByReOrder()
178
- }, [])
210
+ }, [currentCart])
179
211
 
180
212
  return (
181
- <SafeAreaView
213
+ <ContainerSafeAreaView
182
214
  style={{ flex: 1 }}
215
+ isOpenFiltProducts={isOpenFiltProducts}
183
216
  >
184
217
  <Animated.View style={{ position: 'relative' }}>
185
- <TopHeader>
218
+ <TopHeader isIos={Platform.OS === 'ios'}>
186
219
  {!isOpenSearchBar && (
187
220
  <>
188
221
  <View style={{ ...styles.headerItem, flex: 1 }}>
@@ -220,6 +253,47 @@ const BusinessProductsListingUI = (props: BusinessProductsListingParams) => {
220
253
  )}
221
254
  </TopHeader>
222
255
  </Animated.View>
256
+
257
+ {business?.categories?.length > 0 && isOpenFiltProducts && (
258
+ <FiltProductsContainer
259
+ style={{
260
+ height: Dimensions.get('window').height - filtProductsHeight
261
+ }}
262
+ >
263
+ <View style={{ padding: 20, backgroundColor: theme.colors.white }}>
264
+ <BusinessProductsList
265
+ categories={[
266
+ { id: null, name: t('ALL', 'All') },
267
+ { id: 'featured', name: t('FEATURED', 'Featured') },
268
+ ...business?.categories.sort((a: any, b: any) => a.rank - b.rank)
269
+ ]}
270
+ category={categorySelected}
271
+ categoryState={categoryState}
272
+ businessId={business.id}
273
+ errors={errors}
274
+ onProductClick={onProductClick}
275
+ handleSearchRedirect={handleSearchRedirect}
276
+ featured={featuredProducts}
277
+ searchValue={searchValue}
278
+ handleClearSearch={handleChangeSearch}
279
+ errorQuantityProducts={errorQuantityProducts}
280
+ handleCancelSearch={handleCancel}
281
+ categoriesLayout={categoriesLayout}
282
+ subcategoriesSelected={subcategoriesSelected}
283
+ lazyLoadProductsRecommended={business?.lazy_load_products_recommended}
284
+ setCategoriesLayout={setCategoriesLayout}
285
+ currentCart={currentCart}
286
+ setSubcategoriesSelected={setSubcategoriesSelected}
287
+ onClickCategory={handleChangeCategory}
288
+ handleUpdateProducts={handleUpdateProducts}
289
+ isFiltMode
290
+ />
291
+ </View>
292
+ </FiltProductsContainer>
293
+ )}
294
+ {isOpenFiltProducts && (
295
+ <BackgroundGray />
296
+ )}
223
297
  <BusinessProductsListingContainer
224
298
  stickyHeaderIndices={[2]}
225
299
  style={styles.mainContainer}
@@ -254,6 +328,7 @@ const BusinessProductsListingUI = (props: BusinessProductsListingParams) => {
254
328
  lazyLoadProductsRecommended={business?.lazy_load_products_recommended}
255
329
  setSelectedCategoryId={setSelectedCategoryId}
256
330
  setCategoryClicked={setCategoryClicked}
331
+
257
332
  />
258
333
  )}
259
334
  </>
@@ -281,8 +356,13 @@ const BusinessProductsListingUI = (props: BusinessProductsListingParams) => {
281
356
  errorQuantityProducts={errorQuantityProducts}
282
357
  handleCancelSearch={handleCancel}
283
358
  categoriesLayout={categoriesLayout}
359
+ subcategoriesSelected={subcategoriesSelected}
360
+ lazyLoadProductsRecommended={business?.lazy_load_products_recommended}
284
361
  setCategoriesLayout={setCategoriesLayout}
285
362
  currentCart={currentCart}
363
+ setSubcategoriesSelected={setSubcategoriesSelected}
364
+ onClickCategory={handleChangeCategory}
365
+ handleUpdateProducts={handleUpdateProducts}
286
366
  />
287
367
  </WrapContent>
288
368
  </>
@@ -304,6 +384,7 @@ const BusinessProductsListingUI = (props: BusinessProductsListingParams) => {
304
384
  categoryState={categoryState}
305
385
  isBusinessLoading={loading}
306
386
  errorQuantityProducts={errorQuantityProducts}
387
+ handleUpdateProducts={handleUpdateProducts}
307
388
  />
308
389
  </WrapContent>
309
390
  </>
@@ -312,16 +393,18 @@ const BusinessProductsListingUI = (props: BusinessProductsListingParams) => {
312
393
  {!loading && auth && currentCart?.products?.length > 0 && categoryState.products.length !== 0 && (
313
394
  <FloatingButton
314
395
  btnText={
315
- currentCart?.subtotal >= currentCart?.minimum
316
- ? t('VIEW_ORDER', 'View Order')
317
- : `${t('MINIMUN_SUBTOTAL_ORDER', 'Minimum subtotal order:')} ${parsePrice(currentCart?.minimum)}`
396
+ openUpselling
397
+ ? t('LOADING', 'Loading')
398
+ : currentCart?.subtotal >= currentCart?.minimum
399
+ ? t('VIEW_ORDER', 'View Order')
400
+ : `${t('MINIMUN_SUBTOTAL_ORDER', 'Minimum subtotal order:')} ${parsePrice(currentCart?.minimum)}`
318
401
  }
319
- isSecondaryBtn={currentCart?.subtotal < currentCart?.minimum}
402
+ isSecondaryBtn={currentCart?.subtotal < currentCart?.minimum || openUpselling}
320
403
  btnLeftValueShow={currentCart?.subtotal >= currentCart?.minimum && currentCart?.products?.length > 0}
321
404
  btnRightValueShow={currentCart?.subtotal >= currentCart?.minimum && currentCart?.products?.length > 0}
322
- btnLeftValue={currentCart?.products?.length}
405
+ btnLeftValue={currentCart?.products.reduce((prev: number, product: any) => prev + product.quantity, 0)}
323
406
  btnRightValue={parsePrice(currentCart?.total)}
324
- disabled={currentCart?.subtotal < currentCart?.minimum}
407
+ disabled={currentCart?.subtotal < currentCart?.minimum || openUpselling}
325
408
  handleClick={() => setOpenUpselling(true)}
326
409
  />
327
410
  )}
@@ -340,7 +423,14 @@ const BusinessProductsListingUI = (props: BusinessProductsListingParams) => {
340
423
  onRedirect={onRedirect}
341
424
  />
342
425
  )}
343
- </SafeAreaView>
426
+ <Alert
427
+ open={alertState?.open || false}
428
+ title=''
429
+ content={[t('NOT_AVAILABLE_PRODUCTS', 'These products are not available.')]}
430
+ onAccept={() => setAlertState({ open: false, content: [] })}
431
+ onClose={() => setAlertState({ open: false, content: [] })}
432
+ />
433
+ </ContainerSafeAreaView>
344
434
  )
345
435
  }
346
436
 
@@ -1,5 +1,8 @@
1
1
  import styled, { css } from 'styled-components/native'
2
2
 
3
+ export const ContainerSafeAreaView = styled.SafeAreaView`
4
+ `
5
+
3
6
  export const WrapHeader = styled.View`
4
7
  position: relative;
5
8
  `
@@ -11,6 +14,7 @@ export const TopHeader = styled.View`
11
14
  z-index: 1;
12
15
  height: 60px;
13
16
  min-height: 60px;
17
+ margin-top: ${(props : any) => props.isIos ? '0' : '40px'};
14
18
  `
15
19
  export const AddressInput = styled.TouchableOpacity`
16
20
  flex: 1;
@@ -33,3 +37,21 @@ export const BusinessProductsListingContainer = styled.ScrollView`
33
37
  margin-bottom: 50px;
34
38
  `}
35
39
  `
40
+
41
+ export const FiltProductsContainer = styled.ScrollView`
42
+ position: absolute;
43
+ width: 100%;
44
+ z-index: 2000;
45
+ top: ${(props : any) => props.isIos ? '40px': '80px'};
46
+ margin-top: 20px;
47
+ `
48
+
49
+ export const BackgroundGray = styled.View`
50
+ flex: 1;
51
+ height: 100%;
52
+ background-color: rgba(0,0,0,0.5);
53
+ position: absolute;
54
+ margin-top: 100px;
55
+ z-index: 100;
56
+ width: 100%;
57
+ `
@@ -90,33 +90,12 @@ const BusinessReviewsUI = (props: BusinessReviewsParams) => {
90
90
  </View>
91
91
  );
92
92
 
93
- const ReviewItem = ({ comment, created_at, total, customer }: any) => (
93
+ const ReviewItem = ({ comment, created_at, total }: any) => (
94
94
  <View style={{ marginBottom: 30 }}>
95
- <View
96
- style={{ flexDirection: 'row', marginBottom: 19, alignItems: 'center' }}>
97
- <OIcon
98
- url={theme.images.dummies.customerPhoto}
99
- width={38}
100
- height={38}
101
- style={{
102
- borderRadius: 7.6,
103
- borderWidth: 1,
104
- borderColor: theme.colors.border,
105
- marginEnd: 9,
106
- }}
107
- />
108
- <View>
109
- <OText size={12} color={theme.colors.textNormal} weight={'500'}>
110
- {customer?.name || 'Jane Cooper'}
111
- </OText>
112
- <OText size={10} color={theme.colors.textSecondary}>
113
- {moment(created_at).format('MMMM d, yyyy • hh:mm')}
114
- </OText>
115
- </View>
116
- </View>
117
- <OText size={10} color={theme.colors.textNormal}>
118
- {comment}
95
+ <OText size={12} color={theme.colors.textSecondary}>
96
+ {moment(created_at).format('MMMM d, yyyy hh:mm')}
119
97
  </OText>
98
+ <OText size={12} color={theme.colors.textNormal}>{comment}</OText>
120
99
  </View>
121
100
  );
122
101
 
@@ -45,7 +45,6 @@ export const BusinessTypeFilterUI = (props: BusinessTypeFilterParams) => {
45
45
  const renderTypes = ({ item }: any) => {
46
46
  return (
47
47
  <TouchableOpacity
48
- key={item.id}
49
48
  onPress={() => handleChangeBusinessType(item.id)}
50
49
  style={{
51
50
  height: 34,
@@ -103,7 +102,7 @@ export const BusinessTypeFilterUI = (props: BusinessTypeFilterParams) => {
103
102
  showsHorizontalScrollIndicator={false}
104
103
  data={typesState?.types}
105
104
  renderItem={renderTypes}
106
- keyExtractor={(type) => type.name}
105
+ keyExtractor={(type, index) => `${type.name}_${index}`}
107
106
  />
108
107
  <TouchableOpacity
109
108
  style={{ marginLeft: 15 }}