ordering-ui-react-native 0.14.91 → 0.14.94

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 (29) hide show
  1. package/package.json +1 -1
  2. package/src/DeliveryApp.tsx +2 -1
  3. package/src/assets/images/no-network.png +0 -0
  4. package/src/providers/AlertProvider.tsx +4 -1
  5. package/src/theme.json +2 -1
  6. package/themes/business/index.tsx +2 -0
  7. package/themes/business/src/components/NetworkError/index.tsx +61 -0
  8. package/themes/business/src/components/NetworkError/styles.tsx +11 -0
  9. package/themes/business/src/types/index.tsx +4 -0
  10. package/themes/kiosk/index.tsx +2 -0
  11. package/themes/kiosk/src/components/NetworkError/index.tsx +60 -0
  12. package/themes/kiosk/src/components/NetworkError/styles.tsx +11 -0
  13. package/themes/kiosk/src/types/index.d.ts +4 -0
  14. package/themes/original/index.tsx +10 -6
  15. package/themes/original/src/components/BusinessController/index.tsx +9 -4
  16. package/themes/original/src/components/BusinessListingSearch/index.tsx +469 -0
  17. package/themes/original/src/components/BusinessListingSearch/styles.tsx +76 -0
  18. package/themes/original/src/components/BusinessTypeFilter/index.tsx +13 -2
  19. package/themes/original/src/components/BusinessesListing/index.tsx +6 -2
  20. package/themes/original/src/components/NetworkError/index.tsx +61 -0
  21. package/themes/original/src/components/NetworkError/styles.tsx +11 -0
  22. package/themes/original/src/components/OrdersOption/index.tsx +29 -22
  23. package/themes/original/src/components/OrdersOption/styles.tsx +1 -0
  24. package/themes/original/src/components/ProductForm/index.tsx +1 -1
  25. package/themes/original/src/components/SearchBar/index.tsx +10 -4
  26. package/themes/original/src/components/SingleProductCard/index.tsx +9 -1
  27. package/themes/original/src/components/SingleProductCard/styles.tsx +1 -1
  28. package/themes/original/src/components/shared/OInput.tsx +2 -1
  29. package/themes/original/src/types/index.tsx +24 -2
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ordering-ui-react-native",
3
- "version": "0.14.91",
3
+ "version": "0.14.94",
4
4
  "description": "Reusable components made in react native",
5
5
  "main": "src/index.tsx",
6
6
  "author": "ordering.inc",
@@ -88,7 +88,8 @@ theme.images = {
88
88
  close: require('./assets/icons/close.png'),
89
89
  orderCreating: require('./assets/images/order-creating.png'),
90
90
  orderSuccess: require('./assets/images/order-success.png'),
91
- newOrder: require('./assets/images/new-order.png')
91
+ newOrder: require('./assets/images/new-order.png'),
92
+ noNetwork: require('./assets/images/no-network.png')
92
93
  },
