ordering-ui-react-native 0.15.27 → 0.15.29-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 (168) hide show
  1. package/package.json +4 -2
  2. package/src/DeliveryApp.tsx +43 -1
  3. package/src/components/BusinessController/index.tsx +8 -2
  4. package/src/components/BusinessTypeFilter/index.tsx +4 -1
  5. package/src/components/BusinessesListing/index.tsx +1 -1
  6. package/src/components/Checkout/index.tsx +23 -3
  7. package/src/components/DriverTips/index.tsx +11 -6
  8. package/src/components/LanguageSelector/index.tsx +7 -2
  9. package/src/components/OrderDetails/index.tsx +2 -2
  10. package/src/components/PaymentOptions/index.tsx +9 -16
  11. package/src/components/PaymentOptionsWebView/index.tsx +123 -124
  12. package/src/components/SingleProductCard/index.tsx +16 -4
  13. package/src/components/StripeElementsForm/index.tsx +27 -48
  14. package/src/components/UpsellingProducts/index.tsx +1 -1
  15. package/src/components/UserProfileForm/index.tsx +63 -6
  16. package/src/components/UserProfileForm/styles.tsx +8 -0
  17. package/src/components/VerifyPhone/styles.tsx +1 -2
  18. package/src/components/shared/OModal.tsx +1 -1
  19. package/src/config.json +0 -2
  20. package/src/hooks/useCountdownTimer.tsx +26 -0
  21. package/src/navigators/HomeNavigator.tsx +6 -0
  22. package/src/pages/BusinessProductsList.tsx +1 -0
  23. package/src/pages/BusinessesListing.tsx +1 -1
  24. package/src/pages/Checkout.tsx +1 -1
  25. package/src/pages/Sessions.tsx +22 -0
  26. package/src/types/index.tsx +5 -11
  27. package/src/utils/index.tsx +68 -1
  28. package/themes/business/index.tsx +2 -0
  29. package/themes/business/src/components/AcceptOrRejectOrder/index.tsx +103 -15
  30. package/themes/business/src/components/AcceptOrRejectOrder/styles.tsx +6 -0
  31. package/themes/business/src/components/Chat/index.tsx +38 -86
  32. package/themes/business/src/components/DriverMap/index.tsx +6 -5
  33. package/themes/business/src/components/Home/index.tsx +128 -55
  34. package/themes/business/src/components/Home/styles.tsx +8 -1
  35. package/themes/business/src/components/LoginForm/index.tsx +89 -2
  36. package/themes/business/src/components/LoginForm/styles.tsx +6 -0
  37. package/themes/business/src/components/LogoutButton/index.tsx +1 -1
  38. package/themes/business/src/components/NewOrderNotification/index.tsx +79 -105
  39. package/themes/business/src/components/OrderDetails/Business.tsx +2 -1
  40. package/themes/business/src/components/OrderDetails/Delivery.tsx +32 -15
  41. package/themes/business/src/components/OrderDetails/OrderContentComponent.tsx +151 -89
  42. package/themes/business/src/components/OrderDetails/OrderHeaderComponent.tsx +91 -17
  43. package/themes/business/src/components/OrderDetails/styles.tsx +7 -0
  44. package/themes/business/src/components/OrdersListManager/index.tsx +874 -0
  45. package/themes/business/src/components/OrdersListManager/styles.tsx +123 -0
  46. package/themes/business/src/components/OrdersListManager/utils.tsx +216 -0
  47. package/themes/business/src/components/OrdersOption/index.tsx +58 -51
  48. package/themes/business/src/components/PreviousOrders/index.tsx +75 -22
  49. package/themes/business/src/components/shared/OModal.tsx +1 -1
  50. package/themes/business/src/types/index.tsx +5 -1
  51. package/themes/doordash/src/components/BusinessesListing/index.tsx +1 -1
  52. package/themes/doordash/src/components/LoginForm/index.tsx +1 -2
  53. package/themes/instacart/src/components/BusinessesListing/index.tsx +1 -1
  54. package/themes/kiosk/src/components/Cart/index.tsx +98 -24
  55. package/themes/kiosk/src/components/Cart/styles.tsx +6 -0
  56. package/themes/kiosk/src/components/CartBottomSheet/index.tsx +1 -1
  57. package/themes/kiosk/src/components/CartBottomSheet/styles.tsx +1 -1
  58. package/themes/kiosk/src/components/CartContent/index.tsx +13 -3
  59. package/themes/kiosk/src/components/CartItem/index.tsx +20 -8
  60. package/themes/kiosk/src/components/CustomerName/index.tsx +89 -88
  61. package/themes/kiosk/src/components/Intro/index.tsx +13 -13
  62. package/themes/kiosk/src/components/NavBar/index.tsx +14 -14
  63. package/themes/kiosk/src/components/OptionCard/index.tsx +1 -1
  64. package/themes/kiosk/src/components/OrderDetails/index.tsx +136 -41
  65. package/themes/kiosk/src/components/OrderDetails/styles.tsx +5 -0
  66. package/themes/kiosk/src/components/OrderSummary/index.tsx +1 -1
  67. package/themes/kiosk/src/components/OrderTypeCardSelector/index.tsx +10 -12
  68. package/themes/kiosk/src/components/ProductForm/index.tsx +174 -125
  69. package/themes/kiosk/src/components/ProductForm/styles.tsx +1 -1
  70. package/themes/kiosk/src/components/ProductOption/index.tsx +1 -0
  71. package/themes/kiosk/src/components/ProductOption/styles.tsx +1 -0
  72. package/themes/kiosk/src/components/UpsellingProducts/index.tsx +48 -34
  73. package/themes/kiosk/src/components/shared/OButton.tsx +5 -18
  74. package/themes/kiosk/src/types/index.d.ts +2 -0
  75. package/themes/original/index.tsx +178 -1
  76. package/themes/original/src/components/AddressForm/index.tsx +15 -10
  77. package/themes/original/src/components/AddressList/index.tsx +56 -18
  78. package/themes/original/src/components/AppleLogin/index.tsx +117 -78
  79. package/themes/original/src/components/BusinessBasicInformation/index.tsx +96 -45
  80. package/themes/original/src/components/BusinessBasicInformation/styles.tsx +28 -1
  81. package/themes/original/src/components/BusinessController/index.tsx +52 -22
  82. package/themes/original/src/components/BusinessController/styles.tsx +22 -0
  83. package/themes/original/src/components/BusinessFeaturedController/index.tsx +20 -1
  84. package/themes/original/src/components/BusinessFeaturedController/styles.tsx +23 -0
  85. package/themes/original/src/components/BusinessListingSearch/index.tsx +121 -7
  86. package/themes/original/src/components/BusinessListingSearch/styles.tsx +14 -1
  87. package/themes/original/src/components/BusinessMenuList/index.tsx +11 -4
  88. package/themes/original/src/components/BusinessPreorder/index.tsx +142 -122
  89. package/themes/original/src/components/BusinessProductsCategories/index.tsx +9 -7
  90. package/themes/original/src/components/BusinessProductsList/CategoryDescription/index.tsx +44 -0
  91. package/themes/original/src/components/BusinessProductsList/index.tsx +132 -35
  92. package/themes/original/src/components/BusinessProductsList/styles.tsx +29 -2
  93. package/themes/original/src/components/BusinessProductsListing/index.tsx +118 -37
  94. package/themes/original/src/components/BusinessProductsListing/styles.tsx +22 -0
  95. package/themes/original/src/components/BusinessReviews/index.tsx +4 -25
  96. package/themes/original/src/components/BusinessTypeFilter/index.tsx +1 -2
  97. package/themes/original/src/components/BusinessesListing/index.tsx +74 -70
  98. package/themes/original/src/components/Cart/index.tsx +21 -17
  99. package/themes/original/src/components/CartContent/index.tsx +2 -2
  100. package/themes/original/src/components/Checkout/index.tsx +58 -45
  101. package/themes/original/src/components/DriverTips/index.tsx +17 -12
  102. package/themes/original/src/components/ForgotPasswordForm/index.tsx +84 -4
  103. package/themes/original/src/components/GPSButton/index.tsx +15 -8
  104. package/themes/original/src/components/GoogleMap/index.tsx +1 -0
  105. package/themes/original/src/components/Help/index.tsx +21 -4
  106. package/themes/original/src/components/HighestRatedBusinesses/index.tsx +97 -89
  107. package/themes/original/src/components/Home/index.tsx +1 -1
  108. package/themes/original/src/components/LastOrders/index.tsx +12 -1
  109. package/themes/original/src/components/LoginForm/Otp/index.tsx +90 -0
  110. package/themes/original/src/components/LoginForm/Otp/styles.tsx +7 -0
  111. package/themes/original/src/components/LoginForm/index.tsx +389 -156
  112. package/themes/original/src/components/LoginForm/styles.tsx +7 -4
  113. package/themes/original/src/components/LogoutButton/index.tsx +7 -1
  114. package/themes/original/src/components/MessageListing/index.tsx +10 -1
  115. package/themes/original/src/components/Messages/index.tsx +34 -25
  116. package/themes/original/src/components/Messages/styles.tsx +1 -3
  117. package/themes/original/src/components/MomentOption/index.tsx +10 -1
  118. package/themes/original/src/components/MomentOption/styles.tsx +1 -1
  119. package/themes/original/src/components/OrderDetails/index.tsx +56 -33
  120. package/themes/original/src/components/OrderDetails/styles.tsx +1 -2
  121. package/themes/original/src/components/OrderProgress/index.tsx +4 -4
  122. package/themes/original/src/components/OrderProgress/styles.tsx +1 -0
  123. package/themes/original/src/components/OrderSummary/index.tsx +3 -3
  124. package/themes/original/src/components/OrderTypeSelector/index.tsx +4 -2
  125. package/themes/original/src/components/OrdersOption/index.tsx +55 -58
  126. package/themes/original/src/components/OrdersOption/styles.tsx +0 -6
  127. package/themes/original/src/components/PaymentOptionCash/index.tsx +2 -2
  128. package/themes/original/src/components/PaymentOptionWallet/index.tsx +22 -24
  129. package/themes/original/src/components/PaymentOptionWallet/styles.tsx +1 -1
  130. package/themes/original/src/components/PaymentOptions/index.tsx +9 -19
  131. package/themes/original/src/components/PhoneInputNumber/index.tsx +1 -1
  132. package/themes/original/src/components/PreviousOrders/index.tsx +16 -14
  133. package/themes/original/src/components/ProductForm/index.tsx +76 -61
  134. package/themes/original/src/components/ProductForm/styles.tsx +2 -2
  135. package/themes/original/src/components/ProductItemAccordion/index.tsx +2 -2
  136. package/themes/original/src/components/ProductOptionSubOption/index.tsx +18 -12
  137. package/themes/original/src/components/Promotions/index.tsx +250 -0
  138. package/themes/original/src/components/Promotions/styles.tsx +60 -0
  139. package/themes/original/src/components/ReviewOrder/index.tsx +10 -9
  140. package/themes/original/src/components/ReviewProducts/index.tsx +1 -1
  141. package/themes/original/src/components/SearchBar/index.tsx +4 -1
  142. package/themes/original/src/components/Sessions/index.tsx +160 -0
  143. package/themes/original/src/components/Sessions/styles.tsx +15 -0
  144. package/themes/original/src/components/SingleProductCard/index.tsx +47 -21
  145. package/themes/original/src/components/SingleProductCard/styles.tsx +28 -1
  146. package/themes/original/src/components/StripeElementsForm/index.tsx +55 -72
  147. package/themes/original/src/components/TaxInformation/index.tsx +10 -4
  148. package/themes/original/src/components/UpsellingProducts/index.tsx +86 -74
  149. package/themes/original/src/components/UserDetails/index.tsx +4 -95
  150. package/themes/original/src/components/UserFormDetails/index.tsx +34 -24
  151. package/themes/original/src/components/UserProfile/index.tsx +62 -14
  152. package/themes/original/src/components/UserProfileForm/index.tsx +20 -18
  153. package/themes/original/src/components/UserVerification/index.tsx +178 -192
  154. package/themes/original/src/components/VerifyPhone/index.tsx +10 -7
  155. package/themes/original/src/components/VerifyPhone/styles.tsx +2 -1
  156. package/themes/original/src/components/Wallets/index.tsx +76 -9
  157. package/themes/original/src/components/Wallets/styles.tsx +21 -0
  158. package/themes/original/src/components/shared/HeaderTitle.tsx +21 -0
  159. package/themes/original/src/components/shared/OModal.tsx +1 -1
  160. package/themes/original/src/components/shared/index.tsx +2 -0
  161. package/themes/original/src/config/constants.tsx +6 -6
  162. package/themes/original/src/types/index.tsx +68 -6
  163. package/themes/original/src/utils/index.tsx +28 -2
  164. package/themes/single-business/src/components/AddressList/index.tsx +1 -1
  165. package/themes/single-business/src/components/OrderTypeSelector/index.tsx +6 -6
  166. package/themes/single-business/src/components/UserProfile/index.tsx +1 -1
  167. package/themes/uber-eats/src/components/BusinessesListing/index.tsx +1 -1
  168. package/src/components/StripeMethodForm/index.tsx +0 -168
