TP-83691 | Benefit Screen Final (#12582)

Co-authored-by: Kshitij Pramod Ghongadi <kshitij.pramod@navi.com>
This commit is contained in:
Prajjaval Verma
2024-10-09 14:46:26 +05:30
committed by GitHub
parent 4b26ce643b
commit 4db9ca09cd
43 changed files with 972 additions and 52 deletions

View File

@@ -34,4 +34,7 @@ export const commonStyles = StyleSheet.create({
height54: {
height: 54,
},
flexStart: {
alignItems: "flex-start",
},
});

View File

@@ -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";

View 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,
);
});
};

View File

@@ -1,3 +1,4 @@
export * from "./WaitingPeriodApi";
export * from "./QuotePageApi";
export * from "./BenefitPageApi";
export * from "./MarketBenefitComparePageApi";
export * from "./QuotePageApi";
export * from "./WaitingPeriodApi";

View File

@@ -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;

View File

@@ -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;

View File

@@ -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(

View File

@@ -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(

View File

@@ -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,