@propel-nsl/propel-react-native-sdk 1.0.0
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/assets/fonts/Lexend-Black.ttf +0 -0
- package/assets/fonts/Lexend-Bold.ttf +0 -0
- package/assets/fonts/Lexend-ExtraBold.ttf +0 -0
- package/assets/fonts/Lexend-ExtraLight.ttf +0 -0
- package/assets/fonts/Lexend-Light.ttf +0 -0
- package/assets/fonts/Lexend-Medium.ttf +0 -0
- package/assets/fonts/Lexend-Regular.ttf +0 -0
- package/assets/fonts/Lexend-SemiBold.ttf +0 -0
- package/assets/fonts/Lexend-Thin.ttf +0 -0
- package/assets/images/HomeGoods.png +0 -0
- package/assets/images/accessories.png +0 -0
- package/assets/images/amazon.png +0 -0
- package/assets/images/apnaClubLogo.png +0 -0
- package/assets/images/apparel.png +0 -0
- package/assets/images/backgroundblue.png +0 -0
- package/assets/images/bannerCard.png +0 -0
- package/assets/images/bottomWave.png +0 -0
- package/assets/images/coin_1_1.png +0 -0
- package/assets/images/flipkart.png +0 -0
- package/assets/images/frame_1171278967.png +0 -0
- package/assets/images/gift.png +0 -0
- package/assets/images/herobanner.png +0 -0
- package/assets/images/hinduPencilsLogo.png +0 -0
- package/assets/images/icons/addwhiteicon.png +0 -0
- package/assets/images/icons/arrow-back.png +0 -0
- package/assets/images/icons/arrowgreen.png +0 -0
- package/assets/images/icons/arrowred.png +0 -0
- package/assets/images/icons/arrowright.png +0 -0
- package/assets/images/icons/arrowup.png +0 -0
- package/assets/images/icons/blackarrowdown.png +0 -0
- package/assets/images/icons/blackarrowup.png +0 -0
- package/assets/images/icons/blackcross.png +0 -0
- package/assets/images/icons/call.png +0 -0
- package/assets/images/icons/camera.png +0 -0
- package/assets/images/icons/cart.png +0 -0
- package/assets/images/icons/chat.png +0 -0
- package/assets/images/icons/circleblack.png +0 -0
- package/assets/images/icons/copy.png +0 -0
- package/assets/images/icons/cross.png +0 -0
- package/assets/images/icons/delete.png +0 -0
- package/assets/images/icons/delivery.png +0 -0
- package/assets/images/icons/eVoucher.png +0 -0
- package/assets/images/icons/editIcon.png +0 -0
- package/assets/images/icons/email.png +0 -0
- package/assets/images/icons/eye.png +0 -0
- package/assets/images/icons/faq.png +0 -0
- package/assets/images/icons/filtericon.png +0 -0
- package/assets/images/icons/greyDownArrow.png +0 -0
- package/assets/images/icons/help.png +0 -0
- package/assets/images/icons/home.png +0 -0
- package/assets/images/icons/homeinactive.png +0 -0
- package/assets/images/icons/i_blackicon.png +0 -0
- package/assets/images/icons/i_icon.png +0 -0
- package/assets/images/icons/location.png +0 -0
- package/assets/images/icons/logout.png +0 -0
- package/assets/images/icons/minus.png +0 -0
- package/assets/images/icons/myOrders.png +0 -0
- package/assets/images/icons/orders.png +0 -0
- package/assets/images/icons/pencillogo.png +0 -0
- package/assets/images/icons/pending.png +0 -0
- package/assets/images/icons/plus.png +0 -0
- package/assets/images/icons/redCross.png +0 -0
- package/assets/images/icons/redCrossicon.png +0 -0
- package/assets/images/icons/redWarningicon.png +0 -0
- package/assets/images/icons/redeem.png +0 -0
- package/assets/images/icons/redeemactive.png +0 -0
- package/assets/images/icons/redemptionHistory.png +0 -0
- package/assets/images/icons/redhelpicon.png +0 -0
- package/assets/images/icons/search.png +0 -0
- package/assets/images/icons/stopwatch.png +0 -0
- package/assets/images/icons/successTick.gif +0 -0
- package/assets/images/icons/tick.png +0 -0
- package/assets/images/icons/tnc.png +0 -0
- package/assets/images/icons/user.png +0 -0
- package/assets/images/icons/userredicon.png +0 -0
- package/assets/images/icons/wavecorner.png +0 -0
- package/assets/images/logo.png +0 -0
- package/assets/images/myntra_copy.png +0 -0
- package/assets/images/nike.png +0 -0
- package/assets/images/oq3p0u0_1.png +0 -0
- package/assets/images/profileicon.png +0 -0
- package/assets/images/topWave.png +0 -0
- package/assets/images/zagglePropelLogo.png +0 -0
- package/index.ts +23 -0
- package/lib/index.ts +25 -0
- package/package.json +70 -0
- package/src/PropelSDKScreen.tsx +98 -0
- package/src/SDKApp.tsx +540 -0
- package/src/bridge/SDKBridge.ts +104 -0
- package/src/bridge/index.ts +3 -0
- package/src/components/SDKBackHandler.tsx +187 -0
- package/src/components/SDKProfile.tsx +87 -0
- package/src/components/SDKProfileWrapper.tsx +51 -0
- package/src/constants.ts +10 -0
- package/src/contexts/SDKContext.tsx +72 -0
- package/src/hooks/useSDKBackNavigation.ts +61 -0
- package/src/navigation/SDKMainTabNavigator.tsx +315 -0
- package/src/navigation/SDKNavigator.tsx +41 -0
- package/src/redux/store.ts +32 -0
- package/src/screens/Dashboard/index.tsx +531 -0
- package/src/screens/Dashboard/styles.ts +512 -0
- package/src/screens/DeliveryAddress/index.tsx +221 -0
- package/src/screens/DeliveryAddress/styles.ts +122 -0
- package/src/screens/E-Vouchers/index.tsx +157 -0
- package/src/screens/E-Vouchers/styles.ts +106 -0
- package/src/screens/Faq/Faq.constants.ts +164 -0
- package/src/screens/Faq/index.tsx +114 -0
- package/src/screens/Faq/styles.ts +131 -0
- package/src/screens/Help/index.tsx +128 -0
- package/src/screens/Help/styles.ts +121 -0
- package/src/screens/Login/index.tsx +215 -0
- package/src/screens/Login/styles.ts +134 -0
- package/src/screens/MyCart/MyCart.constants.ts +13 -0
- package/src/screens/MyCart/index.tsx +318 -0
- package/src/screens/MyCart/styles.ts +249 -0
- package/src/screens/MyOrders/index.tsx +87 -0
- package/src/screens/MyOrders/styles.ts +281 -0
- package/src/screens/MyProfile/index.tsx +72 -0
- package/src/screens/MyProfile/styles.ts +47 -0
- package/src/screens/NewDeliveryAddress/index.tsx +360 -0
- package/src/screens/NewDeliveryAddress/styles.ts +68 -0
- package/src/screens/Onboarding/index.tsx +57 -0
- package/src/screens/Onboarding/styles.ts +60 -0
- package/src/screens/OrdersDetails/index.tsx +333 -0
- package/src/screens/OrdersDetails/styles.ts +262 -0
- package/src/screens/OtpVerification/index.tsx +283 -0
- package/src/screens/OtpVerification/styles.ts +197 -0
- package/src/screens/PaymentMethod/index.tsx +389 -0
- package/src/screens/PaymentMethod/styles.ts +246 -0
- package/src/screens/PointsLog/index.tsx +286 -0
- package/src/screens/PointsLog/styles.ts +156 -0
- package/src/screens/ProductDetails/index.tsx +682 -0
- package/src/screens/ProductDetails/styles.ts +372 -0
- package/src/screens/Profile/index.tsx +368 -0
- package/src/screens/Profile/styles.ts +158 -0
- package/src/screens/RedemptionHistory/RedemptionHistory.constants.ts +4 -0
- package/src/screens/RedemptionHistory/index.tsx +304 -0
- package/src/screens/RedemptionHistory/styles.ts +84 -0
- package/src/screens/Reedem/index.tsx +345 -0
- package/src/screens/Reedem/styles.ts +269 -0
- package/src/screens/TnC/TnC.constants.ts +169 -0
- package/src/screens/TnC/index.tsx +83 -0
- package/src/screens/TnC/styles.ts +88 -0
- package/src/screens/TransactionSuccessful/index.tsx +77 -0
- package/src/screens/TransactionSuccessful/styles.ts +77 -0
- package/src/screens/Verification/index.tsx +58 -0
- package/src/screens/Verification/styles.ts +74 -0
- package/src/screens/index.ts +23 -0
- package/src/types/index.ts +46 -0
- package/src-app/components/AmountBreakDownModal/index.tsx +86 -0
- package/src-app/components/AmountBreakDownModal/styles.ts +110 -0
- package/src-app/components/BottomNavIcons.tsx +125 -0
- package/src-app/components/Button.tsx +120 -0
- package/src-app/components/Card.tsx +47 -0
- package/src-app/components/ConfirmPopup/ConfirmPopup.constants.ts +25 -0
- package/src-app/components/ConfirmPopup/index.tsx +48 -0
- package/src-app/components/ConfirmPopup/styles.ts +167 -0
- package/src-app/components/CustomButton/index.tsx +67 -0
- package/src-app/components/CustomButton/styles.ts +44 -0
- package/src-app/components/CustomCard/index.tsx +221 -0
- package/src-app/components/CustomCard/styles.ts +184 -0
- package/src-app/components/CustomError/index.tsx +54 -0
- package/src-app/components/CustomError/styles.ts +41 -0
- package/src-app/components/CustomImage/index.tsx +37 -0
- package/src-app/components/CustomImage/styles.ts +5 -0
- package/src-app/components/CustomLoader/index.tsx +45 -0
- package/src-app/components/CustomLoader/styles.ts +35 -0
- package/src-app/components/CustomMessagePopUp/index.tsx +51 -0
- package/src-app/components/CustomMessagePopUp/styles.ts +74 -0
- package/src-app/components/CustomProductCard/index.tsx +13 -0
- package/src-app/components/CustomProductCard/styles.ts +5 -0
- package/src-app/components/FilterModal.tsx +372 -0
- package/src-app/components/Footer/index.tsx +23 -0
- package/src-app/components/Footer/styles.ts +37 -0
- package/src-app/components/Icon.tsx +80 -0
- package/src-app/components/Logout/index.tsx +82 -0
- package/src-app/components/Logout/styles.ts +116 -0
- package/src-app/components/MobileHeader.tsx +141 -0
- package/src-app/components/NoDataFound/index.tsx +18 -0
- package/src-app/components/NoDataFound/styles.ts +26 -0
- package/src-app/components/OTPModal.tsx +747 -0
- package/src-app/components/ProfileField.tsx +47 -0
- package/src-app/components/QuantityModal/index.tsx +113 -0
- package/src-app/components/QuantityModal/styles.ts +84 -0
- package/src-app/components/TabBarIcons.tsx +110 -0
- package/src-app/components/TextInput.tsx +79 -0
- package/src-app/components/ToastConfig.tsx +60 -0
- package/src-app/components/index.ts +18 -0
- package/src-app/config/env.ts +22 -0
- package/src-app/constants/Fonts.ts +12 -0
- package/src-app/constants/Formatter.ts +39 -0
- package/src-app/constants/HtmlSanitization.ts +46 -0
- package/src-app/constants/Images.ts +81 -0
- package/src-app/constants/Labels.ts +8 -0
- package/src-app/constants/Messages.ts +108 -0
- package/src-app/constants/Routes.ts +17 -0
- package/src-app/constants/Scaling.ts +5 -0
- package/src-app/constants/Text.ts +8 -0
- package/src-app/constants/offSets.ts +18 -0
- package/src-app/hooks/useAppDispatch.ts +4 -0
- package/src-app/hooks/useAppSelector.ts +4 -0
- package/src-app/hooks/useBackHandler.ts +47 -0
- package/src-app/hooks/useScreenBackHandler.ts +91 -0
- package/src-app/navigation/AppNavigator.tsx +34 -0
- package/src-app/navigation/MainTabNavigator.tsx +294 -0
- package/src-app/redux/authSaga.ts +605 -0
- package/src-app/redux/authSlice.ts +754 -0
- package/src-app/redux/rootSaga.ts +6 -0
- package/src-app/redux/store.ts +25 -0
- package/src-app/services/api.ts +14 -0
- package/src-app/services/endpoints.ts +33 -0
- package/src-app/services/index.ts +574 -0
- package/src-app/services/sdkCredentials.ts +44 -0
- package/src-app/styles/colors.ts +85 -0
- package/src-app/styles/shared.ts +112 -0
- package/src-app/types/authTypes.ts +155 -0
- package/src-app/types/navigation.ts +99 -0
- package/src-app/utils/Validation.ts +48 -0
- package/src-app/utils/filterPins.ts +29 -0
- package/src-app/utils/navigationUtils.ts +43 -0
- package/src-app/utils/useHardwareBack.ts +21 -0
|
@@ -0,0 +1,304 @@
|
|
|
1
|
+
import React, {useEffect, useMemo, useState, useCallback } from "react";
|
|
2
|
+
import { View, Text, ScrollView, StyleSheet, NativeModules } from "react-native";
|
|
3
|
+
import { StackNavigationProp } from "@react-navigation/stack";
|
|
4
|
+
import { AppStackParamList } from "../../../src-app/types/navigation";
|
|
5
|
+
import MobileHeader from "../../../src-app/components/MobileHeader";
|
|
6
|
+
import styles from "./styles";
|
|
7
|
+
import { RouteProp, useFocusEffect, useRoute } from "@react-navigation/native";
|
|
8
|
+
import { useAppSelector } from "../../../src-app/hooks/useAppSelector";
|
|
9
|
+
import { useAppDispatch } from "../../../src-app/hooks/useAppDispatch";
|
|
10
|
+
import { RootState } from "../../../src-app/redux/store";
|
|
11
|
+
import {
|
|
12
|
+
CustomImage,
|
|
13
|
+
CustomLoader,
|
|
14
|
+
NoDataFound,
|
|
15
|
+
} from "../../../src-app/components";
|
|
16
|
+
import Images from "../../../src-app/constants/Images";
|
|
17
|
+
import { useSafeAreaInsets } from "react-native-safe-area-context";
|
|
18
|
+
import { OrderNo, PointsRedeemed, RedemptionHistoryTitle } from "./RedemptionHistory.constants";
|
|
19
|
+
import { useSDKContext } from '../../contexts/SDKContext';
|
|
20
|
+
import OTPModal from "../../../src-app/components/OTPModal";
|
|
21
|
+
import {
|
|
22
|
+
clearAllAuthState,
|
|
23
|
+
myOrdersGenerateOtpRequest,
|
|
24
|
+
myOrdersValidateOtpRequest,
|
|
25
|
+
resetAuthState,
|
|
26
|
+
} from "../../../src-app/redux/authSlice";
|
|
27
|
+
import { ROUTES } from "../../../src-app/constants/Routes";
|
|
28
|
+
|
|
29
|
+
type RedemptionHistoryNavigationProp = StackNavigationProp<
|
|
30
|
+
AppStackParamList,
|
|
31
|
+
"RedemptionHistory"
|
|
32
|
+
>;
|
|
33
|
+
|
|
34
|
+
interface Props {
|
|
35
|
+
navigation: RedemptionHistoryNavigationProp;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
type RedemptionHistoryRouteProp = RouteProp<
|
|
39
|
+
AppStackParamList,
|
|
40
|
+
"RedemptionHistory"
|
|
41
|
+
>;
|
|
42
|
+
|
|
43
|
+
const TAB_LIKE_OFFSET = 210;
|
|
44
|
+
|
|
45
|
+
const RedemptionHistory: React.FC<Props> = ({ navigation }) => {
|
|
46
|
+
const route = useRoute<RedemptionHistoryRouteProp>();
|
|
47
|
+
const from = route.params?.from;
|
|
48
|
+
const exitToHost = (route.params as any)?.exitToHost;
|
|
49
|
+
const insets = useSafeAreaInsets();
|
|
50
|
+
const { isDeepLinkEntry } = useSDKContext();
|
|
51
|
+
const dispatch = useAppDispatch();
|
|
52
|
+
|
|
53
|
+
// OTP modal state for deep link entry or direct access without prior OTP verification
|
|
54
|
+
const [otpModalVisible, setOtpModalVisible] = useState(false);
|
|
55
|
+
const [resetOtpTrigger, setResetOtpTrigger] = useState(0);
|
|
56
|
+
const [hasTriggeredOtp, setHasTriggeredOtp] = useState(false);
|
|
57
|
+
|
|
58
|
+
// Add mount logging
|
|
59
|
+
React.useEffect(() => {
|
|
60
|
+
console.log('🚀 RedemptionHistory MOUNTED with params:', { from, exitToHost, isDeepLinkEntry });
|
|
61
|
+
return () => {
|
|
62
|
+
console.log('🚀 RedemptionHistory UNMOUNTED');
|
|
63
|
+
};
|
|
64
|
+
}, []);
|
|
65
|
+
|
|
66
|
+
React.useEffect(() => {
|
|
67
|
+
console.log('🚀 RedemptionHistory route params changed:', { from, exitToHost });
|
|
68
|
+
}, [from, exitToHost]);
|
|
69
|
+
|
|
70
|
+
const handleGoBack = () => {
|
|
71
|
+
// If deep-linked from host app, exit SDK instead of navigating back
|
|
72
|
+
if (exitToHost || (isDeepLinkEntry && (!from || from === 'DeepLink' || from === 'HostApp'))) {
|
|
73
|
+
console.log('🚀 RedemptionHistory: Deep link entry - exiting SDK to host app');
|
|
74
|
+
dispatch(clearAllAuthState());
|
|
75
|
+
if (NativeModules.PropelSDKBridge?.closeSDK) {
|
|
76
|
+
NativeModules.PropelSDKBridge.closeSDK();
|
|
77
|
+
} else if (NativeModules.PropelSDKBridge?.dismiss) {
|
|
78
|
+
NativeModules.PropelSDKBridge.dismiss();
|
|
79
|
+
}
|
|
80
|
+
return true;
|
|
81
|
+
}
|
|
82
|
+
if (navigation.canGoBack()) {
|
|
83
|
+
navigation.goBack();
|
|
84
|
+
return true;
|
|
85
|
+
}
|
|
86
|
+
// Fallback: navigate to originating screen or Dashboard
|
|
87
|
+
if (from) {
|
|
88
|
+
navigation.navigate(from as never);
|
|
89
|
+
return true;
|
|
90
|
+
}
|
|
91
|
+
navigation.navigate('DashboardTab' as never, { screen: 'Dashboard' });
|
|
92
|
+
return true;
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
// Use myOrdersValidateOtpData from OTP verification (same as MyOrders screen)
|
|
96
|
+
const {
|
|
97
|
+
myOrdersValidateOtpData,
|
|
98
|
+
myOrdersValidateOtpLoading,
|
|
99
|
+
myOrdersValidateOtpError,
|
|
100
|
+
myOrdersValidateOtpSuccessMessage,
|
|
101
|
+
sdkAuthData,
|
|
102
|
+
} = useAppSelector((state: RootState) => state.auth);
|
|
103
|
+
|
|
104
|
+
// Check if we need to show OTP modal on mount (deep link or direct access without data)
|
|
105
|
+
useFocusEffect(
|
|
106
|
+
React.useCallback(() => {
|
|
107
|
+
console.log('📝 RedemptionHistory: Focus effect - checking if OTP needed', {
|
|
108
|
+
isDeepLinkEntry,
|
|
109
|
+
from,
|
|
110
|
+
hasData: !!myOrdersValidateOtpData?.length,
|
|
111
|
+
hasTriggeredOtp,
|
|
112
|
+
hasSDKAuth: !!sdkAuthData?.session?.token,
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
// Wait for SDK authentication to complete before generating OTP
|
|
116
|
+
// This ensures the auth token is available for the OTP API call
|
|
117
|
+
if (!sdkAuthData?.session?.token) {
|
|
118
|
+
console.log('📝 RedemptionHistory: Waiting for SDK auth to complete before OTP generation');
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// Show OTP modal if:
|
|
123
|
+
// 1. Deep link entry and no data yet
|
|
124
|
+
// 2. Direct access (not from Dashboard/Profile OTP flow) and no data
|
|
125
|
+
const needsOtp = !myOrdersValidateOtpData?.length && !hasTriggeredOtp;
|
|
126
|
+
|
|
127
|
+
if (needsOtp && (isDeepLinkEntry || from === 'DeepLink' || !from)) {
|
|
128
|
+
console.log('📝 RedemptionHistory: Showing OTP modal for authentication');
|
|
129
|
+
setHasTriggeredOtp(true);
|
|
130
|
+
setOtpModalVisible(true);
|
|
131
|
+
dispatch(myOrdersGenerateOtpRequest({}));
|
|
132
|
+
}
|
|
133
|
+
}, [isDeepLinkEntry, from, myOrdersValidateOtpData, hasTriggeredOtp, dispatch, sdkAuthData])
|
|
134
|
+
);
|
|
135
|
+
|
|
136
|
+
// Handle OTP validation success
|
|
137
|
+
useEffect(() => {
|
|
138
|
+
if (otpModalVisible && myOrdersValidateOtpSuccessMessage) {
|
|
139
|
+
console.log('📝 RedemptionHistory: OTP validated successfully, closing modal');
|
|
140
|
+
setOtpModalVisible(false);
|
|
141
|
+
dispatch(resetAuthState("myOrdersValidateOtpSuccessMessage" as any));
|
|
142
|
+
dispatch(resetAuthState("myOrdersValidateOtpError" as any));
|
|
143
|
+
}
|
|
144
|
+
}, [otpModalVisible, myOrdersValidateOtpSuccessMessage, dispatch]);
|
|
145
|
+
|
|
146
|
+
// Close OTP modal when screen loses focus
|
|
147
|
+
useFocusEffect(
|
|
148
|
+
useCallback(() => {
|
|
149
|
+
return () => {
|
|
150
|
+
// This runs when the screen loses focus (unmounts or navigates away)
|
|
151
|
+
console.log('📝 RedemptionHistory: Screen losing focus, closing OTP modal');
|
|
152
|
+
setOtpModalVisible(false);
|
|
153
|
+
};
|
|
154
|
+
}, [])
|
|
155
|
+
);
|
|
156
|
+
|
|
157
|
+
const handleVerify = async (otp: string) => {
|
|
158
|
+
console.log('📝 RedemptionHistory: Verifying OTP:', otp);
|
|
159
|
+
try {
|
|
160
|
+
dispatch(
|
|
161
|
+
myOrdersValidateOtpRequest({
|
|
162
|
+
otp: otp,
|
|
163
|
+
})
|
|
164
|
+
);
|
|
165
|
+
} catch (error) {
|
|
166
|
+
console.error("Error verifying OTP:", error);
|
|
167
|
+
}
|
|
168
|
+
};
|
|
169
|
+
|
|
170
|
+
// Debug API data changes
|
|
171
|
+
useEffect(() => {
|
|
172
|
+
console.log('📋 RedemptionHistory: myOrdersValidateOtpData changed:', {
|
|
173
|
+
isArray: Array.isArray(myOrdersValidateOtpData),
|
|
174
|
+
length: myOrdersValidateOtpData?.length,
|
|
175
|
+
data: myOrdersValidateOtpData,
|
|
176
|
+
});
|
|
177
|
+
}, [myOrdersValidateOtpData]);
|
|
178
|
+
|
|
179
|
+
// Use actual data from myOrdersValidateOtpData (orders API via OTP verification)
|
|
180
|
+
const displayData = useMemo(() => {
|
|
181
|
+
if (Array.isArray(myOrdersValidateOtpData) && myOrdersValidateOtpData.length > 0) {
|
|
182
|
+
console.log('📋 RedemptionHistory: Using orders API data', myOrdersValidateOtpData.length, 'items');
|
|
183
|
+
console.log('📋 RedemptionHistory: API data sample:', myOrdersValidateOtpData[0]);
|
|
184
|
+
return myOrdersValidateOtpData;
|
|
185
|
+
}
|
|
186
|
+
// Return empty array if no data from backend
|
|
187
|
+
console.log('📋 RedemptionHistory: No data from backend, showing empty state');
|
|
188
|
+
return [];
|
|
189
|
+
}, [myOrdersValidateOtpData]);
|
|
190
|
+
|
|
191
|
+
const formatDate = (isoDate: string) => {
|
|
192
|
+
const date = new Date(isoDate);
|
|
193
|
+
const day = date.toLocaleString("en-GB", { day: "2-digit" });
|
|
194
|
+
const month = date.toLocaleString("en-GB", { month: "long" });
|
|
195
|
+
const year = date.getFullYear();
|
|
196
|
+
return `${day} ${month}, ${year}`;
|
|
197
|
+
};
|
|
198
|
+
|
|
199
|
+
const emptyStateStyle = useMemo(
|
|
200
|
+
() =>
|
|
201
|
+
StyleSheet.create({
|
|
202
|
+
root: {
|
|
203
|
+
flex: 1,
|
|
204
|
+
justifyContent: "center",
|
|
205
|
+
paddingBottom: (insets?.bottom ?? 0) + TAB_LIKE_OFFSET,
|
|
206
|
+
},
|
|
207
|
+
}).root,
|
|
208
|
+
[insets?.bottom]
|
|
209
|
+
);
|
|
210
|
+
|
|
211
|
+
// Show loader only when loading and no error
|
|
212
|
+
const showLoader = !myOrdersValidateOtpError && myOrdersValidateOtpLoading;
|
|
213
|
+
const hasData = displayData.length > 0;
|
|
214
|
+
|
|
215
|
+
// Debug logging
|
|
216
|
+
console.log('📋 RedemptionHistory RENDER:', {
|
|
217
|
+
showLoader,
|
|
218
|
+
hasData,
|
|
219
|
+
displayDataLength: displayData.length,
|
|
220
|
+
myOrdersValidateOtpLoading,
|
|
221
|
+
myOrdersValidateOtpError: !!myOrdersValidateOtpError,
|
|
222
|
+
firstItem: displayData[0] ? { id: displayData[0].id, order_no: displayData[0].order_no } : null,
|
|
223
|
+
});
|
|
224
|
+
|
|
225
|
+
return (
|
|
226
|
+
<View style={styles.container}>
|
|
227
|
+
{/* Debug indicator - remove after testing */}
|
|
228
|
+
|
|
229
|
+
<MobileHeader
|
|
230
|
+
title={RedemptionHistoryTitle}
|
|
231
|
+
showBack
|
|
232
|
+
onBack={() => handleGoBack()}
|
|
233
|
+
disableSafeAreaPadding={true}
|
|
234
|
+
/>
|
|
235
|
+
|
|
236
|
+
<OTPModal
|
|
237
|
+
visible={otpModalVisible}
|
|
238
|
+
onClose={() => {
|
|
239
|
+
setOtpModalVisible(false);
|
|
240
|
+
dispatch(resetAuthState("myOrdersGenerateOtpError" as any));
|
|
241
|
+
dispatch(resetAuthState("myOrdersValidateOtpError" as any));
|
|
242
|
+
dispatch(resetAuthState("myOrdersValidateOtpSuccessMessage" as any));
|
|
243
|
+
// If user closes OTP modal without verifying, go back
|
|
244
|
+
if (!myOrdersValidateOtpData?.length) {
|
|
245
|
+
handleGoBack();
|
|
246
|
+
}
|
|
247
|
+
}}
|
|
248
|
+
onVerify={(otp) => {
|
|
249
|
+
handleVerify(otp);
|
|
250
|
+
setResetOtpTrigger((prev) => prev + 1);
|
|
251
|
+
}}
|
|
252
|
+
onResend={() => dispatch(myOrdersGenerateOtpRequest({}))}
|
|
253
|
+
onNavigateToOrders={() => {}}
|
|
254
|
+
resetOtpTrigger={resetOtpTrigger}
|
|
255
|
+
otpLength={4}
|
|
256
|
+
screen={ROUTES.REDEMPTION_HISTORY}
|
|
257
|
+
/>
|
|
258
|
+
|
|
259
|
+
{showLoader ? (
|
|
260
|
+
<CustomLoader loading />
|
|
261
|
+
) : hasData ? (
|
|
262
|
+
<ScrollView
|
|
263
|
+
style={styles.scrollView}
|
|
264
|
+
showsVerticalScrollIndicator={false}
|
|
265
|
+
>
|
|
266
|
+
<View style={styles.content}>
|
|
267
|
+
{displayData.map((item, index) => {
|
|
268
|
+
console.log('📋 RedemptionHistory item:', index, item?.order_no, item?.total_points);
|
|
269
|
+
return (
|
|
270
|
+
<View key={index}>
|
|
271
|
+
<View style={styles.redemptionItem}>
|
|
272
|
+
<View style={styles.itemDetails}>
|
|
273
|
+
<Text style={styles.itemTitle}>{PointsRedeemed}</Text>
|
|
274
|
+
<Text style={styles.itemOrderNo}>
|
|
275
|
+
{OrderNo} {item?.order_no}
|
|
276
|
+
</Text>
|
|
277
|
+
<Text style={styles.itemDate}>
|
|
278
|
+
{formatDate(item?.created_at || item?.date)}
|
|
279
|
+
</Text>
|
|
280
|
+
</View>
|
|
281
|
+
<View style={styles.itemPoints}>
|
|
282
|
+
<CustomImage
|
|
283
|
+
source={Images.arrowred}
|
|
284
|
+
imgStyle={styles.arrowIcon}
|
|
285
|
+
/>
|
|
286
|
+
<Text style={styles.pointsValue}>{(item?.amount_cents || 0) / 100}</Text>
|
|
287
|
+
</View>
|
|
288
|
+
</View>
|
|
289
|
+
{index < displayData.length - 1 && (
|
|
290
|
+
<View style={styles.separator} />
|
|
291
|
+
)}
|
|
292
|
+
</View>
|
|
293
|
+
)})}
|
|
294
|
+
</View>
|
|
295
|
+
</ScrollView>
|
|
296
|
+
) : (
|
|
297
|
+
<NoDataFound containerstyle={emptyStateStyle} />
|
|
298
|
+
)}
|
|
299
|
+
|
|
300
|
+
</View>
|
|
301
|
+
);
|
|
302
|
+
};
|
|
303
|
+
|
|
304
|
+
export default RedemptionHistory;
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { StyleSheet } from 'react-native';
|
|
2
|
+
|
|
3
|
+
import FontFamily from '../../../src-app/constants/Fonts';
|
|
4
|
+
import { colors } from '../../../src-app/styles/colors';
|
|
5
|
+
|
|
6
|
+
const styles = StyleSheet.create({
|
|
7
|
+
container: {
|
|
8
|
+
flex: 1,
|
|
9
|
+
backgroundColor: colors.background,
|
|
10
|
+
},
|
|
11
|
+
scrollView: {
|
|
12
|
+
flex: 1,
|
|
13
|
+
},
|
|
14
|
+
content: {
|
|
15
|
+
padding: 20,
|
|
16
|
+
// paddingTop: 20,
|
|
17
|
+
// paddingBottom: 100, // Space for tab bar
|
|
18
|
+
},
|
|
19
|
+
redemptionItem: {
|
|
20
|
+
flexDirection: 'row',
|
|
21
|
+
justifyContent: 'space-between',
|
|
22
|
+
alignItems: 'flex-start',
|
|
23
|
+
paddingVertical: 0,
|
|
24
|
+
},
|
|
25
|
+
itemDetails: {
|
|
26
|
+
width: 193,
|
|
27
|
+
gap: 8,
|
|
28
|
+
},
|
|
29
|
+
itemTitle: {
|
|
30
|
+
fontFamily: FontFamily.LEXEND_REGULAR,
|
|
31
|
+
fontSize: 12,
|
|
32
|
+
fontWeight: '600',
|
|
33
|
+
lineHeight: 18,
|
|
34
|
+
color: '#1F2937',
|
|
35
|
+
textTransform: 'capitalize',
|
|
36
|
+
},
|
|
37
|
+
itemOrderNo: {
|
|
38
|
+
fontFamily: FontFamily.LEXEND_REGULAR,
|
|
39
|
+
fontSize: 12,
|
|
40
|
+
fontWeight: '500',
|
|
41
|
+
lineHeight: 18,
|
|
42
|
+
color: '#6B7280',
|
|
43
|
+
textTransform: 'capitalize',
|
|
44
|
+
},
|
|
45
|
+
itemDate: {
|
|
46
|
+
fontFamily: FontFamily.LEXEND_REGULAR,
|
|
47
|
+
fontSize: 10,
|
|
48
|
+
fontWeight: '400',
|
|
49
|
+
color: '#6B7280',
|
|
50
|
+
textTransform: 'capitalize',
|
|
51
|
+
},
|
|
52
|
+
itemPoints: {
|
|
53
|
+
flexDirection: 'row',
|
|
54
|
+
alignItems: 'center',
|
|
55
|
+
gap: 8,
|
|
56
|
+
},
|
|
57
|
+
pointsValue: {
|
|
58
|
+
fontFamily: FontFamily.LEXEND_REGULAR,
|
|
59
|
+
fontSize: 16,
|
|
60
|
+
fontWeight: '600',
|
|
61
|
+
color: '#1F2937',
|
|
62
|
+
textAlign: 'right',
|
|
63
|
+
textTransform: 'capitalize',
|
|
64
|
+
},
|
|
65
|
+
separator: {
|
|
66
|
+
width: '100%',
|
|
67
|
+
height: 1.2,
|
|
68
|
+
backgroundColor: 'rgba(209, 213, 219, 0.45)',
|
|
69
|
+
marginVertical: 20,
|
|
70
|
+
},
|
|
71
|
+
arrowIcon: {
|
|
72
|
+
height: 10,
|
|
73
|
+
width: 8,
|
|
74
|
+
resizeMode: 'contain',
|
|
75
|
+
},
|
|
76
|
+
emptyText: {
|
|
77
|
+
textAlign: 'center',
|
|
78
|
+
marginTop: 20,
|
|
79
|
+
fontSize: 16,
|
|
80
|
+
color: 'black',
|
|
81
|
+
},
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
export default styles;
|