ordering-ui-react-native 0.18.1-release → 0.18.2-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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ordering-ui-react-native",
3
- "version": "0.18.1-release",
3
+ "version": "0.18.2-release",
4
4
  "description": "Reusable components made in react native",
5
5
  "main": "src/index.tsx",
6
6
  "author": "ordering.inc",
@@ -0,0 +1,317 @@
1
+ import React, { useState } from 'react'
2
+ import { useLanguage, useOrder } from 'ordering-components/native'
3
+ import { ScrollView, StyleSheet, TouchableOpacity, View, Dimensions } from 'react-native'
4
+ import { useTheme } from 'styled-components/native'
5
+ import { OButton, OModal, OText } from '../shared'
6
+ import AntDesignIcon from 'react-native-vector-icons/AntDesign'
7
+ import {
8
+ ProductsList,
9
+ TagsContainer,
10
+ SortContainer,
11
+ BrandContainer,
12
+ BrandItem,
13
+ PriceFilterWrapper,
14
+ BContainer,
15
+ WrapperButtons
16
+ } from './styles'
17
+ import { Fade, Placeholder, PlaceholderLine } from 'rn-placeholder'
18
+ import { MaxSectionItem } from './MaxSectionItem'
19
+
20
+ export const BusinessSearchFooter = (props: any) => {
21
+ const {
22
+ businessesSearchList,
23
+ handleCloseFilters,
24
+ handleChangeFilters,
25
+ brandList,
26
+ filters,
27
+ handleChangeBrandFilter,
28
+ handleChangePriceRange,
29
+ businessTypes,
30
+ handleApplyFilters,
31
+ clearFilters,
32
+ handleChangeActiveBusinessType,
33
+ openFilters
34
+ } = props
35
+
36
+ const screenHeight = Dimensions.get('window').height;
37
+ const theme = useTheme()
38
+ const [orderState] = useOrder()
39
+
40
+ const [, t] = useLanguage()
41
+
42
+ const maxDeliveryFeeOptions = [15, 25, 35, 'default']
43
+ // const maxProductPriceOptions = [5, 10, 15, 'default']
44
+ const maxDistanceOptions = [1000, 2000, 5000, 'default']
45
+ const maxTimeOptions = [5, 15, 30, 'default']
46
+ const sortItems = [
47
+ { text: t('PICKED_FOR_YOU', 'Picked for you (default)'), value: 'distance' },
48
+ { text: t('DELIVERY_TIME', 'Delivery time'), value: 'delivery_time' },
49
+ { text: t('PICKUP_TIME', 'Pickup time'), value: 'pickup_time' }
50
+ ]
51
+
52
+ const priceList = [
53
+ { level: '1', content: '$' },
54
+ { level: '2', content: '$$' },
55
+ { level: '3', content: '$$$' },
56
+ { level: '4', content: '$$$$' },
57
+ { level: '5', content: '$$$$$' }
58
+ ]
59
+
60
+ const styles = StyleSheet.create({
61
+ container: {
62
+ paddingHorizontal: 40,
63
+ width: '100%'
64
+ },
65
+ filterContainer: {
66
+ maxHeight: screenHeight - 150,
67
+ paddingHorizontal: 20,
68
+ width: '100%'
69
+ },
70
+ businessTypesContainer: {
71
+ width: '100%',
72
+ flexDirection: 'row',
73
+ flexWrap: 'wrap',
74
+ justifyContent: 'center'
75
+ },
76
+ priceContainer: {
77
+ width: '100%',
78
+ flexDirection: 'row',
79
+ flexWrap: 'wrap',
80
+ justifyContent: 'space-between'
81
+ },
82
+ categoryStyle: {
83
+ marginRight: 10,
84
+ marginTop: 10,
85
+ borderRadius: 50,
86
+ paddingHorizontal: 10,
87
+ paddingVertical: 4,
88
+ paddingLeft: 0,
89
+ paddingRight: 0,
90
+ height: 28,
91
+ borderWidth: 0
92
+ },
93
+ priceItem: {
94
+ marginRight: 10,
95
+ marginTop: 10,
96
+ borderRadius: 50,
97
+ paddingVertical: 4,
98
+ paddingLeft: 5,
99
+ paddingRight: 5,
100
+ height: 27,
101
+ borderWidth: 0
102
+ },
103
+ applyButton: {
104
+ paddingHorizontal: 10,
105
+ width: '100%',
106
+ marginTop: 20
107
+ }
108
+ });
109
+
110
+ return (
111
+ <>
112
+ <BContainer
113
+ style={{ paddingHorizontal: 20 }}
114
+ >
115
+ <ProductsList>
116
+ {businessesSearchList?.loading && (
117
+ <>
118
+ {[...Array(3).keys()].map(
119
+ (item, i) => (
120
+ <View key={`skeleton:${i}`} style={{ width: '100%', marginTop: 20 }}>
121
+ <Placeholder key={i} style={{ paddingHorizontal: 5 }} Animation={Fade}>
122
+ <View style={{ flexDirection: 'row' }}>
123
+ <PlaceholderLine
124
+ width={24}
125
+ height={70}
126
+ style={{ marginRight: 10, marginBottom: 10 }}
127
+ />
128
+ <Placeholder style={{ paddingVertical: 10 }}>
129
+ <PlaceholderLine width={20} style={{ marginBottom: 25 }} />
130
+ <PlaceholderLine width={60} />
131
+ </Placeholder>
132
+ </View>
133
+ </Placeholder>
134
+ <Placeholder style={{ paddingHorizontal: 5, bottom: 10 }} Animation={Fade}>
135
+ <View style={{ flexDirection: 'row-reverse', overflow: 'hidden' }}>
136
+ <PlaceholderLine
137
+ width={24}
138
+ height={70}
139
+ style={{ marginRight: 10, marginBottom: 5 }}
140
+ />
141
+ <Placeholder style={{ paddingVertical: 10 }}>
142
+ <PlaceholderLine width={60} height={10} />
143
+ <PlaceholderLine width={50} height={10} />
144
+ <PlaceholderLine width={70} height={10} />
145
+ </Placeholder>
146
+ </View>
147
+ </Placeholder>
148
+ </View>
149
+ ),
150
+ )}
151
+ </>
152
+ )}
153
+ </ProductsList>
154
+ </BContainer>
155
+ <OModal
156
+ open={openFilters}
157
+ onCancel={() => handleCloseFilters()}
158
+ onClose={() => handleCloseFilters()}
159
+ >
160
+ <ScrollView style={styles.filterContainer}>
161
+ <OText
162
+ size={20}
163
+ mBottom={15}
164
+ style={{ marginTop: 10 }}
165
+ >
166
+ {t('FILTER', 'Filter')}
167
+ </OText>
168
+ <SortContainer>
169
+ <OText weight='bold' mBottom={7} size={16}>
170
+ {t('SORT', 'Sort')}
171
+ </OText>
172
+ {sortItems?.filter(item => !(orderState?.options?.type === 1 && item?.value === 'pickup_time') && !(orderState?.options?.type === 2 && item?.value === 'delivery_time'))?.map(item => (
173
+ <TouchableOpacity
174
+ key={item?.value}
175
+ onPress={() => handleChangeFilters('orderBy', item?.value)}
176
+ style={{ marginBottom: 7 }}
177
+ >
178
+ <OText
179
+ weight={filters?.orderBy?.includes(item?.value) ? 'bold' : '500'}
180
+ mBottom={filters?.orderBy?.includes(item?.value) ? 5 : 0}
181
+ >
182
+ {item?.text} {(filters?.orderBy?.includes(item?.value)) && <>{filters?.orderBy?.includes('-') ? <AntDesignIcon name='caretup' /> : <AntDesignIcon name='caretdown' />}</>}
183
+ </OText>
184
+ </TouchableOpacity>
185
+ ))}
186
+ </SortContainer>
187
+ <BrandContainer>
188
+ <OText
189
+ size={16}
190
+ weight='bold'
191
+ lineHeight={24}
192
+ style={{ marginBottom: 10 }}
193
+ >
194
+ {t('BRANDS', 'Brands')}
195
+ </OText>
196
+ {!brandList?.loading && !brandList?.error && brandList?.brands?.length > 0 && (
197
+ <ScrollView
198
+ style={{ maxHeight: 300, marginBottom: 10 }}
199
+ showsVerticalScrollIndicator={true}
200
+ nestedScrollEnabled={true}
201
+ >
202
+ {brandList?.brands.map((brand: any, i: number) => brand?.enabled && (
203
+ <BrandItem
204
+ key={i}
205
+ onPress={() => handleChangeBrandFilter(brand?.id)}
206
+ >
207
+ <OText
208
+ size={14}
209
+ weight={'400'}
210
+ lineHeight={24}
211
+ >
212
+ {brand?.name}
213
+ </OText>
214
+ {filters?.franchise_ids?.includes(brand?.id) && (
215
+ <AntDesignIcon
216
+ name='check'
217
+ color={theme.colors.success500}
218
+ size={16}
219
+ />
220
+ )}
221
+ </BrandItem>
222
+ ))}
223
+ </ScrollView>
224
+ )}
225
+ {!brandList?.loading && ((brandList?.brands?.filter((brand: any) => brand?.enabled))?.length === 0) && (
226
+ <OText size={14} weight='400'>{t('NO_RESULTS_FOUND', 'Sorry, no results found')}</OText>
227
+ )}
228
+ </BrandContainer>
229
+ <PriceFilterWrapper>
230
+ <OText
231
+ size={16}
232
+ weight='bold'
233
+ lineHeight={24}
234
+ style={{ marginBottom: 5 }}
235
+ >
236
+ {t('PRICE_RANGE', 'Price range')}
237
+ </OText>
238
+ <View style={styles.priceContainer}>
239
+ {priceList.map((price: any, i: number) => (
240
+ <OButton
241
+ key={i}
242
+ bgColor={(filters?.price_level === price?.level) ? theme.colors.primary : theme.colors.backgroundGray200}
243
+ onClick={() => handleChangePriceRange(price?.level)}
244
+ text={`${price.content} ${(filters?.price_level === price?.level) ? ' X' : ''}`}
245
+ style={styles.priceItem}
246
+ textStyle={{ fontSize: 10, color: (filters?.price_level === price?.level) ? theme.colors.backgroundLight : theme.colors.textNormal }}
247
+ />
248
+ ))}
249
+ </View>
250
+ </PriceFilterWrapper>
251
+ {orderState?.options?.type === 1 && (
252
+ <MaxSectionItem
253
+ filters={filters}
254
+ title={t('MAX_DELIVERY_FEE', 'Max delivery fee')}
255
+ options={maxDeliveryFeeOptions}
256
+ filter='max_delivery_price'
257
+ handleChangeFilters={handleChangeFilters}
258
+ />
259
+ )}
260
+ {[1, 2].includes(orderState?.options?.type) && (
261
+ <MaxSectionItem
262
+ filters={filters}
263
+ title={orderState?.options?.type === 1 ? t('MAX_DELIVERY_TIME', 'Max delivery time') : t('MAX_PICKUP_TIME', 'Max pickup time')}
264
+ options={maxTimeOptions}
265
+ filter='max_eta'
266
+ handleChangeFilters={handleChangeFilters}
267
+ />
268
+ )}
269
+ <MaxSectionItem
270
+ filters={filters}
271
+ title={t('MAX_DISTANCE', 'Max distance')}
272
+ options={maxDistanceOptions}
273
+ filter='max_distance'
274
+ handleChangeFilters={handleChangeFilters}
275
+ />
276
+ {businessTypes?.length > 0 && (
277
+ <TagsContainer>
278
+ <OText weight='bold' mBottom={7} size={16}>{t('BUSINESS_CATEGORIES', 'Business categories')}</OText>
279
+ <View style={styles.businessTypesContainer}>
280
+ {businessTypes.map((type: any, i: number) => type.enabled && (
281
+ <OButton
282
+ key={type?.id}
283
+ bgColor={(filters?.business_types?.includes(type?.id) || (type?.id === null && filters?.business_types?.length === 0)) ? theme.colors.primary : theme.colors.backgroundGray200}
284
+ onClick={() => handleChangeActiveBusinessType(type)}
285
+ text={`${t(`BUSINESS_TYPE_${type.name.replace(/\s/g, '_').toUpperCase()}`, type.name)} ${filters?.business_types?.includes(type?.id) ? 'X' : ''}`}
286
+ style={styles.categoryStyle}
287
+ textStyle={{ fontSize: 10, color: (filters?.business_types?.includes(type?.id) || (type?.id === null && filters?.business_types?.length === 0)) ? '#fff' : theme.colors.textNormal }}
288
+ />
289
+ ))}
290
+ </View>
291
+ </TagsContainer>
292
+ )}
293
+ </ScrollView>
294
+ <WrapperButtons>
295
+ <View style={{ width: '50%' }}>
296
+ <OButton
297
+ text={t('APPLY', 'Apply')}
298
+ parentStyle={styles.applyButton}
299
+ textStyle={{ color: '#fff' }}
300
+ onClick={() => handleApplyFilters()}
301
+ />
302
+ </View>
303
+ <View style={{ width: '50%' }}>
304
+ <OButton
305
+ text={t('CLEAR_FILTERS', 'Clear')}
306
+ bgColor={theme.colors.white}
307
+ borderColor={theme.colors.primary}
308
+ parentStyle={styles.applyButton}
309
+ textStyle={{ color: theme.colors.primary }}
310
+ onClick={() => clearFilters()}
311
+ />
312
+ </View>
313
+ </WrapperButtons>
314
+ </OModal>
315
+ </>
316
+ )
317
+ }
@@ -0,0 +1,96 @@
1
+ import React, { useEffect, useState } from 'react'
2
+ import { useLanguage } from 'ordering-components/native'
3
+ import { View, Platform, StyleSheet, Dimensions } from 'react-native'
4
+ import { HeaderTitle, OButton, OText } from '../shared'
5
+ import { SearchBar } from '../SearchBar';
6
+ import { NotFoundSource } from '../NotFoundSource'
7
+ import AntDesignIcon from 'react-native-vector-icons/AntDesign'
8
+ import {
9
+ SearchWrapper,
10
+ BContainer,
11
+ } from './styles'
12
+ import { useTheme } from 'styled-components/native'
13
+
14
+ export const BusinessSearchHeader = (props: any) => {
15
+ const {
16
+ businessesSearchList,
17
+ onChangeTermValue,
18
+ termValue,
19
+ handleOpenfilters
20
+ } = props
21
+ const theme = useTheme()
22
+ const [, t] = useLanguage()
23
+ const noResults = (!businessesSearchList.loading && !businessesSearchList.lengthError && businessesSearchList?.businesses?.length === 0)
24
+ const isChewLayout = theme?.header?.components?.layout?.type?.toLowerCase() === 'chew'
25
+ const hideBrowse = theme?.bar_menu?.components?.browse?.hidden
26
+
27
+ const styles = StyleSheet.create({
28
+ searchInput: {
29
+ fontSize: 12,
30
+ height: 44
31
+ }
32
+ });
33
+
34
+ return (
35
+ <>
36
+ <View style={{
37
+ width: '100%',
38
+ display: 'flex',
39
+ flexDirection: 'row',
40
+ alignItems: 'center',
41
+ }}>
42
+ {hideBrowse && !isChewLayout && (
43
+ <OButton
44
+ imgLeftStyle={{ width: 18 }}
45
+ imgRightSrc={null}
46
+ style={{
47
+ borderWidth: 0,
48
+ width: 26,
49
+ height: 26,
50
+ backgroundColor: '#FFF',
51
+ borderColor: '#FFF',
52
+ shadowColor: '#FFF',
53
+ paddingLeft: 0,
54
+ paddingRight: 0,
55
+ marginTop: 50,
56
+ }}
57
+ onClick={() => props.navigation.goBack()}
58
+ icon={AntDesignIcon}
59
+ iconProps={{
60
+ name: 'arrowleft',
61
+ size: 26
62
+ }}
63
+ />
64
+ )}
65
+ <HeaderTitle ph={20} text={t('SEARCH', 'Search')} />
66
+ <AntDesignIcon name='filter' size={18} style={{ marginLeft: 'auto', marginTop: Platform.OS === 'ios' ? 35 : 55, paddingHorizontal: 20 }} onPress={() => handleOpenfilters()} />
67
+ </View>
68
+ <BContainer
69
+ style={{ paddingHorizontal: 20 }}
70
+ >
71
+ <SearchWrapper>
72
+ <SearchBar
73
+ lazyLoad
74
+ {...(isChewLayout && { height: 55 })}
75
+ inputStyle={{ ...styles.searchInput }}
76
+ placeholder={t('SEARCH_BUSINESSES', 'Search Businesses')}
77
+ onSearch={(val: string) => onChangeTermValue(val)}
78
+ value={termValue}
79
+ />
80
+ </SearchWrapper>
81
+ <OText size={12} lineHeight={20} color={theme.colors.textThird} mLeft={5}>
82
+ {t('TYPE_AT_LEAST_2_CHARACTERS', 'Type at least 2 characters')}
83
+ </OText>
84
+ {
85
+ noResults && (
86
+ <View>
87
+ <NotFoundSource
88
+ content={t('NOT_FOUND_BUSINESSES', 'No businesses to delivery / pick up at this address, please change filters or change address.')}
89
+ />
90
+ </View>
91
+ )
92
+ }
93
+ </BContainer>
94
+ </>
95
+ )
96
+ }
@@ -1,36 +1,25 @@
1
1
  import React, { useEffect, useState } from 'react'
