ordering-ui-react-native 0.12.20 → 0.12.24
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 +1 -1
- package/src/components/ActiveOrders/index.tsx +31 -14
- package/src/components/AddressForm/index.tsx +16 -1
- package/src/components/Messages/index.tsx +59 -4
- package/src/components/Messages/styles.tsx +3 -0
- package/themes/business/src/components/Chat/index.tsx +56 -8
- package/themes/business/src/components/Chat/styles.tsx +4 -0
- package/themes/doordash/src/components/Messages/index.tsx +62 -4
- package/themes/doordash/src/components/Messages/styles.tsx +2 -0
- package/themes/doordash/src/components/shared/OButton.tsx +2 -1
- package/themes/instacart/src/components/Messages/index.tsx +60 -5
- package/themes/instacart/src/components/Messages/styles.tsx +2 -0
- package/themes/kiosk/src/components/BusinessProductsListing/index.tsx +7 -1
- package/themes/kiosk/src/components/CartBottomSheet/styles.tsx +1 -1
- package/themes/kiosk/src/components/CategoriesMenu/index.tsx +8 -1
- package/themes/original/src/components/Messages/index.tsx +61 -5
- package/themes/original/src/components/Messages/styles.tsx +2 -2
- package/themes/original/src/components/ProductForm/index.tsx +40 -24
- package/themes/single-business/src/components/AddressList/index.tsx +2 -2
- package/themes/single-business/src/components/BusinessProductsCategories/index.tsx +89 -16
- package/themes/single-business/src/components/BusinessProductsList/index.tsx +22 -8
- package/themes/single-business/src/components/BusinessProductsList/styles.tsx +1 -1
- package/themes/single-business/src/components/BusinessProductsListing/index.tsx +71 -26
- package/themes/single-business/src/components/LoginForm/index.tsx +43 -26
- package/themes/single-business/src/components/SignupForm/index.tsx +15 -16
- package/themes/single-business/src/components/UserProfile/index.tsx +2 -2
- package/themes/single-business/src/types/index.tsx +9 -0
- package/themes/uber-eats/src/components/Messages/index.tsx +59 -4
- package/themes/uber-eats/src/components/Messages/styles.tsx +2 -0
|
@@ -5,9 +5,9 @@ import { launchImageLibrary } from 'react-native-image-picker'
|
|
|
5
5
|
import { GiftedChat, Actions, ActionsProps, InputToolbar, Composer, Send, Bubble, MessageImage, InputToolbarProps, ComposerProps } from 'react-native-gifted-chat'
|
|
6
6
|
import { USER_TYPE } from '../../config/constants'
|
|
7
7
|
import MaterialCommunityIcon from 'react-native-vector-icons/MaterialCommunityIcons'
|
|
8
|
-
import { OIcon, OIconButton, OText } from '../shared'
|
|
8
|
+
import { OIcon, OIconButton, OText, OButton } from '../shared'
|
|
9
9
|
import { TouchableOpacity, ActivityIndicator, StyleSheet, View, Platform, Keyboard } from 'react-native'
|
|
10
|
-
import { Header, TitleHeader, Wrapper } from './styles'
|
|
10
|
+
import { Header, TitleHeader, Wrapper, QuickMessageContainer } from './styles'
|
|
11
11
|
import { MessagesParams } from '../../types'
|
|
12
12
|
import { useWindowDimensions } from 'react-native'
|
|
13
13
|
import { useSafeAreaInsets } from 'react-native-safe-area-context'
|
|
@@ -43,6 +43,17 @@ const MessagesUI = (props: MessagesParams) => {
|
|
|
43
43
|
|
|
44
44
|
const theme = useTheme();
|
|
45
45
|
|
|
46
|
+
const quickMessageList = [
|
|
47
|
+
{ key: 'customer_message_1', text: t('CUSTOMER_MESSAGE_1', 'Lorem ipsum 1') },
|
|
48
|
+
{ key: 'customer_message_2', text: t('CUSTOMER_MESSAGE_2', 'Lorem ipsum 2') },
|
|
49
|
+
{ key: 'customer_message_3', text: t('CUSTOMER_MESSAGE_3', 'Lorem ipsum 3') },
|
|
50
|
+
{ key: 'customer_message_4', text: t('CUSTOMER_MESSAGE_4', 'Lorem ipsum 4') }
|
|
51
|
+
]
|
|
52
|
+
|
|
53
|
+
const handleClickQuickMessage = (text: string) => {
|
|
54
|
+
setMessage && setMessage(`${message}${text}`)
|
|
55
|
+
}
|
|
56
|
+
|
|
46
57
|
const onChangeMessage = (val: string) => {
|
|
47
58
|
setMessage && setMessage(val)
|
|
48
59
|
}
|
|
@@ -227,13 +238,48 @@ const MessagesUI = (props: MessagesParams) => {
|
|
|
227
238
|
)
|
|
228
239
|
}
|
|
229
240
|
|
|
241
|
+
const renderAccessory = () => {
|
|
242
|
+
return (
|
|
243
|
+
<QuickMessageContainer
|
|
244
|
+
style={{
|
|
245
|
+
marginLeft: 10,
|
|
246
|
+
marginBottom: 10
|
|
247
|
+
}}
|
|
248
|
+
contentContainerStyle={{
|
|
249
|
+
alignItems: 'center',
|
|
250
|
+
}}
|
|
251
|
+
horizontal
|
|
252
|
+
showsHorizontalScrollIndicator={false}
|
|
253
|
+
>
|
|
254
|
+
{quickMessageList.map((quickMessage, i) => (
|
|
255
|
+
<OButton
|
|
256
|
+
key={i}
|
|
257
|
+
text={quickMessage.text}
|
|
258
|
+
bgColor='#E9ECEF'
|
|
259
|
+
borderColor='#E9ECEF'
|
|
260
|
+
imgRightSrc={null}
|
|
261
|
+
textStyle={{
|
|
262
|
+
fontSize: 11,
|
|
263
|
+
lineHeight: 16,
|
|
264
|
+
color: '#414954'
|
|
265
|
+
}}
|
|
266
|
+
style={{ ...styles.editButton }}
|
|
267
|
+
onClick={() => handleClickQuickMessage(quickMessage.text)}
|
|
268
|
+
/>
|
|
269
|
+
))}
|
|
270
|
+
</QuickMessageContainer>
|
|
271
|
+
)
|
|
272
|
+
}
|
|
273
|
+
|
|
230
274
|
const renderInputToolbar = (props: typeof InputToolbarProps) => (
|
|
231
275
|
<InputToolbar
|
|
232
276
|
{...props}
|
|
233
277
|
containerStyle={{
|
|
234
|
-
padding: Platform.OS === 'ios' && isKeyboardShow ? 0 : 10
|
|
278
|
+
padding: Platform.OS === 'ios' && isKeyboardShow ? 0 : 10,
|
|
279
|
+
flexDirection: 'column-reverse'
|
|
235
280
|
}}
|
|
236
281
|
primaryStyle={{ alignItems: 'center', justifyContent: 'flex-start' }}
|
|
282
|
+
renderAccessory={() => renderAccessory()}
|
|
237
283
|
/>
|
|
238
284
|
)
|
|
239
285
|
|
|
@@ -385,8 +431,9 @@ const MessagesUI = (props: MessagesParams) => {
|
|
|
385
431
|
renderMessageImage={renderMessageImage}
|
|
386
432
|
scrollToBottomComponent={() => renderScrollToBottomComponent()}
|
|
387
433
|
messagesContainerStyle={{
|
|
388
|
-
|
|
434
|
+
paddingTop: 18,
|
|
389
435
|
paddingHorizontal: 28,
|
|
436
|
+
paddingBottom: 55
|
|
390
437
|
}}
|
|
391
438
|
isLoadingEarlier={messages.loading}
|
|
392
439
|
renderLoading={() => <ActivityIndicator size="small" color="#000" />}
|
|
@@ -412,7 +459,16 @@ const styles = StyleSheet.create({
|
|
|
412
459
|
alignItems: 'center',
|
|
413
460
|
justifyContent: 'center',
|
|
414
461
|
marginHorizontal: 4
|
|
415
|
-
}
|
|
462
|
+
},
|
|
463
|
+
editButton : {
|
|
464
|
+
borderRadius: 50,
|
|
465
|
+
backgroundColor: '#E9ECEF',
|
|
466
|
+
marginRight: 10,
|
|
467
|
+
height: 24,
|
|
468
|
+
borderWidth: 1,
|
|
469
|
+
paddingLeft: 0,
|
|
470
|
+
paddingRight: 0
|
|
471
|
+
}
|
|
416
472
|
})
|
|
417
473
|
|
|
418
474
|
export const Messages = (props: MessagesParams) => {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, { useEffect } from 'react';
|
|
1
|
+
import React, { useEffect, useRef } from 'react';
|
|
2
2
|
import {
|
|
3
3
|
ProductForm as ProductOptions,
|
|
4
4
|
useSession,
|
|
@@ -120,13 +120,13 @@ export const ProductOptionsUI = (props: any) => {
|
|
|
120
120
|
height: 258,
|
|
121
121
|
},
|
|
122
122
|
swiperButton: {
|
|
123
|
-
marginHorizontal:
|
|
123
|
+
marginHorizontal: 25,
|
|
124
124
|
alignItems: 'center',
|
|
125
125
|
justifyContent: 'center',
|
|
126
126
|
width: 32,
|
|
127
127
|
height: 32,
|
|
128
128
|
borderRadius: 16,
|
|
129
|
-
backgroundColor: 'rgba(
|
|
129
|
+
backgroundColor: 'rgba(208,208,208,0.5)'
|
|
130
130
|
}
|
|
131
131
|
});
|
|
132
132
|
|
|
@@ -142,6 +142,8 @@ export const ProductOptionsUI = (props: any) => {
|
|
|
142
142
|
const { height } = useWindowDimensions();
|
|
143
143
|
const [selOpt, setSelectedOpt] = useState(0);
|
|
144
144
|
|
|
145
|
+
const swiperRef: any = useRef(null)
|
|
146
|
+
|
|
145
147
|
const isError = (id: number) => {
|
|
146
148
|
let bgColor = theme.colors.white;
|
|
147
149
|
if (errors[`id:${id}`]) {
|
|
@@ -175,9 +177,17 @@ export const ProductOptionsUI = (props: any) => {
|
|
|
175
177
|
};
|
|
176
178
|
|
|
177
179
|
const handleChangeMainIndex = (index: number) => {
|
|
180
|
+
if (index < 0 || index > gallery.length - 1) {
|
|
181
|
+
setThumbsSwiper(0)
|
|
182
|
+
return
|
|
183
|
+
}
|
|
178
184
|
setThumbsSwiper(index)
|
|
179
185
|
}
|
|
180
186
|
|
|
187
|
+
const handleClickThumb = (index: number) => {
|
|
188
|
+
swiperRef?.current.scrollBy(index - thumbsSwiper, true);
|
|
189
|
+
}
|
|
190
|
+
|
|
181
191
|
const handleRedirectLogin = () => {
|
|
182
192
|
onClose();
|
|
183
193
|
navigation.navigate('Login');
|
|
@@ -186,8 +196,10 @@ export const ProductOptionsUI = (props: any) => {
|
|
|
186
196
|
useEffect(() => {
|
|
187
197
|
const productImgList: any = []
|
|
188
198
|
product?.images && productImgList.push(product.images)
|
|
189
|
-
|
|
190
|
-
|
|
199
|
+
if(product?.gallery && product?.gallery.length > 0) {
|
|
200
|
+
for (const img of product?.gallery) {
|
|
201
|
+
productImgList.push(img.file)
|
|
202
|
+
}
|
|
191
203
|
}
|
|
192
204
|
setGallery(productImgList)
|
|
193
205
|
}, [product])
|
|
@@ -273,9 +285,10 @@ export const ProductOptionsUI = (props: any) => {
|
|
|
273
285
|
<>
|
|
274
286
|
<Swiper
|
|
275
287
|
loop={false}
|
|
288
|
+
ref={swiperRef}
|
|
276
289
|
showsButtons={true}
|
|
277
290
|
style={styles.mainSwiper}
|
|
278
|
-
|
|
291
|
+
showsPagination={false}
|
|
279
292
|
onIndexChanged={(index) => handleChangeMainIndex(index)}
|
|
280
293
|
prevButton={
|
|
281
294
|
<View style={styles.swiperButton}>
|
|
@@ -321,29 +334,32 @@ export const ProductOptionsUI = (props: any) => {
|
|
|
321
334
|
}}
|
|
322
335
|
>
|
|
323
336
|
{gallery.length > 0 && gallery.map((img, index) => (
|
|
324
|
-
<
|
|
337
|
+
<TouchableOpacity
|
|
325
338
|
key={index}
|
|
326
|
-
|
|
327
|
-
height: 56,
|
|
328
|
-
borderRadius: 8,
|
|
329
|
-
margin: 8,
|
|
330
|
-
opacity: index === thumbsSwiper ? 1 : 0.8
|
|
331
|
-
}}
|
|
339
|
+
onPress={() => handleClickThumb(index)}
|
|
332
340
|
>
|
|
333
|
-
<
|
|
334
|
-
url={img}
|
|
341
|
+
<View
|
|
335
342
|
style={{
|
|
336
|
-
|
|
343
|
+
height: 56,
|
|
337
344
|
borderRadius: 8,
|
|
338
|
-
|
|
345
|
+
margin: 8,
|
|
346
|
+
opacity: index === thumbsSwiper ? 1 : 0.8
|
|
339
347
|
}}
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
348
|
+
>
|
|
349
|
+
<OIcon
|
|
350
|
+
url={img}
|
|
351
|
+
style={{
|
|
352
|
+
borderColor: theme.colors.lightGray,
|
|
353
|
+
borderRadius: 8,
|
|
354
|
+
minHeight: '100%'
|
|
355
|
+
}}
|
|
356
|
+
width={56}
|
|
357
|
+
height={56}
|
|
358
|
+
cover
|
|
359
|
+
/>
|
|
360
|
+
</View>
|
|
361
|
+
</TouchableOpacity>
|
|
362
|
+
|
|
347
363
|
))}
|
|
348
364
|
</ScrollView>
|
|
349
365
|
</>
|
|
@@ -257,7 +257,7 @@ const AddressListUI = (props: AddressListParams) => {
|
|
|
257
257
|
{!(
|
|
258
258
|
route && (route?.params?.isFromBusinesses || route?.params?.isFromCheckout)
|
|
259
259
|
) && !isProfile && (
|
|
260
|
-
<OText size={
|
|
260
|
+
<OText size={20} style={{ marginTop: 20 }}>
|
|
261
261
|
{t('WHERE_DELIVER_NOW', 'Where do we deliver you?')}
|
|
262
262
|
</OText>
|
|
263
263
|
)}
|
|
@@ -320,7 +320,7 @@ const styles = StyleSheet.create({
|
|
|
320
320
|
position: 'absolute',
|
|
321
321
|
},
|
|
322
322
|
button: {
|
|
323
|
-
marginTop:
|
|
323
|
+
marginTop: 20,
|
|
324
324
|
marginBottom: 0,
|
|
325
325
|
borderRadius: 7.6,
|
|
326
326
|
borderWidth: 1,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import React from 'react';
|
|
1
|
+
import React, { useEffect, useState, useRef } from 'react';
|
|
2
2
|
import { BusinessProductsCategories as ProductsCategories } from 'ordering-components/native';
|
|
3
3
|
import { useTheme } from 'styled-components/native';
|
|
4
|
-
import { ScrollView, StyleSheet, View } from 'react-native';
|
|
4
|
+
import { ScrollView, StyleSheet, View, Dimensions } from 'react-native';
|
|
5
5
|
import { Tab } from './styles';
|
|
6
6
|
import { OText } from '../shared';
|
|
7
7
|
import { BusinessProductsCategoriesParams } from '../../types';
|
|
@@ -11,28 +11,79 @@ const BusinessProductsCategoriesUI = (props: any) => {
|
|
|
11
11
|
const {
|
|
12
12
|
featured,
|
|
13
13
|
categories,
|
|
14
|
-
handlerClickCategory,
|
|
15
14
|
categorySelected,
|
|
16
15
|
loading,
|
|
16
|
+
scrollViewRef,
|
|
17
|
+
productListLayout,
|
|
18
|
+
categoriesLayout,
|
|
19
|
+
selectedCategoryId,
|
|
20
|
+
setSelectedCategoryId,
|
|
21
|
+
handlerClickCategory,
|
|
22
|
+
lazyLoadProductsRecommended
|
|
17
23
|
} = props;
|
|
18
24
|
|
|
19
25
|
const theme = useTheme();
|
|
26
|
+
const windowWidth = Dimensions.get('window').width
|
|
27
|
+
const [tabLayouts, setTabLayouts] = useState<any>({})
|
|
28
|
+
const [scrollOffsetX, setScrollOffsetX] = useState<any>(0)
|
|
29
|
+
const tabsRef = useRef<any>(null)
|
|
30
|
+
|
|
20
31
|
const styles = StyleSheet.create({
|
|
21
32
|
container: {
|
|
22
|
-
paddingVertical:
|
|
33
|
+
paddingVertical: 5,
|
|
23
34
|
borderColor: theme.colors.clear,
|
|
35
|
+
backgroundColor: '#FFF'
|
|
24
36
|
},
|
|
25
37
|
featuredStyle: {
|
|
26
38
|
display: 'none',
|
|
27
39
|
},
|
|
28
40
|
});
|
|
29
41
|
|
|
42
|
+
const handleCategoryScroll = (category: any) => {
|
|
43
|
+
if (!lazyLoadProductsRecommended) {
|
|
44
|
+
if (category?.id || category.name === 'All') {
|
|
45
|
+
scrollViewRef.current.scrollTo({
|
|
46
|
+
y: categoriesLayout[`cat_${category?.id ?? category?.name}`]?.y + productListLayout?.y - 120,
|
|
47
|
+
animated: true
|
|
48
|
+
})
|
|
49
|
+
} else {
|
|
50
|
+
scrollViewRef.current.scrollTo({
|
|
51
|
+
y: productListLayout?.y - 120,
|
|
52
|
+
animated: true
|
|
53
|
+
})
|
|
54
|
+
}
|
|
55
|
+
} else {
|
|
56
|
+
handlerClickCategory(category)
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const handleOnLayout = (event: any, categoryId: any) => {
|
|
61
|
+
const _tabLayouts = { ...tabLayouts }
|
|
62
|
+
const categoryKey = 'cat_' + categoryId
|
|
63
|
+
_tabLayouts[categoryKey] = event.nativeEvent.layout
|
|
64
|
+
setTabLayouts(_tabLayouts)
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
useEffect(() => {
|
|
68
|
+
if (!selectedCategoryId || Object.keys(tabLayouts).length === 0) return
|
|
69
|
+
tabsRef.current.scrollTo({
|
|
70
|
+
x: tabLayouts[selectedCategoryId]?.x - 40,
|
|
71
|
+
animated: true
|
|
72
|
+
})
|
|
73
|
+
}, [selectedCategoryId, tabLayouts])
|
|
74
|
+
|
|
75
|
+
const initialCategory = featured ? 0 : 1
|
|
76
|
+
|
|
30
77
|
return (
|
|
31
78
|
<ScrollView
|
|
79
|
+
ref={tabsRef}
|
|
32
80
|
horizontal
|
|
33
81
|
style={{ ...styles.container, borderBottomWidth: loading ? 0 : 1 }}
|
|
34
82
|
contentContainerStyle={{ paddingHorizontal: 40 }}
|
|
35
|
-
showsHorizontalScrollIndicator={false}
|
|
83
|
+
showsHorizontalScrollIndicator={false}
|
|
84
|
+
onScroll={(e: any) => setScrollOffsetX(e.nativeEvent.contentOffset.x)}
|
|
85
|
+
scrollEventThrottle={16}
|
|
86
|
+
>
|
|
36
87
|
{loading && (
|
|
37
88
|
<Placeholder Animation={Fade}>
|
|
38
89
|
<View style={{ flexDirection: 'row' }}>
|
|
@@ -45,26 +96,44 @@ const BusinessProductsCategoriesUI = (props: any) => {
|
|
|
45
96
|
{!loading &&
|
|
46
97
|
categories &&
|
|
47
98
|
categories.length &&
|
|
48
|
-
categories.map((category: any) => (
|
|
99
|
+
categories.map((category: any, i: number) => (
|
|
49
100
|
<Tab
|
|
50
101
|
key={category.name}
|
|
51
|
-
onPress={() =>
|
|
102
|
+
onPress={() => handleCategoryScroll(category)}
|
|
52
103
|
style={[
|
|
53
104
|
category.id === 'featured' && !featured && styles.featuredStyle,
|
|
54
105
|
{
|
|
55
106
|
borderColor:
|
|
56
|
-
|
|
57
|
-
?
|
|
58
|
-
:
|
|
107
|
+
(!lazyLoadProductsRecommended
|
|
108
|
+
? (selectedCategoryId === (`cat_${category.id}`) || (i === initialCategory && selectedCategoryId === null))
|
|
109
|
+
: (categorySelected?.id === category.id))
|
|
110
|
+
? theme.colors.textNormal
|
|
111
|
+
: theme.colors.border,
|
|
59
112
|
},
|
|
60
|
-
]}
|
|
113
|
+
]}
|
|
114
|
+
onLayout={(event: any) => handleOnLayout(event, category.id)}
|
|
115
|
+
>
|
|
61
116
|
<OText
|
|
62
|
-
size={
|
|
63
|
-
|
|
117
|
+
size={
|
|
118
|
+
(!lazyLoadProductsRecommended
|
|
119
|
+
? (selectedCategoryId === (`cat_${category.id}`) || (i === initialCategory && selectedCategoryId === null))
|
|
120
|
+
: (categorySelected?.id === category.id))
|
|
121
|
+
? 14
|
|
122
|
+
: 12
|
|
123
|
+
}
|
|
124
|
+
weight={
|
|
125
|
+
(!lazyLoadProductsRecommended
|
|
126
|
+
? (selectedCategoryId === (`cat_${category.id}`) || (i === initialCategory && selectedCategoryId === null))
|
|
127
|
+
: (categorySelected?.id === category.id))
|
|
128
|
+
? '600'
|
|
129
|
+
: '400'
|
|
130
|
+
}
|
|
64
131
|
color={
|
|
65
|
-
|
|
66
|
-
?
|
|
67
|
-
:
|
|
132
|
+
(!lazyLoadProductsRecommended
|
|
133
|
+
? (selectedCategoryId === (`cat_${category.id}`) || (i === initialCategory && selectedCategoryId === null))
|
|
134
|
+
: (categorySelected?.id === category.id))
|
|
135
|
+
? theme.colors.textNormal
|
|
136
|
+
: theme.colors.textSecondary
|
|
68
137
|
}
|
|
69
138
|
style={{ alignSelf: 'center' }}>
|
|
70
139
|
{category.name}
|
|
@@ -78,8 +147,12 @@ const BusinessProductsCategoriesUI = (props: any) => {
|
|
|
78
147
|
export const BusinessProductsCategories = (
|
|
79
148
|
props: BusinessProductsCategoriesParams,
|
|
80
149
|
) => {
|
|
150
|
+
const categoriesToSend = !props.lazyLoadProductsRecommended
|
|
151
|
+
? props.categories.filter((category: any) => category.id)
|
|
152
|
+
: props.categories
|
|
81
153
|
const businessProductsCategoriesProps = {
|
|
82
154
|
...props,
|
|
155
|
+
categories: categoriesToSend,
|
|
83
156
|
UIComponent: BusinessProductsCategoriesUI,
|
|
84
157
|
};
|
|
85
158
|
|
|
@@ -24,11 +24,20 @@ const BusinessProductsListUI = (props: BusinessProductsListParams) => {
|
|
|
24
24
|
handleClearSearch,
|
|
25
25
|
errorQuantityProducts,
|
|
26
26
|
handleCancelSearch,
|
|
27
|
+
categoriesLayout,
|
|
28
|
+
setCategoriesLayout
|
|
27
29
|
} = props;
|
|
28
30
|
|
|
29
31
|
const [, t] = useLanguage();
|
|
30
32
|
const [{ optimizeImage }] = useUtils()
|
|
31
33
|
|
|
34
|
+
const handleOnLayout = (event: any, categoryId: any) => {
|
|
35
|
+
const _categoriesLayout = { ...categoriesLayout }
|
|
36
|
+
const categoryKey = 'cat_' + categoryId
|
|
37
|
+
_categoriesLayout[categoryKey] = event.nativeEvent.layout
|
|
38
|
+
setCategoriesLayout(_categoriesLayout)
|
|
39
|
+
}
|
|
40
|
+
|
|
32
41
|
return (
|
|
33
42
|
<ProductsContainer>
|
|
34
43
|
{category.id &&
|
|
@@ -45,16 +54,18 @@ const BusinessProductsListUI = (props: BusinessProductsListParams) => {
|
|
|
45
54
|
{!category.id &&
|
|
46
55
|
featured &&
|
|
47
56
|
categoryState?.products?.find((product: any) => product.featured) && (
|
|
48
|
-
|
|
57
|
+
<View
|
|
58
|
+
onLayout={(event: any) => handleOnLayout(event, 'featured')}
|
|
59
|
+
>
|
|
49
60
|
<OText size={16} weight={'600'} mBottom={15}>
|
|
50
61
|
{t('FEATURED', 'Featured')}
|
|
51
62
|
</OText>
|
|
52
63
|
<>
|
|
53
64
|
{categoryState.products?.map(
|
|
54
|
-
(product: any) =>
|
|
65
|
+
(product: any, i: any) =>
|
|
55
66
|
product.featured && (
|
|
56
67
|
<SingleProductCard
|
|
57
|
-
key={
|
|
68
|
+
key={i}
|
|
58
69
|
isSoldOut={product.inventoried && !product.quantity}
|
|
59
70
|
product={product}
|
|
60
71
|
businessId={businessId}
|
|
@@ -63,7 +74,7 @@ const BusinessProductsListUI = (props: BusinessProductsListParams) => {
|
|
|
63
74
|
),
|
|
64
75
|
)}
|
|
65
76
|
</>
|
|
66
|
-
|
|
77
|
+
</View>
|
|
67
78
|
)}
|
|
68
79
|
|
|
69
80
|
{!category.id &&
|
|
@@ -79,7 +90,10 @@ const BusinessProductsListUI = (props: BusinessProductsListParams) => {
|
|
|
79
90
|
<React.Fragment key={'cat_' + category.id}>
|
|
80
91
|
{products.length > 0 && (
|
|
81
92
|
<>
|
|
82
|
-
<View
|
|
93
|
+
<View
|
|
94
|
+
style={bpStyles.catWrap}
|
|
95
|
+
onLayout={(event: any) => handleOnLayout(event, category?.id)}
|
|
96
|
+
>
|
|
83
97
|
<View style={bpStyles.catIcon}>
|
|
84
98
|
<OIcon
|
|
85
99
|
url={optimizeImage(category.image, 'h_100,c_limit')}
|
|
@@ -88,14 +102,14 @@ const BusinessProductsListUI = (props: BusinessProductsListParams) => {
|
|
|
88
102
|
style={{ borderRadius: 7.6 }}
|
|
89
103
|
/>
|
|
90
104
|
</View>
|
|
91
|
-
<OText size={16} weight=
|
|
105
|
+
<OText size={16} weight="600">
|
|
92
106
|
{category.name}
|
|
93
107
|
</OText>
|
|
94
108
|
</View>
|
|
95
109
|
<>
|
|
96
|
-
{products.map((product: any) => (
|
|
110
|
+
{products.map((product: any, i: any) => (
|
|
97
111
|
<SingleProductCard
|
|
98
|
-
key={
|
|
112
|
+
key={i}
|
|
99
113
|
isSoldOut={product.inventoried && !product.quantity}
|
|
100
114
|
businessId={businessId}
|
|
101
115
|
product={product}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import React, { useEffect, useState } from 'react'
|
|
2
|
-
import { View, StyleSheet } from 'react-native'
|
|
1
|
+
import React, { useEffect, useState, useRef } from 'react'
|
|
2
|
+
import { View, StyleSheet, SafeAreaView } from 'react-native'
|
|
3
3
|
import { useTheme } from 'styled-components/native';
|
|
4
4
|
import {
|
|
5
5
|
BusinessAndProductList,
|
|
@@ -7,6 +7,8 @@ import {
|
|
|
7
7
|
useOrder,
|
|
8
8
|
useSession,
|
|
9
9
|
useUtils,
|
|
10
|
+
useToast,
|
|
11
|
+
ToastType
|
|
10
12
|
} from 'ordering-components/native'
|
|
11
13
|
import { OButton, OModal } from '../shared'
|
|
12
14
|
import { BusinessBasicInformation } from '../BusinessBasicInformation'
|
|
@@ -27,6 +29,8 @@ import { ProductForm } from '../ProductForm'
|
|
|
27
29
|
import { useSafeAreaInsets } from 'react-native-safe-area-context';
|
|
28
30
|
import { _setStoreData } from '../../providers/StoreUtil';
|
|
29
31
|
|
|
32
|
+
const PIXELS_TO_SCROLL = 1000
|
|
33
|
+
|
|
30
34
|
const BusinessProductsListingUI = (props: BusinessProductsListingParams) => {
|
|
31
35
|
const {
|
|
32
36
|
navigation,
|
|
@@ -41,7 +45,8 @@ const BusinessProductsListingUI = (props: BusinessProductsListingParams) => {
|
|
|
41
45
|
featuredProducts,
|
|
42
46
|
errorQuantityProducts,
|
|
43
47
|
header,
|
|
44
|
-
logo
|
|
48
|
+
logo,
|
|
49
|
+
getNextProducts
|
|
45
50
|
} = props
|
|
46
51
|
|
|
47
52
|
const theme = useTheme();
|
|
@@ -49,6 +54,7 @@ const BusinessProductsListingUI = (props: BusinessProductsListingParams) => {
|
|
|
49
54
|
const [{ auth }] = useSession()
|
|
50
55
|
const [orderState] = useOrder()
|
|
51
56
|
const [{ parsePrice }] = useUtils()
|
|
57
|
+
const [ ,{showToast}] = useToast()
|
|
52
58
|
const { top, bottom } = useSafeAreaInsets()
|
|
53
59
|
|
|
54
60
|
const styles = StyleSheet.create({
|
|
@@ -84,6 +90,11 @@ const BusinessProductsListingUI = (props: BusinessProductsListingParams) => {
|
|
|
84
90
|
const [curProduct, setCurProduct] = useState(null)
|
|
85
91
|
const [openUpselling, setOpenUpselling] = useState(false)
|
|
86
92
|
const [canOpenUpselling, setCanOpenUpselling] = useState(false)
|
|
93
|
+
const scrollViewRef = useRef<any>(null)
|
|
94
|
+
|
|
95
|
+
const [categoriesLayout, setCategoriesLayout] = useState<any>({})
|
|
96
|
+
const [productListLayout, setProductListLayout] = useState<any>(null)
|
|
97
|
+
const [selectedCategoryId, setSelectedCategoryId] = useState<any>(null)
|
|
87
98
|
|
|
88
99
|
const currentCart: any = Object.values(orderState.carts).find((cart: any) => cart?.business?.slug === business?.slug) ?? {}
|
|
89
100
|
|
|
@@ -122,6 +133,28 @@ const BusinessProductsListingUI = (props: BusinessProductsListingParams) => {
|
|
|
122
133
|
setOpenUpselling(false)
|
|
123
134
|
}
|
|
124
135
|
|
|
136
|
+
const handleScroll = ({ nativeEvent }: any) => {
|
|
137
|
+
const scrollOffset = nativeEvent.contentOffset.y
|
|
138
|
+
if (businessState?.business?.lazy_load_products_recommended) {
|
|
139
|
+
const height = nativeEvent.contentSize.height
|
|
140
|
+
const hasMore = !(categoryState.pagination.totalPages === categoryState.pagination.currentPage)
|
|
141
|
+
if (scrollOffset + PIXELS_TO_SCROLL > height && !loading && hasMore && getNextProducts) {
|
|
142
|
+
getNextProducts()
|
|
143
|
+
showToast(ToastType.Info, t('LOADING_MORE_PRODUCTS', 'Loading more products'))
|
|
144
|
+
}
|
|
145
|
+
} else {
|
|
146
|
+
if (!scrollOffset || !categoriesLayout || !productListLayout) return
|
|
147
|
+
for (const key in categoriesLayout) {
|
|
148
|
+
const categoryOffset = categoriesLayout[key].y + productListLayout?.y - 70
|
|
149
|
+
if (categoryOffset - 50 <= scrollOffset && scrollOffset <= categoryOffset + 50) {
|
|
150
|
+
if (selectedCategoryId !== key) {
|
|
151
|
+
setSelectedCategoryId(key)
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
125
158
|
useEffect(() => {
|
|
126
159
|
if (!orderState.loading) {
|
|
127
160
|
handleCloseProductModal()
|
|
@@ -131,16 +164,23 @@ const BusinessProductsListingUI = (props: BusinessProductsListingParams) => {
|
|
|
131
164
|
useEffect(() => {
|
|
132
165
|
if (businessState?.business?.logo) {
|
|
133
166
|
_setStoreData('b_logo', {businessLogo: businessState.business?.logo});
|
|
134
|
-
} else {
|
|
135
|
-
console.log('logo undefined!!')
|
|
136
167
|
}
|
|
137
168
|
}, [businessState])
|
|
138
169
|
|
|
139
170
|
return (
|
|
140
|
-
|
|
141
|
-
|
|
171
|
+
<SafeAreaView
|
|
172
|
+
style={{ flex: 1 }}
|
|
173
|
+
>
|
|
174
|
+
<BusinessProductsListingContainer
|
|
175
|
+
stickyHeaderIndices={[2]}
|
|
176
|
+
style={styles.mainContainer}
|
|
177
|
+
ref={scrollViewRef}
|
|
178
|
+
isActiveFloatingButtom={currentCart?.products?.length > 0 && categoryState.products.length !== 0}
|
|
179
|
+
onScroll={(e: any) => handleScroll(e)}
|
|
180
|
+
scrollEventThrottle={16}
|
|
181
|
+
>
|
|
142
182
|
<WrapHeader>
|
|
143
|
-
{!auth &&
|
|
183
|
+
{!auth &&
|
|
144
184
|
<TopHeader style={{top: top}}>
|
|
145
185
|
<OButton
|
|
146
186
|
imgLeftSrc={theme.images.general.arrow_left}
|
|
@@ -173,14 +213,30 @@ const BusinessProductsListingUI = (props: BusinessProductsListingParams) => {
|
|
|
173
213
|
</WrapSearchBar>
|
|
174
214
|
{!(business?.categories?.length === 0) && (
|
|
175
215
|
<BusinessProductsCategories
|
|
176
|
-
categories={[
|
|
216
|
+
categories={[
|
|
217
|
+
{ id: null, name: t('ALL', 'All') },
|
|
218
|
+
{ id: 'featured', name: t('FEATURED', 'Featured') },
|
|
219
|
+
...business?.categories?.sort((a: any, b: any) => a.rank - b.rank)
|
|
220
|
+
]}
|
|
177
221
|
categorySelected={categorySelected}
|
|
178
222
|
onClickCategory={handleChangeCategory}
|
|
179
223
|
featured={featuredProducts}
|
|
180
224
|
openBusinessInformation={openBusinessInformation}
|
|
225
|
+
scrollViewRef={scrollViewRef}
|
|
226
|
+
productListLayout={productListLayout}
|
|
227
|
+
categoriesLayout={categoriesLayout}
|
|
228
|
+
selectedCategoryId={selectedCategoryId}
|
|
229
|
+
setSelectedCategoryId={setSelectedCategoryId}
|
|
230
|
+
lazyLoadProductsRecommended={business?.lazy_load_products_recommended}
|
|
181
231
|
/>
|
|
182
232
|
)}
|
|
183
|
-
|
|
233
|
+
</>
|
|
234
|
+
)}
|
|
235
|
+
{!loading && business?.id && (
|
|
236
|
+
<>
|
|
237
|
+
<WrapContent
|
|
238
|
+
onLayout={(event: any) => setProductListLayout(event.nativeEvent.layout)}
|
|
239
|
+
>
|
|
184
240
|
<BusinessProductsList
|
|
185
241
|
categories={[
|
|
186
242
|
{ id: null, name: t('ALL', 'All') },
|
|
@@ -198,10 +254,12 @@ const BusinessProductsListingUI = (props: BusinessProductsListingParams) => {
|
|
|
198
254
|
handleClearSearch={handleChangeSearch}
|
|
199
255
|
errorQuantityProducts={errorQuantityProducts}
|
|
200
256
|
handleCancelSearch={handleCancel}
|
|
257
|
+
categoriesLayout={categoriesLayout}
|
|
258
|
+
setCategoriesLayout={setCategoriesLayout}
|
|
201
259
|
/>
|
|
202
260
|
</WrapContent>
|
|
203
|
-
|
|
204
|
-
|
|
261
|
+
</>
|
|
262
|
+
)}
|
|
205
263
|
{loading && !error && (
|
|
206
264
|
<>
|
|
207
265
|
<BusinessProductsCategories
|
|
@@ -256,20 +314,7 @@ const BusinessProductsListingUI = (props: BusinessProductsListingParams) => {
|
|
|
256
314
|
onSave={handlerProductAction}
|
|
257
315
|
/>
|
|
258
316
|
</OModal>
|
|
259
|
-
|
|
260
|
-
<UpsellingProducts
|
|
261
|
-
businessId={currentCart?.business_id}
|
|
262
|
-
business={currentCart?.business}
|
|
263
|
-
cartProducts={currentCart?.products}
|
|
264
|
-
cart={currentCart}
|
|
265
|
-
handleUpsellingPage={handleUpsellingPage}
|
|
266
|
-
handleCloseUpsellingPage={handleCloseUpsellingPage}
|
|
267
|
-
openUpselling={openUpselling}
|
|
268
|
-
canOpenUpselling={canOpenUpselling}
|
|
269
|
-
setCanOpenUpselling={setCanOpenUpselling}
|
|
270
|
-
/>
|
|
271
|
-
)} */}
|
|
272
|
-
</>
|
|
317
|
+
</SafeAreaView>
|
|
273
318
|
)
|
|
274
319
|
}
|
|
275
320
|
|