Heading for Transaction and Category added

This commit is contained in:
Florian 2025-01-20 09:08:44 +01:00
parent c97e422928
commit 8fc52e576d
4 changed files with 110 additions and 22 deletions

View File

@ -2,17 +2,21 @@ package at.xaxa.ledger.ui.category.overview
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.lifecycle.viewmodel.compose.viewModel
import at.xaxa.ledger.ui.AppViewModelProvider
import at.xaxa.ledger.ui.ButtonSuccess
@ -25,7 +29,6 @@ fun CategoryOverview(
onCardClick: (Int) -> Unit,
categoryViewModel: OverviewCategoryViewModel = viewModel(factory = AppViewModelProvider.Factory)
) {
val categories by categoryViewModel.categoryUiState.categories.collectAsState(initial = emptyList())
Column(
@ -34,6 +37,16 @@ fun CategoryOverview(
.padding(16.dp, 0.dp),
horizontalAlignment = Alignment.CenterHorizontally
) {
// Headline: "Your Categories"
Text(
text = "Your Categories",
fontSize = 24.sp,
fontWeight = FontWeight.Bold,
modifier = Modifier
.padding(vertical = 16.dp)
.align(Alignment.Start)
)
LazyColumn(
Modifier.weight(1f)
) {

View File

@ -3,6 +3,7 @@ package at.xaxa.ledger.ui.entry.add
import android.util.Log
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
@ -15,6 +16,7 @@ import androidx.compose.material3.ExposedDropdownMenuBox
import androidx.compose.material3.ExposedDropdownMenuDefaults
import androidx.compose.material3.Icon
import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.Switch
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.runtime.Composable
@ -35,6 +37,7 @@ import at.xaxa.ledger.ui.ButtonSuccess
import at.xaxa.ledger.ui.DatePickerDocked
import at.xaxa.ledger.ui.category.iconNames
import at.xaxa.ledger.ui.category.icons
import kotlin.math.abs
import kotlin.math.log
@OptIn(ExperimentalMaterial3Api::class)
@ -50,10 +53,11 @@ fun Add(
var spending by remember { mutableStateOf("") }
var selectedDate by remember { mutableLongStateOf(System.currentTimeMillis()) }
var expanded by remember { mutableStateOf(false) }
var selectedIconIndex by remember { mutableStateOf(0) } // Store index of selected icon
var selectedCategoryName by remember { mutableStateOf("") } // Store index of selected icon
var selectedIconIndex by remember { mutableStateOf(0) }
var selectedCategoryName by remember { mutableStateOf("") }
var selectedCategory by remember { mutableIntStateOf(-1) }
var parsingError by remember { mutableStateOf(false) }
var isIncome by remember { mutableStateOf(true) } // true for Income, false for Expense
if (parsingError) {
AlertDialog(
@ -97,10 +101,14 @@ fun Add(
modifier = Modifier
.fillMaxWidth()
)
// Toggle between Income and Expense
OutlinedTextField(
value = spending,
onValueChange = {
val isValidSpending = it.matches(Regex("^[+-]?\\d*(\\.\\d{0,2})?$"))
val isValidSpending = it.matches(Regex("^-?\\d*(\\.\\d{0,2})?$"))
if (isValidSpending) {
spending = it
}
@ -115,13 +123,13 @@ fun Add(
onExpandedChange = { expanded = it }
) {
OutlinedTextField(
value = selectedCategoryName, // Show selected icon name
value = selectedCategoryName,
onValueChange = {},
label = { Text("Category") },
readOnly = true,
leadingIcon = {
Icon(
imageVector = icons[selectedIconIndex], // Replace with your desired icon
imageVector = icons[selectedIconIndex],
contentDescription = "Leading Icon"
)
},
@ -139,9 +147,9 @@ fun Add(
) {
categories.forEachIndexed { index, category ->
DropdownMenuItem(
text = { Text(text = category.categoryName) }, // Use name from iconNames
text = { Text(text = category.categoryName) },
onClick = {
selectedIconIndex = category.icon // Update selected index
selectedIconIndex = category.icon
expanded = false
selectedCategoryName = category.categoryName
selectedCategory = category._id
@ -160,7 +168,28 @@ fun Add(
DatePickerDocked { dateMilis ->
selectedDate = dateMilis
}
Row(
modifier = Modifier
.fillMaxWidth()
.padding(8.dp),
verticalAlignment = Alignment.CenterVertically
) {
Text(text = if (isIncome) "Income" else "Expense")
Switch(
modifier = Modifier.padding(8.dp, 0.dp),
checked = isIncome,
onCheckedChange = {
isIncome = it
if(isIncome){
spending = abs(spending.toFloat()).toString()
}else{
spending = (abs(spending.toFloat())*-1f).toString()
}
}
)
}
}
Box(
modifier = Modifier
@ -171,8 +200,7 @@ fun Add(
modifier = Modifier,
"Add Transaction",
onClick = {
val isValidSpending = spending.matches(Regex("^[+-]?\\d*(\\.\\d{0,2})?$"))
val isValidSpending = spending.matches(Regex("^-?\\d*(\\.\\d{0,2})?$"))
if (name.isNotBlank() && isValidSpending && selectedDate != 0L && selectedCategory != -1) {
val newEntry = Entry(
id = 0,
@ -184,7 +212,7 @@ fun Add(
addViewModel.addEntryToDB(newEntry)
onCardClick()
} else {
parsingError = true;
parsingError = true
}
}
)

View File

@ -2,6 +2,7 @@ package at.xaxa.ledger.ui.entry.edit
import android.util.Log
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
@ -12,6 +13,7 @@ import androidx.compose.material3.ExposedDropdownMenuDefaults
import androidx.compose.material3.ExposedDropdownMenuDefaults.TrailingIcon
import androidx.compose.material3.Icon
import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.Switch
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
@ -32,6 +34,7 @@ import at.xaxa.ledger.ui.ButtonSuccess
import at.xaxa.ledger.ui.DatePickerDocked
import at.xaxa.ledger.ui.category.iconNames
import at.xaxa.ledger.ui.category.icons
import kotlin.math.abs
@OptIn(ExperimentalMaterial3Api::class)
@Composable
@ -48,16 +51,16 @@ fun Edit(
var selectedIconIndex by remember { mutableStateOf(category.icon) }
var selectedCategoryName by remember { mutableStateOf(category.categoryName) }
var selectedCategory by remember { mutableIntStateOf(category._id) }
var expanded by remember { mutableStateOf(false) }
var isIncome by remember { mutableStateOf(entry.amount >= 0) } // true for Income, false for Expense
LaunchedEffect(category) {
selectedIconIndex = category.icon
selectedCategoryName = category.categoryName
selectedCategory = category._id
isIncome = (entry.amount >= 0)
}
Column(
modifier = modifier
.fillMaxSize()
@ -73,12 +76,17 @@ fun Edit(
label = { Text("Name") },
modifier = Modifier.fillMaxWidth()
)
// Toggle between Income and Expense
OutlinedTextField(
value = entry.amount.toString(),
onValueChange = {
val isValidSpending = it.matches(Regex("^[+-]?\\d*(\\.\\d{0,2})?$"))
val isValidSpending = it.matches(Regex("^-?\\d*(\\.\\d{0,2})?$"))
if (isValidSpending) {
editViewModel.updateEntry(entry.copy(amount = it.toFloat()))
val amount = if (isIncome) it.toFloat() else -it.toFloat()
editViewModel.updateEntry(entry.copy(amount = amount))
}
},
label = { Text("Amount") },
@ -90,13 +98,13 @@ fun Edit(
onExpandedChange = { expanded = it }
) {
OutlinedTextField(
value = selectedCategoryName, // Show selected category name
value = selectedCategoryName,
onValueChange = {},
label = { Text("Category") },
readOnly = true,
leadingIcon = {
Icon(
imageVector = icons[selectedIconIndex], // Show selected icon
imageVector = icons[selectedIconIndex],
contentDescription = "Leading Icon"
)
},
@ -116,9 +124,9 @@ fun Edit(
DropdownMenuItem(
text = { Text(text = category.categoryName) },
onClick = {
selectedIconIndex = category.icon // Update selected icon index
selectedCategoryName = category.categoryName // Update selected category name
selectedCategory = category._id // Update selected category ID
selectedIconIndex = category.icon
selectedCategoryName = category.categoryName
selectedCategory = category._id
expanded = false
},
leadingIcon = {
@ -135,7 +143,29 @@ fun Edit(
DatePickerDocked(entry) { dateMilis ->
editViewModel.updateEntry(entry.copy(date = dateMilis))
}
Row(
modifier = Modifier
.fillMaxWidth()
.padding(vertical = 8.dp),
verticalAlignment = Alignment.CenterVertically
) {
Text(text = if (isIncome) "Income" else "Expense")
Switch(
modifier = Modifier.padding(8.dp, 0.dp),
checked = isIncome,
onCheckedChange = {
isIncome = it
if(isIncome){
editViewModel.updateEntry(entry.copy(amount = abs(entry.amount)))
}else{
editViewModel.updateEntry(entry.copy(amount = abs(entry.amount)*-1f))
}
}
)
}
}
Column(
modifier = Modifier.fillMaxWidth(),
@ -155,6 +185,7 @@ fun Edit(
modifier = Modifier.fillMaxWidth(),
text = "Done",
onClick = {
editViewModel.updateEntry(entry)
editViewModel.saveEntry()
onCardClick()
}

View File

@ -10,12 +10,15 @@ import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.lifecycle.viewmodel.compose.viewModel
import at.xaxa.ledger.ui.AppViewModelProvider
import at.xaxa.ledger.ui.ButtonSuccess
@ -37,18 +40,31 @@ fun Home(modifier: Modifier = Modifier, onCardClick: (Int) -> Unit, onButtonClic
.padding(16.dp, 0.dp),
horizontalAlignment = Alignment.CenterHorizontally
) {
LazyColumn(
modifier = Modifier
.weight(1f)
) {
stickyHeader {
HeaderCard(modifier = modifier, "%.2f".format(balance)+"", onCatButtonClick)
Text(
text = "Your Transactions",
fontSize = 24.sp,
fontWeight = FontWeight.Bold,
modifier = Modifier
.padding(vertical = 16.dp)
.align(Alignment.Start)
)
}
items(state) { item ->
Column(
modifier = Modifier.padding(vertical = 4.dp)
) {
HorizontalCard(
modifier = modifier,
name = item.name,