ordering-ui-react-native 0.17.10-release → 0.17.11-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.17.10-release",
3
+ "version": "0.17.11-release",
4
4
  "description": "Reusable components made in react native",
5
5
  "main": "src/index.tsx",
6
6
  "author": "ordering.inc",
@@ -187,7 +187,7 @@ export const AnalyticsSegment = (props: any) => {
187
187
  segmentClient.track('Coupon Denied', {
188
188
  business_id: coupon.business_id,
189
189
  coupon: coupon.coupon,
190
- user_id: coupon.user.id,
190
+ user_id: coupon?.user_id,
191
191
  reason: typeof coupon.reason === 'string' ? t(coupon.reason) : t(coupon.reason[0])
192
192
  })
193
193
  }
@@ -1,30 +1,26 @@
1
1
  import React, { useEffect, useState } from 'react'
2
- import { useLanguage, BusinessSearchList, useOrder, useUtils, showToast, ToastType } from 'ordering-components/native'
3
- import { ScrollView, StyleSheet, TouchableOpacity, Platform, View, Dimensions } from 'react-native'
2
+ import { useLanguage, BusinessSearchList, useOrder, useUtils, useEvent, showToast, ToastType } from 'ordering-components/native'
3
+ import { ScrollView, StyleSheet, TouchableOpacity, View, Dimensions } from 'react-native'
4
4
  import { useSafeAreaInsets } from 'react-native-safe-area-context'
5
5
  import { useTheme } from 'styled-components/native'
6
- import { OButton, OModal, OText } from '../shared'
6
+ import { HeaderTitle, OButton, OModal, OText } from '../shared'
7
7
  import { SearchBar } from '../SearchBar';
8
- import { BusinessController } from '../BusinessController'
9
8
  import { NotFoundSource } from '../NotFoundSource'
10
9
  import { SingleProductCard } from '../SingleProductCard'
11
10
  import AntDesignIcon from 'react-native-vector-icons/AntDesign'
12
11
  import {
13
12
  SearchWrapper,
14
- WrapHeader,
15
13
  ProductsList,
16
14
  SingleBusinessSearch,
17
15
  BusinessInfo,
18
16
  BusinessInfoItem,
19
17
  Metadata,
20
18
  SingleBusinessContainer,
21
- LoadMoreBusinessContainer,
22
19
  TagsContainer,
23
20
  SortContainer,
24
21
  BrandContainer,
25
22
  BrandItem,
26
23
  PriceFilterWrapper,
27
- OptionTitle,
28
24
  BContainer,
29
25
  WrapperButtons
30
26
  } from './styles'
@@ -32,10 +28,12 @@ import FastImage from 'react-native-fast-image'
32
28
  import { convertHoursToMinutes } from '../../utils'
33
29
  import { Fade, Placeholder, PlaceholderLine } from 'rn-placeholder'
34
30
  import { BusinessSearchParams } from '../../types'
35
- import { MyOrders } from '../MyOrders'
36
31
  import { useIsFocused } from '@react-navigation/native';
37
32
  import { MaxSectionItem } from './MaxSectionItem'
