From d32b233d9ea3759db87b298a8fa42d900f988645 Mon Sep 17 00:00:00 2001 From: moon <56061215+MgKyawLay@users.noreply.github.com> Date: Sun, 28 Jun 2026 23:29:48 +0630 Subject: [PATCH] Update InputRrnRoute.kt --- .../utsmyanmar/ui/refund_rrn/InputRrnRoute.kt | 342 +++++++++++++++--- 1 file changed, 287 insertions(+), 55 deletions(-) diff --git a/app/src/main/java/com/mob/utsmyanmar/ui/refund_rrn/InputRrnRoute.kt b/app/src/main/java/com/mob/utsmyanmar/ui/refund_rrn/InputRrnRoute.kt index 4a4d646..b129ca6 100644 --- a/app/src/main/java/com/mob/utsmyanmar/ui/refund_rrn/InputRrnRoute.kt +++ b/app/src/main/java/com/mob/utsmyanmar/ui/refund_rrn/InputRrnRoute.kt @@ -1,13 +1,41 @@ package com.mob.utsmyanmar.ui.refund_rrn +import androidx.compose.foundation.background +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.automirrored.filled.ArrowBack +import androidx.compose.material3.Button +import androidx.compose.material3.ButtonDefaults +import androidx.compose.material3.Scaffold +import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.shadow +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp import androidx.lifecycle.compose.collectAsStateWithLifecycle -import com.mob.utsmyanmar.ui.components.NumericEntryScreen +import com.mob.utsmyanmar.ui.components.appbar.AppBar +import com.mob.utsmyanmar.ui.theme.Color +import com.mob.utsmyanmar.ui.theme.MOBPOSTheme import com.mob.utsmyanmar.viewmodel.SharedViewModel import com.mob.utsmyanmar.viewmodel.TransProcessViewModel import com.utsmyanmar.paylibs.model.PayDetail @@ -38,18 +66,13 @@ fun InputRrnRoute( val payDetailState by rrnViewModel.payDetailState.collectAsStateWithLifecycle() - fun processPreAuthComp(payDetail: PayDetail) { val newPay = transProcessViewModel.payDetail - - - newPay?.setReferNo(payDetail.referNo) newPay?.setApprovalCode(payDetail.getApprovalCode()) newPay?.setTradeTime(payDetail.getTradeTime()) newPay?.setTradeDate(payDetail.getTradeDate()) - val tradeData = TradeData() tradeData.payDetail = newPay transProcessViewModel.setOldTransPayDetail(payDetail) @@ -57,15 +80,12 @@ fun InputRrnRoute( rrnViewModel.resetState() onNavigateProcessing() - } fun processPreAuthVoid(payDetail: PayDetail) { val newPay = transProcessViewModel.payDetail - newPay?.setReferNo(payDetail.referNo) - val tradeData = TradeData() tradeData.payDetail = newPay transProcessViewModel.setOldTransPayDetail(payDetail) @@ -75,92 +95,274 @@ fun InputRrnRoute( onNavigateProcessing() } - - - LaunchedEffect(payDetailState) { - LogUtil.d("RRN","paydetail state: $payDetailState") + LogUtil.d("RRN", "paydetail state: $payDetailState") when (val state = payDetailState) { - is RRNViewModel.PayDetailState.Success -> { - - sharedViewModel.payDetail.value = state.data sharedViewModel.rrNNo.value = state.data.referNo - if(sharedViewModel.transactionsType.value == TransactionsType.PRE_AUTH_COMPLETE) { + if (sharedViewModel.transactionsType.value == TransactionsType.PRE_AUTH_COMPLETE) { processPreAuthComp(state.data) - } else if(sharedViewModel.transactionsType.value == TransactionsType.PRE_AUTH_VOID) { + } else if (sharedViewModel.transactionsType.value == TransactionsType.PRE_AUTH_VOID) { processPreAuthVoid(state.data) } - } + is RRNViewModel.PayDetailState.Error -> { errorMessage = state.message rrnViewModel.resetState() - // show dialog - // navigate to home } + else -> Unit } } - NumericEntryScreen( - title = "Input RRN", - prompt = "Enter RRN", - displayValue = rrn.ifEmpty { "0" }, - supportingText = errorMessage ?: "Enter the retrieval reference number to continue", - confirmText = "Next", - onBackClick = onBack, - onCancelClick = onBack, - onConfirmClick = { + InputRrnContent( + rrn = rrn, + errorMessage = errorMessage, + onRrnChange = { value -> + rrn = if (value == "Del") { + rrn.dropLast(1) + } else { + appendRrnValue(rrn, value) + } + errorMessage = null + }, + onBack = onBack, + onNext = { val trimmedRrn = rrn.trim() if (POSUtil.getInstance().checkNumberField(trimmedRrn)) { errorMessage = "Invalid RRN" - return@NumericEntryScreen + return@InputRrnContent } + sharedViewModel.rrNNo.value = trimmedRrn - - if(sharedViewModel.transactionsType.value == TransactionsType.REFUND ) { + if (sharedViewModel.transactionsType.value == TransactionsType.REFUND) { val newPay = transProcessViewModel.payDetail - newPay?.setReferNo(trimmedRrn) val tradeData = TradeData() tradeData.payDetail = newPay transProcessViewModel.setTradeData(tradeData) rrnViewModel.resetState() onNavigateProcessing() - } else{ + } else { rrnViewModel.searchPayDetail( trimmedRrn, - sharedViewModel.payDetail.value?.cardNo?:"" + sharedViewModel.payDetail.value?.cardNo ?: "" ) } - - - }, - onKeyClick = { value -> - rrn = appendRrnValue(rrn, value) - errorMessage = null - }, - onDeleteClick = { - rrn = rrn.dropLast(1) - errorMessage = null - }, - confirmEnabled = rrn.isNotEmpty(), - canDelete = rrn.isNotEmpty(), - keys = listOf( - listOf("1", "2", "3"), - listOf("4", "5", "6"), - listOf("7", "8", "9"), - listOf("", "0", "00") - ) + onDelete = { + if (rrn.isNotEmpty()) { + rrn = rrn.dropLast(1) + } + } ) } +@Composable +private fun InputRrnContent( + rrn: String, + errorMessage: String?, + onRrnChange: (String) -> Unit, + onBack: () -> Unit, + onNext: () -> Unit, + onDelete: () -> Unit, +) { + Scaffold( + containerColor = Color.IvoryBeige, + topBar = { + AppBar( + title = "Input RRN", + icon = Icons.AutoMirrored.Filled.ArrowBack, + onIconClick = onBack + ) + } + ) { paddingValues -> + Column( + modifier = Modifier + .fillMaxSize() + .padding(paddingValues) + ) { + Column( + modifier = Modifier + .fillMaxSize() + .padding(horizontal = 16.dp), + verticalArrangement = Arrangement.SpaceBetween + ) { + Column( + modifier = Modifier.fillMaxWidth() + ) { + Text( + text = "Enter RRN", + color = Color.Gray, + fontSize = 11.sp, + modifier = Modifier.align(Alignment.CenterHorizontally) + ) + + Spacer(modifier = Modifier.height(8.dp)) + + Text( + text = rrn.ifEmpty { "0" }, + color = Color.LegacyRed, + fontSize = 32.sp, + fontWeight = FontWeight.Bold, + modifier = Modifier.align(Alignment.CenterHorizontally) + ) + + Spacer(modifier = Modifier.height(12.dp)) + + Text( + text = errorMessage ?: "Enter the retrieval reference number to continue", + color = if (errorMessage == null) Color.Gray else Color.Error, + fontSize = 11.sp, + modifier = Modifier.align(Alignment.CenterHorizontally) + ) + } + + Spacer(modifier = Modifier.height(24.dp)) + + Column( + modifier = Modifier.fillMaxWidth() + ) { + RrnKeypad( + onKeyClick = onRrnChange, + canDelete = rrn.isNotEmpty() + ) + + Spacer(modifier = Modifier.height(24.dp)) + + Row( + modifier = Modifier + .fillMaxWidth() + .padding(bottom = 18.dp), + horizontalArrangement = Arrangement.spacedBy(12.dp) + ) { + Button( + onClick = onBack, + modifier = Modifier + .weight(1f) + .height(56.dp), + shape = RoundedCornerShape(8.dp), + colors = ButtonDefaults.buttonColors( + containerColor = Color.White, + contentColor = Color.LegacyRed + ) + ) { + Text("Cancel") + } + + Button( + onClick = onNext, + modifier = Modifier + .weight(1f) + .height(56.dp), + enabled = rrn.isNotBlank(), + shape = RoundedCornerShape(8.dp), + colors = ButtonDefaults.buttonColors( + containerColor = Color.LegacyRed, + contentColor = Color.White, + disabledContainerColor = Color.LegacyRed.copy(alpha = 0.5f), + disabledContentColor = Color.White + ) + ) { + Text("Next") + } + } + } + } + +// Card( +// modifier = Modifier +// .align(Alignment.TopEnd) +// .padding(top = 110.dp, end = 16.dp) +// .clickable(enabled = rrn.isNotEmpty()) { +// onDelete() +// }, +// shape = RoundedCornerShape(18.dp), +// colors = CardDefaults.cardColors(containerColor = Color.White), +// elevation = CardDefaults.cardElevation(defaultElevation = 6.dp) +// ) { +// androidx.compose.material3.Icon( +// imageVector = Icons.Rounded.Backspace, +// contentDescription = "Delete", +// tint = if (rrn.isNotEmpty()) Color.LegacyRed else Color.Gray, +// modifier = Modifier.padding(horizontal = 14.dp, vertical = 12.dp) +// ) +// } + } + } +} + +@Composable +private fun RrnKeypad( + onKeyClick: (String) -> Unit, + canDelete: Boolean +) { + val keys = listOf( + listOf("1", "2", "3"), + listOf("4", "5", "6"), + listOf("7", "8", "9"), + listOf("Del", "0", "00") + ) + + Column( + modifier = Modifier.fillMaxWidth(), + verticalArrangement = Arrangement.spacedBy(6.dp) + ) { + keys.forEach { row -> + Row( + modifier = Modifier.fillMaxWidth(), + horizontalArrangement = Arrangement.spacedBy(6.dp) + ) { + row.forEach { key -> + RrnKeypadButton( + text = key, + modifier = Modifier.weight(1f), + enabled = key.isNotBlank() && (key != "Del" || canDelete), + onClick = { onKeyClick(key) } + ) + } + } + } + } +} + +@Composable +private fun RrnKeypadButton( + text: String, + modifier: Modifier = Modifier, + enabled: Boolean = true, + onClick: () -> Unit +) { + Box( + modifier = modifier + .height(66.dp) + .shadow( + elevation = 2.dp, + shape = RoundedCornerShape(8.dp), + clip = false + ) + .background( + color = Color.White, + shape = RoundedCornerShape(8.dp) + ) + .clickable(enabled = enabled) { onClick() }, + contentAlignment = Alignment.Center + ) { + Text( + text = text, + color = if (enabled) Color.LegacyRed else Color.Gray, + fontSize = 24.sp, + fontWeight = FontWeight.Normal, + textAlign = TextAlign.Center + ) + } +} + private fun appendRrnValue(current: String, value: String): String { if (value.isBlank()) { return current @@ -173,3 +375,33 @@ private fun appendRrnValue(current: String, value: String): String { return current + value.take(remainingDigits) } + +@Preview(showBackground = true) +@Composable +private fun InputRrnPreview() { + MOBPOSTheme { + InputRrnContent( + rrn = "123456789012", + errorMessage = null, + onRrnChange = {}, + onBack = {}, + onNext = {}, + onDelete = {} + ) + } +} + +@Preview(showBackground = true) +@Composable +private fun InputRrnErrorPreview() { + MOBPOSTheme { + InputRrnContent( + rrn = "123", + errorMessage = "Invalid RRN", + onRrnChange = {}, + onBack = {}, + onNext = {}, + onDelete = {} + ) + } +}