ordering-ui-react-native 0.15.63 → 0.15.65-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 (213) hide show
  1. package/package.json +7 -3
  2. package/src/DeliveryApp.tsx +43 -1
  3. package/src/components/AddressForm/index.tsx +18 -2
  4. package/src/components/BusinessBasicInformation/index.tsx +11 -19
  5. package/src/components/BusinessController/index.tsx +16 -8
  6. package/src/components/BusinessInformation/index.tsx +14 -0
  7. package/src/components/BusinessTypeFilter/index.tsx +1 -2
  8. package/src/components/BusinessesListing/index.tsx +1 -1
  9. package/src/components/Checkout/index.tsx +23 -2
  10. package/src/components/DriverTips/index.tsx +11 -6
  11. package/src/components/LanguageSelector/index.tsx +6 -2
  12. package/src/components/LoginForm/index.tsx +120 -30
  13. package/src/components/LoginForm/styles.tsx +6 -0
  14. package/src/components/OrderDetails/index.tsx +7 -21
  15. package/src/components/PaymentOptions/index.tsx +67 -50
  16. package/src/components/PaymentOptionsWebView/index.tsx +120 -121
  17. package/src/components/ReviewDriver/index.tsx +1 -1
  18. package/src/components/ReviewOrder/index.tsx +2 -1
  19. package/src/components/ReviewProducts/index.tsx +11 -0
  20. package/src/components/SignupForm/index.tsx +145 -61
  21. package/src/components/SingleProductCard/index.tsx +16 -4
  22. package/src/components/SingleProductReview/index.tsx +1 -1
  23. package/src/components/StripeMethodForm/index.tsx +22 -24
  24. package/src/components/UpsellingProducts/index.tsx +1 -1
  25. package/src/components/UserProfileForm/index.tsx +63 -6
  26. package/src/components/UserProfileForm/styles.tsx +8 -0
  27. package/src/components/VerifyPhone/styles.tsx +1 -2
  28. package/src/components/shared/OModal.tsx +1 -1
  29. package/src/hooks/useCountdownTimer.tsx +26 -0
  30. package/src/navigators/CheckoutNavigator.tsx +6 -0
  31. package/src/navigators/HomeNavigator.tsx +12 -0
  32. package/src/pages/BusinessesListing.tsx +7 -6
  33. package/src/pages/MultiCheckout.tsx +31 -0
  34. package/src/pages/MultiOrdersDetails.tsx +27 -0
  35. package/src/pages/OrderDetails.tsx +1 -1
  36. package/src/pages/ReviewDriver.tsx +2 -2
  37. package/src/pages/ReviewOrder.tsx +2 -2
  38. package/src/pages/Sessions.tsx +22 -0
  39. package/src/theme.json +0 -1
  40. package/src/types/index.tsx +18 -11
  41. package/src/utils/index.tsx +68 -1
  42. package/themes/business/src/components/AcceptOrRejectOrder/index.tsx +103 -15
  43. package/themes/business/src/components/AcceptOrRejectOrder/styles.tsx +6 -0
  44. package/themes/business/src/components/Chat/index.tsx +42 -90
  45. package/themes/business/src/components/DriverMap/index.tsx +6 -5
  46. package/themes/business/src/components/LoginForm/index.tsx +89 -2
  47. package/themes/business/src/components/LoginForm/styles.tsx +6 -0
  48. package/themes/business/src/components/LogoutButton/index.tsx +1 -1
  49. package/themes/business/src/components/NewOrderNotification/index.tsx +26 -13
  50. package/themes/business/src/components/OrderDetails/Business.tsx +2 -2
  51. package/themes/business/src/components/OrderDetails/Delivery.tsx +28 -11
  52. package/themes/business/src/components/OrderDetails/OrderContentComponent.tsx +14 -7
  53. package/themes/business/src/components/OrderDetails/OrderHeaderComponent.tsx +6 -0
  54. package/themes/business/src/components/OrdersListManager/index.tsx +1 -1
  55. package/themes/business/src/components/OrdersOption/index.tsx +8 -4
  56. package/themes/business/src/components/PreviousOrders/index.tsx +7 -7
  57. package/themes/business/src/components/ProductItemAccordion/index.tsx +2 -2
  58. package/themes/business/src/components/UserFormDetails/index.tsx +5 -2
  59. package/themes/business/src/components/UserProfileForm/index.tsx +2 -0
  60. package/themes/business/src/components/shared/OModal.tsx +1 -1
  61. package/themes/business/src/types/index.tsx +8 -2
  62. package/themes/doordash/src/components/BusinessesListing/index.tsx +1 -1
  63. package/themes/doordash/src/components/LoginForm/index.tsx +1 -2
  64. package/themes/instacart/src/components/BusinessesListing/index.tsx +1 -1
  65. package/themes/kiosk/src/components/BusinessMenu/index.tsx +39 -28
  66. package/themes/kiosk/src/components/BusinessesListing/index.tsx +2 -3
  67. package/themes/kiosk/src/components/Cart/index.tsx +11 -12
  68. package/themes/kiosk/src/components/CartBottomSheet/index.tsx +9 -2
  69. package/themes/kiosk/src/components/CartContent/index.tsx +0 -11
  70. package/themes/kiosk/src/components/CartItem/index.tsx +4 -3
  71. package/themes/kiosk/src/components/CategoriesMenu/index.tsx +107 -62
  72. package/themes/kiosk/src/components/Checkout/index.tsx +40 -22
  73. package/themes/kiosk/src/components/CustomerName/index.tsx +0 -6
  74. package/themes/kiosk/src/components/DrawerView/index.tsx +1 -0
  75. package/themes/kiosk/src/components/DrawerView/styles.tsx +2 -2
  76. package/themes/kiosk/src/components/NavBar/index.tsx +29 -20
  77. package/themes/kiosk/src/components/OptionCard/index.tsx +1 -1
  78. package/themes/kiosk/src/components/OrderDetails/index.tsx +32 -27
  79. package/themes/kiosk/src/components/OrderTypeCardSelector/index.tsx +9 -11
  80. package/themes/kiosk/src/components/PaymentOptions/index.tsx +56 -54
  81. package/themes/kiosk/src/components/ProductForm/index.tsx +7 -8
  82. package/themes/kiosk/src/components/ProductItemAccordion/index.tsx +2 -2
  83. package/themes/kiosk/src/components/ProductOption/index.tsx +1 -1
  84. package/themes/kiosk/src/components/ProductOptionSubOption/index.tsx +3 -1
  85. package/themes/kiosk/src/components/UpsellingProducts/index.tsx +16 -5
  86. package/themes/kiosk/src/components/shared/OButton.tsx +5 -18
  87. package/themes/kiosk/src/types/index.d.ts +1 -0
  88. package/themes/original/index.tsx +30 -8
  89. package/themes/original/src/components/ActiveOrders/index.tsx +15 -132
  90. package/themes/original/src/components/ActiveOrders/styles.tsx +0 -54
  91. package/themes/original/src/components/AddressForm/index.tsx +7 -6
  92. package/themes/original/src/components/AddressList/index.tsx +30 -18
  93. package/themes/original/src/components/AppleLogin/index.tsx +6 -8
  94. package/themes/original/src/components/BusinessBasicInformation/index.tsx +305 -159
  95. package/themes/original/src/components/BusinessBasicInformation/styles.tsx +6 -2
  96. package/themes/original/src/components/BusinessController/index.tsx +168 -96
  97. package/themes/original/src/components/BusinessController/styles.tsx +5 -0
  98. package/themes/original/src/components/BusinessItemAccordion/index.tsx +8 -5
  99. package/themes/original/src/components/BusinessItemAccordion/styles.tsx +3 -1
  100. package/themes/original/src/components/BusinessListingSearch/index.tsx +231 -63
  101. package/themes/original/src/components/BusinessListingSearch/styles.tsx +22 -2
  102. package/themes/original/src/components/BusinessPreorder/index.tsx +1 -1
  103. package/themes/original/src/components/BusinessProductsCategories/index.tsx +2 -2
  104. package/themes/original/src/components/BusinessProductsList/CategoryDescription/index.tsx +44 -0
  105. package/themes/original/src/components/BusinessProductsList/index.tsx +51 -52
  106. package/themes/original/src/components/BusinessProductsList/styles.tsx +0 -3
  107. package/themes/original/src/components/BusinessProductsListing/index.tsx +318 -155
  108. package/themes/original/src/components/BusinessProductsListing/styles.tsx +32 -0
  109. package/themes/original/src/components/BusinessReviews/index.tsx +6 -1
  110. package/themes/original/src/components/BusinessTypeFilter/index.tsx +106 -39
  111. package/themes/original/src/components/BusinessTypeFilter/styles.tsx +2 -0
  112. package/themes/original/src/components/BusinessesListing/Layout/Appointment/index.tsx +560 -0
  113. package/themes/original/src/components/BusinessesListing/{styles.tsx → Layout/Appointment/styles.tsx} +24 -2
  114. package/themes/original/src/components/BusinessesListing/Layout/Original/index.tsx +679 -0
  115. package/themes/original/src/components/BusinessesListing/Layout/Original/styles.tsx +137 -0
  116. package/themes/original/src/components/BusinessesListing/index.tsx +99 -458
  117. package/themes/original/src/components/Cart/index.tsx +61 -42
  118. package/themes/original/src/components/Checkout/index.tsx +90 -39
  119. package/themes/original/src/components/DriverTips/index.tsx +17 -12
  120. package/themes/original/src/components/Favorite/index.tsx +92 -0
  121. package/themes/original/src/components/Favorite/styles.tsx +22 -0
  122. package/themes/original/src/components/FavoriteList/index.tsx +298 -0
  123. package/themes/original/src/components/FavoriteList/styles.tsx +5 -0
  124. package/themes/original/src/components/ForgotPasswordForm/index.tsx +84 -4
  125. package/themes/original/src/components/GPSButton/index.tsx +15 -8
  126. package/themes/original/src/components/GoogleMap/index.tsx +11 -11
  127. package/themes/original/src/components/Help/index.tsx +21 -4
  128. package/themes/original/src/components/HighestRatedBusinesses/index.tsx +18 -1
  129. package/themes/original/src/components/LastOrders/index.tsx +12 -1
  130. package/themes/original/src/components/LoginForm/Otp/index.tsx +91 -0
  131. package/themes/original/src/components/LoginForm/Otp/styles.tsx +7 -0
  132. package/themes/original/src/components/LoginForm/index.tsx +332 -164
  133. package/themes/original/src/components/LoginForm/styles.tsx +1 -3
  134. package/themes/original/src/components/MessageListing/index.tsx +10 -1
  135. package/themes/original/src/components/Messages/index.tsx +1 -1
  136. package/themes/original/src/components/MomentOption/index.tsx +10 -1
  137. package/themes/original/src/components/MomentOption/styles.tsx +1 -1
  138. package/themes/original/src/components/MomentSelector/index.tsx +197 -0
  139. package/themes/original/src/components/MomentSelector/styles.tsx +6 -0
  140. package/themes/original/src/components/MultiCartsPaymethodsAndWallets/index.tsx +243 -0
  141. package/themes/original/src/components/MultiCartsPaymethodsAndWallets/styles.tsx +46 -0
  142. package/themes/original/src/components/MultiCheckout/index.tsx +298 -0
  143. package/themes/original/src/components/MultiCheckout/styles.tsx +59 -0
  144. package/themes/original/src/components/MultiOrdersDetails/SingleOrderCard.tsx +372 -0
  145. package/themes/original/src/components/MultiOrdersDetails/index.tsx +258 -0
  146. package/themes/original/src/components/MultiOrdersDetails/styles.tsx +50 -0
  147. package/themes/original/src/components/MyOrders/index.tsx +120 -32
  148. package/themes/original/src/components/MyOrders/styles.tsx +8 -1
  149. package/themes/original/src/components/NavBar/index.tsx +4 -4
  150. package/themes/original/src/components/OrderDetails/OrderHistory.tsx +167 -0
  151. package/themes/original/src/components/OrderDetails/index.tsx +150 -64
  152. package/themes/original/src/components/OrderDetails/styles.tsx +1 -2
  153. package/themes/original/src/components/OrderSummary/index.tsx +6 -6
  154. package/themes/original/src/components/OrderTypeSelector/index.tsx +79 -35
  155. package/themes/original/src/components/OrderTypeSelector/styles.tsx +19 -1
  156. package/themes/original/src/components/OrdersOption/PreviousBusinessOrdered/index.tsx +153 -0
  157. package/themes/original/src/components/OrdersOption/PreviousBusinessOrdered/styles.tsx +6 -0
  158. package/themes/original/src/components/OrdersOption/PreviousProductsOrdered/index.tsx +53 -0
  159. package/themes/original/src/components/OrdersOption/PreviousProductsOrdered/styles.tsx +6 -0
  160. package/themes/original/src/components/OrdersOption/index.tsx +137 -38
  161. package/themes/original/src/components/OrdersOption/styles.tsx +4 -1
  162. package/themes/original/src/components/PaymentOptionCash/index.tsx +2 -2
  163. package/themes/original/src/components/PaymentOptionWallet/index.tsx +17 -23
  164. package/themes/original/src/components/PaymentOptionWallet/styles.tsx +1 -1
  165. package/themes/original/src/components/PaymentOptions/index.tsx +58 -37
  166. package/themes/original/src/components/PhoneInputNumber/index.tsx +5 -11
  167. package/themes/original/src/components/PreviousOrders/index.tsx +18 -147
  168. package/themes/original/src/components/ProductForm/index.tsx +718 -679
  169. package/themes/original/src/components/ProductForm/styles.tsx +6 -2
  170. package/themes/original/src/components/ProductItemAccordion/index.tsx +2 -2
  171. package/themes/original/src/components/ProductOption/index.tsx +1 -1
  172. package/themes/original/src/components/ProductOptionSubOption/index.tsx +18 -12
  173. package/themes/original/src/components/ProfessionalFilter/index.tsx +128 -0
  174. package/themes/original/src/components/ProfessionalFilter/styles.tsx +0 -0
  175. package/themes/original/src/components/ProfessionalProfile/index.tsx +298 -0
  176. package/themes/original/src/components/ProfessionalProfile/styles.tsx +46 -0
  177. package/themes/original/src/components/Promotions/index.tsx +151 -133
  178. package/themes/original/src/components/Promotions/styles.tsx +3 -23
  179. package/themes/original/src/components/ReviewDriver/index.tsx +6 -6
  180. package/themes/original/src/components/ReviewOrder/index.tsx +1 -1
  181. package/themes/original/src/components/ReviewTrigger/index.tsx +118 -0
  182. package/themes/original/src/components/ReviewTrigger/styles.tsx +34 -0
  183. package/themes/original/src/components/SearchBar/index.tsx +13 -5
  184. package/themes/original/src/components/ServiceForm/index.tsx +579 -0
  185. package/themes/original/src/components/ServiceForm/styles.tsx +50 -0
  186. package/themes/original/src/components/Sessions/index.tsx +160 -0
  187. package/themes/original/src/components/Sessions/styles.tsx +15 -0
  188. package/themes/original/src/components/SignupForm/index.tsx +237 -126
  189. package/themes/original/src/components/SingleOrderCard/index.tsx +275 -0
  190. package/themes/original/src/components/SingleOrderCard/styles.tsx +54 -0
  191. package/themes/original/src/components/SingleProductCard/index.tsx +161 -88
  192. package/themes/original/src/components/SingleProductCard/styles.tsx +2 -2
  193. package/themes/original/src/components/StripeElementsForm/index.tsx +16 -8
  194. package/themes/original/src/components/StripeElementsForm/naked.tsx +2 -2
  195. package/themes/original/src/components/UpsellingProducts/index.tsx +86 -74
  196. package/themes/original/src/components/UserDetails/index.tsx +15 -81
  197. package/themes/original/src/components/UserFormDetails/index.tsx +98 -66
  198. package/themes/original/src/components/UserProfile/index.tsx +11 -2
  199. package/themes/original/src/components/UserProfileForm/index.tsx +33 -22
  200. package/themes/original/src/components/UserVerification/index.tsx +178 -192
  201. package/themes/original/src/components/VerifyPhone/index.tsx +10 -7
  202. package/themes/original/src/components/VerifyPhone/styles.tsx +2 -1
  203. package/themes/original/src/components/Wallets/index.tsx +76 -9
  204. package/themes/original/src/components/Wallets/styles.tsx +21 -0
  205. package/themes/original/src/components/shared/OBottomPopup.tsx +44 -13
  206. package/themes/original/src/components/shared/OButton.tsx +2 -0
  207. package/themes/original/src/components/shared/OInput.tsx +3 -2
  208. package/themes/original/src/components/shared/OModal.tsx +4 -2
  209. package/themes/original/src/layouts/FloatingBottomContainer.tsx +5 -1
  210. package/themes/original/src/types/index.tsx +187 -35
  211. package/themes/original/src/utils/index.tsx +96 -2
  212. package/themes/single-business/src/components/OrderTypeSelector/index.tsx +1 -1
  213. package/themes/uber-eats/src/components/BusinessesListing/index.tsx +1 -1
