From da9184edea4b24ecab4a8ffb613e028944697bcf Mon Sep 17 00:00:00 2001 From: dankito Date: Tue, 17 Sep 2024 23:49:22 +0200 Subject: [PATCH] Started AccountTransactionDetailsScreen --- .../banking/ui/appskeleton/SideMenuContent.kt | 3 +- .../banking/ui/composables/StateHandler.kt | 8 +++ .../transactions/TransactionListItem.kt | 1 + .../net/codinux/banking/ui/config/Colors.kt | 5 ++ .../ui/extensions/ModifierExtensions.kt | 11 +++ .../codinux/banking/ui/forms/LabelledValue.kt | 38 ++++++++++ .../codinux/banking/ui/forms/SectionHeader.kt | 28 ++++++++ .../AccountTransactionDetailsScreen.kt | 70 +++++++++++++++++++ .../banking/ui/screens/ExportScreen.kt | 5 +- .../net/codinux/banking/ui/state/UiState.kt | 2 + 10 files changed, 168 insertions(+), 3 deletions(-) create mode 100644 composeApp/src/commonMain/kotlin/net/codinux/banking/ui/extensions/ModifierExtensions.kt create mode 100644 composeApp/src/commonMain/kotlin/net/codinux/banking/ui/forms/LabelledValue.kt create mode 100644 composeApp/src/commonMain/kotlin/net/codinux/banking/ui/forms/SectionHeader.kt create mode 100644 composeApp/src/commonMain/kotlin/net/codinux/banking/ui/screens/AccountTransactionDetailsScreen.kt diff --git a/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/appskeleton/SideMenuContent.kt b/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/appskeleton/SideMenuContent.kt index f9bec1f..94f1b29 100644 --- a/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/appskeleton/SideMenuContent.kt +++ b/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/appskeleton/SideMenuContent.kt @@ -23,6 +23,7 @@ import net.codinux.banking.ui.composables.settings.UiSettings import net.codinux.banking.ui.composables.text.ItemDivider import net.codinux.banking.ui.config.Colors import net.codinux.banking.ui.config.DI +import net.codinux.banking.ui.extensions.verticalScroll import net.codinux.banking.ui.model.ShowTransferMoneyDialogData import org.jetbrains.compose.resources.imageResource @@ -58,7 +59,7 @@ fun SideMenuContent() { val coroutineScope = rememberCoroutineScope() - Column(Modifier.fillMaxSize().background(Colors.DrawerContentBackground).verticalScroll(ScrollState(0), enabled = true)) { + Column(Modifier.fillMaxSize().background(Colors.DrawerContentBackground).verticalScroll()) { Column(Modifier.fillMaxWidth().height(HeaderHeight.dp).background(HeaderBackground).padding(16.dp)) { Spacer(Modifier.weight(1f)) diff --git a/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/composables/StateHandler.kt b/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/composables/StateHandler.kt index de68805..51a5586 100644 --- a/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/composables/StateHandler.kt +++ b/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/composables/StateHandler.kt @@ -6,6 +6,7 @@ import androidx.compose.runtime.* import kotlinx.coroutines.launch import net.codinux.banking.ui.config.DI import net.codinux.banking.ui.dialogs.* +import net.codinux.banking.ui.screens.AccountTransactionDetailsScreen import net.codinux.banking.ui.screens.ExportScreen import net.codinux.banking.ui.state.UiState @@ -15,6 +16,7 @@ private val formatUtil = DI.formatUtil fun StateHandler(uiState: UiState, snackbarHostState: SnackbarHostState) { val showAddAccountDialog by uiState.showAddAccountDialog.collectAsState() val showTransferMoneyDialogData by uiState.showTransferMoneyDialogData.collectAsState() + val showAccountTransactionDetailsScreenForId by uiState.showAccountTransactionDetailsScreenForId.collectAsState() val showExportScreen by uiState.showExportScreen.collectAsState() val tanChallengeReceived by uiState.tanChallengeReceived.collectAsState() @@ -32,6 +34,12 @@ fun StateHandler(uiState: UiState, snackbarHostState: SnackbarHostState) { TransferMoneyDialog(data) { uiState.showTransferMoneyDialogData.value = null } } + showAccountTransactionDetailsScreenForId?.let { transactionId -> + DI.bankingService.getTransaction(transactionId)?.let { transaction -> + AccountTransactionDetailsScreen(transaction) { uiState.showAccountTransactionDetailsScreenForId.value = null } + } + } + if (showExportScreen) { ExportScreen { uiState.showExportScreen.value = false } } diff --git a/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/composables/transactions/TransactionListItem.kt b/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/composables/transactions/TransactionListItem.kt index a304bad..d350a4a 100644 --- a/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/composables/transactions/TransactionListItem.kt +++ b/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/composables/transactions/TransactionListItem.kt @@ -66,6 +66,7 @@ fun TransactionListItem(bank: BankAccess?, transaction: AccountTransactionViewMo .background(color = backgroundColor) .pointerInput(Unit) { detectTapGestures( + onTap = { DI.uiState.showAccountTransactionDetailsScreenForId.value = transaction.id }, onLongPress = { if (transaction.otherPartyName != null) { // TODO: also check if IBAN is set showMenuAt = DpOffset(it.x.dp, it.y.dp - bottomPadding) diff --git a/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/config/Colors.kt b/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/config/Colors.kt index 0cb4269..36524ad 100644 --- a/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/config/Colors.kt +++ b/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/config/Colors.kt @@ -34,6 +34,11 @@ object Colors { val CodinuxSecondaryColor = Color(251, 187, 33) + val FormLabelTextColor = Color(0xFF494949) + + val FormValueTextColor = Color(0xFF999999) + + val Zinc100 = Color(244, 244, 245) val Zinc100_50 = Zinc100.copy(alpha = 0.5f) diff --git a/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/extensions/ModifierExtensions.kt b/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/extensions/ModifierExtensions.kt new file mode 100644 index 0000000..214a249 --- /dev/null +++ b/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/extensions/ModifierExtensions.kt @@ -0,0 +1,11 @@ +package net.codinux.banking.ui.extensions + +import androidx.compose.foundation.ScrollState +import androidx.compose.foundation.horizontalScroll +import androidx.compose.foundation.verticalScroll +import androidx.compose.ui.Modifier + + +fun Modifier.verticalScroll() = this.verticalScroll(ScrollState(0), enabled = true) + +fun Modifier.horizontalScroll() = this.horizontalScroll(ScrollState(0), enabled = true) \ No newline at end of file diff --git a/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/forms/LabelledValue.kt b/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/forms/LabelledValue.kt new file mode 100644 index 0000000..33944be --- /dev/null +++ b/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/forms/LabelledValue.kt @@ -0,0 +1,38 @@ +package net.codinux.banking.ui.forms + +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.material.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.text.style.TextOverflow +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import net.codinux.banking.ui.config.Colors + +@Composable +fun LabelledValue(label: String, value: String?, valueTextColor: Color? = null) { + + if (value != null) { + Column(Modifier.fillMaxWidth()) { + Text( + text = label, + modifier = Modifier.padding(top = 12.dp, bottom = 2.dp), + fontSize = 15.sp, + color = Colors.FormLabelTextColor, + maxLines = 1, + overflow = TextOverflow.Ellipsis + ) + + Text( + text = value, + modifier = Modifier.padding(bottom = 4.dp), + fontSize = 15.sp, + color = valueTextColor ?: Colors.FormValueTextColor + ) + } + } + +} \ No newline at end of file diff --git a/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/forms/SectionHeader.kt b/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/forms/SectionHeader.kt new file mode 100644 index 0000000..b73fff7 --- /dev/null +++ b/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/forms/SectionHeader.kt @@ -0,0 +1,28 @@ +package net.codinux.banking.ui.forms + +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.material.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import net.codinux.banking.ui.config.Colors + +@Composable +fun SectionHeader(title: String, topPadding: Boolean = true) { + + Text( + text = title, + modifier = Modifier.fillMaxWidth().let { + if (topPadding) { + it.padding(top = 24.dp) + } else { + it + } + }, + color = Colors.CodinuxSecondaryColor, + fontSize = 15.sp + ) + +} \ No newline at end of file diff --git a/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/screens/AccountTransactionDetailsScreen.kt b/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/screens/AccountTransactionDetailsScreen.kt new file mode 100644 index 0000000..ca1e0a7 --- /dev/null +++ b/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/screens/AccountTransactionDetailsScreen.kt @@ -0,0 +1,70 @@ +package net.codinux.banking.ui.screens + +import androidx.compose.foundation.layout.* +import androidx.compose.foundation.text.selection.SelectionContainer +import androidx.compose.runtime.Composable +import androidx.compose.runtime.collectAsState +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.dp +import net.codinux.banking.client.model.isNegative +import net.codinux.banking.dataaccess.entities.AccountTransactionEntity +import net.codinux.banking.ui.config.DI +import net.codinux.banking.ui.extensions.verticalScroll +import net.codinux.banking.ui.forms.LabelledValue +import net.codinux.banking.ui.forms.SectionHeader + +private val formatUtil = DI.formatUtil + +@Composable +fun AccountTransactionDetailsScreen(transaction: AccountTransactionEntity, onClosed: () -> Unit) { + + val isExpense = transaction.amount.isNegative + + val account = DI.uiState.banks.value.firstOrNull { it.id == transaction.bankId }?.accounts?.firstOrNull { it.id == transaction.accountId } + + val accountCurrency = account?.currency ?: transaction.currency // transaction.currency just as fallback + + val showColoredAmounts = DI.uiSettings.showColoredAmounts.collectAsState() + + + FullscreenViewBase("Umsatzdetails", onClosed = onClosed) { + SelectionContainer { + Column(Modifier.fillMaxSize().verticalScroll().padding(8.dp)) { + + Column(Modifier.fillMaxWidth()) { + SectionHeader(if (isExpense) "Empfänger*in" else "Zahlende*r", false) + + LabelledValue("Name", transaction.otherPartyName ?: "") + + LabelledValue("BIC", transaction.otherPartyBankId ?: "") + + LabelledValue("IBAN", transaction.otherPartyAccountId ?: "") + } + + Column(Modifier.fillMaxWidth().padding(top = 8.dp)) { + LabelledValue("Betrag", formatUtil.formatAmount(transaction.amount, transaction.currency), + formatUtil.getColorForAmount(transaction.amount, showColoredAmounts.value)) + + LabelledValue("Verwendungszweck", transaction.reference ?: "") + } + + Column(Modifier.fillMaxWidth().padding(top = 24.dp)) { + LabelledValue("Buchungstext", transaction.postingText ?: "") + + LabelledValue("Buchungsdatum", formatUtil.formatDate(transaction.bookingDate)) + + LabelledValue("Wertstellungsdatum", formatUtil.formatDate(transaction.valueDate)) + + transaction.openingBalance?.let { + LabelledValue("Tagesanfangssaldo", formatUtil.formatAmount(it, accountCurrency)) + } + + transaction.closingBalance?.let { + LabelledValue("Tagesendsaldo", formatUtil.formatAmount(it, accountCurrency)) + } + } + } + } + } + +} \ No newline at end of file diff --git a/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/screens/ExportScreen.kt b/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/screens/ExportScreen.kt index 1d4f722..9dcb840 100644 --- a/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/screens/ExportScreen.kt +++ b/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/screens/ExportScreen.kt @@ -1,6 +1,5 @@ package net.codinux.banking.ui.screens -import androidx.compose.foundation.* import androidx.compose.foundation.layout.* import androidx.compose.foundation.text.selection.SelectionContainer import androidx.compose.material.Text @@ -18,6 +17,8 @@ import net.codinux.banking.dataaccess.entities.AccountTransactionEntity import net.codinux.banking.ui.IOorDefault import net.codinux.banking.ui.config.Colors import net.codinux.banking.ui.config.DI +import net.codinux.banking.ui.extensions.horizontalScroll +import net.codinux.banking.ui.extensions.verticalScroll import net.codinux.banking.ui.service.BankDataImporterAndExporter @Composable @@ -66,7 +67,7 @@ fun ExportScreen(onClosed: () -> Unit) { Spacer(Modifier.weight(1f)) } } else { - Column(Modifier.verticalScroll(ScrollState(0), enabled = true).horizontalScroll(ScrollState(0), enabled = true)) { + Column(Modifier.verticalScroll().horizontalScroll()) { SelectionContainer { Text(exportedDataText, fontFamily = FontFamily.Monospace) } diff --git a/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/state/UiState.kt b/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/state/UiState.kt index 4c15b5d..90dbcb9 100644 --- a/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/state/UiState.kt +++ b/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/state/UiState.kt @@ -54,6 +54,8 @@ class UiState : ViewModel() { val showTransferMoneyDialogData = MutableStateFlow(null) + val showAccountTransactionDetailsScreenForId = MutableStateFlow(null) + val showExportScreen = MutableStateFlow(false)