2
2
  import { useLanguage, BusinessSearchList, useOrder, useUtils, useEvent, showToast, ToastType } from 'ordering-components/native'
3
- import { ScrollView, StyleSheet, TouchableOpacity, View, Dimensions, Platform } from 'react-native'
4
- import { useSafeAreaInsets } from 'react-native-safe-area-context'
3
+ import { ScrollView, StyleSheet, Dimensions, FlatList } from 'react-native'
5
4
  import { useTheme } from 'styled-components/native'
6
- import { HeaderTitle, OButton, OModal, OText } from '../shared'
7
- import { SearchBar } from '../SearchBar';
8
- import { NotFoundSource } from '../NotFoundSource'
5
+ import { OButton, OText } from '../shared'
6
+
9
7
  import { SingleProductCard } from '../SingleProductCard'
10
- import AntDesignIcon from 'react-native-vector-icons/AntDesign'
11
8
  import {
12
- SearchWrapper,
13
- ProductsList,
14
9
  SingleBusinessSearch,
15
10
  BusinessInfo,
16
11
  BusinessInfoItem,
17
12
  Metadata,
18
13
  SingleBusinessContainer,
19
- TagsContainer,
20
- SortContainer,
21
- BrandContainer,
22
- BrandItem,
23
- PriceFilterWrapper,
24
14
  BContainer,
25
- WrapperButtons
26
15
  } from './styles'