@@ -0,0 +1,679 @@
1
+ import React, { useCallback, useEffect, useRef, useState } from 'react';
2
+ import { Fade, Placeholder, PlaceholderLine } from 'rn-placeholder';
3
+ import Geolocation from '@react-native-community/geolocation'
4
+ import { IOScrollView } from 'react-native-intersection-observer'
5
+ import { getTrackingStatus, requestTrackingPermission } from 'react-native-tracking-transparency'
6
+ import {
7
+ View,
8
+ StyleSheet,
9
+ ScrollView,
10
+ Platform,
11
+ TouchableOpacity,
12
+ RefreshControl,
13
+ AppState
14
+ } from 'react-native';
15
+ import {
16
+ BusinessList as BusinessesListingController,
17
+ useLanguage,
18
+ useSession,
19
+ useOrder,
20
+ useConfig,
21
+ useUtils,
22
+ useOrderingTheme
23
+ } from 'ordering-components/native';
24
+ import { useTheme } from 'styled-components/native';
25
+ import Ionicons from 'react-native-vector-icons/Ionicons'
26
+
27
+ import {
28
+ Search,
29
+ OrderControlContainer,
30
+ AddressInput,
31
+ WrapMomentOption,
32
+ HeaderWrapper,
33
+ ListWrapper,
34
+ FeaturedWrapper,
35
+ OrderProgressWrapper,
36
+ FarAwayMessage,
37
+ AddressInputContainer,
38
+ PreorderInput,
39
+ OrderTypesContainer,
40
+ BusinessLogosContainer
41
+ } from './styles';
42
+
43
+ import { SearchBar } from '../../../SearchBar';
44
+ import { OButton, OIcon, OText, OBottomPopup, OModal } from '../../../shared';
45
+ import { BusinessesListingParams } from '../../../../types';
46
+ import { NotFoundSource } from '../../../NotFoundSource';
47
+ import { BusinessTypeFilter } from '../../../BusinessTypeFilter';
48
+ import { BusinessController } from '../../../BusinessController';
49
+ import { OrderTypeSelector } from '../../../OrderTypeSelector';
50
+ import { useSafeAreaInsets } from 'react-native-safe-area-context';
51
+ import { BusinessFeaturedController } from '../../../BusinessFeaturedController';
52
+ import { HighestRatedBusinesses } from '../../../HighestRatedBusinesses';
53
+ import { getTypesText, convertToRadian } from '../../../../utils';
54
+ import { OrderProgress } from '../../../OrderProgress';
55
+ import { useFocusEffect, useIsFocused } from '@react-navigation/native';
56
+ import FastImage from 'react-native-fast-image';
57
+
58
+ const PIXELS_TO_SCROLL = 2000;
59
+
60
+ const BusinessesListingUI = (props: BusinessesListingParams) => {
61
+ const {
62
+ navigation,
63
+ businessesList,
64
+ searchValue,
65
+ getBusinesses,
66
+ handleChangeBusinessType,
67
+ handleBusinessClick,
68
+ paginationProps,
69
+ handleChangeSearch,
70
+ businessId,
71
+ isGuestUser,
72
+ handleUpdateBusinessList,
73
+ citiesState,
74
+ actualSlug,
75
+ logosLayout
76
+ } = props;
77
+ const theme = useTheme();
78
+ const [orderingTheme] = useOrderingTheme()
79
+ const isFocused = useIsFocused();
80
+ const appState = useRef(AppState.currentState)
81
+ const searchBarRef = useRef<any>()
82
+ const [appStateVisible, setAppStateVisible] = useState(appState.current);
83
+ const isChewLayout = orderingTheme?.theme?.header?.components?.layout?.type === 'chew'
84
+ const hideCities = orderingTheme?.theme?.business_listing_view?.components?.cities?.hidden
85
+ const [refreshing] = useState(false);
86
+ const styles = StyleSheet.create({
87
+ container: {
88
+ marginBottom: 0,
89
+ },
90
+ welcome: {
91
+ flex: 1,
92
+ flexDirection: 'row',
93
+ },
94
+ inputStyle: {
95
+ backgroundColor: theme.colors.inputDisabled,
96
+ flex: 1,
97
+ },
98
+ wrapperOrderOptions: {
99
+ width: '100%',
100
+ flexDirection: 'row',
101
+ justifyContent: 'center',
102
+ marginBottom: 10,
103
+ zIndex: 100,
104
+ },
105
+ borderStyle: {
106
+ borderColor: theme.colors.backgroundGray,
107
+ borderWidth: 1,
108
+ borderRadius: 10,
109
+ },
110
+ searchInput: {
111
+ fontSize: 16,
112
+ backgroundColor: theme.colors.white,
113
+ paddingLeft: 10,
114
+ paddingTop: 7
115
+ },
116
+ iconStyle: {
117
+ fontSize: 18,
118
+ color: theme.colors.warning5,
119
+ marginRight: 8
120
+ },
121
+ farAwayMsg: {
122
+ paddingVertical: 6,
123
+ paddingHorizontal: 20
124
+ },
125
+ inputContainerStyles: {
126
+ backgroundColor: theme.colors.white,
127
+ borderColor: theme.colors.backgroundGray,
128
+ borderWidth: 1,
129
+ },
130
+ buttonCityStyle: {
131
+ backgroundColor: theme.colors.white,
132
+ borderColor: theme.colors.backgroundGray,
133
+ borderRadius: 8,
134
+ marginHorizontal: 40,
135
+ height: 45
136
+ },
137
+ businessSkeleton: {
138
+ borderRadius: 8,
139
+ marginRight: 20,
140
+ width: 56,
141
+ height: 56
142
+ },
143
+ });
144
+
145
+
146
+ const [, t] = useLanguage();
147
+ const [{ user, auth }] = useSession();
148
+ const [orderState, { changeCityFilter }] = useOrder();
149
+ const [{ configs }] = useConfig();
150
+ const [{ parseDate }] = useUtils();
151
+
152
+ const { top } = useSafeAreaInsets();
153
+
154
+ const [featuredBusiness, setFeaturedBusinesses] = useState(Array);
155
+ const [isFarAway, setIsFarAway] = useState(false)
156
+ const [businessTypes, setBusinessTypes] = useState(null)
157
+ const [orderTypeValue, setOrderTypeValue] = useState(orderState?.options.value)
158
+ const [isOpenCities, setIsOpenCities] = useState(false)
159
+ const isPreorderEnabled = (configs?.preorder_status_enabled?.value === '1' || configs?.preorder_status_enabled?.value === 'true') &&
160
+ Number(configs?.max_days_preorder?.value) > 0
161
+ const isPreOrderSetting = configs?.preorder_status_enabled?.value === '1'
162
+ const timerId = useRef<any>(false)
163
+ const [favoriteIds, setFavoriteIds] = useState<any>([])
164
+ const chewOrderTypes = [{ name: t('DELIVERY', 'Delivery').toUpperCase(), value: 1 }, { name: t('PICKUP', 'Pickup').toUpperCase(), value: 2 }]
165
+
166
+ // const panResponder = useRef(
167
+ // PanResponder.create({
168
+ // onMoveShouldSetPanResponder: (e, gestureState) => {
169
+ // const { dx, dy } = gestureState;
170
+ // resetInactivityTimeout()
171
+ // return (Math.abs(dx) > 20) || (Math.abs(dy) > 20);
172
+ // },
173
+ // })
174
+ // ).current
175
+
176
+ const handleMomentClick = () => {
177
+ if (isPreorderEnabled) {
178
+ navigation.navigate('MomentOption')
179
+ }
180
+ }
181
+
182
+ const configTypes =
183
+ configs?.order_types_allowed?.value
184
+ .split('|')
185
+ .map((value: any) => Number(value)) || [];
186
+
187
+ const handleScroll = ({ nativeEvent }: any) => {
188
+ const y = nativeEvent.contentOffset.y;
189
+ const height = nativeEvent.contentSize.height;
190
+ const hasMore = !(
191
+ paginationProps.totalPages === paginationProps.currentPage
192
+ );
193
+
194
+ if (y + PIXELS_TO_SCROLL > height && !businessesList.loading && hasMore) {
195
+ getBusinesses();
196
+ }
197
+ };
198
+
199
+ const getDistance = (lat1: any, lon1: any, lat2: any, lon2: any) => {
200
+ const R = 6371 // km
201
+ const dLat = convertToRadian(lat2 - lat1)
202
+ const dLon = convertToRadian(lon2 - lon1)
203
+ const curLat1 = convertToRadian(lat1)
204
+ const curLat2 = convertToRadian(lat2)
205
+ const a = Math.sin(dLat / 2) * Math.sin(dLat / 2) + Math.sin(dLon / 2) * Math.sin(dLon / 2) * Math.cos(curLat1) * Math.cos(curLat2)
206
+ const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a))
207
+ return R * c
208
+ }
209
+
210
+ const resetInactivityTimeout = () => {
211
+ if (!logosLayout) {
212
+ clearTimeout(timerId.current)
213
+ timerId.current = setInterval(() => {
214
+ getBusinesses(true)
215
+ }, 120000)
216
+ }
217
+ }
218
+
219
+ const handleChangeCity = (cityId: number | null) => {
220
+ changeCityFilter(orderState?.options?.city_id === cityId ? null : cityId)
221
+ setIsOpenCities(false)
222
+ }
223
+
224
+ useEffect(() => {
225
+ if (!businessesList?.loading) {
226
+ const fb = businessesList.businesses.filter((b) => b.featured === true && b?.open);
227
+ const ary = [];
228
+ while (fb.length > 0) {
229
+ ary.push(fb.splice(0, 2));
230
+ }
231
+ setFeaturedBusinesses(ary);
232
+ }
233
+ resetInactivityTimeout()
234
+ }, [businessesList.loading])
235
+
236
+ const handleOnRefresh = () => {
237
+ if (!businessesList.loading) {
238
+ getBusinesses(true);
239
+ }
240
+ }
241
+
242
+ const checkUserLocation = async () => {
243
+ let trackingStatus = await getTrackingStatus()
244
+ if (trackingStatus === 'not-determined') {
245
+ trackingStatus = await requestTrackingPermission()
246
+ }
247
+ if (trackingStatus === 'authorized' || trackingStatus === 'unavailable') {
248
+ Geolocation.getCurrentPosition((pos) => {
249
+ const crd = pos.coords
250
+ const distance = getDistance(crd.latitude, crd.longitude, orderState?.options?.address?.location?.lat, orderState?.options?.address?.location?.lng)
251
+ if (distance > 20) setIsFarAway(true)
252
+ else setIsFarAway(false)
253
+ }, (err) => {
254
+ console.log(`ERROR(${err.code}): ${err.message}`)
255
+ }, {
256
+ enableHighAccuracy: true, timeout: 15000, maximumAge: 10000
257
+ })
258
+ }
259
+ }
260
+
261
+ useEffect(() => {
262
+ if (!logosLayout) {
263
+ checkUserLocation()
264
+ }
265
+ }, [orderState?.options?.address?.location])
266
+
267
+ useEffect(() => {
268
+ if (!orderState?.loading) {
269
+ setOrderTypeValue(orderState?.options?.type)
270
+ }
271
+ }, [orderState?.options?.type])
272
+
273
+ useFocusEffect(
274
+ useCallback(() => {
275
+ resetInactivityTimeout()
276
+ return () => clearTimeout(timerId.current)
277
+ }, [navigation])
278
+ )
279
+
280
+ useEffect(() => {
281
+ if (!businessesList?.businesses?.length) return
282
+ const ids = [...favoriteIds]
283
+ businessesList.businesses.forEach((business: any) => {
284
+ if (business?.favorite) {
285
+ ids.push(business?.id)
286
+ }
287
+ })
288
+ setFavoriteIds([...new Set(ids)])
289
+ }, [businessesList?.businesses?.length])
290
+
291
+ useEffect(() => {
292
+ setIsOpenCities(false)
293
+ }, [orderState?.options?.city_id])
294
+
295
+ if (logosLayout) {
296
+ return (
297
+ <BusinessLogosContainer horizontal>
298
+ {businessesList?.loading ? (
299
+ <Placeholder Animation={Fade}>
300
+ <View style={{ flexDirection: 'row' }}>
301
+ {[...Array(10).keys()].map(i => (
302
+ <View style={styles.businessSkeleton} key={i}>
303
+ <PlaceholderLine style={{ width: '100%', height: '100%' }} />
304
+ </View>
305
+ ))}
306
+ </View>
307
+ </Placeholder>
308
+ ) : (
309
+ <>
310
+ {businessesList.businesses
311
+ ?.filter(business => business?.slug !== actualSlug && business?.open)
312
+ ?.map(business => (
313
+ <TouchableOpacity
314
+ key={business?.id}
315
+ onPress={() => handleBusinessClick && handleBusinessClick(business)}
316
+ >
317
+ <FastImage
318
+ style={{ width: 56, height: 56, marginRight: 20, borderRadius: 7.6 }}
319
+ source={{
320
+ uri: business?.logo,
321
+ priority: FastImage.priority.normal,
322
+ }}
323
+ resizeMode={FastImage.resizeMode.cover}
324
+ />
325
+ </TouchableOpacity>
326
+ ))}
327
+ </>
328
+ )}
329
+ </BusinessLogosContainer>
330
+ )
331
+ }
332
+
333
+ return (
334
+ <IOScrollView style={styles.container} onScroll={(e) => handleScroll(e)} showsVerticalScrollIndicator={false}
335
+ refreshControl={
336
+ <RefreshControl
337
+ refreshing={refreshing}
338
+ onRefresh={() => handleOnRefresh()}
339
+ />
340
+ }
341
+ >
342
+ <View style={{
343
+ height: !isPreOrderSetting && isChewLayout ? 150 : isChewLayout ? 200 : isFarAway ? 150 : 100,
344
+ marginTop: Platform.OS == 'ios' ? 0 : 50,
345
+ backgroundColor: isChewLayout ? theme?.colors?.chew : theme.colors?.white
346
+ }}
347
+ >
348
+ {isChewLayout && (
349
+ <View style={{ marginTop: 30, paddingHorizontal: 30, flexDirection: 'row', justifyContent: 'space-between' }}>
350
+ <OText size={18} weight={700} color={theme.colors?.white}>
351
+ {t('WELCOME', 'Welcome')} {user?.name}!
352
+ </OText>
353
+ </View>
354
+ )}
355
+ <Search isChewLayout={isChewLayout}>
356
+ <AddressInput
357
+ isChewLayout={isChewLayout}
358
+ onPress={() =>
359
+ auth
360
+ ? navigation.navigate('AddressList', { isFromBusinesses: true })
361
+ : navigation.navigate('AddressForm', {
362
+ address: orderState.options?.address,
363
+ isFromBusinesses: true,
364
+ isGuestUser: isGuestUser
365
+ })
366
+ }>
367
+ <AddressInputContainer isChewLayout={isChewLayout}>
368
+ <OIcon
369
+ src={theme.images.general.pin}
370
+ color={theme.colors.disabled}
371
+ width={16}
372
+ style={{ marginRight: isChewLayout ? 0 : 10 }}
373
+ />
374
+ <OText size={12} numberOfLines={1} style={{ flex: 1 }}>
375
+ {orderState?.options?.address?.address}
376
+ </OText>
377
+ {!isChewLayout && (
378
+ <OIcon
379
+ src={theme.images.general.arrow_down}
380
+ width={10}
381
+ style={{ marginStart: 8 }}
382
+ />
383
+ )}
384
+ </AddressInputContainer>
385
+ </AddressInput>
386
+ </Search>
387
+ {isFarAway && !isChewLayout && (
388
+ <FarAwayMessage style={styles.farAwayMsg}>
389
+ <Ionicons name='md-warning-outline' style={styles.iconStyle} />
390
+ <OText size={12} numberOfLines={1} ellipsizeMode={'tail'} color={theme.colors.textNormal}>{t('YOU_ARE_FAR_FROM_ADDRESS', 'You are far from this address')}</OText>
391
+ </FarAwayMessage>
392
+ )}
393
+ {!isChewLayout ? (
394
+ <OrderControlContainer>
395
+ <View style={styles.wrapperOrderOptions}>
396
+ {isPreOrderSetting && (
397
+ <WrapMomentOption
398
+ onPress={() => handleMomentClick()}>
399
+ <OText
400
+ size={12}
401
+ numberOfLines={1}
402
+ ellipsizeMode="tail"
403
+ color={theme.colors.textSecondary}>
404
+ {orderState.options?.moment
405
+ ? parseDate(orderState.options?.moment, { outputFormat: configs?.dates_moment_format?.value })
406
+ : t('ASAP_ABBREVIATION', 'ASAP')}
407
+ </OText>
408
+ {isPreorderEnabled && (
409
+ <OIcon
410
+ src={theme.images.general.arrow_down}
411
+ width={10}
412
+ style={{ marginStart: 8 }}
413
+ />
414
+ )}
415
+ </WrapMomentOption>
416
+ )}
417
+ <WrapMomentOption onPress={() => navigation.navigate('OrderTypes', { configTypes: configTypes, setOrderTypeValue })}>
418
+ <OText size={12} numberOfLines={1} ellipsizeMode={'tail'} color={theme.colors.textSecondary}>{t(getTypesText(orderTypeValue || orderState?.options?.type || 1), 'Delivery')}</OText>
419
+ <OIcon
420
+ src={theme.images.general.arrow_down}
421
+ width={10}
422
+ style={{ marginStart: 8 }}
423
+ />
424
+ </WrapMomentOption>
425
+ </View>
426
+ </OrderControlContainer>
427
+ ) : (
428
+ <>
429
+ {!isPreOrderSetting && (// cambiar
430
+ <View style={{ paddingHorizontal: 30 }}>
431
+ <PreorderInput
432
+ isChewLayout={isChewLayout}
433
+ onPress={() => handleMomentClick()}
434
+ >
435
+ <OText color={theme.colors.textSecondary}>
436
+ {orderState.options?.moment
437
+ ? parseDate(orderState.options?.moment, { outputFormat: configs?.dates_moment_format?.value })
438
+ : t('ASAP_ABBREVIATION', 'ASAP')}</OText>
439
+ </PreorderInput>
440
+ </View>
441
+ )}
442
+ </>
443
+ )}
444
+ </View>
445
+ {!isChewLayout ? (
446
+ <HeaderWrapper
447
+ source={theme.images.general.homeHero}
448
+ style={{ paddingTop: top + 20 }}
449
+ resizeMode='stretch'
450
+ >
451
+ {!auth && (
452
+ <TouchableOpacity onPress={() => navigation?.canGoBack() && navigation.goBack()} style={{ position: 'absolute', marginStart: 40, paddingVertical: 20 }}>
453
+ <OIcon src={theme.images.general.arrow_left} width={20} style={{ tintColor: theme.colors.white }} />
454
+ </TouchableOpacity>
455
+ )}
456
+ </HeaderWrapper>
457
+ ) : (
458
+ <OrderTypesContainer>
459
+ <OrderTypeSelector
460
+ handleChangeBusinessType={handleChangeBusinessType}
461
+ isChewLayout
462
+ chewOrderTypes={chewOrderTypes}
463
+ />
464
+ </OrderTypesContainer>
465
+ )}
466
+ {!businessId && (
467
+ <SearchBar
468
+ forwardRef={searchBarRef}
469
+ onSearch={handleChangeSearch}
470
+ searchValue={searchValue}
471
+ lazyLoad
472
+ hideIcon
473
+ isCancelXButtonShow={!!searchValue}
474
+ onCancel={() => handleChangeSearch('')}
475
+ placeholder={t('SEARCH', 'Search')}
476
+ height={50}
477
+ isDisabled={!businessTypes}
478
+ inputContainerStyles={styles.inputContainerStyles}
479
+ containerStyles={{
480
+ marginHorizontal: 40,
481
+ marginTop: 20
482
+ }}
483
+ inputStyle={{ ...styles.searchInput, ...Platform.OS === 'ios' ? { paddingBottom: 6 } : { paddingBottom: 4 } }}
484
+ onSubmitEditing={() => { configs?.advanced_business_search_enabled?.value === '1' && navigation.navigate('BusinessSearch', { businessTypes, defaultTerm: searchValue }) }}
485
+ />
486
+ )}
487
+
488
+ {!hideCities && (
489
+ <View style={{ marginTop: 10 }}>
490
+ <OButton
491
+ onClick={() => setIsOpenCities(true)}
492
+ text={citiesState?.cities?.find((city: any) => city?.id === orderState?.options?.city_id)?.name || t('FILTER_BY_CITY', 'Filter by city')}
493
+ style={styles?.buttonCityStyle}
494
+ textStyle={{ color: theme.colors.backgroundGray, fontWeight: 'bold', fontSize: 18 }}
495
+ />
496
+ </View>
497
+ )}
498
+ <OrderProgressWrapper>
499
+ <OrderProgress
500
+ {...props}
501
+ isFocused={isFocused}
502
+ />
503
+ </OrderProgressWrapper>
504
+ {
505
+ !businessId && !props.franchiseId && featuredBusiness && featuredBusiness.length > 0 && (
506
+ <FeaturedWrapper>
507
+ <OText size={16} style={{ marginLeft: 40 }} weight={Platform.OS === 'ios' ? '600' : 'bold'}>{t('BUSINESS_FEATURE', 'Featured business')}</OText>
508
+ <ScrollView
509
+ showsHorizontalScrollIndicator={false}
510
+ nestedScrollEnabled
511
+ horizontal
512
+ contentContainerStyle={{ paddingHorizontal: 40 }}
513
+ >
514
+ {featuredBusiness.map((bAry: any, idx) => (
515
+ <View key={'f-listing_' + idx}>
516
+ <BusinessFeaturedController
517
+ business={bAry[0]}
518
+ isBusinessOpen={bAry[0]?.open}
519
+ handleCustomClick={handleBusinessClick}
520
+ orderType={orderState?.options?.type}
521
+ />
522
+ {bAry.length > 1 && (
523
+ <BusinessFeaturedController
524
+ business={bAry[1]}
525
+ isBusinessOpen={bAry[1]?.open}
526
+ handleCustomClick={handleBusinessClick}
527
+ orderType={orderState?.options?.type}
528
+ />
529
+ )}
530
+ </View>
531
+ ))}
532
+ </ScrollView>
533
+ </FeaturedWrapper>
534
+ )
535
+ }
536
+ <View style={{ height: 8, backgroundColor: theme.colors.backgroundGray100 }} />
537
+ {
538
+ !businessId && !props.franchiseId && (
539
+ <HighestRatedBusinesses
540
+ onBusinessClick={handleBusinessClick}
541
+ navigation={navigation}
542
+ favoriteIds={favoriteIds}
543
+ setFavoriteIds={setFavoriteIds}
544
+ />
545
+ )
546
+ }
547
+ <View style={{ height: 8, backgroundColor: theme.colors.backgroundGray100 }} />
548
+ <ListWrapper>
549
+ {!businessId && (
550
+ <BusinessTypeFilter
551
+ images={props.images}
552
+ businessTypes={props.businessTypes}
553
+ defaultBusinessType={props.defaultBusinessType}
554
+ handleChangeBusinessType={handleChangeBusinessType}
555
+ setBusinessTypes={setBusinessTypes}
556
+ />
557
+ )}
558
+ {!businessesList.loading && businessesList.businesses.length === 0 && (
559
+ <NotFoundSource
560
+ content={t(
561
+ 'NOT_FOUND_BUSINESSES',
562
+ 'No businesses to delivery / pick up at this address, please change filters or change address.',
563
+ )}
564
+ />
565
+ )}
566
+ {businessesList.businesses?.map(
567
+ (business: any, i: number) => (
568
+ <BusinessController
569
+ key={`${business.id}_` + i}
570
+ enableIntersection
571
+ business={business}
572
+ isBusinessOpen={business.open}
573
+ handleCustomClick={handleBusinessClick}
574
+ orderType={orderState?.options?.type}
575
+ navigation={navigation}
576
+ businessHeader={business?.header}
577
+ businessFeatured={business?.featured}
578
+ businessLogo={business?.logo}
579
+ businessReviews={business?.reviews}
580
+ businessDeliveryPrice={business?.delivery_price}
581
+ businessDeliveryTime={business?.delivery_time}
582
+ businessPickupTime={business?.pickup_time}
583
+ businessDistance={business?.distance}
584
+ handleUpdateBusinessList={handleUpdateBusinessList}
585
+ favoriteIds={favoriteIds}
586
+ setFavoriteIds={setFavoriteIds}
587
+ />
588
+ )
589
+ )}
590
+ {businessesList.loading && (
591
+ <>
592
+ {[
593
+ ...Array(
594
+ paginationProps.nextPageItems
595
+ ? paginationProps.nextPageItems
596
+ : 8,
597
+ ).keys(),
598
+ ].map((item, i) => (
599
+ <Placeholder
600
+ Animation={Fade}
601
+ key={i}
602
+ style={{ marginBottom: 20 }}>
603
+ <View style={{ width: '100%' }}>
604
+ <PlaceholderLine
605
+ height={200}
606
+ style={{ marginBottom: 20, borderRadius: 25 }}
607
+ />
608
+ <View style={{ paddingHorizontal: 10 }}>
609
+ <View
610
+ style={{
611
+ flexDirection: 'row',
612
+ justifyContent: 'space-between',
613
+ }}>
614
+ <PlaceholderLine
615
+ height={25}
616
+ width={40}
617
+ style={{ marginBottom: 10 }}
618
+ />
619
+ <PlaceholderLine
620
+ height={25}
621
+ width={20}
622
+ style={{ marginBottom: 10 }}
623
+ />
624
+ </View>
625
+ <PlaceholderLine
626
+ height={20}
627
+ width={30}
628
+ style={{ marginBottom: 10 }}
629
+ />
630
+ <PlaceholderLine
631
+ height={20}
632
+ width={80}
633
+ style={{ marginBottom: 10 }}
634
+ />
635
+ </View>
636
+ </View>
637
+ </Placeholder>
638
+ ))}
639
+ </>
640
+ )}
641
+ </ListWrapper>
642
+ <OModal
643
+ open={isOpenCities}
644
+ onClose={() => setIsOpenCities(false)}
645
+ title={t('SELECT_A_CITY', 'Select a city')}
646
+ >
647
+ <View style={{ padding: 40, width: '100%' }}>
648
+ {citiesState?.cities?.map((city: any) => (
649
+ <TouchableOpacity
650
+ key={city?.id}
651
+ style={{
652
+ padding: 10,
653
+ borderBottomWidth: 1,
654
+ borderBottomColor: orderState?.options?.city_id === city?.id ? theme.colors.primary : theme.colors.backgroundGray,
655
+ marginBottom: 10,
656
+ }}
657
+ onPress={() => handleChangeCity(city?.id)}
658
+ disabled={orderState?.loading}
659
+ >
660
+ <OText color={orderState?.options?.city_id === city?.id ? theme.colors.primary : theme.colors.black}>
661
+ {city?.name}
662
+ </OText>
663
+ </TouchableOpacity>
664
+ ))}
665
+ </View>
666
+ </OModal>
667
+ </IOScrollView>
668
+ );
669
+ };
670
+
671
+ export const BusinessesListing = (props: BusinessesListingParams) => {
672
+ const BusinessesListingProps = {
673
+ ...props,
674
+ isForceSearch: Platform.OS === 'ios',
675
+ UIComponent: BusinessesListingUI,
676
+ };
677
+
678
+ return <BusinessesListingController {...BusinessesListingProps} />;
679
+ };