renew amount screen

This commit is contained in:
moon 2026-05-16 10:33:49 +06:30
parent fb4c832476
commit 283d2d64ce
2 changed files with 197 additions and 324 deletions

View File

@ -15,20 +15,17 @@ fun AmountRoute(
val canGoBack = !action.equals("Sale", ignoreCase = true) val canGoBack = !action.equals("Sale", ignoreCase = true)
AmountScreen( AmountScreen(
action = action,
canGoBack = canGoBack,
onBackClick = onBack, onBackClick = onBack,
onCancelClick = onBack, // onNextClick = { amount ->
onNextClick = { amount -> // sharedViewModel.amount.value = amount
sharedViewModel.amount.value = amount // sharedViewModel.setAmountExist(true)
sharedViewModel.setAmountExist(true) // sharedViewModel.setCardDataExist(false)
sharedViewModel.setCardDataExist(false) // sharedViewModel.setTransMenu(null)
sharedViewModel.setTransMenu(null) // sharedViewModel.transactionsType.value = TransactionsType.SALE
sharedViewModel.transactionsType.value = TransactionsType.SALE // sharedViewModel.processCode.value =
sharedViewModel.processCode.value = // ProcessCode.SALE_PURCHASE + ProcessCode.SMART + ProcessCode.TO_ACCOUNT
ProcessCode.SALE_PURCHASE + ProcessCode.SMART + ProcessCode.TO_ACCOUNT //
// onNavigateCardWaiting()
onNavigateCardWaiting() // }
}
) )
} }

View File