27
16
  import FastImage from 'react-native-fast-image'
28
17
  import { convertHoursToMinutes } from '../../utils'
29
- import { Fade, Placeholder, PlaceholderLine } from 'rn-placeholder'
30
18
  import { BusinessSearchParams } from '../../types'
31
19
  import { useIsFocused } from '@react-navigation/native';
32
- import { MaxSectionItem } from './MaxSectionItem'
33
- import { IOScrollView } from 'react-native-intersection-observer'
20
+
21
+ import { BusinessSearchHeader } from './BusinessSearchHeader'
22
+ import { BusinessSearchFooter } from './BusinessSearchFooter'
34
23
 
35
24
  const PIXELS_TO_SCROLL = 1000
36
25
 
@@ -51,94 +40,20 @@ export const BusinessListingSearchUI = (props: BusinessSearchParams) => {
51
40
  handleUpdateProducts
52
41
  } = props
53
42
 
54
- const screenHeight = Dimensions.get('window').height;
55
43
  const screenWidth = Dimensions.get('window').width;
56
44
  const theme = useTheme()
57
45
  const [orderState] = useOrder()
58
46
  const [events] = useEvent()
59
- const { top } = useSafeAreaInsets();
60
47
  const [, t] = useLanguage()
61
48
  const [{ parsePrice, parseDistance, optimizeImage }] = useUtils();
