196 lines
6.1 KiB
TypeScript
196 lines
6.1 KiB
TypeScript
import _ from "lodash";
|
|
import { useCallback, useEffect, useRef } from "react";
|
|
import { View, ViewStyle, useWindowDimensions } from "react-native";
|
|
import Animated, {
|
|
useAnimatedScrollHandler,
|
|
useSharedValue,
|
|
} from "react-native-reanimated";
|
|
import { AnimatedScrollView } from "react-native-reanimated/lib/typescript/reanimated2/component/ScrollView";
|
|
import { GenericActionPayload } from "../../../App/common/actions/GenericAction";
|
|
import {
|
|
AnalyticsEventNameConstants,
|
|
AnalyticsEventPropertyConstants,
|
|
} from "../../../App/common/constants/AnalyticsEventsConstant";
|
|
import { sendAsAnalyticsEvent } from "../../../App/common/hooks/useAnalyticsEvent";
|
|
import { logToSentry } from "../../../App/common/hooks/useSentryLogging";
|
|
import { AnalyticsEvent } from "../../../App/common/interface";
|
|
import { SumInsuredWidgetData } from "../../../App/common/interface/widgets/widgetData/SumInsuredWidgetData";
|
|
import { getIndexFromOffset } from "../../../App/common/utilities/SizeUtils";
|
|
import CarouselItem from "./component/CarouselItem";
|
|
|
|
const SumInsuredWidget = ({
|
|
widgetData,
|
|
handleActions,
|
|
widgetIndex,
|
|
widgetStyle,
|
|
}: {
|
|
widgetData: SumInsuredWidgetData;
|
|
handleActions: (
|
|
value: any | undefined | null,
|
|
actionPayloadList: GenericActionPayload | undefined
|
|
) => void;
|
|
widgetIndex: number;
|
|
widgetStyle?: ViewStyle;
|
|
}) => {
|
|
const { width } = useWindowDimensions();
|
|
const SIZE = width * 0.4;
|
|
const SPACER_SIZE = (width - SIZE) / 2;
|
|
const x = useSharedValue(0);
|
|
const isMiddleCard = useSharedValue(false);
|
|
const scrollViewRef = useRef<AnimatedScrollView>(null);
|
|
|
|
const scrollToPosition = (index: number) => {
|
|
if (index <= 0) {
|
|
return;
|
|
}
|
|
if (scrollViewRef.current) {
|
|
scrollViewRef.current.scrollTo({
|
|
x: (index - 1) * SIZE,
|
|
animated: true,
|
|
});
|
|
if (widgetData?.carouselListData) {
|
|
handleActions(
|
|
widgetData?.carouselListData[index - 1]?.dependentWidgets,
|
|
widgetData?.widgetMetaData?.onValueChangeAction
|
|
);
|
|
}
|
|
const clickEvent: AnalyticsEvent = {
|
|
name: AnalyticsEventNameConstants.HI_SI_PILLS_CLICK,
|
|
properties: new Map([
|
|
[
|
|
AnalyticsEventPropertyConstants.SUM_INSURED,
|
|
widgetData?.carouselListData
|
|
?.at(index - 1)
|
|
?.sumInsured?.toString() ?? "",
|
|
],
|
|
[
|
|
AnalyticsEventPropertyConstants.TAG,
|
|
widgetData?.widgetMetaData?.recommendItemIndex === index - 1
|
|
? AnalyticsEventPropertyConstants.RECOMMENDED
|
|
: AnalyticsEventPropertyConstants.NOT_RECOMMENDED,
|
|
],
|
|
]),
|
|
};
|
|
sendAsAnalyticsEvent(clickEvent);
|
|
}
|
|
};
|
|
|
|
useEffect(() => {
|
|
if (widgetData?.widgetMetaData?.selectedItemIndex === undefined) return;
|
|
if (scrollViewRef.current) {
|
|
scrollViewRef.current.scrollTo({
|
|
x: SIZE * widgetData?.widgetMetaData?.selectedItemIndex,
|
|
animated: false,
|
|
});
|
|
}
|
|
}, []);
|
|
|
|
const onScroll = useAnimatedScrollHandler({
|
|
onScroll: (event) => {
|
|
x.value = event.contentOffset.x;
|
|
},
|
|
});
|
|
|
|
// Makes a patch call to update the sumInsured in the backend
|
|
const handleActionApiCall = (index: number) => {
|
|
const actionPayloadList =
|
|
widgetData?.widgetMetaData?.onCarouselReleaseActionSequence;
|
|
|
|
if (!actionPayloadList) {
|
|
logToSentry(
|
|
`Payload not present: ${actionPayloadList} | MethodName: handleActionApiCall`
|
|
);
|
|
return;
|
|
}
|
|
|
|
// Makes a patch call to update the sumInsured in the backend
|
|
const updatedActionPayload: GenericActionPayload = {
|
|
...actionPayloadList,
|
|
metaData: actionPayloadList.metaData?.map((actionPayload) => {
|
|
return {
|
|
...actionPayload,
|
|
data: {
|
|
sumInsured: widgetData?.carouselListData?.[index]?.sumInsured,
|
|
},
|
|
};
|
|
}),
|
|
};
|
|
|
|
handleActions(null, updatedActionPayload);
|
|
};
|
|
|
|
// We can use this debounced function to make api calls on scroll
|
|
const debouncedHandleActions = useCallback(
|
|
_.debounce((index: number) => handleActionApiCall(index), 1000),
|
|
[handleActions, handleActionApiCall]
|
|
);
|
|
|
|
const onMomentumScrollEnd = (event: any) => {
|
|
const index = getIndexFromOffset(event.nativeEvent.contentOffset.x, SIZE);
|
|
if (widgetData?.carouselListData) {
|
|
handleActions(
|
|
widgetData?.carouselListData[index]?.dependentWidgets,
|
|
widgetData?.widgetMetaData?.onValueChangeAction
|
|
);
|
|
}
|
|
const clickEvent: AnalyticsEvent = {
|
|
name: AnalyticsEventNameConstants.HI_SI_PILLS_CLICK,
|
|
properties: new Map([
|
|
[
|
|
AnalyticsEventPropertyConstants.SUM_INSURED,
|
|
widgetData?.carouselListData?.at(index)?.sumInsured?.toString() ?? "",
|
|
],
|
|
[
|
|
AnalyticsEventPropertyConstants.TAG,
|
|
widgetData?.widgetMetaData?.recommendItemIndex === index
|
|
? AnalyticsEventPropertyConstants.RECOMMENDED
|
|
: AnalyticsEventPropertyConstants.NOT_RECOMMENDED,
|
|
],
|
|
]),
|
|
};
|
|
sendAsAnalyticsEvent(clickEvent);
|
|
};
|
|
|
|
const data = widgetData.carouselListData && [
|
|
{ isFirst: true },
|
|
...widgetData?.carouselListData,
|
|
{ isLast: true },
|
|
];
|
|
|
|
return (
|
|
<Animated.ScrollView
|
|
ref={scrollViewRef}
|
|
horizontal
|
|
showsHorizontalScrollIndicator={false}
|
|
bounces={false}
|
|
scrollEventThrottle={16}
|
|
snapToInterval={SIZE}
|
|
decelerationRate="fast"
|
|
onScroll={onScroll}
|
|
onMomentumScrollEnd={onMomentumScrollEnd}
|
|
>
|
|
{data?.map((item, index) => {
|
|
if (item?.isFirst || item?.isLast) {
|
|
return <View style={{ width: SPACER_SIZE }} key={index} />;
|
|
}
|
|
|
|
return (
|
|
<View style={{ width: SIZE }} key={item?.itemId + "_" + index}>
|
|
<CarouselItem
|
|
item={item}
|
|
index={index}
|
|
isMiddleCard={isMiddleCard}
|
|
widgetData={widgetData}
|
|
x={x}
|
|
SIZE={SIZE}
|
|
scrollToPosition={scrollToPosition}
|
|
/>
|
|
</View>
|
|
);
|
|
})}
|
|
</Animated.ScrollView>
|
|
);
|
|
};
|
|
|
|
export default SumInsuredWidget;
|