TP-83691 | Benefit Screen Final (#12582)
Co-authored-by: Kshitij Pramod Ghongadi <kshitij.pramod@navi.com>
This commit is contained in:
@@ -34,4 +34,7 @@ export const commonStyles = StyleSheet.create({
|
||||
height54: {
|
||||
height: 54,
|
||||
},
|
||||
flexStart: {
|
||||
alignItems: "flex-start",
|
||||
},
|
||||
});
|
||||
|
||||
@@ -5,3 +5,4 @@ export { default as MarketBenefitCompareScreen } from "./screen/market-benefit-c
|
||||
export { default as WaitingPeriodScreen } from "./screen/waiting-period-screen/WaitingPeriodScreen";
|
||||
export { default as GenericShimmerScreen } from "./screen/generic-shimmer-screen/GenericShimmerScreen";
|
||||
export { default as GenericErrorScreen } from "./screen/generic-error-screen/GenericErrorScreen";
|
||||
export { default as BenefitScreen } from "./screen/benefit-screen/BenefitScreen";
|
||||
|
||||
40
App/Container/Navi-Insurance/network/BenefitPageApi.ts
Normal file
40
App/Container/Navi-Insurance/network/BenefitPageApi.ts
Normal file
@@ -0,0 +1,40 @@
|
||||
import { Dispatch, SetStateAction } from "react";
|
||||
import { getXTargetHeaderInfo } from "../../../../network/ApiClient";
|
||||
import { get } from "../../../../network/NetworkService";
|
||||
import { ActionMetaData } from "../../../common/actions/GenericAction";
|
||||
import {
|
||||
AnalyticsFlowNameConstant,
|
||||
AnalyticsMethodNameConstant,
|
||||
GI,
|
||||
} from "../../../common/constants";
|
||||
import { CtaData } from "../../../common/interface";
|
||||
import { ScreenData } from "../../../common/interface/widgets/screenData/ScreenData";
|
||||
import {
|
||||
handleErrorData,
|
||||
handleResponseData,
|
||||
} from "../../../common/screen/ScreenActionHandler";
|
||||
import { ScreenActionTypes } from "../../../common/screen/ScreenActionTypes";
|
||||
|
||||
export const getBenefitPageData = async (
|
||||
screenMetaData: ActionMetaData,
|
||||
setScreenData: Dispatch<SetStateAction<ScreenData | null>>,
|
||||
) => {
|
||||
const url = "benefits/v2";
|
||||
return get<ApiResponse<CtaData>>(
|
||||
url,
|
||||
getXTargetHeaderInfo(GI.toLocaleUpperCase()),
|
||||
screenMetaData.data,
|
||||
)
|
||||
.then(response => {
|
||||
handleResponseData(setScreenData, response);
|
||||
})
|
||||
.catch(error => {
|
||||
handleErrorData(
|
||||
error,
|
||||
setScreenData,
|
||||
screenMetaData,
|
||||
AnalyticsFlowNameConstant.GI_RN_BENEFIT,
|
||||
AnalyticsMethodNameConstant.FETCH_BENEFIT_LIST,
|
||||
);
|
||||
});
|
||||
};
|
||||
@@ -1,3 +1,4 @@
|
||||
export * from "./WaitingPeriodApi";
|
||||
export * from "./QuotePageApi";
|
||||
export * from "./BenefitPageApi";
|
||||
export * from "./MarketBenefitComparePageApi";
|
||||
export * from "./QuotePageApi";
|
||||
export * from "./WaitingPeriodApi";
|
||||
|
||||
@@ -0,0 +1,261 @@
|
||||
import { useNavigation } from "@react-navigation/native";
|
||||
import { useEffect } from "react";
|
||||
import { NativeScrollEvent, NativeSyntheticEvent, View } from "react-native";
|
||||
import Animated, {
|
||||
useAnimatedStyle,
|
||||
useDerivedValue,
|
||||
useSharedValue,
|
||||
withTiming,
|
||||
} from "react-native-reanimated";
|
||||
import { StyledImage, StyledText } from "../../../../../components/widgets";
|
||||
import BaseWidget from "../../../../../components/widgets/BaseWidget";
|
||||
import {
|
||||
BaseActionTypes,
|
||||
GenericActionPayload,
|
||||
} from "../../../../common/actions/GenericAction";
|
||||
import {
|
||||
AnalyticsEventNameConstants,
|
||||
AnalyticsMethodNameConstant,
|
||||
BENEFIT_SCREEN,
|
||||
ConstantCta,
|
||||
INITIAL_Y_VALUE,
|
||||
NAVIGATION_ERROR,
|
||||
} from "../../../../common/constants";
|
||||
import { sendAsAnalyticsEvent } from "../../../../common/hooks/useAnalyticsEvent";
|
||||
import { NaviLinearGradient } from "../../../../common/hooks/useGradient";
|
||||
import { AnalyticsEvent, CtaData, CtaType } from "../../../../common/interface";
|
||||
import { Widget } from "../../../../common/interface/widgets/Widget";
|
||||
import { BenefitScreenHeaderData } from "../../../../common/interface/widgets/widgetData";
|
||||
import { BenefitScreenProps } from "../../../../common/interface/widgets/widgetData/BenefitScreenHeaderData";
|
||||
import { NativeDeeplinkNavigatorModule } from "../../../../common/native-module/NativeModules";
|
||||
import { CtaNavigator } from "../../../../common/navigator/NavigationRouter";
|
||||
import { ScreenState } from "../../../../common/screen/BaseScreen";
|
||||
import { ScreenActionTypes } from "../../../../common/screen/ScreenActionTypes";
|
||||
import { extractCtaParameters } from "../../../../common/utilities/CtaParamsUtils";
|
||||
import { handleGoBackOrExitApp } from "../../../../common/utilities/NavigationUtil";
|
||||
import GenericShimmerScreen from "../generic-shimmer-screen/GenericShimmerScreen";
|
||||
import QuoteOfferErrorScreen from "../quote-offer-screen/error-screen/QuoteOfferErrorScreen";
|
||||
import styles from "./BenefitScreenStyles";
|
||||
|
||||
const BenefitScreen = ({
|
||||
ctaData,
|
||||
screenData,
|
||||
handleActions,
|
||||
}: BenefitScreenProps) => {
|
||||
const navigation = useNavigation();
|
||||
const y = useSharedValue(INITIAL_Y_VALUE);
|
||||
const onScroll = (event: NativeSyntheticEvent<NativeScrollEvent>) => {
|
||||
y.value = event.nativeEvent.contentOffset.y;
|
||||
};
|
||||
const derivedY = useDerivedValue(() => {
|
||||
return y.value;
|
||||
});
|
||||
|
||||
const handleClick = (cta?: CtaData) => {
|
||||
if (!cta) {
|
||||
const errorEvent: AnalyticsEvent = {
|
||||
name: AnalyticsEventNameConstants.HI_INVALID_SCREEN_CTA,
|
||||
properties: {
|
||||
screenName: BENEFIT_SCREEN,
|
||||
methodName: AnalyticsMethodNameConstant.HANDLE_CTA_CLICK,
|
||||
},
|
||||
};
|
||||
sendAsAnalyticsEvent(errorEvent);
|
||||
return;
|
||||
}
|
||||
const { navigatorType } = extractCtaParameters(cta);
|
||||
try {
|
||||
switch (cta.type) {
|
||||
case CtaType.DEEP_LINK:
|
||||
case CtaType.USE_ROOT_DEEPLINK_NAVIGATOR:
|
||||
NativeDeeplinkNavigatorModule.navigateToNaviInsuranceDeeplinkNavigator(
|
||||
JSON.stringify(cta),
|
||||
);
|
||||
break;
|
||||
case CtaType.RN_NAVIGATOR:
|
||||
CtaNavigator.performNavigation(navigation, navigatorType, cta);
|
||||
break;
|
||||
case CtaType.GO_BACK:
|
||||
handleGoBackOrExitApp(navigation);
|
||||
break;
|
||||
default:
|
||||
NativeDeeplinkNavigatorModule.navigateToNaviDeeplinkNavigator(
|
||||
JSON.stringify(cta),
|
||||
);
|
||||
break;
|
||||
}
|
||||
} catch (error) {
|
||||
const errorEvent: AnalyticsEvent = {
|
||||
name: AnalyticsEventNameConstants.HI_INVALID_SCREEN_CTA,
|
||||
properties: {
|
||||
screenName: BENEFIT_SCREEN,
|
||||
methodName: AnalyticsMethodNameConstant.HANDLE_CTA_CLICK,
|
||||
reason: error?.toString() || NAVIGATION_ERROR,
|
||||
},
|
||||
};
|
||||
sendAsAnalyticsEvent(errorEvent);
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
const { planId, benefitType, sourceScreen } = extractCtaParameters(ctaData);
|
||||
|
||||
const data: BenefitScreenRequest = {
|
||||
planId: planId,
|
||||
benefitType: benefitType,
|
||||
sourceScreen: sourceScreen,
|
||||
};
|
||||
|
||||
handleActions({
|
||||
baseActionType: BaseActionTypes.SCREEN_ACTION,
|
||||
metaData: [
|
||||
{
|
||||
actionType: ScreenActionTypes.FETCH_BENEFIT_LIST,
|
||||
data,
|
||||
screenName: BENEFIT_SCREEN,
|
||||
},
|
||||
],
|
||||
});
|
||||
}, [ctaData]);
|
||||
|
||||
const headerStyle = useAnimatedStyle(() => {
|
||||
return {
|
||||
maxHeight: withTiming(derivedY.value > 0 ? 0 : 200, {
|
||||
duration: derivedY.value > 0 ? 150 : 200,
|
||||
}),
|
||||
// Updating maxHeight to 0 when derivedY.value > 0 to hide the header icon
|
||||
// and updating to 200 [> icon height] when derivedY.value <= 0 to show the header icon
|
||||
opacity: withTiming(derivedY.value > 0 ? 0 : 1, {
|
||||
duration: derivedY.value > 0 ? 10 : 250,
|
||||
}),
|
||||
};
|
||||
});
|
||||
|
||||
const Header = () => {
|
||||
let headerData = screenData?.screenWidgets?.headerWidgets?.at(
|
||||
0,
|
||||
) as BenefitScreenHeaderData;
|
||||
return (
|
||||
<NaviLinearGradient
|
||||
gradientColors={
|
||||
derivedY.value > 0
|
||||
? headerData?.scrolledGradient
|
||||
: headerData?.defaultGradient
|
||||
}
|
||||
>
|
||||
<Animated.View style={styles.header}>
|
||||
<View style={styles.headerContainer}>
|
||||
<View style={styles.headerContainerTopBar}>
|
||||
{headerData?.leftIcon && (
|
||||
<StyledImage
|
||||
imageFieldData={headerData?.leftIcon}
|
||||
handleClick={handleClick}
|
||||
/>
|
||||
)}
|
||||
{headerData?.title && (
|
||||
<StyledText textFieldData={headerData?.title} />
|
||||
)}
|
||||
{headerData?.rightIcon ? (
|
||||
<StyledImage imageFieldData={headerData?.rightIcon} />
|
||||
) : (
|
||||
<View style={styles.placeholderImage} />
|
||||
)}
|
||||
</View>
|
||||
{headerData?.subtitle && (
|
||||
<StyledText textFieldData={headerData?.subtitle} />
|
||||
)}
|
||||
{<View style={styles.spacer} />}
|
||||
{headerData?.description?.url && (
|
||||
<Animated.View
|
||||
style={[styles.headerContainerBottomBar, headerStyle]}
|
||||
>
|
||||
<StyledImage imageFieldData={headerData?.description} />
|
||||
</Animated.View>
|
||||
)}
|
||||
</View>
|
||||
</Animated.View>
|
||||
</NaviLinearGradient>
|
||||
);
|
||||
};
|
||||
|
||||
const Footer = () => {
|
||||
return (
|
||||
<View style={styles.footer}>
|
||||
{getWidgetViews(
|
||||
screenData?.screenWidgets?.footerWidgets,
|
||||
handleActions,
|
||||
screenData?.screenState,
|
||||
handleClick,
|
||||
)}
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
if (screenData?.screenState === ScreenState.LOADING) {
|
||||
return <GenericShimmerScreen handleClick={handleClick} />;
|
||||
}
|
||||
|
||||
if (screenData?.screenState === ScreenState.ERROR) {
|
||||
return (
|
||||
<QuoteOfferErrorScreen
|
||||
errorMetaData={screenData.errorMetaData}
|
||||
handleActions={handleActions}
|
||||
handleClick={handleClick}
|
||||
headerProperties={{
|
||||
leftIconCta: ConstantCta.GO_BACK_CTA,
|
||||
leftIcon: "BACK_ARROW",
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<View style={[styles.container, screenData?.screenStyle]}>
|
||||
<Animated.ScrollView
|
||||
showsVerticalScrollIndicator={false}
|
||||
contentContainerStyle={styles.content}
|
||||
nestedScrollEnabled={true}
|
||||
bounces={false}
|
||||
scrollEnabled={true}
|
||||
onScroll={onScroll}
|
||||
stickyHeaderIndices={[0]}
|
||||
overScrollMode={"never"}
|
||||
>
|
||||
<Header />
|
||||
{getWidgetViews(
|
||||
screenData?.screenWidgets?.contentWidgets,
|
||||
handleActions,
|
||||
screenData?.screenState,
|
||||
handleClick,
|
||||
)}
|
||||
</Animated.ScrollView>
|
||||
<Footer />
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
function getWidgetViews(
|
||||
widgetList: Widget[] | undefined,
|
||||
handleActions: (screenActionPayload?: GenericActionPayload) => void,
|
||||
screenState?: ScreenState | null,
|
||||
handleClick?: (ctaData: CtaData) => void,
|
||||
): React.JSX.Element {
|
||||
return (
|
||||
<View>
|
||||
{widgetList?.map((widget, index) => {
|
||||
return (
|
||||
<BaseWidget
|
||||
widget={widget}
|
||||
handleScreenActions={handleActions}
|
||||
screenState={screenState}
|
||||
widgetIndex={index}
|
||||
key={index}
|
||||
handleClick={handleClick}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
export default BenefitScreen;
|
||||
@@ -0,0 +1,52 @@
|
||||
import { StyleSheet } from "react-native";
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
flexDirection: "column",
|
||||
backgroundColor: "#FFFFFF",
|
||||
},
|
||||
header: {
|
||||
width: "100%",
|
||||
alignItems: "stretch",
|
||||
zIndex: 1,
|
||||
},
|
||||
content: {
|
||||
flexGrow: 1,
|
||||
backgroundColor: "#FFFFFF",
|
||||
},
|
||||
footer: {
|
||||
alignItems: "stretch",
|
||||
},
|
||||
headerContainer: {
|
||||
flexDirection: "column",
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
},
|
||||
headerContainerTopBar: {
|
||||
flexDirection: "row",
|
||||
justifyContent: "space-between",
|
||||
alignItems: "center",
|
||||
width: "100%",
|
||||
paddingHorizontal: 16,
|
||||
paddingTop: 16,
|
||||
paddingBottom: 8,
|
||||
},
|
||||
headerButton: {
|
||||
backgroundColor: "#274688",
|
||||
borderRadius: 16,
|
||||
paddingVertical: 8,
|
||||
paddingHorizontal: 16,
|
||||
},
|
||||
headerContainerBottomBar: {
|
||||
flexDirection: "column",
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
},
|
||||
spacer: {
|
||||
height: 24,
|
||||
},
|
||||
placeholderImage: { height: 24, width: 24 },
|
||||
});
|
||||
|
||||
export default styles;
|
||||
@@ -1,6 +1,6 @@
|
||||
import { useNavigation } from "@react-navigation/native";
|
||||
import React, { useEffect } from "react";
|
||||
import { BackHandler, ScrollView, View } from "react-native";
|
||||
import { ScrollView, View } from "react-native";
|
||||
import BaseWidget from "../../../../../components/widgets/BaseWidget";
|
||||
import {
|
||||
BaseActionTypes,
|
||||
@@ -15,6 +15,7 @@ import { NativeDeeplinkNavigatorModule } from "../../../../common/native-module/
|
||||
import { CtaNavigator } from "../../../../common/navigator/NavigationRouter";
|
||||
import { ScreenState } from "../../../../common/screen/BaseScreen";
|
||||
import { ScreenActionTypes } from "../../../../common/screen/ScreenActionTypes";
|
||||
import { handleGoBackOrExitApp } from "../../../../common/utilities/NavigationUtil";
|
||||
import { extractCtaParameters } from "../../../../common/utilities/CtaParamsUtils";
|
||||
import QuoteOfferErrorScreen from "../quote-offer-screen/error-screen/QuoteOfferErrorScreen";
|
||||
import ComparePlanShimmerScreen from "./shimmer-screen/ComparePlanShimmerScreen";
|
||||
@@ -51,11 +52,7 @@ const ComparePlanScreen = ({
|
||||
CtaNavigator.performNavigation(navigation, navigatorType, cta);
|
||||
break;
|
||||
case CtaType.GO_BACK:
|
||||
if (navigation.canGoBack()) {
|
||||
navigation.goBack();
|
||||
} else {
|
||||
BackHandler.exitApp();
|
||||
}
|
||||
handleGoBackOrExitApp(navigation);
|
||||
break;
|
||||
default:
|
||||
NativeDeeplinkNavigatorModule.navigateToNaviDeeplinkNavigator(
|
||||
|
||||
@@ -1,11 +1,6 @@
|
||||
import { useNavigation } from "@react-navigation/native";
|
||||
import React, { useEffect } from "react";
|
||||
import {
|
||||
BackHandler,
|
||||
NativeScrollEvent,
|
||||
NativeSyntheticEvent,
|
||||
View,
|
||||
} from "react-native";
|
||||
import { NativeScrollEvent, NativeSyntheticEvent, View } from "react-native";
|
||||
import Animated, {
|
||||
useAnimatedStyle,
|
||||
useSharedValue,
|
||||
@@ -30,6 +25,7 @@ import { CtaNavigator } from "../../../../common/navigator/NavigationRouter";
|
||||
import { ScreenState } from "../../../../common/screen/BaseScreen";
|
||||
import { ScreenActionTypes } from "../../../../common/screen/ScreenActionTypes";
|
||||
import { extractCtaParameters } from "../../../../common/utilities/CtaParamsUtils";
|
||||
import { handleGoBackOrExitApp } from "../../../../common/utilities/NavigationUtil";
|
||||
import GenericShimmerScreen from "../generic-shimmer-screen/GenericShimmerScreen";
|
||||
import QuoteOfferErrorScreen from "../quote-offer-screen/error-screen/QuoteOfferErrorScreen";
|
||||
import styles from "./MarketBenefitCompareScreenStyles";
|
||||
@@ -69,11 +65,7 @@ const MarketBenefitCompareScreen = ({
|
||||
CtaNavigator.performNavigation(navigation, navigatorType, cta);
|
||||
break;
|
||||
case CtaType.GO_BACK:
|
||||
if (navigation.canGoBack()) {
|
||||
navigation.goBack();
|
||||
} else {
|
||||
BackHandler.exitApp();
|
||||
}
|
||||
handleGoBackOrExitApp(navigation);
|
||||
break;
|
||||
default:
|
||||
NativeDeeplinkNavigatorModule.navigateToNaviDeeplinkNavigator(
|
||||
|
||||
@@ -49,6 +49,7 @@ import { handleGoBackOrExitApp } from "../../../../common/utilities/NavigationUt
|
||||
import styles from "./QuoteOfferScreenStyle";
|
||||
import QuoteOfferErrorScreen from "./error-screen/QuoteOfferErrorScreen";
|
||||
import QuoteOfferShimmerScreen from "./shimmer-screen/QuoteOfferShimmerScreen";
|
||||
|
||||
const QuoteOfferScreen = ({
|
||||
ctaData,
|
||||
screenData,
|
||||
|
||||
Reference in New Issue
Block a user