ordering-ui-react-native 0.14.99 → 0.15.0-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 (126) hide show
  1. package/package.json +6 -3
  2. package/src/DeliveryApp.tsx +32 -1
  3. package/src/components/BusinessTypeFilter/index.tsx +9 -2
  4. package/src/components/BusinessTypeFilter/styles.tsx +1 -1
  5. package/src/components/BusinessesListing/index.tsx +1 -1
  6. package/src/components/Checkout/index.tsx +0 -1
  7. package/src/components/Home/index.tsx +3 -5
  8. package/src/components/LanguageSelector/index.tsx +65 -97
  9. package/src/components/LanguageSelector/styles.tsx +4 -17
  10. package/src/components/Messages/index.tsx +38 -30
  11. package/src/components/MomentOption/index.tsx +3 -1
  12. package/src/components/OrderDetails/index.tsx +25 -4
  13. package/src/components/PaymentOptions/index.tsx +7 -16
  14. package/src/components/PaymentOptionsWebView/index.tsx +123 -124
  15. package/src/components/ProductForm/index.tsx +1 -1
  16. package/src/components/ProductForm/styles.tsx +1 -0
  17. package/src/components/StripeElementsForm/index.tsx +27 -48
  18. package/src/components/UserProfileForm/index.tsx +35 -1
  19. package/src/components/VerifyPhone/styles.tsx +1 -2
  20. package/src/config.json +0 -2
  21. package/src/pages/Checkout.tsx +1 -1
  22. package/src/types/index.tsx +2 -9
  23. package/src/utils/index.tsx +2 -1
  24. package/themes/business/index.tsx +2 -0
  25. package/themes/business/src/components/Chat/index.tsx +32 -31
  26. package/themes/business/src/components/OrderDetails/Business.tsx +1 -0
  27. package/themes/business/src/components/OrderDetails/OrderHeaderComponent.tsx +85 -17
  28. package/themes/business/src/components/OrdersListManager/index.tsx +874 -0
  29. package/themes/business/src/components/OrdersListManager/styles.tsx +123 -0
  30. package/themes/business/src/components/OrdersListManager/utils.tsx +216 -0
  31. package/themes/business/src/components/OrdersOption/index.tsx +70 -116
  32. package/themes/business/src/components/OrdersOption/styles.tsx +2 -5
  33. package/themes/business/src/components/PreviousOrders/index.tsx +82 -23
  34. package/themes/doordash/src/components/BusinessesListing/index.tsx +1 -1
  35. package/themes/doordash/src/components/LoginForm/index.tsx +1 -2
  36. package/themes/instacart/src/components/BusinessesListing/index.tsx +1 -1
  37. package/themes/kiosk/src/components/BusinessController/index.tsx +27 -6
  38. package/themes/kiosk/src/components/BusinessController/styles.tsx +1 -1
  39. package/themes/kiosk/src/components/BusinessProductsListing/index.tsx +51 -24
  40. package/themes/kiosk/src/components/Cart/index.tsx +1 -1
  41. package/themes/kiosk/src/components/CartBottomSheet/index.tsx +1 -1
  42. package/themes/kiosk/src/components/CartBottomSheet/styles.tsx +1 -1
  43. package/themes/kiosk/src/components/CartContent/index.tsx +13 -3
  44. package/themes/kiosk/src/components/CartItem/index.tsx +20 -8
  45. package/themes/kiosk/src/components/CategoriesMenu/index.tsx +7 -5
  46. package/themes/kiosk/src/components/CustomerName/index.tsx +89 -88
  47. package/themes/kiosk/src/components/Intro/index.tsx +13 -13
  48. package/themes/kiosk/src/components/LanguageSelector/index.tsx +12 -8
  49. package/themes/kiosk/src/components/NavBar/index.tsx +14 -14
  50. package/themes/kiosk/src/components/OptionCard/index.tsx +1 -1
  51. package/themes/kiosk/src/components/OrderDetails/index.tsx +2 -2
  52. package/themes/kiosk/src/components/OrderSummary/index.tsx +1 -1
  53. package/themes/kiosk/src/components/OrderTypeCardSelector/index.tsx +10 -12
  54. package/themes/kiosk/src/components/ProductForm/index.tsx +172 -124
  55. package/themes/kiosk/src/components/ProductForm/styles.tsx +1 -1
  56. package/themes/kiosk/src/components/ProductOption/index.tsx +1 -0
  57. package/themes/kiosk/src/components/ProductOption/styles.tsx +1 -0
  58. package/themes/kiosk/src/components/UpsellingProducts/index.tsx +48 -34
  59. package/themes/kiosk/src/components/shared/OButton.tsx +5 -18
  60. package/themes/kiosk/src/components/shared/OCard.tsx +112 -78
  61. package/themes/original/index.tsx +179 -2
  62. package/themes/original/src/components/AddressForm/index.tsx +15 -10
  63. package/themes/original/src/components/AddressList/index.tsx +27 -1
  64. package/themes/original/src/components/AnalyticsSegment/index.tsx +127 -0
  65. package/themes/original/src/components/BusinessBasicInformation/index.tsx +100 -45
  66. package/themes/original/src/components/BusinessBasicInformation/styles.tsx +28 -1
  67. package/themes/original/src/components/BusinessController/index.tsx +36 -22
  68. package/themes/original/src/components/BusinessMenuList/index.tsx +14 -5
  69. package/themes/original/src/components/BusinessPreorder/index.tsx +142 -121
  70. package/themes/original/src/components/BusinessProductsCategories/index.tsx +7 -5
  71. package/themes/original/src/components/BusinessProductsList/index.tsx +3 -3
  72. package/themes/original/src/components/BusinessProductsListing/index.tsx +23 -30
  73. package/themes/original/src/components/BusinessReviews/index.tsx +4 -3
  74. package/themes/original/src/components/BusinessTypeFilter/index.tsx +2 -13
  75. package/themes/original/src/components/BusinessesListing/index.tsx +41 -58
  76. package/themes/original/src/components/Cart/index.tsx +40 -7
  77. package/themes/original/src/components/CartContent/index.tsx +2 -2
  78. package/themes/original/src/components/Checkout/index.tsx +58 -33
  79. package/themes/original/src/components/Checkout/styles.tsx +7 -0
  80. package/themes/original/src/components/CouponControl/index.tsx +1 -0
  81. package/themes/original/src/components/DriverTips/index.tsx +1 -1
  82. package/themes/original/src/components/ForgotPasswordForm/index.tsx +8 -12
  83. package/themes/original/src/components/HighestRatedBusinesses/index.tsx +105 -90
  84. package/themes/original/src/components/LoginForm/index.tsx +83 -68
  85. package/themes/original/src/components/Messages/index.tsx +52 -45
  86. package/themes/original/src/components/Messages/styles.tsx +1 -3
  87. package/themes/original/src/components/MomentOption/index.tsx +127 -152
  88. package/themes/original/src/components/MomentOption/styles.tsx +42 -18
  89. package/themes/original/src/components/OrderDetails/index.tsx +102 -123
  90. package/themes/original/src/components/OrderDetails/styles.tsx +3 -1
  91. package/themes/original/src/components/OrderProgress/index.tsx +6 -7
  92. package/themes/original/src/components/OrderProgress/styles.tsx +1 -0
  93. package/themes/original/src/components/OrderSummary/index.tsx +34 -1
  94. package/themes/original/src/components/OrdersOption/index.tsx +15 -46
  95. package/themes/original/src/components/OrdersOption/styles.tsx +0 -6
  96. package/themes/original/src/components/PaymentOptionWallet/index.tsx +6 -2
  97. package/themes/original/src/components/PaymentOptions/index.tsx +24 -25
  98. package/themes/original/src/components/PhoneInputNumber/index.tsx +15 -8
  99. package/themes/original/src/components/PlaceSpot/index.tsx +114 -0
  100. package/themes/original/src/components/PlaceSpot/styles.tsx +11 -0
  101. package/themes/original/src/components/PreviousOrders/index.tsx +19 -13
  102. package/themes/original/src/components/ProductForm/index.tsx +153 -104
  103. package/themes/original/src/components/ProductForm/styles.tsx +5 -3
  104. package/themes/original/src/components/ProductOptionSubOption/index.tsx +6 -1
  105. package/themes/original/src/components/ReviewOrder/index.tsx +10 -9
  106. package/themes/original/src/components/ReviewProducts/index.tsx +1 -1
  107. package/themes/original/src/components/SearchBar/index.tsx +4 -10
  108. package/themes/original/src/components/SignupForm/index.tsx +173 -154
  109. package/themes/original/src/components/SingleProductCard/index.tsx +2 -10
  110. package/themes/original/src/components/StripeElementsForm/index.tsx +55 -72
  111. package/themes/original/src/components/UpsellingProducts/index.tsx +6 -6
  112. package/themes/original/src/components/UserDetails/index.tsx +4 -95
  113. package/themes/original/src/components/UserFormDetails/index.tsx +2 -14
  114. package/themes/original/src/components/UserProfile/index.tsx +16 -11
  115. package/themes/original/src/components/UserProfileForm/index.tsx +16 -8
  116. package/themes/original/src/components/VerifyPhone/index.tsx +10 -7
  117. package/themes/original/src/components/VerifyPhone/styles.tsx +2 -1
  118. package/themes/original/src/components/shared/HeaderTitle.tsx +21 -0
  119. package/themes/original/src/components/shared/OInput.tsx +1 -2
  120. package/themes/original/src/components/shared/index.tsx +2 -0
  121. package/themes/original/src/types/index.tsx +25 -28
  122. package/themes/single-business/src/components/OrderTypeSelector/index.tsx +5 -5
  123. package/themes/uber-eats/src/components/BusinessesListing/index.tsx +1 -1
  124. package/src/components/StripeMethodForm/index.tsx +0 -168
  125. package/themes/original/src/components/BusinessListingSearch/index.tsx +0 -469
  126. package/themes/original/src/components/BusinessListingSearch/styles.tsx +0 -76
