ordering-ui-react-native 0.12.19 → 0.12.20
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/themes/doordash/src/components/BusinessProductsCategories/index.tsx +60 -5
- package/themes/doordash/src/components/BusinessProductsList/index.tsx +144 -79
- package/themes/doordash/src/components/BusinessProductsListing/index.tsx +58 -26
- package/themes/doordash/src/components/ForgotPasswordForm/index.tsx +37 -35
- package/themes/doordash/src/components/ForgotPasswordForm/styles.tsx +7 -0
- package/themes/doordash/src/components/Help/index.tsx +1 -1
- package/themes/doordash/src/components/LastOrders/index.tsx +9 -3
- package/themes/doordash/src/components/LastOrders/styles.tsx +1 -1
- package/themes/doordash/src/components/ProductForm/index.tsx +1 -1
- package/themes/doordash/src/types/index.tsx +11 -1
package/package.json
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React from 'react'
|
|
1
|
+
import React, { useEffect, useRef, useState } from 'react'
|
|
2
2
|
import { BusinessProductsCategories as ProductsCategories } from 'ordering-components/native'
|
|
3
3
|
import { I18nManager, ScrollView, StyleSheet, View } from 'react-native'
|
|
4
4
|
import { Tab } from './styles'
|
|
@@ -15,8 +15,20 @@ const BusinessProductsCategoriesUI = (props: any) => {
|
|
|
15
15
|
categorySelected,
|
|
16
16
|
loading,
|
|
17
17
|
contentStyle,
|
|
18
|
+
scrollViewRef,
|
|
19
|
+
productListLayout,
|
|
20
|
+
categoriesLayout,
|
|
21
|
+
selectedCategoryId,
|
|
22
|
+
lazyLoadProductsRecommended,
|
|
23
|
+
setSelectedCategoryId,
|
|
24
|
+
setCategoryClicked
|
|
18
25
|
} = props
|
|
19
26
|
|
|
27
|
+
const [tabLayouts, setTabLayouts] = useState<any>({});
|
|
28
|
+
const [scrollOffsetX, setScrollOffsetX] = useState<any>(0);
|
|
29
|
+
const tabsRef = useRef<any>(null);
|
|
30
|
+
|
|
31
|
+
|
|
20
32
|
const theme = useTheme();
|
|
21
33
|
|
|
22
34
|
const styles = StyleSheet.create({
|
|
@@ -41,8 +53,50 @@ const BusinessProductsCategoriesUI = (props: any) => {
|
|
|
41
53
|
}
|
|
42
54
|
})
|
|
43
55
|
|
|
56
|
+
const handleCategoryScroll = (category: any) => {
|
|
57
|
+
setCategoryClicked(true);
|
|
58
|
+
setSelectedCategoryId(`cat_${category?.id}`);
|
|
59
|
+
|
|
60
|
+
if (!lazyLoadProductsRecommended) {
|
|
61
|
+
if (category?.id) {
|
|
62
|
+
scrollViewRef.current.scrollTo({
|
|
63
|
+
y: categoriesLayout[`cat_${category?.id}`]?.y + productListLayout?.y + 270,
|
|
64
|
+
animated: true
|
|
65
|
+
})
|
|
66
|
+
} else {
|
|
67
|
+
scrollViewRef.current.scrollTo({
|
|
68
|
+
y: productListLayout?.y - 70,
|
|
69
|
+
animated: true
|
|
70
|
+
})
|
|
71
|
+
}
|
|
72
|
+
} else {
|
|
73
|
+
handlerClickCategory(category)
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
const handleOnLayout = (event: any, categoryId: any) => {
|
|
79
|
+
const _tabLayouts = { ...tabLayouts }
|
|
80
|
+
const categoryKey = 'cat_' + categoryId
|
|
81
|
+
_tabLayouts[categoryKey] = event.nativeEvent.layout
|
|
82
|
+
setTabLayouts(_tabLayouts)
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
useEffect(() => {
|
|
86
|
+
if (!selectedCategoryId || Object.keys(tabLayouts).length === 0) return
|
|
87
|
+
tabsRef.current.scrollTo({
|
|
88
|
+
x: tabLayouts[selectedCategoryId]?.x - 40,
|
|
89
|
+
animated: true
|
|
90
|
+
})
|
|
91
|
+
}, [selectedCategoryId, tabLayouts])
|
|
92
|
+
|
|
93
|
+
|
|
44
94
|
return (
|
|
45
|
-
<ScrollView horizontal contentContainerStyle={contentStyle}
|
|
95
|
+
<ScrollView ref={tabsRef} horizontal contentContainerStyle={contentStyle}
|
|
96
|
+
style={{ ...styles.container, borderBottomWidth: loading ? 0 : 1 }} showsHorizontalScrollIndicator={false}
|
|
97
|
+
onScroll={(e: any) => setScrollOffsetX(e.nativeEvent.contentOffset.x)}
|
|
98
|
+
scrollEventThrottle={16}
|
|
99
|
+
>
|
|
46
100
|
{loading && (
|
|
47
101
|
<Placeholder Animation={Fade}>
|
|
48
102
|
<View style={{ flexDirection: 'row' }}>
|
|
@@ -56,15 +110,16 @@ const BusinessProductsCategoriesUI = (props: any) => {
|
|
|
56
110
|
!loading && categories && categories.length && categories.map((category: any) => (
|
|
57
111
|
<Tab
|
|
58
112
|
key={category.name}
|
|
59
|
-
onPress={() =>
|
|
113
|
+
onPress={() => handleCategoryScroll(category)}
|
|
60
114
|
style={{ ...(category.id === 'featured') && !featured && styles.featuredStyle }}
|
|
115
|
+
onLayout={(event: any) => handleOnLayout(event, category.id)}
|
|
61
116
|
>
|
|
62
117
|
<OText
|
|
63
|
-
color={
|
|
118
|
+
color={selectedCategoryId === `cat_${category.id}` ? theme.colors.textPrimary : theme.colors.textSecondary}
|
|
64
119
|
>
|
|
65
120
|
{category.name}
|
|
66
121
|
</OText>
|
|
67
|
-
<View style={
|
|
122
|
+
<View style={selectedCategoryId === `cat_${category.id}` ? styles.tabStyle : styles.tabDeactived} />
|
|
68
123
|
</Tab>
|
|
69
124
|
))
|
|
70
125
|
}
|
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
import React, { useState, useEffect } from 'react'
|
|
2
|
-
import { ProductsList, useLanguage } from 'ordering-components/native'
|
|
1
|
+
import React, { useState, useEffect, Fragment } from 'react'
|
|
2
|
+
import { ProductsList, useLanguage, useUtils } from 'ordering-components/native'
|
|
3
3
|
import { SingleProductCard } from '../SingleProductCard'
|
|
4
4
|
import { NotFoundSource } from '../NotFoundSource'
|
|
5
5
|
import { BusinessProductsListParams } from '../../types'
|
|
6
|
-
import { OText } from '../shared'
|
|
6
|
+
import { OIcon, OText } from '../shared'
|
|
7
7
|
import {
|
|
8
8
|
ProductsContainer,
|
|
9
9
|
ErrorMessage,
|
|
10
10
|
WrapperNotFound
|
|
11
11
|
} from './styles'
|
|
12
12
|
import { Fade, Placeholder, PlaceholderLine } from 'rn-placeholder'
|
|
13
|
-
import { Platform, View } from 'react-native'
|
|
13
|
+
import { Platform, StyleSheet, View } from 'react-native'
|
|
14
14
|
|
|
15
15
|
const BusinessProductsListUI = (props: BusinessProductsListParams) => {
|
|
16
16
|
const {
|
|
@@ -27,120 +27,173 @@ const BusinessProductsListUI = (props: BusinessProductsListParams) => {
|
|
|
27
27
|
handleClearSearch,
|
|
28
28
|
errorQuantityProducts,
|
|
29
29
|
handleCancelSearch,
|
|
30
|
-
sortBy
|
|
30
|
+
sortBy,
|
|
31
|
+
categoriesLayout,
|
|
32
|
+
setCategoriesLayout
|
|
31
33
|
} = props
|
|
32
34
|
|
|
33
35
|
const [, t] = useLanguage()
|
|
34
|
-
const [
|
|
35
|
-
const [allProducts, setAllProducts] = useState(categoryState.products);
|
|
36
|
+
const [{optimizeImage}] = useUtils();
|
|
36
37
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
}
|
|
38
|
+
const handleOnLayout = (event: any, categoryId: any) => {
|
|
39
|
+
const _categoriesLayout = { ...categoriesLayout }
|
|
40
|
+
const categoryKey = 'cat_' + categoryId
|
|
41
|
+
_categoriesLayout[categoryKey] = event.nativeEvent.layout
|
|
42
|
+
setCategoriesLayout(_categoriesLayout)
|
|
43
|
+
}
|
|
43
44
|
|
|
44
45
|
return (
|
|
45
46
|
<ProductsContainer>
|
|
46
|
-
{category.id &&
|
|
47
|
-
|
|
47
|
+
{category.id &&
|
|
48
|
+
categoryState.products?.map((product: any) => (
|
|
48
49
|
<SingleProductCard
|
|
49
|
-
key={product.id}
|
|
50
|
-
isSoldOut={
|
|
50
|
+
key={'prod_' + product.id}
|
|
51
|
+
isSoldOut={product.inventoried && !product.quantity}
|
|
51
52
|
product={product}
|
|
52
53
|
businessId={businessId}
|
|
53
54
|
onProductClick={() => onProductClick(product)}
|
|
54
55
|
/>
|
|
55
|
-
))
|
|
56
|
-
)}
|
|
56
|
+
))}
|
|
57
57
|
|
|
58
|
-
{
|
|
59
|
-
|
|
60
|
-
|
|
58
|
+
{!category.id &&
|
|
59
|
+
featured &&
|
|
60
|
+
categoryState?.products?.find((product: any) => product.featured) && (
|
|
61
|
+
<View
|
|
62
|
+
onLayout={(event: any) => handleOnLayout(event, 'featured')}
|
|
63
|
+
>
|
|
64
|
+
<OText size={16} weight={'600'} mBottom={15}>
|
|
65
|
+
{t('FEATURED', 'Featured')}
|
|
66
|
+
</OText>
|
|
61
67
|
<>
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
68
|
+
{categoryState.products?.map(
|
|
69
|
+
(product: any, i: any) =>
|
|
70
|
+
product.featured && (
|
|
71
|
+
<SingleProductCard
|
|
72
|
+
key={i}
|
|
73
|
+
isSoldOut={product.inventoried && !product.quantity}
|
|
74
|
+
product={product}
|
|
75
|
+
businessId={businessId}
|
|
76
|
+
onProductClick={onProductClick}
|
|
77
|
+
/>
|
|
78
|
+
),
|
|
79
|
+
)}
|
|
72
80
|
</>
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
81
|
+
</View>
|
|
82
|
+
)}
|
|
83
|
+
|
|
76
84
|
|
|
77
|
-
{
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
85
|
+
{!category.id &&
|
|
86
|
+
categories &&
|
|
87
|
+
categories
|
|
88
|
+
.filter((category) => category.id !== null)
|
|
89
|
+
.map((category, i, _categories) => {
|
|
90
|
+
const products =
|
|
91
|
+
categoryState.products?.filter(
|
|
92
|
+
(product: any) => product.category_id === category.id,
|
|
93
|
+
) || [];
|
|
94
|
+
return (
|
|
95
|
+
<React.Fragment key={'cat_' + category.id}>
|
|
96
|
+
{products.length > 0 && (
|
|
97
|
+
<Fragment>
|
|
98
|
+
<View
|
|
99
|
+
style={bpStyles.catWrap}
|
|
100
|
+
onLayout={(event: any) => handleOnLayout(event, category.id)}
|
|
101
|
+
>
|
|
102
|
+
<View style={bpStyles.catIcon}>
|
|
103
|
+
<OIcon
|
|
104
|
+
url={optimizeImage(category.image, 'h_100,c_limit')}
|
|
105
|
+
width={41}
|
|
106
|
+
height={41}
|
|
107
|
+
style={{ borderRadius: 7.6 }}
|
|
108
|
+
/>
|
|
109
|
+
</View>
|
|
110
|
+
<OText size={16} weight="600">
|
|
111
|
+
{category.name}
|
|
112
|
+
</OText>
|
|
113
|
+
</View>
|
|
114
|
+
<Fragment>
|
|
115
|
+
{products.map((product: any, i: any) => (
|
|
89
116
|
<SingleProductCard
|
|
90
|
-
key={
|
|
117
|
+
key={i}
|
|
91
118
|
isSoldOut={product.inventoried && !product.quantity}
|
|
92
119
|
businessId={businessId}
|
|
93
120
|
product={product}
|
|
94
121
|
onProductClick={onProductClick}
|
|
95
122
|
/>
|
|
96
|
-
))
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
)
|
|
104
|
-
})
|
|
105
|
-
}
|
|
123
|
+
))}
|
|
124
|
+
</Fragment>
|
|
125
|
+
</Fragment>
|
|
126
|
+
)}
|
|
127
|
+
</React.Fragment>
|
|
128
|
+
);
|
|
129
|
+
})}
|
|
106
130
|
|
|
107
|
-
{
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
131
|
+
{(categoryState.loading || isBusinessLoading) && (
|
|
132
|
+
<>
|
|
133
|
+
{[...Array(categoryState?.pagination?.nextPageItems).keys()].map(
|
|
134
|
+
(item, i) => (
|
|
111
135
|
<Placeholder key={i} style={{ padding: 5 }} Animation={Fade}>
|
|
112
136
|
<View style={{ flexDirection: 'row' }}>
|
|
113
|
-
<PlaceholderLine
|
|
137
|
+
<PlaceholderLine
|
|
138
|
+
width={24}
|
|
139
|
+
height={70}
|
|
140
|
+
style={{ marginRight: 10, marginBottom: 10 }}
|
|
141
|
+
/>
|
|
114
142
|
<Placeholder style={{ paddingVertical: 10 }}>
|
|
115
|
-
|
|
116
|
-
|
|
143
|
+
<PlaceholderLine width={60} style={{ marginBottom: 25 }} />
|
|
144
|
+
<PlaceholderLine width={20} />
|
|
117
145
|
</Placeholder>
|
|
118
146
|
</View>
|
|
119
147
|
</Placeholder>
|
|
120
|
-
)
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
|
|
148
|
+
),
|
|
149
|
+
)}
|
|
150
|
+
</>
|
|
151
|
+
)}
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
{!categoryState.loading &&
|
|
155
|
+
!isBusinessLoading &&
|
|
156
|
+
categoryState.products.length === 0 &&
|
|
157
|
+
!errors &&
|
|
158
|
+
!(
|
|
159
|
+
(searchValue && errorQuantityProducts) ||
|
|
160
|
+
(!searchValue && !errorQuantityProducts)
|
|
161
|
+
) && (
|
|
126
162
|
<WrapperNotFound>
|
|
127
163
|
<NotFoundSource
|
|
128
|
-
content={
|
|
129
|
-
|
|
130
|
-
|
|
164
|
+
content={
|
|
165
|
+
!searchValue
|
|
166
|
+
? t(
|
|
167
|
+
'ERROR_NOT_FOUND_PRODUCTS_TIME',
|
|
168
|
+
'No products found at this time',
|
|
169
|
+
)
|
|
170
|
+
: t(
|
|
171
|
+
'ERROR_NOT_FOUND_PRODUCTS',
|
|
172
|
+
'No products found, please change filters.',
|
|
173
|
+
)
|
|
174
|
+
}
|
|
175
|
+
btnTitle={
|
|
176
|
+
!searchValue
|
|
177
|
+
? t('SEARCH_REDIRECT', 'Go to Businesses')
|
|
178
|
+
: t('CLEAR_FILTERS', 'Clear filters')
|
|
179
|
+
}
|
|
180
|
+
onClickButton={() =>
|
|
181
|
+
!searchValue
|
|
182
|
+
? handleSearchRedirect && handleSearchRedirect()
|
|
183
|
+
: handleCancelSearch && handleCancelSearch()
|
|
184
|
+
}
|
|
131
185
|
/>
|
|
132
186
|
</WrapperNotFound>
|
|
133
|
-
)
|
|
134
|
-
}
|
|
187
|
+
)}
|
|
135
188
|
|
|
136
|
-
{errors &&
|
|
189
|
+
{errors &&
|
|
190
|
+
errors.length > 0 &&
|
|
137
191
|
errors.map((e: any, i: number) => (
|
|
138
192
|
<ErrorMessage key={i}>
|
|
139
193
|
<OText space>ERROR:</OText>
|
|
140
194
|
<OText>{e}</OText>
|
|
141
195
|
</ErrorMessage>
|
|
142
|
-
))
|
|
143
|
-
)}
|
|
196
|
+
))}
|
|
144
197
|
</ProductsContainer>
|
|
145
198
|
)
|
|
146
199
|
}
|
|
@@ -155,3 +208,15 @@ export const BusinessProductsList = (props: BusinessProductsListParams) => {
|
|
|
155
208
|
<ProductsList {...businessProductsListProps} />
|
|
156
209
|
)
|
|
157
210
|
}
|
|
211
|
+
|
|
212
|
+
const bpStyles = StyleSheet.create({
|
|
213
|
+
catWrap: { flexDirection: 'row', alignItems: 'center', height: 41, marginBottom: 19 },
|
|
214
|
+
catIcon: {
|
|
215
|
+
borderRadius: 7.6,
|
|
216
|
+
shadowColor: '#000000',
|
|
217
|
+
shadowOpacity: 0.1,
|
|
218
|
+
shadowOffset: { width: 0, height: 0 },
|
|
219
|
+
shadowRadius: 1,
|
|
220
|
+
marginEnd: 13,
|
|
221
|
+
},
|
|
222
|
+
});
|
|
@@ -1,11 +1,13 @@
|
|
|
1
|
-
import React, { useState } from 'react'
|
|
1
|
+
import React, { useState, useRef, useCallback } from 'react'
|
|
2
2
|
import { View, TouchableOpacity, StyleSheet, TextStyle, ScrollView, I18nManager, Platform } from 'react-native'
|
|
3
3
|
import {
|
|
4
4
|
BusinessAndProductList,
|
|
5
5
|
useLanguage,
|
|
6
6
|
useOrder,
|
|
7
7
|
useSession,
|
|
8
|
-
useUtils
|
|
8
|
+
useUtils,
|
|
9
|
+
useToast,
|
|
10
|
+
ToastType
|
|
9
11
|
} from 'ordering-components/native'
|
|
10
12
|
import { OButton, OIcon, OModal, OText } from '../shared'
|
|
11
13
|
import { BusinessBasicInformation } from '../BusinessBasicInformation'
|
|
@@ -35,6 +37,8 @@ import { OrderSummary } from '../OrderSummary'
|
|
|
35
37
|
import NavBar from '../NavBar'
|
|
36
38
|
import SocialShareFav from '../SocialShare'
|
|
37
39
|
|
|
40
|
+
const PIXELS_TO_SCROLL = 1000
|
|
41
|
+
|
|
38
42
|
const BusinessProductsListingUI = (props: BusinessProductsListingParams) => {
|
|
39
43
|
const {
|
|
40
44
|
navigation,
|
|
@@ -52,7 +56,8 @@ const BusinessProductsListingUI = (props: BusinessProductsListingParams) => {
|
|
|
52
56
|
productModal,
|
|
53
57
|
handleChangeCategory,
|
|
54
58
|
setProductLogin,
|
|
55
|
-
updateProductModal
|
|
59
|
+
updateProductModal,
|
|
60
|
+
getNextProducts
|
|
56
61
|
} = props
|
|
57
62
|
const theme = useTheme()
|
|
58
63
|
|
|
@@ -97,14 +102,19 @@ const BusinessProductsListingUI = (props: BusinessProductsListingParams) => {
|
|
|
97
102
|
const [{ auth }] = useSession()
|
|
98
103
|
const [orderState] = useOrder()
|
|
99
104
|
const [{ parsePrice }] = useUtils()
|
|
105
|
+
const [ ,{showToast}] = useToast()
|
|
100
106
|
const { business, loading, error } = businessState
|
|
101
107
|
const [openBusinessInformation, setOpenBusinessInformation] = useState(false)
|
|
102
108
|
const [curProduct, setCurProduct] = useState(null)
|
|
103
109
|
const [openUpselling, setOpenUpselling] = useState(false)
|
|
104
110
|
const [openCart, setOpenCart] = useState(false)
|
|
105
|
-
const [
|
|
111
|
+
const [isCategoryClicked, setCategoryClicked] = useState(false)
|
|
112
|
+
const [categoriesLayout, setCategoriesLayout] = useState<any>({})
|
|
113
|
+
const [productListLayout, setProductListLayout] = useState<any>(null)
|
|
114
|
+
const [selectedCategoryId, setSelectedCategoryId] = useState<any>('cat_all')
|
|
115
|
+
|
|
116
|
+
const scrollViewRef = useRef<any>(null)
|
|
106
117
|
|
|
107
|
-
const [isStickyCategory, setStickyCategory] = useState(false);
|
|
108
118
|
const { top } = useSafeAreaInsets();
|
|
109
119
|
const [sortBy, setSortBy] = useState('alphabet');
|
|
110
120
|
|
|
@@ -146,19 +156,36 @@ const BusinessProductsListingUI = (props: BusinessProductsListingParams) => {
|
|
|
146
156
|
setOpenCart(false)
|
|
147
157
|
}
|
|
148
158
|
|
|
149
|
-
const handlePageScroll = (
|
|
150
|
-
const
|
|
151
|
-
if (
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
159
|
+
const handlePageScroll = useCallback(({ nativeEvent }: any) => {
|
|
160
|
+
const scrollOffset = nativeEvent.contentOffset.y
|
|
161
|
+
if (businessState?.business?.lazy_load_products_recommended) {
|
|
162
|
+
const height = nativeEvent.contentSize.height
|
|
163
|
+
const hasMore = !(categoryState.pagination.totalPages === categoryState.pagination.currentPage)
|
|
164
|
+
if (scrollOffset + PIXELS_TO_SCROLL > height && !loading && hasMore && getNextProducts) {
|
|
165
|
+
getNextProducts()
|
|
166
|
+
showToast(ToastType.Info, t('LOADING_MORE_PRODUCTS', 'Loading more products'))
|
|
167
|
+
}
|
|
168
|
+
} else {
|
|
169
|
+
if (!scrollOffset || !categoriesLayout || !productListLayout || isCategoryClicked) return
|
|
170
|
+
|
|
171
|
+
for (const key in categoriesLayout) {
|
|
172
|
+
const categoryOffset = categoriesLayout[key].y + productListLayout?.y - 70
|
|
173
|
+
if (scrollOffset < 10) {
|
|
174
|
+
setSelectedCategoryId('cat_all');
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
177
|
+
if (categoryOffset - 50 <= scrollOffset && scrollOffset <= categoryOffset + 50) {
|
|
178
|
+
if (selectedCategoryId !== key) {
|
|
179
|
+
setSelectedCategoryId(key)
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
}
|
|
155
183
|
}
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
// }, [orderState.loading])
|
|
184
|
+
}, [isCategoryClicked, selectedCategoryId])
|
|
185
|
+
|
|
186
|
+
const handleTouchDrag = useCallback(() => {
|
|
187
|
+
setCategoryClicked(false);
|
|
188
|
+
}, []);
|
|
162
189
|
|
|
163
190
|
return (
|
|
164
191
|
<>
|
|
@@ -172,11 +199,6 @@ const BusinessProductsListingUI = (props: BusinessProductsListingParams) => {
|
|
|
172
199
|
onClick={() => (navigation?.canGoBack() && navigation.goBack()) || (auth && navigation.navigate('BottomTab'))}
|
|
173
200
|
imgLeftStyle={{ tintColor: theme.colors.textPrimary }}
|
|
174
201
|
/>
|
|
175
|
-
{isStickyCategory && (
|
|
176
|
-
<Animated.View style={{ flexBasis: '74%', paddingHorizontal: 10, alignItems: 'center' }}>
|
|
177
|
-
<OText style={theme.labels.middle as TextStyle} numberOfLines={1} ellipsizeMode={'tail'}>{business?.name}</OText>
|
|
178
|
-
</Animated.View>
|
|
179
|
-
)}
|
|
180
202
|
{!errorQuantityProducts && (
|
|
181
203
|
<View style={{ ...styles.headerItem }}>
|
|
182
204
|
<View
|
|
@@ -196,8 +218,10 @@ const BusinessProductsListingUI = (props: BusinessProductsListingParams) => {
|
|
|
196
218
|
style={styles.mainContainer}
|
|
197
219
|
isActiveFloatingButtom={currentCart?.products?.length > 0 && categoryState.products.length !== 0}
|
|
198
220
|
stickyHeaderIndices={[1]}
|
|
221
|
+
ref={scrollViewRef}
|
|
199
222
|
onScroll={handlePageScroll}
|
|
200
|
-
|
|
223
|
+
onScrollBeginDrag={handleTouchDrag}
|
|
224
|
+
scrollEventThrottle={16}
|
|
201
225
|
>
|
|
202
226
|
<WrapHeader>
|
|
203
227
|
<BusinessBasicInformation
|
|
@@ -211,7 +235,6 @@ const BusinessProductsListingUI = (props: BusinessProductsListingParams) => {
|
|
|
211
235
|
<WrapSearchBar>
|
|
212
236
|
<SearchBar
|
|
213
237
|
onSearch={handleChangeSearch}
|
|
214
|
-
// onCancel={() => handleCancel()}
|
|
215
238
|
isCancelXButtonShow
|
|
216
239
|
noBorderShow
|
|
217
240
|
placeholder={t('SEARCH', 'Search')}
|
|
@@ -232,18 +255,25 @@ const BusinessProductsListingUI = (props: BusinessProductsListingParams) => {
|
|
|
232
255
|
{!loading && business?.id && !(business?.categories?.length === 0) && (
|
|
233
256
|
<CategoryWrap>
|
|
234
257
|
<BusinessProductsCategories
|
|
235
|
-
categories={[{ id:
|
|
258
|
+
categories={[{ id: 'all', name: t('ALL', 'All') }, { id: 'featured', name: t('FEATURED', 'Featured') }, ...business?.categories.sort((a: any, b: any) => a.rank - b.rank)]}
|
|
236
259
|
categorySelected={categorySelected}
|
|
237
260
|
onClickCategory={handleChangeCategory}
|
|
238
261
|
featured={featuredProducts}
|
|
239
262
|
openBusinessInformation={openBusinessInformation}
|
|
263
|
+
scrollViewRef={scrollViewRef}
|
|
240
264
|
contentStyle={{ paddingHorizontal: 40 }}
|
|
265
|
+
productListLayout={productListLayout}
|
|
266
|
+
categoriesLayout={categoriesLayout}
|
|
267
|
+
selectedCategoryId={selectedCategoryId}
|
|
268
|
+
setSelectedCategoryId={setSelectedCategoryId}
|
|
269
|
+
setCategoryClicked={setCategoryClicked}
|
|
270
|
+
lazyLoadProductsRecommended={business?.lazy_load_products_recommended}
|
|
241
271
|
/>
|
|
242
272
|
</CategoryWrap>
|
|
243
273
|
)}
|
|
244
274
|
<View>
|
|
245
275
|
{!loading && business?.id && (
|
|
246
|
-
<WrapContent>
|
|
276
|
+
<WrapContent onLayout={(event: any) => setProductListLayout(event.nativeEvent.layout)}>
|
|
247
277
|
<BusinessProductsList
|
|
248
278
|
categories={[
|
|
249
279
|
{ id: null, name: t('ALL', 'All') },
|
|
@@ -262,6 +292,8 @@ const BusinessProductsListingUI = (props: BusinessProductsListingParams) => {
|
|
|
262
292
|
errorQuantityProducts={errorQuantityProducts}
|
|
263
293
|
handleCancelSearch={handleCancel}
|
|
264
294
|
sortBy={sortBy}
|
|
295
|
+
categoriesLayout={categoriesLayout}
|
|
296
|
+
setCategoriesLayout={setCategoriesLayout}
|
|
265
297
|
/>
|
|
266
298
|
</WrapContent>
|
|
267
299
|
)}
|
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
|
|
11
11
|
import NavBar from '../NavBar';
|
|
12
12
|
import { FormInput, FormSide } from '../LoginForm/styles'
|
|
13
|
-
import { Container } from './styles'
|
|
13
|
+
import { Container, InputWrap } from './styles'
|
|
14
14
|
|
|
15
15
|
import { OButton, OInput, OText } from '../shared';
|
|
16
16
|
import { useTheme } from 'styled-components/native';
|
|
@@ -26,9 +26,8 @@ const ForgotPasswordUI = (props: any) => {
|
|
|
26
26
|
|
|
27
27
|
const styles = StyleSheet.create({
|
|
28
28
|
inputStyle: {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
borderColor: theme.colors.disabled
|
|
29
|
+
borderWidth: 0,
|
|
30
|
+
minHeight: 44
|
|
32
31
|
}
|
|
33
32
|
});
|
|
34
33
|
|
|
@@ -84,47 +83,50 @@ const ForgotPasswordUI = (props: any) => {
|
|
|
84
83
|
onActionLeft={() => navigation?.canGoBack() && navigation.goBack()}
|
|
85
84
|
rightImg={null}
|
|
86
85
|
paddingTop={0}
|
|
86
|
+
style={{paddingLeft: 0, paddingRight: 0}}
|
|
87
87
|
/>
|
|
88
88
|
<FormSide>
|
|
89
89
|
<OText
|
|
90
90
|
color={'gray'}
|
|
91
91
|
size={16}
|
|
92
92
|
weight={'300'}
|
|
93
|
-
style={{ marginBottom: 30 }}
|
|
93
|
+
style={{ marginBottom: 30, marginTop: 30 }}
|
|
94
94
|
>
|
|
95
95
|
{t('FORGOT_PASSWORD_TEXT_MESSAGE', "Enter your email address and we'll sent a link to reset your password.")}
|
|
96
96
|
</OText>
|
|
97
97
|
<FormInput>
|
|
98
|
-
<
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
98
|
+
<InputWrap>
|
|
99
|
+
<OText weight="bold">Email</OText>
|
|
100
|
+
<Controller
|
|
101
|
+
control={control}
|
|
102
|
+
render={({ onChange, value }: any) => (
|
|
103
|
+
<OInput
|
|
104
|
+
placeholder={t('EXAMPLE@MAIL.COM', 'your@email.com')}
|
|
105
|
+
style={styles.inputStyle}
|
|
106
|
+
onChange={(e: any) => {
|
|
107
|
+
handleChangeInputEmail(e, onChange)
|
|
108
|
+
}}
|
|
109
|
+
value={value}
|
|
110
|
+
autoCapitalize='none'
|
|
111
|
+
autoCorrect={false}
|
|
112
|
+
type='email-address'
|
|
113
|
+
autoCompleteType='email'
|
|
114
|
+
returnKeyType='done'
|
|
115
|
+
blurOnSubmit
|
|
116
|
+
onSubmitEditing={handleSubmit(onSubmit)}
|
|
117
|
+
/>
|
|
118
|
+
)}
|
|
119
|
+
name="email"
|
|
120
|
+
rules={{
|
|
121
|
+
required: t('VALIDATION_ERROR_EMAIL_REQUIRED', 'The field Email is required').replace('_attribute_', t('EMAIL', 'Email')),
|
|
122
|
+
pattern: {
|
|
123
|
+
value: /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}$/i,
|
|
124
|
+
message: t('INVALID_ERROR_EMAIL', 'Invalid email address').replace('_attribute_', t('EMAIL', 'Email'))
|
|
125
|
+
}
|
|
126
|
+
}}
|
|
127
|
+
defaultValue=""
|
|
128
|
+
/>
|
|
129
|
+
</InputWrap>
|
|
128
130
|
|
|
129
131
|
<OButton
|
|
130
132
|
text={emailSent && !formState.result?.error ? t('LINK_SEND_FORGOT_PASSWORD', 'Link Sent') : t('FRONT_RECOVER_PASSWORD', 'Recover Password')}
|
|
@@ -9,3 +9,10 @@ export const Wrapper = styled.View`
|
|
|
9
9
|
export const Container = styled.View`
|
|
10
10
|
padding-bottom: 40px;
|
|
11
11
|
`
|
|
12
|
+
export const InputWrap = styled.View`
|
|
13
|
+
flex-direction: row;
|
|
14
|
+
align-items: center;
|
|
15
|
+
border-bottom-width: 1px;
|
|
16
|
+
border-bottom-color: #D7D7D7;
|
|
17
|
+
margin-bottom: 35px;
|
|
18
|
+
`
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React from 'react'
|
|
1
|
+
import React, { useCallback } from 'react'
|
|
2
2
|
import {
|
|
3
3
|
OrderList as OrderListController,
|
|
4
4
|
useUtils,
|
|
@@ -17,10 +17,12 @@ import {
|
|
|
17
17
|
OrderContainer,
|
|
18
18
|
OrderInfo
|
|
19
19
|
} from './styles'
|
|
20
|
+
import { StackActions } from '@react-navigation/native'
|
|
20
21
|
|
|
21
22
|
const LastOrdersUI = (props: LastOrdersParams) => {
|
|
22
23
|
const {
|
|
23
|
-
orderList
|
|
24
|
+
orderList,
|
|
25
|
+
navigation
|
|
24
26
|
} = props
|
|
25
27
|
const { loading, error, orders } = orderList
|
|
26
28
|
|
|
@@ -40,6 +42,10 @@ const LastOrdersUI = (props: LastOrdersParams) => {
|
|
|
40
42
|
}
|
|
41
43
|
})
|
|
42
44
|
|
|
45
|
+
const goToOrders = useCallback((order) => {
|
|
46
|
+
navigation.navigate('BottomTab', { screen: 'MyOrders' });
|
|
47
|
+
}, [])
|
|
48
|
+
|
|
43
49
|
return (
|
|
44
50
|
<>
|
|
45
51
|
{loading ? (
|
|
@@ -53,7 +59,7 @@ const LastOrdersUI = (props: LastOrdersParams) => {
|
|
|
53
59
|
) : (
|
|
54
60
|
<>
|
|
55
61
|
{orders.map((order: any) => (
|
|
56
|
-
<OrderContainer key={order.id}>
|
|
62
|
+
<OrderContainer key={order.id} onPress={() => goToOrders(order)}>
|
|
57
63
|
<OIcon
|
|
58
64
|
url={optimizeImage(order.business?.header, 'h_300,c_limit')}
|
|
59
65
|
style={styles.headerLogo}
|
|
@@ -99,7 +99,7 @@ export const ProductOptionsUI = (props: any) => {
|
|
|
99
99
|
minHeight: 200,
|
|
100
100
|
zIndex: 0
|
|
101
101
|
},
|
|
102
|
-
closeButton: { width:
|
|
102
|
+
closeButton: { width: 11, height: 32, backgroundColor: theme.colors.white, alignItems: 'center', justifyContent: 'center' },
|
|
103
103
|
quantityWrap: { width: 40, height: 24, alignItems: 'center', justifyContent: 'center', borderRadius: 7.6, backgroundColor: theme.colors.inputDisabled }
|
|
104
104
|
})
|
|
105
105
|
const [{ parsePrice }] = useUtils()
|
|
@@ -164,6 +164,7 @@ export interface BusinessProductsListingParams {
|
|
|
164
164
|
handleChangeCategory: (value: any) => {};
|
|
165
165
|
setProductLogin?: () => {};
|
|
166
166
|
updateProductModal?: (value: any) => {}
|
|
167
|
+
getNextProducts?: () => {};
|
|
167
168
|
}
|
|
168
169
|
export interface BusinessBasicInformationParams {
|
|
169
170
|
businessState?: any;
|
|
@@ -175,13 +176,19 @@ export interface BusinessBasicInformationParams {
|
|
|
175
176
|
}
|
|
176
177
|
export interface BusinessProductsCategoriesParams {
|
|
177
178
|
categories: Array<any>;
|
|
178
|
-
// handlerClickCategory: any;
|
|
179
179
|
onClickCategory: any;
|
|
180
180
|
openBusinessInformation: any;
|
|
181
181
|
categorySelected: any;
|
|
182
182
|
featured: boolean;
|
|
183
183
|
loading?: any;
|
|
184
184
|
contentStyle?: ViewStyle;
|
|
185
|
+
scrollViewRef?: any;
|
|
186
|
+
productListLayout?: any;
|
|
187
|
+
categoriesLayout?: any;
|
|
188
|
+
selectedCategoryId?: any;
|
|
189
|
+
lazyLoadProductsRecommended?: any;
|
|
190
|
+
setSelectedCategoryId?: any;
|
|
191
|
+
setCategoryClicked?: any;
|
|
185
192
|
}
|
|
186
193
|
export interface BusinessProductsListParams {
|
|
187
194
|
errors?: any;
|
|
@@ -198,6 +205,8 @@ export interface BusinessProductsListParams {
|
|
|
198
205
|
errorQuantityProducts?: boolean;
|
|
199
206
|
handleCancelSearch?: () => void;
|
|
200
207
|
sortBy?: string;
|
|
208
|
+
categoriesLayout?: any,
|
|
209
|
+
setCategoriesLayout?: any
|
|
201
210
|
}
|
|
202
211
|
export interface SingleProductCardParams {
|
|
203
212
|
businessId: any;
|
|
@@ -407,6 +416,7 @@ export interface HelpParams {
|
|
|
407
416
|
}
|
|
408
417
|
|
|
409
418
|
export interface LastOrdersParams {
|
|
419
|
+
navigation?: any,
|
|
410
420
|
orderList?: any,
|
|
411
421
|
}
|
|
412
422
|
|