NTP-69896 | Price Quote Journey V2 | Analytics Instrumentation (#16491)

This commit is contained in:
Kshitij Pramod Ghongadi
2025-06-06 19:12:41 +05:30
committed by GitHub
parent b3bf9ab3af
commit 5bbe380ac2
8 changed files with 62 additions and 46 deletions

View File

@@ -639,11 +639,15 @@ object InsuranceAnalyticsConstants {
const val OTP_CAPTCHA_SCREEN = "otp_captcha"
// Pre Quote Journey Revamp
const val SELECTED_GENDER = "selected_gender"
const val GENDER = "gender"
const val MEMBER_SELECTED = "member_selected"
const val MEMBER_TYPE = "member_type"
const val MEMBER_COUNT = "member_count"
const val MEMBER_AGE = "member_age"
const val CURRENT_PINCODE = "current_pincode"
const val HI_MD_LOCATE_ME_CLICK = "hi_md_locate_me_click"
const val HI_MD_PINCODE_CLEAR_CLICK = "hi_md_pincode_clear_click"
const val HI_MD_PINCODE_INPUT_CHANGED = "hi_md_pincode_input_changed"
// New Renewal Flow
const val RENEWAL_SCREEN = "new_renewal_screen"

View File

@@ -25,6 +25,9 @@ import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import com.navi.analytics.utils.NaviTrackEvent
import com.navi.common.utils.addKeyIfMissing
import com.navi.insurance.analytics.InsuranceAnalyticsConstants.MEMBER_COUNT
import com.navi.insurance.pre.purchase.journey.composables.reusable.CustomCheckBox
import com.navi.insurance.pre.purchase.journey.theme.LocalDimensions
import com.navi.naviwidgets.callbacks.WidgetCallback
@@ -146,6 +149,19 @@ fun MemberGridItem(
MemberCounter(
countData = itemData.countData,
onCountChanged = { updatedCountData ->
updatedCountData.analyticsEventProperties?.run {
name?.let { eventName ->
NaviTrackEvent.trackEvent(
eventName = eventName,
eventValues =
properties?.addKeyIfMissing(
MEMBER_COUNT,
updatedCountData.selectedCount
.toString(),
),
)
}
}
if (updatedCountData.selectedCount == 0) {
onItemSelected(itemData.copy(isSelected = false))
} else {

View File

@@ -31,10 +31,9 @@ import com.navi.common.utils.addKeyIfMissing
import com.navi.common.utils.addKeyIfMissingConditionally
import com.navi.design.decorator.DashedDivider
import com.navi.elex.font.FontWeightEnum
import com.navi.insurance.analytics.InsuranceAnalyticsConstants.GENDER
import com.navi.insurance.analytics.InsuranceAnalyticsConstants.MEMBER_COUNT
import com.navi.insurance.analytics.InsuranceAnalyticsConstants.MEMBER_SELECTED
import com.navi.insurance.analytics.InsuranceAnalyticsConstants.MEMBER_TYPE
import com.navi.insurance.analytics.InsuranceAnalyticsConstants.SELECTED_GENDER
import com.navi.insurance.pre.purchase.journey.PreQuotePageData
import com.navi.insurance.pre.purchase.journey.PreQuotePatchData
import com.navi.insurance.pre.purchase.journey.WidgetKey
@@ -131,20 +130,16 @@ fun MemberSelectionWidgetComposable(
selectedGender ?: "MALE",
)
)
genderData.analyticsEventProperties?.name?.let {
eventName ->
NaviTrackEvent.trackEvent(
eventName = eventName,
eventValues =
data.genderData
?.analyticsEventProperties
?.properties
.addKeyIfMissing(
SELECTED_GENDER,
selectedGender ?: "MALE",
),
)
}
genderItems[selectedGenderIndex]
.analyticsEventProperties
?.run {
name?.let { eventName ->
NaviTrackEvent.trackEvent(
eventName = eventName,
eventValues = properties,
)
}
}
}
},
)
@@ -233,7 +228,6 @@ fun MemberSelectionWidgetComposable(
memberItems = updatedItems
checkWidgetValidity(updatedItems)
// Update patch data with the selection
val selectedGender =
genderItems.find { it.isSelected }?.id ?: "MALE"
updatePatchCallData(
@@ -242,33 +236,30 @@ fun MemberSelectionWidgetComposable(
selectedGender,
)
)
updatedItem.analyticsEventProperties?.name?.let { eventName
->
val item = updatedItems[index]
item.analyticsEventProperties?.name?.let { eventName ->
NaviTrackEvent.trackEvent(
eventName = eventName,
eventValues =
updatedItem.analyticsEventProperties
item.analyticsEventProperties
?.properties
.addKeyIfMissing(
MEMBER_SELECTED,
updatedItem.isSelected.toString(),
)
.addKeyIfMissing(
MEMBER_TYPE,
updatedItem.title?.text.orEmpty(),
item.isSelected.toString(),
)
.addKeyIfMissingConditionally(
MEMBER_COUNT,
updatedItem.countData
item.countData
?.selectedCount
.toString(),
updatedItem.dropdownType ==
item.dropdownType ==
DropdownType.COUNTER,
)
.addKeyIfMissingConditionally(
SELECTED_GENDER,
GENDER,
selectedGender,
updatedItem.id == "SELF",
item.id == "SELF",
),
)
}

View File

@@ -33,7 +33,10 @@ import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.input.KeyboardType
import androidx.lifecycle.ViewModel
import com.navi.analytics.utils.NaviTrackEvent
import com.navi.common.ResponseState
import com.navi.insurance.analytics.InsuranceAnalyticsConstants
import com.navi.insurance.analytics.InsuranceAnalyticsConstants.CURRENT_PINCODE
import com.navi.insurance.location.NaviLocationManager
import com.navi.insurance.pre.purchase.journey.PreQuotePatchData
import com.navi.insurance.pre.purchase.journey.WidgetKey
@@ -74,7 +77,6 @@ fun PincodeInputWidgetV2Composable(
val focusManager = LocalFocusManager.current
val context = LocalContext.current
// Create a dedicated location handler for "Locate Me" button
val locationHandler = remember {
LocationHandler(
context = context,
@@ -85,18 +87,15 @@ fun PincodeInputWidgetV2Composable(
)
}
// Set up the pincode callback for the dedicated handler
locationHandler.pincodeCallback = { newPincode ->
pincode = newPincode
(viewModel as? PreQuoteJourneyViewModel)?.fetchAddressUsingPinCode(newPincode)
}
// Set up the permission denied callback
locationHandler.onPermissionDenied = {
data.widgetData?.settingsCta?.let { cta -> widgetCallback?.onClick(cta) }
}
// Permission launcher specifically for "Locate Me" button
val locatePermissionLauncher =
rememberLauncherForActivityResult(
contract = ActivityResultContracts.RequestMultiplePermissions()
@@ -106,7 +105,6 @@ fun PincodeInputWidgetV2Composable(
permissions[Manifest.permission.ACCESS_COARSE_LOCATION] ?: false
val isPermissionGranted = fineLocationGranted || coarseLocationGranted
// Handle permission result
locationHandler.handlePermissionResult(isPermissionGranted)
}
@@ -242,17 +240,22 @@ fun PincodeInputWidgetV2Composable(
data = data,
isValidWidget = isValidWidget,
)
NaviTrackEvent.trackEvent(
eventName =
InsuranceAnalyticsConstants.HI_MD_PINCODE_INPUT_CHANGED,
eventValues = mapOf(CURRENT_PINCODE to value),
)
},
onLocateMeClick = {
NaviTrackEvent.trackEvent(
eventName = InsuranceAnalyticsConstants.HI_MD_LOCATE_ME_CLICK
)
val isPermissionGranted =
LocationPermissionUtils.isLocationPermissionGranted(context)
if (isPermissionGranted) {
// Permission already granted, fetch location directly
locationHandler.fetchLocation()
} else {
// Request permission using our dedicated launcher
// Mark this as a user-triggered request
locationHandler.prepareForPermissionRequest(true)
locatePermissionLauncher.launch(
LocationPermissionUtils.getLocationPermissions()
@@ -260,6 +263,11 @@ fun PincodeInputWidgetV2Composable(
}
},
onClearClick = {
NaviTrackEvent.trackEvent(
eventName =
InsuranceAnalyticsConstants.HI_MD_PINCODE_CLEAR_CLICK,
eventValues = mapOf(CURRENT_PINCODE to pincode),
)
pincode = ""
preQuoteViewModel?.resetFieldValidationState()
updateAndValidatePincode(

View File

@@ -40,7 +40,6 @@ import com.navi.base.utils.orFalse
import com.navi.common.utils.addKeyIfMissing
import com.navi.elex.font.FontWeightEnum
import com.navi.insurance.analytics.InsuranceAnalyticsConstants.MEMBER_AGE
import com.navi.insurance.analytics.InsuranceAnalyticsConstants.MEMBER_TYPE
import com.navi.insurance.pre.purchase.journey.PreQuotePageData
import com.navi.insurance.pre.purchase.journey.PreQuotePatchData
import com.navi.insurance.pre.purchase.journey.WidgetKey
@@ -254,10 +253,6 @@ fun AgeSelectorComposable(
eventValues =
item.analyticsEventProperties
?.properties
.addKeyIfMissing(
MEMBER_TYPE,
item.selectionItemTitle?.text.orEmpty(),
)
.addKeyIfMissing(
MEMBER_AGE,
item.selectionItemDetails?.text.orEmpty(),

View File

@@ -72,8 +72,8 @@ fun FooterWithCardAndSnackBarWidgetComposable(
FooterCardComposable(
data =
if (state == FooterButtonState.ERROR.name)
data.footerWithCardAndSnackbarWidgetBody.errorCardInfo
else data.footerWithCardAndSnackbarWidgetBody.cardInfo,
data.footerWithCardAndSnackbarWidgetBody?.errorCardInfo
else data.footerWithCardAndSnackbarWidgetBody?.cardInfo,
widgetCallback = widgetCallback,
)
}

View File

@@ -8,6 +8,7 @@
package com.navi.naviwidgets.models
import com.google.gson.annotations.SerializedName
import com.navi.base.model.AnalyticsEvent
import com.navi.base.model.CtaData
import com.navi.naviwidgets.interfaces.GenericWidgetInfo
import com.navi.naviwidgets.models.response.ImageFieldData
@@ -97,4 +98,5 @@ data class CounterDropDownData(
@SerializedName("selectedCount") val selectedCount: Int? = null,
@SerializedName("minCount") val minCount: Int? = null,
@SerializedName("maxCount") val maxCount: Int? = null,
@SerializedName("analyticsEventProperties") val analyticsEventProperties: AnalyticsEvent? = null,
)

View File

@@ -36,7 +36,6 @@ data class MemberSelectionWidgetBody(
val itemList: List<MemberSelectionItemData>? = null,
) {
data class GenderSelectionData(
val analyticsEventProperties: AnalyticsEvent? = null,
val title: TextFieldData? = null,
val items: List<SelectionItemData>? = null,
) {
@@ -44,6 +43,7 @@ data class MemberSelectionWidgetBody(
val id: String? = null,
val title: TextFieldData? = null,
val isSelected: Boolean = false,
val analyticsEventProperties: AnalyticsEvent? = null,
)
}