62
49
 
63
50
  const [openFilters, setOpenFilters] = useState(false)
64
- const noResults = (!businessesSearchList.loading && !businessesSearchList.lengthError && businessesSearchList?.businesses?.length === 0)
65
- const maxDeliveryFeeOptions = [15, 25, 35, 'default']
66
- // const maxProductPriceOptions = [5, 10, 15, 'default']
67
- const maxDistanceOptions = [1000, 2000, 5000, 'default']
68
- const maxTimeOptions = [5, 15, 30, 'default']
69
- const sortItems = [
70
- { text: t('PICKED_FOR_YOU', 'Picked for you (default)'), value: 'distance' },
71
- { text: t('DELIVERY_TIME', 'Delivery time'), value: 'delivery_time' },
72
- { text: t('PICKUP_TIME', 'Pickup time'), value: 'pickup_time' }
73
- ]
74
-
75
- const isChewLayout = theme?.header?.components?.layout?.type?.toLowerCase() === 'chew'
76
- const hideBrowse = theme?.bar_menu?.components?.browse?.hidden
77
-
78
- const priceList = [
79
- { level: '1', content: '$' },
80
- { level: '2', content: '$$' },
81
- { level: '3', content: '$$$' },
82
- { level: '4', content: '$$$$' },
83
- { level: '5', content: '$$$$$' }
84
- ]
85
51
 
