TP-64336 | Multi plan feature (#10813)

Co-authored-by: sangaraboinarishvik <rishvik.vardhan@navi.com>
This commit is contained in:
Mayank Singh
2024-05-14 23:40:14 +05:30
committed by GitHub
parent 5f86a299ae
commit 9527976c41
72 changed files with 1846 additions and 279 deletions

View File

@@ -1,4 +1,4 @@
import React from "react";
import React, { useEffect } from "react";
import { View } from "react-native";
import { GenericActionPayload } from "../../App/common/actions/GenericAction";
import { CtaData } from "../../App/common/interface";
@@ -46,6 +46,10 @@ const BaseWidget = ({
widgetVisibility:
widget.widgetVisibility !== undefined ? widget.widgetVisibility : true,
};
useEffect(() => {
if (widget.widgetVisibility)
handleWidgetActions(null, widget?.widgetRenderActions)
}, [])
return widget.widgetVisibility ? (
<View style={widget.widgetStyle}>
{GetWidgetView.getWidget(

View File

@@ -25,7 +25,7 @@ const HeaderWithAssetsWidget = ({
widgetStyle: ViewStyle;
handleActions: (
value?: any | undefined | null,
screenActionPayload?: GenericActionPayload
screenActionPayload?: GenericActionPayload,
) => void;
widgetIndex: number;
handleClick?: (ctaData: CtaData) => void;
@@ -43,7 +43,7 @@ const HeaderWithAssetsWidget = ({
return () => {
BackHandler.removeEventListener(
"hardwareBackPress",
handleBackButtonClick
handleBackButtonClick,
);
};
}, [widgetData]);
@@ -69,10 +69,12 @@ const HeaderWithAssetsWidget = ({
)}
{widgetData.rightIcon &&
(widgetData.isRightAssetVisible === false ? false : true) && (
<StyledImage
imageFieldData={widgetData?.rightIcon}
handleClick={handleClick}
/>
<View>
<StyledImage
imageFieldData={widgetData?.rightIcon}
handleClick={handleClick}
/>
</View>
)}
{widgetData.rightLottie &&
(widgetData.isRightAssetVisible === false ? false : true) && (

View File

@@ -2,10 +2,10 @@ import { StyleSheet, TouchableOpacity, View, ViewStyle } from "react-native";
import { GenericActionPayload } from "../../App/common/actions/GenericAction";
import { CtaData } from "../../App/common/interface";
import { TitleWithAssetsWidgetData } from "../../App/common/interface/widgets/widgetData/TitleWithAssetsWidgetData";
import Colors from "../../assets/colors/colors";
import { StyledImage } from "../StyledImage";
import { StyledLottie } from "./styled-lottie/StyledLottie";
import { StyledText } from "./styled-text/StyledText";
import Colors from "../../assets/colors/colors";
const TitleWithAssetsWidget = ({
widgetData,
@@ -17,29 +17,45 @@ const TitleWithAssetsWidget = ({
widgetData: TitleWithAssetsWidgetData;
widgetStyle: ViewStyle;
handleActions: (screenActionPayload?: GenericActionPayload) => void;
widgetIndex: number;
widgetIndex?: number;
handleClick?: (ctaData: CtaData) => void;
}) => {
return (
<TouchableOpacity
onPress={() => {
handleClick && widgetData.cta && handleClick(widgetData.cta);
handleClick && widgetData?.cta && handleClick(widgetData?.cta);
}}
activeOpacity={1}
>
<View style={styles.container}>
{widgetData.leftIcon && (
<StyledImage imageFieldData={widgetData?.leftIcon} />
<View
style={
widgetData?.titleStyle ? widgetData?.titleStyle : styles.container
}
>
{widgetData?.leftIcon && (
<View>
<StyledImage imageFieldData={widgetData?.leftIcon} />
</View>
)}
{widgetData.leftLottie && (
<StyledLottie lottieFieldData={widgetData?.leftLottie} />
{widgetData?.leftLottie && (
<View>
<StyledLottie lottieFieldData={widgetData?.leftLottie} />
</View>
)}
{widgetData.title && <StyledText textFieldData={widgetData?.title} />}
{widgetData.rightIcon && (
<StyledImage imageFieldData={widgetData?.rightIcon} />
{widgetData?.title && (
<View>
<StyledText textFieldData={widgetData?.title} />
</View>
)}
{widgetData.rightLottie && (
<StyledLottie lottieFieldData={widgetData?.rightLottie} />
{widgetData?.rightIcon && (
<View>
<StyledImage imageFieldData={widgetData?.rightIcon} />
</View>
)}
{widgetData?.rightLottie && (
<View>
<StyledLottie lottieFieldData={widgetData?.rightLottie} />
</View>
)}
</View>
</TouchableOpacity>

View File

@@ -1,11 +1,6 @@
import throttle from "lodash/throttle";
import React, { useCallback } from "react";
import { View, ViewStyle } from "react-native";
import {
TouchableOpacity,
TouchableWithoutFeedback,
} from "react-native-gesture-handler";
import { TouchableOpacity, View, ViewStyle } from "react-native";
import { commonStyles } from "../../../App/Container/Navi-Insurance/Styles";
import { GenericActionPayload } from "../../../App/common/actions/GenericAction";
import { sendAsAnalyticsEvent } from "../../../App/common/hooks/useAnalyticsEvent";
@@ -55,7 +50,7 @@ const FooterWithCardWidget = ({
widgetStyle: ViewStyle;
handleActions: (
value?: any | undefined | null,
screenActionPayload?: GenericActionPayload
screenActionPayload?: GenericActionPayload,
) => void;
widgetIndex: number;
handleClick?: (ctaData: CtaData) => void;
@@ -88,9 +83,9 @@ const FooterWithCardWidget = ({
{
leading: true,
trailing: false,
}
},
),
[widgetData]
[widgetData],
);
const cardAction = () => {
@@ -144,16 +139,18 @@ const FooterWithCardWidget = ({
)}
<View style={getViewStyle()}>
<View style={commonStyles.flex_1}>
<TouchableOpacity onPress={titleAction} activeOpacity={1}>
<TitleWidget
widgetData={widgetData}
widgetStyle={styles.titleContainer}
handleActions={handleActions}
widgetIndex={widgetIndex}
/>
</TouchableOpacity>
</View>
{widgetData?.title && (
<View style={commonStyles.flex_1}>
<TouchableOpacity onPress={titleAction} activeOpacity={1}>
<TitleWidget
widgetData={widgetData}
widgetStyle={styles.titleContainer}
handleActions={handleActions}
widgetIndex={widgetIndex}
/>
</TouchableOpacity>
</View>
)}
<View style={commonStyles.flex_1}>
<CtaButton
state={buttonState}

View File

@@ -0,0 +1,6 @@
export { StyledText } from "./styled-text/StyledText";
export { StyledImage } from "../StyledImage";
export { default as TitleWidget } from "./title-widget/TitleWidget";
export { default as TitleWithAssetBackgroundWidget } from "./title-with-asset-background/TitleWithAssetBackground";
export { default as SelectCardWithDetailListWidget } from "./select-card-with-detail-list/SelectCardWithDetailList";
export { default as TableWidget } from "./table-widget/Table";

View File

@@ -0,0 +1,78 @@
import { TouchableOpacity } from "react-native";
import { styles } from "./SelectCardWithDetailListStyles";
import { View } from "react-native";
import { StyledImage, StyledText } from "..";
import {
ItemCardProps,
ContainerTag as ContainerTagType,
} from "../../../App/common/interface/widgets/widgetData";
import ItemDetail from "./ItemDetail";
import { SelectButton } from "../../reusable";
import { SelectButtonType } from "../../../App/common/constants";
import { sendAsAnalyticsEvent } from "../../../App/common/hooks/useAnalyticsEvent";
import { useEffect } from "react";
const ContainerTag = ({
containerTag,
}: {
containerTag?: ContainerTagType;
}) => {
return (
<View style={styles.tag}>
<View style={styles.tagContainer}>
{containerTag?.tagTitle?.text && (
<StyledText textFieldData={containerTag?.tagTitle!!} />
)}
</View>
{containerTag?.tag?.url && (
<StyledImage imageFieldData={containerTag?.tag!!} />
)}
</View>
);
};
export const ItemCard = ({
handleClick,
item,
selected,
onSelect,
showContainerTag,
containerTag,
}: ItemCardProps) => {
useEffect(() => {
item?.analyticEvents?.onViewEvent &&
sendAsAnalyticsEvent(item?.analyticEvents?.onViewEvent);
}, []);
return (
<TouchableOpacity
style={[styles.card, selected && styles.selectedCard]}
onPress={onSelect}
activeOpacity={1}
>
{item?.itemType === showContainerTag && (
<ContainerTag containerTag={containerTag} />
)}
<View style={styles.headerContainer}>
<SelectButton selected={selected} type={SelectButtonType.RADIO} />
<View style={styles.alignStart}>
{item?.title?.text && <StyledText textFieldData={item?.title} />}
{item?.subtitle?.text && (
<StyledText textFieldData={item?.subtitle} />
)}
</View>
</View>
<View style={styles.detailCardContainer}>
{item?.details?.map((detail, index) => (
<ItemDetail
key={index}
showBorder={index !== (item?.details?.length ?? 0) - 1}
detail={detail}
selected={selected}
handleClick={handleClick}
/>
))}
</View>
</TouchableOpacity>
);
};

View File

@@ -0,0 +1,39 @@
import { TouchableOpacity, View } from "react-native";
import { styles } from "./SelectCardWithDetailListStyles";
import { ItemDetailProps } from "../../../App/common/interface/widgets/widgetData";
import { StyledText } from "..";
const ItemDetail = ({
detail,
selected,
handleClick,
showBorder,
}: ItemDetailProps) => {
const onPress = () =>
detail?.rightText?.cta &&
handleClick &&
handleClick(detail?.rightText?.cta);
return (
<View
style={[
styles.detailCard,
selected && styles.selectedDetailCard,
showBorder && styles.borderBottom,
]}
>
<View style={styles.detailLeftText}>
{detail?.leftTextWithImage && (
<StyledText textFieldData={detail?.leftTextWithImage} />
)}
{detail?.leftText && <StyledText textFieldData={detail?.leftText} />}
</View>
{detail?.rightText?.cta && (
<TouchableOpacity onPress={onPress} activeOpacity={1}>
<StyledText textFieldData={detail?.rightText} />
</TouchableOpacity>
)}
</View>
);
};
export default ItemDetail;

View File

@@ -0,0 +1,61 @@
import { useState } from "react";
import { TitleWidget } from "..";
import {
Item,
SelectCardWithDetailListProps,
} from "../../../App/common/interface/widgets/widgetData";
import { ItemCard } from "./ItemCard";
import { styles } from "./SelectCardWithDetailListStyles";
import { sendAsAnalyticsEvent } from "../../../App/common/hooks/useAnalyticsEvent";
const SelectCardWithDetailList = ({
widgetData,
widgetStyle,
handleActions,
handleClick,
widgetIndex,
}: SelectCardWithDetailListProps) => {
const [selectedItem, setSelectedItem] = useState<string | undefined>(
widgetData?.widgetMetaData?.selectedItem,
);
const handleSelect = (itemType?: string) => {
setSelectedItem(itemType);
const item = widgetData?.items?.find(
item => item?.itemType === itemType,
);
item?.analyticEvents?.onSelectedEvent && sendAsAnalyticsEvent(item?.analyticEvents?.onSelectedEvent)
if (item?.dependentWidgets) {
handleActions(
item?.dependentWidgets,
widgetData?.widgetMetaData?.onValueChangeAction,
);
}
};
return (
<>
<TitleWidget
widgetData={widgetData}
widgetStyle={styles.detailLeftText}
handleActions={handleActions}
handleClick={handleClick}
widgetIndex={widgetIndex}
/>
{widgetData?.items?.map((item: Item) => {
return (
<ItemCard
handleClick={handleClick}
containerTag={widgetData?.containerTag}
showContainerTag={widgetData?.widgetMetaData?.showContainerTag}
item={item}
selected={selectedItem === item?.itemType}
onSelect={() => handleSelect(item?.itemType)}
/>
);
})}
</>
);
};
export default SelectCardWithDetailList;

View File

@@ -0,0 +1,69 @@
import { StyleSheet } from "react-native";
export const styles = StyleSheet.create({
card: {
backgroundColor: "#fff",
borderRadius: 4,
padding: 16,
marginTop: 16,
width: "100%",
borderColor: "#EBEBEB",
borderWidth: 1,
position: "relative",
elevation: 3,
shadowColor: "#B0C0D9",
shadowOffset: { width: 3, height: 3 },
shadowOpacity: 0.3,
shadowRadius: 16,
},
selectedCard: {
borderColor: "#1F002A",
backgroundColor: "#EAF2FF",
},
detailCardContainer: {
borderRadius: 4,
overflow: "hidden",
},
detailCard: {
display: "flex",
flexDirection: "row",
justifyContent: "space-between",
alignItems: "center",
backgroundColor: "#F5F5F5",
paddingHorizontal: 12,
paddingVertical: 8,
},
detailLeftText: {
flexDirection: "row",
justifyContent: "flex-start",
},
alignStart: {
alignItems: "flex-start",
},
borderBottom: {
borderBottomWidth: 1,
borderBottomColor: "#E3E5E5",
},
selectedDetailCard: {
backgroundColor: "#FFFFFF",
},
headerContainer: {
flexDirection: "row",
marginBottom: 16,
},
tag: {
justifyContent: "flex-start",
alignItems: "flex-end",
top: 14,
right: -3,
position: "absolute",
},
tagContainer: {
backgroundColor: "#3C7DFF",
paddingHorizontal: 8,
paddingVertical: 4,
borderTopStartRadius: 2,
borderTopEndRadius: 2,
borderBottomStartRadius: 2,
},
});

View File

@@ -23,7 +23,6 @@ export const StyledLottie = ({
}, [lottieFieldData]);
if (!lottieFieldData?.url) return <></>;
return (
<TouchableOpacity
onPress={() => {

View File

@@ -0,0 +1,114 @@
import { useEffect, useState } from "react";
import { TouchableOpacity, View } from "react-native";
import {
TableWidgetProps,
Column,
Row,
Cell as CellData,
ColumnsProps,
RowsProps,
CellProps,
} from "../../../App/common/interface/widgets/widgetData";
import { StyledImage, StyledText } from "..";
import { styles } from "./TableWidgetStyles";
import { sendAsAnalyticsEvent } from "../../../App/common/hooks/useAnalyticsEvent";
const Cell = ({ widgetData, cell, index, handleClick }: CellProps) => {
useEffect(()=>{
cell?.analyticEvents?.onViewEvent && sendAsAnalyticsEvent(cell?.analyticEvents?.onViewEvent)
},[])
return (
<TouchableOpacity
style={[styles.cell, widgetData?.columns?.[index]?.columnStyle]}
onPress={() => {
handleClick && cell?.cta && handleClick(cell?.cta);
}}
activeOpacity={1}
>
{cell?.title?.text && (
<StyledText key={`text-${index}`} textFieldData={cell?.title} />
)}
{cell?.image?.url && (
<StyledImage key={`image-${index}`} imageFieldData={cell?.image} />
)}
</TouchableOpacity>
);
};
const Rows = ({ widgetData, rowsToDisplay, handleClick }: RowsProps) => {
return (
<>
{widgetData?.rows &&
widgetData?.rows
?.slice(0, rowsToDisplay)
?.map((row: Row, index: number) => {
return (
<View style={styles.row} key={index}>
{row?.cells?.map((cell: CellData, index: number) => (
<Cell
cell={cell}
index={index}
key={index}
widgetData={widgetData}
handleClick={handleClick}
/>
))}
</View>
);
})}
</>
);
};
const Columns = ({ widgetData }: ColumnsProps) => {
return (
<View style={[styles.row]}>
{widgetData?.columns &&
widgetData?.columns?.map((column: Column, index: number) => {
return (
<View
style={[styles.cell, styles.header, column?.columnStyle]}
key={index}
>
{column?.title?.text && (
<StyledText textFieldData={column?.title} />
)}
{column?.subtitle?.text && (
<StyledText textFieldData={column?.subtitle} />
)}
</View>
);
})}
</View>
);
};
const Table = ({ widgetData, handleClick }: TableWidgetProps) => {
const [rowsToDisplay, setRowsToDisplay] = useState<number | undefined>(
widgetData?.rowsToDisplay || widgetData?.rows?.length,
);
const handleSelect = () => {
setRowsToDisplay(widgetData?.rows?.length);
widgetData.viewButton?.cta?.analyticsEventProperties && sendAsAnalyticsEvent(widgetData.viewButton?.cta?.analyticsEventProperties)
};
return (
<>
<Columns widgetData={widgetData} />
<Rows
widgetData={widgetData}
rowsToDisplay={rowsToDisplay}
handleClick={handleClick}
/>
{rowsToDisplay !== widgetData?.rows?.length &&
widgetData.viewButton?.text && (
<TouchableOpacity onPress={handleSelect} activeOpacity={1}>
<StyledText textFieldData={widgetData?.viewButton} />
</TouchableOpacity>
)}
</>
);
};
export default Table;

View File

@@ -0,0 +1,21 @@
import { StyleSheet } from "react-native";
export const styles = StyleSheet.create({
row: {
flexDirection: "row",
},
header: {
alignItems: "center",
flexDirection: "column"
},
cell: {
flex: 1,
padding: 10,
flexDirection: "row",
textAlign: "left",
alignItems: "center",
justifyContent: "space-between",
borderBottomWidth: 1,
borderBottomColor: "#F5F5F5",
},
});

View File

@@ -1,5 +1,5 @@
import { View, ViewStyle } from "react-native";
import { TouchableWithoutFeedback } from "react-native-gesture-handler";
import { TouchableOpacity } from "react-native";
import { GenericActionPayload } from "../../../App/common/actions/GenericAction";
import { CtaData } from "../../../App/common/interface";
import { TitleWidgetData } from "../../../App/common/interface/widgets/widgetData/TitleWidgetData";
@@ -14,7 +14,10 @@ const TitleWidget = ({
}: {
widgetData: TitleWidgetData;
widgetStyle?: ViewStyle;
handleActions?: (screenActionPayload?: GenericActionPayload) => void;
handleActions?: (
value: any | undefined | null,
actionPayloadList: GenericActionPayload | undefined
) => void;
handleClick?: (cta: CtaData) => void;
widgetIndex?: number;
}) => {
@@ -22,28 +25,32 @@ const TitleWidget = ({
handleClick &&
(widgetData?.title?.cta) &&
handleClick(widgetData?.title?.cta);
widgetData?.title?.actions && handleActions &&
handleActions(null,widgetData?.title?.actions)
};
const handleRightTitleClick = () => {
handleClick &&
(widgetData?.rightTitle?.cta) &&
handleClick(widgetData?.rightTitle?.cta);
widgetData?.rightTitle?.actions && handleActions &&
handleActions(null, widgetData?.rightTitle?.actions)
};
return (
<View style={widgetStyle}>
{widgetData.title && (
<TouchableWithoutFeedback onPress={handleTitleClick}>
<TouchableOpacity onPress={handleTitleClick} activeOpacity={1}>
<StyledText textFieldData={widgetData.title} />
</TouchableWithoutFeedback>
</TouchableOpacity>
)}
{widgetData.subtitle && (
<StyledText textFieldData={widgetData.subtitle} />
)}
{widgetData.rightTitle && (
<TouchableWithoutFeedback onPress={handleRightTitleClick}>
<TouchableOpacity onPress={handleRightTitleClick} activeOpacity={1}>
<StyledText textFieldData={widgetData.rightTitle} />
</TouchableWithoutFeedback>
</TouchableOpacity>
)}
</View>
);

View File

@@ -105,3 +105,5 @@ export const TitleWithAssetBackgroundWidget = ({
</View>
);
};
export default TitleWithAssetBackgroundWidget;

View File

@@ -7,13 +7,26 @@ import {
} from "../../../App/common/interface/widgets/widgetData/TitleWithListWidgetData";
import TitleWidget from "../title-widget/TitleWidget";
import styles from "./TitleWithListWidgetStyle";
import { useEffect } from "react";
import { sendAsAnalyticsEvent } from "../../../App/common/hooks/useAnalyticsEvent";
import { useCallback } from "react";
import throttle from "lodash/throttle";
const ListItemComponent = ({ item }: { item: ListItem }) => {
const ListItemComponent = ({
item,
handleActions,
}: {
item: ListItem;
handleActions?: (screenActionPayload?: GenericActionPayload) => void;
}) => {
useEffect(() => {
item.onViewEvent && sendAsAnalyticsEvent(item.onViewEvent);
});
return (
<TitleWidget
widgetData={item}
widgetStyle={styles.itemRowContainer}
handleActions={() => {}}
handleActions={handleActions}
widgetIndex={Number(item.id)}
/>
);
@@ -30,22 +43,33 @@ const TitleWithListWidget = ({
widgetStyle: ViewStyle;
handleActions: (screenActionPayload?: GenericActionPayload) => void;
handleClick?: (cta: CtaData) => void;
widgetIndex: number;
widgetIndex?: number;
}) => {
const throttledHandleActions = useCallback(
throttle(handleActions, 700, { leading: true, trailing: false }),
[],
);
return (
<View>
<TitleWidget
widgetData={widgetData}
widgetStyle={styles.rowContainer}
handleActions={handleActions}
handleActions={throttledHandleActions}
handleClick={handleClick}
widgetIndex={widgetIndex}
/>
<View style={styles.listContainer}>
<View
style={[
widgetData.listStyle ? widgetData.listStyle : styles.listContainer,
]}
>
<FlatList
data={widgetData.listData}
renderItem={({ item }: { item: ListItem }) => (
<ListItemComponent item={item} />
<ListItemComponent
item={item}
handleActions={throttledHandleActions}
/>
)}
keyExtractor={(item, index) => item.id || index.toString()}
/>

View File

@@ -13,6 +13,11 @@ const styles = StyleSheet.create({
borderRadius: 4,
borderWidth: 1,
borderColor: "#EBEBEB",
elevation: 4,
shadowColor: "#B0C0D9",
shadowOffset: { width: 3, height: 3 },
shadowOpacity: 1,
shadowRadius: 32.962 / 2
},
itemRowContainer: {
flexDirection: "row",