From 283d2d64ce1eea94a5f200c26cbcc4dbd59f16c9 Mon Sep 17 00:00:00 2001 From: moon <56061215+MgKyawLay@users.noreply.github.com> Date: Sat, 16 May 2026 10:33:49 +0630 Subject: [PATCH] renew amount screen --- .../mob/utsmyanmar/ui/amount/AmountRoute.kt | 25 +- .../mob/utsmyanmar/ui/amount/AmountScreen.kt | 496 +++++++----------- 2 files changed, 197 insertions(+), 324 deletions(-) diff --git a/app/src/main/java/com/mob/utsmyanmar/ui/amount/AmountRoute.kt b/app/src/main/java/com/mob/utsmyanmar/ui/amount/AmountRoute.kt index b7409e5..9366700 100644 --- a/app/src/main/java/com/mob/utsmyanmar/ui/amount/AmountRoute.kt +++ b/app/src/main/java/com/mob/utsmyanmar/ui/amount/AmountRoute.kt @@ -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() +// } ) } diff --git a/app/src/main/java/com/mob/utsmyanmar/ui/amount/AmountScreen.kt b/app/src/main/java/com/mob/utsmyanmar/ui/amount/AmountScreen.kt index c7ecd0c..ddb7084 100644 --- a/app/src/main/java/com/mob/utsmyanmar/ui/amount/AmountScreen.kt +++ b/app/src/main/java/com/mob/utsmyanmar/ui/amount/AmountScreen.kt @@ -1,275 +1,203 @@ 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") - } + val displayAmount = amount.ifEmpty { "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 -> - - 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( + Column( modifier = Modifier - .fillMaxWidth() - .height(height) - .background( - color = Primary, - shape = RoundedCornerShape(20.dp) - ) - .padding(horizontal = 24.dp), - contentAlignment = Alignment.CenterEnd + .fillMaxSize() + .background(Color.IvoryBeige) + .padding(horizontal = 20.dp) + .navigationBarsPadding() + .statusBarsPadding() ) { - - Row( - verticalAlignment = Alignment.CenterVertically + Box( + modifier = Modifier + .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 = amount, - color = White, - fontSize = 30.sp, + text = "Amount", + color = Color.LegacyRed, + fontSize = 14.sp, 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 - .background( - color = White, - shape = RoundedCornerShape(10.dp) - ) - .padding( - horizontal = 16.dp, - vertical = 6.dp - ) + .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 = "MMK", - color = Primary, - fontSize = 20.sp, - fontWeight = FontWeight.Bold + 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) - }, - 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 - ) - - } else { - - Text( - text = key, - fontSize = 22.sp, - fontWeight = FontWeight.Bold - ) - } + if (key.isEmpty()) { + Box( + modifier = Modifier + .weight(1f) + .height(66.dp) + ) + } else { + KeypadButton( + text = key, + modifier = Modifier.weight(1f), + onClick = { onNumberClick(key) } + ) } } } @@ -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 -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 { } +} \ No newline at end of file