ordering-ui-react-native 0.15.56 → 0.15.59

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (24) hide show
  1. package/package.json +1 -1
  2. package/src/components/BusinessTypeFilter/index.tsx +4 -1
  3. package/src/pages/BusinessesListing.tsx +1 -1
  4. package/themes/business/src/components/NewOrderNotification/index.tsx +59 -98
  5. package/themes/business/src/components/OrderDetails/OrderContentComponent.tsx +27 -0
  6. package/themes/original/index.tsx +151 -0
  7. package/themes/original/src/components/AddressList/index.tsx +1 -1
  8. package/themes/original/src/components/BusinessController/index.tsx +20 -1
  9. package/themes/original/src/components/BusinessController/styles.tsx +22 -0
  10. package/themes/original/src/components/BusinessFeaturedController/index.tsx +20 -1
  11. package/themes/original/src/components/BusinessFeaturedController/styles.tsx +23 -0
  12. package/themes/original/src/components/BusinessProductsList/index.tsx +104 -18
  13. package/themes/original/src/components/BusinessProductsList/styles.tsx +12 -1
  14. package/themes/original/src/components/BusinessProductsListing/index.tsx +5 -0
  15. package/themes/original/src/components/BusinessesListing/index.tsx +1 -1
  16. package/themes/original/src/components/Home/index.tsx +1 -1
  17. package/themes/original/src/components/PhoneInputNumber/index.tsx +10 -4
  18. package/themes/original/src/components/SignupForm/index.tsx +41 -13
  19. package/themes/original/src/components/UserFormDetails/index.tsx +13 -2
  20. package/themes/original/src/components/UserProfile/index.tsx +1 -1
  21. package/themes/original/src/config/constants.tsx +6 -6
  22. package/themes/original/src/types/index.tsx +6 -1
  23. package/themes/single-business/src/components/AddressList/index.tsx +1 -1
  24. package/themes/single-business/src/components/UserProfile/index.tsx +1 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ordering-ui-react-native",
3
- "version": "0.15.56",
3
+ "version": "0.15.59",
4
4
  "description": "Reusable components made in react native",
5
5
  "main": "src/index.tsx",
6
6
  "author": "ordering.inc",
@@ -1,5 +1,5 @@
1
1
  import React, { useState } from 'react'
2
- import { StyleSheet, View, ScrollView, TouchableOpacity, Dimensions, Platform, PlatformIOSStatic } from 'react-native'
2
+ import { StyleSheet, View, ScrollView, Dimensions, Platform, PlatformIOSStatic, Pressable } from 'react-native'
3
3
  import { Fade, Placeholder, PlaceholderLine } from 'rn-placeholder'
4
4
  import { BusinessTypeFilter as BusinessTypeFilterController, useLanguage } from 'ordering-components/native'
5
5
 
@@ -9,6 +9,7 @@ import { BusinessTypeFilterParams } from '../../types'
9
9
  import { useTheme } from 'styled-components/native'
10
10
  import MaterialIcon from 'react-native-vector-icons/MaterialCommunityIcons';
11
11
  import DeviceInfo from 'react-native-device-info';
12
+ import { TouchableOpacity } from 'react-native-gesture-handler'
12
13
 
13
14
  const windowWidth = Dimensions.get('window').width;
14
15
 
@@ -71,11 +72,13 @@ export const BusinessTypeFilterUI = (props: BusinessTypeFilterParams) => {
71
72
  <OIcon
72
73
  url={item.image}
73
74
  style={styles.logo}
75
+ cover
74
76
  />
75
77
  ) : (
76
78
  <OIcon
77
79
  src={theme.images.categories.all}
78
80
  style={styles.logo}
81
+ cover
79
82
  />
80
83
  )}
81
84
  <OText
