ordering-ui-react-native 0.14.41 → 0.14.42-release
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 -2
- package/src/components/BusinessItemAccordion/index.tsx +2 -2
- package/src/components/Cart/index.tsx +135 -42
- package/src/components/Cart/styles.tsx +7 -0
- package/src/components/Checkout/index.tsx +28 -166
- package/src/components/OrderDetails/index.tsx +102 -34
- package/src/components/OrderDetails/styles.tsx +7 -0
- package/src/components/OrderSummary/index.tsx +140 -37
- package/src/components/OrderSummary/styles.tsx +10 -2
- package/src/components/PaymentOptions/index.tsx +3 -1
- package/src/components/PaymentOptionsWebView/index.tsx +150 -0
- package/src/components/ProductForm/index.tsx +6 -6
- package/src/components/SingleProductCard/index.tsx +1 -1
- package/src/components/StripeElementsForm/index.tsx +28 -13
- package/src/components/TaxInformation/index.tsx +58 -26
- package/src/components/VerifyPhone/styles.tsx +1 -2
- package/src/components/shared/OIcon.tsx +4 -1
- package/src/index.tsx +2 -0
- package/src/navigators/HomeNavigator.tsx +6 -0
- package/src/pages/ProductDetails.tsx +55 -0
- package/themes/doordash/src/components/LoginForm/index.tsx +1 -2
- package/themes/kiosk/src/components/Cart/index.tsx +14 -21
- package/themes/kiosk/src/components/CartItem/index.tsx +9 -7
- package/themes/kiosk/src/components/CustomerName/index.tsx +2 -1
- package/themes/kiosk/src/components/Intro/index.tsx +4 -4
- package/themes/kiosk/src/components/OptionCard/index.tsx +11 -6
- package/themes/kiosk/src/components/PaymentOptions/index.tsx +46 -44
- package/themes/original/src/components/BusinessController/index.tsx +3 -3
- package/themes/original/src/components/BusinessFeaturedController/index.tsx +2 -2
- package/themes/original/src/components/BusinessItemAccordion/index.tsx +12 -9
- package/themes/original/src/components/BusinessItemAccordion/styles.tsx +3 -2
- package/themes/original/src/components/BusinessProductsListing/index.tsx +8 -4
- package/themes/original/src/components/BusinessesListing/index.tsx +129 -94
- package/themes/original/src/components/Cart/index.tsx +122 -24
- package/themes/original/src/components/Cart/styles.tsx +8 -1
- package/themes/original/src/components/Checkout/index.tsx +37 -3
- package/themes/original/src/components/Help/index.tsx +1 -1
- package/themes/original/src/components/HighestRatedBusinesses/index.tsx +1 -0
- package/themes/original/src/components/MessageListing/index.tsx +4 -2
- package/themes/original/src/components/MomentOption/index.tsx +150 -158
- package/themes/original/src/components/OrderDetails/index.tsx +114 -42
- package/themes/original/src/components/OrderDetails/styles.tsx +8 -1
- package/themes/original/src/components/OrderProgress/index.tsx +2 -1
- package/themes/original/src/components/OrderSummary/index.tsx +132 -23
- package/themes/original/src/components/OrderSummary/styles.tsx +7 -0
- package/themes/original/src/components/PaymentOptions/index.tsx +8 -2
- package/themes/original/src/components/ProductForm/index.tsx +63 -56
- package/themes/original/src/components/ProductOptionSubOption/index.tsx +54 -51
- package/themes/original/src/components/ProductOptionSubOption/styles.tsx +8 -1
- package/themes/original/src/components/SingleProductCard/index.tsx +36 -19
- package/themes/original/src/components/SingleProductCard/styles.tsx +4 -0
- package/themes/original/src/components/StripeElementsForm/index.tsx +28 -13
- package/themes/original/src/components/TaxInformation/index.tsx +59 -27
- package/themes/original/src/components/UpsellingProducts/index.tsx +26 -18
- package/themes/original/src/types/index.tsx +2 -0
|
@@ -116,5 +116,12 @@ export const Map = styled.View`
|
|
|
116
116
|
width: 100%;
|
|
117
117
|
height: 250px;
|
|
118
118
|
margin-top: 20px;
|
|
119
|
-
border-radius: 20px
|
|
119
|
+
border-radius: 20px;
|
|
120
|
+
`
|
|
121
|
+
|
|
122
|
+
export const Divider = styled.View`
|
|
123
|
+
border-color: #EAEAEA;
|
|
124
|
+
border-width: 1px;
|
|
125
|
+
margin-top: 5px;
|
|
126
|
+
margin-bottom: 5px;
|
|
120
127
|
`
|
|
@@ -108,7 +108,8 @@ const OrderProgressUI = (props: any) => {
|
|
|
108
108
|
const deliveryTime = order?.delivery_datetime_utc
|
|
109
109
|
? parseDate(order?.delivery_datetime_utc, { outputFormat: 'YYYY-MM-DD HH:mm' })
|
|
110
110
|
: parseDate(order?.delivery_datetime, { utc: false, outputFormat: 'YYYY-MM-DD HH:mm' })
|
|
111
|
-
const
|
|
111
|
+
const hour = time?.split(':')?.[0]
|
|
112
|
+
const minute = time?.split(':')?.[1]
|
|
112
113
|
const result = time ? (parseInt(hour, 10) * 60) + parseInt(minute, 10) : 0
|
|
113
114
|
const returnedDate = moment(deliveryTime).add(result, 'minutes').format('hh:mm A')
|
|
114
115
|
return returnedDate
|
|
@@ -14,7 +14,8 @@ import {
|
|
|
14
14
|
OSProductList,
|
|
15
15
|
OSBill,
|
|
16
16
|
OSTable,
|
|
17
|
-
OSRow
|
|
17
|
+
OSRow,
|
|
18
|
+
Divider
|
|
18
19
|
} from './styles';
|
|
19
20
|
|
|
20
21
|
import { ProductItemAccordion } from '../ProductItemAccordion';
|
|
@@ -24,6 +25,7 @@ import { verifyDecimals } from '../../utils';
|
|
|
24
25
|
import AntIcon from 'react-native-vector-icons/AntDesign'
|
|
25
26
|
import { TaxInformation } from '../TaxInformation';
|
|
26
27
|
import { TouchableOpacity } from 'react-native';
|
|
28
|
+
import { OAlert } from '../../../../../src/components/shared'
|
|
27
29
|
|
|
28
30
|
const OrderSummaryUI = (props: any) => {
|
|
29
31
|
const {
|
|
@@ -35,7 +37,8 @@ const OrderSummaryUI = (props: any) => {
|
|
|
35
37
|
isFromCheckout,
|
|
36
38
|
commentState,
|
|
37
39
|
handleChangeComment,
|
|
38
|
-
onNavigationRedirect
|
|
40
|
+
onNavigationRedirect,
|
|
41
|
+
handleRemoveOfferClick
|
|
39
42
|
} = props;
|
|
40
43
|
|
|
41
44
|
const theme = useTheme()
|
|
@@ -44,8 +47,8 @@ const OrderSummaryUI = (props: any) => {
|
|
|
44
47
|
const [orderState] = useOrder();
|
|
45
48
|
const [{ parsePrice, parseNumber }] = useUtils();
|
|
46
49
|
const [validationFields] = useValidationFields();
|
|
47
|
-
const [openTaxModal, setOpenTaxModal] = useState<any>({ open: false, data: null })
|
|
48
|
-
|
|
50
|
+
const [openTaxModal, setOpenTaxModal] = useState<any>({ open: false, data: null, type: '' })
|
|
51
|
+
const [confirm, setConfirm] = useState<any>({ open: false, content: null, handleOnAccept: null, id: null, title: null })
|
|
49
52
|
const isCouponEnabled = validationFields?.fields?.checkout?.coupon?.enabled;
|
|
50
53
|
|
|
51
54
|
const handleDeleteClick = (product: any) => {
|
|
@@ -61,7 +64,7 @@ const OrderSummaryUI = (props: any) => {
|
|
|
61
64
|
categoryId: product?.category_id,
|
|
62
65
|
productId: product?.id,
|
|
63
66
|
isFromCheckout: isFromCheckout,
|
|
64
|
-
|
|
67
|
+
})
|
|
65
68
|
}
|
|
66
69
|
|
|
67
70
|
const getIncludedTaxes = () => {
|
|
@@ -74,6 +77,22 @@ const OrderSummaryUI = (props: any) => {
|
|
|
74
77
|
}
|
|
75
78
|
}
|
|
76
79
|
|
|
80
|
+
const getIncludedTaxesDiscounts = () => {
|
|
81
|
+
return cart?.taxes?.filter((tax: any) => tax?.type === 1)?.reduce((carry: number, tax: any) => carry + (tax?.summary?.tax_after_discount ?? tax?.summary?.tax), 0)
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
const onRemoveOffer = (id: number) => {
|
|
85
|
+
setConfirm({
|
|
86
|
+
open: true,
|
|
87
|
+
content: [t('QUESTION_DELETE_OFFER', 'Are you sure that you want to delete the offer?')],
|
|
88
|
+
title: t('OFFER', 'Offer'),
|
|
89
|
+
handleOnAccept: () => {
|
|
90
|
+
setConfirm({ ...confirm, open: false })
|
|
91
|
+
handleRemoveOfferClick(id)
|
|
92
|
+
}
|
|
93
|
+
})
|
|
94
|
+
}
|
|
95
|
+
|
|
77
96
|
const cart = orderState?.carts?.[`businessId:${props.cart.business_id}`]
|
|
78
97
|
|
|
79
98
|
const walletName: any = {
|
|
@@ -109,9 +128,11 @@ const OrderSummaryUI = (props: any) => {
|
|
|
109
128
|
<OSBill>
|
|
110
129
|
<OSTable>
|
|
111
130
|
<OText size={12}>{t('SUBTOTAL', 'Subtotal')}</OText>
|
|
112
|
-
<OText size={12}>
|
|
131
|
+
<OText size={12}>
|
|
132
|
+
{parsePrice(cart?.subtotal + getIncludedTaxes())}
|
|
133
|
+
</OText>
|
|
113
134
|
</OSTable>
|
|
114
|
-
{cart?.discount > 0 && cart?.total >= 0 && (
|
|
135
|
+
{cart?.discount > 0 && cart?.total >= 0 && cart?.offers?.length === 0 && (
|
|
115
136
|
<OSTable>
|
|
116
137
|
{cart?.discount_type === 1 ? (
|
|
117
138
|
<OText size={12}>
|
|
@@ -125,34 +146,87 @@ const OrderSummaryUI = (props: any) => {
|
|
|
125
146
|
</OSTable>
|
|
126
147
|
)}
|
|
127
148
|
{
|
|
128
|
-
cart?.
|
|
129
|
-
<OSTable key={
|
|
149
|
+
cart?.offers?.length > 0 && cart?.offers?.filter((offer: any) => offer?.target === 1)?.map((offer: any) => (
|
|
150
|
+
<OSTable key={offer.id}>
|
|
130
151
|
<OSRow>
|
|
131
|
-
<OText size={12}
|
|
132
|
-
|
|
152
|
+
<OText size={12}>{offer.name}</OText>
|
|
153
|
+
{offer.rate_type === 1 && (
|
|
154
|
+
<OText size={12}>{`(${verifyDecimals(offer?.rate, parsePrice)}%)`}</OText>
|
|
155
|
+
)}
|
|
156
|
+
<TouchableOpacity style={{ marginLeft: 3 }} onPress={() => setOpenTaxModal({ open: true, data: offer, type: 'offer_target_1' })}>
|
|
157
|
+
<AntIcon name='exclamationcircleo' size={18} color={theme.colors.primary} />
|
|
158
|
+
</TouchableOpacity>
|
|
159
|
+
<TouchableOpacity style={{ marginLeft: 3 }} onPress={() => onRemoveOffer(offer?.id)}>
|
|
160
|
+
<AntIcon name='closecircle' size={18} color={theme.colors.primary} />
|
|
161
|
+
</TouchableOpacity>
|
|
162
|
+
</OSRow>
|
|
163
|
+
<OText size={12}>
|
|
164
|
+
- {parsePrice(offer?.summary?.discount)}
|
|
165
|
+
</OText>
|
|
166
|
+
</OSTable>
|
|
167
|
+
))
|
|
168
|
+
}
|
|
169
|
+
<Divider />
|
|
170
|
+
{cart?.subtotal_with_discount > 0 && cart?.discount > 0 && cart?.total >= 0 && (
|
|
171
|
+
<OSTable>
|
|
172
|
+
<OText size={12} numberOfLines={1}>{t('SUBTOTAL_WITH_DISCOUNT', 'Subtotal with discount')}</OText>
|
|
173
|
+
{cart?.business?.tax_type === 1 ? (
|
|
174
|
+
<OText size={12}>{parsePrice(cart?.subtotal_with_discount + getIncludedTaxesDiscounts() ?? 0)}</OText>
|
|
175
|
+
) : (
|
|
176
|
+
<OText size={12}>{parsePrice(cart?.subtotal_with_discount ?? 0)}</OText>
|
|
177
|
+
)}
|
|
178
|
+
</OSTable>
|
|
179
|
+
)}
|
|
180
|
+
{
|
|
181
|
+
cart.taxes?.length > 0 && cart.taxes.filter((tax: any) => tax.type === 2 && tax?.rate !== 0).map((tax: any) => (
|
|
182
|
+
<OSTable key={tax.id}>
|
|
183
|
+
<OSRow>
|
|
184
|
+
<OText size={12} numberOfLines={1} >
|
|
185
|
+
{tax.name || t('INHERIT_FROM_BUSINESS', 'Inherit from business')}{' '}
|
|
133
186
|
{`(${verifyDecimals(tax?.rate, parseNumber)}%)`}{' '}
|
|
134
187
|
</OText>
|
|
135
|
-
<TouchableOpacity onPress={() => setOpenTaxModal({ open: true, data: tax })} >
|
|
136
|
-
<AntIcon name='exclamationcircleo' size={
|
|
188
|
+
<TouchableOpacity onPress={() => setOpenTaxModal({ open: true, data: tax, type: 'tax' })} >
|
|
189
|
+
<AntIcon name='exclamationcircleo' size={18} color={theme.colors.primary} />
|
|
137
190
|
</TouchableOpacity>
|
|
138
191
|
</OSRow>
|
|
139
|
-
<OText size={12}>{parsePrice(tax?.summary?.tax
|
|
192
|
+
<OText size={12}>{parsePrice(tax?.summary?.tax_after_discount ?? tax?.summary?.tax ?? 0)}</OText>
|
|
140
193
|
</OSTable>
|
|
141
194
|
))
|
|
142
195
|
}
|
|
143
196
|
{
|
|
144
|
-
cart?.fees?.length > 0 && cart?.fees?.filter((fee: any) => !(fee.fixed === 0 && fee.percentage === 0))
|
|
145
|
-
<OSTable key={fee
|
|
197
|
+
cart?.fees?.length > 0 && cart?.fees?.filter((fee: any) => !(fee.fixed === 0 && fee.percentage === 0)).map((fee: any) => (
|
|
198
|
+
<OSTable key={fee?.id}>
|
|
146
199
|
<OSRow>
|
|
147
200
|
<OText size={12} numberOfLines={1}>
|
|
148
201
|
{fee.name || t('INHERIT_FROM_BUSINESS', 'Inherit from business')}{' '}
|
|
149
|
-
({parsePrice(fee?.fixed)} + {fee
|
|
202
|
+
({parsePrice(fee?.fixed)} + {fee?.percentage}%){' '}
|
|
150
203
|
</OText>
|
|
151
|
-
<TouchableOpacity onPress={() => setOpenTaxModal({ open: true, data: fee })} >
|
|
152
|
-
<AntIcon name='exclamationcircleo' size={
|
|
204
|
+
<TouchableOpacity onPress={() => setOpenTaxModal({ open: true, data: fee, type: 'fee' })} >
|
|
205
|
+
<AntIcon name='exclamationcircleo' size={18} color={theme.colors.primary} />
|
|
153
206
|
</TouchableOpacity>
|
|
154
207
|
</OSRow>
|
|
155
|
-
<OText size={12}>{parsePrice(fee?.summary?.fixed + fee?.summary?.percentage
|
|
208
|
+
<OText size={12}>{parsePrice(fee?.summary?.fixed + (fee?.summary?.percentage_after_discount ?? fee?.summary?.percentage) ?? 0)}</OText>
|
|
209
|
+
</OSTable>
|
|
210
|
+
))
|
|
211
|
+
}
|
|
212
|
+
{
|
|
213
|
+
cart?.offers?.length > 0 && cart?.offers?.filter((offer: any) => offer?.target === 3)?.map((offer: any) => (
|
|
214
|
+
<OSTable key={offer.id}>
|
|
215
|
+
<OSRow>
|
|
216
|
+
<OText size={12}>{offer.name}</OText>
|
|
217
|
+
{offer.rate_type === 1 && (
|
|
218
|
+
<OText size={12}>{`(${verifyDecimals(offer?.rate, parsePrice)}%)`}</OText>
|
|
219
|
+
)}
|
|
220
|
+
<TouchableOpacity style={{ marginLeft: 3 }} onPress={() => setOpenTaxModal({ open: true, data: offer, type: 'offer_target_3' })}>
|
|
221
|
+
<AntIcon name='exclamationcircleo' size={18} color={theme.colors.primary} />
|
|
222
|
+
</TouchableOpacity>
|
|
223
|
+
<TouchableOpacity style={{ marginLeft: 3 }} onPress={() => onRemoveOffer(offer?.id)}>
|
|
224
|
+
<AntIcon name='closecircle' size={18} color={theme.colors.primary} />
|
|
225
|
+
</TouchableOpacity>
|
|
226
|
+
</OSRow>
|
|
227
|
+
<OText size={12}>
|
|
228
|
+
- {parsePrice(offer?.summary?.discount)}
|
|
229
|
+
</OText>
|
|
156
230
|
</OSTable>
|
|
157
231
|
))
|
|
158
232
|
}
|
|
@@ -162,6 +236,27 @@ const OrderSummaryUI = (props: any) => {
|
|
|
162
236
|
<OText size={12}>{parsePrice(cart?.delivery_price)}</OText>
|
|
163
237
|
</OSTable>
|
|
164
238
|
)}
|
|
239
|
+
{
|
|
240
|
+
cart?.offers?.length > 0 && cart?.offers?.filter((offer: any) => offer?.target === 2)?.map((offer: any) => (
|
|
241
|
+
<OSTable key={offer.id}>
|
|
242
|
+
<OSRow>
|
|
243
|
+
<OText size={12}>{offer.name}</OText>
|
|
244
|
+
{offer.rate_type === 1 && (
|
|
245
|
+
<OText size={12}>{`(${verifyDecimals(offer?.rate, parsePrice)}%)`}</OText>
|
|
246
|
+
)}
|
|
247
|
+
<TouchableOpacity style={{ marginLeft: 3 }} onPress={() => setOpenTaxModal({ open: true, data: offer, type: 'offer_target_2' })}>
|
|
248
|
+
<AntIcon name='exclamationcircleo' size={18} color={theme.colors.primary} />
|
|
249
|
+
</TouchableOpacity>
|
|
250
|
+
<TouchableOpacity style={{ marginLeft: 3 }} onPress={() => onRemoveOffer(offer?.id)}>
|
|
251
|
+
<AntIcon name='closecircle' size={18} color={theme.colors.primary} />
|
|
252
|
+
</TouchableOpacity>
|
|
253
|
+
</OSRow>
|
|
254
|
+
<OText size={12}>
|
|
255
|
+
- {parsePrice(offer?.summary?.discount)}
|
|
256
|
+
</OText>
|
|
257
|
+
</OSTable>
|
|
258
|
+
))
|
|
259
|
+
}
|
|
165
260
|
{cart?.driver_tip > 0 && (
|
|
166
261
|
<OSTable>
|
|
167
262
|
<OText size={12}>
|
|
@@ -201,7 +296,7 @@ const OrderSummaryUI = (props: any) => {
|
|
|
201
296
|
{t('TOTAL', 'Total')}
|
|
202
297
|
</OText>
|
|
203
298
|
<OText size={14} style={{ fontWeight: 'bold' }} >
|
|
204
|
-
{parsePrice(cart?.
|
|
299
|
+
{parsePrice(cart?.total >= 0 ? cart?.total : 0)}
|
|
205
300
|
</OText>
|
|
206
301
|
</OSTable>
|
|
207
302
|
</View>
|
|
@@ -243,11 +338,25 @@ const OrderSummaryUI = (props: any) => {
|
|
|
243
338
|
)}
|
|
244
339
|
<OModal
|
|
245
340
|
open={openTaxModal.open}
|
|
246
|
-
onClose={() => setOpenTaxModal({ open: false, data: null })}
|
|
341
|
+
onClose={() => setOpenTaxModal({ open: false, data: null, type: '' })}
|
|
247
342
|
entireModal
|
|
343
|
+
title={`${openTaxModal.data?.name ||
|
|
344
|
+
t('INHERIT_FROM_BUSINESS', 'Inherit from business')} ${openTaxModal.data?.rate_type !== 2 ? `(${typeof openTaxModal.data?.rate === 'number' ? `${openTaxModal.data?.rate}%` : `${parsePrice(openTaxModal.data?.fixed ?? 0)} + ${openTaxModal.data?.percentage}%`})` : ''} `}
|
|
248
345
|
>
|
|
249
|
-
<TaxInformation
|
|
346
|
+
<TaxInformation
|
|
347
|
+
type={openTaxModal.type}
|
|
348
|
+
data={openTaxModal.data}
|
|
349
|
+
products={cart?.products}
|
|
350
|
+
/>
|
|
250
351
|
</OModal>
|
|
352
|
+
<OAlert
|
|
353
|
+
open={confirm.open}
|
|
354
|
+
title={confirm.title}
|
|
355
|
+
content={confirm.content}
|
|
356
|
+
onAccept={confirm.handleOnAccept}
|
|
357
|
+
onCancel={() => setConfirm({ ...confirm, open: false, title: null })}
|
|
358
|
+
onClose={() => setConfirm({ ...confirm, open: false, title: null })}
|
|
359
|
+
/>
|
|
251
360
|
</>
|
|
252
361
|
)}
|
|
253
362
|
</OSContainer>
|
|
@@ -37,6 +37,8 @@ const stripeOptions: any = ['stripe_direct', 'stripe', 'stripe_connect']
|
|
|
37
37
|
// { name: 'iDEAL', value: 'ideal' }
|
|
38
38
|
// ]
|
|
39
39
|
|
|
40
|
+
const webViewPaymentGateway: any = ['paypal', 'square']
|
|
41
|
+
|
|
40
42
|
const PaymentOptionsUI = (props: any) => {
|
|
41
43
|
const {
|
|
42
44
|
cart,
|
|
@@ -49,7 +51,8 @@ const PaymentOptionsUI = (props: any) => {
|
|
|
49
51
|
onNavigationRedirect,
|
|
50
52
|
handlePaymethodClick,
|
|
51
53
|
handlePaymethodDataChange,
|
|
52
|
-
isOpenMethod
|
|
54
|
+
isOpenMethod,
|
|
55
|
+
handlePaymentMethodClickCustom
|
|
53
56
|
} = props
|
|
54
57
|
|
|
55
58
|
const theme = useTheme();
|
|
@@ -90,6 +93,9 @@ const PaymentOptionsUI = (props: any) => {
|
|
|
90
93
|
|
|
91
94
|
const handlePaymentMethodClick = (paymethod: any) => {
|
|
92
95
|
const isPopupMethod = ['stripe', 'stripe_direct', 'stripe_connect', 'stripe_redirect', 'paypal'].includes(paymethod?.gateway)
|
|
96
|
+
if (webViewPaymentGateway.includes(paymethod?.gateway)) {
|
|
97
|
+
handlePaymentMethodClickCustom(paymethod)
|
|
98
|
+
}
|
|
93
99
|
handlePaymethodClick(paymethod, isPopupMethod)
|
|
94
100
|
}
|
|
95
101
|
|
|
@@ -139,7 +145,7 @@ const PaymentOptionsUI = (props: any) => {
|
|
|
139
145
|
)
|
|
140
146
|
}
|
|
141
147
|
|
|
142
|
-
const excludeIds: any = [
|
|
148
|
+
const excludeIds: any = [32, 66]; //exclude paypal & connect & redirect
|
|
143
149
|
|
|
144
150
|
return (
|
|
145
151
|
<PMContainer>
|
|
@@ -155,7 +155,7 @@ export const ProductOptionsUI = (props: any) => {
|
|
|
155
155
|
const { product, loading, error } = productObject;
|
|
156
156
|
const [gallery, setGallery] = useState([])
|
|
157
157
|
const [thumbsSwiper, setThumbsSwiper] = useState(0)
|
|
158
|
-
|
|
158
|
+
const [indexGallery, setIndexGallery] = useState(0)
|
|
159
159
|
const [selOpt, setSelectedOpt] = useState(0);
|
|
160
160
|
const [isHaveWeight, setIsHaveWeight] = useState(false)
|
|
161
161
|
const [qtyBy, setQtyBy] = useState({
|
|
@@ -208,11 +208,16 @@ export const ProductOptionsUI = (props: any) => {
|
|
|
208
208
|
}
|
|
209
209
|
|
|
210
210
|
const handleClickThumb = (index: number) => {
|
|
211
|
-
|
|
211
|
+
if (index !== indexGallery) {
|
|
212
|
+
swiperRef?.current.scrollBy(index - thumbsSwiper, true);
|
|
213
|
+
setIndexGallery(index)
|
|
214
|
+
}
|
|
212
215
|
}
|
|
213
216
|
|
|
214
217
|
const handleRedirectLogin = () => {
|
|
215
|
-
navigation.navigate('Login'
|
|
218
|
+
navigation.navigate('Login', {
|
|
219
|
+
store_slug: props.businessSlug
|
|
220
|
+
});
|
|
216
221
|
};
|
|
217
222
|
|
|
218
223
|
const handleSwitchQtyUnit = (val: string) => {
|
|
@@ -289,16 +294,16 @@ export const ProductOptionsUI = (props: any) => {
|
|
|
289
294
|
</>
|
|
290
295
|
);
|
|
291
296
|
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
297
|
+
const handleGoBack = navigation?.canGoBack()
|
|
298
|
+
? () => navigation.goBack()
|
|
299
|
+
: () => navigation.navigate('Business', { store: props.businessSlug })
|
|
295
300
|
|
|
296
301
|
return (
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
+
<SafeAreaView style={{ flex: 1 }}>
|
|
303
|
+
<TopHeader>
|
|
304
|
+
<TopActions onPress={() => handleGoBack()}>
|
|
305
|
+
<OIcon src={theme.images.general.arrow_left} width={15} />
|
|
306
|
+
</TopActions>
|
|
302
307
|
</TopHeader>
|
|
303
308
|
<ScrollView>
|
|
304
309
|
{!error && (
|
|
@@ -349,13 +354,13 @@ export const ProductOptionsUI = (props: any) => {
|
|
|
349
354
|
style={styles.slide1}
|
|
350
355
|
key={i}
|
|
351
356
|
>
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
357
|
+
<FastImage
|
|
358
|
+
style={{ height: '100%', opacity: isSoldOut ? 0.5 : 1 }}
|
|
359
|
+
source={{
|
|
360
|
+
uri: optimizeImage(img, 'h_258,c_limit'),
|
|
361
|
+
priority: FastImage.priority.normal,
|
|
362
|
+
}}
|
|
363
|
+
/>
|
|
359
364
|
</View>
|
|
360
365
|
))}
|
|
361
366
|
</Swiper>
|
|
@@ -379,18 +384,18 @@ export const ProductOptionsUI = (props: any) => {
|
|
|
379
384
|
opacity: index === thumbsSwiper ? 1 : 0.8
|
|
380
385
|
}}
|
|
381
386
|
>
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
387
|
+
<OIcon
|
|
388
|
+
url={img}
|
|
389
|
+
style={{
|
|
390
|
+
borderColor: theme.colors.lightGray,
|
|
391
|
+
borderRadius: 8,
|
|
392
|
+
minHeight: '100%',
|
|
393
|
+
opacity: isSoldOut ? 0.5 : 1
|
|
394
|
+
}}
|
|
395
|
+
width={56}
|
|
396
|
+
height={56}
|
|
397
|
+
cover
|
|
398
|
+
/>
|
|
394
399
|
</View>
|
|
395
400
|
</TouchableOpacity>
|
|
396
401
|
|
|
@@ -446,21 +451,21 @@ export const ProductOptionsUI = (props: any) => {
|
|
|
446
451
|
) : (
|
|
447
452
|
<View style={{ flexDirection: 'row', marginBottom: 10 }}>
|
|
448
453
|
<OText size={16} style={{ flex: I18nManager.isRTL ? 1 : 0 }} color={theme.colors.primary}>{productCart.price ? parsePrice(productCart.price) : ''}</OText>
|
|
449
|
-
{
|
|
454
|
+
{product?.offer_price !== null && product?.in_offer && (
|
|
450
455
|
<OText style={{
|
|
451
456
|
fontSize: 14,
|
|
452
457
|
color: '#808080',
|
|
453
458
|
textDecorationLine: 'line-through',
|
|
454
459
|
marginLeft: 7,
|
|
455
460
|
marginRight: 7
|
|
456
|
-
}}>{parsePrice(product?.offer_price)}</OText>
|
|
461
|
+
}}>{product?.offer_price ? parsePrice(product?.offer_price) : ''}</OText>
|
|
457
462
|
)}
|
|
458
463
|
</View>
|
|
459
464
|
)}
|
|
460
465
|
</>
|
|
461
466
|
)}
|
|
462
467
|
</ProductTitle>
|
|
463
|
-
|
|
468
|
+
<ProductDescription>
|
|
464
469
|
<OText color={theme.colors.textSecondary} size={12} lineHeight={18}>
|
|
465
470
|
{product?.description || productCart?.description}
|
|
466
471
|
</OText>
|
|
@@ -785,7 +790,7 @@ export const ProductOptionsUI = (props: any) => {
|
|
|
785
790
|
<OText
|
|
786
791
|
size={12}
|
|
787
792
|
lineHeight={18}
|
|
788
|
-
style={{ minWidth:
|
|
793
|
+
style={{ minWidth: 40, textAlign: 'center' }}
|
|
789
794
|
>
|
|
790
795
|
{qtyBy?.pieces && productCart.quantity}
|
|
791
796
|
{qtyBy?.weight_unit && productCart.quantity * product?.weight}
|
|
@@ -809,36 +814,38 @@ export const ProductOptionsUI = (props: any) => {
|
|
|
809
814
|
}
|
|
810
815
|
/>
|
|
811
816
|
</TouchableOpacity>
|
|
812
|
-
|
|
813
|
-
<
|
|
814
|
-
onPress={() => handleSwitchQtyUnit('pieces')}
|
|
815
|
-
>
|
|
816
|
-
<WeightUnitItem active={qtyBy?.pieces}>
|
|
817
|
-
<OText
|
|
818
|
-
size={12}
|
|
819
|
-
lineHeight={18}
|
|
820
|
-
color={qtyBy?.pieces ? theme.colors.primary : theme.colors.textNormal}
|
|
821
|
-
>
|
|
822
|
-
{t('PIECES', 'pieces')}
|
|
823
|
-
</OText>
|
|
824
|
-
</WeightUnitItem>
|
|
825
|
-
</TouchableOpacity>
|
|
826
|
-
<View style={{ alignItems: 'flex-start' }}>
|
|
817
|
+
{isHaveWeight && (
|
|
818
|
+
<WeightUnitSwitch>
|
|
827
819
|
<TouchableOpacity
|
|
828
|
-
onPress={() => handleSwitchQtyUnit('
|
|
820
|
+
onPress={() => handleSwitchQtyUnit('pieces')}
|
|
829
821
|
>
|
|
830
|
-
<WeightUnitItem active={qtyBy?.
|
|
822
|
+
<WeightUnitItem active={qtyBy?.pieces}>
|
|
831
823
|
<OText
|
|
832
824
|
size={12}
|
|
833
825
|
lineHeight={18}
|
|
834
|
-
color={qtyBy?.
|
|
826
|
+
color={qtyBy?.pieces ? theme.colors.primary : theme.colors.textNormal}
|
|
835
827
|
>
|
|
836
|
-
{
|
|
828
|
+
{t('PIECES', 'pcs')}
|
|
837
829
|
</OText>
|
|
838
830
|
</WeightUnitItem>
|
|
839
831
|
</TouchableOpacity>
|
|
840
|
-
|
|
841
|
-
|
|
832
|
+
<View style={{ alignItems: 'flex-start' }}>
|
|
833
|
+
<TouchableOpacity
|
|
834
|
+
onPress={() => handleSwitchQtyUnit('weight_unit')}
|
|
835
|
+
>
|
|
836
|
+
<WeightUnitItem active={qtyBy?.weight_unit}>
|
|
837
|
+
<OText
|
|
838
|
+
size={12}
|
|
839
|
+
lineHeight={18}
|
|
840
|
+
color={qtyBy?.weight_unit ? theme.colors.primary : theme.colors.textNormal}
|
|
841
|
+
>
|
|
842
|
+
{product?.weight_unit}
|
|
843
|
+
</OText>
|
|
844
|
+
</WeightUnitItem>
|
|
845
|
+
</TouchableOpacity>
|
|
846
|
+
</View>
|
|
847
|
+
</WeightUnitSwitch>
|
|
848
|
+
)}
|
|
842
849
|
</View>
|
|
843
850
|
)}
|
|
844
851
|
<View
|
|
@@ -907,7 +914,7 @@ export const ProductOptionsUI = (props: any) => {
|
|
|
907
914
|
</View>
|
|
908
915
|
</ProductActions>
|
|
909
916
|
)}
|
|
910
|
-
|
|
917
|
+
</SafeAreaView>
|
|
911
918
|
);
|
|
912
919
|
};
|
|
913
920
|
|
|
@@ -2,7 +2,7 @@ import React, { useState, useEffect } from 'react'
|
|
|
2
2
|
import {
|
|
3
3
|
useUtils,
|
|
4
4
|
useLanguage,
|
|
5
|
-
ProductOptionSuboption as ProductSubOptionController
|
|
5
|
+
ProductOptionSuboption as ProductSubOptionController
|
|
6
6
|
} from 'ordering-components/native'
|
|
7
7
|
import { useTheme } from 'styled-components/native';
|
|
8
8
|
import { StyleSheet } from 'react-native'
|
|
@@ -51,7 +51,6 @@ export const ProductOptionSubOptionUI = (props: any) => {
|
|
|
51
51
|
|
|
52
52
|
const disableIncrement = option?.limit_suboptions_by_max ? balance === option?.max : state.quantity === suboption?.max || (!state.selected && balance === option?.max)
|
|
53
53
|
const price = option?.with_half_option && suboption?.half_price && state.position !== 'whole' ? suboption?.half_price : suboption?.price
|
|
54
|
-
|
|
55
54
|
return (
|
|
56
55
|
<Container>
|
|
57
56
|
<IconControl disabled={disabled} onPress={() => handleSuboptionClick()}>
|
|
@@ -73,54 +72,57 @@ export const ProductOptionSubOptionUI = (props: any) => {
|
|
|
73
72
|
</OText>
|
|
74
73
|
</IconControl>
|
|
75
74
|
{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
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
<
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
{
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
<
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
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
|
-
|
|
75
|
+
<QuantityControl>
|
|
76
|
+
{option?.allow_suboption_quantity && state?.selected && (
|
|
77
|
+
<>
|
|
78
|
+
<Checkbox disabled={disabled || state.quantity === 0} onPress={decrement}>
|
|
79
|
+
<OIcon
|
|
80
|
+
src={theme.images.general.minus}
|
|
81
|
+
width={16}
|
|
82
|
+
color={state.quantity === 0 || disabled ? theme.colors.disabled : theme.colors.primary}
|
|
83
|
+
/>
|
|
84
|
+
</Checkbox>
|
|
85
|
+
<OText size={12} mLeft={5} mRight={5}>
|
|
86
|
+
{state.quantity}
|
|
87
|
+
</OText>
|
|
88
|
+
<Checkbox disabled={disabled || disableIncrement} onPress={increment}>
|
|
89
|
+
<OIcon
|
|
90
|
+
src={theme.images.general.plus}
|
|
91
|
+
width={16}
|
|
92
|
+
color={disableIncrement || disabled ? theme.colors.disabled : theme.colors.primary}
|
|
93
|
+
/>
|
|
94
|
+
</Checkbox>
|
|
95
|
+
</>
|
|
96
|
+
)}
|
|
97
|
+
</QuantityControl>
|
|
98
|
+
<PositionControl>
|
|
99
|
+
{option?.with_half_option && state?.selected && (
|
|
100
|
+
<>
|
|
101
|
+
<Circle disabled={disabled} onPress={() => changePosition('left')}>
|
|
102
|
+
<OIcon
|
|
103
|
+
src={theme.images.general.half_l}
|
|
104
|
+
color={state.selected && state.position === 'left' ? theme.colors.primary : '#cbcbcb'}
|
|
105
|
+
width={16}
|
|
106
|
+
style={styles.inverse}
|
|
107
|
+
/>
|
|
108
|
+
</Circle>
|
|
109
|
+
<Circle disabled={disabled} onPress={() => changePosition('whole')}>
|
|
110
|
+
<OIcon
|
|
111
|
+
src={theme.images.general.half_f}
|
|
112
|
+
color={state.selected && state.position === 'whole' ? theme.colors.primary : '#cbcbcb'}
|
|
113
|
+
width={16}
|
|
114
|
+
/>
|
|
115
|
+
</Circle>
|
|
116
|
+
<Circle disabled={disabled} onPress={() => changePosition('right')}>
|
|
117
|
+
<OIcon
|
|
118
|
+
src={theme.images.general.half_r}
|
|
119
|
+
color={state.selected && state.position === 'right' ? theme.colors.primary : '#cbcbcb'}
|
|
120
|
+
width={16}
|
|
121
|
+
/>
|
|
122
|
+
</Circle>
|
|
123
|
+
</>
|
|
124
|
+
)}
|
|
125
|
+
</PositionControl>
|
|
124
126
|
<OText size={12} lineHeight={18} color={theme.colors.textSecondary}>
|
|
125
127
|
+ {parsePrice(price)}
|
|
126
128
|
</OText>
|
|
@@ -137,7 +139,8 @@ const styles = StyleSheet.create({
|
|
|
137
139
|
export const ProductOptionSubOption = (props: any) => {
|
|
138
140
|
const productOptionSubOptionProps = {
|
|
139
141
|
...props,
|
|
140
|
-
UIComponent: ProductOptionSubOptionUI
|
|
142
|
+
UIComponent: ProductOptionSubOptionUI,
|
|
143
|
+
isOrigin: true
|
|
141
144
|
}
|
|
142
145
|
|
|
143
146
|
return (
|