86
52
  const isFocused = useIsFocused();
87
53
 
88
54
  const styles = StyleSheet.create({
89
- container: {
90
- paddingHorizontal: 40,
91
- width: '100%'
92
- },
93
- filterContainer: {
94
- maxHeight: screenHeight - 150,
95
- paddingHorizontal: 20,
96
- width: '100%'
97
- },
98
- searchInput: {
99
- fontSize: 12,
100
- height: 44
101
- },
102
55
  productsContainer: {
103
56
  marginTop: 20
104
- },
105
- businessTypesContainer: {
106
- width: '100%',
107
- flexDirection: 'row',
108
- flexWrap: 'wrap',
109
- justifyContent: 'center'
110
- },
111
- priceContainer: {
112
- width: '100%',
113
- flexDirection: 'row',
114
- flexWrap: 'wrap',
115
- justifyContent: 'space-between'
116
- },
117
- categoryStyle: {
118
- marginRight: 10,
119
- marginTop: 10,
120
- borderRadius: 50,
121
- paddingHorizontal: 10,
122
- paddingVertical: 4,
123
- paddingLeft: 0,
124
- paddingRight: 0,
125
- height: 28,
126
- borderWidth: 0
127
- },
128
- priceItem: {
129
- marginRight: 10,
130
- marginTop: 10,
131
- borderRadius: 50,
132
- paddingVertical: 4,
133
- paddingLeft: 5,
134
- paddingRight: 5,
135
- height: 27,
136
- borderWidth: 0
137
- },
138
- applyButton: {
139
- paddingHorizontal: 10,
140
- width: '100%',
141
- marginTop: 20
142
57
  }
143
58
  });
144
59
 
@@ -250,70 +165,37 @@ export const BusinessListingSearchUI = (props: BusinessSearchParams) => {
250
165
  }, [isFocused])
251
166
 