@@ -21,7 +21,7 @@ const BusinessesListing = (props: any) => {
21
21
  ...props,
22
22
  isSearchByName: true,
23
23
  isSearchByDescription: true,
24
- propsToFetch: ['id', 'name', 'header', 'logo', 'location', 'schedule', 'open', 'delivery_price', 'distance', 'delivery_time', 'pickup_time', 'reviews', 'featured', 'offers', 'food', 'laundry', 'alcohol', 'groceries', 'slug'],
24
+ propsToFetch: ['id', 'name', 'header', 'logo', 'ribbon', 'location', 'schedule', 'open', 'delivery_price', 'distance', 'delivery_time', 'pickup_time', 'reviews', 'featured', 'offers', 'food', 'laundry', 'alcohol', 'groceries', 'slug'],
25
25
  onBusinessClick: (business: any) => {
26
26
  props.navigation.navigate('Business', { store: store || business.slug, header: business.header, logo: business.logo })
27
27
  }
@@ -1,50 +1,55 @@
1
- import React, { useState, useEffect, useCallback } from 'react'
2
- import { useEvent, useLanguage, useUtils, useSession, useApi, NewOrderNotification as NewOrderNotificationController } from 'ordering-components/native'
1
+ import React, { useState, useEffect } from 'react'
2
+ import moment from 'moment'
3
3
  import { View, Modal, StyleSheet, TouchableOpacity, Dimensions } from 'react-native'
4
- import { OText, OIcon } from '../shared'
5
- import { useTheme } from 'styled-components/native'
4
+ import Sound from 'react-native-sound'
6
5
  import Icon from 'react-native-vector-icons/Feather'
6
+ import { useTheme } from 'styled-components/native'
7
+ import { useEvent, useLanguage, useSession, useApi, NewOrderNotification as NewOrderNotificationController } from 'ordering-components/native'
8
+
9
+ import { OText, OIcon } from '../shared'
7
10
  import { NotificationContainer } from './styles'
8
- import Sound from 'react-native-sound'
9
- import moment from 'moment'
10
11
  import { useLocation } from '../../hooks/useLocation'
11
- import { useFocusEffect } from '@react-navigation/core'
12
+
12
13
  Sound.setCategory('Playback')
13
14
 
14
15
  const windowWidth = Dimensions.get('screen').width
15
16
 
16
- const NewOrderNotificationUI = (props: any) => {
17
+ const NewOrderNotificationUI = () => {
17
18
  const [events] = useEvent()
18
19
  const theme = useTheme()
19
20
  const [, t] = useLanguage()
20
21
  const [{ user, token }] = useSession()
21
22
  const [ordering] = useApi()
22
- const [{ getTimeAgo }] = useUtils()
23
23
  const { getCurrentLocation } = useLocation();
24
- const [modalOpen, setModalOpen] = useState(false)
25
- const [newOrderId, setNewOrderId] = useState(null)
26
- const [messageOrderId, setMessageOrderId] = useState(null)
27
24
  const [soundTimeout, setSoundTimeout] = useState<any>(null)
28
- const [isFocused, setIsFocused] = useState(false)
29
- const [currentChange, setCurrentChange] = useState(1)
25
+ const [currentEvent, setCurrentEvent] = useState<any>(null)
26
+
27
+ const evtList: any = {
28
+ 1: {
29
+ event: 'messages',
30
+ message: t('NEW_MESSAGES_RECEIVED', 'New messages have been received!'),
31
+ message2: t('ORDER_N_UNREAD_MESSAGES', 'Order #_order_id_ has unread messages.').replace('_order_id_', currentEvent?.orderId),
32
+ },
33
+ 2: {
34
+ event: 'order_added',
35
+ message: t('NEW_ORDERS_RECEIVED', 'New orders have been received!'),
36
+ message2: t('ORDER_N_ORDERED', 'Order #_order_id_ has been ordered.').replace('_order_id_', currentEvent?.orderId),
37
+ },
38
+ 3: {
39
+ event: 'order_updated',
40
+ message: t('NEW_ORDERS_UPDATED', 'New orders have been updated!'),
41
+ message2: t('ORDER_N_UPDATED', 'Order #_order_id_ has been updated.').replace('_order_id_', currentEvent?.orderId),
42
+ },
43
+ }
30
44
 
31
- const notificationSound = new Sound(theme.sounds.notification, error => {
32
- if (error) {
33
- console.log('failed to load the sound', error);
34
- return
35
- }
36
- console.log('loaded successfully');
37
- });
45
+ const notificationSound = new Sound(theme.sounds.notification, (e) => { console.log(e) });
38
46
 
39
47
  const handlePlayNotificationSound = () => {
40
48
  let times = 0
41
49
  const _timeout = setInterval(function () {
42
50
  notificationSound.play(success => {
43
51
  if (success) {
44
- console.log('successfully finished playing');
45
52
  times = times + 1
46
- } else {
47
- console.log('playback failed due to audio decoding errors');
48
53
  }
49
54
  })
50
55
  setSoundTimeout(_timeout)
@@ -57,39 +62,11 @@ const NewOrderNotificationUI = (props: any) => {
57
62
 
58
63
  const handleCloseModal = () => {
59
64
  clearInterval(soundTimeout)
60
- setModalOpen(false)
61
- setNewOrderId(null)
62
- setMessageOrderId(null)
63
- }
64
-
65
- const handleNotification = (order: any) => {
66
- setModalOpen(true)
67
- clearInterval(soundTimeout)
68
- setCurrentChange(1)
69
- handlePlayNotificationSound()
70
- setNewOrderId(order.id)
71
- }
72
-
73
- const handleMessageNotification = (message: any) => {
74
- const { order_id: orderId } = message;
75
- if (!modalOpen) setModalOpen(true)
76
- clearInterval(soundTimeout)
77
- setCurrentChange(2)
78
- handlePlayNotificationSound()
79
- setMessageOrderId(orderId)
65
+ setCurrentEvent({ evt: null })
80
66
  }
81
67
 
82
- useEffect(() => {
83
- events.on('order_added_noification', handleNotification)
84
- events.on('message_added_noification', handleMessageNotification)
85
- return () => {
86
- events.off('order_added_noification', handleNotification)
87
- events.off('message_added_noification', handleMessageNotification)
88
- }
89
- }, [])
90
-
91
- const handleUpdateOrder = useCallback(async (order: any) => {
92
- if (order?.driver) {
68
+ const handleEventNotification = async (evtType: number, value: any) => {
69
+ if (value?.driver) {
93
70
  const location = await getCurrentLocation()
94
71
  await fetch(`${ordering.root}/users/${user.id}/locations`, {
95
72
  method: 'POST',
@@ -98,25 +75,32 @@ const NewOrderNotificationUI = (props: any) => {
98
75
  }),
99
76
  headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${token}` }
100
77
  })
101
- const assignedTimeDiff = moment.utc(order?.driver?.last_order_assigned_at).local().fromNow()
78
+ const assignedTimeDiff = moment.utc(value?.driver?.last_order_assigned_at).local().fromNow()
102
79
  if (assignedTimeDiff === 'a few seconds ago') {
103
- clearInterval(soundTimeout)
104
80
  handlePlayNotificationSound()
105
- setNewOrderId(order.id)
106
- if(isFocused){
107
- setModalOpen(true)
108
- }
81
+ clearInterval(soundTimeout)
82
+ setCurrentEvent({ evt: 2, orderId: value?.id })
109
83
  }
84
+ return
110
85
  }
111
- }, [newOrderId, notificationSound, soundTimeout])
86
+ handlePlayNotificationSound()
87
+ clearInterval(soundTimeout)
88
+ setCurrentEvent({
89
+ evt: evtType,
90
+ orderId: evtList[evtType].event === 'messages' ? value?.order_id : value?.id
91
+ })
92
+ }
112
93
 
113
94
  useEffect(() => {
114
- if (user?.level !== 4) return
115
- events.on('order_updated_noification', handleUpdateOrder)
95
+ events.on('message_added_notification', (o: any) => handleEventNotification(1, o))
96
+ events.on('order_added_notification', (o: any) => handleEventNotification(2, o))
97
+ events.on('order_updated_notification', (o: any) => handleEventNotification(3, o))
116
98
  return () => {
117
- events.off('order_updated_noification', handleUpdateOrder)
99
+ events.off('message_added_notification', (o: any) => handleEventNotification(1, o))
100
+ events.off('order_added_notification', (o: any) => handleEventNotification(2, o))
101
+ events.off('order_updated_notification', (o: any) => handleEventNotification(3, o))
118
102
  }
119
- }, [handleUpdateOrder, user])
103
+ }, [])
120
104
 
121
105
  useEffect(() => {
122
106
  notificationSound.setVolume(1);
@@ -125,21 +109,12 @@ const NewOrderNotificationUI = (props: any) => {
125
109
  }
126
110
  }, [])
127
111
 
128
- useFocusEffect(
129
- useCallback(() => {
130
- setIsFocused(true)
131
- return () => {
132
- setIsFocused(false)
133
- }
134
- }, [])
135
- )
136
-
137
112
  return (
138
113
  <>
139
114
  <Modal
140
115
  animationType='slide'
141
116
  transparent={true}
142
- visible={modalOpen}
117
+ visible={!!currentEvent?.orderId}
143
118
  >
144
119
  <NotificationContainer>
145
120
  <View style={styles.modalView}>
@@ -147,40 +122,26 @@ const NewOrderNotificationUI = (props: any) => {
147
122
  style={styles.wrapperIcon}
148
123
  onPress={() => handleCloseModal()}
149
124
  >
150
- <Icon
151
- name="x"
152
- size={30}
153
- />
125
+ <Icon name="x" size={30} />
154
126
  </TouchableOpacity>
155
127
  <OText
156
128
  size={18}
157
129
  color={theme.colors.textGray}
158
130
  weight={600}
159
131
  >
160
- {currentChange === 1 ? t('NEW_ORDRES_RECEIVED', 'New orders have been received!') : t('NEW_MESSAGES_RECEIVED', 'New messages have been received!')}
132
+ {evtList[currentEvent?.evt]?.message}
161
133
  </OText>
162
134
  <OIcon
163
135
  src={theme.images.general.newOrder}
164
136
  width={250}
165
137
  height={200}
166
138
  />
167
- {newOrderId !== null && (
168
- <OText
169
- color={theme.colors.textGray}
170
- mBottom={15}
171
- >
172
- {t('ORDER_N_ORDERED', 'Order #_order_id_ has been ordered.').replace('_order_id_', newOrderId)}
173
- </OText>
174
- )}
175
-
176
- {messageOrderId !== null && (
177
- <OText
178
- color={theme.colors.textGray}
179
- mBottom={15}
180
- >
181
- {t('ORDER_N_UNREAD_MESSAGES', 'Order #_order_id_ has unread messages.').replace('_order_id_', messageOrderId)}
182
- </OText>
183
- )}
139
+ <OText
140
+ color={theme.colors.textGray}
141
+ mBottom={15}
142
+ >
143
+ {evtList[currentEvent?.evt]?.message2}
144
+ </OText>
184
145
  </View>
185
146
  </NotificationContainer>
186
147
  </Modal>
@@ -95,6 +95,33 @@ export const OrderContentComponent = (props: OrderContent) => {
95
95
  {isOrderGroup && (
96
96
  <OText size={18}>{t('ORDER', 'Order')} #{isOrderGroup ? order?.order_group_id : order?.id}</OText>
97
97
  )}
98
+
99
+ {order?.metafields?.length > 0 && (
100
+ <OrderBusiness>
101
+ <OText style={{ marginBottom: 5 }} size={16} weight="600">
102
+ {t('CUSTOM_FIELDS', 'Custom fields')}
103
+ </OText>
104
+
105
+ {order.metafields.map((field: any) => (
106
+ <View
107
+ key={field.id}
108
+ style={{
109
+ width: '100%',
110
+ flexDirection: 'row',
111
+ marginBottom: 5
112
+ }}
113
+ >
114
+ <OText style={{ width: '50%' }}>
115
+ {field.key}
116
+ </OText>
117
+ <OText style={{ width: '45%', textAlign: 'right' }}>
118
+ {field.value}
119
+ </OText>
120
+ </View>
121
+ ))}
122
+ </OrderBusiness>
123
+ )}
124
+
98
125
  <OrderBusiness>
99
126
  <OText style={{ marginBottom: 5 }} size={16} weight="600">
100
127
  {t('BUSINESS_DETAILS', 'Business details')}
@@ -50,6 +50,74 @@ import { BusinessTypeFilter } from './src/components/BusinessTypeFilter';
50
50
  import { BusinessController } from './src/components/BusinessController';
51
51
  import { BusinessFeaturedController } from './src/components/BusinessFeaturedController';
52
52
  import { HighestRatedBusinesses } from './src/components/HighestRatedBusinesses';
53
+ import { PaymentOptions } from './src/components/PaymentOptions';
54
+ import { DriverTips } from './src/components/DriverTips';
55
+ import { UserDetails } from './src/components/UserDetails';
56
+ import { OrderSummary } from './src/components/OrderSummary';
57
+ import { CartStoresListing } from './src/components/CartStoresListing';
58
+ import { PaymentOptionsWebView } from '../../src/components/PaymentOptionsWebView';
59
+ import { GoogleMap } from './src/components/GoogleMap';
60
+ import { SingleProductCard } from './src/components/SingleProductCard';
61
+ import { UpsellingRedirect } from './src/components/BusinessProductsListing/UpsellingRedirect';
62
+ import { ProductItemAccordion } from './src/components/ProductItemAccordion';
63
+ import { BusinessItemAccordion } from './src/components/BusinessItemAccordion';
64
+ import { CouponControl } from './src/components/CouponControl';
65
+ import { TaxInformation } from './src/components/TaxInformation';
66
+ import { PlaceSpot } from './src/components/PlaceSpot';
67
+ import { Cart } from './src/components/Cart';
68
+ import { LanguageSelector } from './src/components/LanguageSelector';
69
+ import { PhoneInputNumber } from './src/components/PhoneInputNumber'
70
+ import { FacebookLogin } from './src/components/FacebookLogin';
71
+ import { VerifyPhone } from './src/components/VerifyPhone';
72
+ import { GoogleLogin } from './src/components/GoogleLogin';
73
+ import { PreviousOrders } from './src/components/PreviousOrders';
74
+ import { PaymentOptionCash } from './src/components/PaymentOptionCash';
75
+ import { StripeElementsForm } from './src/components/StripeElementsForm';
76
+ import { StripeCardsList } from './src/components/StripeCardsList';
77
+ import { ProductIngredient } from './src/components/ProductIngredient';
78
+ import { ProductOption } from './src/components/ProductOption';
79
+ import { ProductOptionSubOption } from './src/components/ProductOptionSubOption';
80
+ import { SingleProductReview } from './src/components/SingleProductReview';
81
+ import { LogoutButton } from './src/components/LogoutButton';
82
+ import { UserFormDetailsUI } from './src/components/UserFormDetails';
83
+ import { WalletTransactionItem } from './src/components/WalletTransactionItem';
84
+
85
+ import { USER_TYPE, ORDER_TYPES } from './src/config/constants'
86
+
87
+ import { OSBill, OSTable, OSCoupon, OSTotal, OSRow } from './src/components/OrderSummary/styles';
88
+
89
+ import { FormInput, FormSide, ButtonsWrapper, LoginWith, OTab, OTabs } from './src/components/LoginForm/styles';
90
+ import { OSItem, OSItemContent, OSItemActions} from './src/components/PaymentOptionStripe/styles';
91
+
92
+ import Alert from './src/providers/AlertProvider'
93
+
94
+ import {
95
+ LoginParams,
96
+ ProfileParams,
97
+ AddressListParams,
98
+ AddressFormParams,
99
+ SignupParams,
100
+ PhoneInputParams,
101
+ LanguageSelectorParams,
102
+ BusinessesListingParams,
103
+ HighestRatedBusinessesParams,
104
+ BusinessTypeFilterParams,
105
+ BusinessControllerParams,
106
+ BusinessProductsListingParams,
107
+ BusinessBasicInformationParams,
108
+ BusinessProductsCategoriesParams,
109
+ BusinessProductsListParams,
110
+ SingleProductCardParams,
111
+ BusinessInformationParams,
112
+ BusinessReviewsParams,
113
+ SearchBarParams,
114
+ NotFoundSourceParams,
115
+ OrdersOptionParams,
116
+ ActiveOrdersParams,
117
+ PreviousOrdersParams,
118
+ OrderDetailsParams,
119
+ ReviewDriverParams
120
+ } from './src/types';
53
121
 
54
122
  import { Toast } from './src/components/shared/OToast';
55
123
  import {
@@ -71,6 +139,8 @@ import {
71
139
 
72
140
  import { Container } from './src/layouts/Container';
73
141
  import { SafeAreaContainer } from './src/layouts/SafeAreaContainer';
142
+ import { FloatingBottomContainer } from './src/layouts/FloatingBottomContainer';
143
+
74
144
  import {
75
145
  _retrieveStoreData,
76
146
  _setStoreData,
@@ -130,6 +200,86 @@ export {
130
200
  BusinessController,
131
201
  BusinessFeaturedController,
132
202
  HighestRatedBusinesses,
203
+ PaymentOptions,
204
+ DriverTips,
205
+ UserDetails,
206
+ OrderSummary,
207
+ CartStoresListing,
208
+ PaymentOptionsWebView,
209
+ GoogleMap,
210
+ SingleProductCard,
211
+ UpsellingRedirect,
212
+ ProductItemAccordion,
213
+ BusinessItemAccordion,
214
+ CouponControl,
215
+ TaxInformation,
216
+ PlaceSpot,
217
+ Cart,
218
+ LanguageSelector,
219
+ PhoneInputNumber,
220
+ FacebookLogin,
221
+ VerifyPhone,
222
+ GoogleLogin,
223
+ PreviousOrders,
224
+ PaymentOptionCash,
225
+ StripeElementsForm,
226
+ StripeCardsList,
227
+ ProductIngredient,
228
+ ProductOption,
229
+ ProductOptionSubOption,
230
+ SingleProductReview,
231
+ LogoutButton,
232
+ UserFormDetailsUI,
233
+ WalletTransactionItem,
234
+
235
+ ORDER_TYPES,
236
+ USER_TYPE,
237
+
238
+ OSBill,
239
+ OSTable,
240
+ OSCoupon,
241
+ OSTotal,
242
+ OSRow,
243
+
244
+ FormInput,
245
+ FormSide,
246
+ ButtonsWrapper,
247
+ LoginWith,
248
+ OTab,
249
+ OTabs,
250
+
251
+ OSItem,
252
+ OSItemContent,
253
+ OSItemActions,
254
+
255
+ Alert,
256
+
257
+ //Types
258
+ LoginParams,
259
+ ProfileParams,
260
+ AddressListParams,
261
+ AddressFormParams,
262
+ SignupParams,
263
+ PhoneInputParams,
264
+ LanguageSelectorParams,
265
+ BusinessesListingParams,
266
+ HighestRatedBusinessesParams,
267
+ BusinessTypeFilterParams,
268
+ BusinessControllerParams,
269
+ BusinessProductsListingParams,
270
+ BusinessBasicInformationParams,
271
+ BusinessProductsCategoriesParams,
272
+ BusinessProductsListParams,
273
+ SingleProductCardParams,
274
+ BusinessInformationParams,
275
+ BusinessReviewsParams,
276
+ SearchBarParams,
277
+ NotFoundSourceParams,
278
+ OrdersOptionParams,
279
+ ActiveOrdersParams,
280
+ PreviousOrdersParams,
281
+ OrderDetailsParams,
282
+ ReviewDriverParams,
133
283
 
134
284
  // OComponents
135
285
  Toast,
@@ -151,6 +301,7 @@ export {
151
301
  // layout
152
302
  Container,
153
303
  SafeAreaContainer,
304
+ FloatingBottomContainer,
154
305
  NavBar,
155
306
 
156
307
  // utils
@@ -140,7 +140,7 @@ const AddressListUI = (props: AddressListParams) => {
140
140
  <AddressListContainer>
141
141
  {isProfile && (
142
142
  <NavBar
143
- title={t('MY_SAVED_PLACES', 'My saved places')}
143
+ title={t('SAVED_PLACES', 'My saved places')}
144
144
  titleAlign={'center'}
145
145
  onActionLeft={() => goToBack()}
146
146
  showCall={false}
@@ -9,7 +9,7 @@ import {
9
9
  import { OIcon, OText } from '../shared';
10
10
  import { StyleSheet, View } from 'react-native';
11
11
  import { BusinessControllerParams } from '../../types';
12
- import { convertHoursToMinutes } from '../../utils';
12
+ import { convertHoursToMinutes, shape } from '../../utils';
13
13
  import {
14
14
  Card,
15
15
  BusinessHero,
@@ -20,6 +20,7 @@ import {
20
20
  BusinessState,
21
21
  BusinessLogo,
22
22
  Reviews,
23
+ RibbonBox
23
24
  } from './styles';
24
25
  import { useTheme } from 'styled-components/native';
25
26
  import FontAwesomeIcon from 'react-native-vector-icons/FontAwesome5';
@@ -121,6 +122,24 @@ export const BusinessControllerUI = (props: BusinessControllerParams) => {
121
122
 
122
123
  return (
123
124
  <Card activeOpacity={1} onPress={() => handleBusinessClick(business)} style={style}>
125
+ {business?.ribbon?.enabled && (
126
+ <RibbonBox
127
+ bgColor={business?.ribbon?.color}
128
+ isRoundRect={business?.ribbon?.shape === shape?.rectangleRound}
129
+ isCapsule={business?.ribbon?.shape === shape?.capsuleShape}
130
+ >
131
+ <OText
132
+ size={10}
133
+ weight={'400'}
134
+ color={theme.colors.white}
135
+ numberOfLines={2}
136
+ ellipsizeMode='tail'
137
+ lineHeight={13}
138
+ >
139
+ {business?.ribbon?.text}
140
+ </OText>
141
+ </RibbonBox>
142
+ )}
124
143
  <BusinessHero>
125
144
  <FastImage
126
145
  style={{ height: 120 }}
@@ -53,3 +53,25 @@ export const Reviews = styled.View`
53
53
  flex-direction: row;
54
54
  align-items: center;
55
55
  `
56
+
57
+ export const RibbonBox = styled.View`
58
+ position: absolute;
59
+ z-index: 1;
60
+ top: -4px;
61
+ right: -4px;
62
+ background-color: ${(props: any) => props.theme.colors.primary};
63
+ padding: 1px 8px;
64
+ max-width: 180px;
65
+
66
+ ${(props: any) => props.bgColor && css`
67
+ background-color: ${props.bgColor};
68
+ `}
69
+
70
+ ${(props: any) => props.isRoundRect && css`
71
+ border-radius: 7.6px;
72
+ `}
73
+
74
+ ${(props: any) => props.isCapsule && css`
75
+ border-radius: 50px;
76
+ `}
77
+ `
@@ -9,7 +9,7 @@ import { useTheme } from 'styled-components/native';
9
9
  import { OIcon, OText } from '../shared';
10
10
  import { StyleSheet, useWindowDimensions, View } from 'react-native';
11
11
  import { BusinessControllerParams } from '../../types';
12
- import { convertHoursToMinutes } from '../../utils';
12
+ import { convertHoursToMinutes, shape } from '../../utils';
13
13
  import {
14
14
  Card,
15
15
  BusinessHero,
@@ -20,6 +20,7 @@ import {
20
20
  BusinessState,
21
21
  BusinessLogo,
22
22
  Reviews,
23
+ RibbonBox
23
24
  } from './styles';
24
25
 
25
26
  export const BusinessFeaturedCtrlUI = (props: BusinessControllerParams) => {
@@ -97,6 +98,24 @@ export const BusinessFeaturedCtrlUI = (props: BusinessControllerParams) => {
97
98
 
98
99
  return (
99
100
  <Card activeOpacity={1} onPress={() => handleClick(business)}>
101
+ {business?.ribbon?.enabled && (
102
+ <RibbonBox
103
+ bgColor={business?.ribbon?.color}
104
+ isRoundRect={business?.ribbon?.shape === shape?.rectangleRound}
105
+ isCapsule={business?.ribbon?.shape === shape?.capsuleShape}
106
+ >
107
+ <OText
108
+ size={10}
109
+ weight={'400'}
110
+ color={theme.colors.white}
111
+ numberOfLines={2}
112
+ ellipsizeMode='tail'
113
+ lineHeight={13}
114
+ >
115
+ {business?.ribbon?.text}
116
+ </OText>
117
+ </RibbonBox>
118
+ )}
100
119
  <BusinessHero>
101
120
  <BusinessLogo>
102
121
  <OIcon
@@ -4,6 +4,7 @@ export const Card = styled.TouchableOpacity`
4
4
  margin-vertical: 4px;
5
5
  height: 60px;
6
6
  overflow: hidden;
7
+ position: relative;
7
8
  `;
8
9
 
9
10
  export const BusinessHero = styled.View`
@@ -48,3 +49,25 @@ export const BusinessLogo = styled.View`
48
49
  export const Reviews = styled.View`
49
50
  flex-direction: row;
50
51
  `
52
+
53
+ export const RibbonBox = styled.View`
54
+ position: absolute;
55
+ z-index: 1;
56
+ top: 0px;
57
+ right: 5px;
58
+ background-color: ${(props: any) => props.theme.colors.primary};
59
+ padding: 1px 8px;
60
+ max-width: 160px;
61
+
62
+ ${(props: any) => props.bgColor && css`
63
+ background-color: ${props.bgColor};
64
+ `}
65
+
66
+ ${(props: any) => props.isRoundRect && css`
67
+ border-radius: 7.6px;
68
+ `}
69
+
70
+ ${(props: any) => props.isCapsule && css`
71
+ border-radius: 50px;
72
+ `}
73
+ `
@@ -4,7 +4,7 @@ import { SingleProductCard } from '../SingleProductCard';
4
4
  import { NotFoundSource } from '../NotFoundSource';
5
5
  import { BusinessProductsListParams } from '../../types';
6
6
  import { OButton, OIcon, OModal, OText } from '../shared';
7
- import { ProductsContainer, ErrorMessage, WrapperNotFound, RibbonBox } from './styles';
7
+ import { ProductsContainer, ErrorMessage, WrapperNotFound, RibbonBox, SubCategoriesContainer, ContainerButton, HeaderWrapper } from './styles';
8
8
  import { Fade, Placeholder, PlaceholderLine } from 'rn-placeholder';
9
9
  import { View, ScrollView } from 'react-native';
10
10
  import { StyleSheet } from 'react-native';
@@ -28,7 +28,11 @@ const BusinessProductsListUI = (props: BusinessProductsListParams) => {
28
28
  handleCancelSearch,
29
29
  categoriesLayout,
30
30
  setCategoriesLayout,
31
- currentCart
31
+ currentCart,
32
+ setSubcategoriesSelected,
33
+ subcategoriesSelected,
34
+ onClickCategory,
35
+ lazyLoadProductsRecommended
32
36
  } = props;
33
37
 
34
38
  const [, t] = useLanguage();
@@ -44,20 +48,85 @@ const BusinessProductsListUI = (props: BusinessProductsListParams) => {
44
48
  setCategoriesLayout(_categoriesLayout)
45
49
  }
46
50
 
51
+ const onClickSubcategory = (subCategory : any, parentCategory : any) => {
52
+ if (parentCategory && lazyLoadProductsRecommended) {
53
+ onClickCategory(parentCategory)
54
+ }
55
+ if (!subCategory) {
56
+ setSubcategoriesSelected?.(subcategoriesSelected.filter((_subcategory : any) => _subcategory?.parent_category_id !== parentCategory?.id))
57
+ return
58
+ }
59
+ const categoryFounded = subcategoriesSelected.find((_subcategory : any) => subCategory?.id === _subcategory?.id)
60
+ if (categoryFounded) {
61
+ setSubcategoriesSelected?.(subcategoriesSelected.filter((_subcategory : any) => subCategory?.id !== _subcategory?.id))
62
+ } else {
63
+ setSubcategoriesSelected?.([...subcategoriesSelected, subCategory])
64
+ }
65
+ }
66
+
67
+ const SubcategoriesComponent = ({ category } : any) => {
68
+ const allsubcategorySelected = !subcategoriesSelected?.some((subcategory : any) => category?.id === subcategory?.parent_category_id)
69
+
70
+ return (
71
+ <SubCategoriesContainer>
72
+ <ContainerButton
73
+ isSelected={allsubcategorySelected}
74
+ >
75
+ <OButton
76
+ onClick={() => onClickSubcategory(null, category)}
77
+ bgColor={allsubcategorySelected ? theme.colors.primary : theme.colors.backgroundGray}
78
+ text={`${t('ALL', 'All')} ${allsubcategorySelected ? 'X' : ''}`}
79
+ style={bpStyles.categoryButtonStyle}
80
+ textStyle={{ color: allsubcategorySelected ? theme.colors.white : theme.colors.textNormal, fontSize: 12 }}
81
+ />
82
+ </ContainerButton>
83
+ {category?.subcategories?.map((subcategory : any) => {
84
+ const isSubcategorySelected = subcategoriesSelected?.find((_subcategory : any) => _subcategory?.id === subcategory?.id)
85
+ return (
86
+ <ContainerButton
87
+ key={subcategory?.id}
88
+ isSelected={isSubcategorySelected}
89
+ >
90
+ <OButton
91
+ onClick={() => onClickSubcategory(subcategory, category)}
92
+ bgColor={isSubcategorySelected ? theme.colors.primary : theme.colors.backgroundGray}
93
+ text={`${subcategory?.name} ${isSubcategorySelected ? 'X' : ''}`}
94
+ style={bpStyles.categoryButtonStyle}
95
+ textStyle={{ color: isSubcategorySelected ? theme.colors.white : theme.colors.textNormal, fontSize: 12 }}
96
+ />
97
+ </ContainerButton>
98
+ )
99
+ }
100
+ )}
101
+ </SubCategoriesContainer>
102
+ )
103
+ }
104
+
105
+
47
106
  return (
48
107
  <ProductsContainer renderToHardwareTextureAndroid={categoryState.loading || isBusinessLoading}>
108
+ <HeaderWrapper>
109
+ {category?.subcategories?.length > 0 && (
110
+ <SubcategoriesComponent category={category} />
111
+ )}
112
+ </HeaderWrapper>
49
113
  {category.id &&
50
- categoryState.products?.sort((a: any, b: any) => a.rank - b.rank).map((product: any) => (
51
- <SingleProductCard
52
- key={'prod_' + product.id}
53
- isSoldOut={product.inventoried && !product.quantity}
54
- product={product}
55
- businessId={businessId}
56
- onProductClick={() => onProductClick(product)}
57
- productAddedToCartLength={currentCart?.products?.reduce((productsLength: number, Cproduct: any) => { return productsLength + (Cproduct?.id === product?.id ? Cproduct?.quantity : 0) }, 0)}
58
- />
59
- ))}
60
-
114
+ categoryState.products
115
+ ?.filter((product : any) =>
116
+ !subcategoriesSelected.find((subcategory : any) => subcategory?.parent_category_id === category?.id) ||
117
+ subcategoriesSelected?.some((subcategory : any) => subcategory.id === product?.category_id)
118
+ ?.sort((a: any, b: any) => a.rank - b.rank)
119
+ ?.map((product: any) => (
120
+ <SingleProductCard
121
+ key={'prod_' + product.id}
122
+ isSoldOut={product.inventoried && !product.quantity}
123
+ product={product}
124
+ businessId={businessId}
125
+ onProductClick={() => onProductClick(product)}
126
+ productAddedToCartLength={currentCart?.products?.reduce((productsLength: number, Cproduct: any) => { return productsLength + (Cproduct?.id === product?.id ? Cproduct?.quantity : 0) }, 0)}
127
+ />
128
+ ))
129
+ )}
61
130
  {!category.id &&
62
131
  featured &&
63
132
  categoryState?.products?.find((product: any) => product.featured) && (
@@ -72,7 +141,7 @@ const BusinessProductsListUI = (props: BusinessProductsListParams) => {
72
141
  (product: any, i: any) =>
73
142
  product.featured && (
74
143
  <SingleProductCard
75
- key={i}
144
+ key={'feat_' + product.id}
76
145
  isSoldOut={product.inventoried && !product.quantity}
77
146
  product={product}
78
147
  businessId={businessId}
@@ -86,9 +155,14 @@ const BusinessProductsListUI = (props: BusinessProductsListParams) => {
86
155
  )}
87
156
 
88
157
  {!category?.id && categories.filter(category => category?.id !== null).map((category, i, _categories) => {
89
- const products = !isUseParentCategory
90
- ? categoryState?.products?.filter((product: any) => product?.category_id === category?.id) ?? []
91
- : categoryState?.products?.filter((product: any) => category?.children?.some((cat: any) => cat.category_id === product?.category_id)) ?? []
158
+ const _products = !isUseParentCategory
159
+ ? categoryState?.products?.filter((product : any) => product?.category_id === category?.id) ?? []
160
+ : categoryState?.products?.filter((product : any) => category?.children?.some((cat : any) => cat.category_id === product?.category_id)) ?? []
161
+ const products = subcategoriesSelected?.length > 0
162
+ ? _products?.filter((product : any) =>
163
+ !subcategoriesSelected.find((subcategory : any) => subcategory?.parent_category_id === category?.id) ||
164
+ subcategoriesSelected?.some((subcategory : any) => subcategory.id === product?.category_id))
165
+ : _products
92
166
 
93
167
  const shortCategoryDescription = category?.description?.length > 80 ? `${category?.description?.substring(0, 80)}...` : category?.description
94
168
 
@@ -132,7 +206,7 @@ const BusinessProductsListUI = (props: BusinessProductsListParams) => {
132
206
  </View>
133
207
  {!!category?.description && (
134
208
  <View style={{ position: 'relative' }}>
135
- <OText size={12} weight={'500'} mBottom={5}>
209
+ <OText size={12} weight={'500'} mBottom={10} color='#909BA9'>
136
210
  {shortCategoryDescription}
137
211
  {category?.description?.length > 80 && (
138
212
  <OButton
@@ -150,6 +224,9 @@ const BusinessProductsListUI = (props: BusinessProductsListParams) => {
150
224
  />
151
225
  )}
152
226
  </OText>
227
+ {category?.subcategories?.length > 0 && (
228
+ <SubcategoriesComponent category={category} />
229
+ )}
153
230
  </View>
154
231
  )}
155
232
  <>
@@ -265,6 +342,15 @@ const bpStyles = StyleSheet.create({
265
342
  shadowRadius: 1,
266
343
  marginEnd: 13,
267
344
  },
345
+ categoryButtonStyle: {
346
+ borderWidth: 0,
347
+ marginLeft: 5,
348
+ marginRight: 5,
349
+ marginBottom: 10,
350
+ height: 35,
351
+ paddingLeft: 3,
352
+ paddingRight: 3,
353
+ }
268
354
  });
269
355
 
270
356
  export const BusinessProductsList = (props: BusinessProductsListParams) => {
@@ -30,4 +30,15 @@ export const RibbonBox = styled.View`
30
30
  ${(props: any) => props.isCapsule && css`
31
31
  border-radius: 50px;
32
32
  `}
33
- `
33
+ `
34
+
35
+ export const SubCategoriesContainer = styled.View`
36
+ flex-direction: row;
37
+ flex-wrap: wrap;
38
+ margin-bottom: 10px;
39
+ `
40
+
41
+ export const ContainerButton = styled.View`
42
+ `
43
+
44
+ export const HeaderWrapper = styled.View``
@@ -92,6 +92,7 @@ const BusinessProductsListingUI = (props: BusinessProductsListingParams) => {
92
92
  const [categoriesLayout, setCategoriesLayout] = useState<any>({})
93
93
  const [productListLayout, setProductListLayout] = useState<any>(null)
94
94
  const [isCategoryClicked, setCategoryClicked] = useState(false)
95
+ const [subcategoriesSelected, setSubcategoriesSelected] = useState([])
95
96
 
96
97
  const currentCart: any = Object.values(orderState.carts).find((cart: any) => cart?.business?.slug === business?.slug) ?? {}
97
98
 
@@ -254,6 +255,7 @@ const BusinessProductsListingUI = (props: BusinessProductsListingParams) => {
254
255
  lazyLoadProductsRecommended={business?.lazy_load_products_recommended}
255
256
  setSelectedCategoryId={setSelectedCategoryId}
256
257
  setCategoryClicked={setCategoryClicked}
258
+
257
259
  />
258
260
  )}
259
261
  </>
@@ -281,8 +283,11 @@ const BusinessProductsListingUI = (props: BusinessProductsListingParams) => {
281
283
  errorQuantityProducts={errorQuantityProducts}
282
284
  handleCancelSearch={handleCancel}
283
285
  categoriesLayout={categoriesLayout}
286
+ subcategoriesSelected={subcategoriesSelected}
287
+ lazyLoadProductsRecommended={business?.lazy_load_products_recommended}
284
288
  setCategoriesLayout={setCategoriesLayout}
285
289
  currentCart={currentCart}
290
+ setSubcategoriesSelected={setSubcategoriesSelected}
286
291
  />
287
292
  </WrapContent>
288
293
  </>
@@ -317,7 +317,7 @@ const BusinessesListingUI = (props: BusinessesListingParams) => {
317
317
  {
318
318
  !businessId && !props.franchiseId && featuredBusiness && featuredBusiness.length > 0 && (
319
319
  <FeaturedWrapper>
320
- <OText size={16} style={{ marginLeft: 40 }} weight={Platform.OS === 'ios' ? '600' : 'bold'}>{t('FEATURED_BUSINESS', 'Featured business')}</OText>
320
+ <OText size={16} style={{ marginLeft: 40 }} weight={Platform.OS === 'ios' ? '600' : 'bold'}>{t('BUSINESS_FEATURE', 'Featured business')}</OText>
321
321
  <ScrollView
322
322
  showsHorizontalScrollIndicator={false}
323
323
  nestedScrollEnabled
@@ -36,7 +36,7 @@ export const Home = (props: any) => {
36
36
  {t('WELCOME', 'Welcome!')}
37
37
  </OText>
38
38
  <OText color={theme.colors.white} size={14} style={{ marginBottom: 46 }}>
39
- {t('LETS_START_ORDER', "Let's start to order now")}
39
+ {t('SUBTITLE_HOME', "Let's start to order now")}
40
40
  </OText>
41
41
  <OButton
42
42
  text={t('LOGIN_NOW', 'Login now')}
@@ -22,8 +22,9 @@ export const PhoneInputNumber = (props: PhoneInputParams) => {
22
22
  textStyle,
23
23
  flagStyle,
24
24
  noDropIcon,
25
- isDisabled,
26
- isStartValidation
25
+ isDisabled,
26
+ isStartValidation,
27
+ changeCountry
27
28
  } = props
28
29
 
29
30
  const theme = useTheme();
@@ -106,11 +107,16 @@ export const PhoneInputNumber = (props: PhoneInputParams) => {
106
107
  )}
107
108
  <PhoneInput
108
109
  ref={phoneInput}
109
- disabled={isDisabled}
110
+ disabled={isDisabled}
110
111
  defaultValue={userphoneNumber || defaultValue}
111
- defaultCode={defaultCode ? transformCountryCode(defaultCode) : configs?.default_country_code?.value}
112
+ defaultCode={defaultCode ?
113
+ !isNaN(defaultCode)
114
+ ? transformCountryCode(defaultCode)
115
+ : defaultCode
116
+ : configs?.default_country_code?.value}
112
117
  onChangeFormattedText={(text: string) => handleChangeNumber(text)}
113
118
  withDarkTheme
119
+ onChangeCountry={(country) => changeCountry?.(country)}
114
120
  countryPickerProps={{ withAlphaFilter: true }}
115
121
  textContainerStyle={{ ...style.input, ...inputStyle ? inputStyle : {} }}
116
122
  textInputStyle={textStyle}
@@ -119,6 +119,7 @@ const SignupFormUI = (props: SignupParams) => {
119
119
  phone: {
120
120
  country_phone_code: null,
121
121
  cellphone: null,
122
+ country_code: null
122
123
  },
123
124
  });
124
125
  const [recaptchaConfig, setRecaptchaConfig] = useState<any>({})
@@ -133,7 +134,7 @@ const SignupFormUI = (props: SignupParams) => {
133
134
  const passwordRef = useRef<any>(null);
134
135
  const recaptchaRef = useRef<any>({});
135
136
 
136
- const showInputPhoneNumber = (validationFields?.fields?.checkout?.cellphone?.enabled ?? false) || configs?.verification_phone_required?.value === '1'
137
+ const showInputPhoneNumber = (validationFields?.fields?.checkout?.cellphone?.enabled ?? false) || configs?.verification_phone_required?.value === '1'
137
138
 
138
139
  const handleRefs = (ref: any, code: string) => {
139
140
  switch (code) {
@@ -216,8 +217,8 @@ const SignupFormUI = (props: SignupParams) => {
216
217
  !phoneInputData.phone.country_phone_code &&
217
218
  !phoneInputData.phone.cellphone &&
218
219
  ((validationFields?.fields?.checkout?.cellphone?.enabled &&
219
- validationFields?.fields?.checkout?.cellphone?.required) ||
220
- configs?.verification_phone_required?.value === '1')
220
+ validationFields?.fields?.checkout?.cellphone?.required) ||
221
+ configs?.verification_phone_required?.value === '1')
221
222
  ) {
222
223
  showToast(
223
224
  ToastType.Error,
@@ -232,7 +233,8 @@ const SignupFormUI = (props: SignupParams) => {
232
233
  handleButtonSignupClick &&
233
234
  handleButtonSignupClick({
234
235
  ...values,
235
- ...((phoneInputData.phone.cellphone !== null && phoneInputData.phone.country_phone_code !== null) && {...phoneInputData.phone}),
236
+ ...((phoneInputData.phone.cellphone !== null && phoneInputData.phone.country_phone_code !== null) && { ...phoneInputData.phone }),
237
+ country_code: phoneInputData.phone.country_code
236
238
  });
237
239
  if (
238
240
  !formState.loading &&
@@ -295,7 +297,7 @@ const SignupFormUI = (props: SignupParams) => {
295
297
 
296
298
  const handleOpenRecaptcha = () => {
297
299
  setRecaptchaVerified(false)
298
- if (!recaptchaConfig?.siteKey) {
300
+ if (!recaptchaConfig?.siteKey) {
299
301
  showToast(ToastType.Error, t('NO_RECAPTCHA_SITE_KEY', 'The config doesn\'t have recaptcha site key'));
300
302
  return
301
303
  }
@@ -304,7 +306,7 @@ const SignupFormUI = (props: SignupParams) => {
304
306
  return
305
307
  }
306
308
  recaptchaRef.current.open()
307
- }
309
+ }
308
310
 
309
311
  const onRecaptchaVerify = (token: any) => {
310
312
  setRecaptchaVerified(true)
@@ -335,12 +337,12 @@ const SignupFormUI = (props: SignupParams) => {
335
337
  }, [errors]);
336
338
 
337
339
  useEffect(() => {
338
- register('cellphone', {
339
- required: isRequiredField('cellphone')
340
- ? t('VALIDATION_ERROR_MOBILE_PHONE_REQUIRED', 'The field Mobile phone is required').replace('_attribute_', t('CELLPHONE', 'Cellphone'))
341
- : null
342
- })
343
- }, [register])
340
+ register('cellphone', {
341
+ required: isRequiredField('cellphone')
342
+ ? t('VALIDATION_ERROR_MOBILE_PHONE_REQUIRED', 'The field Mobile phone is required').replace('_attribute_', t('CELLPHONE', 'Cellphone'))
343
+ : null
344
+ })
345
+ }, [register])
344
346
 
345
347
  useEffect(() => {
346
348
  if (phoneInputData?.phone?.cellphone) setValue('cellphone', phoneInputData?.phone?.cellphone, '')
@@ -367,6 +369,16 @@ const SignupFormUI = (props: SignupParams) => {
367
369
  }
368
370
  }, [verifyPhoneState]);
369
371
 
372
+ useEffect(() => {
373
+ setPhoneInputData({
374
+ ...phoneInputData,
375
+ phone: {
376
+ ...phoneInputData.phone,
377
+ country_code: configs?.default_country_code?.value
378
+ }
379
+ })
380
+ }, [configs])
381
+
370
382
  return (
371
383
  <View>
372
384
  <NavBar
@@ -490,8 +502,24 @@ const SignupFormUI = (props: SignupParams) => {
490
502
  <View style={{ marginBottom: 25 }}>
491
503
  <PhoneInputNumber
492
504
  data={phoneInputData}
493
- handleData={(val: any) => setPhoneInputData(val)}
505
+ handleData={(val: any) => setPhoneInputData({
506
+ ...phoneInputData,
507
+ ...val,
508
+ phone: {
509
+ ...phoneInputData.phone,
510
+ ...val.phone,
511
+ country_code: phoneInputData.phone.country_code
512
+ }
513
+ })}
494
514
  forwardRef={phoneRef}
515
+ defaultCode={formState?.country_code ?? formState?.country_phone_code ?? null}
516
+ changeCountry={(val: any) => setPhoneInputData({
517
+ ...phoneInputData,
518
+ phone: {
519
+ ...phoneInputData.phone,
520
+ country_code: val.cca2
521
+ }
522
+ })}
495
523
  textInputProps={{
496
524
  returnKeyType: 'next',
497
525
  onSubmitEditing: () => passwordRef?.current?.focus?.(),
@@ -27,7 +27,7 @@ export const UserFormDetailsUI = (props: any) => {
27
27
  hideUpdateButton,
28
28
  setWillVerifyOtpState,
29
29
  isVerifiedPhone,
30
- handleChangePromotions
30
+ handleChangePromotions,
31
31
  } = props;
32
32
 
33
33
  const theme = useTheme();
@@ -182,6 +182,16 @@ export const UserFormDetailsUI = (props: any) => {
182
182
  handleChangeInput(phoneNumber, true);
183
183
  };
184
184
 
185
+ const changeCountry = (country : any) => {
186
+ let countryCode = {
187
+ country_code: {
188
+ name: 'country_code',
189
+ value: country.cca2
190
+ }
191
+ }
192
+ handleChangeInput(countryCode, true);
193
+ }
194
+
185
195
  useEffect(() => {
186
196
  if (Object.keys(errors).length > 0) {
187
197
  const list = Object.values(errors);
@@ -315,8 +325,9 @@ export const UserFormDetailsUI = (props: any) => {
315
325
  <PhoneInputNumber
316
326
  data={phoneInputData}
317
327
  handleData={(val: any) => handleChangePhoneNumber(val)}
328
+ changeCountry={(val : any) => changeCountry(val)}
318
329
  defaultValue={phoneUpdate ? '' : user?.cellphone}
319
- defaultCode={user?.country_phone_code || null}
330
+ defaultCode={user?.country_code ?? user?.country_phone_code ?? null}
320
331
  boxStyle={styles.phoneSelect}
321
332
  inputStyle={styles.phoneInputStyle}
322
333
  textStyle={{ color: theme.colors.textNormal, fontSize: 12, padding: 0 }}
@@ -167,7 +167,7 @@ const ProfileListUI = (props: ProfileParams) => {
167
167
  <Actions>
168
168
  <ListItem onPress={() => onRedirect('AddressList', { isFromProfile: true, isGoBack: true })} activeOpacity={0.7}>
169
169
  <OIcon src={theme.images.general.pin} width={16} color={theme.colors.textNormal} style={{ marginEnd: 14 }} />
170
- <OText size={14} lineHeight={24} weight={'400'} color={theme.colors.textNormal}>{t('MY_SAVED_PLACES', 'My saved places')}</OText>
170
+ <OText size={14} lineHeight={24} weight={'400'} color={theme.colors.textNormal}>{t('SAVED_PLACES', 'My saved places')}</OText>
171
171
  </ListItem>
172
172
  <ListItem onPress={() => onRedirect('Messages', { isFromProfile: true, isGoBack: true })} activeOpacity={0.7}>
173
173
  <MessageCircle name='message1' style={styles.messageIconStyle} color={theme.colors.textNormal} />
@@ -8,26 +8,26 @@ export const ORDER_TYPES = [
8
8
  {
9
9
  value: 1,
10
10
  content: 'DELIVERY',
11
- description: 'DELIVERY_DESCRIPTION'
11
+ description: 'ORDERTYPE_DESCRIPTION_DELIVERY'
12
12
  },
13
13
  {
14
14
  value: 2,
15
15
  content: 'PICKUP',
16
- description: 'PICKUP_DESCRIPTION',
16
+ description: 'ORDERTYPE_DESCRIPTION_PICKUP',
17
17
  },
18
18
  {
19
19
  value: 3,
20
20
  content: 'EAT_IN',
21
- description: 'EAT_IN_DESCRIPTION',
21
+ description: 'ORDERTYPE_DESCRIPTION_EATIN',
22
22
  },
23
23
  {
24
24
  value: 4,
25
25
  content: 'CURBSIDE',
26
- description: 'CURBSIDE_DESCRIPTION',
26
+ description: 'ORDERTYPE_DESCRIPTION_CURBSIDE',
27
27
  },
28
28
  {
29
29
  value: 5,
30
30
  content: 'DRIVE_THRU',
31
- description: 'DRIVE_THRU_DESCRIPTION',
31
+ description: 'ORDERTYPE_DESCRIPTION_DRIVETHRU',
32
32
  }
33
- ]
33
+ ]
@@ -120,6 +120,7 @@ export interface PhoneInputParams {
120
120
  flagStyle?: any;
121
121
  isDisabled?: any;
122
122
  isStartValidation?: any;
123
+ changeCountry?: any;
123
124
  }
124
125
 
125
126
  export interface LanguageSelectorParams {
@@ -240,7 +241,11 @@ export interface BusinessProductsListParams {
240
241
  handleCancelSearch?: () => void,
241
242
  categoriesLayout?: any,
242
243
  setCategoriesLayout?: any,
243
- currentCart?: any
244
+ currentCart?: any,
245
+ setSubcategoriesSelected?: any,
246
+ subcategoriesSelected?: any,
247
+ onClickCategory?: any,
248
+ lazyLoadProductsRecommended?: boolean
244
249
  }
245
250
  export interface SingleProductCardParams {
246
251
  businessId: any,
@@ -140,7 +140,7 @@ const AddressListUI = (props: AddressListParams) => {
140
140
  <AddressListContainer>
141
141
  {isProfile && (
142
142
  <NavBar
143
- title={t('MY_SAVED_PLACES', 'My saved places')}
143
+ title={t('SAVED_PLACES', 'My saved places')}
144
144
  titleAlign={'center'}
145
145
  onActionLeft={() => goToBack()}
146
146
  showCall={false}
@@ -154,7 +154,7 @@ const ProfileListUI = (props: ProfileParams) => {
154
154
  <Actions>
155
155
  <ListItem onPress={() => onRedirect('AddressList', { isFromProfile: true, isGoBack: true })} activeOpacity={0.7}>
156
156
  <OIcon src={theme.images.general.pin} width={16} color={theme.colors.textNormal} style={{ marginEnd: 14 }} />
157
- <OText size={14} lineHeight={24} weight={'400'} color={theme.colors.textNormal}>{t('MY_SAVED_PLACES', 'My saved places')}</OText>
157
+ <OText size={14} lineHeight={24} weight={'400'} color={theme.colors.textNormal}>{t('SAVED_PLACES', 'My saved places')}</OText>
158
158
  </ListItem>
159
159
  <ListItem onPress={() => navigation.navigate('Help', {})} activeOpacity={0.7}>
160
160
  <OIcon src={theme.images.general.help} width={16} color={theme.colors.textNormal} style={{ marginEnd: 14 }} />