sidebar profile added

This commit is contained in:
moon 2026-05-21 21:27:13 +06:30
parent 57dcd13c34
commit 675e398aaf
4 changed files with 486 additions and 385 deletions

View File

@ -3,6 +3,7 @@ package com.mob.utsmyanmar.ui.dashboard
import android.os.Handler import android.os.Handler
import android.os.Looper import android.os.Looper
import androidx.compose.animation.core.tween import androidx.compose.animation.core.tween
import androidx.compose.foundation.Image
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.clickable import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Arrangement
@ -48,6 +49,7 @@ import androidx.compose.material.icons.filled.Wallet
import androidx.compose.material3.rememberDrawerState import androidx.compose.material3.rememberDrawerState
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
@ -59,14 +61,20 @@ import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.text.style.TextOverflow
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 androidx.lifecycle.viewmodel.compose.viewModel
import coil3.compose.AsyncImage import coil3.compose.AsyncImage
import com.mob.utsmyanmar.R
import com.mob.utsmyanmar.ui.components.appbar.AppBar import com.mob.utsmyanmar.ui.components.appbar.AppBar
import com.mob.utsmyanmar.ui.device_info.DeviceInfoViewModel
import com.mob.utsmyanmar.ui.preview.P2Preview import com.mob.utsmyanmar.ui.preview.P2Preview
import com.mob.utsmyanmar.ui.theme.Color import com.mob.utsmyanmar.ui.theme.Color
import com.sunmi.pay.hardware.aidl.AidlConstants
import com.utsmyanmar.baselib.BaseApplication
import com.utsmyanmar.paylibs.sign_on.EchoTestProcess import com.utsmyanmar.paylibs.sign_on.EchoTestProcess
import com.utsmyanmar.paylibs.sign_on.SignOnListener import com.utsmyanmar.paylibs.sign_on.SignOnListener
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
@ -75,9 +83,16 @@ import kotlinx.coroutines.launch
@Composable @Composable
fun DashboardScreen2( fun DashboardScreen2(
onNavigateAmount: (String) -> Unit = {}, onNavigateAmount: (String) -> Unit = {},
onNavigateSignOn: () -> Unit = {} onNavigateSignOn: () -> Unit = {},
deviceInfoViewModel: DeviceInfoViewModel = viewModel()
) { ) {
val drawerState = rememberDrawerState(initialValue = androidx.compose.material3.DrawerValue.Closed) val deviceInfo by deviceInfoViewModel.uiState.collectAsState()
LaunchedEffect(Unit) {
deviceInfoViewModel.loadDeviceInfo();
}
val drawerState = rememberDrawerState(initialValue = androidx.compose.material3.DrawerValue.Open) //for preview
// val drawerState = rememberDrawerState(initialValue = androidx.compose.material3.DrawerValue.Closed) //for normal usage
val scope = rememberCoroutineScope() val scope = rememberCoroutineScope()
val mainHandler = remember { Handler(Looper.getMainLooper()) } val mainHandler = remember { Handler(Looper.getMainLooper()) }
var showHostActionDialog by remember { mutableStateOf(false) } var showHostActionDialog by remember { mutableStateOf(false) }
@ -85,10 +100,14 @@ fun DashboardScreen2(
var isHostActionRunning by remember { mutableStateOf(false) } var isHostActionRunning by remember { mutableStateOf(false) }
var dialogMessage by remember { mutableStateOf("") } var dialogMessage by remember { mutableStateOf("") }
val isOnline = true;
fun confirmationMessage(action: String) = "Do you want to start ${action.lowercase()}?" fun confirmationMessage(action: String) = "Do you want to start ${action.lowercase()}?"
fun processingMessage(action: String) = "Sending ${action.lowercase()} request to host..." fun processingMessage(action: String) = "Sending ${action.lowercase()} request to host..."
fun successMessage(action: String) = "$action success." fun successMessage(action: String) = "$action success."
fun failureMessage(action: String, resultCode: Int?) = "$action failed. Response code: ${resultCode ?: -1}" fun failureMessage(action: String, resultCode: Int?) =
"$action failed. Response code: ${resultCode ?: -1}"
fun networkFailureMessage(action: String) = "Network error during $action." fun networkFailureMessage(action: String) = "Network error during $action."
fun openHostActionDialog(action: String) { fun openHostActionDialog(action: String) {
activeHostAction = action activeHostAction = action
@ -149,7 +168,8 @@ fun DashboardScreen2(
isHostActionRunning = false isHostActionRunning = false
mainHandler.post { mainHandler.post {
isHostActionRunning = false isHostActionRunning = false
dialogMessage = failureMessage(activeHostAction, resultCode) dialogMessage =
failureMessage(activeHostAction, resultCode)
} }
} }
} }
@ -202,21 +222,48 @@ fun DashboardScreen2(
Column( Column(
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.background(Color.LegacyRed) .background(Color.IvoryBeige)
.padding(horizontal = 20.dp, vertical = 28.dp) .padding(horizontal = 20.dp, vertical = 28.dp)
) { ) {
Row() {
Box(
modifier = Modifier
.size(80.dp)
.clip(CircleShape)
.background(Color.White),
contentAlignment = Alignment.Center
) {
Image(
painter = painterResource(R.drawable.logo_mob),
contentDescription = "mob logo",
modifier = Modifier
.size(100.dp)
.padding(16.dp),
contentScale = ContentScale.Fit
)
}
Column() {
Text( Text(
text = "MOBPOS", text = "MOB Merchant",
color = Color.White, color = Color.CrimsonRed,
fontSize = 22.sp, fontSize = 12.sp,
fontWeight = FontWeight.Bold fontWeight = FontWeight.Bold
) )
Spacer(modifier = Modifier.height(6.dp))
Text( Text(
text = "Quick navigation", text = "S/N:${deviceInfo.serialNumber}",
color = Color.White.copy(alpha = 0.85f), color = Color.Black,
fontSize = 13.sp fontSize = 12.sp,
fontWeight = FontWeight.Bold
) )
Text(
text = if(isOnline) "Online" else "Offline",
color = if(isOnline) Color.Success else Color.Error,
fontSize = 12.sp,
fontWeight = FontWeight.Bold
)
}
}
} }
Spacer(modifier = Modifier.height(10.dp)) Spacer(modifier = Modifier.height(10.dp))
@ -229,20 +276,6 @@ fun DashboardScreen2(
scope.launch { drawerState.close() } scope.launch { drawerState.close() }
openHostActionDialog("Log-Off") openHostActionDialog("Log-Off")
} }
DrawerItem("Sale", Icons.Default.PointOfSale) {
scope.launch { drawerState.close() }
onNavigateAmount("Sale")
}
DrawerItem("Sign On", Icons.Default.Link) {
scope.launch { drawerState.close() }
onNavigateSignOn()
}
DrawerItem("Settlement", Icons.Default.Wallet) {
scope.launch { drawerState.close() }
}
DrawerItem("History", Icons.Default.History) {
scope.launch { drawerState.close() }
}
} }
} }
) { ) {
@ -327,7 +360,9 @@ fun DashboardScreen2(
} }
Card( Card(
modifier = Modifier.fillMaxWidth().height(170.dp), modifier = Modifier
.fillMaxWidth()
.height(170.dp),
shape = RoundedCornerShape(0.dp), shape = RoundedCornerShape(0.dp),
colors = CardDefaults.cardColors(containerColor = Color.White), colors = CardDefaults.cardColors(containerColor = Color.White),
) { ) {
@ -349,7 +384,9 @@ fun DashboardScreen2(
@Composable @Composable
private fun SummaryCard() { private fun SummaryCard() {
Card( Card(
modifier = Modifier.fillMaxWidth().padding(horizontal = 16.dp), modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 16.dp),
shape = RoundedCornerShape(16.dp), shape = RoundedCornerShape(16.dp),
colors = CardDefaults.cardColors(containerColor = Color.White), colors = CardDefaults.cardColors(containerColor = Color.White),
elevation = CardDefaults.cardElevation(4.dp) elevation = CardDefaults.cardElevation(4.dp)

View File

@ -0,0 +1,11 @@
package com.mob.utsmyanmar.ui.device_info
data class DeviceInfoUiState(
val hardwareVersion: String = "",
val firmwareVersion: String = "",
val serialNumber: String = "",
val deviceModel: String = "",
val finalVersion: String = "",
val isLoading: Boolean = false,
val errorMessage: String? = null
)

View File

@ -0,0 +1,52 @@
package com.mob.utsmyanmar.ui.device_info
import androidx.lifecycle.ViewModel
import com.sunmi.pay.hardware.aidl.AidlConstants
import com.utsmyanmar.baselib.BaseApplication
import com.utsmyanmar.paylibs.utils.core_utils.SystemParamsOperation
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
class DeviceInfoViewModel : ViewModel() {
private val _uiState = MutableStateFlow(DeviceInfoUiState())
val uiState = _uiState.asStateFlow()
fun loadDeviceInfo() {
_uiState.value = _uiState.value.copy(isLoading = true)
try {
val hardwareVersion = getParams(AidlConstants.SysParam.HARDWARE_VERSION)
val firmwareVersion = getParams(AidlConstants.SysParam.FIRMWARE_VERSION)
val serialNo = getParams(AidlConstants.SysParam.SN)
val deviceModel = getParams(AidlConstants.SysParam.DEVICE_MODEL)
val finalVersion = SystemParamsOperation.getInstance().finalVersion ?: ""
_uiState.value = DeviceInfoUiState(
hardwareVersion = hardwareVersion,
firmwareVersion = firmwareVersion,
serialNumber = serialNo,
deviceModel = deviceModel,
finalVersion = finalVersion,
isLoading = false
)
} catch (e: Exception) {
_uiState.value = _uiState.value.copy(
isLoading = false,
errorMessage = e.message ?: "Failed to load device info"
)
}
}
private fun getParams(name: String): String {
return try {
BaseApplication.getInstance()
.basicOptBinder
?.getSysParam(name)
?: ""
} catch (e: Exception) {
""
}
}
}

View File

@ -22,4 +22,5 @@ object Color {
val Black = Color(0xFF000000) val Black = Color(0xFF000000)
val Gray = Color(0xFF898989) val Gray = Color(0xFF898989)
val Success = Color(0xFF007E33) val Success = Color(0xFF007E33)
val Error = Color(0xFFCD2029)
} }