38
- import { BusinessControllerSkeletons } from './BusinessControllerSkeletons'
33
+ import { IOScrollView } from 'react-native-intersection-observer'
34
+
35
+ const PIXELS_TO_SCROLL = 1000
36
+
39
37
  export const BusinessListingSearchUI = (props: BusinessSearchParams) => {
40
38
  const {
41
39
  navigation,
@@ -43,23 +41,20 @@ export const BusinessListingSearchUI = (props: BusinessSearchParams) => {
43
41
  onBusinessClick,
44
42
  handleChangeTermValue,
45
43
  termValue,
46
- paginationProps,
47
44
  handleSearchbusinessAndProducts,
48
45
  handleChangeFilters,
49
46
  filters,
50
47
  businessTypes,
51
48
  setFilters,
52
49
  brandList,
53
- onNavigationRedirect,
54
- handleUpdateBusinessList,
55
- handleUpdateProducts,
56
- brandId
50
+ handleUpdateProducts
57
51
  } = props
58
52
 
59
53
  const screenHeight = Dimensions.get('window').height;
60
54
  const screenWidth = Dimensions.get('window').width;
61
55
  const theme = useTheme()
62
56
  const [orderState] = useOrder()
57
+ const [events] = useEvent()
63
58
  const { top } = useSafeAreaInsets();
64
59
  const [, t] = useLanguage()
65
60
  const [{ parsePrice, parseDistance, optimizeImage }] = useUtils();
@@ -77,6 +72,7 @@ export const BusinessListingSearchUI = (props: BusinessSearchParams) => {
77
72
  ]
78
73
 
79
74
  const isChewLayout = theme?.header?.components?.layout?.type?.toLowerCase() === 'chew'
75
+ const hideBrowse = theme?.bar_menu?.components?.browse?.hidden
80
76
 
81
77
  const priceList = [
82
78
  { level: '1', content: '$' },
@@ -100,6 +96,7 @@ export const BusinessListingSearchUI = (props: BusinessSearchParams) => {
100
96
  },
101
97
  searchInput: {
102
98
  fontSize: 12,
99
+ height: 44
103
100
  },
104
101
  productsContainer: {
105
102
  marginTop: 20
@@ -217,6 +214,25 @@ export const BusinessListingSearchUI = (props: BusinessSearchParams) => {
217
214
  })
218
215
  }
219
216
 
217
+ const handleScroll = ({ nativeEvent }: any) => {
218
+ const y = nativeEvent.contentOffset.y;
219
+ const height = nativeEvent.contentSize.height;
220
+ const hasMore = !(
221
+ paginationProps.totalPages === paginationProps.currentPage
222
+ );
223
+
224
+ if (y + PIXELS_TO_SCROLL > height && !businessesSearchList.loading && hasMore && businessesSearchList?.businesses?.length > 0) {
225
+ handleSearchbusinessAndProducts();
226
+ }
227
+ };
228
+
229
+ const onChangeTermValue = (query: any) => {
230
+ handleChangeTermValue(query)
231
+ if (query) {
232
+ events.emit('products_searched', query)
233
+ }
234
+ }
235
+
220
236
  useEffect(() => {
221
237
  if (filters.business_types?.length === 0 && filters.orderBy === 'default' && Object.keys(filters)?.length === 2 && !openFilters) {
222
238
  handleSearchbusinessAndProducts(true)
@@ -233,351 +249,334 @@ export const BusinessListingSearchUI = (props: BusinessSearchParams) => {
233
249
  }, [isFocused])
234
250
 
235
251
  return (
236
- <BContainer
237
- style={{ paddingHorizontal: isChewLayout ? 20 : 40 }}
252
+ <IOScrollView
253
+ onScroll={(e: any) => handleScroll(e)}
254
+ showsVerticalScrollIndicator={false}
238
255
  >
239
- <SearchWrapper>
240
- <SearchBar
241
- lazyLoad
242
- {...(isChewLayout && { height: 55 })}
243
- inputStyle={{ ...styles.searchInput }}
244
- placeholder={t('SEARCH_BUSINESSES', 'Search Businesses')}
245
- onSearch={(val: string) => handleChangeTermValue(val)}
246
- value={termValue}
247
- iconCustomRight={<AntDesignIcon name='filter' size={16} style={{ bottom: 2 }} onPress={() => handleOpenfilters()} />}
248
- />
249
- </SearchWrapper>
250
- <OText size={12} lineHeight={20} color={theme.colors.textThird} mLeft={5}>
251
- {t('TYPE_AT_LEAST_3_CHARACTERS', 'Type at least 3 characters')}
252
- </OText>
253
- {
254
- noResults && (
255
- <View>
256
- <NotFoundSource
257
- content={t('NOT_FOUND_BUSINESSES', 'No businesses to delivery / pick up at this address, please change filters or change address.')}
258
- />
259
- </View>
260
- )
261
- }
262
- {businessesSearchList.businesses?.length > 0 && termValue?.length === 0 && (
263
- <MyOrders
264
- hideOrders
265
- businessesSearchList={businessesSearchList}
266
- onNavigationRedirect={onNavigationRedirect}
267
- BusinessControllerSkeletons={BusinessControllerSkeletons}
268
- businessPaginationProps={paginationProps}
269
- franchiseId={brandId}
270
- hideBackBtn
271
- titleStyle={{
272
- paddingHorizontal: 0,
273
- marginTop: 0,
274
- marginLeft: 0
275
- }}
276
- />
277
- )}
278
-
279
- {businessesSearchList.businesses?.length > 0 && (
280
- <OptionTitle isBusinessesSearchList={!!businessesSearchList}>
281
- <OText size={16} lineHeight={24} weight={'500'} color={theme.colors.textNormal} mBottom={10}>
282
- {t('BUSINESSES', 'Businesses')}
283
- </OText>
284
- </OptionTitle>
285
- )}
286
- <ScrollView horizontal showsHorizontalScrollIndicator={false}>
287
- {businessesSearchList.businesses?.length > 0 && businessesSearchList.businesses.map((business: any, i: number) => (
288
- <View
289
- key={business.id}
256
+ <View style={{
257
+ width: '100%',
258
+ display: 'flex',
259
+ flexDirection: 'row',
260
+ alignItems: 'center',
261
+ paddingHorizontal: hideBrowse && !isChewLayout ? 40 : 20,
262
+ }}>
263
+ {hideBrowse && !isChewLayout && (
264
+ <OButton
265
+ imgLeftStyle={{ width: 18 }}
266
+ imgRightSrc={null}
290
267
  style={{
291
- width: screenWidth - 120,
292
- marginRight: (businessesSearchList.loading || i !== businessesSearchList.businesses?.length - 1) ? 20 : 0
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,
293
277
  }}
294
- >
295
- <BusinessController
296
- business={business}
297
- isBusinessOpen={business.open}
298
- enableIntersection={false}
299
- handleCustomClick={() => onBusinessClick(business)}
300
- handleUpdateBusinessList={handleUpdateBusinessList}
301
- orderType={orderState?.options?.type}
302
- />
303
- </View>
304
- ))}
305
- {!businessesSearchList.loading && paginationProps?.totalPages && paginationProps?.currentPage < paginationProps?.totalPages && (
306
- <LoadMoreBusinessContainer>
307
- <OButton
308
- bgColor='transparent'
309
- borderColor={theme.colors.primary}
310
- onClick={() => handleSearchbusinessAndProducts()}
311
- text={t('LOAD_MORE_BUSINESS', 'Load more business')}
312
- textStyle={{ color: theme.colors.primary }}
313
- />
314
- </LoadMoreBusinessContainer>
315
- )}
316
- {businessesSearchList.loading && (
317
- <BusinessControllerSkeletons paginationProps={paginationProps} />
278
+ onClick={() => props.navigation.goBack()}
279
+ icon={AntDesignIcon}
280
+ iconProps={{
281
+ name: 'arrowleft',
282
+ size: 26
283
+ }}
284
+ />
318
285
  )}
319
- </ScrollView>
320
- <ProductsList>
321
- {businessesSearchList.businesses?.filter((business: any) => business?.categories?.length > 0).map((business: any) => (
322
- <SingleBusinessSearch key={`card-${business?.id}`}>
323
- <SingleBusinessContainer>
324
- <BusinessInfo>
325
- {(business?.logo || theme.images?.dummies?.businessLogo) && (
326
- <FastImage
327
- style={{ height: 48, width: 48 }}
328
- source={{
329
- uri: optimizeImage(business?.logo, 'h_120,c_limit'),
330
- priority: FastImage.priority.normal,
331
- }}
332
- resizeMode={FastImage.resizeMode.cover}
333
- />
334
- )}
335
- </BusinessInfo>
336
- <BusinessInfoItem>
337
- <OText size={12}>{business?.name}</OText>
338
- <Metadata>
339
- {orderState?.options?.type === 1 && (
340
- <>
341
- <OText size={10}>{t('DELIVERY_FEE', 'Delivery fee')}{' '}</OText>
342
- <OText size={10} mRight={3}>
343
- {business && parsePrice(business?.delivery_price)}
344
- </OText>
345
- </>
346
- )}
347
- <OText size={10} mRight={3}>
348
- {convertHoursToMinutes(orderState?.options?.type === 1 ? business?.delivery_time : business?.pickup_time)}
349
- </OText>
350
- <OText size={10}>
351
- {parseDistance(business?.distance)}
352
- </OText>
353
- </Metadata>
354
- </BusinessInfoItem>
355
- <OButton
356
- onClick={() => onBusinessClick(business)}
357
- textStyle={{ color: theme.colors.primary, fontSize: 10 }}
358
- text={t('GO_TO_STORE', 'Go to store')}
359
- bgColor='#F5F9FF'
360
- borderColor='#fff'
361
- style={{ borderRadius: 50, paddingLeft: 5, paddingRight: 5, height: 20 }}
286
+ <HeaderTitle ph={20} text={t('SEARCH', 'Search')} />
287
+ <AntDesignIcon name='filter' size={18} style={{ marginLeft: 'auto', marginTop: 55, paddingHorizontal: 20 }} onPress={() => handleOpenfilters()} />
288
+ </View>
289
+ <BContainer
290
+ style={{ paddingHorizontal: isChewLayout ? 20 : 40 }}
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.')}
362
310
  />
363
- </SingleBusinessContainer>
364
- <ScrollView horizontal style={styles.productsContainer} contentContainerStyle={{ flexGrow: 1 }}>
365
- {business?.categories?.map((category: any) => category?.products?.map((product: any, i: number) => (
366
- <SingleProductCard
367
- key={product?.id}
368
- isSoldOut={(product.inventoried && !product.quantity)}
369
- product={product}
370
- enableIntersection={false}
371
- businessId={business?.id}
372
- onProductClick={(product: any) => onProductClick(business, category?.id, product?.id, product)}
373
- productAddedToCartLength={0}
374
- handleUpdateProducts={(productId: number, changes: any) => handleUpdateProducts(productId, category?.id, business?.id, changes)}
375
- style={{ width: screenWidth - 80, maxWidth: screenWidth - 80, marginRight: 20 }}
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}`}>
317
+ <SingleBusinessContainer>
318
+ <BusinessInfo>
319
+ {(business?.logo || theme.images?.dummies?.businessLogo) && (
320
+ <FastImage
321
+ style={{ height: 48, width: 48 }}
322
+ source={{
323
+ uri: optimizeImage(business?.logo, 'h_120,c_limit'),
324
+ priority: FastImage.priority.normal,
325
+ }}
326
+ resizeMode={FastImage.resizeMode.cover}
327
+ />
328
+ )}
329
+ </BusinessInfo>
330
+ <BusinessInfoItem>
331
+ <OText size={12}>{business?.name}</OText>
332
+ <Metadata>
333
+ {orderState?.options?.type === 1 && (
334
+ <>
335
+ <OText size={10}>{t('DELIVERY_FEE', 'Delivery fee')}{' '}</OText>
336
+ <OText size={10} mRight={3}>
337
+ {business && parsePrice(business?.delivery_price)}
338
+ </OText>
339
+ </>
340
+ )}
341
+ <OText size={10} mRight={3}>
342
+ {convertHoursToMinutes(orderState?.options?.type === 1 ? business?.delivery_time : business?.pickup_time)}
343
+ </OText>
344
+ <OText size={10}>
345
+ {parseDistance(business?.distance)}
346
+ </OText>
347
+ </Metadata>
348
+ </BusinessInfoItem>
349
+ <OButton
350
+ onClick={() => onBusinessClick(business)}
351
+ textStyle={{ color: theme.colors.primary, fontSize: 10 }}
352
+ text={t('GO_TO_STORE', 'Go to store')}
353
+ bgColor='#F5F9FF'
354
+ borderColor='#fff'
355
+ style={{ borderRadius: 50, paddingLeft: 5, paddingRight: 5, height: 20 }}
376
356
  />
377
- )))}
357
+ </SingleBusinessContainer>
358
+ <ScrollView horizontal style={styles.productsContainer} contentContainerStyle={{ flexGrow: 1 }}>
359
+ {business?.categories?.map((category: any) => category?.products?.map((product: any, i: number) => (
360
+ <SingleProductCard
361
+ key={product?.id}
362
+ isSoldOut={(product.inventoried && !product.quantity)}
363
+ product={product}
364
+ enableIntersection={false}
365
+ businessId={business?.id}
366
+ onProductClick={(product: any) => onProductClick(business, category?.id, product?.id, product)}
367
+ productAddedToCartLength={0}
368
+ handleUpdateProducts={(productId: number, changes: any) => handleUpdateProducts(productId, category?.id, business?.id, changes)}
369
+ style={{
370
+ width: screenWidth - (category?.products?.length > 1 ? 120 : 80),
371
+ maxWidth: screenWidth - (category?.products?.length > 1 ? 120 : 80),
372
+ marginRight: 20
373
+ }}
374
+ />
375
+ )))}
378
376
 
379
- </ScrollView>
380
- </SingleBusinessSearch>
381
- ))}
382
- {businessesSearchList?.loading && (
383
- <>
384
- {[...Array(3).keys()].map(
385
- (item, i) => (
386
- <View key={`skeleton:${i}`} style={{ width: '100%', marginTop: 20 }}>
387
- <Placeholder key={i} style={{ paddingHorizontal: 5 }} Animation={Fade}>
388
- <View style={{ flexDirection: 'row' }}>
389
- <PlaceholderLine
390
- width={24}
391
- height={70}
392
- style={{ marginRight: 10, marginBottom: 10 }}
393
- />
394
- <Placeholder style={{ paddingVertical: 10 }}>
395
- <PlaceholderLine width={20} style={{ marginBottom: 25 }} />
396
- <PlaceholderLine width={60} />
397
- </Placeholder>
398
- </View>
399
- </Placeholder>
400
- <Placeholder style={{ paddingHorizontal: 5, bottom: 10 }} Animation={Fade}>
401
- <View style={{ flexDirection: 'row-reverse', overflow: 'hidden' }}>
402
- <PlaceholderLine
403
- width={24}
404
- height={70}
405
- style={{ marginRight: 10, marginBottom: 5 }}
406
- />
407
- <Placeholder style={{ paddingVertical: 10 }}>
408
- <PlaceholderLine width={60} height={10} />
409
- <PlaceholderLine width={50} height={10} />
410
- <PlaceholderLine width={70} height={10} />
411
- </Placeholder>
412
- </View>
413
- </Placeholder>
414
- </View>
415
- ),
416
- )}
417
- </>
418
- )}
419
- </ProductsList>
420
- <OModal
421
- open={openFilters}
422
- onCancel={() => handleCloseFilters()}
423
- onClose={() => handleCloseFilters()}
424
- >
425
- <ScrollView style={styles.filterContainer}>
426
- <OText
427
- size={20}
428
- mBottom={15}
429
- style={{ marginTop: 10 }}
430
- >
431
- {t('FILTER', 'Filter')}
432
- </OText>
433
- <SortContainer>
434
- <OText weight='bold' mBottom={7} size={16}>
435
- {t('SORT', 'Sort')}
436
- </OText>
437
- {sortItems?.filter(item => !(orderState?.options?.type === 1 && item?.value === 'pickup_time') && !(orderState?.options?.type === 2 && item?.value === 'delivery_time'))?.map(item => (
438
- <TouchableOpacity
439
- key={item?.value}
440
- onPress={() => handleChangeFilters('orderBy', item?.value)}
441
- style={{ marginBottom: 7 }}
442
- >
443
- <OText
444
- weight={filters?.orderBy?.includes(item?.value) ? 'bold' : '500'}
445
- mBottom={filters?.orderBy?.includes(item?.value) ? 5 : 0}
446
- >
447
- {item?.text} {(filters?.orderBy?.includes(item?.value)) && <>{filters?.orderBy?.includes('-') ? <AntDesignIcon name='caretup' /> : <AntDesignIcon name='caretdown' />}</>}
448
- </OText>
449
- </TouchableOpacity>
450
- ))}
451
- </SortContainer>
452
- <BrandContainer>
377
+ </ScrollView>
378
+ </SingleBusinessSearch>
379
+ ))}
380
+ {businessesSearchList?.loading && (
381
+ <>
382
+ {[...Array(3).keys()].map(
383
+ (item, i) => (
384
+ <View key={`skeleton:${i}`} style={{ width: '100%', marginTop: 20 }}>
385
+ <Placeholder key={i} style={{ paddingHorizontal: 5 }} Animation={Fade}>
386
+ <View style={{ flexDirection: 'row' }}>
387
+ <PlaceholderLine
388
+ width={24}
389
+ height={70}
390
+ style={{ marginRight: 10, marginBottom: 10 }}
391
+ />
392
+ <Placeholder style={{ paddingVertical: 10 }}>
393
+ <PlaceholderLine width={20} style={{ marginBottom: 25 }} />
394
+ <PlaceholderLine width={60} />
395
+ </Placeholder>
396
+ </View>
397
+ </Placeholder>
398
+ <Placeholder style={{ paddingHorizontal: 5, bottom: 10 }} Animation={Fade}>
399
+ <View style={{ flexDirection: 'row-reverse', overflow: 'hidden' }}>
400
+ <PlaceholderLine
401
+ width={24}
402
+ height={70}
403
+ style={{ marginRight: 10, marginBottom: 5 }}
404
+ />
405
+ <Placeholder style={{ paddingVertical: 10 }}>
406
+ <PlaceholderLine width={60} height={10} />
407
+ <PlaceholderLine width={50} height={10} />
408
+ <PlaceholderLine width={70} height={10} />
409
+ </Placeholder>
410
+ </View>
411
+ </Placeholder>
412
+ </View>
413
+ ),
414
+ )}
415
+ </>
416
+ )}
417
+ </ProductsList>
418
+ <OModal
419
+ open={openFilters}
420
+ onCancel={() => handleCloseFilters()}
421
+ onClose={() => handleCloseFilters()}
422
+ >
423
+ <ScrollView style={styles.filterContainer}>
453
424
  <OText
454
- size={16}
455
- weight='bold'
456
- lineHeight={24}
457
- style={{ marginBottom: 10 }}
425
+ size={20}
426
+ mBottom={15}
427
+ style={{ marginTop: 10 }}
458
428
  >
459
- {t('BRANDS', 'Brands')}
429
+ {t('FILTER', 'Filter')}
460
430
  </OText>
461
- {!brandList?.loading && !brandList?.error && brandList?.brands?.length > 0 && (
462
- <ScrollView
463
- style={{ maxHeight: 300, marginBottom: 10 }}
464
- showsVerticalScrollIndicator={true}
465
- nestedScrollEnabled={true}
466
- >
467
- {brandList?.brands.map((brand: any, i: number) => brand?.enabled && (
468
- <BrandItem
469
- key={i}
470
- onPress={() => handleChangeBrandFilter(brand?.id)}
431
+ <SortContainer>
432
+ <OText weight='bold' mBottom={7} size={16}>
433
+ {t('SORT', 'Sort')}
434
+ </OText>
435
+ {sortItems?.filter(item => !(orderState?.options?.type === 1 && item?.value === 'pickup_time') && !(orderState?.options?.type === 2 && item?.value === 'delivery_time'))?.map(item => (
436
+ <TouchableOpacity
437
+ key={item?.value}
438
+ onPress={() => handleChangeFilters('orderBy', item?.value)}
439
+ style={{ marginBottom: 7 }}
440
+ >
441
+ <OText
442
+ weight={filters?.orderBy?.includes(item?.value) ? 'bold' : '500'}
443
+ mBottom={filters?.orderBy?.includes(item?.value) ? 5 : 0}
471
444
  >
472
- <OText
473
- size={14}
474
- weight={'400'}
475
- lineHeight={24}
445
+ {item?.text} {(filters?.orderBy?.includes(item?.value)) && <>{filters?.orderBy?.includes('-') ? <AntDesignIcon name='caretup' /> : <AntDesignIcon name='caretdown' />}</>}
446
+ </OText>
447
+ </TouchableOpacity>
448
+ ))}
449
+ </SortContainer>
450
+ <BrandContainer>
451
+ <OText
452
+ size={16}
453
+ weight='bold'
454
+ lineHeight={24}
455
+ style={{ marginBottom: 10 }}
456
+ >
457
+ {t('BRANDS', 'Brands')}
458
+ </OText>
459
+ {!brandList?.loading && !brandList?.error && brandList?.brands?.length > 0 && (
460
+ <ScrollView
461
+ style={{ maxHeight: 300, marginBottom: 10 }}
462
+ showsVerticalScrollIndicator={true}
463
+ nestedScrollEnabled={true}
464
+ >
465
+ {brandList?.brands.map((brand: any, i: number) => brand?.enabled && (
466
+ <BrandItem
467
+ key={i}
468
+ onPress={() => handleChangeBrandFilter(brand?.id)}
476
469
  >
477
- {brand?.name}
478
- </OText>
479
- {filters?.franchise_ids?.includes(brand?.id) && (
480
- <AntDesignIcon
481
- name='check'
482
- color={theme.colors.success500}
483
- size={16}
484
- />
485
- )}
486
- </BrandItem>
470
+ <OText
471
+ size={14}
472
+ weight={'400'}
473
+ lineHeight={24}
474
+ >
475
+ {brand?.name}
476
+ </OText>
477
+ {filters?.franchise_ids?.includes(brand?.id) && (
478
+ <AntDesignIcon
479
+ name='check'
480
+ color={theme.colors.success500}
481
+ size={16}
482
+ />
483
+ )}
484
+ </BrandItem>
485
+ ))}
486
+ </ScrollView>
487
+ )}
488
+ {!brandList?.loading && ((brandList?.brands?.filter((brand: any) => brand?.enabled))?.length === 0) && (
489
+ <OText size={14} weight='400'>{t('NO_RESULTS_FOUND', 'Sorry, no results found')}</OText>
490
+ )}
491
+ </BrandContainer>
492
+ <PriceFilterWrapper>
493
+ <OText
494
+ size={16}
495
+ weight='bold'
496
+ lineHeight={24}
497
+ style={{ marginBottom: 5 }}
498
+ >
499
+ {t('PRICE_RANGE', 'Price range')}
500
+ </OText>
501
+ <View style={styles.priceContainer}>
502
+ {priceList.map((price: any, i: number) => (
503
+ <OButton
504
+ key={i}
505
+ bgColor={(filters?.price_level === price?.level) ? theme.colors.primary : theme.colors.backgroundGray200}
506
+ onClick={() => handleChangePriceRange(price?.level)}
507
+ text={`${price.content} ${(filters?.price_level === price?.level) ? ' X' : ''}`}
508
+ style={styles.priceItem}
509
+ textStyle={{ fontSize: 10, color: (filters?.price_level === price?.level) ? theme.colors.backgroundLight : theme.colors.textNormal }}
510
+ />
487
511
  ))}
488
- </ScrollView>
512
+ </View>
513
+ </PriceFilterWrapper>
514
+ {orderState?.options?.type === 1 && (
515
+ <MaxSectionItem
516
+ filters={filters}
517
+ title={t('MAX_DELIVERY_FEE', 'Max delivery fee')}
518
+ options={maxDeliveryFeeOptions}
519
+ filter='max_delivery_price'
520
+ handleChangeFilters={handleChangeFilters}
521
+ />
489
522
  )}
490
- {!brandList?.loading && ((brandList?.brands?.filter((brand: any) => brand?.enabled))?.length === 0) && (
491
- <OText size={14} weight='400'>{t('NO_RESULTS_FOUND', 'Sorry, no results found')}</OText>
523
+ {[1, 2].includes(orderState?.options?.type) && (
524
+ <MaxSectionItem
525
+ filters={filters}
526
+ title={orderState?.options?.type === 1 ? t('MAX_DELIVERY_TIME', 'Max delivery time') : t('MAX_PICKUP_TIME', 'Max pickup time')}
527
+ options={maxTimeOptions}
528
+ filter='max_eta'
529
+ handleChangeFilters={handleChangeFilters}
530
+ />
492
531
  )}
493
- </BrandContainer>
494
- <PriceFilterWrapper>
495
- <OText
496
- size={16}
497
- weight='bold'
498
- lineHeight={24}
499
- style={{ marginBottom: 5 }}
500
- >
501
- {t('PRICE_RANGE', 'Price range')}
502
- </OText>
503
- <View style={styles.priceContainer}>
504
- {priceList.map((price: any, i: number) => (
505
- <OButton
506
- key={i}
507
- bgColor={(filters?.price_level === price?.level) ? theme.colors.primary : theme.colors.backgroundGray200}
508
- onClick={() => handleChangePriceRange(price?.level)}
509
- text={`${price.content} ${(filters?.price_level === price?.level) ? ' X' : ''}`}
510
- style={styles.priceItem}
511
- textStyle={{ fontSize: 10, color: (filters?.price_level === price?.level) ? theme.colors.backgroundLight : theme.colors.textNormal }}
512
- />
513
- ))}
514
- </View>
515
- </PriceFilterWrapper>
516
- {orderState?.options?.type === 1 && (
517
532
  <MaxSectionItem
518
533
  filters={filters}
519
- title={t('MAX_DELIVERY_FEE', 'Max delivery fee')}
520
- options={maxDeliveryFeeOptions}
521
- filter='max_delivery_price'
534
+ title={t('MAX_DISTANCE', 'Max distance')}
535
+ options={maxDistanceOptions}
536
+ filter='max_distance'
522
537
  handleChangeFilters={handleChangeFilters}
523
538
  />
524
- )}
525
- {[1, 2].includes(orderState?.options?.type) && (
526
- <MaxSectionItem
527
- filters={filters}
528
- title={orderState?.options?.type === 1 ? t('MAX_DELIVERY_TIME', 'Max delivery time') : t('MAX_PICKUP_TIME', 'Max pickup time')}
529
- options={maxTimeOptions}
530
- filter='max_eta'
531
- handleChangeFilters={handleChangeFilters}
532
- />
533
- )}
534
- <MaxSectionItem
535
- filters={filters}
536
- title={t('MAX_DISTANCE', 'Max distance')}
537
- options={maxDistanceOptions}
538
- filter='max_distance'
539
- handleChangeFilters={handleChangeFilters}
540
- />
541
- {businessTypes?.length > 0 && (
542
- <TagsContainer>
543
- <OText weight='bold' mBottom={7} size={16}>{t('BUSINESS_CATEGORIES', 'Business categories')}</OText>
544
- <View style={styles.businessTypesContainer}>
545
- {businessTypes.map((type: any, i: number) => type.enabled && (
546
- <OButton
547
- key={type?.id}
548
- bgColor={(filters?.business_types?.includes(type?.id) || (type?.id === null && filters?.business_types?.length === 0)) ? theme.colors.primary : theme.colors.backgroundGray200}
549
- onClick={() => handleChangeActiveBusinessType(type)}
550
- text={`${t(`BUSINESS_TYPE_${type.name.replace(/\s/g, '_').toUpperCase()}`, type.name)} ${filters?.business_types?.includes(type?.id) ? 'X' : ''}`}
551
- style={styles.categoryStyle}
552
- textStyle={{ fontSize: 10, color: (filters?.business_types?.includes(type?.id) || (type?.id === null && filters?.business_types?.length === 0)) ? '#fff' : theme.colors.textNormal }}
553
- />
554
- ))}
555
- </View>
556
- </TagsContainer>
557
- )}
558
- </ScrollView>
559
- <WrapperButtons>
560
- <View style={{ width: '50%' }}>
561
- <OButton
562
- text={t('APPLY', 'Apply')}
563
- parentStyle={styles.applyButton}
564
- textStyle={{ color: '#fff' }}
565
- onClick={() => handleApplyFilters()}
566
- />
567
- </View>
568
- <View style={{ width: '50%' }}>
569
- <OButton
570
- text={t('CLEAR_FILTERS', 'Clear')}
571
- bgColor={theme.colors.white}
572
- borderColor={theme.colors.primary}
573
- parentStyle={styles.applyButton}
574
- textStyle={{ color: theme.colors.primary }}
575
- onClick={() => clearFilters()}
576
- />
577
- </View>
578
- </WrapperButtons>
579
- </OModal>
580
- </BContainer>
539
+ {businessTypes?.length > 0 && (
540
+ <TagsContainer>
541
+ <OText weight='bold' mBottom={7} size={16}>{t('BUSINESS_CATEGORIES', 'Business categories')}</OText>
542
+ <View style={styles.businessTypesContainer}>
543
+ {businessTypes.map((type: any, i: number) => type.enabled && (
544
+ <OButton
545
+ key={type?.id}
546
+ bgColor={(filters?.business_types?.includes(type?.id) || (type?.id === null && filters?.business_types?.length === 0)) ? theme.colors.primary : theme.colors.backgroundGray200}
547
+ onClick={() => handleChangeActiveBusinessType(type)}
548
+ text={`${t(`BUSINESS_TYPE_${type.name.replace(/\s/g, '_').toUpperCase()}`, type.name)} ${filters?.business_types?.includes(type?.id) ? 'X' : ''}`}
549
+ style={styles.categoryStyle}
550
+ textStyle={{ fontSize: 10, color: (filters?.business_types?.includes(type?.id) || (type?.id === null && filters?.business_types?.length === 0)) ? '#fff' : theme.colors.textNormal }}
551
+ />
552
+ ))}
553
+ </View>
554
+ </TagsContainer>
555
+ )}
556
+ </ScrollView>
557
+ <WrapperButtons>
558
+ <View style={{ width: '50%' }}>
559
+ <OButton
560
+ text={t('APPLY', 'Apply')}
561
+ parentStyle={styles.applyButton}
562
+ textStyle={{ color: '#fff' }}
563
+ onClick={() => handleApplyFilters()}
564
+ />
565
+ </View>
566
+ <View style={{ width: '50%' }}>
567
+ <OButton
568
+ text={t('CLEAR_FILTERS', 'Clear')}
569
+ bgColor={theme.colors.white}
570
+ borderColor={theme.colors.primary}
571
+ parentStyle={styles.applyButton}
572
+ textStyle={{ color: theme.colors.primary }}
573
+ onClick={() => clearFilters()}
574
+ />
575
+ </View>
576
+ </WrapperButtons>
577
+ </OModal>
578
+ </BContainer>
579
+ </IOScrollView>
581
580
  )
582
581
  }
583
582