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