Merge remote-tracking branch 'origin/Florian'

# Conflicts:
#	Ledger/app/src/main/java/at/xaxa/ledger/ui/AppViewModelProvider.kt
#	Ledger/app/src/main/java/at/xaxa/ledger/ui/category/edit/EditCategory.kt
This commit is contained in:
Xaver 2025-01-15 20:57:02 +01:00
commit 8b57b46546
6 changed files with 160 additions and 92 deletions

View File

@ -43,9 +43,15 @@ class EntryRepository(private val ledgerDao: LedgerDao){
suspend fun updateEntry(entry: Entry) {
ledgerDao.updateEntry(EntryEntity(entry.id, entry.name, entry.amount, entry.date, entry.categoryID))
}
suspend fun updateCategory(category: CategoryEntity) {
ledgerDao.updateCategory(CategoryEntity(category._id, category.categoryName, category.icon))
}
suspend fun deleteEntry(entry: Entry) {
ledgerDao.deleteEntry(EntryEntity(_id = entry.id, entry.name, entry.amount, entry.date, entry.categoryID))
}
suspend fun deleteCategory(category: CategoryEntity) {
ledgerDao.deleteCategory(CategoryEntity(_id = category._id, category.categoryName, category.icon))
}
}

View File

@ -7,7 +7,8 @@ import androidx.lifecycle.viewmodel.viewModelFactory
import at.xaxa.ledger.LedgerApplication
import at.xaxa.ledger.ui.entry.add.AddViewModel
import at.xaxa.ledger.ui.category.CategoryViewModel
import at.xaxa.ledger.ui.entry.edit.EditViewModel
import at.xaxa.ledger.ui.category.edit.EditCategoryViewModel
import at.xaxa.ledger.ui.edit.EditViewModel
import at.xaxa.ledger.ui.home.HomeViewModel
@ -27,5 +28,8 @@ object AppViewModelProvider {
initializer {
CategoryViewModel(this.createSavedStateHandle(), (this[APPLICATION_KEY] as LedgerApplication).entryRepository)
}
initializer {
EditCategoryViewModel(this.createSavedStateHandle(), (this[APPLICATION_KEY] as LedgerApplication).entryRepository)
}
}
}

View File

