diff --git a/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/App.kt b/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/App.kt index e9579c3..67d52df 100644 --- a/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/App.kt +++ b/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/App.kt @@ -1,5 +1,6 @@ package net.codinux.banking.ui +import androidx.compose.foundation.background import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxHeight import androidx.compose.foundation.layout.fillMaxWidth @@ -17,10 +18,11 @@ import kotlinx.coroutines.launch import net.codinux.banking.client.model.AccountTransaction import net.codinux.banking.ui.composables.TransactionsList import net.codinux.banking.ui.service.BankingService +import net.codinux.banking.ui.service.Colors import org.jetbrains.compose.ui.tooling.preview.Preview private val typography = Typography( - body1 = TextStyle(fontSize = 14.sp) + body1 = TextStyle(fontSize = 14.sp, color = Colors.Zinc700) ) private val bankService = BankingService() @@ -36,7 +38,10 @@ fun App() { } MaterialTheme(typography = typography) { - Column(Modifier.fillMaxWidth().fillMaxHeight(), horizontalAlignment = Alignment.CenterHorizontally) { + Column( + Modifier.fillMaxWidth().fillMaxHeight().background(color = Colors.Zinc100), + horizontalAlignment = Alignment.CenterHorizontally + ) { TransactionsList(transactions) } } diff --git a/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/composables/TransactionListItem.kt b/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/composables/TransactionListItem.kt index 90310dc..c875a7a 100644 --- a/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/composables/TransactionListItem.kt +++ b/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/composables/TransactionListItem.kt @@ -10,9 +10,9 @@ import androidx.compose.ui.graphics.Color import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp import net.codinux.banking.client.model.AccountTransaction -import net.codinux.banking.ui.service.FormatUtil +import net.codinux.banking.ui.service.DI -private val formatUtil = FormatUtil() +private val formatUtil = DI.formatUtil @Composable fun TransactionListItem(transaction: AccountTransaction, backgroundColor: Color) { diff --git a/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/composables/TransactionsList.kt b/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/composables/TransactionsList.kt index 07a91a6..591fb3a 100644 --- a/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/composables/TransactionsList.kt +++ b/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/composables/TransactionsList.kt @@ -1,28 +1,58 @@ package net.codinux.banking.ui.composables -import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.* import androidx.compose.foundation.lazy.LazyColumn -import androidx.compose.foundation.lazy.itemsIndexed +import androidx.compose.foundation.lazy.items import androidx.compose.material.Divider import androidx.compose.material.MaterialTheme +import androidx.compose.material.Text import androidx.compose.runtime.Composable +import androidx.compose.runtime.derivedStateOf +import androidx.compose.runtime.getValue +import androidx.compose.runtime.remember import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color +import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import kotlinx.datetime.LocalDate import net.codinux.banking.client.model.AccountTransaction import net.codinux.banking.ui.service.Colors +import net.codinux.banking.ui.service.DI import org.jetbrains.compose.ui.tooling.preview.Preview @Composable fun TransactionsList(transactions: List) { + val groupedByMonth by remember(transactions) { + derivedStateOf { transactions.groupBy { LocalDate(it.valueDate.year, it.valueDate.monthNumber, 1) } } + } + LazyColumn( modifier = Modifier.padding(4.dp) ) { - itemsIndexed(transactions) { index, transaction -> - TransactionListItem(transaction, if (index % 2 == 0) Colors.Zinc100_50 else Color.White) + items(groupedByMonth.keys.sortedDescending()) { month -> + Column(modifier = Modifier.fillMaxWidth()) { + Text( + text = DI.formatUtil.formatMonth(month), + fontSize = 16.sp, + fontWeight = FontWeight.SemiBold, + modifier = Modifier.padding(top = 24.dp, bottom = 2.dp), + ) - if (index < transactions.size) { - Divider(color = Colors.Zinc200, thickness = 1.dp) + Spacer(Modifier.height(4.dp)) + + val monthTransactions = groupedByMonth[month].orEmpty().sortedByDescending { it.valueDate } + + Column(Modifier.background(Color.White)) { // LazyColumn inside LazyColumn is not allowed + monthTransactions.forEachIndexed { index, transaction -> + TransactionListItem(transaction, if (index % 2 == 1) Colors.Zinc100_50 else Color.Transparent) + + if (index < monthTransactions.size - 1) { + Divider(color = Colors.Zinc200, thickness = 1.dp) + } + } + } } } } diff --git a/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/service/Colors.kt b/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/service/Colors.kt index a89c085..f983621 100644 --- a/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/service/Colors.kt +++ b/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/service/Colors.kt @@ -9,4 +9,6 @@ object Colors { val Zinc200 = Color(228, 228, 231) + val Zinc700 = Color(63, 63, 70) + } \ No newline at end of file diff --git a/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/service/DI.kt b/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/service/DI.kt new file mode 100644 index 0000000..51107c6 --- /dev/null +++ b/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/service/DI.kt @@ -0,0 +1,7 @@ +package net.codinux.banking.ui.service + +object DI { + + val formatUtil = FormatUtil() + +} \ No newline at end of file diff --git a/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/service/FormatUtil.kt b/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/service/FormatUtil.kt index 4647079..40c3eb7 100644 --- a/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/service/FormatUtil.kt +++ b/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/service/FormatUtil.kt @@ -2,6 +2,7 @@ package net.codinux.banking.ui.service import androidx.compose.ui.graphics.Color import kotlinx.datetime.LocalDate +import kotlinx.datetime.Month import net.codinux.banking.client.model.Amount import net.codinux.banking.fints.extensions.toStringWithMinDigits @@ -10,6 +11,26 @@ class FormatUtil { fun formatDate(date: LocalDate): String = // TODO: find a better way "${date.dayOfMonth.toStringWithMinDigits(2)}.${date.monthNumber.toStringWithMinDigits(2)}.${date.year.toString().substring(2)}" + fun formatMonth(date: LocalDate): String = // TODO: find a better way + "${getMonthName(date.month)} ${date.year}" + + private fun getMonthName(month: Month): String = when (month) { + Month.JANUARY -> "Januar" + Month.FEBRUARY -> "Februar" + Month.MARCH -> "März" + Month.APRIL -> "April" + Month.MAY -> "Mai" + Month.JUNE -> "Juni" + Month.JULY -> "Juli" + Month.AUGUST -> "August" + Month.SEPTEMBER -> "September" + Month.OCTOBER -> "Oktober" + Month.NOVEMBER -> "November" + Month.DECEMBER -> "Dezember" + else -> "Irgendwas stimmt hier nicht" + } + + fun formatAmount(amount: Amount, currency: String): String { // TODO: find a better way val parts = amount.amount.split('.') val decimalPart = if (parts.size == 2) parts[1] else "00"