252
167
  return (
253
- <IOScrollView
254
- onScroll={(e: any) => handleScroll(e)}
255
- showsVerticalScrollIndicator={false}
256
- >
257
- <View style={{
258
- width: '100%',
259
- display: 'flex',
260
- flexDirection: 'row',
261
- alignItems: 'center',
262
- }}>
263
- {hideBrowse && !isChewLayout && (
264
- <OButton
265
- imgLeftStyle={{ width: 18 }}
266
- imgRightSrc={null}
267
- style={{
268
- borderWidth: 0,
269
- width: 26,
270
- height: 26,
271
- backgroundColor: '#FFF',
272
- borderColor: '#FFF',
273
- shadowColor: '#FFF',
274
- paddingLeft: 0,
275
- paddingRight: 0,
276
- marginTop: 50,
277
- }}
278
- onClick={() => props.navigation.goBack()}
279
- icon={AntDesignIcon}
280
- iconProps={{
281
- name: 'arrowleft',
282
- size: 26
283
- }}
284
- />
285
- )}
286
- <HeaderTitle ph={20} text={t('SEARCH', 'Search')} />
287
- <AntDesignIcon name='filter' size={18} style={{ marginLeft: 'auto', marginTop: Platform.OS === 'ios' ? 35 : 55, paddingHorizontal: 20 }} onPress={() => handleOpenfilters()} />
288
- </View>
289
- <BContainer
290
- style={{ paddingHorizontal: 20 }}
291
- >
292
- <SearchWrapper>
293
- <SearchBar
294
- lazyLoad
295
- {...(isChewLayout && { height: 55 })}
296
- inputStyle={{ ...styles.searchInput }}
297
- placeholder={t('SEARCH_BUSINESSES', 'Search Businesses')}
298
- onSearch={(val: string) => onChangeTermValue(val)}
299
- value={termValue}
300
- />
301
- </SearchWrapper>
302
- <OText size={12} lineHeight={20} color={theme.colors.textThird} mLeft={5}>
303
- {t('TYPE_AT_LEAST_2_CHARACTERS', 'Type at least 2 characters')}
304
- </OText>
305
- {
306
- noResults && (
307
- <View>
308
- <NotFoundSource
309
- content={t('NOT_FOUND_BUSINESSES', 'No businesses to delivery / pick up at this address, please change filters or change address.')}
310
- />
311
- </View>
312
- )
313
- }
314
- <ProductsList>
315
- {businessesSearchList.businesses?.filter((business: any) => business?.categories?.length > 0).map((business: any) => (
316
- <SingleBusinessSearch key={`card-${business?.id}`}>
168
+ <>
169
+ <FlatList
170
+ data={businessesSearchList.businesses?.filter((business: any) => business?.categories?.length > 0)}
171
+ ListFooterComponent={<BusinessSearchFooter
172
+ businessesSearchList={businessesSearchList}
173
+ handleCloseFilters={handleCloseFilters}
174
+ handleChangeFilters={handleChangeFilters}
175
+ brandList={brandList}
176
+ filters={filters}
177
+ handleChangeBrandFilter={handleChangeBrandFilter}
178
+ handleChangePriceRange={handleChangePriceRange}
179
+ businessTypes={businessTypes}
180
+ handleApplyFilters={handleApplyFilters}
181
+ clearFilters={clearFilters}
182
+ handleChangeActiveBusinessType={handleChangeActiveBusinessType}
183
+ openFilters={openFilters}
184
+ />}
185
+ ListHeaderComponent={<BusinessSearchHeader
186
+ businessesSearchList={businessesSearchList}
187
+ onChangeTermValue={onChangeTermValue}
188
+ termValue={termValue}
189
+ handleOpenfilters={handleOpenfilters}
190
+ />}
191
+ onScroll={(e: any) => handleScroll(e)}
192
+ showsVerticalScrollIndicator={false}
193
+ keyExtractor={(business: any, index: number) => `card-${business?.id}-${index}`}
194
+ renderItem={({ item: business }: any) => (
195
+ <BContainer
196
+ style={{ paddingHorizontal: 20, paddingTop: 0, paddingBottom: 0 }}
197
+ >
198
+ <SingleBusinessSearch>
317
199
  <SingleBusinessContainer>
318
200
  <BusinessInfo>
319
201
  {(business?.logo || theme.images?.dummies?.businessLogo) && (
@@ -379,210 +261,18 @@ export const BusinessListingSearchUI = (props: BusinessSearchParams) => {
379
261
  }}
380
262
  />
381
263
  )))}
382
-
383
264
  </ScrollView>
384
265
  </SingleBusinessSearch>
385
- ))}
386
- {businessesSearchList?.loading && (
387
- <>
388
- {[...Array(3).keys()].map(
389
- (item, i) => (
390
- <View key={`skeleton:${i}`} style={{ width: '100%', marginTop: 20 }}>
391
- <Placeholder key={i} style={{ paddingHorizontal: 5 }} Animation={Fade}>
392
- <View style={{ flexDirection: 'row' }}>
393
- <PlaceholderLine
394
- width={24}
395
- height={70}
396
- style={{ marginRight: 10, marginBottom: 10 }}
397
- />
398
- <Placeholder style={{ paddingVertical: 10 }}>
399
- <PlaceholderLine width={20} style={{ marginBottom: 25 }} />
400
- <PlaceholderLine width={60} />
401
- </Placeholder>
402
- </View>
403
- </Placeholder>
404
- <Placeholder style={{ paddingHorizontal: 5, bottom: 10 }} Animation={Fade}>
405
- <View style={{ flexDirection: 'row-reverse', overflow: 'hidden' }}>
406
- <PlaceholderLine
407
- width={24}
408
- height={70}
409
- style={{ marginRight: 10, marginBottom: 5 }}
410
- />
411
- <Placeholder style={{ paddingVertical: 10 }}>
412
- <PlaceholderLine width={60} height={10} />
413
- <PlaceholderLine width={50} height={10} />
414
- <PlaceholderLine width={70} height={10} />
415
- </Placeholder>
416
- </View>
417
- </Placeholder>
418
- </View>
419
- ),
420
- )}
421
- </>
422
- )}
423
- </ProductsList>
424
- <OModal
425
- open={openFilters}
426
- onCancel={() => handleCloseFilters()}
427
- onClose={() => handleCloseFilters()}
428
- >
429
- <ScrollView style={styles.filterContainer}>
430
- <OText
431
- size={20}
432
- mBottom={15}
433
- style={{ marginTop: 10 }}
434
- >
435
- {t('FILTER', 'Filter')}
436
- </OText>
437
- <SortContainer>
438
- <OText weight='bold' mBottom={7} size={16}>
439
- {t('SORT', 'Sort')}
440
- </OText>
441
- {sortItems?.filter(item => !(orderState?.options?.type === 1 && item?.value === 'pickup_time') && !(orderState?.options?.type === 2 && item?.value === 'delivery_time'))?.map(item => (
442
- <TouchableOpacity
443
- key={item?.value}
444
- onPress={() => handleChangeFilters('orderBy', item?.value)}
445
- style={{ marginBottom: 7 }}
446
- >
447
- <OText
448
- weight={filters?.orderBy?.includes(item?.value) ? 'bold' : '500'}
449
- mBottom={filters?.orderBy?.includes(item?.value) ? 5 : 0}
450
- >
451
- {item?.text} {(filters?.orderBy?.includes(item?.value)) && <>{filters?.orderBy?.includes('-') ? <AntDesignIcon name='caretup' /> : <AntDesignIcon name='caretdown' />}</>}
452
- </OText>
453
- </TouchableOpacity>
454
- ))}
455
- </SortContainer>
456
- <BrandContainer>
457
- <OText
458
- size={16}
459
- weight='bold'
460
- lineHeight={24}
461
- style={{ marginBottom: 10 }}
462
- >
463
- {t('BRANDS', 'Brands')}
464
- </OText>
465
- {!brandList?.loading && !brandList?.error && brandList?.brands?.length > 0 && (
466
- <ScrollView
467
- style={{ maxHeight: 300, marginBottom: 10 }}
468
- showsVerticalScrollIndicator={true}
469
- nestedScrollEnabled={true}
470
- >
471
- {brandList?.brands.map((brand: any, i: number) => brand?.enabled && (
472
- <BrandItem
473
- key={i}
474
- onPress={() => handleChangeBrandFilter(brand?.id)}
475
- >
476
- <OText
477
- size={14}
478
- weight={'400'}
479
- lineHeight={24}
480
- >
481
- {brand?.name}
482
- </OText>
483
- {filters?.franchise_ids?.includes(brand?.id) && (
484
- <AntDesignIcon
485
- name='check'
486
- color={theme.colors.success500}
487
- size={16}
488
- />
489
- )}
490
- </BrandItem>
491
- ))}
492
- </ScrollView>
493
- )}
494
- {!brandList?.loading && ((brandList?.brands?.filter((brand: any) => brand?.enabled))?.length === 0) && (
495
- <OText size={14} weight='400'>{t('NO_RESULTS_FOUND', 'Sorry, no results found')}</OText>
496
- )}
497
- </BrandContainer>
498
- <PriceFilterWrapper>
499
- <OText
500
- size={16}
501
- weight='bold'
502
- lineHeight={24}
503
- style={{ marginBottom: 5 }}
504
- >
505
- {t('PRICE_RANGE', 'Price range')}
506
- </OText>
507
- <View style={styles.priceContainer}>
508
- {priceList.map((price: any, i: number) => (
509
- <OButton
510
- key={i}
511
- bgColor={(filters?.price_level === price?.level) ? theme.colors.primary : theme.colors.backgroundGray200}
512
- onClick={() => handleChangePriceRange(price?.level)}
513
- text={`${price.content} ${(filters?.price_level === price?.level) ? ' X' : ''}`}
514
- style={styles.priceItem}
515
- textStyle={{ fontSize: 10, color: (filters?.price_level === price?.level) ? theme.colors.backgroundLight : theme.colors.textNormal }}
516
- />
517
- ))}
518
- </View>
519
- </PriceFilterWrapper>
520
- {orderState?.options?.type === 1 && (
521
- <MaxSectionItem
522
- filters={filters}
523
- title={t('MAX_DELIVERY_FEE', 'Max delivery fee')}
524
- options={maxDeliveryFeeOptions}
525
- filter='max_delivery_price'
526
- handleChangeFilters={handleChangeFilters}
527
- />
528
- )}
529
- {[1, 2].includes(orderState?.options?.type) && (
530
- <MaxSectionItem
531
- filters={filters}
532
- title={orderState?.options?.type === 1 ? t('MAX_DELIVERY_TIME', 'Max delivery time') : t('MAX_PICKUP_TIME', 'Max pickup time')}
533
- options={maxTimeOptions}
534
- filter='max_eta'
535
- handleChangeFilters={handleChangeFilters}
536
- />
537
- )}
538
- <MaxSectionItem
539
- filters={filters}
540
- title={t('MAX_DISTANCE', 'Max distance')}
541
- options={maxDistanceOptions}
542
- filter='max_distance'
543
- handleChangeFilters={handleChangeFilters}
544
- />
545
- {businessTypes?.length > 0 && (
546
- <TagsContainer>
547
- <OText weight='bold' mBottom={7} size={16}>{t('BUSINESS_CATEGORIES', 'Business categories')}</OText>
548
- <View style={styles.businessTypesContainer}>
549
- {businessTypes.map((type: any, i: number) => type.enabled && (
550
- <OButton
551
- key={type?.id}
552
- bgColor={(filters?.business_types?.includes(type?.id) || (type?.id === null && filters?.business_types?.length === 0)) ? theme.colors.primary : theme.colors.backgroundGray200}
553
- onClick={() => handleChangeActiveBusinessType(type)}
554
- text={`${t(`BUSINESS_TYPE_${type.name.replace(/\s/g, '_').toUpperCase()}`, type.name)} ${filters?.business_types?.includes(type?.id) ? 'X' : ''}`}
555
- style={styles.categoryStyle}
556
- textStyle={{ fontSize: 10, color: (filters?.business_types?.includes(type?.id) || (type?.id === null && filters?.business_types?.length === 0)) ? '#fff' : theme.colors.textNormal }}
557
- />
558
- ))}
559
- </View>
560
- </TagsContainer>
561
- )}
562
- </ScrollView>
563
- <WrapperButtons>
564
- <View style={{ width: '50%' }}>
565
- <OButton
566
- text={t('APPLY', 'Apply')}
567
- parentStyle={styles.applyButton}
568
- textStyle={{ color: '#fff' }}
569
- onClick={() => handleApplyFilters()}
570
- />
571
- </View>
572
- <View style={{ width: '50%' }}>
573
- <OButton
574
- text={t('CLEAR_FILTERS', 'Clear')}
575
- bgColor={theme.colors.white}
576
- borderColor={theme.colors.primary}
577
- parentStyle={styles.applyButton}
578
- textStyle={{ color: theme.colors.primary }}
579
- onClick={() => clearFilters()}
580
- />
581
- </View>
582
- </WrapperButtons>
583
- </OModal>
584
- </BContainer>
585
- </IOScrollView>
266
+ </BContainer>
267
+ )}
268
+ />
269
+ {/* <IOScrollView
270
+ onScroll={(e: any) => handleScroll(e)}
271
+ showsVerticalScrollIndicator={false}
272
+ >
273
+
274
+ </IOScrollView> */}
275
+ </>
586
276
  )
