ordering-ui-react-native 0.14.25 → 0.14.29
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/Checkout/index.tsx +3 -3
- package/src/components/Messages/index.tsx +6 -1
- 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/BusinessProductsList/index.tsx +3 -3
- package/themes/original/src/components/Cart/index.tsx +2 -0
- package/themes/original/src/components/Checkout/index.tsx +1 -1
- package/themes/original/src/components/Messages/index.tsx +39 -59
- package/themes/original/src/components/OrderDetails/index.tsx +2 -0
- package/themes/original/src/components/ProductForm/index.tsx +96 -39
- 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/ProductOptionSubOption/index.tsx +11 -11
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.29",
|
|
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",
|
|
@@ -150,10 +150,10 @@ const CheckoutUI = (props: any) => {
|
|
|
150
150
|
const isPreOrderSetting = configs?.preorder_status_enabled?.value === '1'
|
|
151
151
|
const cartsWithProducts = carts && Object.values(carts).filter((cart: any) => cart.products.length) || null
|
|
152
152
|
|
|
153
|
-
const deliveryOptions = instructionsOptions?.result && instructionsOptions?.result?.filter((option: any) => option?.enabled)?.map(option => {
|
|
153
|
+
const deliveryOptions = instructionsOptions?.result && instructionsOptions?.result?.filter((option: any) => option?.enabled)?.map((option: any) => {
|
|
154
154
|
return {
|
|
155
|
-
|
|
156
|
-
|
|
155
|
+
value: option?.id, key: option?.id, label: t(option?.name.toUpperCase().replace(/\s/g, '_'), option?.name)
|
|
156
|
+
}
|
|
157
157
|
})
|
|
158
158
|
|
|
159
159
|
const handlePlaceOrder = () => {
|
|
@@ -45,6 +45,7 @@ const imgOptions = {
|
|
|
45
45
|
includeBase64: true,
|
|
46
46
|
selectionLimit: 0
|
|
47
47
|
}
|
|
48
|
+
const filterSpecialStatus = ['prepared_in', 'delivered_in']
|
|
48
49
|
|
|
49
50
|
const MessagesUI = (props: MessagesParams) => {
|
|
50
51
|
const {
|
|
@@ -118,7 +119,11 @@ const MessagesUI = (props: MessagesParams) => {
|
|
|
118
119
|
const messageConsole = (message: any) => {
|
|
119
120
|
return message.change?.attribute !== 'driver_id'
|
|
120
121
|
?
|
|
121
|
-
`${t('ORDER', 'Order')} ${t(message.change.attribute.toUpperCase(), message.change.attribute.replace('_', ' '))} ${t('CHANGED_FROM', 'Changed from')} ${
|
|
122
|
+
`${t('ORDER', 'Order')} ${t(message.change.attribute.toUpperCase(), message.change.attribute.replace('_', ' '))} ${t('CHANGED_FROM', 'Changed from')} ${
|
|
123
|
+
filterSpecialStatus.includes(message.change.attribute) ?
|
|
124
|
+
`${message.change.old === null ? '0' : message.change.old} ${t('TO', 'to')} ${message.change.new} ${t('MINUTES', 'Minutes')}` :
|
|
125
|
+
`${message.change.old !== null && t(ORDER_STATUS[parseInt(message.change.old, 10)])} ${t('TO', 'to')} ${t(ORDER_STATUS[parseInt(message.change.new, 10)])}`
|
|
126
|
+
}`
|
|
122
127
|
: message.change.new
|
|
123
128
|
?
|
|
124
129
|
`${message.driver?.name} ${message.driver?.lastname !== null ? message.driver.lastname : ''} ${t('WAS_ASSIGNED_AS_DRIVER', 'Was assigned as driver')} ${message.comment ? message.comment.length : ''}`
|
|
@@ -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}
|
|
@@ -42,7 +42,7 @@ 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}
|
|
@@ -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
|
|
@@ -110,7 +110,7 @@ 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}
|
|
@@ -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
|
|
@@ -137,7 +137,7 @@ const CheckoutUI = (props: any) => {
|
|
|
137
137
|
|
|
138
138
|
const deliveryOptions = instructionsOptions?.result && instructionsOptions?.result?.filter((option: any) => option?.enabled)?.map((option: any) => {
|
|
139
139
|
return {
|
|
140
|
-
value: option?.id, key: option?.id, label: option?.name
|
|
140
|
+
value: option?.id, key: option?.id, label: t(option?.name.toUpperCase().replace(/\s/g, '_'), option?.name)
|
|
141
141
|
}
|
|
142
142
|
})
|
|
143
143
|
|
|
@@ -12,6 +12,34 @@ import { MessagesParams } from '../../types'
|
|
|
12
12
|
import { useWindowDimensions } from 'react-native'
|
|
13
13
|
import { useSafeAreaInsets } from 'react-native-safe-area-context'
|
|
14
14
|
|
|
15
|
+
const ORDER_STATUS: any = {
|
|
16
|
+
0: 'ORDER_STATUS_PENDING',
|
|
17
|
+
1: 'ORDERS_COMPLETED',
|
|
18
|
+
2: 'ORDER_REJECTED',
|
|
19
|
+
3: 'ORDER_STATUS_IN_BUSINESS',
|
|
20
|
+
4: 'ORDER_READY',
|
|
21
|
+
5: 'ORDER_REJECTED_RESTAURANT',
|
|
22
|
+
6: 'ORDER_STATUS_CANCELLEDBYDRIVER',
|
|
23
|
+
7: 'ORDER_STATUS_ACCEPTEDBYRESTAURANT',
|
|
24
|
+
8: 'ORDER_CONFIRMED_ACCEPTED_BY_DRIVER',
|
|
25
|
+
9: 'ORDER_PICKUP_COMPLETED_BY_DRIVER',
|
|
26
|
+
10: 'ORDER_PICKUP_FAILED_BY_DRIVER',
|
|
27
|
+
11: 'ORDER_DELIVERY_COMPLETED_BY_DRIVER',
|
|
28
|
+
12: 'ORDER_DELIVERY_FAILED_BY_DRIVER',
|
|
29
|
+
13: 'PREORDER',
|
|
30
|
+
14: 'ORDER_NOT_READY',
|
|
31
|
+
15: 'ORDER_PICKEDUP_COMPLETED_BY_CUSTOMER',
|
|
32
|
+
16: 'ORDER_STATUS_CANCELLED_BY_CUSTOMER',
|
|
33
|
+
17: 'ORDER_NOT_PICKEDUP_BY_CUSTOMER',
|
|
34
|
+
18: 'ORDER_DRIVER_ALMOST_ARRIVED_BUSINESS',
|
|
35
|
+
19: 'ORDER_DRIVER_ALMOST_ARRIVED_CUSTOMER',
|
|
36
|
+
20: 'ORDER_CUSTOMER_ALMOST_ARRIVED_BUSINESS',
|
|
37
|
+
21: 'ORDER_CUSTOMER_ARRIVED_BUSINESS',
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const filterSpecialStatus = ['prepared_in', 'delivered_in']
|
|
41
|
+
|
|
42
|
+
|
|
15
43
|
const MessagesUI = (props: MessagesParams) => {
|
|
16
44
|
const {
|
|
17
45
|
type,
|
|
@@ -94,58 +122,6 @@ const MessagesUI = (props: MessagesParams) => {
|
|
|
94
122
|
});
|
|
95
123
|
};
|
|
96
124
|
|
|
97
|
-
const getStatus = (status: number) => {
|
|
98
|
-
|
|
99
|
-
switch (status) {
|
|
100
|
-
case 0:
|
|
101
|
-
return 'ORDER_STATUS_PENDING'
|
|
102
|
-
case 1:
|
|
103
|
-
return 'ORDERS_COMPLETED'
|
|
104
|
-
case 2:
|
|
105
|
-
return 'ORDER_REJECTED'
|
|
106
|
-
case 3:
|
|
107
|
-
return 'ORDER_STATUS_IN_BUSINESS'
|
|
108
|
-
case 4:
|
|
109
|
-
return 'ORDER_READY'
|
|
110
|
-
case 5:
|
|
111
|
-
return 'ORDER_REJECTED_RESTAURANT'
|
|
112
|
-
case 6:
|
|
113
|
-
return 'ORDER_STATUS_CANCELLEDBYDRIVER'
|
|
114
|
-
case 7:
|
|
115
|
-
return 'ORDER_STATUS_ACCEPTEDBYRESTAURANT'
|
|
116
|
-
case 8:
|
|
117
|
-
return 'ORDER_CONFIRMED_ACCEPTED_BY_DRIVER'
|
|
118
|
-
case 9:
|
|
119
|
-
return 'ORDER_PICKUP_COMPLETED_BY_DRIVER'
|
|
120
|
-
case 10:
|
|
121
|
-
return 'ORDER_PICKUP_FAILED_BY_DRIVER'
|
|
122
|
-
case 11:
|
|
123
|
-
return 'ORDER_DELIVERY_COMPLETED_BY_DRIVER'
|
|
124
|
-
case 12:
|
|
125
|
-
return 'ORDER_DELIVERY_FAILED_BY_DRIVER'
|
|
126
|
-
case 13:
|
|
127
|
-
return 'PREORDER'
|
|
128
|
-
case 14:
|
|
129
|
-
return 'ORDER_NOT_READY'
|
|
130
|
-
case 15:
|
|
131
|
-
return 'ORDER_PICKEDUP_COMPLETED_BY_CUSTOMER'
|
|
132
|
-
case 16:
|
|
133
|
-
return 'ORDER_STATUS_CANCELLED_BY_CUSTOMER'
|
|
134
|
-
case 17:
|
|
135
|
-
return 'ORDER_NOT_PICKEDUP_BY_CUSTOMER'
|
|
136
|
-
case 18:
|
|
137
|
-
return 'ORDER_DRIVER_ALMOST_ARRIVED_BUSINESS'
|
|
138
|
-
case 19:
|
|
139
|
-
return 'ORDER_DRIVER_ALMOST_ARRIVED_CUSTOMER'
|
|
140
|
-
case 20:
|
|
141
|
-
return 'ORDER_CUSTOMER_ALMOST_ARRIVED_BUSINESS'
|
|
142
|
-
case 21:
|
|
143
|
-
return 'ORDER_CUSTOMER_ARRIVED_BUSINESS'
|
|
144
|
-
default:
|
|
145
|
-
return status
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
|
|
149
125
|
const onSubmit = (values: any) => {
|
|
150
126
|
handleSend && handleSend()
|
|
151
127
|
setImage && setImage(null)
|
|
@@ -154,14 +130,18 @@ const MessagesUI = (props: MessagesParams) => {
|
|
|
154
130
|
|
|
155
131
|
const messageConsole = (message: any) => {
|
|
156
132
|
return message.change?.attribute !== 'driver_id'
|
|
133
|
+
?
|
|
134
|
+
`${t('ORDER', 'Order')} ${t(message.change.attribute.toUpperCase(), message.change.attribute.replace('_', ' '))} ${t('CHANGED_FROM', 'Changed from')} ${
|
|
135
|
+
filterSpecialStatus.includes(message.change.attribute) ?
|
|
136
|
+
`${message.change.old === null ? '0' : message.change.old} ${t('TO', 'to')} ${message.change.new} ${t('MINUTES', 'Minutes')}` :
|
|
137
|
+
`${message.change.old !== null && t(ORDER_STATUS[parseInt(message.change.old, 10)])} ${t('TO', 'to')} ${t(ORDER_STATUS[parseInt(message.change.new, 10)])}`
|
|
138
|
+
}`
|
|
139
|
+
: message.change.new
|
|
157
140
|
?
|
|
158
|
-
`${
|
|
159
|
-
:
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
:
|
|
163
|
-
`${t('DRIVER_UNASSIGNED', 'Driver unassigned')}`
|
|
164
|
-
}
|
|
141
|
+
`${message.driver?.name} ${message.driver?.lastname !== null ? message.driver.lastname : ''} ${t('WAS_ASSIGNED_AS_DRIVER', 'Was assigned as driver')} ${message.comment ? message.comment.length : ''}`
|
|
142
|
+
:
|
|
143
|
+
`${t('DRIVER_UNASSIGNED', 'Driver unassigned')}`
|
|
144
|
+
}
|
|
165
145
|
|
|
166
146
|
useEffect(() => {
|
|
167
147
|
let newMessages: Array<any> = []
|
|
@@ -894,6 +894,8 @@ export const OrderDetailsUI = (props: OrderDetailsParams) => {
|
|
|
894
894
|
orderId={order?.id}
|
|
895
895
|
messages={messages}
|
|
896
896
|
order={order}
|
|
897
|
+
business={openModalForBusiness}
|
|
898
|
+
driver={openModalForDriver}
|
|
897
899
|
setMessages={setMessages}
|
|
898
900
|
onClose={handleCloseModal}
|
|
899
901
|
/>
|
|
@@ -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
|
|
|
@@ -401,9 +431,13 @@ export const ProductOptionsUI = (props: any) => {
|
|
|
401
431
|
}
|
|
402
432
|
</OText>
|
|
403
433
|
)}
|
|
404
|
-
|
|
405
|
-
{
|
|
406
|
-
|
|
434
|
+
{isHaveWeight ? (
|
|
435
|
+
<OText size={16} lineHeight={24} color={theme.colors.textNormal}>{parsePrice(pricePerWeightUnit)} / {product?.weight_unit}</OText>
|
|
436
|
+
) : (
|
|
437
|
+
<OText size={16} lineHeight={24} color={theme.colors.textNormal}>
|
|
438
|
+
{productCart.price ? parsePrice(productCart.price) : ''}
|
|
439
|
+
</OText>
|
|
440
|
+
)}
|
|
407
441
|
</>
|
|
408
442
|
)}
|
|
409
443
|
</ProductTitle>
|
|
@@ -488,13 +522,7 @@ export const ProductOptionsUI = (props: any) => {
|
|
|
488
522
|
{t('INGREDIENTS', 'Ingredients')}
|
|
489
523
|
</OText>
|
|
490
524
|
</SectionTitle>
|
|
491
|
-
<WrapperIngredients
|
|
492
|
-
style={{
|
|
493
|
-
backgroundColor:
|
|
494
|
-
isSoldOut || maxProductQuantity <= 0
|
|
495
|
-
? 'hsl(0, 0%, 72%)'
|
|
496
|
-
: theme.colors.white,
|
|
497
|
-
}}>
|
|
525
|
+
<WrapperIngredients>
|
|
498
526
|
{product?.ingredients.map((ingredient: any) => (
|
|
499
527
|
<ProductIngredient
|
|
500
528
|
key={ingredient.id}
|
|
@@ -503,6 +531,7 @@ export const ProductOptionsUI = (props: any) => {
|
|
|
503
531
|
productCart.ingredients[`id:${ingredient.id}`]
|
|
504
532
|
}
|
|
505
533
|
onChange={handleChangeIngredientState}
|
|
534
|
+
isSoldOut={isSoldOut}
|
|
506
535
|
/>
|
|
507
536
|
))}
|
|
508
537
|
</WrapperIngredients>
|
|
@@ -540,6 +569,7 @@ export const ProductOptionsUI = (props: any) => {
|
|
|
540
569
|
return (
|
|
541
570
|
<ProductOptionSubOption
|
|
542
571
|
key={suboption.id}
|
|
572
|
+
isSoldOut={isSoldOut}
|
|
543
573
|
onChange={
|
|
544
574
|
handleChangeSuboptionState
|
|
545
575
|
}
|
|
@@ -573,13 +603,7 @@ export const ProductOptionsUI = (props: any) => {
|
|
|
573
603
|
{t('INGREDIENTS', 'Ingredients')}
|
|
574
604
|
</OText>
|
|
575
605
|
</SectionTitle>
|
|
576
|
-
<WrapperIngredients
|
|
577
|
-
style={{
|
|
578
|
-
backgroundColor:
|
|
579
|
-
isSoldOut || maxProductQuantity <= 0
|
|
580
|
-
? 'hsl(0, 0%, 72%)'
|
|
581
|
-
: theme.colors.white,
|
|
582
|
-
}}>
|
|
606
|
+
<WrapperIngredients>
|
|
583
607
|
{product?.ingredients.map((ingredient: any) => (
|
|
584
608
|
<ProductIngredient
|
|
585
609
|
key={ingredient.id}
|
|
@@ -588,6 +612,7 @@ export const ProductOptionsUI = (props: any) => {
|
|
|
588
612
|
productCart.ingredients[`id:${ingredient.id}`]
|
|
589
613
|
}
|
|
590
614
|
onChange={handleChangeIngredientState}
|
|
615
|
+
isSoldOut={isSoldOut}
|
|
591
616
|
/>
|
|
592
617
|
))}
|
|
593
618
|
</WrapperIngredients>
|
|
@@ -720,8 +745,10 @@ export const ProductOptionsUI = (props: any) => {
|
|
|
720
745
|
<OText
|
|
721
746
|
size={12}
|
|
722
747
|
lineHeight={18}
|
|
723
|
-
style={{ minWidth: 29, textAlign: 'center' }}
|
|
724
|
-
|
|
748
|
+
style={{ minWidth: 29, textAlign: 'center' }}
|
|
749
|
+
>
|
|
750
|
+
{qtyBy?.pieces && productCart.quantity}
|
|
751
|
+
{qtyBy?.weight_unit && productCart.quantity * product?.weight}
|
|
725
752
|
</OText>
|
|
726
753
|
<TouchableOpacity
|
|
727
754
|
onPress={increment}
|
|
@@ -742,6 +769,36 @@ export const ProductOptionsUI = (props: any) => {
|
|
|
742
769
|
}
|
|
743
770
|
/>
|
|
744
771
|
</TouchableOpacity>
|
|
772
|
+
<WeightUnitSwitch>
|
|
773
|
+
<TouchableOpacity
|
|
774
|
+
onPress={() => handleSwitchQtyUnit('pieces')}
|
|
775
|
+
>
|
|
776
|
+
<WeightUnitItem active={qtyBy?.pieces}>
|
|
777
|
+
<OText
|
|
778
|
+
size={12}
|
|
779
|
+
lineHeight={18}
|
|
780
|
+
color={qtyBy?.pieces ? theme.colors.primary : theme.colors.textNormal}
|
|
781
|
+
>
|
|
782
|
+
{t('PIECES', 'pieces')}
|
|
783
|
+
</OText>
|
|
784
|
+
</WeightUnitItem>
|
|
785
|
+
</TouchableOpacity>
|
|
786
|
+
<View style={{ alignItems: 'flex-start' }}>
|
|
787
|
+
<TouchableOpacity
|
|
788
|
+
onPress={() => handleSwitchQtyUnit('weight_unit')}
|
|
789
|
+
>
|
|
790
|
+
<WeightUnitItem active={qtyBy?.weight_unit}>
|
|
791
|
+
<OText
|
|
792
|
+
size={12}
|
|
793
|
+
lineHeight={18}
|
|
794
|
+
color={qtyBy?.weight_unit ? theme.colors.primary : theme.colors.textNormal}
|
|
795
|
+
>
|
|
796
|
+
{product?.weight_unit}
|
|
797
|
+
</OText>
|
|
798
|
+
</WeightUnitItem>
|
|
799
|
+
</TouchableOpacity>
|
|
800
|
+
</View>
|
|
801
|
+
</WeightUnitSwitch>
|
|
745
802
|
</View>
|
|
746
803
|
)}
|
|
747
804
|
<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}>
|
|
@@ -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'}
|