@ -81,7 +81,7 @@ fun LedgerApp(modifier: Modifier = Modifier){
backStackEntry ->
EditCategory(
modifier = Modifier,
onCardClick = {
onButtonClick = {
navController.navigate("category")
}
)
@ -89,7 +89,7 @@ fun LedgerApp(modifier: Modifier = Modifier){
composable(AppRoutes.AddCategory.route){
AddCategory(
onButtonClick = {
navController.navigate("gome")
navController.navigate("home")
}
)
}

View File

@ -1,6 +1,7 @@
package at.xaxa.ledger.ui.category.edit
import android.util.Log
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
@ -8,7 +9,9 @@ import androidx.compose.foundation.layout.padding
import androidx.compose.material3.DropdownMenuItem
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.ExposedDropdownMenuBox
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.Text
import androidx.compose.runtime.Composable
@ -22,43 +25,50 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel
import at.xaxa.ledger.data.Entry
import at.xaxa.ledger.data.db.Category.CategoryEntity
import at.xaxa.ledger.ui.AppViewModelProvider
import at.xaxa.ledger.ui.ButtonDanger
import at.xaxa.ledger.ui.ButtonSuccess
import at.xaxa.ledger.ui.DatePickerDocked
import at.xaxa.ledger.ui.entry.edit.EditViewModel
import at.xaxa.ledger.ui.category.CategoryViewModel
import at.xaxa.ledger.ui.category.iconNames
import at.xaxa.ledger.ui.category.icons
import at.xaxa.ledger.ui.edit.EditViewModel
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun EditCategory(modifier: Modifier = Modifier, onCardClick: () -> Unit, editViewModel : EditViewModel = viewModel(factory = AppViewModelProvider.Factory), onValueChange: (Entry) -> Unit = {},
fun EditCategory(
onButtonClick: () -> Unit,
modifier: Modifier = Modifier,
editCategoryViewModel: EditCategoryViewModel = viewModel(factory = AppViewModelProvider.Factory)
) {
/*
val entry = editViewModel.editUiState.entry
val category = editViewModel.categoryUi.category
val categories by editViewModel.categoryListUiState.categories.collectAsState(initial = emptyList())
var expanded by remember { mutableStateOf(false) }
var expanded by remember { mutableStateOf(false) } // Controls dropdown visibility
val category = editCategoryViewModel.categoryUi.category
var selectedIconIndex = category.icon // Store index of selected icon
Log.d(
"kkjkjkjkj",
category.categoryName)
/*
val categories by categoryViewModel.categoryUiState.categories.collectAsState(initial = emptyList())
val category = categoryViewModel.categoryUi.category
var expanded by remember { mutableStateOf(false) }*/
Column(
modifier = modifier.fillMaxSize()
modifier = modifier
.fillMaxSize()
.padding(16.dp, 0.dp),
horizontalAlignment = Alignment.CenterHorizontally
) {
Column(
Modifier.weight(1f)
) {
OutlinedTextField(
value = entry.name,
onValueChange = {editViewModel.updateEntry(entry.copy(name = it))},
label = { Text("Name") },
modifier = Modifier
.fillMaxWidth()
)
OutlinedTextField(
value = entry.amount.toString(),
onValueChange = { editViewModel.updateEntry(entry.copy(amount = it.toFloat())) },
label = { Text("Spending") },
value = category.categoryName,
onValueChange = { editCategoryViewModel.updateCategory(category.copy(categoryName = it)) },
label = { Text("Category Name") },
modifier = Modifier
.fillMaxWidth()
)
@ -67,65 +77,64 @@ fun EditCategory(modifier: Modifier = Modifier, onCardClick: () -> Unit, editVie
expanded = expanded,
onExpandedChange = { expanded = it }
) {
// TextField to display the selected item and trigger the dropdown
OutlinedTextField(
value = category.categoryName,
value = iconNames[selectedIconIndex], // Show selected icon name
onValueChange = {},
label = { Text("Category") },
label = { Text("Icon") },
readOnly = true,
leadingIcon = {
Icon(
imageVector = icons[selectedIconIndex], // Replace with your desired icon
contentDescription = "Leading Icon"
)
},
trailingIcon = {
TrailingIcon(expanded = expanded)
ExposedDropdownMenuDefaults.TrailingIcon(expanded = expanded)
},
modifier = Modifier
.menuAnchor()
.fillMaxWidth()
)
// Dropdown menu
ExposedDropdownMenu(
expanded = expanded,
onDismissRequest = { expanded = false }
) {
categories.forEach { item ->
icons.forEachIndexed { index, icon ->
DropdownMenuItem(
text = { Text(text = item.categoryName) },
text = { Text(text = iconNames[index]) }, // Use name from iconNames
onClick = {
entry.copy(categoryID = item._id)
editViewModel.updateEntry(entry)
selectedIconIndex = index // Update selected index
category.copy(_id = index)
editCategoryViewModel.updateCategory(category)
expanded = false
},
leadingIcon = {
androidx.compose.material3.Icon(
imageVector = icon,
contentDescription = iconNames[index]
)
}
)
}
}
}
Log.w("xaver", entry.date.toString())
DatePickerDocked(entry){
dateMilis -> editViewModel.updateEntry(entry.copy(date = dateMilis))
}
}
Column(
modifier = Modifier.fillMaxWidth(),
horizontalAlignment = Alignment.CenterHorizontally // Center buttons horizontally
) {
ButtonDanger(
Box(
modifier = Modifier
.fillMaxWidth()
.padding(bottom = 8.dp),
text = "Delete",
onClick = { onCardClick() }
)
.fillMaxWidth(),
contentAlignment = Alignment.Center
) {
ButtonSuccess(
modifier = Modifier.fillMaxWidth(), // Add spacing between buttons
text = "Done",
modifier = Modifier,
"Edit Category",
onClick = {
editViewModel.saveEntry()
onCardClick()
editCategoryViewModel.saveCategory()
onButtonClick()
}
)
}
}*/
}
}

View File

@ -0,0 +1,66 @@
package at.xaxa.ledger.ui.category.edit
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.lifecycle.SavedStateHandle
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import at.xaxa.ledger.data.Entry
import at.xaxa.ledger.data.EntryRepository
import at.xaxa.ledger.data.db.Category.CategoryEntity
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
data class CategoryUIState(val category: CategoryEntity = CategoryEntity(0,"",0))
class EditCategoryViewModel(private val savedStateHandle: SavedStateHandle,
private val entryRepository: EntryRepository
) : ViewModel() {
private val categoryId: Int = checkNotNull(savedStateHandle["categoryId"])
var categoryUiState by mutableStateOf(CategoryUIState())
var categoryUi by mutableStateOf(CategoryUIState())
private set
init {
viewModelScope.launch {
val category = withContext(Dispatchers.IO) {
entryRepository.findCategoryById(categoryId)
}
categoryUi = CategoryUIState(category)
}
}
fun updateCategory(category: CategoryEntity) {
categoryUi = categoryUi.copy(category = category)
}
fun onDeleteEntry(category: CategoryEntity) {
viewModelScope.launch {
entryRepository.deleteCategory(category)
}
}
fun saveCategory() {
viewModelScope.launch {
entryRepository.updateCategory(categoryUi.category)
}
}
fun findCategoryByID(categoryId: Int) {
viewModelScope.launch {
val category = withContext(Dispatchers.IO) {
entryRepository.findCategoryById(categoryId)
}
categoryUi = CategoryUIState(category)
}
}
}

View File

@ -61,23 +61,6 @@ class AddViewModel(
}
}
fun addCategory(category: CategoryEntity) {
viewModelScope.launch {
try {
val categoryEntity = CategoryEntity(
_id = category._id,
categoryName = category.categoryName,
icon = category.icon,
)
withContext(Dispatchers.IO) {
repository.insertCategory(categoryEntity) // Add game to the database
}
// Optionally, log or update UI state to reflect that the game was added
} catch (e: Exception) {
}
}
}
fun getAllCategories() {
viewModelScope.launch {