ordering-ui-react-native 0.17.28-release → 0.17.29-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 +1 -1
- package/themes/original/src/components/AddressForm/index.tsx +28 -26
- package/themes/original/src/components/BusinessController/index.tsx +9 -0
- package/themes/original/src/components/BusinessProductsListing/UpsellingRedirect.tsx +1 -1
- package/themes/original/src/components/BusinessProductsListing/index.tsx +56 -8
- package/themes/original/src/components/Checkout/index.tsx +10 -1
- package/themes/original/src/components/LoginForm/index.tsx +11 -2
- package/themes/original/src/components/MultiOrdersDetails/index.tsx +1 -1
- package/themes/original/src/components/OrderDetails/OrderEta.tsx +21 -9
- package/themes/original/src/components/ProductForm/index.tsx +30 -8
- package/themes/original/src/components/ProductForm/styles.tsx +2 -2
- package/themes/original/src/components/ProductOptionSubOption/index.tsx +1 -1
- package/themes/original/src/components/SignupForm/index.tsx +10 -1
- package/themes/original/src/components/SingleOrderCard/index.tsx +7 -1
- package/themes/original/src/components/UserProfileForm/index.tsx +5 -1
- package/themes/original/src/components/WalletTransactions/index.tsx +3 -3
- package/themes/original/src/components/Wallets/index.tsx +3 -3
- package/themes/original/src/utils/index.tsx +0 -11
package/package.json
CHANGED
|
@@ -531,10 +531,10 @@ const AddressFormUI = (props: AddressFormParams) => {
|
|
|
531
531
|
titleAlign={'center'}
|
|
532
532
|
onActionLeft={goToBack}
|
|
533
533
|
showCall={false}
|
|
534
|
-
btnStyle={{ paddingLeft: 0 }}
|
|
535
|
-
style={{ marginTop: Platform.OS === 'ios' ? 0 :
|
|
536
|
-
titleWrapStyle={{ paddingHorizontal: 0 }}
|
|
537
|
-
titleStyle={{ marginRight: 0, marginLeft: 0 }}
|
|
534
|
+
btnStyle={{ paddingLeft: 0, paddingRight: 5 }}
|
|
535
|
+
style={{ marginTop: Platform.OS === 'ios' ? 0 : 10 }}
|
|
536
|
+
titleWrapStyle={{ paddingHorizontal: 0, width: '100%' }}
|
|
537
|
+
titleStyle={{ marginRight: 0, marginLeft: 0, paddingRight: 5 }}
|
|
538
538
|
/>
|
|
539
539
|
</View>
|
|
540
540
|
<TouchableWithoutFeedback onPress={Keyboard.dismiss}>
|
|
@@ -649,7 +649,7 @@ const AddressFormUI = (props: AddressFormParams) => {
|
|
|
649
649
|
)}
|
|
650
650
|
</AutocompleteInput>
|
|
651
651
|
|
|
652
|
-
{(locationChange || formState.changes?.location) && (
|
|
652
|
+
{!isHideMap && (locationChange || formState.changes?.location) && (
|
|
653
653
|
<View
|
|
654
654
|
style={{
|
|
655
655
|
height: 189,
|
|
@@ -808,27 +808,29 @@ const AddressFormUI = (props: AddressFormParams) => {
|
|
|
808
808
|
/>
|
|
809
809
|
)}
|
|
810
810
|
</FormInput>
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
811
|
+
{!isHideIcons && (
|
|
812
|
+
<IconsContainer>
|
|
813
|
+
{tagsName.map((tag) => (
|
|
814
|
+
<TouchableOpacity
|
|
815
|
+
key={tag.value}
|
|
816
|
+
onPress={() => handleAddressTag(tag.value)}>
|
|
817
|
+
<View
|
|
818
|
+
style={{
|
|
819
|
+
...styles.iconContainer,
|
|
820
|
+
}}>
|
|
821
|
+
<OIcon
|
|
822
|
+
src={tag.icon}
|
|
823
|
+
width={24}
|
|
824
|
+
color={
|
|
825
|
+
addressTag === tag.value ?
|
|
826
|
+
theme.colors.primary : theme.colors.disabled
|
|
827
|
+
}
|
|
828
|
+
/>
|
|
829
|
+
</View>
|
|
830
|
+
</TouchableOpacity>
|
|
831
|
+
))}
|
|
832
|
+
</IconsContainer>
|
|
833
|
+
)}
|
|
832
834
|
</View>
|
|
833
835
|
|
|
834
836
|
<View>
|
|
@@ -15,6 +15,7 @@ import { Dimensions, StyleSheet, Vibration, View } from 'react-native';
|
|
|
15
15
|
import { InView } from 'react-native-intersection-observer'
|
|
16
16
|
import { BusinessControllerParams } from '../../types';
|
|
17
17
|
import { convertHoursToMinutes, lightenDarkenColor, shape } from '../../utils';
|
|
18
|
+
import ReactNativeHapticFeedback from "react-native-haptic-feedback";
|
|
18
19
|
|
|
19
20
|
import {
|
|
20
21
|
BusinessHero,
|
|
@@ -151,6 +152,14 @@ export const BusinessControllerUI = (props: BusinessControllerParams) => {
|
|
|
151
152
|
return _types.join(', ');
|
|
152
153
|
};
|
|
153
154
|
|
|
155
|
+
const vibrateApp = (impact?: string) => {
|
|
156
|
+
const options = {
|
|
157
|
+
enableVibrateFallback: true,
|
|
158
|
+
ignoreAndroidSystemSettings: false
|
|
159
|
+
};
|
|
160
|
+
ReactNativeHapticFeedback.trigger(impact || "impactLight", options);
|
|
161
|
+
}
|
|
162
|
+
|
|
154
163
|
const handleBusinessClick = (selectedBusiness: any) => {
|
|
155
164
|
Vibration.vibrate()
|
|
156
165
|
if (business?.open) handleClick && handleClick(selectedBusiness)
|
|
@@ -13,7 +13,7 @@ const UpsellingRedirectUI = (props: any) => {
|
|
|
13
13
|
if (!upsellingProducts.loading) {
|
|
14
14
|
if (upsellingProducts?.products?.length) {
|
|
15
15
|
onRedirect &&
|
|
16
|
-
onRedirect('UpsellingPage', props)
|
|
16
|
+
onRedirect('UpsellingPage', {...props, products: upsellingProducts?.products })
|
|
17
17
|
} else {
|
|
18
18
|
handleUpsellingPage && handleUpsellingPage()
|
|
19
19
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React, { useCallback, useEffect, useRef, useState } from 'react'
|
|
2
|
-
import { View, TouchableOpacity, StyleSheet, SafeAreaView, Dimensions, Platform, KeyboardAvoidingViewBase, KeyboardAvoidingView,
|
|
2
|
+
import { View, TouchableOpacity, StyleSheet, SafeAreaView, Dimensions, Platform, KeyboardAvoidingViewBase, KeyboardAvoidingView, Keyboard, KeyboardEvent, BackHandler } from 'react-native'
|
|
3
3
|
import { IOScrollView } from 'react-native-intersection-observer'
|
|
4
4
|
import { useSafeAreaInsets } from 'react-native-safe-area-context'
|
|
5
5
|
import { useTheme } from 'styled-components/native';
|
|
@@ -25,6 +25,8 @@ import { BusinessProductsListingParams } from '../../types'
|
|
|
25
25
|
import { _retrieveStoreData, _removeStoreData } from '../../providers/StoreUtil';
|
|
26
26
|
import IconAntDesign from 'react-native-vector-icons/AntDesign';
|
|
27
27
|
import { useIsFocused } from '@react-navigation/native';
|
|
28
|
+
import AntDesignIcon from 'react-native-vector-icons/AntDesign'
|
|
29
|
+
import ReactNativeHapticFeedback from "react-native-haptic-feedback";
|
|
28
30
|
|
|
29
31
|
import {
|
|
30
32
|
TopHeader,
|
|
@@ -135,20 +137,30 @@ const BusinessProductsListingUI = (props: BusinessProductsListingParams) => {
|
|
|
135
137
|
const [openService, setOpenService] = useState(false)
|
|
136
138
|
const [currentProduct, setCurrentProduct] = useState(null)
|
|
137
139
|
const [searchBarHeight, setSearchBarHeight] = useState(60)
|
|
140
|
+
const [keyboardHeight, setKeyboardHeight] = useState(0);
|
|
138
141
|
const [viewedCategory, setViewedCategory] = useState<any>(null)
|
|
142
|
+
const [showTitle, setShowTitle] = useState(false)
|
|
139
143
|
|
|
140
144
|
const isCheckoutMultiBusinessEnabled: Boolean = configs?.checkout_multi_business_enabled?.value === '1'
|
|
141
145
|
const isQuickAddProduct = configs?.add_product_with_one_click?.value === '1'
|
|
142
146
|
const openCarts = (Object.values(orderState?.carts)?.filter((cart: any) => cart?.products && cart?.products?.length && cart?.status !== 2 && cart?.valid_schedule && cart?.valid_products && cart?.valid_address && cart?.valid_maximum && cart?.valid_minimum && !cart?.wallets) || null) || []
|
|
143
|
-
|
|
144
147
|
const currentCart: any = Object.values(orderState.carts).find((cart: any) => cart?.business?.slug === business?.slug) ?? {}
|
|
145
148
|
const isOpenFiltProducts = isOpenSearchBar && !!searchValue
|
|
146
149
|
const filtProductsHeight = Platform.OS === 'ios' ? 165 : 100
|
|
150
|
+
const viewOrderButtonVisible = !loading && auth && currentCart?.products?.length > 0 && categoryState.products.length !== 0
|
|
151
|
+
|
|
147
152
|
const onRedirect = (route: string, params?: any) => {
|
|
148
153
|
navigation.navigate(route, params)
|
|
149
154
|
}
|
|
155
|
+
const vibrateApp = (impact?: string) => {
|
|
156
|
+
const options = {
|
|
157
|
+
enableVibrateFallback: true,
|
|
158
|
+
ignoreAndroidSystemSettings: false
|
|
159
|
+
};
|
|
160
|
+
ReactNativeHapticFeedback.trigger(impact || "impactLight", options);
|
|
161
|
+
}
|
|
150
162
|
const onProductClick = async (product: any) => {
|
|
151
|
-
if (product.extras.length === 0 && !product.inventoried && auth && isQuickAddProduct) {
|
|
163
|
+
if (product.ingredients?.length === 0 && product.extras.length === 0 && !product.inventoried && auth && isQuickAddProduct) {
|
|
152
164
|
const isProductAddedToCart = currentCart?.products?.find((Cproduct: any) => Cproduct.id === product.id)
|
|
153
165
|
const productQuantity = isProductAddedToCart?.quantity
|
|
154
166
|
const addCurrentProduct = {
|
|
@@ -156,11 +168,12 @@ const BusinessProductsListingUI = (props: BusinessProductsListingParams) => {
|
|
|
156
168
|
quantity: 1
|
|
157
169
|
}
|
|
158
170
|
const updateCurrentProduct = {
|
|
171
|
+
name: product?.name,
|
|
159
172
|
id: product.id,
|
|
160
173
|
code: isProductAddedToCart?.code,
|
|
161
174
|
quantity: productQuantity + 1
|
|
162
175
|
}
|
|
163
|
-
|
|
176
|
+
vibrateApp()
|
|
164
177
|
const cartData = currentCart?.business_id ? currentCart : { business_id: business.id }
|
|
165
178
|
if (isProductAddedToCart) {
|
|
166
179
|
await updateProduct(updateCurrentProduct, cartData, isQuickAddProduct)
|
|
@@ -239,6 +252,8 @@ const BusinessProductsListingUI = (props: BusinessProductsListingParams) => {
|
|
|
239
252
|
|
|
240
253
|
const handlePageScroll = useCallback(({ nativeEvent }: any) => {
|
|
241
254
|
const scrollOffset = nativeEvent.contentOffset.y
|
|
255
|
+
setShowTitle(scrollOffset > 30)
|
|
256
|
+
|
|
242
257
|
if (businessState?.business?.lazy_load_products_recommended) {
|
|
243
258
|
const height = nativeEvent.contentSize.height
|
|
244
259
|
const hasMore = !(categoryState.pagination.totalPages === categoryState.pagination.currentPage)
|
|
@@ -307,6 +322,24 @@ const BusinessProductsListingUI = (props: BusinessProductsListingParams) => {
|
|
|
307
322
|
}
|
|
308
323
|
}, [isFocused])
|
|
309
324
|
|
|
325
|
+
|
|
326
|
+
useEffect(() => {
|
|
327
|
+
function onKeyboardDidShow(e: KeyboardEvent) {
|
|
328
|
+
setKeyboardHeight(e?.endCoordinates?.height);
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
function onKeyboardDidHide() {
|
|
332
|
+
setKeyboardHeight(0);
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
const showSubscription = Keyboard.addListener('keyboardDidShow', onKeyboardDidShow);
|
|
336
|
+
const hideSubscription = Keyboard.addListener('keyboardDidHide', onKeyboardDidHide);
|
|
337
|
+
return () => {
|
|
338
|
+
showSubscription.remove();
|
|
339
|
+
hideSubscription.remove();
|
|
340
|
+
};
|
|
341
|
+
}, []);
|
|
342
|
+
|
|
310
343
|
const subtotalWithTaxes = currentCart?.taxes?.reduce((acc: any, item: any) => {
|
|
311
344
|
if (item?.type === 1)
|
|
312
345
|
return acc = acc + item?.summary?.tax
|
|
@@ -369,9 +402,23 @@ const BusinessProductsListingUI = (props: BusinessProductsListingParams) => {
|
|
|
369
402
|
<>
|
|
370
403
|
{!(businessSingleId && auth) && (
|
|
371
404
|
<TopActions onPress={() => handleBackNavigation()}>
|
|
372
|
-
<
|
|
405
|
+
<AntDesignIcon
|
|
406
|
+
name='arrowleft'
|
|
407
|
+
size={26}
|
|
408
|
+
/>
|
|
373
409
|
</TopActions>
|
|
374
410
|
)}
|
|
411
|
+
{showTitle && (
|
|
412
|
+
<OText
|
|
413
|
+
size={16}
|
|
414
|
+
style={{ flex: 1, textAlign: 'center' }}
|
|
415
|
+
weight={Platform.OS === 'ios' ? '600' : 'bold'}
|
|
416
|
+
numberOfLines={2}
|
|
417
|
+
ellipsizeMode='tail'
|
|
418
|
+
>
|
|
419
|
+
{business?.name}
|
|
420
|
+
</OText>
|
|
421
|
+
)}
|
|
375
422
|
{!errorQuantityProducts && (
|
|
376
423
|
<View style={{ ...styles.headerItem }}>
|
|
377
424
|
<TouchableOpacity
|
|
@@ -427,8 +474,8 @@ const BusinessProductsListingUI = (props: BusinessProductsListingParams) => {
|
|
|
427
474
|
{business?.categories?.length > 0 && isOpenFiltProducts && (
|
|
428
475
|
<FiltProductsContainer
|
|
429
476
|
style={{
|
|
430
|
-
height: Dimensions.get('window').height - filtProductsHeight,
|
|
431
|
-
top: Platform.OS === 'ios' ? (searchBarHeight - 10) + insets.top : searchBarHeight
|
|
477
|
+
height: Dimensions.get('window').height - filtProductsHeight - keyboardHeight - (keyboardHeight > 0 && viewOrderButtonVisible ? 55 : 0),
|
|
478
|
+
top: Platform.OS === 'ios' ? (searchBarHeight - 10) + insets.top : searchBarHeight,
|
|
432
479
|
}}
|
|
433
480
|
contentContainerStyle={{ flexGrow: 1 }}
|
|
434
481
|
>
|
|
@@ -593,7 +640,7 @@ const BusinessProductsListingUI = (props: BusinessProductsListingParams) => {
|
|
|
593
640
|
</>
|
|
594
641
|
)}
|
|
595
642
|
</IOScrollView>
|
|
596
|
-
{
|
|
643
|
+
{viewOrderButtonVisible && (
|
|
597
644
|
<View style={{ marginBottom: 0 }}>
|
|
598
645
|
<FloatingButton
|
|
599
646
|
btnText={
|
|
@@ -649,6 +696,7 @@ const BusinessProductsListingUI = (props: BusinessProductsListingParams) => {
|
|
|
649
696
|
professionalList={business?.professionals}
|
|
650
697
|
professionalSelected={professionalSelected}
|
|
651
698
|
handleChangeProfessional={handleChangeProfessionalSelected}
|
|
699
|
+
handleChangeProfessional={handleChangeProfessionalSelected}
|
|
652
700
|
handleUpdateProfessionals={handleUpdateProfessionals}
|
|
653
701
|
onSave={() => setOpenService(false)}
|
|
654
702
|
onClose={() => setOpenService(false)}
|
|
@@ -3,6 +3,7 @@ import { View, StyleSheet, TouchableOpacity, Platform, I18nManager, ScrollView }
|
|
|
3
3
|
import { initStripe, useConfirmPayment } from '@stripe/stripe-react-native';
|
|
4
4
|
import Picker from 'react-native-country-picker-modal';
|
|
5
5
|
import MaterialIcons from 'react-native-vector-icons/MaterialIcons'
|
|
6
|
+
import ReactNativeHapticFeedback from "react-native-haptic-feedback";
|
|
6
7
|
import {
|
|
7
8
|
Checkout as CheckoutController,
|
|
8
9
|
useOrder,
|
|
@@ -52,7 +53,7 @@ import { FloatingButton } from '../FloatingButton';
|
|
|
52
53
|
import { Container } from '../../layouts/Container';
|
|
53
54
|
import NavBar from '../NavBar';
|
|
54
55
|
import { OrderSummary } from '../OrderSummary';
|
|
55
|
-
import { getTypesText
|
|
56
|
+
import { getTypesText } from '../../utils';
|
|
56
57
|
import { CartStoresListing } from '../CartStoresListing';
|
|
57
58
|
import { PaymentOptionsWebView } from '../../../../../src/components/PaymentOptionsWebView';
|
|
58
59
|
|
|
@@ -211,6 +212,14 @@ const CheckoutUI = (props: any) => {
|
|
|
211
212
|
}
|
|
212
213
|
}
|
|
213
214
|
|
|
215
|
+
const vibrateApp = (impact?: string) => {
|
|
216
|
+
const options = {
|
|
217
|
+
enableVibrateFallback: true,
|
|
218
|
+
ignoreAndroidSystemSettings: false
|
|
219
|
+
};
|
|
220
|
+
ReactNativeHapticFeedback.trigger(impact || "impactLight", options);
|
|
221
|
+
}
|
|
222
|
+
|
|
214
223
|
const handleSuccessSignup = (user: any) => {
|
|
215
224
|
login({
|
|
216
225
|
user,
|
|
@@ -6,6 +6,7 @@ import { PhoneInputNumber } from '../PhoneInputNumber';
|
|
|
6
6
|
import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons';
|
|
7
7
|
import Recaptcha from 'react-native-recaptcha-that-works'
|
|
8
8
|
import ReCaptcha from '@fatnlazycat/react-native-recaptcha-v3'
|
|
9
|
+
import ReactNativeHapticFeedback from "react-native-haptic-feedback";
|
|
9
10
|
|
|
10
11
|
import {
|
|
11
12
|
LoginForm as LoginFormController,
|
|
@@ -161,6 +162,14 @@ const LoginFormUI = (props: LoginParams) => {
|
|
|
161
162
|
handleCategoryScroll(otpType ? `${val}_${otpType}` : val)
|
|
162
163
|
};
|
|
163
164
|
|
|
165
|
+
const vibrateApp = (impact?: string) => {
|
|
166
|
+
const options = {
|
|
167
|
+
enableVibrateFallback: true,
|
|
168
|
+
ignoreAndroidSystemSettings: false
|
|
169
|
+
};
|
|
170
|
+
ReactNativeHapticFeedback.trigger(impact || "impactLight", options);
|
|
171
|
+
}
|
|
172
|
+
|
|
164
173
|
const onSubmit = (values?: any) => {
|
|
165
174
|
Keyboard.dismiss();
|
|
166
175
|
if (loginTab === 'otp') {
|
|
@@ -169,7 +178,7 @@ const LoginFormUI = (props: LoginParams) => {
|
|
|
169
178
|
Vibration.vibrate()
|
|
170
179
|
return
|
|
171
180
|
}
|
|
172
|
-
if(!values?.cellphone && otpType === 'cellphone'){
|
|
181
|
+
if (!values?.cellphone && otpType === 'cellphone') {
|
|
173
182
|
showToast(ToastType.Error, t('PHONE_NUMBER_REQUIRED', 'Phone number is required'));
|
|
174
183
|
return
|
|
175
184
|
}
|
|
@@ -258,7 +267,7 @@ const LoginFormUI = (props: LoginParams) => {
|
|
|
258
267
|
const handleLoginOtp = async (code: string) => {
|
|
259
268
|
if (!code) return
|
|
260
269
|
const logged = await handleButtonLoginClick({ code })
|
|
261
|
-
if (logged){
|
|
270
|
+
if (logged) {
|
|
262
271
|
setWillVerifyOtpState(false)
|
|
263
272
|
} else {
|
|
264
273
|
setAlertState({
|
|
@@ -166,7 +166,7 @@ export const MultiOrdersDetailsUI = (props: any) => {
|
|
|
166
166
|
<OText key={event.id} size={12} lineHeight={18} color={theme.colors.textNormal}>
|
|
167
167
|
{event?.wallet_event
|
|
168
168
|
? walletName[event?.wallet_event?.wallet?.type]?.name
|
|
169
|
-
: event?.paymethod?.name}
|
|
169
|
+
: t(event?.paymethod?.name.toUpperCase()?.replace(/ /g, '_'), event?.paymethod?.name)}
|
|
170
170
|
</OText>
|
|
171
171
|
))}
|
|
172
172
|
</Section>
|
|
@@ -12,14 +12,31 @@ export const OrderEta = (props: any) => {
|
|
|
12
12
|
const [estimatedDeliveryTime, setEstimatedDeliveryTime] = useState(null)
|
|
13
13
|
|
|
14
14
|
const getEstimatedDeliveryTime = () => {
|
|
15
|
-
let
|
|
15
|
+
let estimatedUtcTime = null
|
|
16
16
|
let totalEta = 0
|
|
17
|
+
if (order?.delivered_in) totalEta += order?.delivered_in
|
|
18
|
+
if (order?.prepared_in) totalEta += order?.prepared_in
|
|
19
|
+
if (order?.delivery_type === 1 && order?.eta_drive_time) {
|
|
20
|
+
totalEta += order?.eta_drive_time
|
|
21
|
+
}
|
|
22
|
+
|
|
17
23
|
const _delivery = order?.delivery_datetime_utc
|
|
18
24
|
? order?.delivery_datetime_utc
|
|
19
25
|
: order?.delivery_datetime
|
|
26
|
+
|
|
20
27
|
if (order?.eta_current_status_time) {
|
|
21
28
|
const currentStatueEta = order?.eta_current_status_time
|
|
22
29
|
totalEta += currentStatueEta
|
|
30
|
+
let previousStatusTimes = 0
|
|
31
|
+
if (order?.eta_previous_status_times) {
|
|
32
|
+
Object.keys(order.eta_previous_status_times).map(key => {
|
|
33
|
+
if (!key.includes('status_penalty')) {
|
|
34
|
+
previousStatusTimes += order.eta_previous_status_times[key]
|
|
35
|
+
}
|
|
36
|
+
})
|
|
37
|
+
}
|
|
38
|
+
totalEta += previousStatusTimes
|
|
39
|
+
|
|
23
40
|
let nextStatusTimes = 0
|
|
24
41
|
if (order?.eta_next_status_times) {
|
|
25
42
|
Object.keys(order.eta_next_status_times).map(key => {
|
|
@@ -28,7 +45,6 @@ export const OrderEta = (props: any) => {
|
|
|
28
45
|
}
|
|
29
46
|
})
|
|
30
47
|
}
|
|
31
|
-
|
|
32
48
|
totalEta += nextStatusTimes
|
|
33
49
|
|
|
34
50
|
const diffTimeAsSeconds = moment.utc(order?.reporting_data?.at[`status:${order.status}`]).add(order?.eta_current_status_time, 'minutes').diff(moment().utc(), 'seconds')
|
|
@@ -36,15 +52,11 @@ export const OrderEta = (props: any) => {
|
|
|
36
52
|
if (diffTimeAsMinutes <= 0) {
|
|
37
53
|
totalEta += (Math.floor(Math.abs(diffTimeAsMinutes / order?.eta_current_status_time) + 1) * order?.eta_current_status_penalty_time)
|
|
38
54
|
}
|
|
39
|
-
_estimatedTime = moment.utc(_delivery).add(totalEta, 'minutes')
|
|
40
55
|
} else {
|
|
41
|
-
|
|
42
|
-
if (order?.delivered_in) timesToAdd += order?.delivered_in
|
|
43
|
-
if (order?.prepared_in) timesToAdd += order?.prepared_in
|
|
44
|
-
const _etaTime = order?.eta_time + timesToAdd
|
|
45
|
-
_estimatedTime = moment.utc(_delivery).add(_etaTime, 'minutes')
|
|
56
|
+
totalEta = order?.eta_time + totalEta
|
|
46
57
|
}
|
|
47
|
-
|
|
58
|
+
estimatedUtcTime = moment.utc(_delivery).add(totalEta, 'minutes')
|
|
59
|
+
const _estimatedTime = outputFormat ? moment(estimatedUtcTime).local().format(outputFormat) : parseDate(estimatedUtcTime, { utc: false })
|
|
48
60
|
setEstimatedDeliveryTime(_estimatedTime)
|
|
49
61
|
}
|
|
50
62
|
|
|
@@ -31,6 +31,7 @@ import Swiper from 'react-native-swiper'
|
|
|
31
31
|
import FastImage from 'react-native-fast-image';
|
|
32
32
|
import IconAntDesign from 'react-native-vector-icons/AntDesign';
|
|
33
33
|
import YoutubePlayer from "react-native-youtube-iframe"
|
|
34
|
+
import ReactNativeHapticFeedback from "react-native-haptic-feedback";
|
|
34
35
|
|
|
35
36
|
import {
|
|
36
37
|
WrapHeader,
|
|
@@ -206,9 +207,18 @@ export const ProductOptionsUI = (props: any) => {
|
|
|
206
207
|
const [isScrollAvailable, setIsScrollAvailable] = useState(null)
|
|
207
208
|
const [editionsLayoutY, setEditionsLayoutY] = useState(null)
|
|
208
209
|
const [viewedProduct, setViewedProduct] = useState<any>(null)
|
|
210
|
+
const [showTitle, setShowTitle] = useState(false)
|
|
209
211
|
|
|
210
212
|
const guestCheckoutEnabled = configs?.guest_checkout_enabled?.value === '1'
|
|
211
|
-
|
|
213
|
+
const orderTypeEnabled = !orderTypeList[orderState?.options?.type - 1] || configs?.allowed_order_types_guest_checkout?.value?.includes(orderTypeList[orderState?.options?.type - 1])
|
|
214
|
+
|
|
215
|
+
const vibrateApp = (impact?: string) => {
|
|
216
|
+
const options = {
|
|
217
|
+
enableVibrateFallback: true,
|
|
218
|
+
ignoreAndroidSystemSettings: false
|
|
219
|
+
};
|
|
220
|
+
ReactNativeHapticFeedback.trigger(impact || "impactLight", options);
|
|
221
|
+
}
|
|
212
222
|
|
|
213
223
|
const isError = (id: number) => {
|
|
214
224
|
let bgColor = theme.colors.white;
|
|
@@ -363,7 +373,7 @@ export const ProductOptionsUI = (props: any) => {
|
|
|
363
373
|
);
|
|
364
374
|
|
|
365
375
|
const handleScroll = ({ nativeEvent: { contentOffset, layoutMeasurement } }: any) => {
|
|
366
|
-
|
|
376
|
+
setShowTitle(contentOffset.y > 30)
|
|
367
377
|
const _topOption = Object.keys(optionLayout).find(((option: any) => Math.abs(contentOffset?.y - layoutMeasurement?.height - optionLayout[option]?.y) < 20))
|
|
368
378
|
if (_topOption) {
|
|
369
379
|
const _topOptionId = Number(_topOption.replace('id:', ''))
|
|
@@ -527,12 +537,24 @@ export const ProductOptionsUI = (props: any) => {
|
|
|
527
537
|
return (
|
|
528
538
|
<SafeAreaView style={{ flex: 1 }}>
|
|
529
539
|
<View style={styles.wrapperNavbar}>
|
|
530
|
-
<
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
540
|
+
<TopHeader>
|
|
541
|
+
<>
|
|
542
|
+
<TopActions onPress={() => handleGoBack()}>
|
|
543
|
+
<OIcon src={theme.images.general.arrow_left} color={theme.colors.textNormal} />
|
|
544
|
+
</TopActions>
|
|
545
|
+
{showTitle && (
|
|
546
|
+
<OText
|
|
547
|
+
size={16}
|
|
548
|
+
style={{ flex: 1, textAlign: 'center' }}
|
|
549
|
+
weight={Platform.OS === 'ios' ? '600' : 'bold'}
|
|
550
|
+
numberOfLines={2}
|
|
551
|
+
ellipsizeMode='tail'
|
|
552
|
+
>
|
|
553
|
+
{product?.name}
|
|
554
|
+
</OText>
|
|
555
|
+
)}
|
|
556
|
+
</>
|
|
557
|
+
</TopHeader>
|
|
536
558
|
</View>
|
|
537
559
|
{!error && (
|
|
538
560
|
<ScrollView
|
|
@@ -8,8 +8,8 @@ export const WrapHeader = styled.View`
|
|
|
8
8
|
export const TopActions = styled.TouchableOpacity`
|
|
9
9
|
height: 60px;
|
|
10
10
|
justify-content: center;
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
min-width: 30px;
|
|
12
|
+
padding-right: 15px;
|
|
13
13
|
`;
|
|
14
14
|
|
|
15
15
|
export const TopHeader = styled.View`
|
|
@@ -68,7 +68,7 @@ export const ProductOptionSubOptionUI = (props: any) => {
|
|
|
68
68
|
|
|
69
69
|
return (
|
|
70
70
|
<View>
|
|
71
|
-
<Container onPress={() => handleSuboptionClick()}>
|
|
71
|
+
<Container onPress={!(option?.with_half_option || option?.allow_suboption_quantity) ? () => handleSuboptionClick() : null}>
|
|
72
72
|
<IconControl disabled={disabled} onPress={() => handleSuboptionClick()}>
|
|
73
73
|
{((option?.min === 0 && option?.max === 1) || option?.max > 1) ? (
|
|
74
74
|
state?.selected ? (
|
|
@@ -8,6 +8,7 @@ import { PhoneInputNumber } from '../PhoneInputNumber';
|
|
|
8
8
|
import { FacebookLogin } from '../FacebookLogin';
|
|
9
9
|
import Recaptcha from 'react-native-recaptcha-that-works'
|
|
10
10
|
import ReCaptcha from '@fatnlazycat/react-native-recaptcha-v3'
|
|
11
|
+
import ReactNativeHapticFeedback from "react-native-haptic-feedback";
|
|
11
12
|
|
|
12
13
|
import {
|
|
13
14
|
SignupForm as SignUpController,
|
|
@@ -37,7 +38,7 @@ import Alert from '../../../../../src/providers/AlertProvider'
|
|
|
37
38
|
import { OText, OButton, OInput } from '../shared';
|
|
38
39
|
import { OModal } from '../../../../../src/components/shared';
|
|
39
40
|
import { SignupParams } from '../../types';
|
|
40
|
-
import { sortInputFields
|
|
41
|
+
import { sortInputFields } from '../../utils';
|
|
41
42
|
import { GoogleLogin } from '../GoogleLogin';
|
|
42
43
|
import { AppleLogin } from '../AppleLogin';
|
|
43
44
|
|
|
@@ -164,6 +165,14 @@ const SignupFormUI = (props: SignupParams) => {
|
|
|
164
165
|
})
|
|
165
166
|
}
|
|
166
167
|
|
|
168
|
+
const vibrateApp = (impact?: string) => {
|
|
169
|
+
const options = {
|
|
170
|
+
enableVibrateFallback: true,
|
|
171
|
+
ignoreAndroidSystemSettings: false
|
|
172
|
+
};
|
|
173
|
+
ReactNativeHapticFeedback.trigger(impact || "impactLight", options);
|
|
174
|
+
}
|
|
175
|
+
|
|
167
176
|
const handleRefs = (ref: any, code: string) => {
|
|
168
177
|
switch (code) {
|
|
169
178
|
case 'name': {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, { useState } from 'react';
|
|
1
|
+
import React, { useState, useEffect } from 'react';
|
|
2
2
|
import {
|
|
3
3
|
SingleOrderCard as SingleOrderCardController,
|
|
4
4
|
useUtils,
|
|
@@ -12,6 +12,7 @@ import { OIcon, OText, OButton } from '../shared';
|
|
|
12
12
|
import { SingleOrderCardParams } from '../../types';
|
|
13
13
|
import { OAlert } from '../../../../../src/components/shared'
|
|
14
14
|
import { OrderEta } from '../OrderDetails/OrderEta'
|
|
15
|
+
import { useIsFocused } from '@react-navigation/native';
|
|
15
16
|
import {
|
|
16
17
|
InnerContainer,
|
|
17
18
|
Logo,
|
|
@@ -45,6 +46,7 @@ const SingleOrderCardUI = (props: SingleOrderCardParams) => {
|
|
|
45
46
|
const [, t] = useLanguage();
|
|
46
47
|
const [{ carts }] = useOrder()
|
|
47
48
|
const theme = useTheme();
|
|
49
|
+
const isFocused = useIsFocused();
|
|
48
50
|
|
|
49
51
|
let [reorderSelected, setReorderSelected] = useState<number | null>(null);
|
|
50
52
|
const [confirm, setConfirm] = useState<any>({ open: false, content: null, handleOnAccept: null, id: null, title: null })
|
|
@@ -209,6 +211,10 @@ const SingleOrderCardUI = (props: SingleOrderCardParams) => {
|
|
|
209
211
|
const hideFavorite = theme?.orders?.components?.favorite?.hidden
|
|
210
212
|
const hideOrderStatus = theme?.orders?.components?.order_status?.hidden
|
|
211
213
|
|
|
214
|
+
useEffect(() => {
|
|
215
|
+
if (isFocused) setReorderSelected(null)
|
|
216
|
+
}, [isFocused])
|
|
217
|
+
|
|
212
218
|
return (
|
|
213
219
|
<>
|
|
214
220
|
<CardAnimation
|
|
@@ -288,7 +288,11 @@ const ProfileUI = (props: ProfileParams) => {
|
|
|
288
288
|
showCall={false}
|
|
289
289
|
btnStyle={{ paddingLeft: 0 }}
|
|
290
290
|
/>
|
|
291
|
-
<KeyboardAvoidingView
|
|
291
|
+
<KeyboardAvoidingView
|
|
292
|
+
behavior={Platform.OS == 'ios' ? 'padding' : 'height'}
|
|
293
|
+
enabled={Platform.OS === 'ios' ? true : false}
|
|
294
|
+
style={{ flex: 1, flexDirection: 'column', justifyContent: 'center' }}
|
|
295
|
+
>
|
|
292
296
|
<CenterView>
|
|
293
297
|
<View style={styles.photo}>
|
|
294
298
|
{user?.photo ? (
|
|
@@ -63,12 +63,12 @@ export const WalletTransactions = (props: any) => {
|
|
|
63
63
|
(transactionsList?.error ||
|
|
64
64
|
!transactionsList.list?.[`wallet:${currentWalletSelected?.id}`]?.length) &&
|
|
65
65
|
(
|
|
66
|
-
<
|
|
67
|
-
|
|
66
|
+
<OText color={theme.colors.disabled} size={16} style={{ textAlign: 'center' }}>
|
|
67
|
+
{transactionsList?.error
|
|
68
68
|
? t('ERROR_NOT_FOUND_TRANSACTIONS', 'Sorry, an error has occurred')
|
|
69
69
|
: t('NOT_FOUND_TRANSACTIONS', 'No transactions to show at this time.')
|
|
70
70
|
}
|
|
71
|
-
|
|
71
|
+
</OText>
|
|
72
72
|
)}
|
|
73
73
|
</View>
|
|
74
74
|
</Container>
|
|
@@ -195,9 +195,9 @@ const WalletsUI = (props: any) => {
|
|
|
195
195
|
<LoyaltyContent>
|
|
196
196
|
<LoyaltyWrapp>
|
|
197
197
|
<OText size={20}>
|
|
198
|
-
{`${t('LOYALTY_LEVEL_TITLE', 'Your level is')}
|
|
198
|
+
{`${t('LOYALTY_LEVEL_TITLE', 'Your level is')}`}
|
|
199
199
|
</OText>
|
|
200
|
-
{
|
|
200
|
+
{loyaltyLevel.image ? (
|
|
201
201
|
<FastImage
|
|
202
202
|
style={styles.logoStyle}
|
|
203
203
|
source={{
|
|
@@ -212,7 +212,7 @@ const WalletsUI = (props: any) => {
|
|
|
212
212
|
source={theme.images.dummies.loyaltyLevel}
|
|
213
213
|
resizeMode='contain'
|
|
214
214
|
/>
|
|
215
|
-
)}
|
|
215
|
+
)}
|
|
216
216
|
<OText
|
|
217
217
|
size={22}
|
|
218
218
|
weight='bold'
|
|
@@ -4,7 +4,6 @@ import FontAwesome from 'react-native-vector-icons/FontAwesome';
|
|
|
4
4
|
import { CODES } from 'ordering-components/native'
|
|
5
5
|
import { ORDER_TYPES } from '../config/constants';
|
|
6
6
|
import { useTheme } from 'styled-components/native';
|
|
7
|
-
import ReactNativeHapticFeedback from "react-native-haptic-feedback";
|
|
8
7
|
|
|
9
8
|
const [languageState, t] = useLanguage();
|
|
10
9
|
const theme = useTheme()
|
|
@@ -613,13 +612,3 @@ export const lightenDarkenColor = (color: any) => {
|
|
|
613
612
|
return false
|
|
614
613
|
}
|
|
615
614
|
}
|
|
616
|
-
|
|
617
|
-
export const vibrateApp = (impact?: string) => {
|
|
618
|
-
const options = {
|
|
619
|
-
enableVibrateFallback: true,
|
|
620
|
-
ignoreAndroidSystemSettings: false
|
|
621
|
-
};
|
|
622
|
-
|
|
623
|
-
ReactNativeHapticFeedback.trigger(impact || "impactLight", options);
|
|
624
|
-
|
|
625
|
-
}
|