587
277
  }
588
278
 
@@ -129,7 +129,7 @@ const WalletsUI = (props: any) => {
129
129
  flexDirection: !hideWalletsTheme ? 'column' : 'row',
130
130
  justifyContent: !hideWalletsTheme ? 'flex-start' : 'space-between',
131
131
  alignItems: !hideWalletsTheme ? 'flex-start' : 'center',
132
- marginTop: !hideWalletsTheme ? 0 : 10,
132
+ marginTop: !hideWalletsTheme ? 30 : 10,
133
133
  },
134
134
  }}>
135
135
  <NavBar
@@ -3,7 +3,7 @@ import styled from 'styled-components/native'
3
3
  export const Container = styled.View`
4
4
  padding-horizontal: 20px;
5
5
  padding-bottom: 20px;
6
- padding-top: ${(props: any) => props.pdng};
6
+ padding-top: ${(props: any) => props.pdng || 0};
7
7
  `
8
8
  export const Header = styled.View`
9
9
  flex-direction: row;
@@ -4,7 +4,9 @@ import styled, { css, useTheme } from 'styled-components/native';
4
4
  import { Platform, View } from 'react-native';
5
5
 
6
6
  const ContainerStyled = styled.ScrollView`
7
- flex: 1;
7
+ ${(props: any) => !props.disableFlex && css`
8
+ flex: 1
9
+ `}
8
10
  ${(props: any) => !props.noPadding && css`
9
11
  padding: ${Platform.OS === 'ios' ? '0px 20px' : '20px 20px'};
10
12
  `}
@@ -17,7 +19,7 @@ export const Container = (props: any) => {
17
19
  return (
18
20
  <View
19
21
  style={{
20
- flex: 1,
22
+ flex: props.disableFlex ? undefined : 1,
21
23
  paddingTop: props.pt ?? insets.top,
22
24
  backgroundColor: theme.colors.backgroundPage
23
25
  }}