Grouping transactions by month

This commit is contained in:
dankito 2024-08-25 02:25:30 +02:00
parent 32657331f9
commit 3124bfc8f8
6 changed files with 75 additions and 10 deletions

View File

@ -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)
}
}

View File

@ -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) {

View File

@ -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<AccountTransaction>) {
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)
}
}
}
}
}
}

View File

@ -9,4 +9,6 @@ object Colors {
val Zinc200 = Color(228, 228, 231)
val Zinc700 = Color(63, 63, 70)
}

View File

@ -0,0 +1,7 @@
package net.codinux.banking.ui.service
object DI {
val formatUtil = FormatUtil()
}

View File

@ -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"