@ -1,275 +1,203 @@
package com.mob.utsmyanmar.ui.amount package com.mob.utsmyanmar.ui.amount
import androidx.activity.compose.BackHandler
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.* import androidx.compose.foundation.layout.*
import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.verticalScroll import androidx.compose.material.icons.Icons
import androidx.compose.material3.Button import androidx.compose.material.icons.rounded.KeyboardArrowLeft
import androidx.compose.material3.ButtonDefaults import androidx.compose.material3.*
import androidx.compose.material3.CenterAlignedTopAppBar
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.runtime.* import androidx.compose.runtime.*
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.res.painterResource import androidx.compose.ui.draw.shadow
import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp import androidx.compose.ui.unit.sp
import com.mob.utsmyanmar.ui.theme.MOBPOSTheme import com.mob.utsmyanmar.ui.preview.P2Preview
import com.mob.utsmyanmar.ui.theme.Primary import com.mob.utsmyanmar.ui.theme.Color
import com.mob.utsmyanmar.ui.theme.White
import com.mob.utsmyanmar.R
@OptIn(ExperimentalMaterial3Api::class)
@Composable @Composable
fun AmountScreen( fun AmountScreen(
action: String, onBackClick: () -> Unit = {},
canGoBack: Boolean = true, onChargeClick: (String) -> Unit = {}
onBackClick: () -> Unit,
onCancelClick: () -> Unit = {},
onNextClick: (String) -> Unit = {}
) { ) {
BackHandler(enabled = canGoBack) { var amount by remember { mutableStateOf("") }
onBackClick()
}
var amount by remember { val displayAmount = amount.ifEmpty { "0" }
mutableStateOf("0")
}
Scaffold( Column(
topBar = {
CenterAlignedTopAppBar(
title = {
Text(
text = action.uppercase(),
color = White,
fontSize = 16.sp,
fontWeight = FontWeight.SemiBold
)
},
navigationIcon = {
if (canGoBack) {
IconButton(onClick = onBackClick) {
Icon(
painter = painterResource(R.drawable.ic_left_arrow),
contentDescription = "Back",
modifier = Modifier.size(24.dp),
tint = White
)
}
}
},
colors = TopAppBarDefaults.topAppBarColors(
containerColor = Primary
)
)
},
containerColor = White
) { paddingValues ->
Column(
modifier = Modifier
.fillMaxSize()
.padding(paddingValues)
.background(White)
.verticalScroll(rememberScrollState())
.padding(horizontal = 24.dp),
horizontalAlignment = Alignment.CenterHorizontally
) {
Spacer(modifier = Modifier.height(16.dp))
AmountBox(
amount = formatTypedAmount(amount),
height = 134.dp
)
Spacer(modifier = Modifier.height(24.dp))
Keypad(
buttonHeight = 74.dp,
buttonSpacing = 12.dp,
onKeyClick = { key ->
amount = handleAmountInput(amount, key)
}
)
Spacer(modifier = Modifier.height(18.dp))
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.spacedBy(14.dp)
) {
Button(
onClick = {
onNextClick(normalizeAmount(amount))
},
modifier = Modifier
.weight(if (canGoBack) 1f else 2f)
.height(68.dp),
shape = RoundedCornerShape(18.dp),
colors = ButtonDefaults.buttonColors(
containerColor = Primary,
contentColor = White
)
) {
Text(
text = "Enter",
fontSize = 20.sp,
fontWeight = FontWeight.Bold
)
}
if (canGoBack) {
Button(
onClick = onCancelClick,
modifier = Modifier
.weight(1f)
.height(68.dp),
shape = RoundedCornerShape(18.dp),
colors = ButtonDefaults.buttonColors(
containerColor = White,
contentColor = Primary
),
border = ButtonDefaults.outlinedButtonBorder
) {
Text(
text = "Cancel",
fontSize = 20.sp,
fontWeight = FontWeight.Bold
)
}
}
}
Spacer(modifier = Modifier.height(12.dp))
}
}
}
@Composable
private fun AmountBox(
amount: String,
height: Dp
) {
Box(
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxSize()
.height(height) .background(Color.IvoryBeige)
.background( .padding(horizontal = 20.dp)
color = Primary, .navigationBarsPadding()
shape = RoundedCornerShape(20.dp) .statusBarsPadding()
)
.padding(horizontal = 24.dp),
contentAlignment = Alignment.CenterEnd
) { ) {
Box(
Row( modifier = Modifier
verticalAlignment = Alignment.CenterVertically .fillMaxWidth()
.height(56.dp),
contentAlignment = Alignment.Center
) { ) {
IconButton(
onClick = onBackClick,
modifier = Modifier.align(Alignment.CenterStart)
) {
Icon(
imageVector = Icons.Rounded.KeyboardArrowLeft,
contentDescription = "Back",
tint = Color.LegacyRed
)
}
Text( Text(
text = amount, text = "Amount",
color = White, color = Color.LegacyRed,
fontSize = 30.sp, fontSize = 14.sp,
fontWeight = FontWeight.Bold fontWeight = FontWeight.Bold
) )
}
Spacer(modifier = Modifier.width(14.dp)) Spacer(modifier = Modifier.height(36.dp))
Box( Text(
text = "Enter Amount",
color = Color.Gray,
fontSize = 11.sp,
modifier = Modifier.align(Alignment.CenterHorizontally)
)
Spacer(modifier = Modifier.height(8.dp))
Row(
modifier = Modifier.align(Alignment.CenterHorizontally),
verticalAlignment = Alignment.Bottom
) {
Text(
text = "MMK",
color = Color.LegacyRed,
fontSize = 13.sp,
fontWeight = FontWeight.Medium,
modifier = Modifier.padding(end = 10.dp, bottom = 6.dp)
)
Text(
text = formatAmount(displayAmount),
color = Color.LegacyRed,
fontSize = 32.sp,
fontWeight = FontWeight.Bold
)
}
Spacer(modifier = Modifier.height(12.dp))
Text(
text = "Enter the amount to charge",
color = Color.Gray,
fontSize = 11.sp,
modifier = Modifier.align(Alignment.CenterHorizontally)
)
Spacer(modifier = Modifier.height(28.dp))
AmountKeypad(
onNumberClick = { value ->
if (amount.length < 9) {
amount += value
}
},
onDeleteClick = {
amount = amount.dropLast(1)
}
)
Spacer(modifier = Modifier.weight(1f))
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.spacedBy(12.dp)
) {
Button(
onClick = { },
modifier = Modifier modifier = Modifier
.background( .weight(1f)
color = White, .height(56.dp),
shape = RoundedCornerShape(10.dp) shape = RoundedCornerShape(8.dp),
) colors = ButtonDefaults.buttonColors(
.padding( containerColor = Color.White,
horizontal = 16.dp, contentColor = Color.LegacyRed
vertical = 6.dp )
)
) { ) {
Text("Cancel")
}
Button(
onClick = {
if (amount.isNotEmpty()) {
onChargeClick(amount)
}
},
modifier = Modifier
.weight(1f)
.height(56.dp),
enabled = amount.isNotEmpty(),
shape = RoundedCornerShape(8.dp),
colors = ButtonDefaults.buttonColors(
containerColor = Color.LegacyRed,
contentColor = Color.White,
disabledContainerColor = Color.LegacyRed.copy(alpha = 0.5f),
disabledContentColor = Color.White
)
) {
Text( Text(
text = "MMK", text = "Next",
color = Primary, fontSize = 14.sp,
fontSize = 20.sp, fontWeight = FontWeight.Medium
fontWeight = FontWeight.Bold
) )
} }
} }
Spacer(modifier = Modifier.height(18.dp))
} }
} }
@Composable @Composable
private fun Keypad( private fun AmountKeypad(
buttonHeight: Dp, onNumberClick: (String) -> Unit,
buttonSpacing: Dp, onDeleteClick: () -> Unit
onKeyClick: (String) -> Unit
) { ) {
val keys = listOf( val keys = listOf(
listOf("1", "2", "3"), listOf("1", "2", "3"),
listOf("4", "5", "6"), listOf("4", "5", "6"),
listOf("7", "8", "9"), listOf("7", "8", "9"),
listOf(".", "0", "DEL") listOf("", "0", "00")
) )
Column( Column(
verticalArrangement = Arrangement.spacedBy(buttonSpacing) modifier = Modifier.fillMaxWidth(),
verticalArrangement = Arrangement.spacedBy(6.dp)
) { ) {
keys.forEach { row -> keys.forEach { row ->
Row( Row(
modifier = Modifier.fillMaxWidth(), modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.spacedBy(8.dp) horizontalArrangement = Arrangement.spacedBy(6.dp)
) { ) {
row.forEach { key -> row.forEach { key ->
if (key.isEmpty()) {
Button( Box(
onClick = { modifier = Modifier
onKeyClick(key) .weight(1f)
}, .height(66.dp)
modifier = Modifier )
.weight(1f) } else {
.height(buttonHeight), KeypadButton(
shape = RoundedCornerShape(18.dp), text = key,
colors = ButtonDefaults.buttonColors( modifier = Modifier.weight(1f),
containerColor = Primary, onClick = { onNumberClick(key) }
contentColor = White )
),
contentPadding = PaddingValues(0.dp)
) {
if (key == "DEL") {
Text(
text = "",
fontSize = 26.sp,
fontWeight = FontWeight.Bold
)
} else {
Text(
text = key,
fontSize = 22.sp,
fontWeight = FontWeight.Bold
)
}
} }
} }
} }
@ -277,96 +205,44 @@ private fun Keypad(
} }
} }
private fun handleAmountInput(
current: String,
key: String
): String {
return when (key.uppercase()) {
"DEL" -> {
current
.dropLast(1)
.ifEmpty { "0" }
}
"." -> {
if (current.contains(".")) {
current
} else {
"${current.ifEmpty { "0" }}."
}
}
in "0".."9" -> {
val sanitizedCurrent = if (current == "0") "" else current
if (sanitizedCurrent.contains(".")) {
val decimal = sanitizedCurrent.substringAfter(".")
if (decimal.length >= 2) {
current
} else {
sanitizedCurrent + key
}
} else {
val nextValue = sanitizedCurrent + key
nextValue.trimStart('0').ifEmpty { "0" }
}
}
else -> current
}
}
private fun normalizeAmount(value: String): String {
if (value.isBlank()) return "0.00"
val normalized = if (value.endsWith(".")) {
value.dropLast(1)
} else {
value
}
return when {
normalized.isBlank() -> "0.00"
normalized.contains(".") -> {
val whole = normalized.substringBefore(".").ifEmpty { "0" }
val decimal = normalized.substringAfter(".")
when (decimal.length) {
0 -> "$whole.00"
1 -> "$whole.${decimal}0"
else -> "$whole.${decimal.take(2)}"
}
}
else -> "${normalized}.00"
}
}
private fun formatTypedAmount(value: String): String {
if (!value.contains(".")) return "$value.00"
val whole = value.substringBefore(".").ifEmpty { "0" }
val decimal = value.substringAfter(".")
return when (decimal.length) {
0 -> "$whole."
1 -> "$whole.${decimal}0"
else -> "$whole.${decimal.take(2)}"
}
}
@Preview(showBackground = true)
@Composable @Composable
private fun AmountScreenPreview() { private fun KeypadButton(
text: String,
MOBPOSTheme { modifier: Modifier = Modifier,
onClick: () -> Unit
AmountScreen( ) {
action = "Amount", Box(
canGoBack = true, modifier = modifier
onBackClick = {} .height(66.dp)
.shadow(
elevation = 2.dp,
shape = RoundedCornerShape(8.dp),
clip = false
)
.background(
color = Color.White,
shape = RoundedCornerShape(8.dp)
)
.clickable { onClick() },
contentAlignment = Alignment.Center
) {
Text(
text = text,
color = Color.LegacyRed,
fontSize = 24.sp,
fontWeight = FontWeight.Normal,
textAlign = TextAlign.Center
) )
} }
} }
private fun formatAmount(value: String): String {
val number = value.toLongOrNull() ?: 0L
return "%,d".format(number)
}
@P2Preview
@Composable
fun PreviewAmountScreen() {
AmountScreen { }
}