NTP-57102 | Goal Based Investing (#16105)

Co-authored-by: shrihari-raju_navi <shrihari.raju@navi.com>
This commit is contained in:
Varun Jain
2025-05-22 12:22:07 +05:30
committed by GitHub
parent b129735575
commit a5e33c10da
101 changed files with 4820 additions and 265 deletions

View File

@@ -12,6 +12,7 @@ import androidx.lifecycle.LiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.lifecycleScope
import com.navi.amc.common.viewmodel.CheckerVM
import com.navi.amc.compose.feature.goalBasedSip.viewmodel.GoalBasedSipSetupVM
import com.navi.amc.fundbuy.models.AutoPaySetupRequestData
import com.navi.amc.fundbuy.viewmodel.FundBuyFlowViewModel
import com.navi.amc.fundbuy.viewmodel.FundListViewModel
@@ -30,12 +31,17 @@ import com.navi.amc.utils.AmcAnalytics.ORDER_TYPE
import com.navi.amc.utils.Constant.ACTION_PERFORMED
import com.navi.amc.utils.Constant.AMOUNT
import com.navi.amc.utils.Constant.BANK_DETAILS_REF_ID
import com.navi.amc.utils.Constant.GOAL_NAME
import com.navi.amc.utils.Constant.GOAL_REFERENCE_ID
import com.navi.amc.utils.Constant.MANDATE_OPTED_IN
import com.navi.amc.utils.Constant.PAYMENT_MODE
import com.navi.amc.utils.Constant.SETUP_AUTOPAY_EXISTING_SIP
import com.navi.amc.utils.Constant.SIP_REFERENCE_ID
import com.navi.analytics.utils.NaviTrackEvent
import com.navi.base.model.CtaData
import com.navi.common.utils.Constants.AMC_GOAL_BASED_SIP_AMOUNT_SCREEN
import com.navi.common.utils.Constants.AMC_GOAL_BASED_SIP_SUMMARY_SCREEN
import com.navi.common.utils.Constants.AMC_GOAL_BASED_SIP_TARGET_SETUP_SCREEN
import com.navi.common.utils.Constants.CTAData
import com.navi.common.utils.Constants.HOPPER_API_RESPONSE_NOT_RECEIVED
import com.navi.common.utils.Constants.HOPPER_API_TIMEOUT
@@ -52,6 +58,7 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.cancel
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.SharedFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.launch
@@ -180,6 +187,62 @@ class HopperHelper {
)
}
}
is GoalBasedSipSetupVM -> {
when (ctaData.url) {
AMC_GOAL_BASED_SIP_TARGET_SETUP_SCREEN -> {
viewModel.fetchTargetSetupScreenDataFromRemote(
goalName =
ctaData.parameters
?.firstOrNull { it.key == GOAL_NAME }
?.value
.orEmpty(),
goalReferenceId =
ctaData.parameters
?.firstOrNull { it.key == GOAL_REFERENCE_ID }
?.value
.orEmpty(),
)
observeAndHandleResponse(
activity,
ctaData,
onResult = onResult,
stateFlow = viewModel.goalBasedSipScreenState,
)
}
AMC_GOAL_BASED_SIP_AMOUNT_SCREEN -> {
viewModel.fetchSipAmountScreenDataFromRemote(
screenName = AMC_GOAL_BASED_SIP_AMOUNT_SCREEN,
goalReferenceId =
ctaData.parameters
?.firstOrNull { it.key == GOAL_REFERENCE_ID }
?.value
.orEmpty(),
)
observeAndHandleResponse(
activity,
ctaData,
viewModel.sipAmountScreenData,
onResult,
)
}
AMC_GOAL_BASED_SIP_SUMMARY_SCREEN -> {
viewModel.fetchGoalSummaryScreenDataFromRemote(
screenName = AMC_GOAL_BASED_SIP_SUMMARY_SCREEN,
goalReferenceId =
ctaData.parameters
?.firstOrNull { it.key == GOAL_REFERENCE_ID }
?.value
.orEmpty(),
)
observeAndHandleResponse(
activity,
ctaData,
viewModel.goalSummaryScreenData,
onResult,
)
}
}
}
else -> {
onResult(false)
}
@@ -191,7 +254,10 @@ class HopperHelper {
CoroutineScope(Dispatchers.Main).launch {
when (viewModel) {
is InvestmentsVm -> {
viewModel.getDynamicCTA(ctaData.action ?: KYC_JOURNEY)
viewModel.getDynamicCTA(
ctaData.action ?: KYC_JOURNEY,
ctaData.parameters ?: emptyList(),
)
observeAndHandleDynamicCtaResponse(viewModel.dynamicCta, onResult)
}
}
@@ -213,9 +279,10 @@ class HopperHelper {
private fun observeAndHandleResponse(
activity: ComponentActivity,
ctaData: CtaData,
liveData: LiveData<*>,
liveData: LiveData<*>? = null,
onResult: (Boolean) -> Unit,
timeoutMillis: Long = HOPPER_API_TIMEOUT,
stateFlow: StateFlow<*>? = null,
) {
var responseReceived = false
val job =
@@ -225,8 +292,13 @@ class HopperHelper {
NaviTrackEvent.trackEvent(eventName = HOPPER_API_RESPONSE_NOT_RECEIVED)
onResult(false)
}
stateFlow?.collectLatest { response ->
responseReceived = true
cancel()
handleResponse(ctaData, response, onResult)
}
}
liveData.observeNullable(activity) { response ->
liveData?.observeNullable(activity) { response ->
responseReceived = true
liveData.removeObservers(activity)
job.cancel()

View File

@@ -1,6 +1,6 @@
/*
*
* * Copyright © 2024 by Navi Technologies Limited
* * Copyright © 2024-2025 by Navi Technologies Limited
* * All rights reserved. Strictly confidential
*
*/
@@ -12,6 +12,7 @@ import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import com.navi.amc.common.viewmodel.CheckerVM
import com.navi.amc.common.viewmodel.OTPVM
import com.navi.amc.compose.feature.goalBasedSip.viewmodel.GoalBasedSipSetupVM
import com.navi.amc.fundbuy.viewmodel.FundBuyFlowViewModel
import com.navi.amc.fundbuy.viewmodel.FundListViewModel
import com.navi.amc.kyc.viewmodel.BankDetailsVM
@@ -29,6 +30,9 @@ import com.navi.amc.portfolio.viewmodels.SipModificationVM
import com.navi.base.model.CtaData
import com.navi.common.utils.Constants.AMC_FUND_AUTOPAY_SETUP_V3
import com.navi.common.utils.Constants.AMC_FUND_OTP
import com.navi.common.utils.Constants.AMC_GOAL_BASED_SIP_AMOUNT_SCREEN
import com.navi.common.utils.Constants.AMC_GOAL_BASED_SIP_SUMMARY_SCREEN
import com.navi.common.utils.Constants.AMC_GOAL_BASED_SIP_TARGET_SETUP_SCREEN
import com.navi.common.utils.Constants.AMC_HPC_NAME_REDIRECT_PAGE_URL
import com.navi.common.utils.Constants.AMC_HPC_PAN_REDIRECT_PAGE_URL
import com.navi.common.utils.Constants.AMC_KYC_BANK_DETAILS_URL
@@ -72,6 +76,10 @@ class ViewModelMapper {
AMC_FUND_OTP -> ViewModelProvider(activity)[OTPVM::class.java]
AMC_FUND_AUTOPAY_SETUP_V3 ->
ViewModelProvider(activity)[FundBuyFlowViewModel::class.java]
AMC_GOAL_BASED_SIP_TARGET_SETUP_SCREEN,
AMC_GOAL_BASED_SIP_AMOUNT_SCREEN,
AMC_GOAL_BASED_SIP_SUMMARY_SCREEN ->
ViewModelProvider(activity)[GoalBasedSipSetupVM::class.java]
else -> null
}
}

View File

@@ -10,6 +10,7 @@ package com.naviapp.home.dashboard.models.investmentTabWidgetData
import com.google.gson.annotations.SerializedName
import com.navi.amc.common.model.GenericComposableWidget
import com.navi.amc.fundbuy.models.widgets.FundCardData
import com.navi.amc.fundbuy.models.widgets.SetupMonthlyTargetCard
import com.navi.base.model.GenericAnalytics
import com.navi.common.model.InvestmentBaseProperty
import com.navi.naviwidgets.models.response.Footer
@@ -35,7 +36,8 @@ data class TopInvestingFundsExtraData(
)
data class TopInvestingFundsContentData(
@SerializedName("fundCards") val fundCards: List<FundCardData>? = null
@SerializedName("goalCards") val goalCards: List<SetupMonthlyTargetCard>? = null,
@SerializedName("fundCards") val fundCards: List<FundCardData>? = null,
)
data class HeaderData(

View File

@@ -9,6 +9,7 @@ package com.naviapp.home.dashboard.repo
import com.navi.base.model.ActionData
import com.navi.base.model.JourneyType
import com.navi.base.model.LineItem
import com.navi.common.checkmate.model.MetricInfo
import com.navi.common.model.ModuleNameV2
import com.navi.common.network.models.RepoResult
@@ -42,12 +43,13 @@ constructor(@SuperAppRetroFit private val superAppRetrofitService: RetrofitServi
suspend fun getDynamicCTA(
context: String?,
parameters: List<LineItem>? = null,
metricInfo: MetricInfo<RepoResult<ActionData>>,
): RepoResult<ActionData> {
return apiResponseCallback(
superAppRetrofitService.getDynamicCta(
target = ModuleNameV2.AMC.name,
journeyType = JourneyType(context = context),
journeyType = JourneyType(context = context, parameters = parameters),
),
metricInfo = metricInfo,
)

View File

@@ -91,6 +91,7 @@ fun InvestmentGenericComposableWidgetFactory(
onClick = onClick,
investmentsTabVm = investmentsTabVm,
onVisible = onVisible,
onHopperStart = onHopperStart,
)
}
}

View File

@@ -10,11 +10,13 @@ package com.naviapp.home.dashboard.ui.compose.investmentTab
import UpcomingSipPaymentWidget
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import com.navi.amc.fundbuy.models.cards.InvestmentGoalCardData
import com.navi.amc.fundbuy.models.cards.PaymentCard
import com.navi.amc.fundbuy.models.widgets.FtueWithTrackerWidget
import com.navi.amc.fundbuy.models.widgets.FundCardData
import com.navi.amc.fundbuy.models.widgets.RepeatOrderWidget
import com.navi.amc.fundbuy.models.widgets.RiskFreeFundWidget
import com.navi.amc.fundbuy.models.widgets.SetupMonthlyTargetCard
import com.navi.amc.fundbuy.models.widgets.SetupMonthlyTargetWidget
import com.navi.base.model.GenericAnalytics
import com.naviapp.home.dashboard.models.investmentTabWidgetData.ActionCardWidget
@@ -73,6 +75,8 @@ fun <T> extractMetaData(widgetData: T): GenericAnalytics? {
is CutOffTimerWidget -> widgetData.widgetData?.extraData?.metaData
is BuyTheDipWidget -> widgetData.widgetData?.extraData?.metaData
is FtueWithTrackerWidget -> widgetData.widgetData?.extraData?.metaData
is SetupMonthlyTargetCard -> widgetData.actionData?.metaData
is InvestmentGoalCardData -> widgetData.actionData?.metaData
else -> null
}
}

View File

@@ -23,9 +23,12 @@ import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
import com.navi.amc.fundbuy.composables.cards.MonthlyInvestmentGoalCardComposable
import com.navi.amc.fundbuy.composables.cards.SetupMonthlyTargetCardComposable
import com.navi.amc.fundbuy.models.cards.InvestmentGoalCardData
import com.navi.amc.fundbuy.models.cards.PaymentCard
import com.navi.amc.fundbuy.models.widgets.FundCardData
import com.navi.amc.fundbuy.models.widgets.SetupMonthlyTargetCard
import com.navi.amc.utils.Constant.GOAL_BASED_SIP_SETUP_CARD
import com.navi.base.model.ActionData
import com.navi.base.model.CtaData
import com.navi.base.model.GenericAnalytics
@@ -47,6 +50,7 @@ import com.naviapp.utils.Constants.ORDER_IN_PROGRESS_CARD
import com.naviapp.utils.Constants.PAGER_SCROLL
import com.naviapp.utils.Constants.RANK_OF_CARD
import com.naviapp.utils.Constants.REPEAT_ORDER
import com.naviapp.utils.Constants.SETUP_MONTHLY_INVESTMENT_GOAL_CARD
import com.naviapp.utils.Constants.SIP_AUTOPAY_NUDGE_CARD
import com.naviapp.utils.Constants.SIP_AUTOPAY_NUDGE_CARD_V2
import com.naviapp.utils.Constants.UPCOMING_SIP_PAYMENT_CARD
@@ -254,5 +258,26 @@ fun RenderCardBasedOnType(
)
}
}
SETUP_MONTHLY_INVESTMENT_GOAL_CARD -> {
VisibilityTracker(widgetData = data, onVisible = onVisible) {
SetupMonthlyTargetCardComposable(
cardData = data as SetupMonthlyTargetCard,
onClick = onClick,
cardWidth = cardWidth,
)
}
}
GOAL_BASED_SIP_SETUP_CARD -> {
VisibilityTracker(widgetData = data, onVisible = onVisible) {
GoalBasedSipSetupCardComposable(
cardData = data as SetupMonthlyTargetCard,
onClick = onClick,
cardWidth = cardWidth,
onHopperStart = onHopperStart,
)
}
}
}
}