@@ -1,168 +0,0 @@
1
- import React, { useState, useEffect } from 'react'
2
- import { useLanguage } from 'ordering-components/native'
3
- import { useGooglePay, ApplePayButton, useApplePay } from '@stripe/stripe-react-native'
4
- import { OButton } from '../shared';
5
- import { Platform, View } from 'react-native';
6
- import { StripeMethodFormParams } from '../../types';
7
- import Spinner from 'react-native-loading-spinner-overlay';
8
- import { android_app_id } from '../../config.json'
9
- export const StripeMethodForm = (props: StripeMethodFormParams) => {
10
- const {
11
- cart,
12
- handleSource,
13
- onCancel,
14
- setErrors,
15
- paymethod,
16
- devMode
17
- } = props
18
- const { initGooglePay, createGooglePayPaymentMethod, loading } = useGooglePay();
19
- const { presentApplePay, isApplePaySupported } = useApplePay();
20
- const [initialized, setInitialized] = useState(false);
21
- const [loadingGooglePayment, setLoadingGooglePayment] = useState(false)
22
- const [, t] = useLanguage()
23
-
24
- useEffect(() => {
25
- if (paymethod !== 'google_pay' || !initGooglePay) return
26
- if (Platform.OS === 'ios') {
27
- setErrors(t('GOOGLE_PAY_NOT_SUPPORTED', 'Google pay not supported'))
28
- return
29
- }
30
- const initialize = async () => {
31
- try {
32
- const { error } = await initGooglePay({
33
- testEnv: devMode,
34
- merchantName: android_app_id,
35
- countryCode: 'US',
36
- billingAddressConfig: {
37
- format: 'FULL',
38
- isPhoneNumberRequired: true,
39
- isRequired: false,
40
- },
41
- existingPaymentMethodRequired: false,
42
- isEmailRequired: true,
43
- });
44
-
45
- if (error) {
46
- setErrors(error.code + ' - ' + error.message);
47
- return;
48
- }
49
- setInitialized(true);
50
- } catch (err: any) {
51
- setErrors('Catch ' + err?.message)
52
- }
53
- }
54
- initialize();
55
- }, [initGooglePay]);
56
-
57
- useEffect(() => {
58
- if (paymethod !== 'apple_pay') return
59
- if (Platform.OS === 'android') {
60
- setErrors(t('APPLE_PAY_NOT_SUPPORTED', 'Apple pay not supported'))
61
- return
62
- }
63
- }, [])
64
-
65
- const createPaymentMethod = async () => {
66
- setLoadingGooglePayment(true)
67
- const { error, paymentMethod } = await createGooglePayPaymentMethod({
68
- amount: cart?.balance ?? cart?.total,
69
- currencyCode: 'USD',
70
- });
71
- if (error) {
72
- setErrors(error.code + ' - ' + error.message);
73
- setLoadingGooglePayment(false)
74
- return;
75
- } else if (paymentMethod) {
76
- handleSource({
77
- ...paymentMethod?.Card,
78
- id: paymentMethod.id,
79
- type: paymentMethod.type,
80
- source_id: paymentMethod?.id,
81
- card: {
82
- brand: paymentMethod.Card.brand,
83
- last4: paymentMethod.Card.last4
84
- }
85
- })
86
- onCancel()
87
- setLoadingGooglePayment(false)
88
- }
89
- };
90
-
91
- const pay = async () => {
92
- if (!isApplePaySupported) {
93
- setErrors(t('APPLE_PAY_NOT_SUPPORTED', 'Apple pay not supported'))
94
- return
95
- }
96
-
97
- const { error, paymentMethod } = await presentApplePay({
98
- cartItems: cart?.products?.map((product: any) => ({ label: product?.name, amount: product?.price?.toString?.() })),
99
- country: 'US',
100
- currency: 'USD',
101
- shippingMethods: [
102
- {
103
- amount: cart?.balance?.toString() ?? cart?.total?.toString?.(),
104
- identifier: 'DPS',
105
- label: 'Courier',
106
- detail: 'Delivery',
107
- type: 'final',
108
- },
109
- ],
110
-
111
- requiredShippingAddressFields: ['emailAddress', 'phoneNumber'],
112
- requiredBillingContactFields: ['phoneNumber', 'name'],
113
- });
114
- if (error) {
115
- setErrors(error.code + ' - ' + error.message);
116
- } else if (paymentMethod) {
117
- handleSource({
118
- ...paymentMethod?.Card,
119
- id: paymentMethod.id,
120
- type: paymentMethod.type,
121
- source_id: paymentMethod?.id,
122
- card: {
123
- brand: paymentMethod.Card.brand,
124
- last4: paymentMethod.Card.last4
125
- }
126
- })
127
- onCancel()
128
- }
129
- }
130
-
131
- return (
132
- <>
133
- {paymethod === 'google_pay' ? (
134
- <View>
135
- <OButton
136
- textStyle={{
137
- color: '#fff'
138
- }}
139
- imgRightSrc={null}
140
- onClick={createPaymentMethod}
141
- isDisabled={loading || !initialized}
142
- text={t('PAY_WITH_GOOGLE_PAY', 'Pay with Google Pay')}
143
- isLoading={loading || !initialized}
144
- style={{ marginTop: 20 }}
145
- />
146
- </View>
147
- ) : (
148
- <View>
149
- {isApplePaySupported && (
150
- <ApplePayButton
151
- onPress={pay}
152
- type="plain"
153
- buttonStyle="black"
154
- borderRadius={4}
155
- style={{
156
- width: '100%',
157
- height: 50,
158
- }}
159
- />
160
- )}
161
- </View>
162
- )}
163
- <Spinner
164
- visible={loadingGooglePayment}
165
- />
166
- </>
167
- )
168
- }
@@ -1,469 +0,0 @@
1
- import React, { useEffect, useState } from 'react'
2
- import { useLanguage, BusinessSearchList, useOrder, useUtils } from 'ordering-components/native'
3
- import { ScrollView, StyleSheet, TouchableOpacity, Platform, View } from 'react-native'
4
- import { useSafeAreaInsets } from 'react-native-safe-area-context'
5
- import { useTheme } from 'styled-components/native'
6
- import { OButton, OIcon, OModal, OText } from '../shared'
7
- import { SearchBar } from '../SearchBar';
8
- import { BusinessController } from '../BusinessController'
9
- import { NotFoundSource } from '../NotFoundSource'
10
- import { SingleProductCard } from '../SingleProductCard'
11
- import AntDesignIcon from 'react-native-vector-icons/AntDesign'
12
- import {
13
- SearchWrapper,
14
- WrapHeader,
15
- ProductsList,
16
- SingleBusinessSearch,
17
- BusinessInfo,
18
- BusinessInfoItem,
19
- Metadata,
20
- SingleBusinessContainer,
21
- LoadMoreBusinessContainer,
22
- ProgressContentWrapper,
23
- ProgressBar,
24
- TagsContainer,
25
- SortContainer
26
- } from './styles'
27
- import FastImage from 'react-native-fast-image'
28
- import { convertHoursToMinutes } from '../../utils'
29
- import { Fade, Placeholder, PlaceholderLine } from 'rn-placeholder'
30
- import { BusinessSearchParams } from '../../types'
31
-
32
- export const BusinessListingSearchUI = (props : BusinessSearchParams) => {
33
-
34
- const {
35
- navigation,
36
- businessesSearchList,
37
- onBusinessClick,
38
- handleChangeTermValue,
39
- termValue,
40
- paginationProps,
41
- handleSearchbusinessAndProducts,
42
- handleChangeFilters,
43
- filters,
44
- businessTypes,
45
- setFilters
46
- } = props
47
-
48
- const theme = useTheme()
49
- const [orderState] = useOrder()
50
- const { top } = useSafeAreaInsets();
51
- const [, t] = useLanguage()
52
- const [{ parsePrice, parseDistance, optimizeImage }] = useUtils();
53
-
54
- const [openFilters, setOpenFilters] = useState(false)
55
- const noResults = (!businessesSearchList.loading && !businessesSearchList.lengthError && businessesSearchList?.businesses?.length === 0)
56
- const maxDeliveryFeeOptions = [15, 25, 35, 'default']
57
- // const maxProductPriceOptions = [5, 10, 15, 'default']
58
- const maxDistanceOptions = [1000, 2000, 5000, 'default']
59
- const maxTimeOptions = [5, 15, 30, 'default']
60
- const sortItems = [
61
- { text: t('PICKED_FOR_YOU', 'Picked for you (default)'), value: 'default' },
62
- { text: t('DELIVERY_TIME', 'Delivery time'), value: 'delivery_time' },
63
- { text: t('PICKUP_TIME', 'Pickup time'), value: 'pickup_type' }
64
- ]
65
-
66
- const styles = StyleSheet.create({
67
- container: {
68
- paddingHorizontal: 40,
69
- width: '100%'
70
- },
71
- searchInput: {
72
- fontSize: 10,
73
- },
74
- productsContainer: {
75
- marginTop: 20
76
- },
77
- maxContainer: {
78
- flexDirection: 'row',
79
- justifyContent: 'space-between'
80
- },
81
- businessTypesContainer: {
82
- width: '100%',
83
- flexDirection: 'row',
84
- flexWrap: 'wrap',
85
- justifyContent: 'center'
86
- },
87
- categoryStyle: {
88
- marginRight: 10,
89
- marginTop: 10,
90
- borderRadius: 50,
91
- paddingHorizontal: 10,
92
- paddingVertical: 4,
93
- paddingLeft: 0,
94
- paddingRight: 0,
95
- height: 28,
96
- borderWidth: 0
97
- },
98
- applyButton: {
99
- paddingHorizontal: 40,
100
- width: '100%',
101
- marginTop: 20
102
- }
103
- });
104
-
105
- const handleOpenfilters = () => {
106
- setOpenFilters(true)
107
- }
108
-
109
- const handleCloseFilters = () => {
110
- setFilters({ business_types: [], orderBy: 'default' })
111
- setOpenFilters(false)
112
- }
113
-
114
- const handleChangeActiveBusinessType = (type: any) => {
115
- if (type?.id === null) {
116
- handleChangeFilters('business_types', [])
117
- return
118
- }
119
- if (filters?.business_types?.includes(type?.id)) {
120
- const arrayAux = filters?.business_types
121
- const index = arrayAux?.indexOf(type?.id)
122
- arrayAux.splice(index, 1)
123
- handleChangeFilters('business_types', arrayAux)
124
- } else {
125
- handleChangeFilters('business_types', [...filters?.business_types, type?.id])
126
- }
127
- }
128
-
129
- const handleApplyFilters = () => {
130
- handleSearchbusinessAndProducts(true)
131
- setOpenFilters(false)
132
- }
133
-
134
- useEffect(() => {
135
- if (filters.business_types?.length === 0 && filters.orderBy === 'default' && Object.keys(filters)?.length === 2 && !openFilters) {
136
- handleSearchbusinessAndProducts(true)
137
- }
138
- }, [filters, openFilters])
139
-
140
- const MaxSectionItem = ({ title, options, filter }: any) => {
141
- const parseValue = (option: number) => {
142
- return filter === 'max_distance'
143
- ? `${option / 1000} ${t('KM', 'Km')}`
144
- : filter === 'max_eta'
145
- ? `${option} ${t('MIN', 'min')}`
146
- : parsePrice(option)
147
- }
148
- return (
149
- <View style={{ marginBottom: 20 }}>
150
- <OText weight='bold' mBottom={10} size={16}>
151
- {title}
152
- </OText>
153
- <ProgressContentWrapper>
154
- <ProgressBar style={{ width: `${((options.indexOf(filters?.[filter]) / 3) * 100) ?? 100}%` }} />
155
- </ProgressContentWrapper>
156
- <View style={styles.maxContainer}>
157
- {options.map((option: any, i: number) => (
158
- <TouchableOpacity
159
- onPress={() => handleChangeFilters(filter, option)}
160
- key={option}
161
- >
162
- <OText
163
- size={12}
164
- weight={filters?.[filter] === option || (option === 'default' && (filters?.[filter] === 'default' || !filters?.[filter])) ? 'bold' : '500'}
165
- >
166
- {option === 'default' ? `${parseValue(options[i - 1])}+` : parseValue(option)}
167
- </OText>
168
- </TouchableOpacity>
169
- ))}
170
- </View>
171
- </View>
172
- )
173
- }
174
-
175
- return (
176
- <ScrollView style={styles.container}>
177
- <WrapHeader style={{ paddingTop: top + 20, marginVertical: 2 }}>
178
- <TouchableOpacity onPress={() => navigation?.canGoBack() && navigation.goBack()} style={{ position: 'absolute', paddingVertical: 20 }}>
179
- <OIcon src={theme.images.general.arrow_left} width={20} />
180
- </TouchableOpacity>
181
- <OText
182
- size={20}
183
- mBottom={15}
184
- weight='bold'
185
- style={{ marginTop: 10 }}
186
- >
187
- {t('SEARCH', 'Search')}
188
- </OText>
189
- </WrapHeader>
190
- <SearchWrapper>
191
- <SearchBar
192
- lazyLoad
193
- inputStyle={{ ...styles.searchInput, ...Platform.OS === 'ios' ? {} : { paddingBottom: 4 } }}
194
- placeholder={`${t('SEARCH_BUSINESSES', 'Search Businesses')} / ${t('TYPE_AT_LEAST_3_CHARACTERS', 'type at least 3 characters')}`}
195
- onSearch={(val: string) => handleChangeTermValue(val)}
196
- value={termValue}
197
- iconCustomRight={<AntDesignIcon name='filter' size={16} style={{ bottom: 2 }} onPress={() => handleOpenfilters()} />}
198
- />
199
-
200
- </SearchWrapper>
201
- {
202
- noResults && (
203
- <View>
204
- <NotFoundSource
205
- content={t('NOT_FOUND_BUSINESSES', 'No businesses to delivery / pick up at this address, please change filters or change address.')}
206
- />
207
- </View>
208
- )
209
- }
210
- <ScrollView horizontal>
211
- {businessesSearchList.businesses?.length > 0 && businessesSearchList.businesses.map((business: any, i: number) => (
212
- <BusinessController
213
- key={business.id}
214
- business={business}
215
- isBusinessOpen={business.open}
216
- handleCustomClick={() => onBusinessClick(business)}
217
- orderType={orderState?.options?.type}
218
- style={{ width: 320, marginRight: (businessesSearchList.loading || i !== businessesSearchList.businesses?.length - 1) ? 20 : 0 }}
219
- />
220
- ))}
221
- {!businessesSearchList.loading && paginationProps?.totalPages && paginationProps?.currentPage < paginationProps?.totalPages && (
222
- <LoadMoreBusinessContainer>
223
- <OButton
224
- bgColor='transparent'
225
- borderColor={theme.colors.primary}
226
- onClick={() => handleSearchbusinessAndProducts()}
227
- text={t('LOAD_MORE_BUSINESS', 'Load more business')}
228
- textStyle={{ color: theme.colors.primary }}
229
- />
230
- </LoadMoreBusinessContainer>
231
- )}
232
- {businessesSearchList.loading && (
233
- <>
234
- {[
235
- ...Array(
236
- paginationProps.nextPageItems
237
- ? paginationProps.nextPageItems
238
- : 3,
239
- ).keys(),
240
- ].map((item, i) => (
241
- <Placeholder
242
- Animation={Fade}
243
- key={i}
244
- style={{ width: 320, marginRight: 20, marginTop: 20 }}>
245
- <View style={{ width: 320 }}>
246
- <PlaceholderLine
247
- height={155}
248
- style={{ marginBottom: 20, borderRadius: 25 }}
249
- />
250
- <View style={{ paddingHorizontal: 10 }}>
251
- <View
252
- style={{
253
- flexDirection: 'row',
254
- justifyContent: 'space-between',
255
- }}>
256
- <PlaceholderLine
257
- height={25}
258
- width={40}
259
- style={{ marginBottom: 10 }}
260
- />
261
- <PlaceholderLine
262
- height={25}
263
- width={20}
264
- style={{ marginBottom: 10 }}
265
- />
266
- </View>
267
- <PlaceholderLine
268
- height={20}
269
- width={30}
270
- style={{ marginBottom: 10 }}
271
- />
272
- <PlaceholderLine
273
- height={20}
274
- width={80}
275
- style={{ marginBottom: 0 }}
276
- />
277
- </View>
278
- </View>
279
- </Placeholder>
280
- ))}
281
- </>
282
- )}
283
- </ScrollView>
284
- <ProductsList>
285
- {businessesSearchList.businesses?.filter((business: any) => business?.categories?.length > 0).map((business: any) => (
286
- <SingleBusinessSearch key={`card-${business?.id}`}>
287
- <SingleBusinessContainer>
288
- <BusinessInfo>
289
- {(business?.logo || theme.images?.dummies?.businessLogo) && (
290
- <FastImage
291
- style={{ height: 48, width: 48 }}
292
- source={{
293
- uri: optimizeImage(business?.logo, 'h_120,c_limit'),
294
- priority: FastImage.priority.normal,
295
- }}
296
- resizeMode={FastImage.resizeMode.cover}
297
- />
298
- )}
299
- </BusinessInfo>
300
- <BusinessInfoItem>
301
- <OText size={12}>{business?.name}</OText>
302
- <Metadata>
303
- {orderState?.options?.type === 1 && (
304
- <>
305
- <OText size={10}>{t('DELIVERY_FEE', 'Delivery fee')}{' '}</OText>
306
- <OText size={10} mRight={3}>
307
- {business && parsePrice(business?.delivery_price)}
308
- </OText>
309
- </>
310
- )}
311
- <OText size={10} mRight={3}>
312
- {convertHoursToMinutes(orderState?.options?.type === 1 ? business?.delivery_time : business?.pickup_time)}
313
- </OText>
314
- <OText size={10}>
315
- {parseDistance(business?.distance)}
316
- </OText>
317
- </Metadata>
318
- </BusinessInfoItem>
319
- <OButton
320
- onClick={() => onBusinessClick(business)}
321
- textStyle={{ color: theme.colors.primary, fontSize: 10 }}
322
- text={t('GO_TO_STORE', 'Go to store')}
323
- bgColor='#F5F9FF'
324
- borderColor='#fff'
325
- style={{ borderRadius: 50, paddingLeft: 5, paddingRight: 5, height: 20 }}
326
- />
327
- </SingleBusinessContainer>
328
- <ScrollView horizontal style={styles.productsContainer}>
329
- {business?.categories?.map((category: any) => category?.products?.map((product: any, i: number) => (
330
- <SingleProductCard
331
- key={product?.id}
332
- isSoldOut={(product.inventoried && !product.quantity)}
333
- product={product}
334
- businessId={business?.id}
335
- onProductClick={() => { }}
336
- productAddedToCartLength={0}
337
- style={{ width: 320, marginRight: i === category?.products?.length - 1 ? 0 : 20 }}
338
- />
339
- )))}
340
-
341
- </ScrollView>
342
- </SingleBusinessSearch>
343
- ))}
344
- {businessesSearchList?.loading && (
345
- <>
346
- {[...Array(3).keys()].map(
347
- (item, i) => (
348
- <View key={`skeleton:${i}`} style={{ width: '100%', marginTop: 20 }}>
349
- <Placeholder key={i} style={{ paddingHorizontal: 5 }} Animation={Fade}>
350
- <View style={{ flexDirection: 'row' }}>
351
- <PlaceholderLine
352
- width={24}
353
- height={70}
354
- style={{ marginRight: 10, marginBottom: 10 }}
355
- />
356
- <Placeholder style={{ paddingVertical: 10 }}>
357
- <PlaceholderLine width={20} style={{ marginBottom: 25 }} />
358
- <PlaceholderLine width={60} />
359
- </Placeholder>
360
- </View>
361
- </Placeholder>
362
- <Placeholder style={{ paddingHorizontal: 5, bottom: 10 }} Animation={Fade}>
363
- <View style={{ flexDirection: 'row-reverse' }}>
364
- <PlaceholderLine
365
- width={24}
366
- height={70}
367
- style={{ marginRight: 10, marginBottom: 5 }}
368
- />
369
- <Placeholder style={{ paddingVertical: 10 }}>
370
- <PlaceholderLine width={60} height={10} />
371
- <PlaceholderLine width={50} height={10} />
372
- <PlaceholderLine width={70} height={10} />
373
- </Placeholder>
374
- </View>
375
- </Placeholder>
376
- </View>
377
- ),
378
- )}
379
- </>
380
- )}
381
- </ProductsList>
382
- <OModal
383
- open={openFilters}
384
- onCancel={() => handleCloseFilters()}
385
- onClose={() => handleCloseFilters()}
386
- >
387
- <ScrollView style={styles.container}>
388
- <OText
389
- size={20}
390
- mBottom={15}
391
- style={{ marginTop: 10 }}
392
- >
393
- {t('FILTER', 'Filter')}
394
- </OText>
395
- <SortContainer>
396
- <OText weight='bold' mBottom={7} size={16}>
397
- {t('SORT', 'Sort')}
398
- </OText>
399
- {sortItems?.map(item => (
400
- <TouchableOpacity
401
- key={item?.value}
402
- onPress={() => handleChangeFilters('orderBy', item?.value)}
403
- style={{ marginBottom: 7 }}
404
- >
405
- <OText
406
- weight={filters?.orderBy?.includes(item?.value) ? 'bold' : '500'}
407
- mBottom={filters?.orderBy?.includes(item?.value) ? 5 : 0}
408
- >
409
- {item?.text} {(filters?.orderBy?.includes(item?.value)) && <>{filters?.orderBy?.includes('-') ? <AntDesignIcon name='caretup' /> : <AntDesignIcon name='caretdown' />}</>}
410
- </OText>
411
- </TouchableOpacity>
412
- ))}
413
- </SortContainer>
414
- {orderState?.options?.type === 1 && (
415
- <MaxSectionItem
416
- title={t('MAX_DELIVERY_FEE', 'Max delivery fee')}
417
- options={maxDeliveryFeeOptions}
418
- filter='max_delivery_price'
419
- />
420
- )}
421
- {[1, 2].includes(orderState?.options?.type) && (
422
- <MaxSectionItem
423
- title={orderState?.options?.type === 1 ? t('MAX_DELIVERY_TIME', 'Max delivery time') : t('MAX_PICKUP_TIME', 'Max pickup time')}
424
- options={maxTimeOptions}
425
- filter='max_eta'
426
- />
427
- )}
428
- <MaxSectionItem
429
- title={t('MAX_DISTANCE', 'Max distance')}
430
- options={maxDistanceOptions}
431
- filter='max_distance'
432
- />
433
- {businessTypes?.length > 0 && (
434
- <TagsContainer>
435
- <OText weight='bold' mBottom={7} size={16}>{t('BUSINESS_CATEGORIES', 'Business categories')}</OText>
436
- <View style={styles.businessTypesContainer}>
437
- {businessTypes.map((type: any, i: number) => type.enabled && (
438
- <OButton
439
- key={type?.id}
440
- bgColor={(filters?.business_types?.includes(type?.id) || (type?.id === null && filters?.business_types?.length === 0)) ? theme.colors.primary : theme.colors.backgroundGray200}
441
- onClick={() => handleChangeActiveBusinessType(type)}
442
- text={`${t(`BUSINESS_TYPE_${type.name.replace(/\s/g, '_').toUpperCase()}`, type.name)} ${filters?.business_types?.includes(type?.id) ? 'X' : ''}`}
443
- style={styles.categoryStyle}
444
- textStyle={{ fontSize: 10, color: (filters?.business_types?.includes(type?.id) || (type?.id === null && filters?.business_types?.length === 0)) ? '#fff' : theme.colors.textNormal }}
445
- />
446
- ))}
447
- </View>
448
- </TagsContainer>
449
- )}
450
- </ScrollView>
451
- <OButton
452
- text={t('APPLY', 'Apply')}
453
- parentStyle={styles.applyButton}
454
- textStyle={{ color: '#fff' }}
455
- onClick={() => handleApplyFilters()}
456
- />
457
- </OModal>
458
- </ScrollView>
459
- )
460
- }
461
-
462
- export const BusinessListingSearch = (props: BusinessSearchParams) => {
463
- const BusinessListSearchProps = {
464
- ...props,
465
- UIComponent: BusinessListingSearchUI,
466
- lazySearch: true
467
- }
468
- return <BusinessSearchList {...BusinessListSearchProps} />
469
- }