Files
super-app/App/Container/Navi-Insurance/screen/quote-offer-screen/QuoteOfferScreen.tsx
2024-12-11 05:47:17 +00:00

336 lines
10 KiB
TypeScript

import { useNavigation } from "@react-navigation/native";
import throttle from "lodash/throttle";
import React, { useCallback, useEffect } from "react";
import {
EmitterSubscription,
NativeEventEmitter,
NativeModules,
NativeScrollEvent,
NativeSyntheticEvent,
Platform,
View,
} from "react-native";
import Animated, {
useAnimatedStyle,
useDerivedValue,
useSharedValue,
withTiming,
} from "react-native-reanimated";
import Colors from "../../../../../assets/colors/colors";
import BaseWidget from "../../../../../components/widgets/BaseWidget";
import FAB from "../../../../../components/widgets/fab/FAB";
import {
BaseActionTypes,
GenericActionPayload,
} from "../../../../common/actions/GenericAction";
import {
ADVERSE,
AnalyticsEventNameConstants,
AnalyticsFlowNameConstant,
ConstantCta,
FabTextStyleProperties,
HEADER_LOTTIE_TITLE_HEIGHT,
HEADER_LOTTIE_WIDGET_HEIGHT,
HOME,
INITIAL_Y_VALUE,
NativeEventNameConstants,
OsTypeConstants,
QUOTE_OFFER_SCREEN,
} from "../../../../common/constants";
import { sendAsAnalyticsEvent } from "../../../../common/hooks/useAnalyticsEvent";
import { AnalyticsEvent, CtaData, CtaType } from "../../../../common/interface";
import { Widget } from "../../../../common/interface/widgets/Widget";
import { ScreenData } from "../../../../common/interface/widgets/screenData/ScreenData";
import { FabWidgetData } from "../../../../common/interface/widgets/widgetData/FabWidgetData";
import { ScreenState } from "../../../../common/screen/BaseScreen";
import { ScreenActionTypes } from "../../../../common/screen/ScreenActionTypes";
import { extractCtaParameters } from "../../../../common/utilities/CtaParamsUtils";
import { globalHandleClick } from "../../../../common/utilities/NavigationUtil";
import { extractScreenProperties } from "../../../../common/utilities/ScreenPropertiesUtils";
import { commonHeaderShadowStyle } from "../../Styles";
import styles from "./QuoteOfferScreenStyle";
import QuoteOfferErrorScreen from "./error-screen/QuoteOfferErrorScreen";
import QuoteOfferShimmerScreen from "./shimmer-screen/QuoteOfferShimmerScreen";
const QuoteOfferScreen = ({
ctaData,
screenData,
handleActions,
}: {
ctaData: CtaData;
screenData: ScreenData | null;
handleActions: (screenPayload?: GenericActionPayload) => void;
}) => {
const y = useSharedValue(0);
const lastScrollPosition = useSharedValue(0);
const navigation = useNavigation();
const nativeEventListener =
Platform.OS === OsTypeConstants.ANDROID
? new NativeEventEmitter()
: new NativeEventEmitter(NativeModules.DeviceEventEmitterModule);
const derivedY = useDerivedValue(() => y.value);
let reloadPageEventListener = {} as EmitterSubscription;
const animationConfig = {
duration: FabTextStyleProperties.ANIMATION_DURATION,
};
const headerShadowStyle = commonHeaderShadowStyle(derivedY);
const onScroll = (event: NativeSyntheticEvent<NativeScrollEvent>) => {
lastScrollPosition.value = y.value;
y.value = event.nativeEvent.contentOffset.y;
};
const fabTextStyle = useAnimatedStyle(() => {
const isAtTop = derivedY.value <= INITIAL_Y_VALUE;
return {
maxWidth: withTiming(
isAtTop
? FabTextStyleProperties.INITIAL_MAX_WIDTH
: FabTextStyleProperties.COLLAPSED_MAX_WIDTH,
animationConfig,
),
paddingRight: withTiming(
isAtTop
? FabTextStyleProperties.INITIAL_PADDING_RIGHT
: FabTextStyleProperties.COLLAPSED_PADDING_RIGHT,
animationConfig,
),
opacity: withTiming(
isAtTop
? FabTextStyleProperties.INITIAL_OPACITY
: FabTextStyleProperties.COLLAPSED_OPACITY,
animationConfig,
),
};
});
const { animateHeader, showHeaderShadow } = extractScreenProperties(
screenData?.screenMetaData?.screenProperties,
);
const headerBgStyle = useAnimatedStyle(() => {
if (!animateHeader) return { backgroundColor: Colors.white };
return {
backgroundColor:
derivedY.value > HEADER_LOTTIE_WIDGET_HEIGHT
? Colors.grey
: derivedY.value > HEADER_LOTTIE_TITLE_HEIGHT
? Colors.aliceBlue
: Colors.transparent,
};
});
const { applicationId, preQuoteId, quoteId, source } =
extractCtaParameters(ctaData);
const handleClick = (cta?: CtaData) => {
if (!!cta && cta.url === HOME && source === ADVERSE) {
cta.type = CtaType.GO_BACK;
}
globalHandleClick(navigation, cta, QUOTE_OFFER_SCREEN);
};
const throttledHandleClick = useCallback(
throttle(handleClick, 700, {
leading: true,
trailing: false,
}),
[],
);
useEffect(() => {
const screenActionType = preQuoteId
? ScreenActionTypes.FETCH_QUOTE_V4
: ScreenActionTypes.FETCH_INSURANCE_QUOTE_PAGE_FROM_BACKEND;
const data: QuoteOfferRequest = {
preQuoteId: preQuoteId,
quoteId: quoteId,
applicationId: applicationId,
};
handleActions({
baseActionType: BaseActionTypes.SCREEN_ACTION,
metaData: [
{
actionType: screenActionType,
data: data,
screenName: QUOTE_OFFER_SCREEN,
},
],
});
return () => {};
}, [ctaData, preQuoteId, quoteId]);
useEffect(() => {
reloadPageEventListener = nativeEventListener.addListener(
NativeEventNameConstants.reloadPage,
event => {
if (event === true) {
const screenActionType = preQuoteId
? ScreenActionTypes.FETCH_QUOTE_V4
: ScreenActionTypes.FETCH_INSURANCE_QUOTE_PAGE_FROM_BACKEND;
const data: QuoteOfferRequest = {
preQuoteId: preQuoteId ? preQuoteId : undefined,
quoteId: quoteId ? quoteId : undefined,
applicationId: applicationId ? applicationId : undefined,
};
handleActions({
baseActionType: BaseActionTypes.SCREEN_ACTION,
metaData: [
{
actionType: screenActionType,
data: data,
screenName: QUOTE_OFFER_SCREEN,
},
],
});
}
},
);
return () => {
reloadPageEventListener.remove();
nativeEventListener.removeAllListeners(
NativeEventNameConstants.reloadPage,
);
};
}, [reloadPageEventListener]);
useEffect(() => {
switch (screenData?.screenState) {
case ScreenState.LOADED:
const initEvent: AnalyticsEvent = {
name: AnalyticsEventNameConstants.HI_RN_QUOTE_PAGE_INIT,
properties: {
screen: AnalyticsFlowNameConstant.GI_RN_QUOTE,
},
};
sendAsAnalyticsEvent(initEvent);
break;
case ScreenState.ERROR:
const errorEvent: AnalyticsEvent = {
name: AnalyticsEventNameConstants.HI_RN_QUOTE_PAGE_ERROR_VIEW,
properties: {
screen: AnalyticsFlowNameConstant.GI_RN_QUOTE,
},
};
sendAsAnalyticsEvent(errorEvent);
break;
default:
break;
}
}, [screenData?.screenState]);
useEffect(() => {
if (
screenData?.screenState !== ScreenState.ERROR &&
screenData?.screenState !== ScreenState.LOADING
) {
screenData?.screenMetaData?.redirectionCta &&
handleClick(screenData?.screenMetaData?.redirectionCta);
}
}, [screenData?.screenMetaData?.redirectionCta]);
if (screenData?.screenState === ScreenState.LOADING) {
return <QuoteOfferShimmerScreen handleClick={handleClick} />;
}
if (screenData?.screenState === ScreenState.ERROR) {
return (
<QuoteOfferErrorScreen
errorMetaData={screenData.errorMetaData}
handleActions={handleActions}
handleClick={handleClick}
headerProperties={{
leftIconCta: ConstantCta.STATIC_HEADER_LEFT_ICON_CTA,
rightIconCta: ConstantCta.STATIC_HEADER_RIGHT_ICON_CTA,
}}
/>
);
}
const getPointerEvents = () =>
screenData?.screenState === ScreenState.OVERLAY ? "none" : "auto";
return (
<View style={[styles.container, screenData?.screenStyle]}>
<Animated.View
style={[
styles.header,
showHeaderShadow
? [headerShadowStyle, styles.headerBackgroundColor]
: headerBgStyle,
]}
>
{getWidgetViews(
screenData?.screenWidgets?.headerWidgets,
handleActions,
screenData?.screenState,
throttledHandleClick,
)}
</Animated.View>
<Animated.ScrollView
showsVerticalScrollIndicator={false}
contentContainerStyle={styles.content}
scrollEventThrottle={16}
onScroll={onScroll}
nestedScrollEnabled={true}
pointerEvents={getPointerEvents()}
overScrollMode={"never"}
>
<View pointerEvents={getPointerEvents()}>
{getWidgetViews(
screenData?.screenWidgets?.contentWidgets,
handleActions,
screenData?.screenState,
throttledHandleClick,
)}
</View>
</Animated.ScrollView>
<View style={styles.footer} pointerEvents={getPointerEvents()}>
{getWidgetViews(
screenData?.screenWidgets?.footerWidgets,
handleActions,
screenData?.screenState,
throttledHandleClick,
)}
</View>
{screenData?.screenMetaData?.floatingWidgets?.map(
(fabWidget: Widget, index: number) => {
return (
<FAB
key={`${fabWidget.widgetId}_${index}`}
widgetData={fabWidget.widgetData as FabWidgetData}
handleActions={handleActions}
handleClick={throttledHandleClick}
scrollStyle={fabTextStyle}
/>
);
},
)}
</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 QuoteOfferScreen;