ordering-ui-react-native 0.14.27 → 0.14.31
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 +2 -1
- package/src/components/ProductForm/index.tsx +27 -19
- package/themes/original/src/components/BusinessItemAccordion/index.tsx +49 -31
- package/themes/original/src/components/BusinessItemAccordion/styles.tsx +7 -0
- package/themes/original/src/components/BusinessPreorder/index.tsx +2 -1
- package/themes/original/src/components/BusinessProductsList/index.tsx +6 -6
- package/themes/original/src/components/Cart/index.tsx +2 -0
- package/themes/original/src/components/DriverTips/index.tsx +3 -3
- package/themes/original/src/components/DriverTips/styles.tsx +5 -5
- package/themes/original/src/components/ProductForm/index.tsx +120 -46
- package/themes/original/src/components/ProductForm/styles.tsx +12 -0
- package/themes/original/src/components/ProductIngredient/index.tsx +5 -4
- package/themes/original/src/components/ProductItemAccordion/index.tsx +2 -2
- package/themes/original/src/components/ProductOptionSubOption/index.tsx +11 -11
- package/themes/original/src/components/SingleProductCard/index.tsx +3 -4
- package/themes/original/src/components/SingleProductCard/styles.tsx +3 -1
- package/themes/original/src/types/index.tsx +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ordering-ui-react-native",
|
|
3
|
-
"version": "0.14.
|
|
3
|
+
"version": "0.14.31",
|
|
4
4
|
"description": "Reusable components made in react native",
|
|
5
5
|
"main": "src/index.tsx",
|
|
6
6
|
"author": "ordering.inc",
|
|
@@ -70,6 +70,7 @@
|
|
|
70
70
|
"react-native-bootsplash": "^3.2.3",
|
|
71
71
|
"react-native-calendar-picker": "^7.1.2",
|
|
72
72
|
"react-native-calendar-strip": "^2.2.5",
|
|
73
|
+
"react-native-color-matrix-image-filters": "^5.2.10",
|
|
73
74
|
"react-native-country-picker-modal": "^2.0.0",
|
|
74
75
|
"react-native-credit-card-input": "^0.4.1",
|
|
75
76
|
"react-native-document-picker": "^5.2.0",
|
|
@@ -132,7 +132,18 @@ export const ProductOptionsUI = (props: any) => {
|
|
|
132
132
|
) : (
|
|
133
133
|
<>
|
|
134
134
|
<View style={{ flexDirection: 'column', width: '100%' }}>
|
|
135
|
-
<
|
|
135
|
+
<View style={{ flexDirection: 'row', marginTop: 15 }}>
|
|
136
|
+
<OText size={20} style={{ flex: I18nManager.isRTL ? 0 : 1, marginBottom: 10 }}>{product?.name || productCart.name}{' '}</OText>
|
|
137
|
+
{product?.calories && (
|
|
138
|
+
<OText size={16} style={styles.caloriesStyle}>{product?.calories} cal</OText>
|
|
139
|
+
)}
|
|
140
|
+
</View>
|
|
141
|
+
<View style={{ flexDirection: 'row', marginBottom: 10 }}>
|
|
142
|
+
<OText size={16} style={{ flex: I18nManager.isRTL ? 1 : 0 }} color={theme.colors.primary}>{productCart.price ? parsePrice(productCart.price) : ''}</OText>
|
|
143
|
+
{product?.offer_price && (
|
|
144
|
+
<OText style={styles.regularPriceStyle}>{parsePrice(product?.offer_price)}</OText>
|
|
145
|
+
)}
|
|
146
|
+
</View>
|
|
136
147
|
{(product?.estimated_person || (product?.sku && product?.sku !== '-1' && product?.sku !== '1')) && (
|
|
137
148
|
<OText size={14} style={{ flex: I18nManager.isRTL ? 1 : 0, marginBottom: 10 }} color={'#909BA9'}>
|
|
138
149
|
{
|
|
@@ -147,12 +158,6 @@ export const ProductOptionsUI = (props: any) => {
|
|
|
147
158
|
}
|
|
148
159
|
</OText>
|
|
149
160
|
)}
|
|
150
|
-
<View style={{ flexDirection: 'row', marginBottom: 10}}>
|
|
151
|
-
<OText size={16} style={{ flex: I18nManager.isRTL ? 1 : 0 }} color={theme.colors.primary}>{productCart.price ? parsePrice(productCart.price) : ''}</OText>
|
|
152
|
-
{product?.offer_price && (
|
|
153
|
-
<OText style={styles.regularPriceStyle}>{parsePrice(product?.offer_price)}</OText>
|
|
154
|
-
)}
|
|
155
|
-
</View>
|
|
156
161
|
</View>
|
|
157
162
|
</>
|
|
158
163
|
)}
|
|
@@ -162,17 +167,17 @@ export const ProductOptionsUI = (props: any) => {
|
|
|
162
167
|
</ProductDescription>
|
|
163
168
|
{loading && !product ? (
|
|
164
169
|
<>
|
|
165
|
-
{[...Array(2)].map((item,i) => (
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
170
|
+
{[...Array(2)].map((item, i) => (
|
|
171
|
+
<Placeholder key={i} style={{ marginBottom: 20 }} Animation={Fade}>
|
|
172
|
+
<PlaceholderLine height={40} style={{ flex: 1, marginTop: 10 }} />
|
|
173
|
+
{[...Array(3)].map((item, i) => (
|
|
174
|
+
<View key={i} style={{ flexDirection: 'row', justifyContent: 'space-between' }}>
|
|
175
|
+
<PlaceholderLine height={30} width={10} style={{ marginBottom: 20 }} />
|
|
176
|
+
<PlaceholderLine height={30} width={50} style={{ marginBottom: 20 }} />
|
|
177
|
+
<PlaceholderLine height={30} width={30} style={{ marginBottom: 20 }} />
|
|
178
|
+
</View>
|
|
179
|
+
))}
|
|
180
|
+
</Placeholder>
|
|
176
181
|
))}
|
|
177
182
|
</>
|
|
178
183
|
) : (
|
|
@@ -221,7 +226,7 @@ export const ProductOptionsUI = (props: any) => {
|
|
|
221
226
|
state={currentState}
|
|
222
227
|
disabled={isSoldOut || maxProductQuantity <= 0}
|
|
223
228
|
/>
|
|
224
|
-
): null
|
|
229
|
+
) : null
|
|
225
230
|
})
|
|
226
231
|
}
|
|
227
232
|
</WrapperSubOption>
|
|
@@ -383,6 +388,9 @@ const styles = StyleSheet.create({
|
|
|
383
388
|
textDecorationLine: 'line-through',
|
|
384
389
|
marginLeft: 7,
|
|
385
390
|
marginRight: 7
|
|
391
|
+
},
|
|
392
|
+
caloriesStyle: {
|
|
393
|
+
color: '#808080'
|
|
386
394
|
}
|
|
387
395
|
})
|
|
388
396
|
|
|
@@ -9,16 +9,19 @@ import {
|
|
|
9
9
|
BIInfo,
|
|
10
10
|
BIContentInfo,
|
|
11
11
|
BITotal,
|
|
12
|
-
BIActions
|
|
12
|
+
BIActions,
|
|
13
|
+
PriceContainer
|
|
13
14
|
} from './styles';
|
|
14
|
-
import { OAlert, OIcon, OText } from '../shared';
|
|
15
|
+
import { OAlert, OButton, OIcon, OText } from '../shared';
|
|
15
16
|
|
|
16
17
|
export const BusinessItemAccordion = (props: any) => {
|
|
17
18
|
const {
|
|
18
19
|
cart,
|
|
19
20
|
moment,
|
|
20
|
-
|
|
21
|
-
handleClearProducts
|
|
21
|
+
singleBusiness,
|
|
22
|
+
handleClearProducts,
|
|
23
|
+
handleClickCheckout,
|
|
24
|
+
checkoutButtonDisabled
|
|
22
25
|
} = props
|
|
23
26
|
|
|
24
27
|
const [orderState] = useOrder();
|
|
@@ -41,7 +44,7 @@ export const BusinessItemAccordion = (props: any) => {
|
|
|
41
44
|
}, [orderState?.carts])
|
|
42
45
|
|
|
43
46
|
return (
|
|
44
|
-
<BIContainer isClosed={isClosed}>
|
|
47
|
+
<BIContainer isClosed={isClosed} checkoutVisible={!isActive && !isClosed && !!isProducts && !checkoutButtonDisabled}>
|
|
45
48
|
<BIHeader
|
|
46
49
|
isClosed={isClosed}
|
|
47
50
|
onPress={() => !isClosed ? setActiveState(!isActive) : isClosed}
|
|
@@ -71,37 +74,39 @@ export const BusinessItemAccordion = (props: any) => {
|
|
|
71
74
|
{props.onNavigationRedirect && !isClosed && (
|
|
72
75
|
<>
|
|
73
76
|
<TouchableOpacity onPress={() => props.onNavigationRedirect('Business', { store: cart?.business?.slug })}>
|
|
74
|
-
<OText color={theme.colors.
|
|
77
|
+
<OText color={theme.colors.primary} size={12} lineHeight={18} style={{ textDecorationLine: 'underline' }}>{t('GO_TO_STORE', 'Go to store')}</OText>
|
|
75
78
|
</TouchableOpacity>
|
|
76
|
-
<OText color={theme.colors.textSecondary}>{' \u2022 '}</OText>
|
|
77
79
|
</>
|
|
78
80
|
)}
|
|
79
81
|
{!isCartPending && !isClosed && (
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
82
|
+
<>
|
|
83
|
+
<OText color={theme.colors.textSecondary}>{' \u2022 '}</OText>
|
|
84
|
+
<OAlert
|
|
85
|
+
title={t('DELETE_CART', 'Delete Cart')}
|
|
86
|
+
message={t('QUESTION_DELETE_CART', 'Are you sure to you wants delete the selected cart')}
|
|
87
|
+
onAccept={() => handleClearProducts()}
|
|
88
|
+
>
|
|
89
|
+
<OText size={12} lineHeight={18} color={theme.colors.primary} style={{ textDecorationLine: 'underline' }}>{t('CLEAR_CART', 'Clear cart')}</OText>
|
|
90
|
+
</OAlert>
|
|
91
|
+
</>
|
|
92
|
+
)}
|
|
93
|
+
{props.handleChangeStore && (
|
|
94
|
+
<>
|
|
95
|
+
<OText color={theme.colors.textSecondary}>{' \u2022 '}</OText>
|
|
96
|
+
<TouchableOpacity
|
|
97
|
+
onPress={props.handleChangeStore}
|
|
98
|
+
>
|
|
99
|
+
<OText
|
|
100
|
+
size={12}
|
|
101
|
+
lineHeight={18}
|
|
102
|
+
color={theme.colors.textSecondary}
|
|
103
|
+
style={{ textDecorationLine: 'underline' }}
|
|
104
|
+
>
|
|
105
|
+
{t('CHANGE_STORE', 'Change store')}
|
|
106
|
+
</OText>
|
|
107
|
+
</TouchableOpacity>
|
|
108
|
+
</>
|
|
87
109
|
)}
|
|
88
|
-
{props.handleChangeStore && (
|
|
89
|
-
<>
|
|
90
|
-
<OText color={theme.colors.textSecondary}>{' \u2022 '}</OText>
|
|
91
|
-
<TouchableOpacity
|
|
92
|
-
onPress={props.handleChangeStore}
|
|
93
|
-
>
|
|
94
|
-
<OText
|
|
95
|
-
size={12}
|
|
96
|
-
lineHeight={18}
|
|
97
|
-
color={theme.colors.textSecondary}
|
|
98
|
-
style={{ textDecorationLine: 'underline' }}
|
|
99
|
-
>
|
|
100
|
-
{t('CHANGE_STORE', 'Change store')}
|
|
101
|
-
</OText>
|
|
102
|
-
</TouchableOpacity>
|
|
103
|
-
</>
|
|
104
|
-
)}
|
|
105
110
|
</View>
|
|
106
111
|
</BIContentInfo>
|
|
107
112
|
</BIInfo>
|
|
@@ -134,6 +139,19 @@ export const BusinessItemAccordion = (props: any) => {
|
|
|
134
139
|
)}
|
|
135
140
|
</BIActions>
|
|
136
141
|
</BIHeader>
|
|
142
|
+
{!isActive && !isClosed && !!isProducts && !checkoutButtonDisabled && (
|
|
143
|
+
<PriceContainer>
|
|
144
|
+
<OText>{parsePrice(cart?.total)}</OText>
|
|
145
|
+
<OButton
|
|
146
|
+
onClick={handleClickCheckout}
|
|
147
|
+
textStyle={{ color: 'white', textAlign: 'center', flex: 1 }}
|
|
148
|
+
style={{ width: 160, flexDirection: 'row', justifyContent: 'center', borderRadius: 7.6, shadowOpacity: 0 }}
|
|
149
|
+
text={t('CHECKOUT', 'Checkout')}
|
|
150
|
+
bgColor={(cart?.subtotal < cart?.minimum || !cart?.valid_address) ? theme.colors.secundary : theme.colors.primary}
|
|
151
|
+
borderColor={theme.colors.primary}
|
|
152
|
+
/>
|
|
153
|
+
</PriceContainer>
|
|
154
|
+
)}
|
|
137
155
|
|
|
138
156
|
<BIContent style={{ display: isActive ? 'flex' : 'none' }}>
|
|
139
157
|
{props.children}
|
|
@@ -82,7 +82,7 @@ const BusinessPreorderUI = (props: BusinessPreorderParams) => {
|
|
|
82
82
|
paddingBottom: 15,
|
|
83
83
|
borderBottomWidth: 1,
|
|
84
84
|
borderColor: theme.colors.backgroundGray200,
|
|
85
|
-
height:
|
|
85
|
+
height: 100
|
|
86
86
|
},
|
|
87
87
|
calendarHeaderContainer: {
|
|
88
88
|
flex: 1,
|
|
@@ -400,6 +400,7 @@ const BusinessPreorderUI = (props: BusinessPreorderParams) => {
|
|
|
400
400
|
iconStyle={{borderWidth: 1}}
|
|
401
401
|
selectedDate={selectDate}
|
|
402
402
|
datesWhitelist={datesWhitelist}
|
|
403
|
+
dayContainerStyle={{height: 40}}
|
|
403
404
|
disabledDateNameStyle={styles.disabledDateName}
|
|
404
405
|
disabledDateNumberStyle={styles.disabledDateNumber}
|
|
405
406
|
disabledDateOpacity={0.6}
|
|
@@ -42,14 +42,14 @@ const BusinessProductsListUI = (props: BusinessProductsListParams) => {
|
|
|
42
42
|
return (
|
|
43
43
|
<ProductsContainer>
|
|
44
44
|
{category.id &&
|
|
45
|
-
categoryState.products?.map((product: any) => (
|
|
45
|
+
categoryState.products?.sort((a: any, b: any) => a.rank - b.rank).map((product: any) => (
|
|
46
46
|
<SingleProductCard
|
|
47
47
|
key={'prod_' + product.id}
|
|
48
48
|
isSoldOut={product.inventoried && !product.quantity}
|
|
49
49
|
product={product}
|
|
50
50
|
businessId={businessId}
|
|
51
51
|
onProductClick={() => onProductClick(product)}
|
|
52
|
-
|
|
52
|
+
productAddedToCartLength={currentCart?.products?.reduce((productsLength: number, Cproduct: any) => { return productsLength + (Cproduct?.id === product?.id ? Cproduct?.quantity : 0) }, 0)}
|
|
53
53
|
/>
|
|
54
54
|
))}
|
|
55
55
|
|
|
@@ -63,7 +63,7 @@ const BusinessProductsListUI = (props: BusinessProductsListParams) => {
|
|
|
63
63
|
{t('FEATURED', 'Featured')}
|
|
64
64
|
</OText>
|
|
65
65
|
<>
|
|
66
|
-
{categoryState.products?.map(
|
|
66
|
+
{categoryState.products?.sort((a: any, b: any) => a.rank - b.rank).map(
|
|
67
67
|
(product: any, i: any) =>
|
|
68
68
|
product.featured && (
|
|
69
69
|
<SingleProductCard
|
|
@@ -72,7 +72,7 @@ const BusinessProductsListUI = (props: BusinessProductsListParams) => {
|
|
|
72
72
|
product={product}
|
|
73
73
|
businessId={businessId}
|
|
74
74
|
onProductClick={onProductClick}
|
|
75
|
-
|
|
75
|
+
productAddedToCartLength={currentCart?.products?.reduce((productsLength: number, Cproduct: any) => { return productsLength + (Cproduct?.id === product?.id ? Cproduct?.quantity : 0) }, 0)}
|
|
76
76
|
/>
|
|
77
77
|
),
|
|
78
78
|
)}
|
|
@@ -110,14 +110,14 @@ const BusinessProductsListUI = (props: BusinessProductsListParams) => {
|
|
|
110
110
|
</OText>
|
|
111
111
|
</View>
|
|
112
112
|
<>
|
|
113
|
-
{products.map((product: any, i: any) => (
|
|
113
|
+
{products.sort((a: any, b: any) => a.rank - b.rank).map((product: any, i: any) => (
|
|
114
114
|
<SingleProductCard
|
|
115
115
|
key={i}
|
|
116
116
|
isSoldOut={product.inventoried && !product.quantity}
|
|
117
117
|
businessId={businessId}
|
|
118
118
|
product={product}
|
|
119
119
|
onProductClick={onProductClick}
|
|
120
|
-
|
|
120
|
+
productAddedToCartLength={currentCart?.products?.reduce((productsLength: number, Cproduct: any) => { return productsLength + (Cproduct?.id === product?.id ? Cproduct?.quantity : 0) }, 0)}
|
|
121
121
|
/>
|
|
122
122
|
))}
|
|
123
123
|
</>
|
|
@@ -145,6 +145,8 @@ const CartUI = (props: any) => {
|
|
|
145
145
|
handleCartOpen={handleCartOpen}
|
|
146
146
|
onNavigationRedirect={props.onNavigationRedirect}
|
|
147
147
|
handleChangeStore={props.isFranchiseApp ? () => setOpenChangeStore(true) : null}
|
|
148
|
+
handleClickCheckout={() => setOpenUpselling(true)}
|
|
149
|
+
checkoutButtonDisabled={(openUpselling && !canOpenUpselling) || cart?.subtotal < cart?.minimum || !cart?.valid_address}
|
|
148
150
|
>
|
|
149
151
|
{cart?.products?.length > 0 && cart?.products.map((product: any) => (
|
|
150
152
|
<ProductItemAccordion
|
|
@@ -44,7 +44,7 @@ const DriverTipsUI = (props: any) => {
|
|
|
44
44
|
borderWidth: 1,
|
|
45
45
|
borderColor: theme.colors.inputDisabled,
|
|
46
46
|
marginRight: 10,
|
|
47
|
-
height:
|
|
47
|
+
height: 50
|
|
48
48
|
}
|
|
49
49
|
})
|
|
50
50
|
|
|
@@ -63,7 +63,7 @@ const DriverTipsUI = (props: any) => {
|
|
|
63
63
|
return (
|
|
64
64
|
<DTContainer>
|
|
65
65
|
<DTWrapperTips>
|
|
66
|
-
{driverTipsOptions.map((option: any, i: number) => (
|
|
66
|
+
{driverTipsOptions.map((option: any, i: number) => (
|
|
67
67
|
<TouchableOpacity
|
|
68
68
|
key={i}
|
|
69
69
|
onPress={() => handlerChangeOption(option)}
|
|
@@ -72,7 +72,7 @@ const DriverTipsUI = (props: any) => {
|
|
|
72
72
|
style={style.circle}
|
|
73
73
|
isActive={option === optionSelected}
|
|
74
74
|
>
|
|
75
|
-
<OText size={
|
|
75
|
+
<OText size={12} numberOfLines={1} color={option === optionSelected ? '#FFF' : theme.colors.textSecondary}>
|
|
76
76
|
{`${isFixedPrice ? parsePrice(option) : `${option}%`}`}
|
|
77
77
|
</OText>
|
|
78
78
|
</DTCard>
|
|
@@ -15,7 +15,7 @@ export const DTWrapperTips = styled.View`
|
|
|
15
15
|
width: 100%;
|
|
16
16
|
justify-content: space-evenly;
|
|
17
17
|
align-items: center;
|
|
18
|
-
flex-wrap:
|
|
18
|
+
flex-wrap: wrap;
|
|
19
19
|
`
|
|
20
20
|
|
|
21
21
|
export const DTCard = styled.View`
|
|
@@ -24,10 +24,10 @@ export const DTCard = styled.View`
|
|
|
24
24
|
align-items: center;
|
|
25
25
|
border: 1px solid ${(props: any) => props.isActive ? props.theme.colors.primary : props.theme.colors.border};
|
|
26
26
|
text-transform: capitalize;
|
|
27
|
-
min-height:
|
|
28
|
-
min-width:
|
|
29
|
-
max-width:
|
|
30
|
-
max-height:
|
|
27
|
+
min-height: 55px;
|
|
28
|
+
min-width: 55px;
|
|
29
|
+
max-width: 55px;
|
|
30
|
+
max-height: 55px;
|
|
31
31
|
margin-right: 10px;
|
|
32
32
|
margin-left: 10px;
|
|
33
33
|
margin-top: 10px;
|
|
@@ -12,6 +12,9 @@ import { ProductOption } from '../ProductOption';
|
|
|
12
12
|
import Swiper from 'react-native-swiper'
|
|
13
13
|
import FastImage from 'react-native-fast-image';
|
|
14
14
|
import IconAntDesign from 'react-native-vector-icons/AntDesign';
|
|
15
|
+
import {
|
|
16
|
+
Grayscale
|
|
17
|
+
} from 'react-native-color-matrix-image-filters'
|
|
15
18
|
|
|
16
19
|
import { View, TouchableOpacity, StyleSheet, Dimensions, Platform, AppRegistry, I18nManager } from 'react-native';
|
|
17
20
|
|
|
@@ -28,7 +31,9 @@ import {
|
|
|
28
31
|
WrapperSubOption,
|
|
29
32
|
ProductComment,
|
|
30
33
|
ProductActions,
|
|
31
|
-
ExtraOptionWrap
|
|
34
|
+
ExtraOptionWrap,
|
|
35
|
+
WeightUnitSwitch,
|
|
36
|
+
WeightUnitItem
|
|
32
37
|
} from './styles';
|
|
33
38
|
import { OButton, OIcon, OInput, OText } from '../shared';
|
|
34
39
|
import { ScrollView } from 'react-native-gesture-handler';
|
|
@@ -127,6 +132,9 @@ export const ProductOptionsUI = (props: any) => {
|
|
|
127
132
|
height: 32,
|
|
128
133
|
borderRadius: 16,
|
|
129
134
|
backgroundColor: 'rgba(208,208,208,0.5)'
|
|
135
|
+
},
|
|
136
|
+
unitItem: {
|
|
137
|
+
fontSize: 12
|
|
130
138
|
}
|
|
131
139
|
});
|
|
132
140
|
|
|
@@ -141,6 +149,12 @@ export const ProductOptionsUI = (props: any) => {
|
|
|
141
149
|
const { top, bottom } = useSafeAreaInsets();
|
|
142
150
|
const { height } = useWindowDimensions();
|
|
143
151
|
const [selOpt, setSelectedOpt] = useState(0);
|
|
152
|
+
const [isHaveWeight, setIsHaveWeight] = useState(false)
|
|
153
|
+
const [qtyBy, setQtyBy] = useState({
|
|
154
|
+
weight_unit: false,
|
|
155
|
+
pieces: true
|
|
156
|
+
})
|
|
157
|
+
const [pricePerWeightUnit, setPricePerWeightUnit] = useState(null)
|
|
144
158
|
|
|
145
159
|
const swiperRef: any = useRef(null)
|
|
146
160
|
|
|
@@ -149,9 +163,12 @@ export const ProductOptionsUI = (props: any) => {
|
|
|
149
163
|
if (errors[`id:${id}`]) {
|
|
150
164
|
bgColor = 'rgba(255, 0, 0, 0.05)';
|
|
151
165
|
}
|
|
152
|
-
if (
|
|
166
|
+
if (maxProductQuantity <= 0) {
|
|
153
167
|
bgColor = 'hsl(0, 0%, 72%)';
|
|
154
168
|
}
|
|
169
|
+
if (isSoldOut) {
|
|
170
|
+
bgColor = theme.colors.white;
|
|
171
|
+
}
|
|
155
172
|
return bgColor;
|
|
156
173
|
};
|
|
157
174
|
|
|
@@ -193,6 +210,10 @@ export const ProductOptionsUI = (props: any) => {
|
|
|
193
210
|
navigation.navigate('Login');
|
|
194
211
|
};
|
|
195
212
|
|
|
213
|
+
const handleSwitchQtyUnit = (val: string) => {
|
|
214
|
+
setQtyBy({ [val]: true, [!val]: false })
|
|
215
|
+
}
|
|
216
|
+
|
|
196
217
|
useEffect(() => {
|
|
197
218
|
const productImgList: any = []
|
|
198
219
|
product?.images && productImgList.push(product.images)
|
|
@@ -202,6 +223,11 @@ export const ProductOptionsUI = (props: any) => {
|
|
|
202
223
|
}
|
|
203
224
|
}
|
|
204
225
|
setGallery(productImgList)
|
|
226
|
+
|
|
227
|
+
if (product?.weight && product?.weight_unit) {
|
|
228
|
+
setIsHaveWeight(true)
|
|
229
|
+
setPricePerWeightUnit(product?.price / product?.weight)
|
|
230
|
+
}
|
|
205
231
|
}, [product])
|
|
206
232
|
|
|
207
233
|
const saveErrors =
|
|
@@ -316,13 +342,15 @@ export const ProductOptionsUI = (props: any) => {
|
|
|
316
342
|
style={styles.slide1}
|
|
317
343
|
key={i}
|
|
318
344
|
>
|
|
319
|
-
<
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
345
|
+
<Grayscale amount={isSoldOut ? 1 : 0}>
|
|
346
|
+
<FastImage
|
|
347
|
+
style={{ height: '100%' }}
|
|
348
|
+
source={{
|
|
349
|
+
uri: optimizeImage(img, 'h_258,c_limit'),
|
|
350
|
+
priority: FastImage.priority.normal,
|
|
351
|
+
}}
|
|
352
|
+
/>
|
|
353
|
+
</Grayscale>
|
|
326
354
|
</View>
|
|
327
355
|
))}
|
|
328
356
|
</Swiper>
|
|
@@ -346,17 +374,19 @@ export const ProductOptionsUI = (props: any) => {
|
|
|
346
374
|
opacity: index === thumbsSwiper ? 1 : 0.8
|
|
347
375
|
}}
|
|
348
376
|
>
|
|
349
|
-
<
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
377
|
+
<Grayscale amount={isSoldOut ? 1 : 0}>
|
|
378
|
+
<OIcon
|
|
379
|
+
url={img}
|
|
380
|
+
style={{
|
|
381
|
+
borderColor: theme.colors.lightGray,
|
|
382
|
+
borderRadius: 8,
|
|
383
|
+
minHeight: '100%'
|
|
384
|
+
}}
|
|
385
|
+
width={56}
|
|
386
|
+
height={56}
|
|
387
|
+
cover
|
|
388
|
+
/>
|
|
389
|
+
</Grayscale>
|
|
360
390
|
</View>
|
|
361
391
|
</TouchableOpacity>
|
|
362
392
|
|
|
@@ -380,13 +410,30 @@ export const ProductOptionsUI = (props: any) => {
|
|
|
380
410
|
</Placeholder>
|
|
381
411
|
) : (
|
|
382
412
|
<>
|
|
383
|
-
<
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
413
|
+
<View style={{ flexDirection: 'row' }}>
|
|
414
|
+
<OText
|
|
415
|
+
size={20}
|
|
416
|
+
lineHeight={30}
|
|
417
|
+
weight={'600'}
|
|
418
|
+
style={{ flex: 1, marginBottom: 10 }}>
|
|
419
|
+
{product?.name || productCart.name}
|
|
420
|
+
</OText>
|
|
421
|
+
{product?.calories && (
|
|
422
|
+
<OText size={16} style={{ color: '#808080' }}>{product?.calories} cal
|
|
423
|
+
</OText>
|
|
424
|
+
)}
|
|
425
|
+
</View>
|
|
426
|
+
<View style={{ flexDirection: 'row', marginBottom: 10 }}>
|
|
427
|
+
<OText size={16} style={{ flex: I18nManager.isRTL ? 1 : 0 }} color={theme.colors.primary}>{productCart.price ? parsePrice(productCart.price) : ''}</OText>
|
|
428
|
+
{product?.offer_price && (
|
|
429
|
+
<OText style={{ fontSize: 14,
|
|
430
|
+
color: '#808080',
|
|
431
|
+
textDecorationLine: 'line-through',
|
|
432
|
+
marginLeft: 7,
|
|
433
|
+
marginRight: 7
|
|
434
|
+
}}>{parsePrice(product?.offer_price)}</OText>
|
|
435
|
+
)}
|
|
436
|
+
</View>
|
|
390
437
|
{((product?.sku && product?.sku !== '-1' && product?.sku !== '1') || (product?.estimated_person)) && (
|
|
391
438
|
<OText size={14} style={{ flex: I18nManager.isRTL ? 1 : 0 }} color={'#909BA9'} mBottom={7}>
|
|
392
439
|
{
|
|
@@ -401,9 +448,13 @@ export const ProductOptionsUI = (props: any) => {
|
|
|
401
448
|
}
|
|
402
449
|
</OText>
|
|
403
450
|
)}
|
|
404
|
-
|
|
405
|
-
{
|
|
406
|
-
|
|
451
|
+
{isHaveWeight ? (
|
|
452
|
+
<OText size={16} lineHeight={24} color={theme.colors.textNormal}>{parsePrice(pricePerWeightUnit)} / {product?.weight_unit}</OText>
|
|
453
|
+
) : (
|
|
454
|
+
<OText size={16} lineHeight={24} color={theme.colors.textNormal}>
|
|
455
|
+
{productCart.price ? parsePrice(productCart.price) : ''}
|
|
456
|
+
</OText>
|
|
457
|
+
)}
|
|
407
458
|
</>
|
|
408
459
|
)}
|
|
409
460
|
</ProductTitle>
|
|
@@ -488,13 +539,7 @@ export const ProductOptionsUI = (props: any) => {
|
|
|
488
539
|
{t('INGREDIENTS', 'Ingredients')}
|
|
489
540
|
</OText>
|
|
490
541
|
</SectionTitle>
|
|
491
|
-
<WrapperIngredients
|
|
492
|
-
style={{
|
|
493
|
-
backgroundColor:
|
|
494
|
-
isSoldOut || maxProductQuantity <= 0
|
|
495
|
-
? 'hsl(0, 0%, 72%)'
|
|
496
|
-
: theme.colors.white,
|
|
497
|
-
}}>
|
|
542
|
+
<WrapperIngredients>
|
|
498
543
|
{product?.ingredients.map((ingredient: any) => (
|
|
499
544
|
<ProductIngredient
|
|
500
545
|
key={ingredient.id}
|
|
@@ -503,6 +548,7 @@ export const ProductOptionsUI = (props: any) => {
|
|
|
503
548
|
productCart.ingredients[`id:${ingredient.id}`]
|
|
504
549
|
}
|
|
505
550
|
onChange={handleChangeIngredientState}
|
|
551
|
+
isSoldOut={isSoldOut}
|
|
506
552
|
/>
|
|
507
553
|
))}
|
|
508
554
|
</WrapperIngredients>
|
|
@@ -540,6 +586,7 @@ export const ProductOptionsUI = (props: any) => {
|
|
|
540
586
|
return (
|
|
541
587
|
<ProductOptionSubOption
|
|
542
588
|
key={suboption.id}
|
|
589
|
+
isSoldOut={isSoldOut}
|
|
543
590
|
onChange={
|
|
544
591
|
handleChangeSuboptionState
|
|
545
592
|
}
|
|
@@ -573,13 +620,7 @@ export const ProductOptionsUI = (props: any) => {
|
|
|
573
620
|
{t('INGREDIENTS', 'Ingredients')}
|
|
574
621
|
</OText>
|
|
575
622
|
</SectionTitle>
|
|
576
|
-
<WrapperIngredients
|
|
577
|
-
style={{
|
|
578
|
-
backgroundColor:
|
|
579
|
-
isSoldOut || maxProductQuantity <= 0
|
|
580
|
-
? 'hsl(0, 0%, 72%)'
|
|
581
|
-
: theme.colors.white,
|
|
582
|
-
}}>
|
|
623
|
+
<WrapperIngredients>
|
|
583
624
|
{product?.ingredients.map((ingredient: any) => (
|
|
584
625
|
<ProductIngredient
|
|
585
626
|
key={ingredient.id}
|
|
@@ -588,6 +629,7 @@ export const ProductOptionsUI = (props: any) => {
|
|
|
588
629
|
productCart.ingredients[`id:${ingredient.id}`]
|
|
589
630
|
}
|
|
590
631
|
onChange={handleChangeIngredientState}
|
|
632
|
+
isSoldOut={isSoldOut}
|
|
591
633
|
/>
|
|
592
634
|
))}
|
|
593
635
|
</WrapperIngredients>
|
|
@@ -720,8 +762,10 @@ export const ProductOptionsUI = (props: any) => {
|
|
|
720
762
|
<OText
|
|
721
763
|
size={12}
|
|
722
764
|
lineHeight={18}
|
|
723
|
-
style={{ minWidth: 29, textAlign: 'center' }}
|
|
724
|
-
|
|
765
|
+
style={{ minWidth: 29, textAlign: 'center' }}
|
|
766
|
+
>
|
|
767
|
+
{qtyBy?.pieces && productCart.quantity}
|
|
768
|
+
{qtyBy?.weight_unit && productCart.quantity * product?.weight}
|
|
725
769
|
</OText>
|
|
726
770
|
<TouchableOpacity
|
|
727
771
|
onPress={increment}
|
|
@@ -742,6 +786,36 @@ export const ProductOptionsUI = (props: any) => {
|
|
|
742
786
|
}
|
|
743
787
|
/>
|
|
744
788
|
</TouchableOpacity>
|
|
789
|
+
<WeightUnitSwitch>
|
|
790
|
+
<TouchableOpacity
|
|
791
|
+
onPress={() => handleSwitchQtyUnit('pieces')}
|
|
792
|
+
>
|
|
793
|
+
<WeightUnitItem active={qtyBy?.pieces}>
|
|
794
|
+
<OText
|
|
795
|
+
size={12}
|
|
796
|
+
lineHeight={18}
|
|
797
|
+
color={qtyBy?.pieces ? theme.colors.primary : theme.colors.textNormal}
|
|
798
|
+
>
|
|
799
|
+
{t('PIECES', 'pieces')}
|
|
800
|
+
</OText>
|
|
801
|
+
</WeightUnitItem>
|
|
802
|
+
</TouchableOpacity>
|
|
803
|
+
<View style={{ alignItems: 'flex-start' }}>
|
|
804
|
+
<TouchableOpacity
|
|
805
|
+
onPress={() => handleSwitchQtyUnit('weight_unit')}
|
|
806
|
+
>
|
|
807
|
+
<WeightUnitItem active={qtyBy?.weight_unit}>
|
|
808
|
+
<OText
|
|
809
|
+
size={12}
|
|
810
|
+
lineHeight={18}
|
|
811
|
+
color={qtyBy?.weight_unit ? theme.colors.primary : theme.colors.textNormal}
|
|
812
|
+
>
|
|
813
|
+
{product?.weight_unit}
|
|
814
|
+
</OText>
|
|
815
|
+
</WeightUnitItem>
|
|
816
|
+
</TouchableOpacity>
|
|
817
|
+
</View>
|
|
818
|
+
</WeightUnitSwitch>
|
|
745
819
|
</View>
|
|
746
820
|
)}
|
|
747
821
|
<View
|
|
@@ -78,3 +78,15 @@ export const ProductActions = styled.View`
|
|
|
78
78
|
export const ExtraOptionWrap = styled.ScrollView`
|
|
79
79
|
margin-horizontal: -40px;
|
|
80
80
|
`;
|
|
81
|
+
|
|
82
|
+
export const WeightUnitSwitch = styled.View`
|
|
83
|
+
margin-left: 10px;
|
|
84
|
+
`
|
|
85
|
+
export const WeightUnitItem = styled.View`
|
|
86
|
+
padding: 1px 5px;
|
|
87
|
+
border-radius: 4px;
|
|
88
|
+
|
|
89
|
+
${({ active }: any) => active && css`
|
|
90
|
+
background-color: ${(props: any) => props.theme.colors.primary}20;
|
|
91
|
+
`}
|
|
92
|
+
`
|
|
@@ -10,18 +10,19 @@ const ProductIngredientUI = (props: any) => {
|
|
|
10
10
|
const {
|
|
11
11
|
state,
|
|
12
12
|
ingredient,
|
|
13
|
-
toggleSelect
|
|
13
|
+
toggleSelect,
|
|
14
|
+
isSoldOut
|
|
14
15
|
} = props
|
|
15
16
|
|
|
16
17
|
const theme = useTheme();
|
|
17
18
|
|
|
18
19
|
return (
|
|
19
|
-
<Container onPress={() => toggleSelect()}>
|
|
20
|
+
<Container disabled={isSoldOut} onPress={() => toggleSelect()}>
|
|
20
21
|
<View>
|
|
21
|
-
{state?.selected ? (
|
|
22
|
+
{state?.selected && !isSoldOut ? (
|
|
22
23
|
<MaterialCommunityIcon name='checkbox-marked' color={theme.colors.primary} size={24} />
|
|
23
24
|
) : (
|
|
24
|
-
<MaterialCommunityIcon name='checkbox-blank-outline' color=
|
|
25
|
+
<MaterialCommunityIcon name='checkbox-blank-outline' color='#cbcbcb' size={24} />
|
|
25
26
|
)}
|
|
26
27
|
</View>
|
|
27
28
|
<OText mLeft={10}>
|
|
@@ -212,8 +212,8 @@ export const ProductItemAccordion = (props: ProductItemAccordionParams) => {
|
|
|
212
212
|
</View>
|
|
213
213
|
{((isCartProduct && !isCartPending && product?.valid_menu && !product?.valid_quantity) ||
|
|
214
214
|
(!product?.valid_menu && isCartProduct && !isCartPending)) && (
|
|
215
|
-
<View style={{ alignItems: 'flex-end', width: '100%' }}>
|
|
216
|
-
<OText size={14} color={theme.colors.red} style={{ textAlign: 'right',
|
|
215
|
+
<View style={{ alignItems: 'flex-end', width: '100%', }}>
|
|
216
|
+
<OText size={14} color={theme.colors.red} style={{ textAlign: 'right', marginTop: 5 }}>
|
|
217
217
|
{t('NOT_AVAILABLE', 'Not available')}
|
|
218
218
|
</OText>
|
|
219
219
|
</View>
|
|
@@ -53,8 +53,8 @@ export const ProductOptionSubOptionUI = (props: any) => {
|
|
|
53
53
|
const price = option?.with_half_option && suboption?.half_price && state.position !== 'whole' ? suboption?.half_price : suboption?.price
|
|
54
54
|
|
|
55
55
|
return (
|
|
56
|
-
<Container
|
|
57
|
-
<IconControl onPress={() => handleSuboptionClick()}>
|
|
56
|
+
<Container>
|
|
57
|
+
<IconControl disabled={disabled} onPress={() => handleSuboptionClick()}>
|
|
58
58
|
{((option?.min === 0 && option?.max === 1) || option?.max > 1) ? (
|
|
59
59
|
state?.selected ? (
|
|
60
60
|
<OIcon src={theme.images.general.check_act} color={theme.colors.primary} width={16} />
|
|
@@ -73,30 +73,30 @@ export const ProductOptionSubOptionUI = (props: any) => {
|
|
|
73
73
|
</OText>
|
|
74
74
|
</IconControl>
|
|
75
75
|
{showMessage && <OText size={10} mLeft={4} mRight={4} style={{ flex: 1, textAlign: 'center' }} color={theme.colors.primary}>{`${t('OPTIONS_MAX_LIMIT', 'Maximum options to choose')}: ${option?.max}`}</OText>}
|
|
76
|
-
{option?.allow_suboption_quantity && (
|
|
76
|
+
{option?.allow_suboption_quantity && state?.selected && (
|
|
77
77
|
<QuantityControl>
|
|
78
|
-
<Checkbox disabled={state.quantity === 0} onPress={decrement}>
|
|
78
|
+
<Checkbox disabled={disabled || state.quantity === 0} onPress={decrement}>
|
|
79
79
|
<OIcon
|
|
80
80
|
src={theme.images.general.minus}
|
|
81
81
|
width={16}
|
|
82
|
-
color={state.quantity === 0 ? theme.colors.disabled : theme.colors.primary}
|
|
82
|
+
color={state.quantity === 0 || disabled ? theme.colors.disabled : theme.colors.primary}
|
|
83
83
|
/>
|
|
84
84
|
</Checkbox>
|
|
85
85
|
<OText mLeft={5} mRight={5}>
|
|
86
86
|
{state.quantity}
|
|
87
87
|
</OText>
|
|
88
|
-
<Checkbox disabled={disableIncrement} onPress={increment}>
|
|
88
|
+
<Checkbox disabled={disabled || disableIncrement} onPress={increment}>
|
|
89
89
|
<OIcon
|
|
90
90
|
src={theme.images.general.plus}
|
|
91
91
|
width={16}
|
|
92
|
-
color={disableIncrement ? theme.colors.disabled : theme.colors.primary}
|
|
92
|
+
color={disableIncrement || disabled ? theme.colors.disabled : theme.colors.primary}
|
|
93
93
|
/>
|
|
94
94
|
</Checkbox>
|
|
95
95
|
</QuantityControl>
|
|
96
96
|
)}
|
|
97
|
-
{option?.with_half_option && (
|
|
97
|
+
{option?.with_half_option && state?.selected && (
|
|
98
98
|
<PositionControl>
|
|
99
|
-
<Circle onPress={() => changePosition('left')}>
|
|
99
|
+
<Circle disabled={disabled} onPress={() => changePosition('left')}>
|
|
100
100
|
<OIcon
|
|
101
101
|
src={theme.images.general.half_l}
|
|
102
102
|
color={state.selected && state.position === 'left' ? theme.colors.primary : '#cbcbcb'}
|
|
@@ -104,14 +104,14 @@ export const ProductOptionSubOptionUI = (props: any) => {
|
|
|
104
104
|
style={styles.inverse}
|
|
105
105
|
/>
|
|
106
106
|
</Circle>
|
|
107
|
-
<Circle onPress={() => changePosition('whole')}>
|
|
107
|
+
<Circle disabled={disabled} onPress={() => changePosition('whole')}>
|
|
108
108
|
<OIcon
|
|
109
109
|
src={theme.images.general.half_f}
|
|
110
110
|
color={state.selected && state.position === 'whole' ? theme.colors.primary : '#cbcbcb'}
|
|
111
111
|
width={16}
|
|
112
112
|
/>
|
|
113
113
|
</Circle>
|
|
114
|
-
<Circle onPress={() => changePosition('right')}>
|
|
114
|
+
<Circle disabled={disabled} onPress={() => changePosition('right')}>
|
|
115
115
|
<OIcon
|
|
116
116
|
src={theme.images.general.half_r}
|
|
117
117
|
color={state.selected && state.position === 'right' ? theme.colors.primary : '#cbcbcb'}
|
|
@@ -13,7 +13,7 @@ import { OText, OIcon } from '../shared';
|
|
|
13
13
|
import FastImage from 'react-native-fast-image'
|
|
14
14
|
|
|
15
15
|
export const SingleProductCard = (props: SingleProductCardParams) => {
|
|
16
|
-
const { businessId, product, isSoldOut, onProductClick,
|
|
16
|
+
const { businessId, product, isSoldOut, onProductClick, productAddedToCartLength } = props;
|
|
17
17
|
|
|
18
18
|
const theme = useTheme();
|
|
19
19
|
|
|
@@ -90,7 +90,6 @@ export const SingleProductCard = (props: SingleProductCardParams) => {
|
|
|
90
90
|
maxCartProductConfig,
|
|
91
91
|
maxCartProductInventory,
|
|
92
92
|
);
|
|
93
|
-
|
|
94
93
|
return (
|
|
95
94
|
<CardContainer
|
|
96
95
|
style={[
|
|
@@ -98,11 +97,11 @@ export const SingleProductCard = (props: SingleProductCardParams) => {
|
|
|
98
97
|
(isSoldOut || maxProductQuantity <= 0) && styles.soldOutBackgroundStyle,
|
|
99
98
|
]}
|
|
100
99
|
onPress={() => onProductClick?.(product)}>
|
|
101
|
-
{
|
|
100
|
+
{productAddedToCartLength > 0 && (
|
|
102
101
|
<QuantityContainer style={[styles.quantityContainer, {
|
|
103
102
|
transform: [{ translateX: 10 }, { translateY: -10 }],
|
|
104
103
|
}]}>
|
|
105
|
-
<OText color={theme.colors.white}>{
|
|
104
|
+
<OText size={12} color={theme.colors.white}>{productAddedToCartLength.toString()}</OText>
|
|
106
105
|
</QuantityContainer>
|
|
107
106
|
)}
|
|
108
107
|
<CardInfo>
|
|
@@ -221,7 +221,7 @@ export interface SingleProductCardParams {
|
|
|
221
221
|
product: any;
|
|
222
222
|
isSoldOut: boolean;
|
|
223
223
|
onProductClick: any;
|
|
224
|
-
|
|
224
|
+
productAddedToCartLength: number
|
|
225
225
|
}
|
|
226
226
|
export interface BusinessInformationParams {
|
|
227
227
|
navigation?: any,
|