TP-62951 | Saksham Mahajan | Amc stop sip (#10315)

Co-authored-by: saksham <saksham>
This commit is contained in:
Saksham Mahajan
2024-04-09 20:54:02 +05:30
committed by GitHub
parent 0d91916d38
commit aeadacfc61
15 changed files with 345 additions and 25 deletions

View File

@@ -22,4 +22,12 @@ data class Footer(
@SerializedName("backCta") var backCta: ActionData? = null,
@SerializedName("progress") var progress: Int? = null,
@SerializedName("note") var note: DataSafeWidget? = null,
@SerializedName("footerCallout") var footerCallout: FooterCallout? = null
) : Parcelable
@Parcelize
data class FooterCallout(
@SerializedName("title") var title: TextWithStyle? = null,
@SerializedName("subTitle", alternate = ["subtitle"]) var subTitle: TextWithStyle? = null,
@SerializedName("iconCode") var iconCode: String? = null,
) : Parcelable

View File

@@ -25,6 +25,7 @@ import com.navi.base.model.ActionData
import com.navi.design.utils.parseColorSafe
import com.navi.design.utils.setSpannableString
import com.navi.naviwidgets.extensions.setGradient
import com.navi.naviwidgets.extensions.showWhenDataIsAvailable
class FooterView(context: Context, attrs: AttributeSet?) : ConstraintLayout(context, attrs) {
private var binding: FooterLayoutBinding
@@ -95,6 +96,18 @@ class FooterView(context: Context, attrs: AttributeSet?) : ConstraintLayout(cont
} ?: kotlin.run {
binding.footerNote.isVisible = false
}
footer?.footerCallout?.let {
binding.footerTextWithImage.root.isVisible = true
binding.footerTextWithImage.title.showWhenDataIsAvailable(it.title)
binding.footerTextWithImage.subTitle.showWhenDataIsAvailable(it.subTitle)
binding.footerTextWithImage.image.showWhenDataIsAvailable(it.iconCode)
binding.divider.isVisible = true
} ?: kotlin.run {
binding.footerTextWithImage.root.isVisible = false
binding.divider.isVisible = false
}
} ?: run {
isVisible = false
}

View File

@@ -20,6 +20,7 @@ import com.navi.amc.redemption.model.RedemptionOrderDetails
import com.navi.amc.utils.Constant.FUND_LANDING_DATA_V2
import com.navi.amc.utils.Constant.FUND_LIST_DATA_V2
import com.navi.base.model.ActionData
import com.navi.common.csat.models.NetPromoterScoreRequest
import com.navi.common.model.UploadDataAsyncResponse
import com.navi.common.network.models.GenericResponse
import com.navi.common.network.models.SuccessResponse
@@ -319,7 +320,8 @@ interface RetrofitService {
@POST("/sip/modify")
suspend fun updateSip(
@Query("sipReferenceId") sipReferenceId: String,
@Query("modifyAction") modifyAction: String
@Query("modifyAction") modifyAction: String,
@Body netPromoterScoreRequest: NetPromoterScoreRequest
): Response<GenericResponse<SipUpdateResponse>>
@POST("/orders/create-redemption-order/vendor")

View File

@@ -33,6 +33,7 @@ import com.navi.amc.utils.AmcAnalytics
import com.navi.amc.utils.Constant
import com.navi.amc.utils.Constant.ACTION_PERFORMED
import com.navi.amc.utils.Constant.DELETED
import com.navi.amc.utils.Constant.DELETE_SIP_WITH_REASON
import com.navi.amc.utils.Constant.MANDATE_OPTED_IN
import com.navi.amc.utils.Constant.MANDATE_OPTED_OUT
import com.navi.amc.utils.Constant.MODIFY_BOTTOM_SHEET
@@ -44,7 +45,10 @@ import com.navi.amc.utils.Constant.SKIPPED
import com.navi.amc.utils.SubPageStatusType
import com.navi.amc.utils.showToastMessage
import com.navi.base.model.ActionData
import com.navi.base.model.CtaData
import com.navi.base.utils.orFalse
import com.navi.common.csat.CsatBottomSheet
import com.navi.common.csat.models.NetPromoterScoreRequest
import com.navi.common.listeners.FragmentInterchangeListener
import com.navi.common.listeners.HeaderInteractionListener
import com.navi.common.model.ModuleNameV2
@@ -55,6 +59,7 @@ import com.navi.common.utils.observeNonNull
import com.navi.common.utils.toActionData
import com.navi.design.utils.dpToPxInInt
import com.navi.naviwidgets.models.SingleSelectionBottomSheetData
import com.navi.naviwidgets.models.response.CsatWidgetData
import com.navi.naviwidgets.models.response.DataSafeWidget
import com.navi.naviwidgets.models.response.NoteWidget
import com.navi.naviwidgets.utils.getDividerView
@@ -210,19 +215,42 @@ class SipModifyFragment : AmcBaseFragment(), FooterInteractionListener {
}
} else if (actionData?.url == MODIFY_BOTTOM_SHEET) {
openBottomSheet(viewModel.sipDetailsData.value?.content?.modifyBottomSheetData)
} else if (isApiNeedsToCall(actionData?.url)) {
} else if (actionData?.url == DELETE_SIP_WITH_REASON) {
openCsatBottomSheet(viewModel.sipDetailsData.value?.content?.csatWidgetData)
}
else if (isApiNeedsToCall(actionData?.url)) {
showLoader()
viewModel.updateSip(
arguments?.getString(SIP_REFERENCE_ID).orEmpty(),
actionData?.url.orEmpty()
actionData?.url.orEmpty(),
viewModel.getNetPromoterScoreRequest()
)
} else if (actionData?.url.isNullOrEmpty().not()) {
fragmentInterchangeListener?.navigateToNextScreen(actionData, arguments ?: Bundle())
}
}
private fun openCsatBottomSheet(data: CsatWidgetData?) {
data?.selected = DELETE_SIP_WITH_REASON
data?.bottomSheetData?.get(DELETE_SIP_WITH_REASON)?.reasons?.forEach {
it.isChecked = false
}
val bottomSheet =
CsatBottomSheet.getInstance(data, enableBlackCtaStyle = true, action = ::onClickCtaData)
safelyShowBottomSheet(bottomSheet, CsatBottomSheet.TAG)
}
private fun onClickCtaData(
ctaData: CtaData,
netPromoterScoreRequest: NetPromoterScoreRequest
) {
viewModel.setNetPromoterScoreRequest(netPromoterScoreRequest)
handleOnClick(ctaData.toActionData())
}
private fun openBottomSheet(data: SingleSelectionBottomSheetData?) {
val bottomSheet = SingleSelectionBottomSheet.getInstance(data)
viewModel.clearNetPromoterScoreRequest()
safelyShowBottomSheet(bottomSheet, SingleSelectionBottomSheet.SINGLE_SELECTION_BOTTOM_SHEET)
bottomSheet.selectedItem.observeNonNull(this) { item ->
handleOnClick(ActionData(url = item.id))

View File

@@ -16,6 +16,7 @@ import com.navi.common.network.models.GenericErrorResponse
import com.navi.naviwidgets.models.NaviWidget
import com.navi.naviwidgets.models.SingleSelectionBottomSheetData
import com.navi.naviwidgets.models.response.CardType
import com.navi.naviwidgets.models.response.CsatWidgetData
data class SipModificationResponse(
@SerializedName("header") val header: Header? = null,
@@ -30,7 +31,8 @@ data class SipModificationContent(
@SerializedName("genericBottomSheets")
val genericBottomSheets: Map<String, GenericErrorResponse>? = null,
@SerializedName("items") val items: List<CardType>? = null,
@SerializedName("toastMessage") var toastMessage: ToastMessage? = null
@SerializedName("toastMessage") var toastMessage: ToastMessage? = null,
@SerializedName("csatWidgetData") val csatWidgetData: CsatWidgetData? = null
)
data class SipItems(@SerializedName("widgets") val widgets: List<NaviWidget>? = null)

View File

@@ -8,6 +8,7 @@
package com.navi.amc.portfolio.repositories
import com.navi.amc.network.retrofit.RetrofitService
import com.navi.common.csat.models.NetPromoterScoreRequest
import com.navi.common.network.retrofit.ResponseCallback
import javax.inject.Inject
@@ -17,6 +18,16 @@ class SipModificationRepository @Inject constructor(private val retrofitService:
suspend fun fetchSipModificationDetails(sipReferenceId: String, source: String) =
apiResponseCallback(retrofitService.fetchSipModificationDetails(sipReferenceId, source))
suspend fun updateSip(sipReferenceId: String, action: String) =
apiResponseCallback(retrofitService.updateSip(sipReferenceId, action))
suspend fun updateSip(
sipReferenceId: String,
action: String,
netPromoterScoreRequest: NetPromoterScoreRequest
) =
apiResponseCallback(
retrofitService.updateSip(
sipReferenceId,
action,
netPromoterScoreRequest
)
)
}

View File

@@ -13,6 +13,7 @@ import androidx.lifecycle.viewModelScope
import com.navi.amc.portfolio.models.SipModificationResponse
import com.navi.amc.portfolio.models.SipUpdateResponse
import com.navi.amc.portfolio.repositories.SipModificationRepository
import com.navi.common.csat.models.NetPromoterScoreRequest
import com.navi.common.utils.SingleLiveEvent
import com.navi.common.viewmodel.BaseVM
import dagger.hilt.android.lifecycle.HiltViewModel
@@ -30,6 +31,8 @@ class SipModificationVM @Inject constructor(private val repository: SipModificat
val sipUpdateData: LiveData<SipUpdateResponse?>
get() = _sipUpdateData
private var netPromoterScoreRequest : NetPromoterScoreRequest = NetPromoterScoreRequest()
fun fetchSipModificationDetails(sipReferenceId: String, source: String) {
viewModelScope.launch {
val response = repository.fetchSipModificationDetails(sipReferenceId, source)
@@ -41,9 +44,13 @@ class SipModificationVM @Inject constructor(private val repository: SipModificat
}
}
fun updateSip(sipReferenceId: String, action: String) {
fun updateSip(
sipReferenceId: String,
action: String,
netPromoterScoreRequest: NetPromoterScoreRequest = NetPromoterScoreRequest()
) {
viewModelScope.launch {
val response = repository.updateSip(sipReferenceId, action)
val response = repository.updateSip(sipReferenceId, action, netPromoterScoreRequest)
if (response.error == null && response.errors.isNullOrEmpty()) {
_sipUpdateData.value = response.data
} else {
@@ -52,10 +59,23 @@ class SipModificationVM @Inject constructor(private val repository: SipModificat
}
}
fun getNetPromoterScoreRequest(): NetPromoterScoreRequest {
return netPromoterScoreRequest
}
fun clearNetPromoterScoreRequest() {
netPromoterScoreRequest = NetPromoterScoreRequest()
}
fun setNetPromoterScoreRequest(netPromoterScoreRequest: NetPromoterScoreRequest) {
this.netPromoterScoreRequest = netPromoterScoreRequest
}
override fun onCleared() {
_sipDetailsData.value = null
_sipUpdateData.value = null
errorResponse.value = null
netPromoterScoreRequest = NetPromoterScoreRequest()
super.onCleared()
}
}

View File

@@ -175,4 +175,5 @@ object Constant {
const val CAPS_DATA ="DATA"
const val AUTOPAY_TYPE = "autopay_type"
const val AUTOPAY = "AUTOPAY"
const val DELETE_SIP_WITH_REASON = "DELETE_SIP_WITH_REASON"
}

View File

@@ -0,0 +1,48 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dp_16">
<ImageView
android:id="@+id/image"
android:layout_width="@dimen/_24dp"
android:layout_height="@dimen/_24dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<com.navi.design.textview.NaviTextView
android:id="@+id/title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/dp_12"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/image"
app:layout_constraintTop_toTopOf="parent"
tools:text="Autopay failed, SIP at risk!"
tools:visibility="visible" />
<com.navi.design.textview.NaviTextView
android:id="@+id/subTitle"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/dp_12"
android:layout_marginTop="@dimen/dp_4"
android:gravity="start"
android:lineHeight="@dimen/_18sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/image"
app:layout_constraintTop_toBottomOf="@id/title"
tools:text="Pay installment to avoid SIP deletion. SIPs will be auto-deleted after 2 more failures."
tools:visibility="visible" />
/>
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>

View File

@@ -41,26 +41,40 @@
android:layout_marginStart="@dimen/dp_16"
android:layout_marginTop="@dimen/dp_12"
android:layout_marginEnd="@dimen/dp_16"
android:gravity="center"
android:paddingHorizontal="@dimen/dp_8"
android:paddingVertical="@dimen/dp_4"
android:gravity="center"
android:visibility="gone"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/progress_bar"
tools:text="Set up an account win up to ₹100" />
tools:text="Set up an account win up to ₹100"
tools:visibility="gone" />
<include
android:id="@+id/footer_text_with_image"
layout="@layout/footer_image_with_text_and_subtitle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/dp_16"
android:layout_marginTop="@dimen/dp_12"
android:layout_marginEnd="@dimen/dp_16"
android:visibility="gone"
app:layout_constraintTop_toBottomOf="@id/title"
tools:visibility="visible" />
<View
android:id="@+id/divider"
android:layout_width="@dimen/dp_0"
android:visibility="gone"
android:layout_height="@dimen/dp_2"
android:layout_marginTop="@dimen/dp_12"
android:layout_marginHorizontal="@dimen/dp_16"
android:layout_marginTop="@dimen/dp_12"
android:background="@drawable/dash_line_horizontal_grey"
android:visibility="gone"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/title"
android:background="@drawable/dash_line_horizontal_grey" />
app:layout_constraintTop_toBottomOf="@id/footer_text_with_image"
tools:visibility="gone" />
<com.navi.design.textview.NaviTextView
android:id="@+id/back_cta"

View File

@@ -120,6 +120,7 @@ class CsatAdapter(
view.setOnClickListener {
data.isChecked = data.isChecked.not()
freeTextBoxListener?.onOptionSelect(data)
freeTextBoxListener?.onOptionClicked(data)
notifyDataSetChanged()
}
return view

View File

@@ -19,6 +19,7 @@ import android.view.inputmethod.InputMethodManager
import android.widget.ImageView
import android.widget.LinearLayout
import androidx.core.content.ContextCompat
import androidx.core.content.ContextCompat.getColor
import androidx.core.content.ContextCompat.getSystemService
import androidx.core.view.isVisible
import androidx.databinding.DataBindingUtil
@@ -26,6 +27,7 @@ import androidx.fragment.app.viewModels
import androidx.lifecycle.lifecycleScope
import com.airbnb.lottie.LottieAnimationView
import com.navi.base.model.AnalyticsEvent
import com.navi.base.model.CtaData
import com.navi.base.model.ImageDetail
import com.navi.base.utils.isNotNull
import com.navi.base.utils.isNotNullAndNotEmpty
@@ -71,11 +73,13 @@ class CsatBottomSheet : BaseBottomSheet(), OthersInputBoxListener {
private var selectedRating: Int? = null
private val csatVM: CsatVM by viewModels<CsatVM>()
private var action: ((CtaData, NetPromoterScoreRequest) -> Unit)? = null
override fun setContainerView(viewStub: ViewStub) {
viewStub.layoutResource = R.layout.csat_common_bottom_sheet
binding = DataBindingUtil.getBinding(viewStub.inflate())!!
initUI()
initObserver()
}
override fun onResume() {
@@ -83,15 +87,51 @@ class CsatBottomSheet : BaseBottomSheet(), OthersInputBoxListener {
setBottomSheetHeightRatio(0.15f)
}
private fun initUI() {
arguments?.getParcelable<CsatWidgetData>(DATA)?.let { npsV2WidgetData ->
updateLayoutData(npsV2WidgetData)
private fun initObserver() {
csatVM.numberOfItemSelected.observeNonNull(viewLifecycleOwner) { numberOfItems ->
if (bottomSheetData?.shouldDisableFooter.orFalse()) {
if (numberOfItems > 0) {
binding.primaryAbv.isEnabled = true
binding.primaryAbv.background =
getNaviDrawable(
backgroundColor =
getColor(requireContext(), DesignR.color.purple_button_color),
radii =
CornerRadius(
leftTop = dpToPx(4),
rightTop = dpToPx(4),
leftBottom = dpToPx(4),
rightBottom = dpToPx(4)
)
)
} else {
binding.primaryAbv.isEnabled = false
binding.primaryAbv.background =
getNaviDrawable(
backgroundColor = getColor(requireContext(), DesignR.color.dark_grey),
radii =
CornerRadius(
leftTop = dpToPx(4),
rightTop = dpToPx(4),
leftBottom = dpToPx(4),
rightBottom = dpToPx(4)
)
)
}
}
}
}
private fun initUI() {
arguments?.getBoolean(ENABLE_BLACK_CTA_STYLE)?.let { enableBlackCtaStyle ->
if (enableBlackCtaStyle) {
enableBlackCta = true
}
}
arguments?.getParcelable<CsatWidgetData>(DATA)?.let { npsV2WidgetData ->
addCountOfPreSelectedItems(npsV2WidgetData)
updateLayoutData(npsV2WidgetData)
}
csatVM.errorResponse.observeNonNull(viewLifecycleOwner) {
it.first.let {
@@ -114,7 +154,8 @@ class CsatBottomSheet : BaseBottomSheet(), OthersInputBoxListener {
if (enableBlackCta.orFalse()) {
binding.tryAgainBtn.background =
getNaviDrawable(
backgroundColor = blackCtaColor.parseColorSafe(),
backgroundColor =
getColor(requireContext(), DesignR.color.purple_button_color),
radii =
CornerRadius(
leftTop = dpToPx(4),
@@ -208,6 +249,14 @@ class CsatBottomSheet : BaseBottomSheet(), OthersInputBoxListener {
}
}
private fun addCountOfPreSelectedItems(csatWidgetData: CsatWidgetData) {
csatWidgetData.bottomSheetData?.get(csatWidgetData.selected)?.reasons?.forEach {
if (it.isChecked) {
csatVM.incrementNumberOfItemSelected()
}
}
}
private fun updateLayoutData(csatWidgetData: CsatWidgetData) {
val bottomSheetData = csatWidgetData.bottomSheetData?.get(csatWidgetData.selected)
bottomSheetData?.let { data ->
@@ -255,6 +304,29 @@ class CsatBottomSheet : BaseBottomSheet(), OthersInputBoxListener {
binding.csatOptionsLayout.addView(itemView)
}
binding.primaryAbv.setLayoutFieldData(data.footer)
data.secondaryFooter?.let {
binding.secondaryAbv.apply {
setLayoutFieldData(it)
background =
getNaviDrawable(
backgroundColor = data?.secondaryFooter?.bgColor?.parseColorSafe(),
radii =
CornerRadius(
leftTop = dpToPx(4),
rightTop = dpToPx(4),
leftBottom = dpToPx(4),
rightBottom = dpToPx(4)
)
)
visibility = View.VISIBLE
setOnClickListener {
bottomSheetData?.secondaryFooter?.action?.cta?.let {
action?.invoke(it, getNetPromoterScoreRequest(data, csatWidgetData))
safelyDismissDialog()
}
}
}
}
if (screen?.equals(REWARDS) == true) {
if (csatVM.isRatingGood(data.ratingIndex?.toIntOrNull().orZero())) {
val layoutParams =
@@ -271,7 +343,8 @@ class CsatBottomSheet : BaseBottomSheet(), OthersInputBoxListener {
if (enableBlackCta.orFalse()) {
binding.primaryAbv.background =
getNaviDrawable(
backgroundColor = blackCtaColor.parseColorSafe(),
backgroundColor =
getColor(requireContext(), DesignR.color.purple_button_color),
radii =
CornerRadius(
leftTop = dpToPx(4),
@@ -284,8 +357,43 @@ class CsatBottomSheet : BaseBottomSheet(), OthersInputBoxListener {
binding.primaryAbv.setOnClickListener(
MultipleClicksHandler {
selectedRating = data.ratingIndex?.toIntOrNull()
submitNpsDetails(data, csatWidgetData)
bottomSheetData?.footer?.action?.cta?.let {
var isFreeTextEmpty = false
bottomSheetData?.reasons?.let {
it.forEach { response ->
if (response.isChecked) {
if (
response.takeUserInput == true &&
binding.freeText.isVisible &&
binding.freeText.text?.isEmpty() == true
) {
isFreeTextEmpty = true
}
}
}
}
if (isFreeTextEmpty) {
binding.freeText.background =
getNaviDrawable(
strokeColor = getColor(requireContext(), DesignR.color.red),
strokeWidth = dpToPx(1).toInt(),
radii =
CornerRadius(
leftTop = dpToPx(8),
rightTop = dpToPx(8),
leftBottom = dpToPx(8),
rightBottom = dpToPx(8)
)
)
} else {
action?.invoke(it, getNetPromoterScoreRequest(data, csatWidgetData))
safelyDismissDialog()
}
}
?: run {
selectedRating = data.ratingIndex?.toIntOrNull()
submitNpsDetails(data, csatWidgetData)
}
}
)
@@ -437,13 +545,13 @@ class CsatBottomSheet : BaseBottomSheet(), OthersInputBoxListener {
const val DEFAULT_DELAY_BETWEEN_SCREENS_IN_MILLISECS = 3000L
const val METADATA_SUBMIT_ANALYTICS_EVENT = "submitAnalyticsEvent"
const val METADATA_PARTIAL_FILL_ANALYTICS_EVENT = "partialFillAnalyticsEvent"
const val blackCtaColor = "#1F002A"
const val FIVE_RATING = 5
const val FOUR_RATING = 4
fun getInstance(
npsV2WidgetData: CsatWidgetData? = null,
enableBlackCtaStyle: Boolean = false
enableBlackCtaStyle: Boolean = false,
action: ((CtaData, NetPromoterScoreRequest) -> Unit)? = null
): CsatBottomSheet {
return CsatBottomSheet().apply {
arguments =
@@ -451,6 +559,7 @@ class CsatBottomSheet : BaseBottomSheet(), OthersInputBoxListener {
putParcelable(Constants.DATA, npsV2WidgetData)
putBoolean(Constants.ENABLE_BLACK_CTA_STYLE, enableBlackCtaStyle)
}
this.action = action
}
}
}
@@ -459,6 +568,22 @@ class CsatBottomSheet : BaseBottomSheet(), OthersInputBoxListener {
if (data?.takeUserInput == true) {
binding.freeText.isVisible = data.isChecked == true
binding.freeText.setRawInputType(EditorInfo.TYPE_CLASS_TEXT)
binding.freeText.setOnTouchListener { _, _ ->
binding.freeText.background =
getNaviDrawable(
strokeColor =
getColor(requireContext(), DesignR.color.border_dark_grey_color),
strokeWidth = dpToPx(1).toInt(),
radii =
CornerRadius(
leftTop = dpToPx(8),
rightTop = dpToPx(8),
leftBottom = dpToPx(8),
rightBottom = dpToPx(8)
)
)
false
}
binding.freeText.setOnEditorActionListener { v, actionId, event ->
if (
actionId == EditorInfo.IME_ACTION_DONE ||
@@ -483,6 +608,16 @@ class CsatBottomSheet : BaseBottomSheet(), OthersInputBoxListener {
}
}
override fun onOptionClicked(data: ReasonItem?) {
if (bottomSheetData?.shouldDisableFooter.orFalse()) {
if (data?.isChecked == true) {
csatVM.incrementNumberOfItemSelected()
} else {
csatVM.decrementNumberOfItemSelected()
}
}
}
fun setListener(listener: CsatCompletionListener) {
npsCompletionListener = listener
}
@@ -518,6 +653,8 @@ class CsatBottomSheet : BaseBottomSheet(), OthersInputBoxListener {
interface OthersInputBoxListener {
fun onOptionSelect(data: ReasonItem?)
fun onOptionClicked(data: ReasonItem?)
}
interface CsatCompletionListener {

View File

@@ -7,6 +7,8 @@
package com.navi.common.csat
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import com.navi.common.csat.models.NetPromoterScoreRequest
import com.navi.common.csat.state.CsatSubmitResponseState
import com.navi.common.viewmodel.BaseVM
@@ -25,6 +27,10 @@ class CsatVM @Inject constructor(private val repository: CsatRepository) : BaseV
inline fun isRatingGood(rating: Int): Boolean = rating >= NPS_RATING_GOOD
private val _numberOfItemSelected = MutableLiveData<Int>(0)
val numberOfItemSelected: LiveData<Int>
get() = _numberOfItemSelected
fun submitNpsDetails(netPromoterScoreRequest: NetPromoterScoreRequest) {
coroutineScope.launch {
_npsSubmitResponse.emit(CsatSubmitResponseState.Loading)
@@ -38,6 +44,14 @@ class CsatVM @Inject constructor(private val repository: CsatRepository) : BaseV
}
}
fun incrementNumberOfItemSelected() {
_numberOfItemSelected.value = (_numberOfItemSelected.value ?: 0) + 1
}
fun decrementNumberOfItemSelected() {
_numberOfItemSelected.value = (_numberOfItemSelected.value ?: 0) - 1
}
companion object {
const val NPS_RATING_GOOD = 4
}

View File

@@ -245,9 +245,28 @@
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/free_text_heading" />
<com.navi.design.textview.NaviTextView
android:id="@+id/secondary_abv"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dp_32"
android:layout_marginEnd="@dimen/dp_16"
android:layout_marginBottom="@dimen/layout_dp_16"
android:background="@drawable/rounded_negative_button_bg"
android:gravity="center_horizontal"
android:paddingVertical="@dimen/dp_13"
android:textColor="@color/white"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@id/primary_abv"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/free_text"
tools:text="Submit"
tools:visibility="gone" />
<com.navi.design.textview.NaviTextView
android:id="@+id/primary_abv"
android:layout_width="match_parent"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dp_32"
android:layout_marginBottom="@dimen/layout_dp_16"
@@ -258,7 +277,7 @@
android:visibility="visible"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintStart_toEndOf="@id/secondary_abv"
app:layout_constraintTop_toBottomOf="@id/free_text"
tools:text="Submit"
tools:visibility="visible" />

View File

@@ -56,6 +56,8 @@ data class CsatBottomSheetData(
@SerializedName("state") val state: CsatReasonSelectionState? = null,
@SerializedName("reasons") val reasons: List<ReasonItem>? = null,
@SerializedName("footer") val footer: LayoutFieldData? = null,
@SerializedName("shouldDisableFooter") val shouldDisableFooter: Boolean? = false,
@SerializedName("secondaryFooter") val secondaryFooter: LayoutFieldData? = null,
@SerializedName("ratingIndex") val ratingIndex: String? = null,
@SerializedName("metadata") var metadata: MutableMap<String?, ParameterValue?>? = null
) : Parcelable