View File

@@ -0,0 +1,235 @@
/*
*
* * Copyright © 2025 by Navi Technologies Limited
* * All rights reserved. Strictly confidential
*
*/
package com.naviapp.home.dashboard.ui.compose.investmentTab.genericComposables
import androidx.compose.foundation.BorderStroke
import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.layout.wrapContentHeight
import androidx.compose.foundation.layout.wrapContentWidth
import androidx.compose.material.Card
import androidx.compose.runtime.Composable
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.shadow
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import com.navi.amc.fundbuy.models.widgets.SetupMonthlyTargetCard
import com.navi.amc.utils.Constant.DEFAULT_COLUMN_WEIGHT
import com.navi.base.model.ActionData
import com.navi.base.model.CtaData
import com.navi.common.utils.Constants.HOPPER
import com.navi.common.utils.toCtaData
import com.navi.design.utils.clickableWithNoGesture
import com.navi.naviwidgets.composewidget.reusable.ButtonComposable
import com.navi.naviwidgets.extensions.NaviImage
import com.navi.naviwidgets.extensions.NaviTextWidgetized
import com.navi.naviwidgets.extensions.hexToColor
import com.navi.naviwidgets.models.FooterButtonData
import com.navi.naviwidgets.models.FooterButtonState
import com.navi.uitron.utils.ShapeUtil
import com.navi.uitron.utils.getBorderStrokeBrushData
import com.navi.uitron.utils.hexToComposeColor
import com.navi.uitron.utils.setPadding
import com.naviapp.R
import com.naviapp.home.dashboard.ui.compose.investmentTab.InvestmentsScreenHelper
@Composable
fun GoalBasedSipSetupCardComposable(
cardData: SetupMonthlyTargetCard? = null,
onClick: (actionData: ActionData?) -> Unit = {},
cardWidth: Dp,
onHopperStart: (ctaData: CtaData, buttonState: MutableState<FooterButtonState>) -> Unit =
{ _, _ ->
},
) {
val buttonState = remember { mutableStateOf(FooterButtonState.ENABLED) }
cardData?.let { it ->
Card(
shape = ShapeUtil.run { getShape(shape = it.properties?.cardProperty?.shape) },
elevation = it.properties?.cardProperty?.elevation?.dp ?: 0.dp,
backgroundColor =
it.properties?.cardProperty?.backgroundColor?.hexToComposeColor ?: Color.White,
border =
BorderStroke(
width = ((it.properties?.cardProperty?.borderStrokeData?.width) ?: 0.0f).dp,
brush = getBorderStrokeBrushData(it.properties?.cardProperty?.borderStrokeData),
),
modifier =
Modifier.width(cardWidth)
.shadow(
elevation = (it.properties?.cardProperty?.elevation ?: 0).dp,
ambientColor = hexToColor(it.properties?.cardProperty?.ambientColor),
spotColor = hexToColor(it.properties?.cardProperty?.spotColor),
shape = ShapeUtil.getShape(shape = it.properties?.cardProperty?.shape),
)
.clickableWithNoGesture {
it.actionData?.let { actionData ->
if (actionData.url == HOPPER) {
InvestmentsScreenHelper()
.setActionStatus(
actionData = actionData,
buttonState = buttonState,
onClick = onClick,
onHopperStart = onHopperStart,
)
} else {
onClick(actionData)
}
}
},
) {
Box(
modifier =
Modifier.padding(end = it.properties?.cardProperty?.padding?.end?.dp ?: 0.dp),
contentAlignment = Alignment.TopEnd,
) {
NaviTextWidgetized(
textFieldData = it.tagData,
modifier =
Modifier.background(
color =
it.properties?.tagProperty?.backgroundColor?.hexToComposeColor
?: Color.Transparent,
shape = ShapeUtil.getShape(it.properties?.tagProperty?.shape),
)
.border(
BorderStroke(
width =
it.properties?.tagProperty?.borderStrokeData?.width?.dp
?: 0.dp,
brush =
getBorderStrokeBrushData(
it.properties?.tagProperty?.borderStrokeData
),
),
shape = ShapeUtil.getShape(it.properties?.tagProperty?.shape),
)
.setPadding(it.properties?.tagProperty?.padding),
)
}
Column(modifier = Modifier.fillMaxWidth()) {
Column(Modifier.fillMaxWidth().setPadding(it.properties?.cardProperty?.padding)) {
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.spacedBy(8.dp),
) {
Column(
modifier =
Modifier.weight(
it.properties?.cardProperty?.columnWeight
?: DEFAULT_COLUMN_WEIGHT
)
) {
NaviTextWidgetized(
textFieldData = it.title,
modifier =
Modifier.setPadding(it.properties?.titleProperty?.padding),
)
NaviTextWidgetized(
textFieldData = it.subtitle,
modifier =
Modifier.setPadding(it.properties?.subtitleProperty?.padding),
)
Spacer(modifier = Modifier.weight(1f))
ButtonComposable(
data =
FooterButtonData(
title = it.buttonText,
backgroundColor =
if (
buttonState.value.name ==
FooterButtonState.LOADING.name
)
"#8F8095"
else "#1F002A",
cta = it.actionData?.toCtaData(),
),
modifier = Modifier.wrapContentWidth().wrapContentHeight(),
textModifier = Modifier.wrapContentWidth().wrapContentHeight(),
contentPadding =
if (buttonState.value.name == FooterButtonState.LOADING.name) {
PaddingValues(
start = 16.dp,
end = 16.dp,
top = 12.dp,
bottom = 12.dp,
)
} else {
PaddingValues(
start =
((it.properties?.buttonProperty?.padding?.start)
?: R.integer.value_16)
.dp,
end =
((it.properties?.buttonProperty?.padding?.end)
?: R.integer.value_16)
.dp,
top =
((it.properties?.buttonProperty?.padding?.top)
?: R.integer.value_12)
.dp,
bottom =
((it.properties?.buttonProperty?.padding?.bottom)
?: R.integer.value_12)
.dp,
)
},
state = buttonState.value.name,
onClick = { ctaData ->
it.actionData?.let {
InvestmentsScreenHelper()
.setActionStatus(
actionData = it,
buttonState = buttonState,
onClick = onClick,
onHopperStart = onHopperStart,
)
}
},
)
}
Column(
modifier =
Modifier.weight(
1 -
(it.properties?.cardProperty?.columnWeight
?: DEFAULT_COLUMN_WEIGHT)
)
.align(Alignment.Bottom),
horizontalAlignment = Alignment.End,
) {
NaviImage(
imageFieldData = it.icon,
modifier =
Modifier.setPadding(it.properties?.cardIconProperty?.padding),
)
}
}
}
}
}
}
}