93
94
  order: {
94
95
  status0: require('./assets/images/status-0.png'),
Binary file
@@ -28,7 +28,10 @@ const Alert = (props: Props) => {
28
28
  show={open}
29
29
  showProgress={false}
30
30
  title={title}
31
- message={getTraduction(content?.[0], t)}
31
+ message={typeof content === 'string'
32
+ ? content
33
+ : getTraduction(content?.[0], t)
34
+ }
32
35
  closeOnTouchOutside={true}
33
36
  closeOnHardwareBackPress={false}
34
37
  showConfirmButton={true}
package/src/theme.json CHANGED
@@ -93,7 +93,8 @@
93
93
  "close": "",
94
94
  "orderCreating": "",
95
95
  "orderSuccess": "",
96
- "newOrder": ""
96
+ "newOrder": "",
97
+ "noNetwork": ""
97
98
  },
98
99
  "order": {
99
100
  "status0": "",
@@ -10,6 +10,7 @@ import { LanguageSelector } from './src/components/LanguageSelector';
10
10
  import { LoginForm } from './src/components/LoginForm';
11
11
  import { LogoutButton } from './src/components/LogoutButton';
12
12
  import { MessagesOption } from './src/components/MessagesOption';
13
+ import { NetworkError } from './src/components/NetworkError';
13
14
  import { NotFoundSource } from './src/components/NotFoundSource';
14
15
  import { OrderMessage } from './src/components/OrderMessage';
15
16
  import { OrderDetailsBusiness } from './src/components/OrderDetails/Business';
@@ -77,6 +78,7 @@ export {
77
78
  MessagesOption,
78
79
  MapView,
79
80
  NewOrderNotification,
81
+ NetworkError,
80
82
  NotFoundSource,
81
83
  OrderDetailsBusiness,
82
84
  OrderDetailsDelivery,
@@ -0,0 +1,61 @@
1
+ import React from 'react'
2
+ import { useLanguage } from 'ordering-components/native'
3
+ import { Dimensions } from 'react-native'
4
+ import RNRestart from 'react-native-restart'
5
+ import { OText, OIcon, OButton } from '../shared'
6
+ import { useTheme } from 'styled-components/native'
7
+ import { NoNetworkParams } from '../../types'
8
+ import {
9
+ Container,
10
+ ImageContainer
11
+ } from './styles'
12
+
13
+ export const NetworkError = (props: NoNetworkParams) => {
14
+ const {
15
+ image
16
+ } = props
17
+ const theme = useTheme()
18
+ const [, t] = useLanguage()
19
+
20
+ const noNetworkImage = image || theme.images.general.noNetwork
21
+ const deviceWidth = Dimensions.get('screen').width
22
+
23
+ return (
24
+ <Container>
25
+ <OText
26
+ color={theme.colors.darkText}
27
+ size={20}
28
+ weight='700'
29
+ style={{ marginBottom: 14 }}
30
+ >
31
+ {t('MOBILE_NO_INTERNET', 'No internet connection')}
32
+ </OText>
33
+ <OText
34
+ color={theme.colors.darkText}
35
+ size={14}
36
+ >
37
+ {t('NETWORK_OFFLINE_MESSAGE', 'Your connection appears to be off-line. Try to refresh the page')}
38
+ </OText>
39
+ <ImageContainer>
40
+ <OIcon
41
+ src={noNetworkImage}
42
+ width={(deviceWidth - 80) * 0.9}
43
+ height={(deviceWidth - 80) * 0.8}
44
+ />
45
+ <OButton
46
+ text={t('REFRESH', 'Refresh')}
47
+ bgColor={theme.colors.primary}
48
+ borderColor={theme.colors.primary}
49
+ style={{
50
+ borderRadius: 8,
51
+ marginTop: 45
52
+ }}
53
+ textStyle={{
54
+ color: theme.colors.white
55
+ }}
56
+ onClick={() => RNRestart.Restart()}
57
+ />
58
+ </ImageContainer>
59
+ </Container>
60
+ )
61
+ }
@@ -0,0 +1,11 @@
1
+ import styled from 'styled-components/native'
2
+
3
+ export const Container = styled.View`
4
+ flex: 1;
5
+ padding: 20px 40px;
6
+ `
7
+ export const ImageContainer = styled.View`
8
+ flex: 1;
9
+ align-items: center;
10
+ justify-content: center;
11
+ `
@@ -575,3 +575,7 @@ export interface ReviewCustomerParams {
575
575
  handleChangeQualification?: any,
576
576
  handleSendCustomerReview?: any,
577
577
  }
578
+
579
+ export interface NoNetworkParams {
580
+ image?: any;
581
+ }
@@ -14,6 +14,7 @@ import { LanguageSelector } from './src/components/LanguageSelector'
14
14
  import { LoginForm } from './src/components/LoginForm'
15
15
  import { LogoutPopup } from './src/components/LogoutPopup'
16
16
  import Navbar from './src/components/NavBar'
17
+ import { NetworkError } from './src/components/NetworkError'
17
18
  import { NotFoundSource } from './src/components/NotFoundSource'
18
19
  import OptionCard from './src/components/OptionCard'
19
20
  import { OrderDetails } from './src/components/OrderDetails'
@@ -82,6 +83,7 @@ export {
82
83
  LoginForm,
83
84
  LogoutPopup,
84
85
  Navbar,
86
+ NetworkError,
85
87
  NotFoundSource,
86
88
  OptionCard,
87
89
  OrderDetails,
@@ -0,0 +1,60 @@
1
+ import React from 'react'
2
+ import { useLanguage } from 'ordering-components/native'
3
+ import { Dimensions } from 'react-native'
4
+ import RNRestart from 'react-native-restart'
5
+ import { OText, OIcon, OButton } from '../shared'
6
+ import { useTheme } from 'styled-components/native'
7
+ import { NoNetworkParams } from '../../types'
8
+ import {
9
+ Container,
10
+ ImageContainer
11
+ } from './styles'
12
+
13
+ export const NetworkError = (props: NoNetworkParams) => {
14
+ const {
15
+ image
16
+ } = props
17
+ const theme = useTheme()
18
+ const [, t] = useLanguage()
19
+
20
+ const noNetworkImage = image || theme.images.general.noNetwork
21
+ const deviceHeight = Dimensions.get('screen').height
22
+
23
+ return (
24
+ <Container>
25
+ <OText
26
+ size={20}
27
+ weight='700'
28
+ style={{ marginBottom: 14 }}
29
+ >
30
+ {t('MOBILE_NO_INTERNET', 'No internet connection')}
31
+ </OText>
32
+ <OText
33
+ size={14}
34
+ >
35
+ {t('NETWORK_OFFLINE_MESSAGE', 'Your connection appears to be off-line. Try to refresh the page')}
36
+ </OText>
37
+ <ImageContainer>
38
+ <OIcon
39
+ src={noNetworkImage}
40
+ width={(deviceHeight - 180) * 0.7}
41
+ height={(deviceHeight - 180) * 0.63}
42
+ />
43
+ <OButton
44
+ text={t('REFRESH', 'Refresh')}
45
+ bgColor={theme.colors.primary}
46
+ borderColor={theme.colors.primary}
47
+ style={{
48
+ borderRadius: 8,
49
+ marginTop: 45,
50
+ height: 44
51
+ }}
52
+ textStyle={{
53
+ color: theme.colors.white
54
+ }}
55
+ onClick={() => RNRestart.Restart()}
56
+ />
57
+ </ImageContainer>
58
+ </Container>
59
+ )
60
+ }
@@ -0,0 +1,11 @@
1
+ import styled from 'styled-components/native'
2
+
3
+ export const Container = styled.View`
4
+ flex: 1;
5
+ padding: 20px 40px;
6
+ `
7
+ export const ImageContainer = styled.View`
8
+ flex: 1;
9
+ align-items: center;
10
+ justify-content: center;
11
+ `
@@ -473,3 +473,7 @@ export interface Cart {
473
473
  total: number;
474
474
  clearInactivityTimeout: any;
475
475
  }
476
+
477
+ export interface NoNetworkParams {
478
+ image?: any;
479
+ }
@@ -28,6 +28,7 @@ import { Help } from './src/components/Help';
28
28
  import { HelpAccountAndPayment } from './src/components/HelpAccountAndPayment';
29
29
  import { HelpGuide } from './src/components/HelpGuide';
30
30
  import { HelpOrder } from './src/components/HelpOrder';
31
+ import { NetworkError } from './src/components/NetworkError';
31
32
  import { NotFoundSource } from './src/components/NotFoundSource';
32
33
  import { OrderTypeSelector } from './src/components/OrderTypeSelector';
33
34
  import { Wallets } from './src/components/Wallets';
@@ -35,6 +36,7 @@ import { PaymentOptionWallet } from './src/components/PaymentOptionWallet';
35
36
  import { ProductForm } from './src/components/ProductForm';
36
37
  import { UpsellingProducts } from './src/components/UpsellingProducts';
37
38
  import { UserVerification } from './src/components/UserVerification';
39
+ import { BusinessListingSearch } from './src/components/BusinessListingSearch';
38
40
 
39
41
  import { Toast } from './src/components/shared/OToast';
40
42
  import {
@@ -74,7 +76,7 @@ export {
74
76
  BusinessesListing,
75
77
  BusinessProductsListing,
76
78
  CartContent,
77
- BusinessCart,
79
+ BusinessCart,
78
80
  Checkout,
79
81
  ForgotPasswordForm,
80
82
  MomentOption,
@@ -93,13 +95,15 @@ export {
93
95
  HelpAccountAndPayment,
94
96
  HelpGuide,
95
97
  HelpOrder,
98
+ NetworkError,
96
99
  NotFoundSource,
97
100
  OrderTypeSelector,
98
- Wallets,
99
- PaymentOptionWallet,
100
- ProductForm,
101
- UpsellingProducts,
102
- UserVerification,
101
+ Wallets,
102
+ PaymentOptionWallet,
103
+ ProductForm,
104
+ UpsellingProducts,
105
+ UserVerification,
106
+ BusinessListingSearch,
103
107
 
104
108
  // OComponents
105
109
  Toast,
@@ -25,9 +25,14 @@ import FontAwesomeIcon from 'react-native-vector-icons/FontAwesome5';
25
25
  import FastImage from 'react-native-fast-image'
26
26
 
27
27
  export const BusinessControllerUI = (props: BusinessControllerParams) => {
28
- const { business, handleClick, navigation, isBusinessOpen } = props;
29
- const [{ parsePrice, parseDistance, parseNumber, optimizeImage }] =
30
- useUtils();
28
+ const {
29
+ business,
30
+ handleClick,
31
+ navigation,
32
+ isBusinessOpen,
33
+ style
34
+ } = props;
35
+ const [{ parsePrice, parseDistance, parseNumber, optimizeImage }] = useUtils();
31
36
  const [orderState] = useOrder();
32
37
  const [, t] = useLanguage();
33
38
  const theme = useTheme()
@@ -106,7 +111,7 @@ export const BusinessControllerUI = (props: BusinessControllerParams) => {
106
111
  }
107
112
 
108
113
  return (
109
- <Card activeOpacity={1} onPress={() => handleBusinessClick(business)}>
114
+ <Card activeOpacity={1} onPress={() => handleBusinessClick(business)} style={style}>
110
115
  <BusinessHero>
111
116
  <FastImage
112
117
  style={{ height: 120 }}
@@ -0,0 +1,469 @@
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
+ }
@@ -0,0 +1,76 @@
1
+ import styled from 'styled-components/native'
2
+
3
+ export const WrapHeader = styled.View`
4
+ width: 100%;
5
+ padding-vertical: 20px;
6
+ `
7
+
8
+ export const SearchWrapper = styled.View`
9
+
10
+ `
11
+
12
+ export const ProductsList = styled.View`
13
+
14
+ `
15
+
16
+ export const SingleBusinessSearch = styled.View`
17
+ width: 100%;
18
+ margin: 20px 0;
19
+ `
20
+
21
+ export const BusinessInfo = styled.View`
22
+ width: 15%;
23
+ flex-direction: row;
24
+ `
25
+
26
+ export const BusinessLogo = styled.View`
27
+
28
+ `
29
+
30
+ export const BusinessInfoItem = styled.View`
31
+ width: 50%;
32
+ display: flex;
33
+ flex-direction: column;
34
+ justify-content: center;
35
+ font-size: 12px;
36
+ margin-left: 10px;
37
+ `
38
+
39
+ export const Metadata = styled.View`
40
+ margin-top: 5px;
41
+ display: flex;
42
+ flex-direction: row;
43
+ flex-wrap: wrap;
44
+ `
45
+
46
+ export const SingleBusinessContainer = styled.View`
47
+ width: 100%;
48
+ flex-direction: row;
49
+ justify-content: space-between;
50
+ `
51
+
52
+ export const LoadMoreBusinessContainer = styled.View`
53
+ align-items: center;
54
+ justify-content: center;
55
+ margin-left: 20px;
56
+ `
57
+
58
+ export const ProgressBar = styled.View`
59
+ height: 4px;
60
+ background: ${(props: any) => props.theme.colors.textNormal};
61
+ `
62
+
63
+ export const ProgressContentWrapper = styled.View`
64
+ height: 4px;
65
+ background: #F8F9FA;
66
+ margin-bottom: 10px;
67
+ flex: 1;
68
+ `
69
+
70
+ export const TagsContainer = styled.View`
71
+
72
+ `
73
+
74
+ export const SortContainer = styled.View`
75
+ margin-bottom: 10px;
76
+ `
@@ -1,4 +1,4 @@
1
- import React, { useState } from 'react';
1
+ import React, { useState, useEffect } from 'react';
2
2
  import {
3
3
  StyleSheet,
4
4
  FlatList,
@@ -24,13 +24,24 @@ import { BusinessTypeFilterParams } from '../../types';
24
24
  const windowWidth = Dimensions.get('window').width;
25
25
 
26
26
  export const BusinessTypeFilterUI = (props: BusinessTypeFilterParams) => {
27
- const { typesState, currentTypeSelected, handleChangeBusinessType } = props;
27
+ const {
28
+ typesState,
29
+ currentTypeSelected,
30
+ handleChangeBusinessType,
31
+ setBusinessTypes
32
+ } = props;
28
33
 
29
34
  const [, t] = useLanguage();
30
35
 
31
36
  const theme = useTheme();
32
37
  const [isOpenAllCategories, setIsOpenAllCategories] = useState(false)
33
38
 
39
+ useEffect(() => {
40
+ if(typesState?.types?.length > 0){
41
+ setBusinessTypes && setBusinessTypes(typesState?.types)
42
+ }
43
+ }, [typesState])
44
+
34
45
  const renderTypes = ({ item }: any) => {
35
46
  return (
36
47
  <TouchableOpacity
@@ -116,8 +116,9 @@ const BusinessesListingUI = (props: BusinessesListingParams) => {
116
116
 
117
117
  const [featuredBusiness, setFeaturedBusinesses] = useState(Array);
118
118
  const [isFarAway, setIsFarAway] = useState(false)
119
+ const [businessTypes, setBusinessTypes] = useState(null)
119
120
 
120
- const isPreorderEnabled = (configs?.preorder_status_enabled?.value === '1' || configs?.preorder_status_enabled?.value === 'true') &&
121
+ const isPreorderEnabled = (configs?.preorder_status_enabled?.value === '1' || configs?.preorder_status_enabled?.value === 'true') &&
121
122
  Number(configs?.max_days_preorder?.value) > 0
122
123
 
123
124
  const timerId = useRef<any>(false)
@@ -131,7 +132,7 @@ const BusinessesListingUI = (props: BusinessesListingParams) => {
131
132
  // })
132
133
  // ).current
133
134
 
134
- const handleMomentClick = () => {
135
+ const handleMomentClick = () => {
135
136
  if (isPreorderEnabled) {
136
137
  navigation.navigate('MomentOption')
137
138
  }
@@ -317,7 +318,9 @@ const BusinessesListingUI = (props: BusinessesListingParams) => {
317
318
  onCancel={() => handleChangeSearch('')}
318
319
  placeholder={t('SEARCH', 'Search')}
319
320
  height={26}
321
+ isDisabled={configs?.advanced_business_search_enabled?.value === '1' || !businessTypes}
320
322
  inputStyle={{ ...styles.searchInput, ...Platform.OS === 'ios' ? {} : { paddingBottom: 4 } }}
323
+ onPress={() => { configs?.advanced_business_search_enabled?.value === '1' && navigation.navigate('BusinessSearch', { businessTypes }) }}
321
324
  />
322
325
  )}
323
326
 
@@ -378,6 +381,7 @@ const BusinessesListingUI = (props: BusinessesListingParams) => {
378
381
  businessTypes={props.businessTypes}
379
382
  defaultBusinessType={props.defaultBusinessType}
380
383
  handleChangeBusinessType={handleChangeBusinessType}
384
+ setBusinessTypes={setBusinessTypes}
381
385
  />
382
386
  )}
383
387
  {!businessesList.loading && businessesList.businesses.length === 0 && (
@@ -0,0 +1,61 @@
1
+ import React from 'react'
2
+ import { useLanguage } from 'ordering-components/native'
3
+ import { Dimensions } from 'react-native'
4
+ import RNRestart from 'react-native-restart'
5
+ import { OText, OIcon, OButton } from '../shared'
6
+ import { useTheme } from 'styled-components/native'
7
+ import { NoNetworkParams } from '../../types'
8
+ import {
9
+ Container,
10
+ ImageContainer
11
+ } from './styles'
12
+
13
+ export const NetworkError = (props: NoNetworkParams) => {
14
+ const {
15
+ image
16
+ } = props
17
+ const theme = useTheme()
18
+ const [, t] = useLanguage()
19
+
20
+ const noNetworkImage = image || theme.images.general.noNetwork
21
+ const deviceWidth = Dimensions.get('screen').width
22
+
23
+ return (
24
+ <Container>
25
+ <OText
26
+ color={theme.colors.textNormal}
27
+ size={20}
28
+ weight='700'
29
+ style={{ marginBottom: 14 }}
30
+ >
31
+ {t('MOBILE_NO_INTERNET', 'No internet connection')}
32
+ </OText>
33
+ <OText
34
+ color={theme.colors.textNormal}
35
+ size={14}
36
+ >
37
+ {t('NETWORK_OFFLINE_MESSAGE', 'Your connection appears to be off-line. Try to refresh the page')}
38
+ </OText>
39
+ <ImageContainer>
40
+ <OIcon
41
+ src={noNetworkImage}
42
+ width={(deviceWidth - 80) * 0.9}
43
+ height={(deviceWidth - 80) * 0.8}
44
+ />
45
+ <OButton
46
+ text={t('REFRESH', 'Refresh')}
47
+ bgColor={theme.colors.primary}
48
+ borderColor={theme.colors.primary}
49
+ style={{
50
+ borderRadius: 8,
51
+ marginTop: 45
52
+ }}
53
+ textStyle={{
54
+ color: theme.colors.white
55
+ }}
56
+ onClick={() => RNRestart.Restart()}
57
+ />
58
+ </ImageContainer>
59
+ </Container>
60
+ )
61
+ }
@@ -0,0 +1,11 @@
1
+ import styled from 'styled-components/native'
2
+
3
+ export const Container = styled.View`
4
+ flex: 1;
5
+ padding: 20px 40px;
6
+ `
7
+ export const ImageContainer = styled.View`
8
+ flex: 1;
9
+ align-items: center;
10
+ justify-content: center;
11
+ `
@@ -95,7 +95,7 @@ const OrdersOptionUI = (props: OrdersOptionParams) => {
95
95
  { key: 20, value: t('ORDER_CUSTOMER_ALMOST_ARRIVED_BUSINESS', 'Customer almost arrived to business') },
96
96
  { key: 21, value: t('ORDER_CUSTOMER_ARRIVED_BUSINESS', 'Customer arrived to business') },
97
97
  { key: 22, value: t('ORDER_LOOKING_FOR_DRIVER', 'Looking for driver') },
98
- { key: 23, value: t('ORDER_DRIVER_ON_WAY', 'Driver on way') }
98
+ { key: 23, value: t('ORDER_DRIVER_ON_WAY', 'Driver on way') }
99
99
  ]
100
100
 
101
101
  const objectStatus = orderStatus.find((o) => o.key === status)
@@ -105,9 +105,9 @@ const OrdersOptionUI = (props: OrdersOptionParams) => {
105
105
 
106
106
  useFocusEffect(
107
107
  React.useCallback(() => {
108
- loadOrders()
108
+ loadOrders()
109
109
  }, [navigation])
110
- )
110
+ )
111
111
 
112
112
  useEffect(() => {
113
113
  const hasMore = pagination?.totalPages && pagination?.currentPage !== pagination?.totalPages
@@ -126,27 +126,11 @@ const OrdersOptionUI = (props: OrdersOptionParams) => {
126
126
  } else if (!preOrders) {
127
127
  setOrdersLength && setOrdersLength({ ...ordersLength, previousOrdersLength: updateOrders?.length })
128
128
  }
129
- }, [orders?.length])
129
+ }, [orders, activeOrders])
130
130
 
131
131
  return (
132
132
  <>
133
- <OptionTitle>
134
- <OText size={16} lineHeight={24} weight={'500'} color={theme.colors.textNormal} mBottom={10} >
135
- {titleContent || (activeOrders
136
- ? t('ACTIVE', 'Active')
137
- : preOrders
138
- ? t('PREORDERS', 'Preorders')
139
- : t('PAST', 'Past'))}
140
- </OText>
141
- </OptionTitle>
142
- {!(activeOrders && ordersLength.activeOrdersLength === 0 && ordersLength.previousOrdersLength === 0) && !loading && orders.length === 0 && (
143
- <NotFoundSource
144
- content={t('NO_RESULTS_FOUND', 'Sorry, no results found')}
145
- image={imageFails}
146
- conditioned
147
- />
148
- )}
149
- {!loading && ordersLength.activeOrdersLength === 0 && ordersLength.previousOrdersLength === 0 && activeOrders && (
133
+ {!loading && ordersLength.activeOrdersLength === 0 && ordersLength.previousOrdersLength === 0 && !activeOrders && (
150
134
  <NoOrdersWrapper>
151
135
  <OText size={14} numberOfLines={1}>
152
136
  {t('YOU_DONT_HAVE_ORDERS', 'You don\'t have any orders')}
@@ -157,9 +141,32 @@ const OrdersOptionUI = (props: OrdersOptionParams) => {
157
141
  textStyle={{ color: 'white', fontSize: 14 }}
158
142
  style={{ borderRadius: 7.6, marginBottom: 10, marginTop: 10, height: 44, paddingLeft: 10, paddingRight: 10 }}
159
143
  />
160
-
144
+
161
145
  </NoOrdersWrapper>
162
146
  )}
147
+ {(ordersLength.activeOrdersLength > 0 || ordersLength.previousOrdersLength > 0) && (
148
+ <>
149
+ <OptionTitle>
150
+ <OText size={16} lineHeight={24} weight={'500'} color={theme.colors.textNormal} mBottom={10} >
151
+ {titleContent || (activeOrders
152
+ ? t('ACTIVE', 'Active')
153
+ : preOrders
154
+ ? t('PREORDERS', 'Preorders')
155
+ : t('PAST', 'Past'))}
156
+ </OText>
157
+ </OptionTitle>
158
+ {!(ordersLength.activeOrdersLength === 0 && ordersLength.previousOrdersLength === 0) &&
159
+ !loading &&
160
+ orders.filter((order: any) => orderStatus.includes(order.status)).length === 0 &&
161
+ (
162
+ <NotFoundSource
163
+ content={t('NO_RESULTS_FOUND', 'Sorry, no results found')}
164
+ image={imageFails}
165
+ conditioned
166
+ />
167
+ )}
168
+ </>
169
+ )}
163
170
  {loading && (
164
171
  <>
165
172
  {!activeOrders ? (
@@ -7,4 +7,5 @@ export const OptionTitle = styled.View`
7
7
  export const NoOrdersWrapper = styled.View`
8
8
  flex-direction: column;
9
9
  align-items: center;
10
+ margin-top: 50px;
10
11
  `
@@ -396,7 +396,7 @@ export const ProductOptionsUI = (props: any) => {
396
396
  <FastImage
397
397
  style={{ height: '100%', opacity: isSoldOut ? 0.5 : 1 }}
398
398
  source={{
399
- uri: optimizeImage(img, 'h_258,c_limit'),
399
+ uri: optimizeImage(img, 'h_1024,c_limit'),
400
400
  priority: FastImage.priority.normal,
401
401
  }}
402
402
  />
@@ -1,5 +1,5 @@
1
1
  import React from 'react'
2
- import { StyleSheet, View, TouchableOpacity, ImageStore, Platform, TextInput } from 'react-native'
2
+ import { StyleSheet, View, TouchableOpacity, ImageStore, Platform, TextInput, Pressable } from 'react-native'
3
3
  import { OInput, OButton } from '../shared'
4
4
  import { useLanguage } from 'ordering-components/native'
5
5
  import { useTheme } from 'styled-components/native';
@@ -17,7 +17,10 @@ export const SearchBar = (props: any) => {
17
17
  noBorderShow,
18
18
  borderStyle,
19
19
  height,
20
- inputStyle
20
+ inputStyle,
21
+ onPress,
22
+ isDisabled,
23
+ iconCustomRight
21
24
  } = props
22
25
 
23
26
  const theme = useTheme();
@@ -72,16 +75,19 @@ export const SearchBar = (props: any) => {
72
75
  }
73
76
 
74
77
  return (
75
- <View style={[styles.container, { height: height }]}>
78
+ <Pressable style={[styles.container, { height: height }]}>
76
79
  <OInput
77
80
  value={searchValue}
78
81
  onChange={onChangeSearch}
79
82
  style={styles.inputStyle}
80
83
  placeholder={placeholder}
81
84
  icon={theme.images.general.search}
85
+ isDisabled={isDisabled}
82
86
  iconStyle={{ width: 12 }}
83
87
  returnKeyType='done'
84
88
  inputStyle={{padding: 0, paddingTop: Platform.OS == 'android' ? 2 : 0, ...inputStyle}}
89
+ onPress={() => onPress && onPress()}
90
+ iconCustomRight={iconCustomRight}
85
91
  />
86
92
  {isCancelButtonShow && (
87
93
  <OButton
@@ -105,6 +111,6 @@ export const SearchBar = (props: any) => {
105
111
  />
106
112
  </TouchableOpacity>
107
113
  )}
108
- </View>
114
+ </Pressable>
109
115
  )
110
116
  }
@@ -13,7 +13,14 @@ import { OText, OIcon } from '../shared';
13
13
  import FastImage from 'react-native-fast-image'
14
14
 
15
15
  export const SingleProductCard = (props: SingleProductCardParams) => {
16
- const { businessId, product, isSoldOut, onProductClick, productAddedToCartLength } = props;
16
+ const {
17
+ businessId,
18
+ product,
19
+ isSoldOut,
20
+ onProductClick,
21
+ productAddedToCartLength,
22
+ style
23
+ } = props;
17
24
 
18
25
  const theme = useTheme();
19
26
 
@@ -102,6 +109,7 @@ export const SingleProductCard = (props: SingleProductCardParams) => {
102
109
  style={[
103
110
  styles.container,
104
111
  (isSoldOut || maxProductQuantity <= 0) && styles.soldOutBackgroundStyle,
112
+ (style && { ...style }),
105
113
  ]}
106
114
  onPress={() => onProductClick?.(product)}>
107
115
  {productAddedToCartLength > 0 && (
@@ -30,4 +30,4 @@ export const QuantityContainer = styled.View`
30
30
  export const PricesContainer = styled.View`
31
31
  flex-direction: row;
32
32
  align-items: center;
33
- `
33
+ `
@@ -38,6 +38,7 @@ interface Props extends TextInputProps {
38
38
  forwardRef?: any;
39
39
  inputStyle?: TextStyle;
40
40
  wrapperRef?: any;
41
+ onPress?: any;
41
42
  }
42
43
 
43
44
  const Wrapper = styled.Pressable`
@@ -55,7 +56,7 @@ const Wrapper = styled.Pressable`
55
56
  const OInput = (props: Props): React.ReactElement => {
56
57
  return (
57
58
  <Wrapper
58
- onPress={() => props.forwardRef?.current?.focus?.()}
59
+ onPress={() => {props.forwardRef?.current?.focus?.(); props.onPress && props.onPress()}}
59
60
  style={{
60
61
  backgroundColor: props.bgColor,
61
62
  borderColor: props.borderColor,
@@ -151,6 +151,7 @@ export interface BusinessTypeFilterParams {
151
151
  defaultBusinessType?: string | null;
152
152
  images?: any
153
153
  typesState?: any
154
+ setBusinessTypes?: any
154
155
  }
155
156
  export interface BusinessControllerParams {
156
157
  key?: number;
@@ -161,7 +162,8 @@ export interface BusinessControllerParams {
161
162
  isBusinessOpen?: boolean;
162
163
  businessWillCloseSoonMinutes?: number
163
164
  isBusinessClose?: number,
164
- navigation?: any
165
+ navigation?: any,
166
+ style?: ViewStyle
165
167
  }
166
168
  export interface BusinessProductsListingParams {
167
169
  navigation?: any;
@@ -229,7 +231,8 @@ export interface SingleProductCardParams {
229
231
  product: any;
230
232
  isSoldOut: boolean;
231
233
  onProductClick: any;
232
- productAddedToCartLength: number
234
+ productAddedToCartLength: number;
235
+ style?: ViewStyle
233
236
  }
234
237
  export interface BusinessInformationParams {
235
238
  navigation?: any,
@@ -520,3 +523,22 @@ export interface MessageListingParams {
520
523
  navigation: any;
521
524
  franchiseId?: any;
522
525
  }
526
+
527
+ export interface BusinessSearchParams {
528
+ navigation: any,
529
+ businessesSearchList: any,
530
+ onBusinessClick: any,
531
+ handleChangeTermValue: (term: string) => void,
532
+ termValue: string,
533
+ paginationProps: any,
534
+ handleSearchbusinessAndProducts: (newFetch?: boolean) => void,
535
+ handleChangeFilters: (prop : string, value : any) => void,
536
+ filters: any,
537
+ businessTypes: Array<number>,
538
+ setFilters: (filters: any) => void,
539
+ lazySearch?: boolean
540
+ }
541
+
542
+ export interface NoNetworkParams {
543
+ image?: any,
544
+ }