TP-73090 TP-73092 | Nominee details page changes (#11770)

This commit is contained in:
Kshitij Pramod Ghongadi
2024-08-09 16:31:30 +05:30
committed by GitHub
parent 5114dce317
commit ef1b830fe1
8 changed files with 383 additions and 67 deletions

View File

@@ -12,6 +12,7 @@ import com.navi.naviwidgets.models.response.TextFieldData
data class MemberDetailInputWidgetModel(
@SerializedName("dropDownDetails") val dropDownDetails: DropDownDetails? = null,
@SerializedName("radioQuestionInfo") val radioQuestionInfo: RadioInput? = null,
@SerializedName("pickerInfo") val pickerInfo: PickerTextInput? = null,
@SerializedName("subWidgetData") val subWidgetData: SubWidgetData? = null,
@SerializedName("textInputDetails") val textInputDetails: TextInputDetails? = null,
@@ -54,3 +55,14 @@ data class TextInputDetails(
@SerializedName("labelName") val labelName: TextFieldData? = null,
@SerializedName("inputText") val inputText: TextFieldData? = null
)
data class RadioInput(
@SerializedName("labelName") val labelName: TextFieldData? = null,
@SerializedName("radioOptionOne") val radioOptionYes: RadioOption? = null,
@SerializedName("radioOptionTwo") val radioOptionNo: RadioOption? = null
) {
data class RadioOption(
@SerializedName("labelName") val labelName: TextFieldData? = null,
@SerializedName("id") val id: String? = null
)
}

View File

@@ -63,7 +63,8 @@ data class OptionsData(
@SerializedName("gender") val gender: String? = null,
@SerializedName("isDefaultSelected", alternate = ["defaultSelected"])
val isDefaultSelected: Boolean? = null,
@SerializedName("imageUrl") val imageUrl: String? = null
@SerializedName("imageUrl") val imageUrl: String? = null,
@SerializedName("showDependentWidget") val showDependentWidget: Boolean? = null
)
data class NumberPickerData(

View File

@@ -28,6 +28,7 @@ import com.navi.base.model.AnalyticsEvent
import com.navi.base.model.CtaData
import com.navi.base.model.CtaType
import com.navi.base.model.LineItem
import com.navi.base.utils.isNotNull
import com.navi.base.utils.isNull
import com.navi.base.utils.orFalse
import com.navi.common.ResponseState
@@ -102,6 +103,7 @@ class PostPurchaseFormBasedFragment : GiBaseFragment(), ActionHandler.ActionOwne
private var pageType: String? = null
private var requestPageType: String? = null
private var footerData: NaviWidgetData? = null
private var footerLoaderEnabled: Boolean = false
private var nextTransitionName: String? = null
private var previousTransitionName: String? = null
@@ -237,19 +239,18 @@ class PostPurchaseFormBasedFragment : GiBaseFragment(), ActionHandler.ActionOwne
(footerBinding?.root as? BaseNaviWidgetView)?.showErrorView(
error = formNextPageState.errorData
)
binding.progressBar.isVisible = false
hideLoader(footerLoaderEnabled)
binding.formList.isVisible = true
}
is FormNextPageResponseState.Error -> {
shouldHandleBackPress = false
binding.progressBar.isVisible = false
hideLoader(footerLoaderEnabled)
}
is FormNextPageResponseState.Loading -> {
binding.progressBar.isVisible = true
binding.formList.isVisible = false
showLoader(footerLoaderEnabled)
}
is FormNextPageResponseState.Success -> {
binding.progressBar.isVisible = false
hideLoader(footerLoaderEnabled)
viewModel.performActionFromCta(
formNextPageState.data?.cta,
activity as? PostPurchaseFormActivity
@@ -272,18 +273,17 @@ class PostPurchaseFormBasedFragment : GiBaseFragment(), ActionHandler.ActionOwne
when (formPreviousPageState) {
is FormPreviousPageResponseState.Failure -> {
shouldHandleBackPress = false
binding.progressBar.isVisible = false
hideLoader(footerLoaderEnabled)
}
is FormPreviousPageResponseState.Error -> {
shouldHandleBackPress = false
binding.progressBar.isVisible = false
hideLoader(footerLoaderEnabled)
}
is FormPreviousPageResponseState.Loading -> {
binding.progressBar.isVisible = true
binding.formList.isVisible = false
showLoader(footerLoaderEnabled)
}
is FormPreviousPageResponseState.Success -> {
binding.progressBar.isVisible = false
hideLoader(footerLoaderEnabled)
viewModel.performActionFromCta(
formPreviousPageState.data?.backCta,
activity as? PostPurchaseFormActivity
@@ -347,6 +347,11 @@ class PostPurchaseFormBasedFragment : GiBaseFragment(), ActionHandler.ActionOwne
formPageViewState.data?.footer?.getOrNull(0)?.widgetData?.run {
updateContainer(this, binding.footerContainer, true)
footerData = this
footerLoaderEnabled =
(footerData as? FooterWithLeftRightButtonData)
?.rightButton
?.lottieLoaderUrl
.isNotNull()
}
sendInitEvent(
formPageViewState.data?.metaData?.analyticsInitEventName,
@@ -384,6 +389,29 @@ class PostPurchaseFormBasedFragment : GiBaseFragment(), ActionHandler.ActionOwne
}
}
private fun showLoader(footerLoaderEnabled: Boolean) {
if (footerLoaderEnabled) {
toggleFooterLoader(true)
} else {
binding.progressBar.isVisible = true
binding.formList.isVisible = false
}
}
private fun hideLoader(footerLoaderEnabled: Boolean) {
if (footerLoaderEnabled) {
toggleFooterLoader(false)
} else {
binding.progressBar.isVisible = false
}
}
private fun toggleFooterLoader(isLoading: Boolean) {
(binding.footerContainer.children.firstOrNull() as? FooterWithLeftRightButtonView)
?.handleLoader(showRightButtonLoader = isLoading)
binding.root.isClickable = !isLoading
}
private val widgetCallback = { cta: CtaData ->
cta.analyticsEventProperties?.run { analyticsHandler.sendEvent(this, screenName) }
when (cta.type) {
@@ -460,7 +488,7 @@ class PostPurchaseFormBasedFragment : GiBaseFragment(), ActionHandler.ActionOwne
private fun processNext(transitionKey: String? = null) {
if (formAdapter?.isValidWidget() == true) {
binding.progressBar.isVisible = true
showLoader(footerLoaderEnabled)
viewModel.processDataForNextPageApi(
formAdapter?.getFormPageData(),
referenceId,
@@ -492,15 +520,21 @@ class PostPurchaseFormBasedFragment : GiBaseFragment(), ActionHandler.ActionOwne
// The below method will trigger for UI validations if required
// Used for overriding default footer behaviours as well
validateWidgetErrors(it)
// We don't need to validate when back button is clicked
if (
(it.type != CtaType.TRANSITION_API.value ||
getTransitionName(it) != TRANSITION_BACK) &&
it.type != CtaType.PREVIOUS_PAGE_API.value
) {
validateWidgetErrors(it)
}
when (it.type) {
CtaType.VALIDATE_FORM_PAGE.value -> {
toggleFooterState()
}
CtaType.TRANSITION_API.value -> {
val transitionName = getTransitionName(it)
if (transitionName == "BACK") {
if (transitionName == TRANSITION_BACK) {
previousTransitionName = transitionName
processPrevious(transitionKey = transitionName)
} else {
@@ -655,6 +689,7 @@ class PostPurchaseFormBasedFragment : GiBaseFragment(), ActionHandler.ActionOwne
const val TAG = "PostPurchaseFormBasedFragment"
const val PAGE_TYPE = "pageType"
const val POSITION = "position"
const val TRANSITION_BACK = "BACK"
}
override val screenName: String

View File

@@ -18,6 +18,7 @@ import android.view.ViewParent
import android.view.inputmethod.InputMethodManager
import android.widget.AdapterView
import android.widget.EditText
import android.widget.ImageView
import android.widget.ScrollView
import android.widget.TextView
import androidx.core.view.isVisible
@@ -25,6 +26,7 @@ import androidx.databinding.ViewDataBinding
import androidx.fragment.app.Fragment
import com.google.firebase.crashlytics.FirebaseCrashlytics
import com.navi.base.model.CtaData
import com.navi.base.utils.orFalse
import com.navi.common.R as CommonR
import com.navi.design.utils.hideCutCopyMenuPopUp
import com.navi.insurance.R
@@ -35,8 +37,11 @@ import com.navi.insurance.common.fragment.NaviInsuranceDatePickerHelper
import com.navi.insurance.common.listener.EmptyTextWatcher
import com.navi.insurance.common.models.DropDownData
import com.navi.insurance.common.models.MemberDetailInputWidgetModel
import com.navi.insurance.common.models.MemberDetailInputWidgetModel.SubWidgetData.AdditionalInputDetail
import com.navi.insurance.common.models.NaviWidgetData
import com.navi.insurance.common.models.OptionsData
import com.navi.insurance.common.models.PickerTextInput
import com.navi.insurance.common.models.RadioInput
import com.navi.insurance.common.widgets.FormBaseWidgetView
import com.navi.insurance.databinding.WidgetMemberDetailInputBinding
import com.navi.insurance.health.fragment.CompleteMemberDetailFormFragment
@@ -69,6 +74,8 @@ class MemberDetailInputWidget(context: Context, attrs: AttributeSet? = null) :
private val analyticsEventTracker = NaviInsuranceAnalytics.instance.CompleteMemberDetailForm()
private val screenName = InsuranceAnalyticsConstants.POLICY_CREATION_FORM_SCREEN
private var applicationType = EMPTY
// To check if the age radio type question has been answered
private var isRadioOptionSelected = false
override fun updateLayout(
binding: ViewDataBinding?,
@@ -101,25 +108,45 @@ class MemberDetailInputWidget(context: Context, attrs: AttributeSet? = null) :
policyDetailsNomineeLabelRelationship.setTextFieldData(
it.dropDownDetails?.labelName
)
// To set relationship data in the spinner
setRelationshipData(
policyDetailsNomineeRelationship,
relationshipSelectErrorTv,
(it.dropDownDetails?.dropDownInfo?.data as? DropDownData)?.options
)
policyDetailsNomineeLabelDob.setTextFieldData(it.pickerInfo?.labelName)
policyDetailsNomineeInputDob.hideCutCopyMenuPopUp()
policyDetailsNomineeInputDob.setTextFieldHintData(it.pickerInfo?.hint)
policyDetailsNomineeInputDob.setText(
formatDate(it.pickerInfo?.inputText?.text, YYYY_MM_DD, DD_MM_YYYY)
)
stringToDate(it.pickerInfo?.inputText?.text, YYYY_MM_DD)?.let { date ->
toggleAppointeeView(date)
) { selectedOption ->
// To show/hide age radio widget based on the selected relationship
toggleAgeRadioWidgetView(selectedOption?.showDependentWidget.orFalse())
}
setDatePickerFor(
policyDetailsNomineeInputDob,
policyDetailsNomineeLabelDobVerify
) { date ->
toggleAppointeeView(date)
// To show/hide DOB question based on pickInfo present in the response
updateDobView(it.pickerInfo)
}
}
}
private fun updateDobView(pickerInfo: PickerTextInput?) {
val isVisible = pickerInfo != null
binding.run {
policyDetailsNomineeLabelDob.visibility = if (isVisible) VISIBLE else GONE
policyDetailsNomineeInputDob.visibility = if (isVisible) VISIBLE else GONE
policyDetailsNomineeLabelDobVerify.visibility = if (isVisible) VISIBLE else GONE
if (isVisible) {
pickerInfo?.let {
policyDetailsNomineeLabelDob.setTextFieldData(it.labelName)
policyDetailsNomineeInputDob.hideCutCopyMenuPopUp()
policyDetailsNomineeInputDob.setTextFieldHintData(it.hint)
policyDetailsNomineeInputDob.setText(
formatDate(it.inputText?.text, YYYY_MM_DD, DD_MM_YYYY)
)
stringToDate(it.inputText?.text, YYYY_MM_DD)?.let { date ->
toggleAppointeeView(date)
}
setDatePickerFor(
policyDetailsNomineeInputDob,
policyDetailsNomineeLabelDobVerify
) { date ->
toggleAppointeeView(date)
}
}
}
}
@@ -137,6 +164,51 @@ class MemberDetailInputWidget(context: Context, attrs: AttributeSet? = null) :
}
}
private fun toggleAgeRadioWidgetView(isVisible: Boolean) {
// Ensure the appointee view is initially toggled off
toggleAppointeeView(false)
// Determine the visibility state
val visibility = if (isVisible) VISIBLE else GONE
// Update the visibility of the age-related UI elements
binding.policyDetailsNomineeLabelAge.visibility = visibility
binding.policyDetailsNomineeAgeRadioYes.visibility = visibility
binding.policyDetailsNomineeAgeRadioNo.visibility = visibility
binding.ageErrorTv.visibility = GONE
if (isVisible) {
memberDetailInputWidgetModel?.radioQuestionInfo?.let { radioQuestionInfo ->
// Set the text for the age label
binding.policyDetailsNomineeLabelAge.setTextFieldData(radioQuestionInfo.labelName)
// Set the radio options data and handle selection callback
setRadioOptionsData(
binding.policyDetailsNomineeAgeRadioYes,
binding.policyDetailsNomineeAgeRadioNo,
binding.ageErrorTv,
radioQuestionInfo.radioOptionYes,
radioQuestionInfo.radioOptionNo
) { selectedRadioOption ->
// Determine if the selected option indicates the nominee is above 18
val isNomineeAgeAbove18 = selectedRadioOption.id == RADIO_OPTION_YES
// Toggle the appointee view based on the selected option
toggleAppointeeView(!isNomineeAgeAbove18)
}
}
}
}
private fun toggleAppointeeView(isVisible: Boolean) {
if (isVisible && memberDetailInputWidgetModel?.widgetKey == TYPE_NOMINEE) { // 18 years
binding.appointeeView.visibility = VISIBLE
} else {
formAppointeeRequestPayload.clear()
binding.appointeeView.visibility = GONE
}
}
private fun setAppointeeUI() {
binding.run {
memberDetailInputWidgetModel?.subWidgetData?.let {
@@ -163,12 +235,25 @@ class MemberDetailInputWidget(context: Context, attrs: AttributeSet? = null) :
policyDetailsAppointeeInputDob.setText(
formatDate(it.pickerTextInput?.inputText?.text, YYYY_MM_DD, DD_MM_YYYY)
)
policyDetailsAppointeeLabelPhone.setTextFieldData(
it.additionalInputDetails?.labelName
)
policyDetailsAppointeePhone.hideCutCopyMenuPopUp()
policyDetailsAppointeePhone.setTextFieldHintData(it.additionalInputDetails?.hint)
policyDetailsAppointeePhone.setTextFieldData(it.additionalInputDetails?.inputText)
if (it.additionalInputDetails == null) {
policyDetailsAppointeeLabelPhone.visibility = GONE
policyDetailsAppointeePhone.visibility = GONE
} else {
policyDetailsAppointeeLabelPhone.visibility = VISIBLE
policyDetailsAppointeePhone.visibility = VISIBLE
updateAppointeePhoneDetails(it.additionalInputDetails)
}
}
}
}
private fun updateAppointeePhoneDetails(details: AdditionalInputDetail) {
binding.run {
policyDetailsAppointeeLabelPhone.setTextFieldData(details.labelName)
policyDetailsAppointeePhone.apply {
hideCutCopyMenuPopUp()
setTextFieldHintData(details.hint)
setTextFieldData(details.inputText)
}
}
}
@@ -184,7 +269,8 @@ class MemberDetailInputWidget(context: Context, attrs: AttributeSet? = null) :
private fun setRelationshipData(
customSpinner: CustomSpinner,
errorTextView: TextView,
options: List<OptionsData?>?
options: List<OptionsData?>?,
onItemSelected: (OptionsData?) -> Unit = {}
) {
var selectedItemPosition = -1
val dataList: Array<OptionsData> =
@@ -205,7 +291,9 @@ class MemberDetailInputWidget(context: Context, attrs: AttributeSet? = null) :
customSpinner.onItemSelectedListener =
object : AdapterView.OnItemSelectedListener {
override fun onNothingSelected(parent: AdapterView<*>?) {}
override fun onNothingSelected(parent: AdapterView<*>?) {
onItemSelected(null)
}
override fun onItemSelected(
parent: AdapterView<*>?,
@@ -223,6 +311,9 @@ class MemberDetailInputWidget(context: Context, attrs: AttributeSet? = null) :
)
if (position < dataList.size) {
customSpinner.tag = dataList[position].id
onItemSelected(dataList[position])
} else {
onItemSelected(null)
}
errorTextView.visibility =
if (
@@ -236,6 +327,73 @@ class MemberDetailInputWidget(context: Context, attrs: AttributeSet? = null) :
}
}
private fun setRadioOptionsData(
optionOne: View,
optionTwo: View,
errorTextView: TextView,
radioOptionOne: RadioInput.RadioOption?,
radioOptionTwo: RadioInput.RadioOption?,
callback: (selectedOption: RadioInput.RadioOption) -> Unit = {}
) {
// Reset the radio button selection state
isRadioOptionSelected = false
setRadioButtonState(
binding.policyDetailsNomineeAgeRadioBtnYes,
binding.policyDetailsNomineeAgeRadioBtnNo,
isSelected = false
)
// Set the text for radio options
binding.policyDetailsNomineeAgeRadioBtnTxtYes.setTextFieldData(radioOptionOne?.labelName)
binding.policyDetailsNomineeAgeRadioBtnTxtNo.setTextFieldData(radioOptionTwo?.labelName)
// Configure click listeners for radio options
optionOne.setOnClickListener {
handleRadioOptionClick(
selectedOptionView = binding.policyDetailsNomineeAgeRadioBtnYes,
otherOptionView = binding.policyDetailsNomineeAgeRadioBtnNo,
errorTextView = errorTextView,
callback = callback,
selectedOption = radioOptionOne
)
}
optionTwo.setOnClickListener {
handleRadioOptionClick(
selectedOptionView = binding.policyDetailsNomineeAgeRadioBtnNo,
otherOptionView = binding.policyDetailsNomineeAgeRadioBtnYes,
errorTextView = errorTextView,
callback = callback,
selectedOption = radioOptionTwo
)
}
}
private fun setRadioButtonState(
selectedView: ImageView,
unselectedView: ImageView,
isSelected: Boolean
) {
selectedView.setImageResource(
if (isSelected) com.navi.naviwidgets.R.drawable.radio_button_checked_blue
else com.navi.naviwidgets.R.drawable.radio_button_unchecked_grey
)
unselectedView.setImageResource(com.navi.naviwidgets.R.drawable.radio_button_unchecked_grey)
}
private fun handleRadioOptionClick(
selectedOptionView: ImageView,
otherOptionView: ImageView,
errorTextView: TextView,
callback: (selectedOption: RadioInput.RadioOption) -> Unit,
selectedOption: RadioInput.RadioOption?
) {
if (selectedOption == null) return
errorTextView.visibility = GONE
isRadioOptionSelected = true
setRadioButtonState(selectedOptionView, otherOptionView, isSelected = true)
callback(selectedOption)
}
private fun addNomineeDetailsTextWatcher() {
binding.policyDetailsNomineeInputFullName.addTextChangedListener(
EmptyTextWatcher(binding.nameErrorTv)
@@ -391,7 +549,8 @@ class MemberDetailInputWidget(context: Context, attrs: AttributeSet? = null) :
hideKeyboard()
validateNomineeName(name)
validateNomineeRelation(relation)
validateNomineeDob(dob)
memberDetailInputWidgetModel?.radioQuestionInfo?.let { validateNomineeAgeSelection() }
memberDetailInputWidgetModel?.pickerInfo?.let { validateNomineeDob(dob) }
validateAppointeeView()
if (isValid) {
onValid()
@@ -414,14 +573,16 @@ class MemberDetailInputWidget(context: Context, attrs: AttributeSet? = null) :
formNomineeRequestPayload =
mutableMapOf<String, String>().apply {
put(KEY_NAME, binding.policyDetailsNomineeInputFullName.text.toString().trim())
put(
KEY_DOB,
sdf.format(
displayDateFormat.parse(
binding.policyDetailsNomineeInputDob.text.toString()
memberDetailInputWidgetModel?.pickerInfo?.let {
put(
KEY_DOB,
sdf.format(
displayDateFormat.parse(
binding.policyDetailsNomineeInputDob.text.toString()
)
)
)
)
}
(binding.policyDetailsNomineeRelationship.tag as? String)?.let {
when (memberDetailInputWidgetModel?.widgetKey) {
TYPE_NOMINEE -> put(KEY_RELATION, it)
@@ -450,7 +611,9 @@ class MemberDetailInputWidget(context: Context, attrs: AttributeSet? = null) :
(binding.policyDetailsAppointeeRelationship.tag as? String)?.let {
put(KEY_RELATION, it)
}
put(KEY_PHONE, binding.policyDetailsAppointeePhone.text.toString().trim())
memberDetailInputWidgetModel?.subWidgetData?.additionalInputDetails?.let {
put(KEY_PHONE, binding.policyDetailsAppointeePhone.text.toString().trim())
}
}
}
}
@@ -465,7 +628,9 @@ class MemberDetailInputWidget(context: Context, attrs: AttributeSet? = null) :
validateAppointeeName(name)
validateAppointeeRelation(relation)
validateAppointeeDob(dob)
validateAppointeePhone(phone)
memberDetailInputWidgetModel?.subWidgetData?.additionalInputDetails?.let {
validateAppointeePhone(phone)
}
}
}
@@ -647,6 +812,17 @@ class MemberDetailInputWidget(context: Context, attrs: AttributeSet? = null) :
}
}
private fun validateNomineeAgeSelection() {
val isAgeVisible = binding.policyDetailsNomineeLabelAge.isVisible
val isValidSelection = !isAgeVisible || isRadioOptionSelected
isValid = isValid && isValidSelection
if (!isValidSelection) {
showAgeError()
}
}
private fun validateNomineeRelation(relation: String) {
isValid =
isValid &&
@@ -709,6 +885,17 @@ class MemberDetailInputWidget(context: Context, attrs: AttributeSet? = null) :
}
}
private fun showAgeError() {
binding.ageErrorTv.apply {
visibility = VISIBLE
text = context.getString(R.string.error_select_age_option)
}
bringAttentionOnErrorView(
binding.policyDetailsNomineeAgeRadioGrp,
binding.layoutPolicyNomineeView
)
}
private fun stringToDate(date: String?, format: String): Date? {
return try {
val simpleDateFormat = SimpleDateFormat(format)
@@ -785,5 +972,7 @@ class MemberDetailInputWidget(context: Context, attrs: AttributeSet? = null) :
const val TYPE_SELF = "owner_details"
const val TYPE_NOMINEE = "nominee_detail"
const val RADIO_OPTION_YES = "YES"
}
}

View File

@@ -69,7 +69,7 @@
android:orientation="vertical"
android:paddingTop="@dimen/dp_8"
android:translationY="@dimen/dp_1"
android:visibility="visible"
android:visibility="gone"
app:layout_constraintTop_toBottomOf="@id/error_view"
app:layout_constraintBottom_toTopOf="@id/progressBar"
tools:visibility="visible">

View File

@@ -15,15 +15,7 @@
android:orientation="vertical">
<LinearLayout
android:id="@+id/layout_policy_nominee"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:animateLayoutChanges="true"
android:focusable="true"
android:gravity="center_horizontal|top"
android:orientation="vertical">
<LinearLayout
android:id="@+id/layout_policy_nominee"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="6dp"
@@ -36,12 +28,6 @@
android:paddingRight="20dp"
android:paddingBottom="20dp">
<View
android:layout_width="32dp"
android:layout_height="1dp"
android:layout_marginTop="24dp"
android:background="#dfdfdf" />
<com.navi.design.textview.NaviTextView
android:id="@+id/policy_details_nominee_name"
@@ -82,7 +68,7 @@
android:importantForAutofill="no"
android:inputType="textPersonName|textCapWords|textFilter|textVisiblePassword"
android:maxLines="1"
android:minWidth="140dp"
android:minWidth="280dp"
android:textSize="16sp" />
<com.navi.design.textview.NaviTextView
@@ -133,6 +119,99 @@
tools:text="Please enter gender"
android:visibility="gone" />
<com.navi.design.textview.NaviTextView
android:id="@+id/policy_details_nominee_label_age"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="start"
android:layout_marginTop="40dp"
android:clipToPadding="false"
android:fontFamily="@font/tt_regular"
android:gravity="start"
tools:text="Is nominees age more than 18?"
android:textColor="#4D4D4D"
android:textSize="14sp" />
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/policy_details_nominee_age_radio_grp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dp_6">
<!-- Yes option -->
<LinearLayout
android:id="@+id/policy_details_nominee_age_radio_yes"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:orientation="horizontal"
android:clickable="true"
android:focusable="true"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent">
<ImageView
android:id="@+id/policy_details_nominee_age_radio_btn_yes"
android:layout_width="@dimen/layout_dp_14"
android:layout_height="@dimen/layout_dp_14"
android:src="@drawable/radio_button_unchecked_grey" />
<com.navi.design.textview.NaviTextView
android:id="@+id/policy_details_nominee_age_radio_btn_txt_yes"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="@font/tt_medium"
android:layout_marginStart="@dimen/dp_8"
android:textColor="#191919"
android:textSize="14sp"
android:gravity="center_vertical"
tools:text="Yes" />
</LinearLayout>
<!-- No option -->
<LinearLayout
android:id="@+id/policy_details_nominee_age_radio_no"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/dp_24"
android:gravity="center_vertical"
android:orientation="horizontal"
android:clickable="true"
android:focusable="true"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toEndOf="@id/policy_details_nominee_age_radio_yes">
<ImageView
android:id="@+id/policy_details_nominee_age_radio_btn_no"
android:layout_width="@dimen/layout_dp_14"
android:layout_height="@dimen/layout_dp_14"
android:src="@drawable/radio_button_unchecked_grey" />
<com.navi.design.textview.NaviTextView
android:id="@+id/policy_details_nominee_age_radio_btn_txt_no"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="@font/tt_medium"
android:layout_marginStart="@dimen/dp_8"
android:textColor="#191919"
android:textSize="14sp"
android:gravity="center_vertical"
tools:text="No" />
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
<com.navi.design.textview.NaviTextView
android:id="@+id/age_error_tv"
style="@style/ErrorTextFontStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="start"
android:clipToPadding="false"
tools:text="Please select nominee's age"
android:visibility="gone" />
<com.navi.design.textview.NaviTextView
android:id="@+id/policy_details_nominee_label_dob"
@@ -147,6 +226,7 @@
android:textColor="#4D4D4D"
android:textSize="14sp" />
<EditText
android:id="@+id/policy_details_nominee_input_dob"
android:layout_width="wrap_content"
@@ -163,7 +243,6 @@
android:maxLines="1"
android:minWidth="140dp"
android:textSize="16sp" />
<com.navi.design.textview.NaviTextView
android:id="@+id/dob_error_tv"
@@ -255,7 +334,7 @@
android:importantForAutofill="no"
android:inputType="textPersonName|textCapWords|textFilter|textVisiblePassword"
android:maxLines="1"
android:minWidth="140dp"
android:minWidth="280dp"
android:textSize="16sp" />
<com.navi.design.textview.NaviTextView
@@ -407,7 +486,6 @@
</LinearLayout>
</LinearLayout>
</LinearLayout>
</ScrollView>
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>

View File

@@ -481,6 +481,7 @@ I highly recommend Navi Health policy because of its comprehensive benefits with
<string name="error_enter_appointee_full_name">Please enter appointee\'s full name</string>
<string name="error_please_enter_nominee_relationship">Please enter nominee\'s relationship with you</string>
<string name="error_enter_nominee_dob">Please enter nominee\'s date of birth</string>
<string name="error_select_age_option">Please select an option</string>
<string name="error_enter_relationship_with_nominee">Please enter appointee\'s relationship with nominee</string>
<string name="error_enter_appointee_dob">Please enter appointee\'s date of birth</string>
<string name="error_appointee_min_age">Appointee should be at-least 18 years old</string>

View File

@@ -453,7 +453,7 @@ fun TextView.setTextFieldData(
data.cta?.let {
if (ctaCallback != null) {
addOnMultipleClicksHandler { ctaCallback?.invoke(data.cta) }
}
} else setOnClickListener(null)
}
}
}