View File

@@ -15,17 +15,21 @@ import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
import androidx.compose.runtime.Composable
import androidx.compose.runtime.MutableState
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.unit.dp
import com.navi.amc.utils.Constant.GOAL_BASED_SIP_SETUP_CARD
import com.navi.base.model.ActionData
import com.navi.base.model.CtaData
import com.navi.base.model.GenericAnalytics
import com.navi.design.theme.FFF6D5
import com.navi.design.theme.FFF9E0
import com.navi.naviwidgets.extensions.NaviImage
import com.navi.naviwidgets.extensions.NaviTextWidgetized
import com.navi.naviwidgets.models.FooterButtonState
import com.navi.rr.utils.composeutils.brushType
import com.navi.uitron.utils.setPadding
import com.naviapp.R
@@ -43,6 +47,9 @@ fun TopInvestingFundsWidgetComposable(
investmentsTabVm: InvestmentsVm,
onClick: (actionData: ActionData?) -> Unit,
onVisible: (genericAnalytics: GenericAnalytics?) -> Unit,
onHopperStart: (ctaData: CtaData, buttonState: MutableState<FooterButtonState>) -> Unit =
{ _, _ ->
},
) {
widget?.widgetData?.let { widgetData ->
Column(
@@ -64,7 +71,7 @@ fun TopInvestingFundsWidgetComposable(
widgetData.header.let { headerData ->
Row(
modifier = Modifier.fillMaxWidth().setPadding(headerData?.property?.padding),
verticalAlignment = Alignment.Top,
verticalAlignment = Alignment.CenterVertically,
) {
Column(
modifier =
@@ -118,8 +125,7 @@ fun TopInvestingFundsWidgetComposable(
Spacer(
modifier =
Modifier.height(
widgetData.topInvestingFundsContent.fundCards
.get(0)
widgetData.topInvestingFundsContent.fundCards[0]
.property
?.margin
?.top
@@ -142,6 +148,34 @@ fun TopInvestingFundsWidgetComposable(
investmentsTabVm = investmentsTabVm,
)
}
if (widgetData.topInvestingFundsContent?.goalCards?.isNotEmpty() == true) {
Spacer(
modifier =
Modifier.height(
widgetData.topInvestingFundsContent.goalCards[0]
.properties
?.cardProperty
?.margin
?.top
?.dp ?: R.integer.value_24.dp
)
)
}
widgetData.topInvestingFundsContent?.goalCards?.let { list ->
CardListComposable(
cardType = GOAL_BASED_SIP_SETUP_CARD,
cardWidthFactor =
(widgetData.extraData?.extraProperties?.cardWidthFactor
?: DEFAULT_CARD_WIDTH_FACTOR),
cardList = list,
onClick = onClick,
onVisible = onVisible,
investmentsTabVm = investmentsTabVm,
onHopperStart = onHopperStart,
)
}
}
}
}

View File

@@ -27,6 +27,7 @@ import com.navi.base.cache.repository.NaviCacheRepositoryImpl
import com.navi.base.cache.util.NaviSharedDbKeys
import com.navi.base.model.ActionData
import com.navi.base.model.CtaData
import com.navi.base.model.LineItem
import com.navi.base.sharedpref.PreferenceManager
import com.navi.base.utils.isNotNull
import com.navi.base.utils.orFalse
@@ -390,14 +391,15 @@ constructor(
return bottomSheetDataFromType[bottomSheetType]
}
fun getDynamicCTA(context: String?) {
fun getDynamicCTA(context: String?, parameters: List<LineItem>) {
viewModelScope.safeLaunch(Dispatchers.IO) {
val metricInfo =
MetricInfo.AMCMetric<ActionData>(
screen = INVESTMENT_TAB_SCREEN_V3,
isNae = { !(it.errors.isNullOrEmpty() && it.error == null) },
)
val response = investmentsTabRepository.getDynamicCTA(context, metricInfo = metricInfo)
val response =
investmentsTabRepository.getDynamicCTA(context, parameters, metricInfo = metricInfo)
if (response.error == null && response.errors.isNullOrEmpty()) {
response.data?.let { _dynamicCta.emit(it.toCtaData()) }
} else {

View File

@@ -196,6 +196,7 @@ object Constants {
const val SIP_AUTOPAY_NUDGE_CARD = "sipAutopayNudgeCard"
const val SIP_AUTOPAY_NUDGE_CARD_V2 = "sipAutopayNudgeCardV2"
const val MONTHLY_INVESTMENT_GOAL_CARD = "monthlyInvestmentGoalCard"
const val SETUP_MONTHLY_INVESTMENT_GOAL_CARD = "setupMonthlyInvestmentGoalCard"
const val DEFAULT_CARD_WIDTH_FACTOR = 0.92f
const val FUND_CARD = "fundCard"
const val FUND_BOX_CARD = "fundBoxCard"