ordering-ui-react-native 0.16.69 → 0.16.72

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.16.69",
3
+ "version": "0.16.72",
4
4
  "description": "Reusable components made in react native",
5
5
  "main": "src/index.tsx",
6
6
  "author": "ordering.inc",
@@ -1,6 +1,6 @@
1
1
  import React, { useState, useEffect } from 'react';
2
2
  import { StyleSheet, View, TouchableOpacity, Linking, Pressable } from 'react-native';
3
- import { useUtils, useOrder, useLanguage, useOrderingTheme } from 'ordering-components/native';
3
+ import { useUtils, useOrder, useLanguage } from 'ordering-components/native';
4
4
  import { useTheme } from 'styled-components/native';
5
5
  import { OIcon, OText, OModal } from '../shared';
6
6
  import { BusinessBasicInformationParams } from '../../types';
@@ -38,7 +38,6 @@ export const BusinessBasicInformation = (
38
38
  const { business, loading } = businessState;
39
39
 
40
40
  const theme = useTheme();
41
- const [orderingTheme] = useOrderingTheme()
42
41
  const [orderState] = useOrder();
43
42
  const [, t] = useLanguage();
44
43
  const [{ parsePrice, parseDistance, optimizeImage }] = useUtils();
@@ -46,9 +45,9 @@ export const BusinessBasicInformation = (
46
45
  const [openBusinessReviews, setOpenBusinessReviews] = useState(false);
47
46
  const [businessInformationObtained, setBusinessInformationObtained] = useState(false)
48
47
  const [businessReviewsObtained, setBusinessReviewsObtainedbtained] = useState(false)
49
- const isChewLayout = orderingTheme?.theme?.business_view?.components?.header?.components?.layout?.type === 'chew'
50
- const showLogo = !orderingTheme?.theme?.business_view?.components?.header?.components?.business?.components?.logo?.hidden
51
-
48
+ const isChewLayout = theme?.business_view?.components?.header?.components?.layout?.type === 'original'
49
+ const showLogo = !theme?.business_view?.components?.header?.components?.business?.components?.logo?.hidden
50
+
52
51
  const styles = StyleSheet.create({
53
52
  businesInfoheaderStyle: {
54
53
  height: 150,
@@ -247,7 +246,7 @@ export const BusinessBasicInformation = (
247
246
  )}
248
247
  {isChewLayout && (
249
248
  <TouchableOpacity onPress={() => handleClickBusinessInformation()}>
250
- <OText style={{textDecorationColor: theme.colors.black, textDecorationLine: 'underline'}}>
249
+ <OText style={{ textDecorationColor: theme.colors.black, textDecorationLine: 'underline' }}>
251
250
  {t('SEE_MORE_DESCRIPTION', 'See more')}
252
251
  </OText>
253
252
  </TouchableOpacity>
@@ -298,22 +297,14 @@ export const BusinessBasicInformation = (
298
297
  <BusinessInfo style={styles.businessInfo}>
299
298
  {showLogo && (
300
299
  <BusinessLogo isChewLayout={isChewLayout}>
301
- {loading ? (
302
- <View>
303
- <Placeholder Animation={Fade}>
304
- <PlaceholderLine height={50} width={20} />
305
- </Placeholder>
306
- </View>
307
- ) : (
308
- !isBusinessInfoShow && (
309
- <OIcon
310
- url={
311
- logo ||
312
- optimizeImage(businessState?.business?.logo, 'h_70,c_limit')
313
- }
314
- style={styles.businessLogo}
315
- />
316
- )
300
+ {!isBusinessInfoShow && (
301
+ <OIcon
302
+ url={
303
+ logo ||
304
+ optimizeImage(businessState?.business?.logo, 'h_70,c_limit')
305
+ }
306
+ style={styles.businessLogo}
307
+ />
317
308
  )}
318
309
  </BusinessLogo>
319
310
  )}
@@ -327,16 +327,17 @@ export const BusinessListingSearchUI = (props: BusinessSearchParams) => {
327
327
  </OText>
328
328
  </WrapHeader>
329
329
  <SearchWrapper>
330
- <SearchBar
331
- autoFocus
332
- lazyLoad
333
- inputStyle={{ ...styles.searchInput, ...Platform.OS === 'ios' ? {} : { paddingBottom: 4 } }}
334
- placeholder={`${t('SEARCH_BUSINESSES', 'Search Businesses')} / ${t('TYPE_AT_LEAST_3_CHARACTERS', 'type at least 3 characters')}`}
335
- onSearch={(val: string) => handleChangeTermValue(val)}
336
- value={termValue}
337
- iconCustomRight={<AntDesignIcon name='filter' size={16} style={{ bottom: 2 }} onPress={() => handleOpenfilters()} />}
338
- />
339
-
330
+ {isFocused && (
331
+ <SearchBar
332
+ autoFocus
333
+ lazyLoad
334
+ inputStyle={{ ...styles.searchInput, ...Platform.OS === 'ios' ? {} : { paddingBottom: 4 } }}
335
+ placeholder={`${t('SEARCH_BUSINESSES', 'Search Businesses')} / ${t('TYPE_AT_LEAST_3_CHARACTERS', 'type at least 3 characters')}`}
336
+ onSearch={(val: string) => handleChangeTermValue(val)}
337
+ value={termValue}
338
+ iconCustomRight={<AntDesignIcon name='filter' size={16} style={{ bottom: 2 }} onPress={() => handleOpenfilters()} />}
339
+ />
340
+ )}
340
341
  </SearchWrapper>
341
342
  {
342
343
  noResults && (
@@ -10,9 +10,9 @@ import {
10
10
  useUtils,
11
11
  ToastType,
12
12
  useToast,
13
- useConfig,
14
- useOrderingTheme
13
+ useConfig
15
14
  } from 'ordering-components/native'
15
+ import { Fade, Placeholder, PlaceholderLine } from 'rn-placeholder';
16
16
  import { OButton, OIcon, OModal, OText } from '../shared'
17
17
  import Alert from '../../providers/AlertProvider'
18
18
  import { BusinessBasicInformation } from '../BusinessBasicInformation'
@@ -66,7 +66,6 @@ const BusinessProductsListingUI = (props: BusinessProductsListingParams) => {
66
66
  } = props
67
67
 
68
68
  const theme = useTheme();
69
- const [orderingTheme] = useOrderingTheme()
70
69
  const [, t] = useLanguage()
71
70
  const [{ auth }] = useSession()
72
71
  const [orderState, { clearCart }] = useOrder()
@@ -75,9 +74,9 @@ const BusinessProductsListingUI = (props: BusinessProductsListingParams) => {
75
74
  const [{ configs }] = useConfig()
76
75
  const isPreOrder = configs?.preorder_status_enabled?.value === '1'
77
76
 
78
- const isChewLayout = orderingTheme?.theme?.business_view?.components?.header?.components?.layout?.type === 'chew'
79
- const showLogo = !orderingTheme?.theme?.business_view?.components?.header?.components?.business?.components?.logo?.hidden
80
- const hideBusinessNearCity = orderingTheme?.theme?.business_view?.components?.near_business?.hidden
77
+ const isChewLayout = theme?.business_view?.components?.header?.components?.layout?.type === 'chew'
78
+ const showLogo = !theme?.business_view?.components?.header?.components?.business?.components?.logo?.hidden
79
+ const hideBusinessNearCity = theme?.business_view?.components?.near_business?.hidden ?? true
81
80
 
82
81
  const styles = StyleSheet.create({
83
82
  mainContainer: {
@@ -103,7 +102,13 @@ const BusinessProductsListingUI = (props: BusinessProductsListingParams) => {
103
102
  padding: 15,
104
103
  justifyContent: 'center',
105
104
  shadowColor: theme.colors.clear,
106
- }
105
+ },
106
+ businessSkeleton: {
107
+ borderRadius: 8,
108
+ marginRight: 20,
109
+ width: 56,
110
+ height: 56
111
+ },
107
112
  })
108
113
 
109
114
  const { business, loading, error } = businessState
@@ -277,6 +282,19 @@ const BusinessProductsListingUI = (props: BusinessProductsListingParams) => {
277
282
  </WrapSearchBar>
278
283
  )}
279
284
  </TopHeader>
285
+ {!hideBusinessNearCity && loading && (
286
+ <NearBusiness style={{ paddingBottom: 10 }}>
287
+ <Placeholder Animation={Fade}>
288
+ <View style={{ flexDirection: 'row' }}>
289
+ {[...Array(10).keys()].map(i => (
290
+ <View style={styles.businessSkeleton} key={i}>
291
+ <PlaceholderLine style={{ width: '100%', height: '100%' }} />
292
+ </View>
293
+ ))}
294
+ </View>
295
+ </Placeholder>
296
+ </NearBusiness>
297
+ )}
280
298
  {!hideBusinessNearCity && businessState?.business?.city_id && (
281
299
  <NearBusiness>
282
300
  <BusinessesListing
@@ -18,8 +18,7 @@ import {
18
18
  useSession,
19
19
  useOrder,
20
20
  useConfig,
21
- useUtils,
22
- useOrderingTheme
21
+ useUtils
23
22
  } from 'ordering-components/native';
24
23
  import { useTheme } from 'styled-components/native';
25
24
  import Ionicons from 'react-native-vector-icons/Ionicons'
@@ -75,13 +74,12 @@ const BusinessesListingUI = (props: BusinessesListingParams) => {
75
74
  logosLayout
76
75
  } = props;
77
76
  const theme = useTheme();
78
- const [orderingTheme] = useOrderingTheme()
79
77
  const isFocused = useIsFocused();
80
78
  const appState = useRef(AppState.currentState)
81
79
  const searchBarRef = useRef<any>()
82
80
  const [appStateVisible, setAppStateVisible] = useState(appState.current);
83
- const isChewLayout = orderingTheme?.theme?.header?.components?.layout?.type === 'chew'
84
- const hideCities = orderingTheme?.theme?.business_listing_view?.components?.cities?.hidden
81
+ const isChewLayout = theme?.header?.components?.layout?.type === 'original'
82
+ const hideCities = theme?.business_listing_view?.components?.cities?.hidden ?? true
85
83
  const [refreshing] = useState(false);
86
84
  const styles = StyleSheet.create({
87
85
  container: {
@@ -132,7 +130,10 @@ const BusinessesListingUI = (props: BusinessesListingParams) => {
132
130
  borderColor: theme.colors.backgroundGray,
133
131
  borderRadius: 8,
134
132
  marginHorizontal: 40,
135
- height: 45
133
+ minHeight: 45,
134
+ paddingVertical: 5,
135
+ paddingHorizontal: 20,
136
+ borderWidth: 1
136
137
  },
137
138
  businessSkeleton: {
138
139
  borderRadius: 8,
@@ -426,7 +427,7 @@ const BusinessesListingUI = (props: BusinessesListingParams) => {
426
427
  </OrderControlContainer>
427
428
  ) : (
428
429
  <>
429
- {!isPreOrderSetting && (// cambiar
430
+ {isPreOrderSetting && (
430
431
  <View style={{ paddingHorizontal: 30 }}>
431
432
  <PreorderInput
432
433
  isChewLayout={isChewLayout}
@@ -474,25 +475,28 @@ const BusinessesListingUI = (props: BusinessesListingParams) => {
474
475
  onCancel={() => handleChangeSearch('')}
475
476
  placeholder={t('SEARCH', 'Search')}
476
477
  height={50}
477
- isDisabled={!businessTypes}
478
+ isDisabled={true}
478
479
  inputContainerStyles={styles.inputContainerStyles}
479
480
  containerStyles={{
480
481
  marginHorizontal: 40,
481
482
  marginTop: 20
482
483
  }}
483
484
  inputStyle={{ ...styles.searchInput, ...Platform.OS === 'ios' ? { paddingBottom: 6 } : { paddingBottom: 4 } }}
484
- onSubmitEditing={() => { configs?.advanced_business_search_enabled?.value === '1' && navigation.navigate('BusinessSearch', { businessTypes, defaultTerm: searchValue }) }}
485
+ onPress={() => { navigation.navigate('BusinessSearch', { businessTypes }) }}
486
+ onSubmitEditing={() => { navigation.navigate('BusinessSearch', { businessTypes, defaultTerm: searchValue }) }}
485
487
  />
486
488
  )}
487
489
 
488
490
  {!hideCities && (
489
491
  <View style={{ marginTop: 10 }}>
490
- <OButton
491
- onClick={() => setIsOpenCities(true)}
492
- text={citiesState?.cities?.find((city: any) => city?.id === orderState?.options?.city_id)?.name || t('FILTER_BY_CITY', 'Filter by city')}
493
- style={styles?.buttonCityStyle}
494
- textStyle={{ color: theme.colors.backgroundGray, fontWeight: 'bold', fontSize: 18 }}
495
- />
492
+ <TouchableOpacity
493
+ style={styles.buttonCityStyle}
494
+ onPress={() => setIsOpenCities(true)}
495
+ >
496
+ <OText size={18} color={theme.colors.backgroundGray} weight='bold' style={{ textAlign: 'center' }}>
497
+ {citiesState?.cities?.find((city: any) => city?.id === orderState?.options?.city_id)?.name || t('FILTER_BY_CITY', 'Filter by city')}
498
+ </OText>
499
+ </TouchableOpacity>
496
500
  </View>
497
501
  )}
498
502
  <OrderProgressWrapper>
@@ -1,6 +1,6 @@
1
1
 
2
2
  import React, { useState, useEffect } from 'react'
3
- import { useOrder, useSession, useLanguage, useOrderingTheme } from 'ordering-components/native';
3
+ import { useOrder, useSession, useLanguage } from 'ordering-components/native';
4
4
 
5
5
  import { useTheme } from 'styled-components/native'
6
6
  import { BusinessesListing as OriginalBusinessListing } from './Layout/Original'
@@ -12,8 +12,7 @@ import { NotificationSetting } from '../../../../../src/components/NotificationS
12
12
  export const BusinessesListing = (props: any) => {
13
13
  const { logosLayout } = props
14
14
  const theme = useTheme()
15
- const [orderingTheme] = useOrderingTheme()
16
- const layout = orderingTheme?.theme?.business_listing_view?.components?.layout?.type || 'original'
15
+ const layout = theme?.business_listing_view?.components?.layout?.type || 'original'
17
16
  const [, t] = useLanguage();
18
17
  const [{ auth }] = useSession()
19
18
  const [, { getLastOrderHasNoReview }] = useOrder();
@@ -24,6 +24,7 @@ import { DriverTips } from '../DriverTips';
24
24
  import { NotFoundSource } from '../NotFoundSource';
25
25
  import { UserDetails } from '../UserDetails';
26
26
  import { PaymentOptionWallet } from '../PaymentOptionWallet';
27
+ import { PlaceSpot } from '../PlaceSpot'
27
28
 
28
29
  import {
29
30
  ChContainer,
@@ -143,7 +144,8 @@ const CheckoutUI = (props: any) => {
143
144
  const [isOpen, setIsOpen] = useState(false)
144
145
  const [requiredFields, setRequiredFields] = useState<any>([])
145
146
 
146
- const placeSpotTypes = [4]
147
+ const placeSpotTypes = [3, 4, 5]
148
+ const placeSpotsEnabled = placeSpotTypes.includes(options?.type)
147
149
  const businessConfigs = businessDetails?.business?.configs ?? []
148
150
  const isWalletCashEnabled = businessConfigs.find((config: any) => config.key === 'wallet_cash_enabled')?.value === '1'
149
151
  const isWalletCreditPointsEnabled = businessConfigs.find((config: any) => config.key === 'wallet_credit_point_enabled')?.value === '1'
@@ -151,8 +153,9 @@ const CheckoutUI = (props: any) => {
151
153
  const isBusinessChangeEnabled = configs?.cart_change_business_validation?.value === '1'
152
154
 
153
155
  const isPreOrder = configs?.preorder_status_enabled?.value === '1'
154
- const isDisabledButtonPlace = loading || !cart?.valid || (!paymethodSelected && cart?.balance > 0) || placing || errorCash ||
155
- cart?.subtotal < cart?.minimum || (placeSpotTypes.includes(options?.type) && !cart?.place) ||
156
+ const isDisabledButtonPlace = loading || !cart?.valid || (!paymethodSelected && cart?.balance > 0) ||
157
+ placing || errorCash || cart?.subtotal < cart?.minimum ||
158
+ // (placeSpotTypes.includes(options?.type) && !cart?.place) ||
156
159
  (options.type === 1 &&
157
160
  validationFields?.fields?.checkout?.driver_tip?.enabled &&
158
161
  validationFields?.fields?.checkout?.driver_tip?.required &&
@@ -595,6 +598,20 @@ const CheckoutUI = (props: any) => {
595
598
  )}
596
599
 
597
600
 
601
+ {!cartState.loading && placeSpotsEnabled && (
602
+ <>
603
+ <View style={{ height: 8, backgroundColor: theme.colors.backgroundGray100, marginTop: 30, marginHorizontal: -40 }} />
604
+ <PlaceSpot
605
+ isCheckout
606
+ isInputMode
607
+ cart={cart}
608
+ spotNumberDefault={cartState?.cart?.spot_number ?? cart?.spot_number}
609
+ vehicleDefault={cart?.vehicle}
610
+ />
611
+ <View style={{ height: 8, backgroundColor: theme.colors.backgroundGray100, marginHorizontal: -40 }} />
612
+ </>
613
+ )}
614
+
598
615
  {!cartState.loading && cart && (
599
616
  <ChSection>
600
617
  <ChCart>
@@ -683,14 +700,6 @@ const CheckoutUI = (props: any) => {
683
700
  {t('WARNING_INVALID_PRODUCTS_CHECKOUT', 'To continue with your checkout, please remove from your cart the products that are not available.')}
684
701
  </OText>
685
702
  )}
686
- {placeSpotTypes.includes(options?.type) && !cart?.place && (
687
- <OText
688
- color={theme.colors.error}
689
- size={12}
690
- >
691
- {t('WARNING_PLACE_SPOT', 'Please, select your spot to place order.')}
692
- </OText>
693
- )}
694
703
  {options.type === 1 &&
695
704
  validationFields?.fields?.checkout?.driver_tip?.enabled &&
696
705
  validationFields?.fields?.checkout?.driver_tip?.required &&
@@ -30,7 +30,8 @@ import {
30
30
  OrderDriver,
31
31
  Map,
32
32
  Divider,
33
- OrderAction
33
+ OrderAction,
34
+ PlaceSpotWrapper
34
35
  } from './styles';
35
36
  import { OButton, OIcon, OModal, OText } from '../shared';
36
37
  import { ProductItemAccordion } from '../ProductItemAccordion';
@@ -44,6 +45,7 @@ import { TaxInformation } from '../TaxInformation';
44
45
  import { Placeholder, PlaceholderLine } from 'rn-placeholder';
45
46
  import NavBar from '../NavBar'
46
47
  import { OrderHistory } from './OrderHistory';
48
+ import { PlaceSpot } from '../PlaceSpot'
47
49
  export const OrderDetailsUI = (props: OrderDetailsParams) => {
48
50
  const {
49
51
  navigation,
@@ -105,6 +107,7 @@ export const OrderDetailsUI = (props: OrderDetailsParams) => {
105
107
  const [refreshing] = useState(false);
106
108
  const { order, businessData } = props.order;
107
109
  const mapValidStatuses = [9, 19, 23]
110
+ const placeSpotTypes = [3, 4, 5]
108
111
 
109
112
  const walletName: any = {
110
113
  cash: {
@@ -680,6 +683,18 @@ export const OrderDetailsUI = (props: OrderDetailsParams) => {
680
683
  </OText>
681
684
  </View>
682
685
  </OrderBusiness>
686
+
687
+ {placeSpotTypes.includes(order?.delivery_type) && (
688
+ <PlaceSpotWrapper>
689
+ <PlaceSpot
690
+ isInputMode
691
+ cart={order}
692
+ spotNumberDefault={order?.spot_number}
693
+ vehicleDefault={order?.vehicle}
694
+ />
695
+ </PlaceSpotWrapper>
696
+ )}
697
+
683
698
  <View
684
699
  style={{
685
700
  height: 8,
@@ -127,4 +127,8 @@ export const Divider = styled.View`
127
127
  `
128
128
  export const OrderAction = styled.View`
129
129
  flex-direction: row;
130
- `
130
+ `
131
+
132
+ export const PlaceSpotWrapper = styled.View`
133
+ padding-horizontal: 40px;
134
+ `
@@ -26,7 +26,6 @@ import AntIcon from 'react-native-vector-icons/AntDesign'
26
26
  import { TaxInformation } from '../TaxInformation';
27
27
  import { TouchableOpacity } from 'react-native';
28
28
  import { OAlert } from '../../../../../src/components/shared'
29
- import { PlaceSpot } from '../PlaceSpot'
30
29
 
31
30
  const OrderSummaryUI = (props: any) => {
32
31
  const {
@@ -39,8 +38,7 @@ const OrderSummaryUI = (props: any) => {
39
38
  commentState,
40
39
  handleChangeComment,
41
40
  onNavigationRedirect,
42
- handleRemoveOfferClick,
43
- placeSpotTypes
41
+ handleRemoveOfferClick
44
42
  } = props;
45
43
 
46
44
  const theme = useTheme()
@@ -51,7 +49,6 @@ const OrderSummaryUI = (props: any) => {
51
49
  const [validationFields] = useValidationFields();
52
50
  const [openTaxModal, setOpenTaxModal] = useState<any>({ open: false, data: null, type: '' })
53
51
  const [confirm, setConfirm] = useState<any>({ open: false, content: null, handleOnAccept: null, id: null, title: null })
54
- const [openPlaceModal, setOpenPlaceModal] = useState(false)
55
52
  const isCouponEnabled = validationFields?.fields?.checkout?.coupon?.enabled;
56
53
 
57
54
  const handleDeleteClick = (product: any) => {
@@ -304,24 +301,6 @@ const OrderSummaryUI = (props: any) => {
304
301
  </OSTable>
305
302
  </View>
306
303
  )}
307
- {placeSpotTypes && placeSpotTypes.includes(orderState?.options?.type) && (
308
- <OSTable style={{ marginTop: 15 }}>
309
- <OText size={14} lineHeight={21} weight={'600'}>
310
- {t('SPOT', 'Spot')}: {cart?.place?.name || t('NO_SELECTED', 'No selected')}
311
- </OText>
312
- <TouchableOpacity onPress={() => setOpenPlaceModal(true)}>
313
- <OText
314
- size={14}
315
- lineHeight={21}
316
- weight={'600'}
317
- color={theme.colors.primary}
318
- style={{ textDecorationLine: 'underline' }}
319
- >
320
- {t('EDIT', 'Edit')}
321
- </OText>
322
- </TouchableOpacity>
323
- </OSTable>
324
- )}
325
304
  {cart?.status !== 2 && (
326
305
  <OSTable>
327
306
  <View style={{ width: '100%', marginTop: 20 }}>
@@ -370,18 +349,6 @@ const OrderSummaryUI = (props: any) => {
370
349
  products={cart?.products}
371
350
  />
372
351
  </OModal>
373
- <OModal
374
- open={openPlaceModal}
375
- title={t('CHOOSE_YOUR_SPOT', 'Choose your spot')}
376
- onClose={() => setOpenPlaceModal(false)}
377
- entireModal
378
- >
379
- <PlaceSpot
380
- cart={cart}
381
- isOpenPlaceSpot={openPlaceModal}
382
- setOpenPlaceModal={setOpenPlaceModal}
383
- />
384
- </OModal>
385
352
  <OAlert
386
353
  open={confirm.open}
387
354
  title={confirm.title}
@@ -1,24 +1,78 @@
1
1
  import React, { useEffect, useState } from 'react'
2
- import { View } from 'react-native'
3
- import { PlaceSpot as PlaceSpotController, useLanguage } from 'ordering-components/native'
2
+ import { View, StyleSheet } from 'react-native'
3
+ import { PlaceSpot as PlaceSpotController, useLanguage, useOrder, useToast, ToastType } from 'ordering-components/native'
4
4
  import { PlaceGroupContainer, PlaceSpotContainer } from './styles'
5
5
  import { NotFoundSource } from '../NotFoundSource'
6
- import { OText, ODropDown } from '../shared'
6
+ import { OText, ODropDown, OInput, OButton } from '../shared'
7
7
  import { Placeholder, PlaceholderLine } from 'rn-placeholder'
8
8
  import { PlaceSpotParams } from '../../types'
9
+ import { useTheme } from 'styled-components/native'
10
+ import SelectDropdown from 'react-native-select-dropdown'
11
+ import IconAntDesign from 'react-native-vector-icons/AntDesign'
9
12
 
10
13
  const PlaceSpotUI = (props: PlaceSpotParams) => {
11
14
  const {
12
- isOpenPlaceSpot,
13
15
  cart,
16
+ orderTypes,
14
17
  placesState,
15
18
  handleChangePlace,
16
- getPlacesList,
17
- setOpenPlaceModal
19
+ spotNumber,
20
+ spotState,
21
+ isCheckout,
22
+ vehicle,
23
+ isInputMode,
24
+ setSpotNumber,
25
+ setVehicle,
26
+ handleChangeSpot
18
27
  } = props
19
28
 
29
+ const theme = useTheme()
20
30
  const [, t] = useLanguage()
31
+ const [orderState] = useOrder()
32
+ const [, { showToast }] = useToast();
33
+
21
34
  const [placeGroupSelected, setPlaceGroupSelected] = useState<any>(null)
35
+ const vehicleInputAllowed = [4, 5]
36
+
37
+ const currentOrderType = isCheckout ? orderState?.options?.type : cart?.delivery_type
38
+ const isEatin = currentOrderType === 3
39
+ const isDriveThru = currentOrderType === 5
40
+ const placeholderText = isEatin
41
+ ? t('EATIN_SPOT_NUMBER', 'Table number')
42
+ : isDriveThru
43
+ ? t('DRIVE_THRU_SPOT_NUMBER', 'Drive thru lane')
44
+ : t('CURBSIDE_SPOT_NUMBER', 'Spot number')
45
+
46
+ const styles = StyleSheet.create({
47
+ selectOption: {
48
+ backgroundColor: theme.colors.backgroundGray100,
49
+ borderRadius: 7.6,
50
+ paddingVertical: 10,
51
+ paddingHorizontal: 14,
52
+ flexDirection: 'row-reverse',
53
+ alignItems: 'center',
54
+ justifyContent: 'space-between',
55
+ height: 50,
56
+ width: '100%'
57
+ },
58
+ optionWrapper: {
59
+ marginBottom: 20
60
+ }
61
+ })
62
+
63
+ const vehicleTypeList: any = [
64
+ { key: 'car', text: t('VEHICLE_TYPE_CAR', 'Car') },
65
+ { key: 'truck', text: t('VEHICLE_TYPE_TRUCK', 'Truck') },
66
+ { key: 'suv', text: t('VEHICLE_TYPE_SUV', 'SUV') },
67
+ { key: 'van', text: t('VEHICLE_TYPE_VAN', 'Van') },
68
+ { key: 'motorcycle', text: t('VEHICLE_TYPE_MOTORCYCLE', 'Motorcycle') }
69
+ ]
70
+
71
+ const vehicleInputList = [
72
+ { key: 'model', text: t('VEHICLE_MODEL', 'Model') },
73
+ { key: 'car_registration', text: t('VEHICLE_CAR_REGISTRATION', 'Car registration') },
74
+ { key: 'color', text: t('VEHICLE_COLOR', 'Color') }
75
+ ]
22
76
 
23
77
  const getPlacesGroups = () => {
24
78
  const groups = placesState.placeGroups?.filter((group: any) => group?.enabled && placesState?.places?.find((place: any) => place?.enabled && place?.place_group_id === group?.id))
@@ -39,10 +93,29 @@ const PlaceSpotUI = (props: PlaceSpotParams) => {
39
93
  }
40
94
 
41
95
  const handlerChangePlace = (place: any) => {
42
- setOpenPlaceModal(false)
43
96
  handleChangePlace(place)
44
97
  }
45
98
 
99
+ const onChangeSpot = () => {
100
+ if (orderState.loading) return
101
+ const isVehicle = Object.values(vehicle).every(e => e)
102
+ const bodyToSend: any = {}
103
+ spotNumber && (bodyToSend.spot_number = spotNumber)
104
+ isVehicle && (bodyToSend.vehicle = vehicle)
105
+
106
+ if (Object.keys(bodyToSend).length) {
107
+ handleChangeSpot({ bodyToSend, isCheckout: !!isCheckout })
108
+ }
109
+ }
110
+
111
+ const manageErrorsToShow = (array = []) => {
112
+ let stringError = ''
113
+ const list = Array.isArray(array) ? array : Object.values(array)
114
+ list.map((item: any, i: number) => {
115
+ stringError += (i + 1) === array.length ? `- ${item?.message || item}` : `- ${item?.message || item}\n`
116
+ })
117
+ return stringError;
118
+ }
46
119
 
47
120
  useEffect(() => {
48
121
  if (!placesState?.loading) {
@@ -52,51 +125,157 @@ const PlaceSpotUI = (props: PlaceSpotParams) => {
52
125
  }, [placesState])
53
126
 
54
127
  useEffect(() => {
55
- getPlacesList()
56
- }, [isOpenPlaceSpot])
128
+ if (spotState?.error?.length > 0) {
129
+ const errorText = manageErrorsToShow(spotState?.errors)
130
+ showToast(ToastType.Error, errorText)
131
+ }
132
+ }, [spotState?.error])
57
133
 
58
134
  return (
59
135
  <PlaceSpotContainer>
60
- {(placesState.error || placesState?.placeGroups?.length === 0) && !placesState?.loading && (
61
- <NotFoundSource
62
- content={t('NO_PLACES_THIS_BUSINESS', 'There are not places for this business')}
63
- />
64
- )}
65
- {placesState?.loading && (
66
- <Placeholder>
67
- <PlaceGroupContainer>
68
- <PlaceholderLine width={100} height={25} />
69
- <PlaceholderLine height={30} />
70
- </PlaceGroupContainer>
71
- <View>
72
- <PlaceholderLine width={120} height={25} />
73
- <PlaceholderLine height={30} />
136
+ {isInputMode ? (
137
+ <PlaceGroupContainer>
138
+ <OText color={theme.colors.textNormal} size={16} weight='500' mBottom={15}>{orderTypes[currentOrderType]}</OText>
139
+ {vehicleInputAllowed.includes(currentOrderType) && (
140
+ <>
141
+ <View style={styles.optionWrapper}>
142
+ <OText color={theme.colors.textNormal} size={12} mBottom={5}>{t('VEHICLE_TYPE', 'Vehicle type')}</OText>
143
+ <SelectDropdown
144
+ defaultButtonText={t('SELECT_AN_OPTION', 'Select an option')}
145
+ data={vehicleTypeList}
146
+ defaultValue={vehicle?.type ? vehicleTypeList.find((obj: any) => obj.key === vehicle.type) : null}
147
+ onSelect={(selectedItem, index) => {
148
+ setVehicle({ ...vehicle, type: selectedItem.key ?? '' })
149
+ }}
150
+ buttonTextAfterSelection={(selectedItem, index) => {
151
+ return selectedItem.text
152
+ }}
153
+ rowTextForSelection={(item, index) => {
154
+ return item.text
155
+ }}
156
+ buttonStyle={styles.selectOption}
157
+ buttonTextStyle={{
158
+ color: theme.colors.disabled,
159
+ fontSize: 14,
160
+ textAlign: 'left',
161
+ marginHorizontal: 0
162
+ }}
163
+ dropdownStyle={{
164
+ borderRadius: 8,
165
+ borderColor: theme.colors.lightGray
166
+ }}
167
+ rowStyle={{
168
+ borderBottomColor: theme.colors.backgroundGray100,
169
+ backgroundColor: theme.colors.backgroundGray100,
170
+ height: 40,
171
+ flexDirection: 'column',
172
+ alignItems: 'flex-start',
173
+ paddingTop: 8,
174
+ paddingHorizontal: 14
175
+ }}
176
+ rowTextStyle={{
177
+ color: theme.colors.disabled,
178
+ fontSize: 14,
179
+ marginHorizontal: 0
180
+ }}
181
+ renderDropdownIcon={() => {
182
+ return (
183
+ <IconAntDesign
184
+ name='down'
185
+ color={theme.colors.textThird}
186
+ size={16}
187
+ />
188
+ )
189
+ }}
190
+ />
191
+ </View>
192
+ {vehicleInputList.map((input: any) => (
193
+ <View key={input.key}>
194
+ <OText color={theme.colors.textNormal} size={12} mBottom={5}>{input.text}</OText>
195
+ <OInput
196
+ placeholder={input.text}
197
+ value={vehicle[input.key] ?? ''}
198
+ onChange={(value: string) => setVehicle({ ...vehicle, [input.key]: value })}
199
+ style={{
200
+ borderColor: theme.colors.border,
201
+ borderRadius: 7.6,
202
+ marginBottom: 20
203
+ }}
204
+ inputStyle={{ fontSize: 12, color: theme.colors.textNormal }}
205
+ />
206
+ </View>
207
+ ))}
208
+ </>
209
+ )}
210
+ <OText color={theme.colors.textNormal} size={12} mBottom={5}>{placeholderText}</OText>
211
+ <OInput
212
+ value={spotNumber?.toString() ?? ''}
213
+ placeholder={placeholderText}
214
+ keyboardType='number-pad'
215
+ onChange={(value: string) => setSpotNumber(value)}
216
+ style={{
217
+ borderColor: theme.colors.border,
218
+ borderRadius: 7.6
219
+ }}
220
+ inputStyle={{ fontSize: 12, color: theme.colors.textNormal }}
221
+ />
222
+ <View style={{ alignItems: 'flex-start' }}>
223
+ <OButton
224
+ onClick={() => onChangeSpot()}
225
+ bgColor={theme.colors.primary}
226
+ borderColor={theme.colors.primary}
227
+ textStyle={{ color: 'white', fontSize: 12 }}
228
+ imgRightSrc={null}
229
+ text={t('UPDATE_SPOT_NUMBER', 'Update')}
230
+ isDisabled={(!spotNumber && !Object.values(vehicle).every(e => e))}
231
+ style={{ borderRadius: 7.6, height: 44, shadowOpacity: 0, marginTop: 20 }}
232
+ />
74
233
  </View>
75
- </Placeholder>
76
- )}
77
- {!(placesState.error || placesState?.placeGroups?.length === 0) && !placesState?.loading && (
234
+ </PlaceGroupContainer>
235
+ ) : (
78
236
  <>
79
- <PlaceGroupContainer>
80
- <OText size={16} mBottom={10}>{t('PLACE_GROUP', 'Place group')}</OText>
81
- <ODropDown
82
- placeholder={t('PLACE_GROUP', 'Place group')}
83
- options={getPlacesGroups()}
84
- onSelect={(group: any) => setPlaceGroupSelected(group)}
85
- defaultValue={placeGroupSelected ?? cart?.place}
86
- isModal
237
+ {(placesState.error || placesState?.placeGroups?.length === 0) && !placesState?.loading && (
238
+ <NotFoundSource
239
+ content={t('NO_PLACES_THIS_BUSINESS', 'There are not places for this business')}
87
240
  />
88
- </PlaceGroupContainer>
89
- {placeGroupSelected && (
90
- <View>
91
- <OText size={16} mBottom={10}>{t('SELECT_YOUR_SPOT', 'Select your spot')}</OText>
92
- <ODropDown
93
- onSelect={(place: any) => handlerChangePlace(place)}
94
- placeholder={t('SELECT_YOUR_SPOT', 'Select your spot')}
95
- options={getPlaces()}
96
- defaultValue={placesState?.places?.find((place : any) => place?.id === cart?.place_id)}
97
- isModal
98
- />
99
- </View>
241
+ )}
242
+ {placesState?.loading && (
243
+ <Placeholder>
244
+ <PlaceGroupContainer>
245
+ <PlaceholderLine width={100} height={25} />
246
+ <PlaceholderLine height={30} />
247
+ </PlaceGroupContainer>
248
+ <View>
249
+ <PlaceholderLine width={120} height={25} />
250
+ <PlaceholderLine height={30} />
251
+ </View>
252
+ </Placeholder>
253
+ )}
254
+ {!(placesState.error || placesState?.placeGroups?.length === 0) && !placesState?.loading && (
255
+ <>
256
+ <PlaceGroupContainer>
257
+ <OText size={16} mBottom={10}>{t('PLACE_GROUP', 'Place group')}</OText>
258
+ <ODropDown
259
+ placeholder={t('PLACE_GROUP', 'Place group')}
260
+ options={getPlacesGroups()}
261
+ onSelect={(group: any) => setPlaceGroupSelected(group)}
262
+ defaultValue={placeGroupSelected ?? cart?.place}
263
+ isModal
264
+ />
265
+ </PlaceGroupContainer>
266
+ {placeGroupSelected && (
267
+ <View>
268
+ <OText size={16} mBottom={10}>{t('SELECT_YOUR_SPOT', 'Select your spot')}</OText>
269
+ <ODropDown
270
+ onSelect={(place: any) => handlerChangePlace(place)}
271
+ placeholder={t('SELECT_YOUR_SPOT', 'Select your spot')}
272
+ options={getPlaces()}
273
+ defaultValue={placesState?.places?.find((place : any) => place?.id === cart?.place_id)}
274
+ isModal
275
+ />
276
+ </View>
277
+ )}
278
+ </>
100
279
  )}
101
280
  </>
102
281
  )}
@@ -105,9 +284,18 @@ const PlaceSpotUI = (props: PlaceSpotParams) => {
105
284
  }
106
285
 
107
286
  export const PlaceSpot = (props: PlaceSpotParams) => {
287
+ const [, t] = useLanguage()
288
+
108
289
  const placeSpotProps = {
109
290
  ...props,
110
- UIComponent: PlaceSpotUI
291
+ UIComponent: PlaceSpotUI,
292
+ orderTypes: {
293
+ 1: t('DELIVERY', 'Delivery'),
294
+ 2: t('PICKUP', 'Pickup'),
295
+ 3: t('EAT_IN', 'Eat in'),
296
+ 4: t('CURBSIDE', 'Curbside'),
297
+ 5: t('DRIVE_THRU', 'Drive thru')
298
+ }
111
299
  }
112
300
 
113
301
  return <PlaceSpotController {...placeSpotProps} />
@@ -1,8 +1,6 @@
1
1
  import styled from 'styled-components/native'
2
2
 
3
3
  export const PlaceSpotContainer = styled.View`
4
- min-height: 300px;
5
- padding: 20px;
6
4
  `
7
5
 
8
6
  export const PlaceGroupContainer = styled.View`
@@ -145,6 +145,10 @@ const SingleOrderCardUI = (props: SingleOrderCardParams) => {
145
145
  };
146
146
 
147
147
  const handleClickViewOrder = (uuid: string) => {
148
+ if (isMessageView) {
149
+ handleClickOrder(order?.uuid)
150
+ return
151
+ }
148
152
  onNavigationRedirect &&
149
153
  onNavigationRedirect('OrderDetails', { orderId: uuid });
150
154
  };
@@ -274,16 +278,18 @@ const SingleOrderCardUI = (props: SingleOrderCardParams) => {
274
278
  {getOrderStatus(order.status)?.value}
275
279
  </OText>
276
280
  </View>
277
- <TouchableOpacity
278
- onPress={handleChangeFavorite}
279
- style={{ marginTop: 5 }}
280
- >
281
- <IconAntDesign
282
- name={order?.favorite ? 'heart' : 'hearto'}
283
- color={theme.colors.danger5}
284
- size={16}
285
- />
286
- </TouchableOpacity>
281
+ {!isMessageView && (
282
+ <TouchableOpacity
283
+ onPress={handleChangeFavorite}
284
+ style={{ marginTop: 5 }}
285
+ >
286
+ <IconAntDesign
287
+ name={order?.favorite ? 'heart' : 'hearto'}
288
+ color={theme.colors.danger5}
289
+ size={16}
290
+ />
291
+ </TouchableOpacity>
292
+ )}
287
293
  </ContentFooter>
288
294
  </CardInfoWrapper>
289
295
  </InnerContainer>
@@ -5,7 +5,6 @@ import {
5
5
  useOrder,
6
6
  useUtils,
7
7
  useSession,
8
- useOrderingTheme,
9
8
  SingleProductCard as SingleProductCardController
10
9
  } from 'ordering-components/native';
11
10
  import { useTheme } from 'styled-components/native';
@@ -41,8 +40,7 @@ const SingleProductCardUI = React.memo((props: SingleProductCardParams) => {
41
40
  } = props;
42
41
 
43
42
  const theme = useTheme();
44
- const [orderingTheme] = useOrderingTheme()
45
- const hideAddButton = orderingTheme?.theme?.business_view?.components?.products?.components?.add_to_cart_button?.hidden
43
+ const hideAddButton = theme?.business_view?.components?.products?.components?.add_to_cart_button?.hidden ?? true
46
44
 
47
45
  const fadeAnim = useRef(new Animated.Value(0)).current;
48
46
 
@@ -52,6 +50,7 @@ const SingleProductCardUI = React.memo((props: SingleProductCardParams) => {
52
50
  borderRadius: 7.6,
53
51
  borderColor: theme.colors.border,
54
52
  marginBottom: 28,
53
+ minHeight: 165
55
54
  },
56
55
  titleWrapper: {
57
56
  flexDirection: 'row',
@@ -642,12 +642,20 @@ export interface NoNetworkParams {
642
642
  }
643
643
 
644
644
  export interface PlaceSpotParams {
645
- isOpenPlaceSpot?: boolean,
645
+ isCheckout?: any,
646
+ isInputMode?: any,
646
647
  cart?: any,
648
+ spotNumberDefault?: any,
649
+ vehicleDefault?: any,
650
+ spotNumber?: any,
651
+ setSpotNumber?: any,
652
+ orderTypes?: any,
647
653
  placesState?: any,
648
- handleChangePlace?: any,
649
- getPlacesList?: any,
650
- setOpenPlaceModal?: any
654
+ handleChangePlace? : any,
655
+ spotState?: any,
656
+ vehicle?: any,
657
+ setVehicle?: any,
658
+ handleChangeSpot?: any
651
659
  }
652
660
 
653
661
  export interface PromotionParams {