@@ -4,11 +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 } 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
+ import { shape } from '../../utils'
13
+ import { CategoryDescriptionMemoized } from './CategoryDescription';
12
14
 
13
15
  const BusinessProductsListUI = (props: BusinessProductsListParams) => {
14
16
  const {
@@ -27,7 +29,13 @@ const BusinessProductsListUI = (props: BusinessProductsListParams) => {
27
29
  handleCancelSearch,
28
30
  categoriesLayout,
29
31
  setCategoriesLayout,
30
- currentCart
32
+ currentCart,
33
+ setSubcategoriesSelected,
34
+ subcategoriesSelected,
35
+ onClickCategory,
36
+ lazyLoadProductsRecommended,
37
+ handleUpdateProducts,
38
+ isFiltMode
31
39
  } = props;
32
40
 
33
41
  const [, t] = useLanguage();
@@ -43,20 +51,84 @@ const BusinessProductsListUI = (props: BusinessProductsListParams) => {
43
51
  setCategoriesLayout(_categoriesLayout)
44
52
  }
45
53
 
46
- return (
47
- <ProductsContainer>
48
- {category.id &&
49
- categoryState.products?.sort((a: any, b: any) => a.rank - b.rank).map((product: any) => (
50
- <SingleProductCard
51
- key={'prod_' + product.id}
52
- isSoldOut={product.inventoried && !product.quantity}
53
- product={product}
54
- businessId={businessId}
55
- onProductClick={() => onProductClick(product)}
56
- 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 }}
57
84
  />
58
- ))}
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
+ }
59
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
+ onProductClick={() => onProductClick(product)}
128
+ productAddedToCartLength={currentCart?.products?.reduce((productsLength: number, Cproduct: any) => { return productsLength + (Cproduct?.id === product?.id ? Cproduct?.quantity : 0) }, 0)}
129
+ />
130
+ ))
131
+ }
60
132
  {!category.id &&
61
133
  featured &&
62
134
  categoryState?.products?.find((product: any) => product.featured) && (
@@ -71,7 +143,7 @@ const BusinessProductsListUI = (props: BusinessProductsListParams) => {
71
143
  (product: any, i: any) =>
72
144
  product.featured && (
73
145
  <SingleProductCard
74
- key={i}
146
+ key={'feat_' + product.id + `_${i}`}
75
147
  isSoldOut={product.inventoried && !product.quantity}
76
148
  product={product}
77
149
  businessId={businessId}
@@ -85,9 +157,14 @@ const BusinessProductsListUI = (props: BusinessProductsListParams) => {
85
157
  )}
86
158
 
87
159
  {!category?.id && categories.filter(category => category?.id !== null).map((category, i, _categories) => {
88
- const products = !isUseParentCategory
160
+ const _products = !isUseParentCategory
89
161
  ? categoryState?.products?.filter((product: any) => product?.category_id === category?.id) ?? []
90
162
  : categoryState?.products?.filter((product: any) => category?.children?.some((cat: any) => cat.category_id === product?.category_id)) ?? []
163
+ const products = subcategoriesSelected?.length > 0
164
+ ? _products?.filter((product: any) =>
165
+ !subcategoriesSelected.find((subcategory: any) => subcategory?.parent_category_id === category?.id) ||
166
+ subcategoriesSelected?.some((subcategory: any) => subcategory.id === product?.category_id))
167
+ : _products
91
168
 
92
169
  const shortCategoryDescription = category?.description?.length > 80 ? `${category?.description?.substring(0, 80)}...` : category?.description
93
170
 
@@ -110,10 +187,28 @@ const BusinessProductsListUI = (props: BusinessProductsListParams) => {
110
187
  <OText size={16} weight="600">
111
188
  {category.name}
112
189
  </OText>
190
+ {category?.ribbon?.enabled && (
191
+ <RibbonBox
192
+ bgColor={category?.ribbon?.color}
193
+ isRoundRect={category?.ribbon?.shape === shape?.rectangleRound}
194
+ isCapsule={category?.ribbon?.shape === shape?.capsuleShape}
195
+ >
196
+ <OText
197
+ size={10}
198
+ weight={'400'}
199
+ color={theme.colors.white}
200
+ numberOfLines={2}
201
+ ellipsizeMode='tail'
202
+ lineHeight={13}
203
+ >
204
+ {category?.ribbon?.text}
205
+ </OText>
206
+ </RibbonBox>
207
+ )}
113
208
  </View>
114
209
  {!!category?.description && (
115
210
  <View style={{ position: 'relative' }}>
116
- <OText size={12} weight={'500'} mBottom={5}>
211
+ <OText size={12} weight={'500'} mBottom={10} color='#909BA9'>
117
212
  {shortCategoryDescription}
118
213
  {category?.description?.length > 80 && (
119
214
  <OButton
@@ -133,6 +228,9 @@ const BusinessProductsListUI = (props: BusinessProductsListParams) => {
133
228
  </OText>
134
229
  </View>
135
230
  )}
231
+ {category?.subcategories?.length > 0 && !isFiltMode && (
232
+ <SubcategoriesComponent category={category} />
233
+ )}
136
234
  <>
137
235
  {products.sort((a: any, b: any) => a.rank - b.rank).map((product: any, i: any) => (
138
236
  <SingleProductCard
@@ -176,6 +274,7 @@ const BusinessProductsListUI = (props: BusinessProductsListParams) => {
176
274
  !isBusinessLoading &&
177
275
  categoryState.products.length === 0 &&
178
276
  !errors &&
277
+ !isFiltMode &&
179
278
  !(
180
279
  (searchValue && errorQuantityProducts) ||
181
280
  (!searchValue && !errorQuantityProducts)
@@ -215,29 +314,18 @@ const BusinessProductsListUI = (props: BusinessProductsListParams) => {
215
314
  <OText>{e}</OText>
216
315
  </ErrorMessage>
217
316
  ))}
218
- <OModal
219
- open={!!openDescription}
220
- title={openDescription?.name}
221
- onClose={() => setOpenDescription(null)}
222
- >
223
- <ScrollView style={{ padding: 20 }}>
224
- {!!openDescription?.image && (
225
- <OIcon
226
- url={optimizeImage(openDescription?.image, 'h_100,c_limit')}
227
- width={240}
228
- height={240}
229
- style={{ borderRadius: 7.6 }}
230
- />
231
- )}
232
- <OText>{openDescription?.description}</OText>
233
- </ScrollView>
234
- </OModal>
317
+ {!!openDescription && (
318
+ <CategoryDescriptionMemoized
319
+ openDescription={openDescription}
320
+ setOpenDescription={setOpenDescription}
321
+ />
322
+ )}
235
323
  </ProductsContainer>
236
324
  );
237
325
  };
238
326
 
239
327
  const bpStyles = StyleSheet.create({
240
- catWrap: { flexDirection: 'row', alignItems: 'center', height: 41, marginBottom: 19 },
328
+ catWrap: { flexDirection: 'row', alignItems: 'center', marginBottom: 19 },
241
329
  catIcon: {
242
330
  borderRadius: 7.6,
243
331
  shadowColor: '#000000',
@@ -246,6 +334,15 @@ const bpStyles = StyleSheet.create({
246
334
  shadowRadius: 1,
247
335
  marginEnd: 13,
248
336
  },
337
+ categoryButtonStyle: {
338
+ borderWidth: 0,
339
+ marginLeft: 5,
340
+ marginRight: 5,
341
+ marginBottom: 10,
342
+ height: 35,
343
+ paddingLeft: 3,
344
+ paddingRight: 3,
345
+ }
249
346
  });
250
347
 
251
348
  export const BusinessProductsList = (props: BusinessProductsListParams) => {
@@ -1,4 +1,4 @@
1
- import styled from 'styled-components/native'
1
+ import styled, { css } from 'styled-components/native'
2
2
 
3
3
  export const ProductsContainer = styled.View`
4
4
  `
@@ -11,4 +11,31 @@ export const ErrorMessage = styled.View`
11
11
 
12
12
  export const WrapperNotFound = styled.View`
13
13
  height: 500px;
14
- `
14
+ `
15
+
16
+ export const RibbonBox = styled.View`
17
+ margin-left: 5px;
18
+ background-color: ${(props: any) => props.theme.colors.primary};
19
+ padding: 2px 8px;
20
+ max-width: 180px;
21
+ ${(props: any) => props.bgColor && css`
22
+ background-color: ${props.bgColor};
23
+ `}
24
+ ${(props: any) => props.isRoundRect && css`
25
+ border-radius: 7.6px;
26
+ `}
27
+ ${(props: any) => props.isCapsule && css`
28
+ border-radius: 50px;
29
+ `}
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,22 +12,27 @@ 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'
18
19
  import { BusinessProductsList } from '../BusinessProductsList'
19
20
  import { BusinessProductsListingParams } from '../../types'
21
+ import { _retrieveStoreData, _removeStoreData } from '../../providers/StoreUtil';
20
22
  import {
21
23
  TopHeader,
22
24
  WrapSearchBar,
23
25
  WrapContent,
24
- BusinessProductsListingContainer
26
+ BusinessProductsListingContainer,
27
+ FiltProductsContainer,
28
+ ContainerSafeAreaView,
29
+ BackgroundGray
25
30
  } from './styles'
26
31
  import { FloatingButton } from '../FloatingButton'
27
32
  import { UpsellingRedirect } from './UpsellingRedirect'
28
33
  import Animated from 'react-native-reanimated'
29
34
 
30
- const PIXELS_TO_SCROLL = 1000
35
+ const PIXELS_TO_SCROLL = 2000
31
36
 
32
37
  const BusinessProductsListingUI = (props: BusinessProductsListingParams) => {
33
38
  const {
@@ -44,13 +49,16 @@ const BusinessProductsListingUI = (props: BusinessProductsListingParams) => {
44
49
  errorQuantityProducts,
45
50
  header,
46
51
  logo,
52
+ alertState,
53
+ setAlertState,
54
+ multiRemoveProducts,
47
55
  getNextProducts,
48
56
  } = props
49
57
 
50
58
  const theme = useTheme();
51
59
  const [, t] = useLanguage()
52
60
  const [{ auth }] = useSession()
53
- const [orderState] = useOrder()
61
+ const [orderState, { clearCart }] = useOrder()
54
62
  const [{ parsePrice }] = useUtils()
55
63
  const [, { showToast }] = useToast()
56
64
  const [{ configs }] = useConfig()
@@ -72,6 +80,7 @@ const BusinessProductsListingUI = (props: BusinessProductsListingParams) => {
72
80
  borderWidth: 0,
73
81
  backgroundColor: theme.colors.clear,
74
82
  shadowColor: theme.colors.clear,
83
+ padding: 40,
75
84
  },
76
85
  searchIcon: {
77
86
  borderWidth: 0,
@@ -90,32 +99,21 @@ const BusinessProductsListingUI = (props: BusinessProductsListingParams) => {
90
99
  const [categoriesLayout, setCategoriesLayout] = useState<any>({})
91
100
  const [productListLayout, setProductListLayout] = useState<any>(null)
92
101
  const [isCategoryClicked, setCategoryClicked] = useState(false)
102
+ const [subcategoriesSelected, setSubcategoriesSelected] = useState([])
93
103
 
94
104
  const currentCart: any = Object.values(orderState.carts).find((cart: any) => cart?.business?.slug === business?.slug) ?? {}
95
-
105
+ const isOpenFiltProducts = isOpenSearchBar && !!searchValue
106
+ const filtProductsHeight = Platform.OS === 'ios' ? 0 : 35
96
107
  const onRedirect = (route: string, params?: any) => {
97
108
  navigation.navigate(route, params)
98
109
  }
99
110
 
100
111
  const onProductClick = (product: any) => {
101
- const cartProduct = currentCart?.products?.find((cproduct: any) => cproduct?.id === product?.id)
102
- if (cartProduct) {
103
- onRedirect('ProductDetails', {
104
- businessId: business.id,
105
- isCartProduct: true,
106
- productCart: cartProduct,
107
- businessSlug: business?.slug,
108
- categoryId: cartProduct?.category_id,
109
- productId: cartProduct?.id,
110
- })
111
- } else {
112
- onRedirect('ProductDetails', {
113
- product: product,
114
- businessSlug: business.slug,
115
- businessId: business.id,
116
- })
117
- }
118
-
112
+ onRedirect('ProductDetails', {
113
+ product: product,
114
+ businessSlug: business.slug,
115
+ businessId: business.id,
116
+ })
119
117
  }
120
118
 
121
119
  const handleCancel = () => {
@@ -169,18 +167,47 @@ const BusinessProductsListingUI = (props: BusinessProductsListingParams) => {
169
167
 
170
168
  const handleTouchDrag = useCallback(() => {
171
169
  setCategoryClicked(false);
172
- }, []);
173
-
170
+ }, []);
171
+
174
172
  const handleBackNavigation = () => {
175
173
  navigation?.canGoBack() ? navigation.goBack() : navigation.navigate('BottomTab')
176
174
  }
177
175
 
176
+ const adjustBusiness = async (adjustBusinessId: number) => {
177
+ const _carts = orderState?.carts?.[adjustBusinessId]
178
+ const products = _carts?.products
179
+ const unavailableProducts = products.filter((product: any) => product.valid !== true)
180
+ const alreadyRemoved = await _retrieveStoreData('already-removed')
181
+ _removeStoreData('already-removed')
182
+ if (unavailableProducts.length > 0) {
183
+ multiRemoveProducts && await multiRemoveProducts(unavailableProducts, _carts)
184
+ return
185
+ }
186
+
187
+ if (alreadyRemoved === 'removed') {
188
+ setAlertState({ open: true, content: [t('NOT_AVAILABLE_PRODUCT', 'This product is not available.')] })
189
+ }
190
+ }
191
+
192
+ const removeCartByReOrder = async () => {
193
+ const adjustBusinessId = await _retrieveStoreData('adjust-cart-products')
194
+ if (currentCart && adjustBusinessId) {
195
+ _removeStoreData('adjust-cart-products')
196
+ adjustBusiness(adjustBusinessId)
197
+ }
198
+ }
199
+
200
+ useEffect(() => {
201
+ removeCartByReOrder()
202
+ }, [currentCart])
203
+
178
204
  return (
179
- <SafeAreaView
205
+ <ContainerSafeAreaView
180
206
  style={{ flex: 1 }}
207
+ isOpenFiltProducts={isOpenFiltProducts}
181
208
  >
182
209
  <Animated.View style={{ position: 'relative' }}>
183
- <TopHeader>
210
+ <TopHeader isIos={Platform.OS === 'ios'}>
184
211
  {!isOpenSearchBar && (
185
212
  <>
186
213
  <View style={{ ...styles.headerItem, flex: 1 }}>
@@ -218,6 +245,46 @@ const BusinessProductsListingUI = (props: BusinessProductsListingParams) => {
218
245
  )}
219
246
  </TopHeader>
220
247
  </Animated.View>
248
+
249
+ {business?.categories?.length > 0 && isOpenFiltProducts && (
250
+ <FiltProductsContainer
251
+ style={{
252
+ height: Dimensions.get('window').height - filtProductsHeight
253
+ }}
254
+ >
255
+ <View style={{ padding: 20, backgroundColor: theme.colors.white }}>
256
+ <BusinessProductsList
257
+ categories={[
258
+ { id: null, name: t('ALL', 'All') },
259
+ { id: 'featured', name: t('FEATURED', 'Featured') },
260
+ ...business?.categories.sort((a: any, b: any) => a.rank - b.rank)
261
+ ]}
262
+ category={categorySelected}
263
+ categoryState={categoryState}
264
+ businessId={business.id}
265
+ errors={errors}
266
+ onProductClick={onProductClick}
267
+ handleSearchRedirect={handleSearchRedirect}
268
+ featured={featuredProducts}
269
+ searchValue={searchValue}
270
+ handleClearSearch={handleChangeSearch}
271
+ errorQuantityProducts={errorQuantityProducts}
272
+ handleCancelSearch={handleCancel}
273
+ categoriesLayout={categoriesLayout}
274
+ subcategoriesSelected={subcategoriesSelected}
275
+ lazyLoadProductsRecommended={business?.lazy_load_products_recommended}
276
+ setCategoriesLayout={setCategoriesLayout}
277
+ currentCart={currentCart}
278
+ setSubcategoriesSelected={setSubcategoriesSelected}
279
+ onClickCategory={handleChangeCategory}
280
+ isFiltMode
281
+ />
282
+ </View>
283
+ </FiltProductsContainer>
284
+ )}
285
+ {isOpenFiltProducts && (
286
+ <BackgroundGray />
287
+ )}
221
288
  <BusinessProductsListingContainer
222
289
  stickyHeaderIndices={[2]}
223
290
  style={styles.mainContainer}
@@ -251,7 +318,8 @@ const BusinessProductsListingUI = (props: BusinessProductsListingParams) => {
251
318
  selectedCategoryId={selectedCategoryId}
252
319
  lazyLoadProductsRecommended={business?.lazy_load_products_recommended}
253
320
  setSelectedCategoryId={setSelectedCategoryId}
254
- setCategoryClicked={setCategoryClicked}
321
+ setCategoryClicked={setCategoryClicked}
322
+
255
323
  />
256
324
  )}
257
325
  </>
@@ -279,8 +347,12 @@ const BusinessProductsListingUI = (props: BusinessProductsListingParams) => {
279
347
  errorQuantityProducts={errorQuantityProducts}
280
348
  handleCancelSearch={handleCancel}
281
349
  categoriesLayout={categoriesLayout}
350
+ subcategoriesSelected={subcategoriesSelected}
351
+ lazyLoadProductsRecommended={business?.lazy_load_products_recommended}
282
352
  setCategoriesLayout={setCategoriesLayout}
283
353
  currentCart={currentCart}
354
+ setSubcategoriesSelected={setSubcategoriesSelected}
355
+ onClickCategory={handleChangeCategory}
284
356
  />
285
357
  </WrapContent>
286
358
  </>
@@ -310,16 +382,18 @@ const BusinessProductsListingUI = (props: BusinessProductsListingParams) => {
310
382
  {!loading && auth && currentCart?.products?.length > 0 && categoryState.products.length !== 0 && (
311
383
  <FloatingButton
312
384
  btnText={
313
- currentCart?.subtotal >= currentCart?.minimum
314
- ? t('VIEW_ORDER', 'View Order')
315
- : `${t('MINIMUN_SUBTOTAL_ORDER', 'Minimum subtotal order:')} ${parsePrice(currentCart?.minimum)}`
385
+ openUpselling
386
+ ? t('LOADING', 'Loading')
387
+ : currentCart?.subtotal >= currentCart?.minimum
388
+ ? t('VIEW_ORDER', 'View Order')
389
+ : `${t('MINIMUN_SUBTOTAL_ORDER', 'Minimum subtotal order:')} ${parsePrice(currentCart?.minimum)}`
316
390
  }
317
- isSecondaryBtn={currentCart?.subtotal < currentCart?.minimum}
391
+ isSecondaryBtn={currentCart?.subtotal < currentCart?.minimum || openUpselling}
318
392
  btnLeftValueShow={currentCart?.subtotal >= currentCart?.minimum && currentCart?.products?.length > 0}
319
393
  btnRightValueShow={currentCart?.subtotal >= currentCart?.minimum && currentCart?.products?.length > 0}
320
- btnLeftValue={currentCart?.products?.length}
394
+ btnLeftValue={currentCart?.products.reduce((prev: number, product: any) => prev + product.quantity, 0)}
321
395
  btnRightValue={parsePrice(currentCart?.total)}
322
- disabled={currentCart?.subtotal < currentCart?.minimum}
396
+ disabled={currentCart?.subtotal < currentCart?.minimum || openUpselling}
323
397
  handleClick={() => setOpenUpselling(true)}
324
398
  />
325
399
  )}
@@ -329,16 +403,23 @@ const BusinessProductsListingUI = (props: BusinessProductsListingParams) => {
329
403
  business={currentCart?.business}
330
404
  cartProducts={currentCart?.products}
331
405
  cart={currentCart}
332
- setOpenUpselling={setOpenUpselling}
406
+ setOpenUpselling={setOpenUpselling}
333
407
  handleUpsellingPage={handleUpsellingPage}
334
408
  handleCloseUpsellingPage={handleCloseUpsellingPage}
335
409
  openUpselling={openUpselling}
336
410
  canOpenUpselling={canOpenUpselling}
337
411
  setCanOpenUpselling={setCanOpenUpselling}
338
- onRedirect={onRedirect}
412
+ onRedirect={onRedirect}
339
413
  />
340
414
  )}
341
- </SafeAreaView>
415
+ <Alert
416
+ open={alertState?.open || false}
417
+ title=''
418
+ content={[t('NOT_AVAILABLE_PRODUCTS', 'These products are not available.')]}
419
+ onAccept={() => setAlertState({ open: false, content: [] })}
420
+ onClose={() => setAlertState({ open: false, content: [] })}
421
+ />
422
+ </ContainerSafeAreaView>
342
423
  )
343
424
  }
344
425
 
@@ -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 }}