Files
super-app/App/common/screen/BaseScreen.tsx
Mayank Singh 9527976c41 TP-64336 | Multi plan feature (#10813)
Co-authored-by: sangaraboinarishvik <rishvik.vardhan@navi.com>
2024-05-14 18:10:14 +00:00

170 lines
5.4 KiB
TypeScript

import isEqual from "lodash/isEqual";
import React, { useEffect, useMemo, useState } from "react";
import { View } from "react-native";
import { useDispatch, useSelector } from "react-redux";
import { commonStyles } from "../../Container/Navi-Insurance/Styles";
import { ActionMetaData, GenericActionPayload } from "../actions/GenericAction";
import { sendAsAnalyticsEvent } from "../hooks/useAnalyticsEvent";
import { useBottomSheet } from "../hooks/useBottomSheet";
import { logToSentry } from "../hooks/useSentryLogging";
import { CtaData } from "../interface";
import { ModalView } from "../interface/modals/ModalView";
import { ScreenData } from "../interface/widgets/screenData/ScreenData";
import { Router } from "../navigator/NavigationRouter";
import { updateCtaData } from "../redux/screens/screenActionCreators";
import { setCurrentScreenName } from "../utilities/AlfredUtils";
import {
getCacheKey,
getScreenDataFromCache,
isScreenWhiteListedForCaching,
saveScreenDataInCache,
} from "../utilities/CacheUtils";
import {
getScreenMapperNameFromCtaData,
getScreenNameFromCtaData,
} from "../utilities/MiscUtils";
import { WidgetActionTypes } from "../widgets/widget-actions/WidgetActionTypes";
import { ScreenMapper } from "./screen-mappers/ScreenMapper";
const BaseScreen: React.FC<{ navigation: any; route: any }> = ({
navigation,
route,
}) => {
const [screenData, setScreenData] = useState<ScreenData | null>(null);
const [screenName, setScreenName] = useState<string | null>(null);
const [screenKey, setScreenKey] = useState<string | null>(null);
const [screenState, setScreenState] = useState<ScreenState | null>(
ScreenState.LOADING
);
const [errorMetaData, setErrorMetaData] = useState<ActionMetaData[] | null>(
null
);
useEffect(() => {
const cacheKey = getCacheKey(screenName, screenKey);
if (!screenData) {
const screenInitialData: ScreenData = {
screenState: ScreenState.LOADING,
};
setScreenData(screenInitialData);
}
if (!!cacheKey && isScreenWhiteListedForCaching(screenName)) {
if (
!(
!!screenData?.errorMetaData ||
screenData?.screenState === ScreenState.ERROR
)
) {
saveScreenDataInCache(screenName, screenData);
}
}
}, [screenData]);
useEffect(() => {
if (!!getScreenNameFromCtaData(route.params?.ctaData)) {
setScreenName(getScreenNameFromCtaData(route.params?.ctaData)!!);
if (!!route.params?.ctaData?.screenKey) {
setScreenKey(route.params?.ctaData?.screenKey);
}
if (isScreenWhiteListedForCaching(screenName)) {
retrieveScreenDataFromCache(
getScreenNameFromCtaData(route.params?.ctaData)!!,
route.params?.ctaData?.screenKey
);
}
}
}, []);
const dispatch = useDispatch();
const retrieveScreenDataFromCache = (
screenName: string | null | undefined,
screenKey: string | null | undefined
) => {
let cacheKey = getCacheKey(screenName, screenKey);
if (!!cacheKey) {
getScreenDataFromCache(cacheKey).then((screenData) => {
if (!!screenData) {
setScreenData(screenData);
}
});
}
};
const { cta } = useSelector((state: any) => {
const savedCta = state.screenReducer.ctaData;
if (isEqual(savedCta, route.params.ctaData)) {
return { cta: state.screenReducer.ctaData };
}
return { cta: route.params.ctaData };
});
useEffect(() => {
const ctaData: CtaData = route.params.ctaData;
if (!isEqual(cta, ctaData)) {
dispatch(updateCtaData({ cta: ctaData, setScreenState: screenState }));
}
}, [route.params.ctaData, screenState]);
const handleActions = (actionPayload?: GenericActionPayload) => {
actionPayload?.metaData?.forEach((ActionMetaData) => {
if (!!ActionMetaData.analyticsEventProperties) {
sendAsAnalyticsEvent(ActionMetaData.analyticsEventProperties);
}
if (ActionMetaData.actionType === WidgetActionTypes.OPEN_BOTTOM_SHEET) {
addBottomSheet(ActionMetaData.data as ModalView);
} else {
const updatedActionPayload: GenericActionPayload = {
...(actionPayload as GenericActionPayload),
setScreenData,
setScreenState,
setErrorMetaData,
ctaData: cta,
screenData: { ...screenData },
};
if (!!actionPayload) {
Router.handleAction(updatedActionPayload, navigation);
} else {
// handle error
logToSentry(
`Action payload is missing or invalid: ${actionPayload} | MethodName: handleActions`
);
}
}
});
};
const { bottomsheet, addBottomSheet } = useBottomSheet(handleActions);
const MemoizedScreenMapper = useMemo(() => {
const secondIdentifier = getScreenMapperNameFromCtaData(cta);
setCurrentScreenName(
"RN_" + secondIdentifier?.toUpperCase() + "_" + screenName
);
return (
<View style={commonStyles.flex_1}>
{ScreenMapper.getScreenMapper(cta, screenData, handleActions)}
</View>
);
}, [cta, screenData]);
return (
<View style={commonStyles.flex_1}>
{MemoizedScreenMapper}
{bottomsheet.map((sheet, index) => (
<React.Fragment key={`bottomSheet-${index}`}>{sheet}</React.Fragment>
))}
</View>
);
};
export enum ScreenState {
LOADING,
LOADED,
ERROR,
OVERLAY,
}
export default BaseScreen;