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)
AmountScreen(
action = action,
canGoBack = canGoBack,
onBackClick = onBack,
onCancelClick = onBack,
onNextClick = { amount ->
sharedViewModel.amount.value = amount
sharedViewModel.setAmountExist(true)
sharedViewModel.setCardDataExist(false)
sharedViewModel.setTransMenu(null)
sharedViewModel.transactionsType.value = TransactionsType.SALE
sharedViewModel.processCode.value =
ProcessCode.SALE_PURCHASE + ProcessCode.SMART + ProcessCode.TO_ACCOUNT
onNavigateCardWaiting()
}
// onNextClick = { amount ->
// sharedViewModel.amount.value = amount
// sharedViewModel.setAmountExist(true)
// sharedViewModel.setCardDataExist(false)
// sharedViewModel.setTransMenu(null)
// sharedViewModel.transactionsType.value = TransactionsType.SALE
// sharedViewModel.processCode.value =
// ProcessCode.SALE_PURCHASE + ProcessCode.SMART + ProcessCode.TO_ACCOUNT
//
// onNavigateCardWaiting()
// }
)
}

View File

@ -1,372 +1,248 @@
package com.mob.utsmyanmar.ui.amount
import androidx.activity.compose.BackHandler
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
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.verticalScroll
import androidx.compose.material3.Button
import androidx.compose.material3.ButtonDefaults
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.material.icons.Icons
import androidx.compose.material.icons.rounded.KeyboardArrowLeft
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
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.tooling.preview.Preview
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.mob.utsmyanmar.ui.theme.MOBPOSTheme
import com.mob.utsmyanmar.ui.theme.Primary
import com.mob.utsmyanmar.ui.theme.White
import com.mob.utsmyanmar.R
import com.mob.utsmyanmar.ui.preview.P2Preview
import com.mob.utsmyanmar.ui.theme.Color
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun AmountScreen(
action: String,
canGoBack: Boolean = true,
onBackClick: () -> Unit,
onCancelClick: () -> Unit = {},
onNextClick: (String) -> Unit = {}
onBackClick: () -> Unit = {},
onChargeClick: (String) -> Unit = {}
) {
BackHandler(enabled = canGoBack) {
onBackClick()
}
var amount by remember { mutableStateOf("") }
var amount by remember {
mutableStateOf("0")
}
Scaffold(
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 ->
val displayAmount = amount.ifEmpty { "0" }
Column(
modifier = Modifier
.fillMaxSize()
.padding(paddingValues)
.background(White)
.verticalScroll(rememberScrollState())
.padding(horizontal = 24.dp),
horizontalAlignment = Alignment.CenterHorizontally
.background(Color.IvoryBeige)
.padding(horizontal = 20.dp)
.navigationBarsPadding()
.statusBarsPadding()
) {
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
.fillMaxWidth()
.height(height)
.background(
color = Primary,
shape = RoundedCornerShape(20.dp)
)
.padding(horizontal = 24.dp),
contentAlignment = Alignment.CenterEnd
.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 = "Amount",
color = Color.LegacyRed,
fontSize = 14.sp,
fontWeight = FontWeight.Bold
)
}
Spacer(modifier = Modifier.height(36.dp))
Text(
text = "Enter Amount",
color = Color.Gray,
fontSize = 11.sp,
modifier = Modifier.align(Alignment.CenterHorizontally)
)
Spacer(modifier = Modifier.height(8.dp))
Row(
verticalAlignment = Alignment.CenterVertically
modifier = Modifier.align(Alignment.CenterHorizontally),
verticalAlignment = Alignment.Bottom
) {
Text(
text = amount,
color = White,
fontSize = 30.sp,
fontWeight = FontWeight.Bold
)
Spacer(modifier = Modifier.width(14.dp))
Box(
modifier = Modifier
.background(
color = White,
shape = RoundedCornerShape(10.dp)
)
.padding(
horizontal = 16.dp,
vertical = 6.dp
)
) {
Text(
text = "MMK",
color = Primary,
fontSize = 20.sp,
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
.weight(1f)
.height(56.dp),
shape = RoundedCornerShape(8.dp),
colors = ButtonDefaults.buttonColors(
containerColor = Color.White,
contentColor = Color.LegacyRed
)
) {
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 = "Next",
fontSize = 14.sp,
fontWeight = FontWeight.Medium
)
}
}
Spacer(modifier = Modifier.height(18.dp))
}
}
@Composable
private fun Keypad(
buttonHeight: Dp,
buttonSpacing: Dp,
onKeyClick: (String) -> Unit
private fun AmountKeypad(
onNumberClick: (String) -> Unit,
onDeleteClick: () -> Unit
) {
val keys = listOf(
listOf("1", "2", "3"),
listOf("4", "5", "6"),
listOf("7", "8", "9"),
listOf(".", "0", "DEL")
listOf("", "0", "00")
)
Column(
verticalArrangement = Arrangement.spacedBy(buttonSpacing)
modifier = Modifier.fillMaxWidth(),
verticalArrangement = Arrangement.spacedBy(6.dp)
) {
keys.forEach { row ->
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.spacedBy(8.dp)
horizontalArrangement = Arrangement.spacedBy(6.dp)
) {
row.forEach { key ->
Button(
onClick = {
onKeyClick(key)
},
if (key.isEmpty()) {
Box(
modifier = Modifier
.weight(1f)
.height(buttonHeight),
shape = RoundedCornerShape(18.dp),
colors = ButtonDefaults.buttonColors(
containerColor = Primary,
contentColor = White
),
contentPadding = PaddingValues(0.dp)
) {
if (key == "DEL") {
Text(
text = "",
fontSize = 26.sp,
fontWeight = FontWeight.Bold
.height(66.dp)
)
} else {
Text(
KeypadButton(
text = key,
fontSize = 22.sp,
fontWeight = FontWeight.Bold
modifier = Modifier.weight(1f),
onClick = { onNumberClick(key) }
)
}
}
}
}
}
}
}
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
private fun AmountScreenPreview() {
MOBPOSTheme {
AmountScreen(
action = "Amount",
canGoBack = true,
onBackClick = {}
private fun KeypadButton(
text: String,
modifier: Modifier = Modifier,
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 { 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 { }
}