From 1f6d125571389fa3b219bf0eee6584e88763ba26 Mon Sep 17 00:00:00 2001
From: dovicrad <dovicrad@fel.cvut.cz>
Date: Tue, 16 Apr 2024 19:42:32 +0200
Subject: [PATCH 01/12] :cooking: add transaction database and handeling

---
 .idea/deploymentTargetDropDown.xml            |   3 +
 .idea/misc.xml                                |   1 -
 app/build.gradle.kts                          |  21 +-
 .../ExampleInstrumentedTest.kt                |   6 +-
 app/src/main/AndroidManifest.xml              |   4 +-
 .../financemanagement/FinanceManagementApp.kt |   2 +-
 .../FinanceManagementApplication.kt           |  13 ++
 .../fel/pda/financemanagement/MainActivity.kt |   7 -
 .../database/OfflineTransactionRepository.kt  |  12 ++
 .../financemanagement/database/Transaction.kt |  15 ++
 .../database/TransactionDao.kt                |  34 ++++
 .../database/TransactionDatabase.kt           |  34 ++++
 .../database/TransactionRepository.kt         |  12 ++
 .../database/typeConvertion/Converters.kt     |  16 ++
 .../pda/financemanagement/di/AppContainer.kt  |  16 ++
 .../model/TransactionCategory.kt              |  17 ++
 .../financemanagement/model/common/Result.kt  |  16 ++
 .../ui/components/BottomNavigation.kt         |   2 +-
 .../ui/components/CommonScreenForState.kt     |  47 +++++
 .../financemanagement/ui/components/TopBar.kt |   2 +-
 .../ui/screens/TransactionsScreen.kt          | 125 ------------
 .../transactions/TransactionViewModel.kt      |  65 +++++++
 .../transactions/TransactionsScreen.kt        | 184 ++++++++++++++++++
 .../ui/utils/AppViewModelProvider.kt          |  21 ++
 .../pda/financemanagement/ExampleUnitTest.kt  |   3 +-
 build.gradle.kts                              |   1 +
 gradle/libs.versions.toml                     |  25 ++-
 27 files changed, 554 insertions(+), 150 deletions(-)
 create mode 100644 app/src/main/java/cz/cvut/fel/pda/financemanagement/FinanceManagementApplication.kt
 create mode 100644 app/src/main/java/cz/cvut/fel/pda/financemanagement/database/OfflineTransactionRepository.kt
 create mode 100644 app/src/main/java/cz/cvut/fel/pda/financemanagement/database/Transaction.kt
 create mode 100644 app/src/main/java/cz/cvut/fel/pda/financemanagement/database/TransactionDao.kt
 create mode 100644 app/src/main/java/cz/cvut/fel/pda/financemanagement/database/TransactionDatabase.kt
 create mode 100644 app/src/main/java/cz/cvut/fel/pda/financemanagement/database/TransactionRepository.kt
 create mode 100644 app/src/main/java/cz/cvut/fel/pda/financemanagement/database/typeConvertion/Converters.kt
 create mode 100644 app/src/main/java/cz/cvut/fel/pda/financemanagement/di/AppContainer.kt
 create mode 100644 app/src/main/java/cz/cvut/fel/pda/financemanagement/model/TransactionCategory.kt
 create mode 100644 app/src/main/java/cz/cvut/fel/pda/financemanagement/model/common/Result.kt
 create mode 100644 app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/components/CommonScreenForState.kt
 delete mode 100644 app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/TransactionsScreen.kt
 create mode 100644 app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/transactions/TransactionViewModel.kt
 create mode 100644 app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/transactions/TransactionsScreen.kt
 create mode 100644 app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/utils/AppViewModelProvider.kt

diff --git a/.idea/deploymentTargetDropDown.xml b/.idea/deploymentTargetDropDown.xml
index 0c0c338..9c96b2b 100644
--- a/.idea/deploymentTargetDropDown.xml
+++ b/.idea/deploymentTargetDropDown.xml
@@ -2,6 +2,9 @@
 <project version="4">
   <component name="deploymentTargetDropDown">
     <value>
+      <entry key="MainActivity">
+        <State />
+      </entry>
       <entry key="app">
         <State />
       </entry>
diff --git a/.idea/misc.xml b/.idea/misc.xml
index 0ad17cb..8978d23 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -1,4 +1,3 @@
-<?xml version="1.0" encoding="UTF-8"?>
 <project version="4">
   <component name="ExternalStorageConfigurationManager" enabled="true" />
   <component name="ProjectRootManager" version="2" languageLevel="JDK_17" default="true" project-jdk-name="jbr-17" project-jdk-type="JavaSDK">
diff --git a/app/build.gradle.kts b/app/build.gradle.kts
index c5ae397..befa91c 100644
--- a/app/build.gradle.kts
+++ b/app/build.gradle.kts
@@ -1,6 +1,7 @@
 plugins {
     alias(libs.plugins.androidApplication)
     alias(libs.plugins.jetbrainsKotlinAndroid)
+    alias(libs.plugins.ksp)
 }
 
 android {
@@ -50,7 +51,6 @@ android {
 }
 
 dependencies {
-
     implementation(libs.androidx.core.ktx)
     implementation(libs.androidx.lifecycle.runtime.ktx)
     implementation(libs.androidx.activity.compose)
@@ -59,8 +59,25 @@ dependencies {
     implementation(libs.androidx.ui.graphics)
     implementation(libs.androidx.ui.tooling.preview)
     implementation(libs.androidx.material3)
-    implementation(libs.androidx.navigation.runtime.ktx)
     implementation(libs.androidx.navigation.compose)
+    implementation(libs.androidx.lifecycle.runtime.compose)
+    implementation(libs.androidx.datastore.preferences)
+
+    //Room
+    implementation(libs.androidx.room.runtime)
+    ksp(libs.androidx.room.compiler)
+    implementation(libs.androidx.room.ktx)
+
+    //Json and GeoJson
+    implementation(libs.geojson.jackson)
+    implementation(libs.jackson.module.kotlin)
+
+    implementation(libs.retrofit)
+    implementation(libs.converterJackson)
+
+    //Glide
+    implementation(libs.compose)
+
     testImplementation(libs.junit)
     androidTestImplementation(libs.androidx.junit)
     androidTestImplementation(libs.androidx.espresso.core)
diff --git a/app/src/androidTest/java/cz/cvut/fel/pda/financemanagement/ExampleInstrumentedTest.kt b/app/src/androidTest/java/cz/cvut/fel/pda/financemanagement/ExampleInstrumentedTest.kt
index b729528..cbe2fe2 100644
--- a/app/src/androidTest/java/cz/cvut/fel/pda/financemanagement/ExampleInstrumentedTest.kt
+++ b/app/src/androidTest/java/cz/cvut/fel/pda/financemanagement/ExampleInstrumentedTest.kt
@@ -1,13 +1,11 @@
 package cz.cvut.fel.pda.financemanagement
 
-import androidx.test.platform.app.InstrumentationRegistry
 import androidx.test.ext.junit.runners.AndroidJUnit4
-
+import androidx.test.platform.app.InstrumentationRegistry
+import org.junit.Assert.assertEquals
 import org.junit.Test
 import org.junit.runner.RunWith
 
-import org.junit.Assert.*
-
 /**
  * Instrumented test, which will execute on an Android device.
  *
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 4509b3a..024c48e 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -3,6 +3,7 @@
     xmlns:tools="http://schemas.android.com/tools">
 
     <application
+        android:name=".FinanceManagementApplication"
         android:allowBackup="true"
         android:dataExtractionRules="@xml/data_extraction_rules"
         android:fullBackupContent="@xml/backup_rules"
@@ -11,11 +12,10 @@
         android:roundIcon="@mipmap/ic_launcher_round"
         android:supportsRtl="true"
         android:theme="@style/Theme.FinanceManagement"
-        tools:targetApi="31">
+        >
         <activity
             android:name=".MainActivity"
             android:exported="true"
-            android:label="@string/app_name"
             android:theme="@style/Theme.FinanceManagement">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
diff --git a/app/src/main/java/cz/cvut/fel/pda/financemanagement/FinanceManagementApp.kt b/app/src/main/java/cz/cvut/fel/pda/financemanagement/FinanceManagementApp.kt
index 78f9a69..6760bdf 100644
--- a/app/src/main/java/cz/cvut/fel/pda/financemanagement/FinanceManagementApp.kt
+++ b/app/src/main/java/cz/cvut/fel/pda/financemanagement/FinanceManagementApp.kt
@@ -9,7 +9,7 @@ import androidx.navigation.compose.rememberNavController
 import cz.cvut.fel.pda.financemanagement.ui.screens.AccountsScreen
 import cz.cvut.fel.pda.financemanagement.ui.screens.CategoriesScreen
 import cz.cvut.fel.pda.financemanagement.ui.screens.LoansScreen
-import cz.cvut.fel.pda.financemanagement.ui.screens.TransactionsScreen
+import cz.cvut.fel.pda.financemanagement.ui.screens.transactions.TransactionsScreen
 
 
 enum class FinanceManagementScreens() {
diff --git a/app/src/main/java/cz/cvut/fel/pda/financemanagement/FinanceManagementApplication.kt b/app/src/main/java/cz/cvut/fel/pda/financemanagement/FinanceManagementApplication.kt
new file mode 100644
index 0000000..785cbdd
--- /dev/null
+++ b/app/src/main/java/cz/cvut/fel/pda/financemanagement/FinanceManagementApplication.kt
@@ -0,0 +1,13 @@
+package cz.cvut.fel.pda.financemanagement
+
+import android.app.Application
+import cz.cvut.fel.pda.financemanagement.di.AppContainer
+import cz.cvut.fel.pda.financemanagement.di.AppDataContainer
+class FinanceManagementApplication : Application(){
+    lateinit var container: AppContainer
+
+    override fun onCreate() {
+        super.onCreate()
+        container = AppDataContainer(this)
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/cz/cvut/fel/pda/financemanagement/MainActivity.kt b/app/src/main/java/cz/cvut/fel/pda/financemanagement/MainActivity.kt
index ba7ceb9..35c973b 100644
--- a/app/src/main/java/cz/cvut/fel/pda/financemanagement/MainActivity.kt
+++ b/app/src/main/java/cz/cvut/fel/pda/financemanagement/MainActivity.kt
@@ -3,13 +3,6 @@ package cz.cvut.fel.pda.financemanagement
 import android.os.Bundle
 import androidx.activity.ComponentActivity
 import androidx.activity.compose.setContent
-import androidx.compose.foundation.layout.fillMaxSize
-import androidx.compose.material3.MaterialTheme
-import androidx.compose.material3.Surface
-import androidx.compose.material3.Text
-import androidx.compose.runtime.Composable
-import androidx.compose.ui.Modifier
-import androidx.compose.ui.tooling.preview.Preview
 import cz.cvut.fel.pda.financemanagement.ui.theme.FinanceManagementTheme
 
 class MainActivity : ComponentActivity() {
diff --git a/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/OfflineTransactionRepository.kt b/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/OfflineTransactionRepository.kt
new file mode 100644
index 0000000..d2dd746
--- /dev/null
+++ b/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/OfflineTransactionRepository.kt
@@ -0,0 +1,12 @@
+package cz.cvut.fel.pda.financemanagement.database
+
+import kotlinx.coroutines.flow.Flow
+
+class OfflineTransactionRepository(private val transactionDao: TransactionDao): TransactionRepository{
+    override fun getAllTransactionsStream(): Flow<List<Transaction>> = transactionDao.getAllTransactions()
+    override fun getTransactionForIdStream(id: Long): Flow<Transaction?> = transactionDao.getTransactionForId(id)
+    override suspend fun insertTransactions(vararg transactions: Transaction) = transactionDao.insertTransactions(*transactions)
+    override suspend fun deleteTransaction(transaction: Transaction) = transactionDao.delete(transaction)
+    override suspend fun deleteAllTransactions() = transactionDao.deleteAll()
+    override suspend fun updateTransactions(vararg transactions: Transaction) = transactionDao.updateTransactions(*transactions)
+}
\ No newline at end of file
diff --git a/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/Transaction.kt b/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/Transaction.kt
new file mode 100644
index 0000000..fe7ecd1
--- /dev/null
+++ b/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/Transaction.kt
@@ -0,0 +1,15 @@
+package cz.cvut.fel.pda.financemanagement.database
+
+import androidx.room.Entity
+import androidx.room.PrimaryKey
+import java.math.BigDecimal
+
+
+@Entity(tableName = "transaction")
+data class Transaction(
+    @PrimaryKey(autoGenerate = true)
+    val id: Long = 0,
+    val description: String = "",
+    val imageUrl: String = "",
+    val amount: BigDecimal = BigDecimal.ZERO
+)
diff --git a/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/TransactionDao.kt b/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/TransactionDao.kt
new file mode 100644
index 0000000..50d5aa3
--- /dev/null
+++ b/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/TransactionDao.kt
@@ -0,0 +1,34 @@
+package cz.cvut.fel.pda.financemanagement.database
+
+import androidx.room.Dao
+import androidx.room.Delete
+import androidx.room.Insert
+import androidx.room.OnConflictStrategy
+import androidx.room.Query
+import androidx.room.Update
+import kotlinx.coroutines.flow.Flow
+
+@Dao
+interface TransactionDao {
+
+    @Query("SELECT * FROM `transaction` ORDER BY id ASC")
+    fun getAllTransactions(): Flow<List<Transaction>>
+
+    @Query("SELECT * FROM `transaction` WHERE id = :id")
+    fun getTransactionForId(id: Long): Flow<Transaction>
+
+    @Insert(onConflict = OnConflictStrategy.REPLACE)
+    suspend fun insertTransactions(vararg transactions: Transaction)
+
+    @Update
+    suspend fun updateTransactions(vararg transactions: Transaction)
+
+    @Delete
+    suspend fun delete(item: Transaction)
+
+    @Query("DELETE FROM `transaction`")
+    suspend fun deleteAll()
+
+    @Query("SELECT * FROM `transaction` ORDER BY id ASC")
+    suspend fun getTransactions(): List<Transaction>
+}
\ No newline at end of file
diff --git a/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/TransactionDatabase.kt b/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/TransactionDatabase.kt
new file mode 100644
index 0000000..295d19f
--- /dev/null
+++ b/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/TransactionDatabase.kt
@@ -0,0 +1,34 @@
+package cz.cvut.fel.pda.financemanagement.database
+
+import android.content.Context
+import androidx.room.Database
+import androidx.room.Room
+import androidx.room.RoomDatabase
+import androidx.room.TypeConverters
+import cz.cvut.fel.pda.financemanagement.database.typeConvertion.Converters
+
+@Database(entities = [Transaction::class], version = 4, exportSchema = false)
+@TypeConverters(Converters::class)
+abstract class TransactionDatabase : RoomDatabase(){
+    abstract fun transactionDao(): TransactionDao
+
+    companion object{
+        @Volatile
+        private var INSTANCE: TransactionDatabase? = null
+
+        fun getDatabase(context: Context): TransactionDatabase {
+            return INSTANCE ?: synchronized(this) {
+                Room.databaseBuilder(
+                    context.applicationContext,
+                    TransactionDatabase::class.java,
+                    "transaction_database"
+                )
+                .fallbackToDestructiveMigration()
+                .build()
+                .also {
+                    INSTANCE = it
+                }
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/TransactionRepository.kt b/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/TransactionRepository.kt
new file mode 100644
index 0000000..d16ad62
--- /dev/null
+++ b/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/TransactionRepository.kt
@@ -0,0 +1,12 @@
+package cz.cvut.fel.pda.financemanagement.database
+
+import kotlinx.coroutines.flow.Flow
+
+interface TransactionRepository {
+    fun getAllTransactionsStream(): Flow<List<Transaction>>
+    fun getTransactionForIdStream(id: Long): Flow<Transaction?>
+    suspend fun insertTransactions(vararg transactions: Transaction)
+    suspend fun deleteTransaction(transaction: Transaction)
+    suspend fun deleteAllTransactions()
+    suspend fun updateTransactions(vararg transactions: Transaction)
+}
\ No newline at end of file
diff --git a/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/typeConvertion/Converters.kt b/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/typeConvertion/Converters.kt
new file mode 100644
index 0000000..23841c0
--- /dev/null
+++ b/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/typeConvertion/Converters.kt
@@ -0,0 +1,16 @@
+package cz.cvut.fel.pda.financemanagement.database.typeConvertion
+
+import androidx.room.TypeConverter
+import java.math.BigDecimal
+
+class Converters {
+    @TypeConverter
+    fun fromBigDecimal(value: BigDecimal): String {
+        return value.toString()
+    }
+
+    @TypeConverter
+    fun toBigDecimal(value: String): BigDecimal {
+        return BigDecimal(value)
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/cz/cvut/fel/pda/financemanagement/di/AppContainer.kt b/app/src/main/java/cz/cvut/fel/pda/financemanagement/di/AppContainer.kt
new file mode 100644
index 0000000..7510af9
--- /dev/null
+++ b/app/src/main/java/cz/cvut/fel/pda/financemanagement/di/AppContainer.kt
@@ -0,0 +1,16 @@
+package cz.cvut.fel.pda.financemanagement.di
+
+import android.content.Context
+import cz.cvut.fel.pda.financemanagement.database.OfflineTransactionRepository
+import cz.cvut.fel.pda.financemanagement.database.TransactionDatabase
+import cz.cvut.fel.pda.financemanagement.database.TransactionRepository
+
+interface AppContainer {
+    val transactionRepository: TransactionRepository
+}
+
+class AppDataContainer(private val context: Context) : AppContainer {
+    override val transactionRepository: TransactionRepository by lazy {
+        OfflineTransactionRepository(TransactionDatabase.getDatabase(context).transactionDao())
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/cz/cvut/fel/pda/financemanagement/model/TransactionCategory.kt b/app/src/main/java/cz/cvut/fel/pda/financemanagement/model/TransactionCategory.kt
new file mode 100644
index 0000000..a357182
--- /dev/null
+++ b/app/src/main/java/cz/cvut/fel/pda/financemanagement/model/TransactionCategory.kt
@@ -0,0 +1,17 @@
+package cz.cvut.fel.pda.financemanagement.model
+
+enum class Category {
+    SALARY,
+    RENT,
+    GROCERIES,
+}
+
+enum class Type {
+    INCOME,
+    EXPENSE
+}
+
+data class TransactionCategory(
+    val type: Type = Type.EXPENSE,
+    val category: Category = Category.RENT
+)
\ No newline at end of file
diff --git a/app/src/main/java/cz/cvut/fel/pda/financemanagement/model/common/Result.kt b/app/src/main/java/cz/cvut/fel/pda/financemanagement/model/common/Result.kt
new file mode 100644
index 0000000..e06b3ed
--- /dev/null
+++ b/app/src/main/java/cz/cvut/fel/pda/financemanagement/model/common/Result.kt
@@ -0,0 +1,16 @@
+package cz.cvut.fel.pda.financemanagement.model.common
+
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.catch
+import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.onStart
+
+sealed interface Result<out T> {
+    data class Success<T>(val data: T) : Result<T>
+    data class Error(val exception: Throwable) : Result<Nothing>
+    data object Loading : Result<Nothing>
+}
+
+fun <T> Flow<T>.asResult(): Flow<Result<T>> = map<T, Result<T>> { Result.Success(it) }
+    .onStart { emit(Result.Loading) }
+    .catch { emit(Result.Error(it)) }
diff --git a/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/components/BottomNavigation.kt b/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/components/BottomNavigation.kt
index 9828e37..ef012a3 100644
--- a/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/components/BottomNavigation.kt
+++ b/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/components/BottomNavigation.kt
@@ -34,7 +34,7 @@ fun BottomNavigation(navController: NavHostController) {
                 selected = currentRoute == it.second,
                 onClick = {
                     navController.navigate(it.second) {
-                        // Avoid multiple copies of the same destination when reselecting the same item
+                        // Avoid multiple copies of the same destination when re-selecting the same item
                         launchSingleTop = true
                         popUpTo(navController.graph.findStartDestination().id) {
                             saveState = true // Save the state of all destinations before popping them
diff --git a/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/components/CommonScreenForState.kt b/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/components/CommonScreenForState.kt
new file mode 100644
index 0000000..c2d6867
--- /dev/null
+++ b/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/components/CommonScreenForState.kt
@@ -0,0 +1,47 @@
+package cz.cvut.fel.pda.financemanagement.ui.components
+
+import androidx.compose.foundation.clickable
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.PaddingValues
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.padding
+import androidx.compose.material3.CircularProgressIndicator
+import androidx.compose.material3.Surface
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.unit.dp
+
+@Composable
+fun ShowErrorScreen(
+    errorMessage: String = "Error",
+    onClick : () -> Unit = { },
+    innerPaddings: PaddingValues = PaddingValues(0.dp)
+){
+    Surface(
+        modifier = Modifier
+            .fillMaxSize()
+            .padding(innerPaddings)
+            .clickable { onClick() }
+    ) {
+        Box(
+            contentAlignment = Alignment.Center
+        ){
+            Text(text = errorMessage)
+        }
+    }
+}
+
+@Composable
+fun ShowLoadingScreen(
+    innerPaddings: PaddingValues = PaddingValues(0.dp)
+){
+    Surface(
+        modifier = Modifier
+            .fillMaxSize()
+            .padding(innerPaddings)
+    ) {
+        CircularProgressIndicator()
+    }
+}
diff --git a/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/components/TopBar.kt b/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/components/TopBar.kt
index dd3c868..3512327 100644
--- a/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/components/TopBar.kt
+++ b/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/components/TopBar.kt
@@ -8,11 +8,11 @@ import androidx.compose.material3.Icon
 import androidx.compose.material3.IconButton
 import androidx.compose.material3.Text
 import androidx.compose.runtime.Composable
+import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.text.TextStyle
 import androidx.compose.ui.text.font.FontWeight
 import androidx.compose.ui.unit.sp
-import androidx.compose.ui.Alignment
 
 @Composable
 fun TopBar() {
diff --git a/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/TransactionsScreen.kt b/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/TransactionsScreen.kt
deleted file mode 100644
index 186368c..0000000
--- a/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/TransactionsScreen.kt
+++ /dev/null
@@ -1,125 +0,0 @@
-package cz.cvut.fel.pda.financemanagement.ui.screens
-
-import androidx.compose.foundation.border
-import androidx.compose.foundation.layout.Arrangement
-import androidx.compose.foundation.layout.Box
-import androidx.compose.foundation.layout.Column
-import androidx.compose.foundation.layout.PaddingValues
-import androidx.compose.foundation.layout.Row
-import androidx.compose.foundation.layout.fillMaxWidth
-import androidx.compose.foundation.layout.padding
-import androidx.compose.foundation.shape.RoundedCornerShape
-import androidx.compose.material.icons.Icons
-import androidx.compose.material.icons.filled.ArrowDropDown
-import androidx.compose.material.icons.filled.MoreVert
-import androidx.compose.material.icons.outlined.Add
-import androidx.compose.material3.Divider
-import androidx.compose.material3.FloatingActionButton
-import androidx.compose.material3.Icon
-import androidx.compose.material3.IconButton
-import androidx.compose.material3.Scaffold
-import androidx.compose.material3.Text
-import androidx.compose.runtime.Composable
-import androidx.compose.ui.Alignment
-import androidx.compose.ui.Modifier
-import androidx.compose.ui.text.TextStyle
-import androidx.compose.ui.text.font.FontWeight
-import androidx.compose.ui.tooling.preview.Preview
-import androidx.compose.ui.unit.dp
-import androidx.compose.ui.unit.sp
-import androidx.navigation.NavHostController
-import androidx.navigation.compose.rememberNavController
-import androidx.compose.ui.graphics.Color
-import cz.cvut.fel.pda.financemanagement.ui.components.BottomNavigation
-import cz.cvut.fel.pda.financemanagement.ui.components.TopBar
-import cz.cvut.fel.pda.financemanagement.ui.theme.FinanceManagementTheme
-
-@Composable
-fun TransactionsScreen(
-    navController: NavHostController
-) {
-    Scaffold(
-        topBar = {
-            TopBar()
-        },
-        floatingActionButton = {
-            FloatingActionButton(onClick = { /*TODO*/ }) {
-                Icon(Icons.Outlined.Add, contentDescription = "Add transaction")
-            }
-        },
-        bottomBar = {
-            BottomNavigation(navController = navController)
-        },
-    ){ innerPadding ->
-        TransactionScreenContent(innerPadding)
-    }
-}
-
-@Composable
-fun TransactionScreenContent(paddingValues: PaddingValues) {
-    Column(modifier = Modifier
-        .padding(paddingValues)
-        .fillMaxWidth()) {
-        Row(modifier = Modifier
-            .align(Alignment.CenterHorizontally)
-            .padding(14.dp)) {
-            Text(text = "Total: ", style = TextStyle(fontSize = 24.sp, fontWeight = FontWeight.Bold))
-            Text(text = "46.245 CZK",
-                style = TextStyle(
-                    fontSize = 24.sp,
-                    fontWeight = FontWeight.Bold,
-                    color = Color(50, 168, 82)
-                )
-            )
-        }
-        Column(modifier = Modifier.padding(horizontal = 14.dp)) {
-            Row(modifier = Modifier
-                .fillMaxWidth(),
-                horizontalArrangement = Arrangement.SpaceBetween
-            ){
-                Text(text = "Transactions", style = TextStyle(fontSize = 16.sp, fontWeight = FontWeight.Bold))
-                Row{
-                    Text(text = "sort")
-                    Icon(Icons.Filled.ArrowDropDown, contentDescription = "Sort options")
-                }
-
-            }
-            Divider()
-
-            TransactionItem(TransactionType.GROCERIES, 5000)
-            TransactionItem(TransactionType.SALARY, 47000)
-        }
-  }
-}
-
-enum class TransactionType {
-    GROCERIES, SALARY
-}
-
-@Composable
-fun TransactionItem(type: TransactionType, sum: Int) {
-    Row(
-        modifier = Modifier
-            .fillMaxWidth()
-            .padding(vertical = 8.dp)
-            .border(1.dp, Color.Gray, shape = RoundedCornerShape(3.dp))
-            .padding(8.dp)
-            , horizontalArrangement = Arrangement.SpaceBetween
-    ) {
-        Column {
-            Text(text = type.name, style = TextStyle(fontSize = 16.sp, fontWeight = FontWeight.Bold))
-            Text(text = sum.toString(), style = TextStyle(fontSize = 16.sp, fontWeight = FontWeight.Bold))
-        }
-        IconButton(onClick = { /* Handle click event here */ }) {
-            Icon(Icons.Filled.MoreVert, contentDescription = "Options")
-        }
-    }
-}
-
-@Preview(showBackground = true)
-@Composable
-fun TransactionScreenPreview() {
-    FinanceManagementTheme {
-        TransactionsScreen(navController = rememberNavController())
-    }
-}
\ No newline at end of file
diff --git a/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/transactions/TransactionViewModel.kt b/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/transactions/TransactionViewModel.kt
new file mode 100644
index 0000000..2d99e18
--- /dev/null
+++ b/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/transactions/TransactionViewModel.kt
@@ -0,0 +1,65 @@
+package cz.cvut.fel.pda.financemanagement.ui.screens.transactions
+
+import androidx.lifecycle.ViewModel
+import androidx.lifecycle.viewModelScope
+import cz.cvut.fel.pda.financemanagement.database.Transaction
+import cz.cvut.fel.pda.financemanagement.database.TransactionRepository
+import cz.cvut.fel.pda.financemanagement.model.common.Result
+import cz.cvut.fel.pda.financemanagement.model.common.asResult
+import kotlinx.coroutines.flow.SharingStarted
+import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.stateIn
+import kotlinx.coroutines.launch
+
+class TransactionViewModel(
+    private val transactionRepository: TransactionRepository,
+) : ViewModel(){
+    val transactions : StateFlow<TransactionsUiState> =
+        transactionRepository
+            .getAllTransactionsStream()
+            .asResult()
+            .map { allTransactionsToResult ->
+                when (allTransactionsToResult) {
+                    is Result.Error -> TransactionsUiState.Error(Exception(allTransactionsToResult.exception))
+                    is Result.Loading -> TransactionsUiState.Loading
+                    is Result.Success -> TransactionsUiState.Success(allTransactionsToResult.data)
+                }
+            }.stateIn(
+                scope = viewModelScope,
+                started = SharingStarted.WhileSubscribed(5000L),
+                initialValue = TransactionsUiState.Loading
+            )
+    fun addTransaction(transaction: Transaction) {
+        viewModelScope.launch {
+            transactionRepository.insertTransactions(
+                transaction)
+        }
+    }
+/*
+    fun addRandomTransaction() {
+        viewModelScope.launch {
+            transactionRepository.insertPlaygrounds(
+                assetsGeojsonFileRepository.getRandomPlayground().toPlayground()
+            )
+        }
+    }
+
+    fun importTransactions() {
+        viewModelScope.launch {
+            transactionRepository.insertPlaygrounds(*assetsGeojsonFileRepository.getAllPlaygrounds().map { it.toPlayground() }.toTypedArray())
+        }
+    }*/
+
+    fun deleteAllTransactions() {
+        viewModelScope.launch {
+            transactionRepository.deleteAllTransactions()
+        }
+    }
+}
+
+sealed interface TransactionsUiState {
+    data object Loading : TransactionsUiState
+    data class Success(val itemList: List<Transaction> = listOf()) : TransactionsUiState
+    data class Error(val exception: Exception) : TransactionsUiState
+}
\ No newline at end of file
diff --git a/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/transactions/TransactionsScreen.kt b/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/transactions/TransactionsScreen.kt
new file mode 100644
index 0000000..bef3ba2
--- /dev/null
+++ b/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/transactions/TransactionsScreen.kt
@@ -0,0 +1,184 @@
+package cz.cvut.fel.pda.financemanagement.ui.screens.transactions
+
+import androidx.compose.foundation.border
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.PaddingValues
+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.foundation.shape.RoundedCornerShape
+import androidx.compose.material.icons.Icons
+import androidx.compose.material.icons.filled.ArrowDropDown
+import androidx.compose.material.icons.filled.MoreVert
+import androidx.compose.material.icons.outlined.Add
+import androidx.compose.material3.FloatingActionButton
+import androidx.compose.material3.HorizontalDivider
+import androidx.compose.material3.Icon
+import androidx.compose.material3.IconButton
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.Scaffold
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.getValue
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.text.TextStyle
+import androidx.compose.ui.text.font.FontWeight
+import androidx.compose.ui.text.style.TextAlign
+import androidx.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.unit.dp
+import androidx.compose.ui.unit.sp
+import androidx.lifecycle.compose.collectAsStateWithLifecycle
+import androidx.lifecycle.viewmodel.compose.viewModel
+import androidx.navigation.NavHostController
+import androidx.navigation.compose.rememberNavController
+import cz.cvut.fel.pda.financemanagement.database.Transaction
+import cz.cvut.fel.pda.financemanagement.model.Type
+import cz.cvut.fel.pda.financemanagement.ui.components.BottomNavigation
+import cz.cvut.fel.pda.financemanagement.ui.components.ShowErrorScreen
+import cz.cvut.fel.pda.financemanagement.ui.components.ShowLoadingScreen
+import cz.cvut.fel.pda.financemanagement.ui.components.TopBar
+import cz.cvut.fel.pda.financemanagement.ui.theme.FinanceManagementTheme
+import cz.cvut.fel.pda.financemanagement.ui.utils.AppViewModelProvider
+import java.math.BigDecimal
+
+@Composable
+fun TransactionsScreen(
+    navController: NavHostController,
+    transactionViewModel: TransactionViewModel= viewModel(
+        factory = AppViewModelProvider.Factory
+    )
+) {
+    val transactionsUiState: TransactionsUiState by transactionViewModel.transactions.collectAsStateWithLifecycle()
+    Scaffold(
+        topBar = { TopBar() },
+        content = { innerPadding ->
+            when (transactionsUiState) {
+                is TransactionsUiState.Loading -> {
+                    ShowLoadingScreen()
+                }
+                is TransactionsUiState.Error -> {
+                    ShowErrorScreen(
+                        errorMessage = (transactionsUiState as TransactionsUiState.Error).exception.message ?: "Error",
+                    )
+                }
+                is TransactionsUiState.Success -> {
+                    TransactionScreenContent( (transactionsUiState as TransactionsUiState.Success).itemList, innerPadding)
+                }
+            }
+        },
+        floatingActionButton = {
+            FloatingActionButton(onClick = { /*TODO*/ }) {
+                Icon(Icons.Outlined.Add, contentDescription = "Add transaction")
+            }
+        },
+        bottomBar = { BottomNavigation(navController = navController) },
+    )
+}
+
+@Composable
+fun TransactionScreenContent(transactions: List<Transaction>, innerPadding: PaddingValues) {
+    Column(modifier = Modifier
+        .padding(innerPadding)
+        .fillMaxWidth()) {
+        TotalSumOfTransactions(transactions)
+        Column(modifier = Modifier.padding(horizontal = 14.dp)) {
+            Row(modifier = Modifier
+                .fillMaxWidth(),
+                horizontalArrangement = Arrangement.SpaceBetween
+            ){
+                Text(text = "Transactions", style = TextStyle(fontSize = 16.sp, fontWeight = FontWeight.Bold))
+                Row{
+                    Text(text = "sort")
+                    Icon(Icons.Filled.ArrowDropDown, contentDescription = "Sort options")
+                }
+
+            }
+            HorizontalDivider()
+            ShowTabListSuccessScreen(transactions)
+        }
+  }
+}
+
+@Composable
+fun TotalSumOfTransactions(transactions: List<Transaction>) {
+    val totalSum = transactions.sumOf { it.amount }.toString()
+    Row(modifier = Modifier.fillMaxWidth().padding(14.dp),
+        horizontalArrangement = Arrangement.Center){
+        Text(text = "Total: ", style = TextStyle(fontSize = 24.sp, fontWeight = FontWeight.Bold))
+        Text(text = "$totalSum CZK",
+            style = TextStyle(
+                fontSize = 24.sp,
+                fontWeight = FontWeight.Bold,
+                color = Color(50, 168, 82)
+            )
+        )
+    }
+}
+
+@Composable
+fun ShowTabListSuccessScreen(itemList: List<Transaction>) {
+    if (itemList.isEmpty()){
+        Box (
+            modifier = Modifier.fillMaxSize(),
+            contentAlignment = Alignment.Center
+        ) {
+            Text(
+                text = "No transactions found.",
+                textAlign = TextAlign.Center,
+                style = MaterialTheme.typography.titleLarge,
+                modifier = Modifier.padding(16.dp)
+            )
+        }
+    } else {
+        TransactionsList(itemList)
+    }
+}
+
+@Composable
+fun TransactionsList(
+    itemList: List<Transaction>,
+    modifier: Modifier = Modifier
+) {
+    LazyColumn(
+        modifier = modifier.fillMaxSize(),
+        verticalArrangement = Arrangement.Top
+    ) {
+        items(itemList) { _ ->
+            TransactionItem(Type.EXPENSE, 10.toBigDecimal())
+        }
+    }
+}
+@Composable
+fun TransactionItem(type: Type, sum: BigDecimal) {
+    Row(
+        modifier = Modifier
+            .fillMaxWidth()
+            .padding(vertical = 8.dp)
+            .border(1.dp, Color.Gray, shape = RoundedCornerShape(3.dp))
+            .padding(8.dp)
+            , horizontalArrangement = Arrangement.SpaceBetween
+    ) {
+        Column {
+            Text(text = type.name, style = TextStyle(fontSize = 16.sp, fontWeight = FontWeight.Bold))
+            Text(text = sum.toString(), style = TextStyle(fontSize = 16.sp, fontWeight = FontWeight.Bold))
+        }
+        IconButton(onClick = { /* Handle click event here */ }) {
+            Icon(Icons.Filled.MoreVert, contentDescription = "Options")
+        }
+    }
+}
+
+@Preview(showBackground = true)
+@Composable
+fun TransactionScreenPreview() {
+    FinanceManagementTheme {
+        TransactionsScreen(navController = rememberNavController())
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/utils/AppViewModelProvider.kt b/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/utils/AppViewModelProvider.kt
new file mode 100644
index 0000000..a9604da
--- /dev/null
+++ b/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/utils/AppViewModelProvider.kt
@@ -0,0 +1,21 @@
+package cz.cvut.fel.pda.financemanagement.ui.utils
+
+import androidx.lifecycle.ViewModelProvider
+import androidx.lifecycle.viewmodel.CreationExtras
+import androidx.lifecycle.viewmodel.initializer
+import androidx.lifecycle.viewmodel.viewModelFactory
+import cz.cvut.fel.pda.financemanagement.FinanceManagementApplication
+import cz.cvut.fel.pda.financemanagement.ui.screens.transactions.TransactionViewModel
+
+object AppViewModelProvider {
+    val Factory = viewModelFactory {
+        initializer {
+            TransactionViewModel(
+                financemanagementApplication().container.transactionRepository
+            )
+        }
+    }
+}
+
+fun CreationExtras.financemanagementApplication(): FinanceManagementApplication =
+    (this[ViewModelProvider.AndroidViewModelFactory.APPLICATION_KEY] as FinanceManagementApplication)
\ No newline at end of file
diff --git a/app/src/test/java/cz/cvut/fel/pda/financemanagement/ExampleUnitTest.kt b/app/src/test/java/cz/cvut/fel/pda/financemanagement/ExampleUnitTest.kt
index 373bbb0..dedf2d5 100644
--- a/app/src/test/java/cz/cvut/fel/pda/financemanagement/ExampleUnitTest.kt
+++ b/app/src/test/java/cz/cvut/fel/pda/financemanagement/ExampleUnitTest.kt
@@ -1,9 +1,8 @@
 package cz.cvut.fel.pda.financemanagement
 
+import org.junit.Assert.assertEquals
 import org.junit.Test
 
-import org.junit.Assert.*
-
 /**
  * Example local unit test, which will execute on the development machine (host).
  *
diff --git a/build.gradle.kts b/build.gradle.kts
index a0985ef..0374c1c 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -2,4 +2,5 @@
 plugins {
     alias(libs.plugins.androidApplication) apply false
     alias(libs.plugins.jetbrainsKotlinAndroid) apply false
+    alias(libs.plugins.ksp) apply false
 }
\ No newline at end of file
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
index ae97388..024cf92 100644
--- a/gradle/libs.versions.toml
+++ b/gradle/libs.versions.toml
@@ -1,18 +1,34 @@
 [versions]
-agp = "8.3.0"
+agp = "8.3.2"
+glideCompose = "1.0.0-beta01"
+datastorePreferences = "1.0.0"
+jacksonModuleKotlin = "2.12.0"
+geojsonJackson = "1.6"
 kotlin = "1.9.0"
+ksp = "1.9.0-1.0.13"
 coreKtx = "1.12.0"
 junit = "4.13.2"
 junitVersion = "1.1.5"
 espressoCore = "3.5.1"
 lifecycleRuntimeKtx = "2.7.0"
 activityCompose = "1.8.2"
-composeBom = "2023.08.00"
-navigationRuntimeKtx = "2.7.7"
+composeBom = "2024.04.00"
 navigationCompose = "2.7.7"
+lifecycleRuntimeCompose = "2.7.0"
+roomVersion = "2.6.1"
+retrofit = "2.9.0"
 
 [libraries]
+retrofit = { module = "com.squareup.retrofit2:retrofit", version.ref = "retrofit" }
+converterJackson = { module = "com.squareup.retrofit2:converter-jackson", version.ref = "retrofit" }
 androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
+androidx-datastore-preferences = { module = "androidx.datastore:datastore-preferences", version.ref = "datastorePreferences" }
+androidx-room-compiler = { module = "androidx.room:room-compiler", version.ref = "roomVersion" }
+androidx-room-ktx = { module = "androidx.room:room-ktx", version.ref = "roomVersion" }
+androidx-room-runtime = { module = "androidx.room:room-runtime", version.ref = "roomVersion" }
+compose = { module = "com.github.bumptech.glide:compose", version.ref = "glideCompose" }
+jackson-module-kotlin = { module = "com.fasterxml.jackson.module:jackson-module-kotlin", version.ref = "jacksonModuleKotlin" }
+geojson-jackson = { module = "de.grundid.opendatalab:geojson-jackson", version.ref = "geojsonJackson" }
 junit = { group = "junit", name = "junit", version.ref = "junit" }
 androidx-junit = { group = "androidx.test.ext", name = "junit", version.ref = "junitVersion" }
 androidx-espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espressoCore" }
@@ -26,10 +42,11 @@ androidx-ui-tooling-preview = { group = "androidx.compose.ui", name = "ui-toolin
 androidx-ui-test-manifest = { group = "androidx.compose.ui", name = "ui-test-manifest" }
 androidx-ui-test-junit4 = { group = "androidx.compose.ui", name = "ui-test-junit4" }
 androidx-material3 = { group = "androidx.compose.material3", name = "material3" }
-androidx-navigation-runtime-ktx = { group = "androidx.navigation", name = "navigation-runtime-ktx", version.ref = "navigationRuntimeKtx" }
 androidx-navigation-compose = { group = "androidx.navigation", name = "navigation-compose", version.ref = "navigationCompose" }
+androidx-lifecycle-runtime-compose = { group = "androidx.lifecycle", name = "lifecycle-runtime-compose", version.ref = "lifecycleRuntimeCompose" }
 
 [plugins]
 androidApplication = { id = "com.android.application", version.ref = "agp" }
 jetbrainsKotlinAndroid = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }
+ksp = { id = "com.google.devtools.ksp", version.ref = "ksp" }
 
-- 
GitLab


From 8430594b41a8ea3e9a83172502e952805f068d9a Mon Sep 17 00:00:00 2001
From: dovicrad <dovicrad@fel.cvut.cz>
Date: Thu, 18 Apr 2024 10:59:46 +0200
Subject: [PATCH 02/12] :cooking: semi working transaction creation , saving
 and display

---
 .../financemanagement/FinanceManagementApp.kt |  10 ++
 .../OfflineTransactionRepository.kt           |   5 +-
 .../database/{ => transaction}/Transaction.kt |   2 +-
 .../{ => transaction}/TransactionDao.kt       |   2 +-
 .../{ => transaction}/TransactionDatabase.kt  |   2 +-
 .../TransactionRepository.kt                  |   2 +-
 .../pda/financemanagement/di/AppContainer.kt  |   6 +-
 .../transactions/EditTransactionScreen.kt     | 133 ++++++++++++++++++
 .../TransactionDetailViewModel.kt             |  55 ++++++++
 .../transactions/TransactionViewModel.kt      |   4 +-
 .../transactions/TransactionsScreen.kt        |  15 +-
 .../ui/utils/AppViewModelProvider.kt          |   8 ++
 12 files changed, 226 insertions(+), 18 deletions(-)
 rename app/src/main/java/cz/cvut/fel/pda/financemanagement/database/{ => transaction}/OfflineTransactionRepository.kt (87%)
 rename app/src/main/java/cz/cvut/fel/pda/financemanagement/database/{ => transaction}/Transaction.kt (83%)
 rename app/src/main/java/cz/cvut/fel/pda/financemanagement/database/{ => transaction}/TransactionDao.kt (93%)
 rename app/src/main/java/cz/cvut/fel/pda/financemanagement/database/{ => transaction}/TransactionDatabase.kt (94%)
 rename app/src/main/java/cz/cvut/fel/pda/financemanagement/database/{ => transaction}/TransactionRepository.kt (87%)
 create mode 100644 app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/transactions/EditTransactionScreen.kt
 create mode 100644 app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/transactions/TransactionDetailViewModel.kt

diff --git a/app/src/main/java/cz/cvut/fel/pda/financemanagement/FinanceManagementApp.kt b/app/src/main/java/cz/cvut/fel/pda/financemanagement/FinanceManagementApp.kt
index 6760bdf..abf31dd 100644
--- a/app/src/main/java/cz/cvut/fel/pda/financemanagement/FinanceManagementApp.kt
+++ b/app/src/main/java/cz/cvut/fel/pda/financemanagement/FinanceManagementApp.kt
@@ -3,17 +3,21 @@ package cz.cvut.fel.pda.financemanagement
 import androidx.compose.runtime.Composable
 import androidx.compose.ui.Modifier
 import androidx.navigation.NavHostController
+import androidx.navigation.NavType
 import androidx.navigation.compose.NavHost
 import androidx.navigation.compose.composable
 import androidx.navigation.compose.rememberNavController
+import androidx.navigation.navArgument
 import cz.cvut.fel.pda.financemanagement.ui.screens.AccountsScreen
 import cz.cvut.fel.pda.financemanagement.ui.screens.CategoriesScreen
 import cz.cvut.fel.pda.financemanagement.ui.screens.LoansScreen
+import cz.cvut.fel.pda.financemanagement.ui.screens.transactions.EditTransactionScreen
 import cz.cvut.fel.pda.financemanagement.ui.screens.transactions.TransactionsScreen
 
 
 enum class FinanceManagementScreens() {
     Transactions,
+    EditTransaction,
     Accounts,
     Categories,
     Loans
@@ -41,5 +45,11 @@ fun FinanceManagementApp() {
         composable(route = FinanceManagementScreens.Categories.name) {
            CategoriesScreen(navController)
         }
+        composable(route = "${FinanceManagementScreens.EditTransaction.name}/{Id}",
+            arguments = listOf(navArgument("Id") { type = NavType.LongType })){
+            EditTransactionScreen(navController,
+                transitionId = it.arguments?.getLong("Id")
+            )
+        }
     }
 }
\ No newline at end of file
diff --git a/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/OfflineTransactionRepository.kt b/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/transaction/OfflineTransactionRepository.kt
similarity index 87%
rename from app/src/main/java/cz/cvut/fel/pda/financemanagement/database/OfflineTransactionRepository.kt
rename to app/src/main/java/cz/cvut/fel/pda/financemanagement/database/transaction/OfflineTransactionRepository.kt
index d2dd746..6015f19 100644
--- a/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/OfflineTransactionRepository.kt
+++ b/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/transaction/OfflineTransactionRepository.kt
@@ -1,8 +1,9 @@
-package cz.cvut.fel.pda.financemanagement.database
+package cz.cvut.fel.pda.financemanagement.database.transaction
 
 import kotlinx.coroutines.flow.Flow
 
-class OfflineTransactionRepository(private val transactionDao: TransactionDao): TransactionRepository{
+class OfflineTransactionRepository(private val transactionDao: TransactionDao):
+    TransactionRepository {
     override fun getAllTransactionsStream(): Flow<List<Transaction>> = transactionDao.getAllTransactions()
     override fun getTransactionForIdStream(id: Long): Flow<Transaction?> = transactionDao.getTransactionForId(id)
     override suspend fun insertTransactions(vararg transactions: Transaction) = transactionDao.insertTransactions(*transactions)
diff --git a/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/Transaction.kt b/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/transaction/Transaction.kt
similarity index 83%
rename from app/src/main/java/cz/cvut/fel/pda/financemanagement/database/Transaction.kt
rename to app/src/main/java/cz/cvut/fel/pda/financemanagement/database/transaction/Transaction.kt
index fe7ecd1..540a53c 100644
--- a/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/Transaction.kt
+++ b/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/transaction/Transaction.kt
@@ -1,4 +1,4 @@
-package cz.cvut.fel.pda.financemanagement.database
+package cz.cvut.fel.pda.financemanagement.database.transaction
 
 import androidx.room.Entity
 import androidx.room.PrimaryKey
diff --git a/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/TransactionDao.kt b/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/transaction/TransactionDao.kt
similarity index 93%
rename from app/src/main/java/cz/cvut/fel/pda/financemanagement/database/TransactionDao.kt
rename to app/src/main/java/cz/cvut/fel/pda/financemanagement/database/transaction/TransactionDao.kt
index 50d5aa3..e31cc3c 100644
--- a/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/TransactionDao.kt
+++ b/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/transaction/TransactionDao.kt
@@ -1,4 +1,4 @@
-package cz.cvut.fel.pda.financemanagement.database
+package cz.cvut.fel.pda.financemanagement.database.transaction
 
 import androidx.room.Dao
 import androidx.room.Delete
diff --git a/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/TransactionDatabase.kt b/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/transaction/TransactionDatabase.kt
similarity index 94%
rename from app/src/main/java/cz/cvut/fel/pda/financemanagement/database/TransactionDatabase.kt
rename to app/src/main/java/cz/cvut/fel/pda/financemanagement/database/transaction/TransactionDatabase.kt
index 295d19f..885e02a 100644
--- a/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/TransactionDatabase.kt
+++ b/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/transaction/TransactionDatabase.kt
@@ -1,4 +1,4 @@
-package cz.cvut.fel.pda.financemanagement.database
+package cz.cvut.fel.pda.financemanagement.database.transaction
 
 import android.content.Context
 import androidx.room.Database
diff --git a/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/TransactionRepository.kt b/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/transaction/TransactionRepository.kt
similarity index 87%
rename from app/src/main/java/cz/cvut/fel/pda/financemanagement/database/TransactionRepository.kt
rename to app/src/main/java/cz/cvut/fel/pda/financemanagement/database/transaction/TransactionRepository.kt
index d16ad62..64fef70 100644
--- a/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/TransactionRepository.kt
+++ b/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/transaction/TransactionRepository.kt
@@ -1,4 +1,4 @@
-package cz.cvut.fel.pda.financemanagement.database
+package cz.cvut.fel.pda.financemanagement.database.transaction
 
 import kotlinx.coroutines.flow.Flow
 
diff --git a/app/src/main/java/cz/cvut/fel/pda/financemanagement/di/AppContainer.kt b/app/src/main/java/cz/cvut/fel/pda/financemanagement/di/AppContainer.kt
index 7510af9..51b346a 100644
--- a/app/src/main/java/cz/cvut/fel/pda/financemanagement/di/AppContainer.kt
+++ b/app/src/main/java/cz/cvut/fel/pda/financemanagement/di/AppContainer.kt
@@ -1,9 +1,9 @@
 package cz.cvut.fel.pda.financemanagement.di
 
 import android.content.Context
-import cz.cvut.fel.pda.financemanagement.database.OfflineTransactionRepository
-import cz.cvut.fel.pda.financemanagement.database.TransactionDatabase
-import cz.cvut.fel.pda.financemanagement.database.TransactionRepository
+import cz.cvut.fel.pda.financemanagement.database.transaction.OfflineTransactionRepository
+import cz.cvut.fel.pda.financemanagement.database.transaction.TransactionDatabase
+import cz.cvut.fel.pda.financemanagement.database.transaction.TransactionRepository
 
 interface AppContainer {
     val transactionRepository: TransactionRepository
diff --git a/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/transactions/EditTransactionScreen.kt b/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/transactions/EditTransactionScreen.kt
new file mode 100644
index 0000000..abc86f3
--- /dev/null
+++ b/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/transactions/EditTransactionScreen.kt
@@ -0,0 +1,133 @@
+package cz.cvut.fel.pda.financemanagement.ui.screens.transactions
+
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.PaddingValues
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.rememberScrollState
+import androidx.compose.foundation.verticalScroll
+import androidx.compose.material.icons.Icons
+import androidx.compose.material.icons.outlined.Close
+import androidx.compose.material3.ExperimentalMaterial3Api
+import androidx.compose.material3.Icon
+import androidx.compose.material3.IconButton
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.OutlinedTextField
+import androidx.compose.material3.Scaffold
+import androidx.compose.material3.Text
+import androidx.compose.material3.TextButton
+import androidx.compose.material3.TopAppBar
+import androidx.compose.material3.TopAppBarDefaults
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.MutableState
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
+import androidx.compose.runtime.saveable.rememberSaveable
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.unit.dp
+import androidx.lifecycle.compose.collectAsStateWithLifecycle
+import androidx.lifecycle.viewmodel.compose.viewModel
+import androidx.navigation.NavHostController
+import cz.cvut.fel.pda.financemanagement.database.transaction.Transaction
+import cz.cvut.fel.pda.financemanagement.ui.components.ShowErrorScreen
+import cz.cvut.fel.pda.financemanagement.ui.components.ShowLoadingScreen
+import cz.cvut.fel.pda.financemanagement.ui.utils.AppViewModelProvider
+import java.math.BigDecimal
+
+@Composable
+fun EditTransactionScreen(navController: NavHostController,
+                          transitionId: Long?,
+                          transitionDetailViewModel: TransactionDetailViewModel = viewModel(
+                              factory = AppViewModelProvider.Factory
+),){
+    val uiState by transitionDetailViewModel.uiState.collectAsStateWithLifecycle()
+
+    when (val state = uiState) {
+        is TransactionUiState.Error -> {
+            ShowErrorScreen(
+                errorMessage = state.exception.message ?: "Error",
+                onClick = { navController.popBackStack() }
+            )
+        }
+        TransactionUiState.Loading -> {
+            ShowLoadingScreen()
+        }
+        is TransactionUiState.Success -> {
+            ShowSuccessScreen(
+                state.transaction,
+                navController,
+                transitionDetailViewModel
+            )
+        }
+    }
+}
+
+@OptIn(ExperimentalMaterial3Api::class)
+@Composable
+fun ShowSuccessScreen(
+    transaction: Transaction,
+    navController: NavHostController,
+    transactionViewModel: TransactionDetailViewModel
+) {
+    val amount = rememberSaveable { mutableStateOf(transaction.amount.toString()) }
+
+    Scaffold(
+        topBar = {
+            TopAppBar(
+                title = { Text("neco") },
+                colors = TopAppBarDefaults.mediumTopAppBarColors(
+                    containerColor = MaterialTheme.colorScheme.primaryContainer
+                ),
+                modifier = Modifier,
+                navigationIcon = {
+                    IconButton(onClick = { navController.popBackStack() }) {
+                        Icon(
+                            imageVector = Icons.Outlined.Close,
+                            contentDescription = "cs"
+                        )
+                    }
+                },
+                actions = {
+                    TextButton(
+                        onClick = {
+                            transactionViewModel.savePlayground(
+                                amount = BigDecimal(amount.value)
+                            )
+                            navController.popBackStack()
+                        },
+                        modifier = Modifier.padding(16.dp)
+                    ) {
+                        Text(text = "save")
+                    }
+                }
+            )
+        },
+        content = {innerPadding ->
+            EditTransactionDetailSuccessContent(innerPadding, amount)
+        }
+    )
+}
+@Composable
+fun EditTransactionDetailSuccessContent(innerPadding: PaddingValues, amount: MutableState<String>) {
+    val openDialog = remember { mutableStateOf(false) }
+
+    Column (
+        modifier = Modifier
+            .fillMaxWidth()
+            .verticalScroll(rememberScrollState())
+            .padding(innerPadding), // use innerPadding here
+        horizontalAlignment = Alignment.CenterHorizontally
+    ) {
+        val spaceModifier = Modifier
+            .fillMaxWidth()
+            .padding(24.dp, 4.dp)
+        OutlinedTextField(
+            value = amount.value,
+            onValueChange = { newValue -> amount.value = newValue },
+            label = { Text("xd") },
+            modifier = spaceModifier
+        )
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/transactions/TransactionDetailViewModel.kt b/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/transactions/TransactionDetailViewModel.kt
new file mode 100644
index 0000000..753dfe3
--- /dev/null
+++ b/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/transactions/TransactionDetailViewModel.kt
@@ -0,0 +1,55 @@
+package cz.cvut.fel.pda.financemanagement.ui.screens.transactions
+
+import androidx.lifecycle.SavedStateHandle
+import androidx.lifecycle.ViewModel
+import cz.cvut.fel.pda.financemanagement.database.transaction.Transaction
+import cz.cvut.fel.pda.financemanagement.database.transaction.TransactionRepository
+import kotlinx.coroutines.flow.StateFlow
+import androidx.lifecycle.viewModelScope
+import kotlinx.coroutines.flow.SharingStarted
+import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.stateIn
+import kotlinx.coroutines.launch
+import java.math.BigDecimal
+
+class TransactionDetailViewModel(
+    private val transactionRepository: TransactionRepository,
+    savedStateHandle: SavedStateHandle
+): ViewModel() {
+    private val transactionId: Long = savedStateHandle.get<Long>("Id")!!
+
+    val uiState: StateFlow<TransactionUiState> =
+        transactionRepository
+            .getTransactionForIdStream(transactionId)
+            .map {
+                if (it != null) {
+                    TransactionUiState.Success(it)
+                } else if (transactionId == 0L) {
+                    TransactionUiState.Success(Transaction())
+                } else {
+                    TransactionUiState.Error(Exception("Transaction not found"))
+                }
+            }.stateIn(
+                scope = viewModelScope,
+                started = SharingStarted.WhileSubscribed(5000L),
+                initialValue = TransactionUiState.Loading
+            )
+    fun savePlayground(
+        amount: BigDecimal
+    ) {
+        viewModelScope.launch {
+            transactionRepository.insertTransactions(
+                Transaction(
+                    id = transactionId,
+                    amount = amount
+                )
+            )
+        }
+    }
+}
+
+sealed interface TransactionUiState {
+    data object Loading : TransactionUiState
+    data class Success(val transaction: Transaction) : TransactionUiState
+    data class Error(val exception: Exception) : TransactionUiState
+}
\ No newline at end of file
diff --git a/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/transactions/TransactionViewModel.kt b/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/transactions/TransactionViewModel.kt
index 2d99e18..ecae25f 100644
--- a/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/transactions/TransactionViewModel.kt
+++ b/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/transactions/TransactionViewModel.kt
@@ -2,8 +2,8 @@ package cz.cvut.fel.pda.financemanagement.ui.screens.transactions
 
 import androidx.lifecycle.ViewModel
 import androidx.lifecycle.viewModelScope
-import cz.cvut.fel.pda.financemanagement.database.Transaction
-import cz.cvut.fel.pda.financemanagement.database.TransactionRepository
+import cz.cvut.fel.pda.financemanagement.database.transaction.Transaction
+import cz.cvut.fel.pda.financemanagement.database.transaction.TransactionRepository
 import cz.cvut.fel.pda.financemanagement.model.common.Result
 import cz.cvut.fel.pda.financemanagement.model.common.asResult
 import kotlinx.coroutines.flow.SharingStarted
diff --git a/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/transactions/TransactionsScreen.kt b/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/transactions/TransactionsScreen.kt
index bef3ba2..991daa4 100644
--- a/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/transactions/TransactionsScreen.kt
+++ b/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/transactions/TransactionsScreen.kt
@@ -38,7 +38,8 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle
 import androidx.lifecycle.viewmodel.compose.viewModel
 import androidx.navigation.NavHostController
 import androidx.navigation.compose.rememberNavController
-import cz.cvut.fel.pda.financemanagement.database.Transaction
+import cz.cvut.fel.pda.financemanagement.FinanceManagementScreens
+import cz.cvut.fel.pda.financemanagement.database.transaction.Transaction
 import cz.cvut.fel.pda.financemanagement.model.Type
 import cz.cvut.fel.pda.financemanagement.ui.components.BottomNavigation
 import cz.cvut.fel.pda.financemanagement.ui.components.ShowErrorScreen
@@ -74,7 +75,7 @@ fun TransactionsScreen(
             }
         },
         floatingActionButton = {
-            FloatingActionButton(onClick = { /*TODO*/ }) {
+            FloatingActionButton(onClick = { navController.navigate("${FinanceManagementScreens.EditTransaction.name}/0")}) {
                 Icon(Icons.Outlined.Add, contentDescription = "Add transaction")
             }
         },
@@ -150,13 +151,13 @@ fun TransactionsList(
         modifier = modifier.fillMaxSize(),
         verticalArrangement = Arrangement.Top
     ) {
-        items(itemList) { _ ->
-            TransactionItem(Type.EXPENSE, 10.toBigDecimal())
+        items(itemList) { transaction->
+            TransactionItem(transaction)
         }
     }
 }
 @Composable
-fun TransactionItem(type: Type, sum: BigDecimal) {
+fun TransactionItem(transaction: Transaction) {
     Row(
         modifier = Modifier
             .fillMaxWidth()
@@ -166,8 +167,8 @@ fun TransactionItem(type: Type, sum: BigDecimal) {
             , horizontalArrangement = Arrangement.SpaceBetween
     ) {
         Column {
-            Text(text = type.name, style = TextStyle(fontSize = 16.sp, fontWeight = FontWeight.Bold))
-            Text(text = sum.toString(), style = TextStyle(fontSize = 16.sp, fontWeight = FontWeight.Bold))
+            Text(text = transaction.description, style = TextStyle(fontSize = 16.sp, fontWeight = FontWeight.Bold))
+            Text(text = transaction.amount.toString(), style = TextStyle(fontSize = 16.sp, fontWeight = FontWeight.Bold))
         }
         IconButton(onClick = { /* Handle click event here */ }) {
             Icon(Icons.Filled.MoreVert, contentDescription = "Options")
diff --git a/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/utils/AppViewModelProvider.kt b/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/utils/AppViewModelProvider.kt
index a9604da..696af66 100644
--- a/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/utils/AppViewModelProvider.kt
+++ b/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/utils/AppViewModelProvider.kt
@@ -1,10 +1,12 @@
 package cz.cvut.fel.pda.financemanagement.ui.utils
 
 import androidx.lifecycle.ViewModelProvider
+import androidx.lifecycle.createSavedStateHandle
 import androidx.lifecycle.viewmodel.CreationExtras
 import androidx.lifecycle.viewmodel.initializer
 import androidx.lifecycle.viewmodel.viewModelFactory
 import cz.cvut.fel.pda.financemanagement.FinanceManagementApplication
+import cz.cvut.fel.pda.financemanagement.ui.screens.transactions.TransactionDetailViewModel
 import cz.cvut.fel.pda.financemanagement.ui.screens.transactions.TransactionViewModel
 
 object AppViewModelProvider {
@@ -14,6 +16,12 @@ object AppViewModelProvider {
                 financemanagementApplication().container.transactionRepository
             )
         }
+        initializer {
+            TransactionDetailViewModel(
+                financemanagementApplication().container.transactionRepository,
+                this.createSavedStateHandle()
+            )
+        }
     }
 }
 
-- 
GitLab


From 040b38bf5dae2f0b196ba24f8404d861355e776f Mon Sep 17 00:00:00 2001
From: dovicrad <dovicrad@fel.cvut.cz>
Date: Mon, 22 Apr 2024 16:58:10 +0200
Subject: [PATCH 03/12] :cooking: add working transaction with category
 relation

---
 app/src/main/AndroidManifest.xml              |  3 +-
 .../financemanagement/database/AppDatabase.kt | 39 ++++++++++++++
 .../database/category/Category.kt             | 21 ++++++++
 .../database/category/CategoryDao.kt          | 34 ++++++++++++
 .../database/category/CategoryRepository.kt   | 12 +++++
 .../OfflineTransactionRepository.kt           |  3 ++
 .../database/transaction/Transaction.kt       |  3 +-
 .../database/transaction/TransactionDao.kt    | 11 ++--
 .../transaction/TransactionDatabase.kt        | 34 ------------
 .../transaction/TransactionRepository.kt      |  2 +
 .../pda/financemanagement/di/AppContainer.kt  |  4 +-
 .../model/CategoryWithTransaction.kt          | 15 ++++++
 .../model/TransactionCategory.kt              | 17 ------
 .../transactions/EditTransactionScreen.kt     |  6 +--
 .../TransactionDetailViewModel.kt             | 11 ++--
 .../transactions/TransactionViewModel.kt      | 49 ++++-------------
 .../transactions/TransactionsScreen.kt        | 52 +++++++++++--------
 .../financemanagement/ui/utils/ColorUtils.kt  | 25 +++++++++
 18 files changed, 215 insertions(+), 126 deletions(-)
 create mode 100644 app/src/main/java/cz/cvut/fel/pda/financemanagement/database/AppDatabase.kt
 create mode 100644 app/src/main/java/cz/cvut/fel/pda/financemanagement/database/category/Category.kt
 create mode 100644 app/src/main/java/cz/cvut/fel/pda/financemanagement/database/category/CategoryDao.kt
 create mode 100644 app/src/main/java/cz/cvut/fel/pda/financemanagement/database/category/CategoryRepository.kt
 delete mode 100644 app/src/main/java/cz/cvut/fel/pda/financemanagement/database/transaction/TransactionDatabase.kt
 create mode 100644 app/src/main/java/cz/cvut/fel/pda/financemanagement/model/CategoryWithTransaction.kt
 delete mode 100644 app/src/main/java/cz/cvut/fel/pda/financemanagement/model/TransactionCategory.kt
 create mode 100644 app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/utils/ColorUtils.kt

diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 024c48e..c49185b 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -1,6 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:tools="http://schemas.android.com/tools">
+<manifest xmlns:android="http://schemas.android.com/apk/res/android">
 
     <application
         android:name=".FinanceManagementApplication"
diff --git a/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/AppDatabase.kt b/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/AppDatabase.kt
new file mode 100644
index 0000000..7abdd45
--- /dev/null
+++ b/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/AppDatabase.kt
@@ -0,0 +1,39 @@
+package cz.cvut.fel.pda.financemanagement.database
+
+import android.content.Context
+import androidx.room.Database
+import androidx.room.Room
+import androidx.room.RoomDatabase
+import androidx.room.TypeConverters
+import cz.cvut.fel.pda.financemanagement.database.category.Category
+import cz.cvut.fel.pda.financemanagement.database.category.CategoryDao
+import cz.cvut.fel.pda.financemanagement.database.transaction.Transaction
+import cz.cvut.fel.pda.financemanagement.database.transaction.TransactionDao
+import cz.cvut.fel.pda.financemanagement.database.typeConvertion.Converters
+
+@Database(entities = [Transaction::class, Category::class], version = 6, exportSchema = false)
+@TypeConverters(Converters::class)
+abstract class AppDatabase : RoomDatabase(){
+    abstract fun transactionDao(): TransactionDao
+    abstract fun categoryDao(): CategoryDao
+
+    companion object{
+        @Volatile
+        private var INSTANCE: AppDatabase? = null
+
+        fun getDatabase(context: Context): AppDatabase {
+            return INSTANCE ?: synchronized(this) {
+                Room.databaseBuilder(
+                    context.applicationContext,
+                    AppDatabase::class.java,
+                    "database"
+                )
+                    .fallbackToDestructiveMigration()
+                    .build()
+                    .also {
+                        INSTANCE = it
+                    }
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/category/Category.kt b/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/category/Category.kt
new file mode 100644
index 0000000..9cc2b60
--- /dev/null
+++ b/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/category/Category.kt
@@ -0,0 +1,21 @@
+package cz.cvut.fel.pda.financemanagement.database.category
+
+import androidx.room.Entity
+import androidx.room.PrimaryKey
+
+@Entity(tableName = "category")
+data class Category(
+    @PrimaryKey(autoGenerate = true)
+    val id: Long = 0,
+    val name: CategoryName,
+    val type: CategoryType,
+)
+
+enum class CategoryType {
+    EXPENSE,
+    INCOME,
+}
+
+enum class CategoryName {
+    GROCERIES,
+}
diff --git a/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/category/CategoryDao.kt b/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/category/CategoryDao.kt
new file mode 100644
index 0000000..02a9323
--- /dev/null
+++ b/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/category/CategoryDao.kt
@@ -0,0 +1,34 @@
+package cz.cvut.fel.pda.financemanagement.database.category
+
+import androidx.room.Dao
+import androidx.room.Delete
+import androidx.room.Insert
+import androidx.room.OnConflictStrategy
+import androidx.room.Query
+import androidx.room.Update
+import kotlinx.coroutines.flow.Flow
+
+@Dao
+interface CategoryDao {
+
+    @Query("SELECT * FROM `category` ORDER BY id ASC")
+    fun getAllCategories(): Flow<List<Category>>
+
+    @Query("SELECT * FROM `category` WHERE id = :id")
+    fun getCategoryForId(id: Long): Flow<Category>
+
+    @Insert(onConflict = OnConflictStrategy.REPLACE)
+    suspend fun insertCategories(vararg transactions: Category)
+
+    @Update
+    suspend fun updateCategories(vararg transactions: Category)
+
+    @Delete
+    suspend fun delete(item: Category)
+
+    @Query("DELETE FROM `category`")
+    suspend fun deleteAll()
+
+    @Query("SELECT * FROM `category` ORDER BY id ASC")
+    suspend fun getCategories(): List<Category>
+}
\ No newline at end of file
diff --git a/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/category/CategoryRepository.kt b/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/category/CategoryRepository.kt
new file mode 100644
index 0000000..cfd96e9
--- /dev/null
+++ b/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/category/CategoryRepository.kt
@@ -0,0 +1,12 @@
+package cz.cvut.fel.pda.financemanagement.database.category
+
+import kotlinx.coroutines.flow.Flow
+
+interface CategoryRepository {
+    fun getAllCategoriesStream(): Flow<List<Category>>
+    fun getCategoryForIdStream(id: Long): Flow<Category?>
+    suspend fun insertCategories(vararg categories: Category)
+    suspend fun deleteCategory(category: Category)
+    suspend fun deleteAllCategories()
+    suspend fun updateCategory(vararg categories: Category)
+}
\ No newline at end of file
diff --git a/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/transaction/OfflineTransactionRepository.kt b/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/transaction/OfflineTransactionRepository.kt
index 6015f19..f5204f7 100644
--- a/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/transaction/OfflineTransactionRepository.kt
+++ b/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/transaction/OfflineTransactionRepository.kt
@@ -1,11 +1,14 @@
 package cz.cvut.fel.pda.financemanagement.database.transaction
 
+import cz.cvut.fel.pda.financemanagement.model.CategoryWithTransaction
 import kotlinx.coroutines.flow.Flow
 
 class OfflineTransactionRepository(private val transactionDao: TransactionDao):
     TransactionRepository {
     override fun getAllTransactionsStream(): Flow<List<Transaction>> = transactionDao.getAllTransactions()
     override fun getTransactionForIdStream(id: Long): Flow<Transaction?> = transactionDao.getTransactionForId(id)
+    override fun getTransactionsWithCategory(): Flow<List<CategoryWithTransaction>> = transactionDao.getTransactionsWithCategory()
+
     override suspend fun insertTransactions(vararg transactions: Transaction) = transactionDao.insertTransactions(*transactions)
     override suspend fun deleteTransaction(transaction: Transaction) = transactionDao.delete(transaction)
     override suspend fun deleteAllTransactions() = transactionDao.deleteAll()
diff --git a/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/transaction/Transaction.kt b/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/transaction/Transaction.kt
index 540a53c..5486dd5 100644
--- a/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/transaction/Transaction.kt
+++ b/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/transaction/Transaction.kt
@@ -11,5 +11,6 @@ data class Transaction(
     val id: Long = 0,
     val description: String = "",
     val imageUrl: String = "",
-    val amount: BigDecimal = BigDecimal.ZERO
+    val amount: BigDecimal = BigDecimal.ZERO,
+    val categoryId: Long,
 )
diff --git a/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/transaction/TransactionDao.kt b/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/transaction/TransactionDao.kt
index e31cc3c..a47fda2 100644
--- a/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/transaction/TransactionDao.kt
+++ b/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/transaction/TransactionDao.kt
@@ -6,6 +6,7 @@ import androidx.room.Insert
 import androidx.room.OnConflictStrategy
 import androidx.room.Query
 import androidx.room.Update
+import cz.cvut.fel.pda.financemanagement.model.CategoryWithTransaction
 import kotlinx.coroutines.flow.Flow
 
 @Dao
@@ -17,6 +18,13 @@ interface TransactionDao {
     @Query("SELECT * FROM `transaction` WHERE id = :id")
     fun getTransactionForId(id: Long): Flow<Transaction>
 
+    @Query("""
+    SELECT * FROM `transaction`
+    INNER JOIN `category` ON `transaction`.categoryId = `category`.id
+    ORDER BY `transaction`.id ASC
+""")
+    fun getTransactionsWithCategory(): Flow<List<CategoryWithTransaction>>
+
     @Insert(onConflict = OnConflictStrategy.REPLACE)
     suspend fun insertTransactions(vararg transactions: Transaction)
 
@@ -28,7 +36,4 @@ interface TransactionDao {
 
     @Query("DELETE FROM `transaction`")
     suspend fun deleteAll()
-
-    @Query("SELECT * FROM `transaction` ORDER BY id ASC")
-    suspend fun getTransactions(): List<Transaction>
 }
\ No newline at end of file
diff --git a/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/transaction/TransactionDatabase.kt b/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/transaction/TransactionDatabase.kt
deleted file mode 100644
index 885e02a..0000000
--- a/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/transaction/TransactionDatabase.kt
+++ /dev/null
@@ -1,34 +0,0 @@
-package cz.cvut.fel.pda.financemanagement.database.transaction
-
-import android.content.Context
-import androidx.room.Database
-import androidx.room.Room
-import androidx.room.RoomDatabase
-import androidx.room.TypeConverters
-import cz.cvut.fel.pda.financemanagement.database.typeConvertion.Converters
-
-@Database(entities = [Transaction::class], version = 4, exportSchema = false)
-@TypeConverters(Converters::class)
-abstract class TransactionDatabase : RoomDatabase(){
-    abstract fun transactionDao(): TransactionDao
-
-    companion object{
-        @Volatile
-        private var INSTANCE: TransactionDatabase? = null
-
-        fun getDatabase(context: Context): TransactionDatabase {
-            return INSTANCE ?: synchronized(this) {
-                Room.databaseBuilder(
-                    context.applicationContext,
-                    TransactionDatabase::class.java,
-                    "transaction_database"
-                )
-                .fallbackToDestructiveMigration()
-                .build()
-                .also {
-                    INSTANCE = it
-                }
-            }
-        }
-    }
-}
\ No newline at end of file
diff --git a/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/transaction/TransactionRepository.kt b/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/transaction/TransactionRepository.kt
index 64fef70..86f9951 100644
--- a/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/transaction/TransactionRepository.kt
+++ b/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/transaction/TransactionRepository.kt
@@ -1,10 +1,12 @@
 package cz.cvut.fel.pda.financemanagement.database.transaction
 
+import cz.cvut.fel.pda.financemanagement.model.CategoryWithTransaction
 import kotlinx.coroutines.flow.Flow
 
 interface TransactionRepository {
     fun getAllTransactionsStream(): Flow<List<Transaction>>
     fun getTransactionForIdStream(id: Long): Flow<Transaction?>
+    fun getTransactionsWithCategory(): Flow<List<CategoryWithTransaction>>
     suspend fun insertTransactions(vararg transactions: Transaction)
     suspend fun deleteTransaction(transaction: Transaction)
     suspend fun deleteAllTransactions()
diff --git a/app/src/main/java/cz/cvut/fel/pda/financemanagement/di/AppContainer.kt b/app/src/main/java/cz/cvut/fel/pda/financemanagement/di/AppContainer.kt
index 51b346a..fdc8ec7 100644
--- a/app/src/main/java/cz/cvut/fel/pda/financemanagement/di/AppContainer.kt
+++ b/app/src/main/java/cz/cvut/fel/pda/financemanagement/di/AppContainer.kt
@@ -1,8 +1,8 @@
 package cz.cvut.fel.pda.financemanagement.di
 
 import android.content.Context
+import cz.cvut.fel.pda.financemanagement.database.AppDatabase
 import cz.cvut.fel.pda.financemanagement.database.transaction.OfflineTransactionRepository
-import cz.cvut.fel.pda.financemanagement.database.transaction.TransactionDatabase
 import cz.cvut.fel.pda.financemanagement.database.transaction.TransactionRepository
 
 interface AppContainer {
@@ -11,6 +11,6 @@ interface AppContainer {
 
 class AppDataContainer(private val context: Context) : AppContainer {
     override val transactionRepository: TransactionRepository by lazy {
-        OfflineTransactionRepository(TransactionDatabase.getDatabase(context).transactionDao())
+        OfflineTransactionRepository(AppDatabase.getDatabase(context).transactionDao())
     }
 }
\ No newline at end of file
diff --git a/app/src/main/java/cz/cvut/fel/pda/financemanagement/model/CategoryWithTransaction.kt b/app/src/main/java/cz/cvut/fel/pda/financemanagement/model/CategoryWithTransaction.kt
new file mode 100644
index 0000000..7c31e6f
--- /dev/null
+++ b/app/src/main/java/cz/cvut/fel/pda/financemanagement/model/CategoryWithTransaction.kt
@@ -0,0 +1,15 @@
+package cz.cvut.fel.pda.financemanagement.model
+
+import androidx.room.Embedded
+import androidx.room.Relation
+import cz.cvut.fel.pda.financemanagement.database.category.Category
+import cz.cvut.fel.pda.financemanagement.database.transaction.Transaction
+
+data class CategoryWithTransaction(
+    @Embedded val transaction: Transaction,
+    @Relation(
+        parentColumn = "categoryId",
+        entityColumn = "id"
+    )
+    val category: Category
+)
\ No newline at end of file
diff --git a/app/src/main/java/cz/cvut/fel/pda/financemanagement/model/TransactionCategory.kt b/app/src/main/java/cz/cvut/fel/pda/financemanagement/model/TransactionCategory.kt
deleted file mode 100644
index a357182..0000000
--- a/app/src/main/java/cz/cvut/fel/pda/financemanagement/model/TransactionCategory.kt
+++ /dev/null
@@ -1,17 +0,0 @@
-package cz.cvut.fel.pda.financemanagement.model
-
-enum class Category {
-    SALARY,
-    RENT,
-    GROCERIES,
-}
-
-enum class Type {
-    INCOME,
-    EXPENSE
-}
-
-data class TransactionCategory(
-    val type: Type = Type.EXPENSE,
-    val category: Category = Category.RENT
-)
\ No newline at end of file
diff --git a/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/transactions/EditTransactionScreen.kt b/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/transactions/EditTransactionScreen.kt
index abc86f3..463bd58 100644
--- a/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/transactions/EditTransactionScreen.kt
+++ b/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/transactions/EditTransactionScreen.kt
@@ -19,8 +19,8 @@ import androidx.compose.material3.TextButton
 import androidx.compose.material3.TopAppBar
 import androidx.compose.material3.TopAppBarDefaults
 import androidx.compose.runtime.Composable
-import androidx.compose.runtime.getValue
 import androidx.compose.runtime.MutableState
+import androidx.compose.runtime.getValue
 import androidx.compose.runtime.mutableStateOf
 import androidx.compose.runtime.remember
 import androidx.compose.runtime.saveable.rememberSaveable
@@ -92,8 +92,8 @@ fun ShowSuccessScreen(
                 actions = {
                     TextButton(
                         onClick = {
-                            transactionViewModel.savePlayground(
-                                amount = BigDecimal(amount.value)
+                            transactionViewModel.saveTransaction(
+                                amount = BigDecimal(amount.value),
                             )
                             navController.popBackStack()
                         },
diff --git a/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/transactions/TransactionDetailViewModel.kt b/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/transactions/TransactionDetailViewModel.kt
index 753dfe3..1d34f03 100644
--- a/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/transactions/TransactionDetailViewModel.kt
+++ b/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/transactions/TransactionDetailViewModel.kt
@@ -2,11 +2,11 @@ package cz.cvut.fel.pda.financemanagement.ui.screens.transactions
 
 import androidx.lifecycle.SavedStateHandle
 import androidx.lifecycle.ViewModel
+import androidx.lifecycle.viewModelScope
 import cz.cvut.fel.pda.financemanagement.database.transaction.Transaction
 import cz.cvut.fel.pda.financemanagement.database.transaction.TransactionRepository
-import kotlinx.coroutines.flow.StateFlow
-import androidx.lifecycle.viewModelScope
 import kotlinx.coroutines.flow.SharingStarted
+import kotlinx.coroutines.flow.StateFlow
 import kotlinx.coroutines.flow.map
 import kotlinx.coroutines.flow.stateIn
 import kotlinx.coroutines.launch
@@ -25,7 +25,7 @@ class TransactionDetailViewModel(
                 if (it != null) {
                     TransactionUiState.Success(it)
                 } else if (transactionId == 0L) {
-                    TransactionUiState.Success(Transaction())
+                    TransactionUiState.Success(Transaction(categoryId = 0L))
                 } else {
                     TransactionUiState.Error(Exception("Transaction not found"))
                 }
@@ -34,14 +34,15 @@ class TransactionDetailViewModel(
                 started = SharingStarted.WhileSubscribed(5000L),
                 initialValue = TransactionUiState.Loading
             )
-    fun savePlayground(
+    fun saveTransaction(
         amount: BigDecimal
     ) {
         viewModelScope.launch {
             transactionRepository.insertTransactions(
                 Transaction(
                     id = transactionId,
-                    amount = amount
+                    amount = amount,
+                    categoryId = 1L
                 )
             )
         }
diff --git a/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/transactions/TransactionViewModel.kt b/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/transactions/TransactionViewModel.kt
index ecae25f..f41519f 100644
--- a/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/transactions/TransactionViewModel.kt
+++ b/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/transactions/TransactionViewModel.kt
@@ -2,64 +2,37 @@ package cz.cvut.fel.pda.financemanagement.ui.screens.transactions
 
 import androidx.lifecycle.ViewModel
 import androidx.lifecycle.viewModelScope
-import cz.cvut.fel.pda.financemanagement.database.transaction.Transaction
 import cz.cvut.fel.pda.financemanagement.database.transaction.TransactionRepository
+import cz.cvut.fel.pda.financemanagement.model.CategoryWithTransaction
 import cz.cvut.fel.pda.financemanagement.model.common.Result
 import cz.cvut.fel.pda.financemanagement.model.common.asResult
 import kotlinx.coroutines.flow.SharingStarted
 import kotlinx.coroutines.flow.StateFlow
 import kotlinx.coroutines.flow.map
 import kotlinx.coroutines.flow.stateIn
-import kotlinx.coroutines.launch
 
 class TransactionViewModel(
     private val transactionRepository: TransactionRepository,
 ) : ViewModel(){
-    val transactions : StateFlow<TransactionsUiState> =
+    val transactionsWithCategory : StateFlow<TransactionsWithCategoryUiState> =
         transactionRepository
-            .getAllTransactionsStream()
+            .getTransactionsWithCategory()
             .asResult()
             .map { allTransactionsToResult ->
                 when (allTransactionsToResult) {
-                    is Result.Error -> TransactionsUiState.Error(Exception(allTransactionsToResult.exception))
-                    is Result.Loading -> TransactionsUiState.Loading
-                    is Result.Success -> TransactionsUiState.Success(allTransactionsToResult.data)
+                    is Result.Error -> TransactionsWithCategoryUiState.Error(Exception(allTransactionsToResult.exception))
+                    is Result.Loading -> TransactionsWithCategoryUiState.Loading
+                    is Result.Success -> TransactionsWithCategoryUiState.Success(allTransactionsToResult.data)
                 }
             }.stateIn(
                 scope = viewModelScope,
                 started = SharingStarted.WhileSubscribed(5000L),
-                initialValue = TransactionsUiState.Loading
+                initialValue = TransactionsWithCategoryUiState.Loading
             )
-    fun addTransaction(transaction: Transaction) {
-        viewModelScope.launch {
-            transactionRepository.insertTransactions(
-                transaction)
-        }
-    }
-/*
-    fun addRandomTransaction() {
-        viewModelScope.launch {
-            transactionRepository.insertPlaygrounds(
-                assetsGeojsonFileRepository.getRandomPlayground().toPlayground()
-            )
-        }
-    }
-
-    fun importTransactions() {
-        viewModelScope.launch {
-            transactionRepository.insertPlaygrounds(*assetsGeojsonFileRepository.getAllPlaygrounds().map { it.toPlayground() }.toTypedArray())
-        }
-    }*/
-
-    fun deleteAllTransactions() {
-        viewModelScope.launch {
-            transactionRepository.deleteAllTransactions()
-        }
-    }
 }
 
-sealed interface TransactionsUiState {
-    data object Loading : TransactionsUiState
-    data class Success(val itemList: List<Transaction> = listOf()) : TransactionsUiState
-    data class Error(val exception: Exception) : TransactionsUiState
+sealed interface TransactionsWithCategoryUiState {
+    data object Loading : TransactionsWithCategoryUiState
+    data class Success(val itemList: List<CategoryWithTransaction> = listOf()) : TransactionsWithCategoryUiState
+    data class Error(val exception: Exception) : TransactionsWithCategoryUiState
 }
\ No newline at end of file
diff --git a/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/transactions/TransactionsScreen.kt b/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/transactions/TransactionsScreen.kt
index 991daa4..925275d 100644
--- a/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/transactions/TransactionsScreen.kt
+++ b/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/transactions/TransactionsScreen.kt
@@ -39,15 +39,18 @@ import androidx.lifecycle.viewmodel.compose.viewModel
 import androidx.navigation.NavHostController
 import androidx.navigation.compose.rememberNavController
 import cz.cvut.fel.pda.financemanagement.FinanceManagementScreens
+import cz.cvut.fel.pda.financemanagement.database.category.Category
+import cz.cvut.fel.pda.financemanagement.database.category.CategoryType
 import cz.cvut.fel.pda.financemanagement.database.transaction.Transaction
-import cz.cvut.fel.pda.financemanagement.model.Type
+import cz.cvut.fel.pda.financemanagement.model.CategoryWithTransaction
 import cz.cvut.fel.pda.financemanagement.ui.components.BottomNavigation
 import cz.cvut.fel.pda.financemanagement.ui.components.ShowErrorScreen
 import cz.cvut.fel.pda.financemanagement.ui.components.ShowLoadingScreen
 import cz.cvut.fel.pda.financemanagement.ui.components.TopBar
 import cz.cvut.fel.pda.financemanagement.ui.theme.FinanceManagementTheme
 import cz.cvut.fel.pda.financemanagement.ui.utils.AppViewModelProvider
-import java.math.BigDecimal
+import cz.cvut.fel.pda.financemanagement.ui.utils.ColorUtils.getCategoryColor
+import cz.cvut.fel.pda.financemanagement.ui.utils.ColorUtils.getTotalValueColor
 
 @Composable
 fun TransactionsScreen(
@@ -56,21 +59,21 @@ fun TransactionsScreen(
         factory = AppViewModelProvider.Factory
     )
 ) {
-    val transactionsUiState: TransactionsUiState by transactionViewModel.transactions.collectAsStateWithLifecycle()
+    val transactionsUiState: TransactionsWithCategoryUiState by transactionViewModel.transactionsWithCategory.collectAsStateWithLifecycle()
     Scaffold(
         topBar = { TopBar() },
         content = { innerPadding ->
             when (transactionsUiState) {
-                is TransactionsUiState.Loading -> {
+                is TransactionsWithCategoryUiState.Loading -> {
                     ShowLoadingScreen()
                 }
-                is TransactionsUiState.Error -> {
+                is TransactionsWithCategoryUiState.Error -> {
                     ShowErrorScreen(
-                        errorMessage = (transactionsUiState as TransactionsUiState.Error).exception.message ?: "Error",
+                        errorMessage = (transactionsUiState as TransactionsWithCategoryUiState.Error).exception.message ?: "Error",
                     )
                 }
-                is TransactionsUiState.Success -> {
-                    TransactionScreenContent( (transactionsUiState as TransactionsUiState.Success).itemList, innerPadding)
+                is TransactionsWithCategoryUiState.Success -> {
+                    TransactionScreenContent( (transactionsUiState as TransactionsWithCategoryUiState.Success).itemList, innerPadding)
                 }
             }
         },
@@ -84,7 +87,7 @@ fun TransactionsScreen(
 }
 
 @Composable
-fun TransactionScreenContent(transactions: List<Transaction>, innerPadding: PaddingValues) {
+fun TransactionScreenContent(transactions: List<CategoryWithTransaction>, innerPadding: PaddingValues) {
     Column(modifier = Modifier
         .padding(innerPadding)
         .fillMaxWidth()) {
@@ -108,23 +111,27 @@ fun TransactionScreenContent(transactions: List<Transaction>, innerPadding: Padd
 }
 
 @Composable
-fun TotalSumOfTransactions(transactions: List<Transaction>) {
-    val totalSum = transactions.sumOf { it.amount }.toString()
-    Row(modifier = Modifier.fillMaxWidth().padding(14.dp),
+fun TotalSumOfTransactions(transactions: List<CategoryWithTransaction>) {
+    val totalIncome = transactions.filter { it.category.type == CategoryType.INCOME }.sumOf { it.transaction.amount }
+    val totalExpense = transactions.filter { it.category.type == CategoryType.EXPENSE }.sumOf { it.transaction.amount }
+    val totalSum = ((totalExpense.times((-1).toBigDecimal())) + totalIncome)
+    Row(modifier = Modifier
+        .fillMaxWidth()
+        .padding(14.dp),
         horizontalArrangement = Arrangement.Center){
         Text(text = "Total: ", style = TextStyle(fontSize = 24.sp, fontWeight = FontWeight.Bold))
         Text(text = "$totalSum CZK",
             style = TextStyle(
                 fontSize = 24.sp,
                 fontWeight = FontWeight.Bold,
-                color = Color(50, 168, 82)
+                color = getTotalValueColor(totalSum)
             )
         )
     }
 }
 
 @Composable
-fun ShowTabListSuccessScreen(itemList: List<Transaction>) {
+fun ShowTabListSuccessScreen(itemList: List<CategoryWithTransaction>) {
     if (itemList.isEmpty()){
         Box (
             modifier = Modifier.fillMaxSize(),
@@ -144,20 +151,20 @@ fun ShowTabListSuccessScreen(itemList: List<Transaction>) {
 
 @Composable
 fun TransactionsList(
-    itemList: List<Transaction>,
+    itemList: List<CategoryWithTransaction>,
     modifier: Modifier = Modifier
 ) {
     LazyColumn(
         modifier = modifier.fillMaxSize(),
         verticalArrangement = Arrangement.Top
     ) {
-        items(itemList) { transaction->
-            TransactionItem(transaction)
+        items(itemList) {transaction ->
+            TransactionItem(transaction.transaction, transaction.category)
         }
     }
 }
 @Composable
-fun TransactionItem(transaction: Transaction) {
+fun TransactionItem(transaction: Transaction, category: Category) {
     Row(
         modifier = Modifier
             .fillMaxWidth()
@@ -167,9 +174,12 @@ fun TransactionItem(transaction: Transaction) {
             , horizontalArrangement = Arrangement.SpaceBetween
     ) {
         Column {
-            Text(text = transaction.description, style = TextStyle(fontSize = 16.sp, fontWeight = FontWeight.Bold))
-            Text(text = transaction.amount.toString(), style = TextStyle(fontSize = 16.sp, fontWeight = FontWeight.Bold))
-        }
+            Text(text = category.name.toString(), style = TextStyle(fontSize = 16.sp, fontWeight = FontWeight.Bold))
+            Text(
+                text = if (category.type == CategoryType.EXPENSE) "-${transaction.amount}" else transaction.amount.toString(),
+                color = getCategoryColor(category),
+                style = TextStyle(fontSize = 16.sp, fontWeight = FontWeight.Bold)
+            ) }
         IconButton(onClick = { /* Handle click event here */ }) {
             Icon(Icons.Filled.MoreVert, contentDescription = "Options")
         }
diff --git a/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/utils/ColorUtils.kt b/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/utils/ColorUtils.kt
new file mode 100644
index 0000000..c3ffc91
--- /dev/null
+++ b/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/utils/ColorUtils.kt
@@ -0,0 +1,25 @@
+package cz.cvut.fel.pda.financemanagement.ui.utils
+
+import androidx.compose.ui.graphics.Color
+import cz.cvut.fel.pda.financemanagement.database.category.Category
+import cz.cvut.fel.pda.financemanagement.database.category.CategoryType
+import java.math.BigDecimal
+
+object ColorUtils {
+    private val negativeValue = Color(255, 0, 0)
+    private val positiveValue = Color(50, 168, 82)
+    fun getCategoryColor(category: Category): Color {
+        return if (category.type == CategoryType.INCOME) {
+            positiveValue
+        } else {
+            negativeValue
+        }
+    }
+    fun getTotalValueColor(value: BigDecimal): Color {
+        return if (value >= BigDecimal.ZERO) {
+            positiveValue
+        } else {
+            negativeValue
+        }
+    }
+}
\ No newline at end of file
-- 
GitLab


From 8f0493067160e81a147fefeb4ec53ab0022f893f Mon Sep 17 00:00:00 2001
From: dovicrad <dovicrad@fel.cvut.cz>
Date: Thu, 25 Apr 2024 10:42:05 +0200
Subject: [PATCH 04/12] :cooking: add transaction detail

---
 .idea/deploymentTargetDropDown.xml            |  3 +
 .../financemanagement/FinanceManagementApp.kt |  8 ++
 .../OfflineTransactionRepository.kt           |  2 +-
 .../database/transaction/TransactionDao.kt    |  8 +-
 .../transaction/TransactionRepository.kt      | 18 ++++-
 .../model/CategoryWithTransaction.kt          |  8 +-
 .../model/TransactionWithCategory.kt          |  9 +++
 .../transactions/TransactionDetailScreen.kt   | 78 +++++++++++++++++++
 .../TransactionDetailViewModel.kt             |  5 +-
 .../transactions/TransactionViewModel.kt      |  3 +-
 .../transactions/TransactionsScreen.kt        | 26 ++++---
 11 files changed, 147 insertions(+), 21 deletions(-)
 create mode 100644 app/src/main/java/cz/cvut/fel/pda/financemanagement/model/TransactionWithCategory.kt
 create mode 100644 app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/transactions/TransactionDetailScreen.kt

diff --git a/.idea/deploymentTargetDropDown.xml b/.idea/deploymentTargetDropDown.xml
index 9c96b2b..51f9d01 100644
--- a/.idea/deploymentTargetDropDown.xml
+++ b/.idea/deploymentTargetDropDown.xml
@@ -5,6 +5,9 @@
       <entry key="MainActivity">
         <State />
       </entry>
+      <entry key="MainActivity (1)">
+        <State />
+      </entry>
       <entry key="app">
         <State />
       </entry>
diff --git a/app/src/main/java/cz/cvut/fel/pda/financemanagement/FinanceManagementApp.kt b/app/src/main/java/cz/cvut/fel/pda/financemanagement/FinanceManagementApp.kt
index abf31dd..c930012 100644
--- a/app/src/main/java/cz/cvut/fel/pda/financemanagement/FinanceManagementApp.kt
+++ b/app/src/main/java/cz/cvut/fel/pda/financemanagement/FinanceManagementApp.kt
@@ -12,11 +12,13 @@ import cz.cvut.fel.pda.financemanagement.ui.screens.AccountsScreen
 import cz.cvut.fel.pda.financemanagement.ui.screens.CategoriesScreen
 import cz.cvut.fel.pda.financemanagement.ui.screens.LoansScreen
 import cz.cvut.fel.pda.financemanagement.ui.screens.transactions.EditTransactionScreen
+import cz.cvut.fel.pda.financemanagement.ui.screens.transactions.TransactionDetailScreen
 import cz.cvut.fel.pda.financemanagement.ui.screens.transactions.TransactionsScreen
 
 
 enum class FinanceManagementScreens() {
     Transactions,
+    TransactionsDetail,
     EditTransaction,
     Accounts,
     Categories,
@@ -51,5 +53,11 @@ fun FinanceManagementApp() {
                 transitionId = it.arguments?.getLong("Id")
             )
         }
+        composable(route = "${FinanceManagementScreens.TransactionsDetail.name}/{Id}",
+            arguments = listOf(navArgument("Id") { type = NavType.LongType })){
+            TransactionDetailScreen(navController,
+                transactionId = it.arguments?.getLong("Id")
+            )
+        }
     }
 }
\ No newline at end of file
diff --git a/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/transaction/OfflineTransactionRepository.kt b/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/transaction/OfflineTransactionRepository.kt
index f5204f7..316a714 100644
--- a/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/transaction/OfflineTransactionRepository.kt
+++ b/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/transaction/OfflineTransactionRepository.kt
@@ -7,7 +7,7 @@ class OfflineTransactionRepository(private val transactionDao: TransactionDao):
     TransactionRepository {
     override fun getAllTransactionsStream(): Flow<List<Transaction>> = transactionDao.getAllTransactions()
     override fun getTransactionForIdStream(id: Long): Flow<Transaction?> = transactionDao.getTransactionForId(id)
-    override fun getTransactionsWithCategory(): Flow<List<CategoryWithTransaction>> = transactionDao.getTransactionsWithCategory()
+    override fun getCategoryWithTransactions(): Flow<List<CategoryWithTransaction>> = transactionDao.getCategoryWithTransaction()
 
     override suspend fun insertTransactions(vararg transactions: Transaction) = transactionDao.insertTransactions(*transactions)
     override suspend fun deleteTransaction(transaction: Transaction) = transactionDao.delete(transaction)
diff --git a/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/transaction/TransactionDao.kt b/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/transaction/TransactionDao.kt
index a47fda2..6e5b40a 100644
--- a/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/transaction/TransactionDao.kt
+++ b/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/transaction/TransactionDao.kt
@@ -19,11 +19,11 @@ interface TransactionDao {
     fun getTransactionForId(id: Long): Flow<Transaction>
 
     @Query("""
-    SELECT * FROM `transaction`
-    INNER JOIN `category` ON `transaction`.categoryId = `category`.id
-    ORDER BY `transaction`.id ASC
+    SELECT * FROM `category`
+    INNER JOIN `transaction` ON `transaction`.categoryId = `category`.id
+    ORDER BY `category`.id ASC
 """)
-    fun getTransactionsWithCategory(): Flow<List<CategoryWithTransaction>>
+    fun getCategoryWithTransaction(): Flow<List<CategoryWithTransaction>>
 
     @Insert(onConflict = OnConflictStrategy.REPLACE)
     suspend fun insertTransactions(vararg transactions: Transaction)
diff --git a/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/transaction/TransactionRepository.kt b/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/transaction/TransactionRepository.kt
index 86f9951..52b4cbd 100644
--- a/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/transaction/TransactionRepository.kt
+++ b/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/transaction/TransactionRepository.kt
@@ -1,12 +1,28 @@
 package cz.cvut.fel.pda.financemanagement.database.transaction
 
+import android.util.Log
 import cz.cvut.fel.pda.financemanagement.model.CategoryWithTransaction
+import cz.cvut.fel.pda.financemanagement.model.TransactionWithCategory
 import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.map
 
 interface TransactionRepository {
     fun getAllTransactionsStream(): Flow<List<Transaction>>
     fun getTransactionForIdStream(id: Long): Flow<Transaction?>
-    fun getTransactionsWithCategory(): Flow<List<CategoryWithTransaction>>
+
+    fun getCategoryWithTransactions(): Flow<List<CategoryWithTransaction>>
+    fun getTransactionsWithCategory(): Flow<List<TransactionWithCategory>> {
+        return getCategoryWithTransactions().map { categoryWithTransactionList ->
+            categoryWithTransactionList.flatMap { categoryWithTransaction ->
+                categoryWithTransaction.transaction.map { transaction ->
+                    TransactionWithCategory(
+                        transaction = transaction,
+                        category = categoryWithTransaction.category
+                    )
+                }
+            }
+        }
+    }
     suspend fun insertTransactions(vararg transactions: Transaction)
     suspend fun deleteTransaction(transaction: Transaction)
     suspend fun deleteAllTransactions()
diff --git a/app/src/main/java/cz/cvut/fel/pda/financemanagement/model/CategoryWithTransaction.kt b/app/src/main/java/cz/cvut/fel/pda/financemanagement/model/CategoryWithTransaction.kt
index 7c31e6f..5d11a1e 100644
--- a/app/src/main/java/cz/cvut/fel/pda/financemanagement/model/CategoryWithTransaction.kt
+++ b/app/src/main/java/cz/cvut/fel/pda/financemanagement/model/CategoryWithTransaction.kt
@@ -6,10 +6,10 @@ import cz.cvut.fel.pda.financemanagement.database.category.Category
 import cz.cvut.fel.pda.financemanagement.database.transaction.Transaction
 
 data class CategoryWithTransaction(
-    @Embedded val transaction: Transaction,
+    @Embedded val category: Category,
     @Relation(
-        parentColumn = "categoryId",
-        entityColumn = "id"
+        parentColumn = "id",
+        entityColumn = "categoryId"
     )
-    val category: Category
+    val transaction: List<Transaction>,
 )
\ No newline at end of file
diff --git a/app/src/main/java/cz/cvut/fel/pda/financemanagement/model/TransactionWithCategory.kt b/app/src/main/java/cz/cvut/fel/pda/financemanagement/model/TransactionWithCategory.kt
new file mode 100644
index 0000000..0e4a422
--- /dev/null
+++ b/app/src/main/java/cz/cvut/fel/pda/financemanagement/model/TransactionWithCategory.kt
@@ -0,0 +1,9 @@
+package cz.cvut.fel.pda.financemanagement.model
+
+import cz.cvut.fel.pda.financemanagement.database.category.Category
+import cz.cvut.fel.pda.financemanagement.database.transaction.Transaction
+
+data class TransactionWithCategory(
+    val transaction: Transaction,
+    val category: Category,
+)
\ No newline at end of file
diff --git a/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/transactions/TransactionDetailScreen.kt b/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/transactions/TransactionDetailScreen.kt
new file mode 100644
index 0000000..ef838f4
--- /dev/null
+++ b/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/transactions/TransactionDetailScreen.kt
@@ -0,0 +1,78 @@
+package cz.cvut.fel.pda.financemanagement.ui.screens.transactions
+
+import android.provider.Settings.Global.putLong
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.PaddingValues
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.Spacer
+import androidx.compose.foundation.layout.height
+import androidx.compose.foundation.layout.padding
+import androidx.compose.material3.Scaffold
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.getValue
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.unit.dp
+import androidx.lifecycle.compose.collectAsStateWithLifecycle
+import androidx.lifecycle.viewmodel.CreationExtras
+import androidx.lifecycle.viewmodel.compose.viewModel
+import androidx.navigation.NavHostController
+import cz.cvut.fel.pda.financemanagement.database.transaction.Transaction
+import cz.cvut.fel.pda.financemanagement.ui.components.BottomNavigation
+import cz.cvut.fel.pda.financemanagement.ui.components.ShowErrorScreen
+import cz.cvut.fel.pda.financemanagement.ui.components.ShowLoadingScreen
+import cz.cvut.fel.pda.financemanagement.ui.components.TopBar
+import cz.cvut.fel.pda.financemanagement.ui.utils.AppViewModelProvider
+
+
+@Composable
+fun TransactionDetailScreen(
+    navController: NavHostController,
+    transactionId: Long?,
+    transactionViewModel: TransactionDetailViewModel = viewModel(
+        factory = AppViewModelProvider.Factory
+    )
+){
+    transactionViewModel.setTransactionId(transactionId ?: 0L)
+    val transactionUiState: TransactionUiState by transactionViewModel.uiState.collectAsStateWithLifecycle()
+
+    Scaffold (
+        topBar = {TopBar()},
+        content = {
+            innerPadding ->
+            when (transactionUiState) {
+                is TransactionUiState.Loading -> {
+                    ShowLoadingScreen()
+                }
+                is TransactionUiState.Error -> {
+                    ShowErrorScreen(
+                        errorMessage = (transactionUiState as TransactionUiState.Error).exception.message ?: "Error",
+                    )
+                }
+                is TransactionUiState.Success -> {
+                    TransactionScreenContent( (transactionUiState as TransactionUiState.Success).transaction, innerPadding, navController)
+                }
+            }
+        },
+        bottomBar = {
+            BottomNavigation(navController = navController)
+        }
+    )
+}
+
+@Composable
+fun TransactionScreenContent(transaction: Transaction, innerPadding: PaddingValues, navController: NavHostController) {
+    Column(modifier = Modifier.padding(innerPadding)) {
+        Text(text = "Transaction Details")
+        Spacer(modifier = Modifier.height(16.dp))
+        Row {
+            Text(text = "ID: ")
+            Text(text = transaction.id.toString())
+        }
+        Row {
+            Text(text = "Amount: ")
+            Text(text = transaction.amount.toString())
+        }
+        // Add more fields as needed
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/transactions/TransactionDetailViewModel.kt b/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/transactions/TransactionDetailViewModel.kt
index 1d34f03..ce6080c 100644
--- a/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/transactions/TransactionDetailViewModel.kt
+++ b/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/transactions/TransactionDetailViewModel.kt
@@ -16,7 +16,7 @@ class TransactionDetailViewModel(
     private val transactionRepository: TransactionRepository,
     savedStateHandle: SavedStateHandle
 ): ViewModel() {
-    private val transactionId: Long = savedStateHandle.get<Long>("Id")!!
+    private var transactionId: Long = savedStateHandle.get<Long>("Id")!!
 
     val uiState: StateFlow<TransactionUiState> =
         transactionRepository
@@ -34,6 +34,9 @@ class TransactionDetailViewModel(
                 started = SharingStarted.WhileSubscribed(5000L),
                 initialValue = TransactionUiState.Loading
             )
+    fun setTransactionId(id: Long) {
+        transactionId = id
+    }
     fun saveTransaction(
         amount: BigDecimal
     ) {
diff --git a/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/transactions/TransactionViewModel.kt b/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/transactions/TransactionViewModel.kt
index f41519f..0851eaa 100644
--- a/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/transactions/TransactionViewModel.kt
+++ b/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/transactions/TransactionViewModel.kt
@@ -4,6 +4,7 @@ import androidx.lifecycle.ViewModel
 import androidx.lifecycle.viewModelScope
 import cz.cvut.fel.pda.financemanagement.database.transaction.TransactionRepository
 import cz.cvut.fel.pda.financemanagement.model.CategoryWithTransaction
+import cz.cvut.fel.pda.financemanagement.model.TransactionWithCategory
 import cz.cvut.fel.pda.financemanagement.model.common.Result
 import cz.cvut.fel.pda.financemanagement.model.common.asResult
 import kotlinx.coroutines.flow.SharingStarted
@@ -33,6 +34,6 @@ class TransactionViewModel(
 
 sealed interface TransactionsWithCategoryUiState {
     data object Loading : TransactionsWithCategoryUiState
-    data class Success(val itemList: List<CategoryWithTransaction> = listOf()) : TransactionsWithCategoryUiState
+    data class Success(val itemList: List<TransactionWithCategory> = listOf()) : TransactionsWithCategoryUiState
     data class Error(val exception: Exception) : TransactionsWithCategoryUiState
 }
\ No newline at end of file
diff --git a/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/transactions/TransactionsScreen.kt b/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/transactions/TransactionsScreen.kt
index 925275d..c39b30b 100644
--- a/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/transactions/TransactionsScreen.kt
+++ b/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/transactions/TransactionsScreen.kt
@@ -1,6 +1,7 @@
 package cz.cvut.fel.pda.financemanagement.ui.screens.transactions
 
 import androidx.compose.foundation.border
+import androidx.compose.foundation.clickable
 import androidx.compose.foundation.layout.Arrangement
 import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.Column
@@ -43,6 +44,7 @@ import cz.cvut.fel.pda.financemanagement.database.category.Category
 import cz.cvut.fel.pda.financemanagement.database.category.CategoryType
 import cz.cvut.fel.pda.financemanagement.database.transaction.Transaction
 import cz.cvut.fel.pda.financemanagement.model.CategoryWithTransaction
+import cz.cvut.fel.pda.financemanagement.model.TransactionWithCategory
 import cz.cvut.fel.pda.financemanagement.ui.components.BottomNavigation
 import cz.cvut.fel.pda.financemanagement.ui.components.ShowErrorScreen
 import cz.cvut.fel.pda.financemanagement.ui.components.ShowLoadingScreen
@@ -73,7 +75,7 @@ fun TransactionsScreen(
                     )
                 }
                 is TransactionsWithCategoryUiState.Success -> {
-                    TransactionScreenContent( (transactionsUiState as TransactionsWithCategoryUiState.Success).itemList, innerPadding)
+                    TransactionScreenContent( (transactionsUiState as TransactionsWithCategoryUiState.Success).itemList,navController, innerPadding)
                 }
             }
         },
@@ -87,7 +89,11 @@ fun TransactionsScreen(
 }
 
 @Composable
-fun TransactionScreenContent(transactions: List<CategoryWithTransaction>, innerPadding: PaddingValues) {
+fun TransactionScreenContent(
+    transactions: List<TransactionWithCategory>,
+    navController: NavHostController,
+    innerPadding: PaddingValues
+) {
     Column(modifier = Modifier
         .padding(innerPadding)
         .fillMaxWidth()) {
@@ -105,13 +111,13 @@ fun TransactionScreenContent(transactions: List<CategoryWithTransaction>, innerP
 
             }
             HorizontalDivider()
-            ShowTabListSuccessScreen(transactions)
+            ShowTabListSuccessScreen(transactions, navController)
         }
   }
 }
 
 @Composable
-fun TotalSumOfTransactions(transactions: List<CategoryWithTransaction>) {
+fun TotalSumOfTransactions(transactions: List<TransactionWithCategory>) {
     val totalIncome = transactions.filter { it.category.type == CategoryType.INCOME }.sumOf { it.transaction.amount }
     val totalExpense = transactions.filter { it.category.type == CategoryType.EXPENSE }.sumOf { it.transaction.amount }
     val totalSum = ((totalExpense.times((-1).toBigDecimal())) + totalIncome)
@@ -131,7 +137,7 @@ fun TotalSumOfTransactions(transactions: List<CategoryWithTransaction>) {
 }
 
 @Composable
-fun ShowTabListSuccessScreen(itemList: List<CategoryWithTransaction>) {
+fun ShowTabListSuccessScreen(itemList: List<TransactionWithCategory>, navController: NavHostController) {
     if (itemList.isEmpty()){
         Box (
             modifier = Modifier.fillMaxSize(),
@@ -145,13 +151,14 @@ fun ShowTabListSuccessScreen(itemList: List<CategoryWithTransaction>) {
             )
         }
     } else {
-        TransactionsList(itemList)
+        TransactionsList(itemList, navController)
     }
 }
 
 @Composable
 fun TransactionsList(
-    itemList: List<CategoryWithTransaction>,
+    itemList: List<TransactionWithCategory>,
+    navController: NavHostController,
     modifier: Modifier = Modifier
 ) {
     LazyColumn(
@@ -159,17 +166,18 @@ fun TransactionsList(
         verticalArrangement = Arrangement.Top
     ) {
         items(itemList) {transaction ->
-            TransactionItem(transaction.transaction, transaction.category)
+            TransactionItem(transaction.transaction, transaction.category, navController)
         }
     }
 }
 @Composable
-fun TransactionItem(transaction: Transaction, category: Category) {
+fun TransactionItem(transaction: Transaction, category: Category, navController: NavHostController) {
     Row(
         modifier = Modifier
             .fillMaxWidth()
             .padding(vertical = 8.dp)
             .border(1.dp, Color.Gray, shape = RoundedCornerShape(3.dp))
+            .clickable { navController.navigate("${FinanceManagementScreens.TransactionsDetail.name}/${transaction.id}") }
             .padding(8.dp)
             , horizontalArrangement = Arrangement.SpaceBetween
     ) {
-- 
GitLab


From 32f2488fabb6324b0949f2e6e16b74cc1d4639ed Mon Sep 17 00:00:00 2001
From: dovicrad <dovicrad@fel.cvut.cz>
Date: Thu, 25 Apr 2024 12:14:12 +0200
Subject: [PATCH 05/12] :cooking: add transaction sorting

---
 .../financemanagement/database/AppDatabase.kt |  2 +-
 .../database/transaction/Operation.kt         | 17 +++++++
 .../database/transaction/Transaction.kt       | 14 +++---
 .../database/typeConvertion/Converters.kt     | 12 +++++
 .../financemanagement/ui/components/TopBar.kt |  2 +-
 .../transactions/EditTransactionScreen.kt     | 10 ++--
 .../transactions/TransactionsScreen.kt        | 48 +++++++++++++++----
 7 files changed, 85 insertions(+), 20 deletions(-)
 create mode 100644 app/src/main/java/cz/cvut/fel/pda/financemanagement/database/transaction/Operation.kt

diff --git a/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/AppDatabase.kt b/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/AppDatabase.kt
index 7abdd45..ac315bf 100644
--- a/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/AppDatabase.kt
+++ b/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/AppDatabase.kt
@@ -11,7 +11,7 @@ import cz.cvut.fel.pda.financemanagement.database.transaction.Transaction
 import cz.cvut.fel.pda.financemanagement.database.transaction.TransactionDao
 import cz.cvut.fel.pda.financemanagement.database.typeConvertion.Converters
 
-@Database(entities = [Transaction::class, Category::class], version = 6, exportSchema = false)
+@Database(entities = [Transaction::class, Category::class], version = 7, exportSchema = false)
 @TypeConverters(Converters::class)
 abstract class AppDatabase : RoomDatabase(){
     abstract fun transactionDao(): TransactionDao
diff --git a/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/transaction/Operation.kt b/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/transaction/Operation.kt
new file mode 100644
index 0000000..5618432
--- /dev/null
+++ b/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/transaction/Operation.kt
@@ -0,0 +1,17 @@
+package cz.cvut.fel.pda.financemanagement.database.transaction;
+
+import androidx.room.Entity;
+import androidx.room.PrimaryKey;
+
+import java.math.BigDecimal;
+import java.time.LocalDateTime
+import java.util.Date
+
+@Entity(tableName = "operation")
+abstract class Operation {
+        @PrimaryKey(autoGenerate = true)
+        open var id: Long = 0
+        abstract var description: String
+        abstract var amount: BigDecimal
+        abstract var dateCreated: LocalDateTime
+}
\ No newline at end of file
diff --git a/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/transaction/Transaction.kt b/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/transaction/Transaction.kt
index 5486dd5..5042f03 100644
--- a/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/transaction/Transaction.kt
+++ b/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/transaction/Transaction.kt
@@ -3,14 +3,16 @@ package cz.cvut.fel.pda.financemanagement.database.transaction
 import androidx.room.Entity
 import androidx.room.PrimaryKey
 import java.math.BigDecimal
+import java.time.LocalDateTime
 
 
 @Entity(tableName = "transaction")
 data class Transaction(
     @PrimaryKey(autoGenerate = true)
-    val id: Long = 0,
-    val description: String = "",
-    val imageUrl: String = "",
-    val amount: BigDecimal = BigDecimal.ZERO,
-    val categoryId: Long,
-)
+    override var id: Long = 0,
+    override var description: String = "",
+    override var amount: BigDecimal = BigDecimal.ZERO,
+    override var dateCreated: LocalDateTime = LocalDateTime.now(),
+    var imageUrl: String = "",
+    var categoryId: Long,
+) : Operation()
diff --git a/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/typeConvertion/Converters.kt b/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/typeConvertion/Converters.kt
index 23841c0..c6ca942 100644
--- a/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/typeConvertion/Converters.kt
+++ b/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/typeConvertion/Converters.kt
@@ -2,6 +2,8 @@ package cz.cvut.fel.pda.financemanagement.database.typeConvertion
 
 import androidx.room.TypeConverter
 import java.math.BigDecimal
+import java.time.LocalDateTime
+import java.time.format.DateTimeFormatter
 
 class Converters {
     @TypeConverter
@@ -13,4 +15,14 @@ class Converters {
     fun toBigDecimal(value: String): BigDecimal {
         return BigDecimal(value)
     }
+
+    @TypeConverter
+    fun fromLocalDateTime(value: LocalDateTime): String {
+        return value.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME)
+    }
+
+    @TypeConverter
+    fun toLocalDateTime(value: String): LocalDateTime {
+        return LocalDateTime.parse(value, DateTimeFormatter.ISO_LOCAL_DATE_TIME)
+    }
 }
\ No newline at end of file
diff --git a/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/components/TopBar.kt b/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/components/TopBar.kt
index 3512327..4472df4 100644
--- a/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/components/TopBar.kt
+++ b/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/components/TopBar.kt
@@ -22,7 +22,7 @@ fun TopBar() {
         }
 
         Text(
-            text = "Money management app",
+            text = "CoinKeeper",
             style = TextStyle(fontSize = 24.sp, fontWeight = FontWeight.Bold),
             modifier = Modifier.align(Alignment.Center)
         )
diff --git a/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/transactions/EditTransactionScreen.kt b/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/transactions/EditTransactionScreen.kt
index 463bd58..1b692a3 100644
--- a/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/transactions/EditTransactionScreen.kt
+++ b/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/transactions/EditTransactionScreen.kt
@@ -76,7 +76,7 @@ fun ShowSuccessScreen(
     Scaffold(
         topBar = {
             TopAppBar(
-                title = { Text("neco") },
+                title = { Text("Transaction edit") },
                 colors = TopAppBarDefaults.mediumTopAppBarColors(
                     containerColor = MaterialTheme.colorScheme.primaryContainer
                 ),
@@ -125,8 +125,12 @@ fun EditTransactionDetailSuccessContent(innerPadding: PaddingValues, amount: Mut
             .padding(24.dp, 4.dp)
         OutlinedTextField(
             value = amount.value,
-            onValueChange = { newValue -> amount.value = newValue },
-            label = { Text("xd") },
+            onValueChange = { newValue ->
+                if (newValue.all { it.isDigit() }) {
+                    amount.value = newValue
+                }
+            },
+            label = { Text("amount") },
             modifier = spaceModifier
         )
     }
diff --git a/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/transactions/TransactionsScreen.kt b/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/transactions/TransactionsScreen.kt
index c39b30b..eb2de35 100644
--- a/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/transactions/TransactionsScreen.kt
+++ b/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/transactions/TransactionsScreen.kt
@@ -17,6 +17,8 @@ import androidx.compose.material.icons.Icons
 import androidx.compose.material.icons.filled.ArrowDropDown
 import androidx.compose.material.icons.filled.MoreVert
 import androidx.compose.material.icons.outlined.Add
+import androidx.compose.material3.DropdownMenu
+import androidx.compose.material3.DropdownMenuItem
 import androidx.compose.material3.FloatingActionButton
 import androidx.compose.material3.HorizontalDivider
 import androidx.compose.material3.Icon
@@ -25,7 +27,11 @@ import androidx.compose.material3.MaterialTheme
 import androidx.compose.material3.Scaffold
 import androidx.compose.material3.Text
 import androidx.compose.runtime.Composable
+import androidx.compose.runtime.MutableState
 import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
+import androidx.compose.runtime.setValue
 import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.graphics.Color
@@ -43,7 +49,6 @@ import cz.cvut.fel.pda.financemanagement.FinanceManagementScreens
 import cz.cvut.fel.pda.financemanagement.database.category.Category
 import cz.cvut.fel.pda.financemanagement.database.category.CategoryType
 import cz.cvut.fel.pda.financemanagement.database.transaction.Transaction
-import cz.cvut.fel.pda.financemanagement.model.CategoryWithTransaction
 import cz.cvut.fel.pda.financemanagement.model.TransactionWithCategory
 import cz.cvut.fel.pda.financemanagement.ui.components.BottomNavigation
 import cz.cvut.fel.pda.financemanagement.ui.components.ShowErrorScreen
@@ -94,26 +99,51 @@ fun TransactionScreenContent(
     navController: NavHostController,
     innerPadding: PaddingValues
 ) {
+    val sortState = remember { mutableStateOf("Don't sort") }
+    val sortedTransactions = when (sortState.value) {
+        "Sort by Amount" -> transactions.sortedBy { it.transaction.amount }
+        "Sort by Date" -> transactions.sortedBy { it.transaction.dateCreated }
+        else -> transactions
+    }
+
     Column(modifier = Modifier
         .padding(innerPadding)
         .fillMaxWidth()) {
-        TotalSumOfTransactions(transactions)
+        TotalSumOfTransactions(sortedTransactions)
         Column(modifier = Modifier.padding(horizontal = 14.dp)) {
             Row(modifier = Modifier
                 .fillMaxWidth(),
                 horizontalArrangement = Arrangement.SpaceBetween
             ){
                 Text(text = "Transactions", style = TextStyle(fontSize = 16.sp, fontWeight = FontWeight.Bold))
-                Row{
-                    Text(text = "sort")
-                    Icon(Icons.Filled.ArrowDropDown, contentDescription = "Sort options")
-                }
-
+                SortDropdown(sortState)
             }
             HorizontalDivider()
-            ShowTabListSuccessScreen(transactions, navController)
+            ShowTabListSuccessScreen(sortedTransactions, navController)
+        }
+    }
+}
+
+@Composable
+fun SortDropdown(sortState: MutableState<String>) {
+    var expanded by remember { mutableStateOf(false) }
+    val options = listOf("Don't sort", "Sort by Amount", "Sort by Date")
+
+    Box(Modifier.clickable { expanded = true }) {
+        Text(text = sortState.value)
+        Icon(Icons.Filled.ArrowDropDown, contentDescription = "Sort options")
+        DropdownMenu(expanded = expanded, onDismissRequest = { expanded = false }) {
+            options.forEach { label ->
+                DropdownMenuItem(
+                    onClick = {
+                        sortState.value = label
+                        expanded = false
+                    },
+                    text = { Text(label) }
+                )
+            }
         }
-  }
+    }
 }
 
 @Composable
-- 
GitLab


From 9dc5f01aa3cb7bd8f59226cb439cbac2a929c495 Mon Sep 17 00:00:00 2001
From: dovicrad <dovicrad@fel.cvut.cz>
Date: Thu, 25 Apr 2024 14:28:24 +0200
Subject: [PATCH 06/12] :cooking: add categories display

---
 .../financemanagement/FinanceManagementApp.kt |   2 +-
 .../database/category/CategoryRepository.kt   |   2 +-
 .../category/OfflineCategoryRepository.kt     |  13 +++
 .../OfflineTransactionRepository.kt           |   3 +
 .../database/transaction/TransactionDao.kt    |   7 ++
 .../transaction/TransactionRepository.kt      |  12 +-
 .../pda/financemanagement/di/AppContainer.kt  |   6 +
 .../ui/screens/CategoriesScreen.kt            |  33 ------
 .../ui/screens/cateegory/CategoriesScreen.kt  | 105 ++++++++++++++++++
 .../ui/screens/cateegory/CategoryViewModel.kt |  38 +++++++
 .../transactions/EditTransactionScreen.kt     |  11 +-
 .../transactions/TransactionDetailScreen.kt   |  31 ++++--
 .../TransactionDetailViewModel.kt             |  29 +++--
 .../transactions/TransactionViewModel.kt      |   3 +-
 .../ui/utils/AppViewModelProvider.kt          |   6 +
 15 files changed, 239 insertions(+), 62 deletions(-)
 create mode 100644 app/src/main/java/cz/cvut/fel/pda/financemanagement/database/category/OfflineCategoryRepository.kt
 delete mode 100644 app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/CategoriesScreen.kt
 create mode 100644 app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/cateegory/CategoriesScreen.kt
 create mode 100644 app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/cateegory/CategoryViewModel.kt

diff --git a/app/src/main/java/cz/cvut/fel/pda/financemanagement/FinanceManagementApp.kt b/app/src/main/java/cz/cvut/fel/pda/financemanagement/FinanceManagementApp.kt
index c930012..4cc1431 100644
--- a/app/src/main/java/cz/cvut/fel/pda/financemanagement/FinanceManagementApp.kt
+++ b/app/src/main/java/cz/cvut/fel/pda/financemanagement/FinanceManagementApp.kt
@@ -9,7 +9,7 @@ import androidx.navigation.compose.composable
 import androidx.navigation.compose.rememberNavController
 import androidx.navigation.navArgument
 import cz.cvut.fel.pda.financemanagement.ui.screens.AccountsScreen
-import cz.cvut.fel.pda.financemanagement.ui.screens.CategoriesScreen
+import cz.cvut.fel.pda.financemanagement.ui.screens.cateegory.CategoriesScreen
 import cz.cvut.fel.pda.financemanagement.ui.screens.LoansScreen
 import cz.cvut.fel.pda.financemanagement.ui.screens.transactions.EditTransactionScreen
 import cz.cvut.fel.pda.financemanagement.ui.screens.transactions.TransactionDetailScreen
diff --git a/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/category/CategoryRepository.kt b/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/category/CategoryRepository.kt
index cfd96e9..1e1538e 100644
--- a/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/category/CategoryRepository.kt
+++ b/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/category/CategoryRepository.kt
@@ -8,5 +8,5 @@ interface CategoryRepository {
     suspend fun insertCategories(vararg categories: Category)
     suspend fun deleteCategory(category: Category)
     suspend fun deleteAllCategories()
-    suspend fun updateCategory(vararg categories: Category)
+    suspend fun updateCategory(vararg category: Category)
 }
\ No newline at end of file
diff --git a/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/category/OfflineCategoryRepository.kt b/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/category/OfflineCategoryRepository.kt
new file mode 100644
index 0000000..0b83212
--- /dev/null
+++ b/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/category/OfflineCategoryRepository.kt
@@ -0,0 +1,13 @@
+package cz.cvut.fel.pda.financemanagement.database.category
+
+import kotlinx.coroutines.flow.Flow
+
+class OfflineCategoryRepository(private val CategoryDao: CategoryDao):
+    CategoryRepository {
+    override fun getAllCategoriesStream(): Flow<List<Category>> = CategoryDao.getAllCategories()
+    override fun getCategoryForIdStream(id: Long): Flow<Category?> = CategoryDao.getCategoryForId(id)
+    override suspend fun insertCategories(vararg categories: Category) = CategoryDao.insertCategories(*categories)
+    override suspend fun deleteCategory(category: Category) = CategoryDao.delete(category)
+    override suspend fun deleteAllCategories() = CategoryDao.deleteAll()
+    override suspend fun updateCategory(vararg category: Category) = CategoryDao.updateCategories(*category)
+}
\ No newline at end of file
diff --git a/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/transaction/OfflineTransactionRepository.kt b/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/transaction/OfflineTransactionRepository.kt
index 316a714..402b2e9 100644
--- a/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/transaction/OfflineTransactionRepository.kt
+++ b/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/transaction/OfflineTransactionRepository.kt
@@ -1,12 +1,15 @@
 package cz.cvut.fel.pda.financemanagement.database.transaction
 
 import cz.cvut.fel.pda.financemanagement.model.CategoryWithTransaction
+import cz.cvut.fel.pda.financemanagement.model.TransactionWithCategory
 import kotlinx.coroutines.flow.Flow
 
 class OfflineTransactionRepository(private val transactionDao: TransactionDao):
     TransactionRepository {
     override fun getAllTransactionsStream(): Flow<List<Transaction>> = transactionDao.getAllTransactions()
     override fun getTransactionForIdStream(id: Long): Flow<Transaction?> = transactionDao.getTransactionForId(id)
+    override fun getCategoryWithTransactionForIdStream(id: Long): Flow<CategoryWithTransaction> = transactionDao.getCategoryWithTransactionForId(id)
+
     override fun getCategoryWithTransactions(): Flow<List<CategoryWithTransaction>> = transactionDao.getCategoryWithTransaction()
 
     override suspend fun insertTransactions(vararg transactions: Transaction) = transactionDao.insertTransactions(*transactions)
diff --git a/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/transaction/TransactionDao.kt b/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/transaction/TransactionDao.kt
index 6e5b40a..ae82277 100644
--- a/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/transaction/TransactionDao.kt
+++ b/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/transaction/TransactionDao.kt
@@ -18,6 +18,13 @@ interface TransactionDao {
     @Query("SELECT * FROM `transaction` WHERE id = :id")
     fun getTransactionForId(id: Long): Flow<Transaction>
 
+    @Query("""
+    SELECT * FROM `category`
+    JOIN `transaction` ON `transaction`.categoryId = `category`.id
+    WHERE `transaction`.id = :id
+""")
+    fun getCategoryWithTransactionForId(id: Long): Flow<CategoryWithTransaction>
+
     @Query("""
     SELECT * FROM `category`
     INNER JOIN `transaction` ON `transaction`.categoryId = `category`.id
diff --git a/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/transaction/TransactionRepository.kt b/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/transaction/TransactionRepository.kt
index 52b4cbd..e900a4c 100644
--- a/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/transaction/TransactionRepository.kt
+++ b/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/transaction/TransactionRepository.kt
@@ -1,6 +1,5 @@
 package cz.cvut.fel.pda.financemanagement.database.transaction
 
-import android.util.Log
 import cz.cvut.fel.pda.financemanagement.model.CategoryWithTransaction
 import cz.cvut.fel.pda.financemanagement.model.TransactionWithCategory
 import kotlinx.coroutines.flow.Flow
@@ -9,6 +8,17 @@ import kotlinx.coroutines.flow.map
 interface TransactionRepository {
     fun getAllTransactionsStream(): Flow<List<Transaction>>
     fun getTransactionForIdStream(id: Long): Flow<Transaction?>
+    fun getTransactionWithCategoryForIdStream(id: Long): Flow<TransactionWithCategory?> {
+        return getCategoryWithTransactionForIdStream(id).map { transaction ->
+            transaction.let {
+                TransactionWithCategory(
+                    transaction = it.transaction.firstOrNull { transaction -> transaction.id == id } ?: Transaction(categoryId = 0L),
+                    category = it.category
+                )
+            }
+        }
+    }
+    fun getCategoryWithTransactionForIdStream(id: Long): Flow<CategoryWithTransaction>
 
     fun getCategoryWithTransactions(): Flow<List<CategoryWithTransaction>>
     fun getTransactionsWithCategory(): Flow<List<TransactionWithCategory>> {
diff --git a/app/src/main/java/cz/cvut/fel/pda/financemanagement/di/AppContainer.kt b/app/src/main/java/cz/cvut/fel/pda/financemanagement/di/AppContainer.kt
index fdc8ec7..7ee3744 100644
--- a/app/src/main/java/cz/cvut/fel/pda/financemanagement/di/AppContainer.kt
+++ b/app/src/main/java/cz/cvut/fel/pda/financemanagement/di/AppContainer.kt
@@ -2,15 +2,21 @@ package cz.cvut.fel.pda.financemanagement.di
 
 import android.content.Context
 import cz.cvut.fel.pda.financemanagement.database.AppDatabase
+import cz.cvut.fel.pda.financemanagement.database.category.CategoryRepository
+import cz.cvut.fel.pda.financemanagement.database.category.OfflineCategoryRepository
 import cz.cvut.fel.pda.financemanagement.database.transaction.OfflineTransactionRepository
 import cz.cvut.fel.pda.financemanagement.database.transaction.TransactionRepository
 
 interface AppContainer {
     val transactionRepository: TransactionRepository
+    val categoryRepository: CategoryRepository
 }
 
 class AppDataContainer(private val context: Context) : AppContainer {
     override val transactionRepository: TransactionRepository by lazy {
         OfflineTransactionRepository(AppDatabase.getDatabase(context).transactionDao())
     }
+    override val categoryRepository: CategoryRepository by lazy {
+        OfflineCategoryRepository(AppDatabase.getDatabase(context).categoryDao())
+    }
 }
\ No newline at end of file
diff --git a/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/CategoriesScreen.kt b/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/CategoriesScreen.kt
deleted file mode 100644
index 10fefbc..0000000
--- a/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/CategoriesScreen.kt
+++ /dev/null
@@ -1,33 +0,0 @@
-package cz.cvut.fel.pda.financemanagement.ui.screens
-
-import androidx.compose.foundation.layout.Column
-import androidx.compose.foundation.layout.PaddingValues
-import androidx.compose.foundation.layout.padding
-import androidx.compose.material3.Scaffold
-import androidx.compose.material3.Text
-import androidx.compose.runtime.Composable
-import androidx.compose.ui.Modifier
-import androidx.navigation.NavHostController
-import cz.cvut.fel.pda.financemanagement.ui.components.BottomNavigation
-import cz.cvut.fel.pda.financemanagement.ui.components.TopBar
-
-@Composable
-fun CategoriesScreen(navController: NavHostController){
-    Scaffold(
-        topBar = {
-            TopBar()
-        },
-        bottomBar = {
-            BottomNavigation(navController = navController)
-        }
-    ) {
-            innerPadding -> LoansScreenContent(innerPadding)
-    }
-}
-
-@Composable
-fun LoansScreenContent(innerPadding: PaddingValues) {
-    Column(modifier = Modifier.padding(innerPadding)) {
-        Text(text = "Categories")
-    }
-}
diff --git a/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/cateegory/CategoriesScreen.kt b/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/cateegory/CategoriesScreen.kt
new file mode 100644
index 0000000..fc7a6c1
--- /dev/null
+++ b/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/cateegory/CategoriesScreen.kt
@@ -0,0 +1,105 @@
+package cz.cvut.fel.pda.financemanagement.ui.screens.cateegory
+
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.PaddingValues
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.lazy.LazyColumn
+import androidx.compose.material.icons.Icons
+import androidx.compose.material.icons.filled.Add
+import androidx.compose.material3.FloatingActionButton
+import androidx.compose.material3.Icon
+import androidx.compose.material3.Scaffold
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.getValue
+import androidx.compose.ui.Modifier
+import androidx.lifecycle.compose.collectAsStateWithLifecycle
+import androidx.lifecycle.viewmodel.compose.viewModel
+import androidx.navigation.NavHostController
+import cz.cvut.fel.pda.financemanagement.database.category.Category
+import cz.cvut.fel.pda.financemanagement.database.category.CategoryType
+import cz.cvut.fel.pda.financemanagement.ui.components.BottomNavigation
+import cz.cvut.fel.pda.financemanagement.ui.components.ShowErrorScreen
+import cz.cvut.fel.pda.financemanagement.ui.components.ShowLoadingScreen
+import cz.cvut.fel.pda.financemanagement.ui.components.TopBar
+import cz.cvut.fel.pda.financemanagement.ui.utils.AppViewModelProvider
+import androidx.compose.foundation.lazy.items
+import androidx.compose.material3.HorizontalDivider
+import androidx.compose.ui.text.TextStyle
+import androidx.compose.ui.text.font.FontWeight
+import androidx.compose.ui.unit.dp
+import androidx.compose.ui.unit.sp
+import java.util.Locale
+
+@Composable
+fun CategoriesScreen(
+    navController: NavHostController,
+    categoryViewModel: CategoryViewModel = viewModel(
+        factory = AppViewModelProvider.Factory
+    )
+){
+    val categoriesUiState: CategoriesUiState by categoryViewModel.categories.collectAsStateWithLifecycle()
+
+    Scaffold(
+        topBar = {
+            TopBar()
+        },
+        content = {
+                innerPadding ->
+            when (categoriesUiState) {
+                is CategoriesUiState.Loading -> {
+                    ShowLoadingScreen()
+                }
+                is CategoriesUiState.Error -> {
+                    ShowErrorScreen(
+                        errorMessage = (categoriesUiState as CategoriesUiState.Error).exception.message ?: "Error",
+                    )
+                }
+                is CategoriesUiState.Success -> {
+                    CategoriesScreenContent((categoriesUiState as CategoriesUiState.Success).itemList,navController, innerPadding)
+                }
+            }
+        },
+        floatingActionButton = {
+             FloatingActionButton(onClick = {  }) {
+                Icon(Icons.Default.Add, contentDescription = "Add")
+             }
+
+        },
+        bottomBar = {
+            BottomNavigation(navController = navController)
+        }
+    )
+}
+
+@Composable
+fun CategoriesScreenContent(categories: List<Category>, navController: NavHostController, innerPadding: PaddingValues) {
+    val expenseCategories = categories.filter { it.type == CategoryType.EXPENSE }
+    val incomeCategories = categories.filter { it.type == CategoryType.INCOME }
+
+    Column(modifier = Modifier.padding(innerPadding).padding(horizontal = 14.dp)) {
+        Text(text = "Expense Categories:", style = TextStyle(fontSize = 16.sp, fontWeight = FontWeight.Bold))
+        HorizontalDivider()
+        CategoriesList(expenseCategories)
+        Text(text = "Income Categories:", style = TextStyle(fontSize = 16.sp, fontWeight = FontWeight.Bold))
+        HorizontalDivider()
+        CategoriesList(incomeCategories)
+    }
+}
+
+@Composable
+fun CategoriesList(categories: List<Category>) {
+    LazyColumn {
+        items(categories) { category ->
+            CategoryItem(category)
+        }
+    }
+}
+
+@Composable
+fun CategoryItem(category: Category) {
+    Row {
+        Text(text = category.name.toString().lowercase().replaceFirstChar { it.titlecase(Locale.ROOT)})
+    }
+}
diff --git a/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/cateegory/CategoryViewModel.kt b/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/cateegory/CategoryViewModel.kt
new file mode 100644
index 0000000..4777dfb
--- /dev/null
+++ b/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/cateegory/CategoryViewModel.kt
@@ -0,0 +1,38 @@
+package cz.cvut.fel.pda.financemanagement.ui.screens.cateegory
+
+import androidx.lifecycle.ViewModel
+import androidx.lifecycle.viewModelScope
+import cz.cvut.fel.pda.financemanagement.database.category.Category
+import cz.cvut.fel.pda.financemanagement.database.category.CategoryRepository
+import cz.cvut.fel.pda.financemanagement.model.common.Result
+import cz.cvut.fel.pda.financemanagement.model.common.asResult
+import kotlinx.coroutines.flow.SharingStarted
+import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.stateIn
+
+class CategoryViewModel(
+    categoryRepository: CategoryRepository,
+) : ViewModel(){
+    val categories : StateFlow<CategoriesUiState> =
+        categoryRepository
+            .getAllCategoriesStream()
+            .asResult()
+            .map { allCategoriesToResult ->
+                when ( allCategoriesToResult) {
+                    is Result.Error -> CategoriesUiState.Error(Exception( allCategoriesToResult.exception))
+                    is Result.Loading -> CategoriesUiState.Loading
+                    is Result.Success -> CategoriesUiState.Success( allCategoriesToResult.data)
+                }
+            }.stateIn(
+                scope = viewModelScope,
+                started = SharingStarted.WhileSubscribed(5000L),
+                initialValue = CategoriesUiState.Loading
+            )
+}
+
+sealed interface CategoriesUiState {
+    data object Loading : CategoriesUiState
+    data class Success(val itemList: List<Category> = listOf()) : CategoriesUiState
+    data class Error(val exception: Exception) : CategoriesUiState
+}
\ No newline at end of file
diff --git a/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/transactions/EditTransactionScreen.kt b/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/transactions/EditTransactionScreen.kt
index 1b692a3..5ea69ae 100644
--- a/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/transactions/EditTransactionScreen.kt
+++ b/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/transactions/EditTransactionScreen.kt
@@ -31,6 +31,7 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle
 import androidx.lifecycle.viewmodel.compose.viewModel
 import androidx.navigation.NavHostController
 import cz.cvut.fel.pda.financemanagement.database.transaction.Transaction
+import cz.cvut.fel.pda.financemanagement.model.TransactionWithCategory
 import cz.cvut.fel.pda.financemanagement.ui.components.ShowErrorScreen
 import cz.cvut.fel.pda.financemanagement.ui.components.ShowLoadingScreen
 import cz.cvut.fel.pda.financemanagement.ui.utils.AppViewModelProvider
@@ -45,16 +46,16 @@ fun EditTransactionScreen(navController: NavHostController,
     val uiState by transitionDetailViewModel.uiState.collectAsStateWithLifecycle()
 
     when (val state = uiState) {
-        is TransactionUiState.Error -> {
+        is TransactionWithCategoryUiState.Error -> {
             ShowErrorScreen(
                 errorMessage = state.exception.message ?: "Error",
                 onClick = { navController.popBackStack() }
             )
         }
-        TransactionUiState.Loading -> {
+        TransactionWithCategoryUiState.Loading -> {
             ShowLoadingScreen()
         }
-        is TransactionUiState.Success -> {
+        is TransactionWithCategoryUiState.Success -> {
             ShowSuccessScreen(
                 state.transaction,
                 navController,
@@ -67,11 +68,11 @@ fun EditTransactionScreen(navController: NavHostController,
 @OptIn(ExperimentalMaterial3Api::class)
 @Composable
 fun ShowSuccessScreen(
-    transaction: Transaction,
+    transaction: TransactionWithCategory,
     navController: NavHostController,
     transactionViewModel: TransactionDetailViewModel
 ) {
-    val amount = rememberSaveable { mutableStateOf(transaction.amount.toString()) }
+    val amount = rememberSaveable { mutableStateOf(transaction.transaction.amount.toString()) }
 
     Scaffold(
         topBar = {
diff --git a/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/transactions/TransactionDetailScreen.kt b/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/transactions/TransactionDetailScreen.kt
index ef838f4..2ed972e 100644
--- a/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/transactions/TransactionDetailScreen.kt
+++ b/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/transactions/TransactionDetailScreen.kt
@@ -18,6 +18,7 @@ import androidx.lifecycle.viewmodel.CreationExtras
 import androidx.lifecycle.viewmodel.compose.viewModel
 import androidx.navigation.NavHostController
 import cz.cvut.fel.pda.financemanagement.database.transaction.Transaction
+import cz.cvut.fel.pda.financemanagement.model.TransactionWithCategory
 import cz.cvut.fel.pda.financemanagement.ui.components.BottomNavigation
 import cz.cvut.fel.pda.financemanagement.ui.components.ShowErrorScreen
 import cz.cvut.fel.pda.financemanagement.ui.components.ShowLoadingScreen
@@ -34,23 +35,23 @@ fun TransactionDetailScreen(
     )
 ){
     transactionViewModel.setTransactionId(transactionId ?: 0L)
-    val transactionUiState: TransactionUiState by transactionViewModel.uiState.collectAsStateWithLifecycle()
+    val transactionUiState: TransactionWithCategoryUiState by transactionViewModel.uiState.collectAsStateWithLifecycle()
 
     Scaffold (
         topBar = {TopBar()},
         content = {
             innerPadding ->
             when (transactionUiState) {
-                is TransactionUiState.Loading -> {
+                is TransactionWithCategoryUiState.Loading -> {
                     ShowLoadingScreen()
                 }
-                is TransactionUiState.Error -> {
+                is TransactionWithCategoryUiState.Error -> {
                     ShowErrorScreen(
-                        errorMessage = (transactionUiState as TransactionUiState.Error).exception.message ?: "Error",
+                        errorMessage = (transactionUiState as TransactionWithCategoryUiState.Error).exception.message ?: "Error",
                     )
                 }
-                is TransactionUiState.Success -> {
-                    TransactionScreenContent( (transactionUiState as TransactionUiState.Success).transaction, innerPadding, navController)
+                is TransactionWithCategoryUiState.Success -> {
+                    TransactionScreenContent( (transactionUiState as TransactionWithCategoryUiState.Success).transaction, innerPadding, navController)
                 }
             }
         },
@@ -61,17 +62,29 @@ fun TransactionDetailScreen(
 }
 
 @Composable
-fun TransactionScreenContent(transaction: Transaction, innerPadding: PaddingValues, navController: NavHostController) {
+fun TransactionScreenContent(transaction: TransactionWithCategory, innerPadding: PaddingValues, navController: NavHostController) {
     Column(modifier = Modifier.padding(innerPadding)) {
         Text(text = "Transaction Details")
         Spacer(modifier = Modifier.height(16.dp))
         Row {
             Text(text = "ID: ")
-            Text(text = transaction.id.toString())
+            Text(text = transaction.transaction.id.toString())
+        }
+        Row {
+            Text(text = "Created: ")
+            Text(text = transaction.transaction.dateCreated.toString())
         }
         Row {
             Text(text = "Amount: ")
-            Text(text = transaction.amount.toString())
+            Text(text = transaction.transaction.amount.toString())
+        }
+        Row {
+            Text(text = "Category name: ")
+            Text(text = transaction.category.name.toString())
+        }
+        Row {
+            Text(text = "Category type: ")
+            Text(text = transaction.category.type.toString())
         }
         // Add more fields as needed
     }
diff --git a/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/transactions/TransactionDetailViewModel.kt b/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/transactions/TransactionDetailViewModel.kt
index ce6080c..a9eceea 100644
--- a/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/transactions/TransactionDetailViewModel.kt
+++ b/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/transactions/TransactionDetailViewModel.kt
@@ -3,8 +3,12 @@ package cz.cvut.fel.pda.financemanagement.ui.screens.transactions
 import androidx.lifecycle.SavedStateHandle
 import androidx.lifecycle.ViewModel
 import androidx.lifecycle.viewModelScope
+import cz.cvut.fel.pda.financemanagement.database.category.Category
+import cz.cvut.fel.pda.financemanagement.database.category.CategoryName
+import cz.cvut.fel.pda.financemanagement.database.category.CategoryType
 import cz.cvut.fel.pda.financemanagement.database.transaction.Transaction
 import cz.cvut.fel.pda.financemanagement.database.transaction.TransactionRepository
+import cz.cvut.fel.pda.financemanagement.model.TransactionWithCategory
 import kotlinx.coroutines.flow.SharingStarted
 import kotlinx.coroutines.flow.StateFlow
 import kotlinx.coroutines.flow.map
@@ -18,21 +22,26 @@ class TransactionDetailViewModel(
 ): ViewModel() {
     private var transactionId: Long = savedStateHandle.get<Long>("Id")!!
 
-    val uiState: StateFlow<TransactionUiState> =
+    val uiState: StateFlow<TransactionWithCategoryUiState> =
         transactionRepository
-            .getTransactionForIdStream(transactionId)
+            .getTransactionWithCategoryForIdStream(transactionId)
             .map {
                 if (it != null) {
-                    TransactionUiState.Success(it)
+                    TransactionWithCategoryUiState.Success(it)
                 } else if (transactionId == 0L) {
-                    TransactionUiState.Success(Transaction(categoryId = 0L))
+                    TransactionWithCategoryUiState.Success(
+                        TransactionWithCategory(
+                        transaction = Transaction(categoryId = 0L),
+                        category = Category(0, CategoryName.GROCERIES,CategoryType.INCOME)
+                    )
+                    )
                 } else {
-                    TransactionUiState.Error(Exception("Transaction not found"))
+                    TransactionWithCategoryUiState.Error(Exception("Transaction not found"))
                 }
             }.stateIn(
                 scope = viewModelScope,
                 started = SharingStarted.WhileSubscribed(5000L),
-                initialValue = TransactionUiState.Loading
+                initialValue = TransactionWithCategoryUiState.Loading
             )
     fun setTransactionId(id: Long) {
         transactionId = id
@@ -52,8 +61,8 @@ class TransactionDetailViewModel(
     }
 }
 
-sealed interface TransactionUiState {
-    data object Loading : TransactionUiState
-    data class Success(val transaction: Transaction) : TransactionUiState
-    data class Error(val exception: Exception) : TransactionUiState
+sealed interface TransactionWithCategoryUiState {
+    data object Loading : TransactionWithCategoryUiState
+    data class Success(val transaction: TransactionWithCategory) : TransactionWithCategoryUiState
+    data class Error(val exception: Exception) : TransactionWithCategoryUiState
 }
\ No newline at end of file
diff --git a/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/transactions/TransactionViewModel.kt b/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/transactions/TransactionViewModel.kt
index 0851eaa..b90f770 100644
--- a/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/transactions/TransactionViewModel.kt
+++ b/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/transactions/TransactionViewModel.kt
@@ -3,7 +3,6 @@ package cz.cvut.fel.pda.financemanagement.ui.screens.transactions
 import androidx.lifecycle.ViewModel
 import androidx.lifecycle.viewModelScope
 import cz.cvut.fel.pda.financemanagement.database.transaction.TransactionRepository
-import cz.cvut.fel.pda.financemanagement.model.CategoryWithTransaction
 import cz.cvut.fel.pda.financemanagement.model.TransactionWithCategory
 import cz.cvut.fel.pda.financemanagement.model.common.Result
 import cz.cvut.fel.pda.financemanagement.model.common.asResult
@@ -13,7 +12,7 @@ import kotlinx.coroutines.flow.map
 import kotlinx.coroutines.flow.stateIn
 
 class TransactionViewModel(
-    private val transactionRepository: TransactionRepository,
+    transactionRepository: TransactionRepository,
 ) : ViewModel(){
     val transactionsWithCategory : StateFlow<TransactionsWithCategoryUiState> =
         transactionRepository
diff --git a/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/utils/AppViewModelProvider.kt b/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/utils/AppViewModelProvider.kt
index 696af66..f854683 100644
--- a/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/utils/AppViewModelProvider.kt
+++ b/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/utils/AppViewModelProvider.kt
@@ -6,6 +6,7 @@ import androidx.lifecycle.viewmodel.CreationExtras
 import androidx.lifecycle.viewmodel.initializer
 import androidx.lifecycle.viewmodel.viewModelFactory
 import cz.cvut.fel.pda.financemanagement.FinanceManagementApplication
+import cz.cvut.fel.pda.financemanagement.ui.screens.cateegory.CategoryViewModel
 import cz.cvut.fel.pda.financemanagement.ui.screens.transactions.TransactionDetailViewModel
 import cz.cvut.fel.pda.financemanagement.ui.screens.transactions.TransactionViewModel
 
@@ -22,6 +23,11 @@ object AppViewModelProvider {
                 this.createSavedStateHandle()
             )
         }
+        initializer {
+            CategoryViewModel(
+                financemanagementApplication().container.categoryRepository,
+            )
+        }
     }
 }
 
-- 
GitLab


From c9256fc28fb4c699c22e4528dbfea437e462a935 Mon Sep 17 00:00:00 2001
From: dovicrad <dovicrad@fel.cvut.cz>
Date: Mon, 29 Apr 2024 18:02:19 +0200
Subject: [PATCH 07/12] :cooking: FIX TRANSACTION WITH CATEGORY (hopefully)
 !!!!

---
 .../financemanagement/FinanceManagementApp.kt | 12 +++-
 .../OfflineTransactionRepository.kt           |  2 +-
 .../database/transaction/TransactionDao.kt    |  3 +-
 .../transaction/TransactionRepository.kt      | 12 +---
 .../model/TransactionWithCategory.kt          |  8 ++-
 .../ui/components/SideSheet.kt                | 14 ++++
 .../financemanagement/ui/components/TopBar.kt |  8 ++-
 .../ui/screens/AccountsScreen.kt              |  2 +-
 .../ui/screens/LoansScreen.kt                 |  2 +-
 .../ui/screens/cateegory/CategoriesScreen.kt  |  6 +-
 .../cateegory/CategoryDetailViewModel.kt      | 66 +++++++++++++++++++
 .../screens/cateegory/EditCategoryScreen.kt   | 52 +++++++++++++++
 .../transactions/TransactionDetailScreen.kt   |  2 +-
 .../transactions/TransactionsScreen.kt        |  2 +-
 .../ui/utils/AppViewModelProvider.kt          |  7 ++
 15 files changed, 175 insertions(+), 23 deletions(-)
 create mode 100644 app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/components/SideSheet.kt
 create mode 100644 app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/cateegory/CategoryDetailViewModel.kt
 create mode 100644 app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/cateegory/EditCategoryScreen.kt

diff --git a/app/src/main/java/cz/cvut/fel/pda/financemanagement/FinanceManagementApp.kt b/app/src/main/java/cz/cvut/fel/pda/financemanagement/FinanceManagementApp.kt
index 4cc1431..d7c98c5 100644
--- a/app/src/main/java/cz/cvut/fel/pda/financemanagement/FinanceManagementApp.kt
+++ b/app/src/main/java/cz/cvut/fel/pda/financemanagement/FinanceManagementApp.kt
@@ -11,6 +11,7 @@ import androidx.navigation.navArgument
 import cz.cvut.fel.pda.financemanagement.ui.screens.AccountsScreen
 import cz.cvut.fel.pda.financemanagement.ui.screens.cateegory.CategoriesScreen
 import cz.cvut.fel.pda.financemanagement.ui.screens.LoansScreen
+import cz.cvut.fel.pda.financemanagement.ui.screens.cateegory.EditCategoryScreen
 import cz.cvut.fel.pda.financemanagement.ui.screens.transactions.EditTransactionScreen
 import cz.cvut.fel.pda.financemanagement.ui.screens.transactions.TransactionDetailScreen
 import cz.cvut.fel.pda.financemanagement.ui.screens.transactions.TransactionsScreen
@@ -20,8 +21,11 @@ enum class FinanceManagementScreens() {
     Transactions,
     TransactionsDetail,
     EditTransaction,
-    Accounts,
+
     Categories,
+    EditCategory,
+
+    Accounts,
     Loans
 }
 
@@ -59,5 +63,11 @@ fun FinanceManagementApp() {
                 transactionId = it.arguments?.getLong("Id")
             )
         }
+        composable(route = "${FinanceManagementScreens.EditCategory.name}/{Id}",
+            arguments = listOf(navArgument("Id") { type = NavType.LongType })){
+            EditCategoryScreen(navController,
+                it.arguments?.getLong("Id")
+            )
+        }
     }
 }
\ No newline at end of file
diff --git a/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/transaction/OfflineTransactionRepository.kt b/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/transaction/OfflineTransactionRepository.kt
index 402b2e9..d1be722 100644
--- a/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/transaction/OfflineTransactionRepository.kt
+++ b/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/transaction/OfflineTransactionRepository.kt
@@ -8,7 +8,7 @@ class OfflineTransactionRepository(private val transactionDao: TransactionDao):
     TransactionRepository {
     override fun getAllTransactionsStream(): Flow<List<Transaction>> = transactionDao.getAllTransactions()
     override fun getTransactionForIdStream(id: Long): Flow<Transaction?> = transactionDao.getTransactionForId(id)
-    override fun getCategoryWithTransactionForIdStream(id: Long): Flow<CategoryWithTransaction> = transactionDao.getCategoryWithTransactionForId(id)
+    override fun getTransactionWithCategoryForIdStream(id: Long): Flow<TransactionWithCategory> = transactionDao.getCategoryWithTransactionForId(id)
 
     override fun getCategoryWithTransactions(): Flow<List<CategoryWithTransaction>> = transactionDao.getCategoryWithTransaction()
 
diff --git a/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/transaction/TransactionDao.kt b/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/transaction/TransactionDao.kt
index ae82277..3755614 100644
--- a/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/transaction/TransactionDao.kt
+++ b/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/transaction/TransactionDao.kt
@@ -7,6 +7,7 @@ import androidx.room.OnConflictStrategy
 import androidx.room.Query
 import androidx.room.Update
 import cz.cvut.fel.pda.financemanagement.model.CategoryWithTransaction
+import cz.cvut.fel.pda.financemanagement.model.TransactionWithCategory
 import kotlinx.coroutines.flow.Flow
 
 @Dao
@@ -23,7 +24,7 @@ interface TransactionDao {
     JOIN `transaction` ON `transaction`.categoryId = `category`.id
     WHERE `transaction`.id = :id
 """)
-    fun getCategoryWithTransactionForId(id: Long): Flow<CategoryWithTransaction>
+    fun getCategoryWithTransactionForId(id: Long): Flow<TransactionWithCategory>
 
     @Query("""
     SELECT * FROM `category`
diff --git a/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/transaction/TransactionRepository.kt b/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/transaction/TransactionRepository.kt
index e900a4c..60d929f 100644
--- a/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/transaction/TransactionRepository.kt
+++ b/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/transaction/TransactionRepository.kt
@@ -8,17 +8,7 @@ import kotlinx.coroutines.flow.map
 interface TransactionRepository {
     fun getAllTransactionsStream(): Flow<List<Transaction>>
     fun getTransactionForIdStream(id: Long): Flow<Transaction?>
-    fun getTransactionWithCategoryForIdStream(id: Long): Flow<TransactionWithCategory?> {
-        return getCategoryWithTransactionForIdStream(id).map { transaction ->
-            transaction.let {
-                TransactionWithCategory(
-                    transaction = it.transaction.firstOrNull { transaction -> transaction.id == id } ?: Transaction(categoryId = 0L),
-                    category = it.category
-                )
-            }
-        }
-    }
-    fun getCategoryWithTransactionForIdStream(id: Long): Flow<CategoryWithTransaction>
+    fun getTransactionWithCategoryForIdStream(id: Long): Flow<TransactionWithCategory>
 
     fun getCategoryWithTransactions(): Flow<List<CategoryWithTransaction>>
     fun getTransactionsWithCategory(): Flow<List<TransactionWithCategory>> {
diff --git a/app/src/main/java/cz/cvut/fel/pda/financemanagement/model/TransactionWithCategory.kt b/app/src/main/java/cz/cvut/fel/pda/financemanagement/model/TransactionWithCategory.kt
index 0e4a422..661daa9 100644
--- a/app/src/main/java/cz/cvut/fel/pda/financemanagement/model/TransactionWithCategory.kt
+++ b/app/src/main/java/cz/cvut/fel/pda/financemanagement/model/TransactionWithCategory.kt
@@ -1,9 +1,15 @@
 package cz.cvut.fel.pda.financemanagement.model
 
+import androidx.room.Embedded
+import androidx.room.Relation
 import cz.cvut.fel.pda.financemanagement.database.category.Category
 import cz.cvut.fel.pda.financemanagement.database.transaction.Transaction
 
 data class TransactionWithCategory(
-    val transaction: Transaction,
+    @Embedded val transaction: Transaction,
+    @Relation(
+        parentColumn = "categoryId",
+        entityColumn = "id"
+    )
     val category: Category,
 )
\ No newline at end of file
diff --git a/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/components/SideSheet.kt b/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/components/SideSheet.kt
new file mode 100644
index 0000000..8c553b1
--- /dev/null
+++ b/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/components/SideSheet.kt
@@ -0,0 +1,14 @@
+package cz.cvut.fel.pda.financemanagement.ui.components
+
+import androidx.compose.foundation.layout.Column
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+
+@Composable
+fun SideSheet() {
+    Column {
+        Text("Preferences")
+        Text("Notifications")
+        Text("Documentation")
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/components/TopBar.kt b/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/components/TopBar.kt
index 4472df4..05a9f80 100644
--- a/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/components/TopBar.kt
+++ b/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/components/TopBar.kt
@@ -4,18 +4,24 @@ import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.fillMaxWidth
 import androidx.compose.material.icons.Icons
 import androidx.compose.material.icons.filled.Menu
+import androidx.compose.material3.DrawerValue
 import androidx.compose.material3.Icon
 import androidx.compose.material3.IconButton
+import androidx.compose.material3.ModalNavigationDrawer
 import androidx.compose.material3.Text
+import androidx.compose.material3.rememberDrawerState
 import androidx.compose.runtime.Composable
+import androidx.compose.runtime.rememberCoroutineScope
 import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.text.TextStyle
 import androidx.compose.ui.text.font.FontWeight
 import androidx.compose.ui.unit.sp
+import androidx.navigation.NavHostController
+import kotlinx.coroutines.launch
 
 @Composable
-fun TopBar() {
+fun TopBar(navHostController: NavHostController) {
     Box(modifier = Modifier.fillMaxWidth()) {
         IconButton(onClick = { /* Handle navigation drawer opening here */ }) {
             Icon(Icons.Filled.Menu, contentDescription = "Menu")
diff --git a/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/AccountsScreen.kt b/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/AccountsScreen.kt
index f9b9d5c..e50e0dd 100644
--- a/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/AccountsScreen.kt
+++ b/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/AccountsScreen.kt
@@ -15,7 +15,7 @@ import cz.cvut.fel.pda.financemanagement.ui.components.TopBar
 fun AccountsScreen(navController: NavHostController){
     Scaffold(
         topBar = {
-            TopBar()
+            TopBar(navController)
         },
         bottomBar = {
             BottomNavigation(navController = navController)
diff --git a/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/LoansScreen.kt b/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/LoansScreen.kt
index 505b26c..926f5f9 100644
--- a/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/LoansScreen.kt
+++ b/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/LoansScreen.kt
@@ -15,7 +15,7 @@ import cz.cvut.fel.pda.financemanagement.ui.components.TopBar
 fun LoansScreen(navController: NavHostController){
     Scaffold(
         topBar = {
-            TopBar()
+            TopBar(navController)
         },
         bottomBar = {
             BottomNavigation(navController = navController)
diff --git a/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/cateegory/CategoriesScreen.kt b/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/cateegory/CategoriesScreen.kt
index fc7a6c1..7be1f9c 100644
--- a/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/cateegory/CategoriesScreen.kt
+++ b/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/cateegory/CategoriesScreen.kt
@@ -30,6 +30,7 @@ import androidx.compose.ui.text.TextStyle
 import androidx.compose.ui.text.font.FontWeight
 import androidx.compose.ui.unit.dp
 import androidx.compose.ui.unit.sp
+import cz.cvut.fel.pda.financemanagement.FinanceManagementScreens
 import java.util.Locale
 
 @Composable
@@ -43,7 +44,7 @@ fun CategoriesScreen(
 
     Scaffold(
         topBar = {
-            TopBar()
+            TopBar(navController)
         },
         content = {
                 innerPadding ->
@@ -62,10 +63,9 @@ fun CategoriesScreen(
             }
         },
         floatingActionButton = {
-             FloatingActionButton(onClick = {  }) {
+             FloatingActionButton(onClick = {navController.navigate("${FinanceManagementScreens.EditCategory.name}/0    ")}) {
                 Icon(Icons.Default.Add, contentDescription = "Add")
              }
-
         },
         bottomBar = {
             BottomNavigation(navController = navController)
diff --git a/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/cateegory/CategoryDetailViewModel.kt b/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/cateegory/CategoryDetailViewModel.kt
new file mode 100644
index 0000000..1aa0979
--- /dev/null
+++ b/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/cateegory/CategoryDetailViewModel.kt
@@ -0,0 +1,66 @@
+package cz.cvut.fel.pda.financemanagement.ui.screens.cateegory
+
+import androidx.lifecycle.SavedStateHandle
+import androidx.lifecycle.ViewModel
+import androidx.lifecycle.viewModelScope
+import cz.cvut.fel.pda.financemanagement.database.category.Category
+import cz.cvut.fel.pda.financemanagement.database.category.CategoryName
+import cz.cvut.fel.pda.financemanagement.database.category.CategoryType
+import cz.cvut.fel.pda.financemanagement.database.category.CategoryRepository
+import kotlinx.coroutines.flow.SharingStarted
+import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.stateIn
+import kotlinx.coroutines.launch
+class CategoryDetailViewModel(
+    private val categoryRepository: CategoryRepository,
+    savedStateHandle: SavedStateHandle
+): ViewModel() {
+    private var categoryId: Long = savedStateHandle.get<Long>("Id")!!
+
+    val uiState: StateFlow<CategoryDetailUiState> =
+        categoryRepository
+            .getCategoryForIdStream(categoryId)
+            .map {
+                if (it != null) {
+                    CategoryDetailUiState.Success(it)
+                } else if (categoryId == 0L) {
+                    CategoryDetailUiState.Success(
+                        Category(
+                            id = 0,
+                            name = CategoryName.GROCERIES,
+                            type = CategoryType.EXPENSE
+                    )
+                    )
+                } else {
+                    CategoryDetailUiState.Error(Exception("Category not found"))
+                }
+            }.stateIn(
+                scope = viewModelScope,
+                started = SharingStarted.WhileSubscribed(5000L),
+                initialValue = CategoryDetailUiState.Loading
+            )
+    fun setCategoryId(id: Long) {
+        categoryId = id
+    }
+    fun saveCategory(
+       type: CategoryType,
+       name: CategoryName,
+    ) {
+        viewModelScope.launch {
+            categoryRepository.insertCategories(
+                Category(
+                    id = categoryId,
+                    type = type,
+                    name = name
+                )
+            )
+        }
+    }
+}
+
+sealed interface CategoryDetailUiState {
+    data object Loading : CategoryDetailUiState
+    data class Success(val category: Category) : CategoryDetailUiState
+    data class Error(val exception: Exception) : CategoryDetailUiState
+}
\ No newline at end of file
diff --git a/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/cateegory/EditCategoryScreen.kt b/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/cateegory/EditCategoryScreen.kt
new file mode 100644
index 0000000..244583d
--- /dev/null
+++ b/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/cateegory/EditCategoryScreen.kt
@@ -0,0 +1,52 @@
+package cz.cvut.fel.pda.financemanagement.ui.screens.cateegory
+
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.getValue
+import androidx.lifecycle.compose.collectAsStateWithLifecycle
+import androidx.lifecycle.viewmodel.compose.viewModel
+import androidx.navigation.NavHostController
+import cz.cvut.fel.pda.financemanagement.database.category.Category
+import cz.cvut.fel.pda.financemanagement.ui.components.ShowErrorScreen
+import cz.cvut.fel.pda.financemanagement.ui.components.ShowLoadingScreen
+import cz.cvut.fel.pda.financemanagement.ui.screens.transactions.ShowSuccessScreen
+import cz.cvut.fel.pda.financemanagement.ui.screens.transactions.TransactionDetailViewModel
+import cz.cvut.fel.pda.financemanagement.ui.screens.transactions.TransactionWithCategoryUiState
+import cz.cvut.fel.pda.financemanagement.ui.utils.AppViewModelProvider
+
+@Composable
+fun EditCategoryScreen(navController: NavHostController,
+                          categoryId: Long?,
+                          categoryDetailViewModel: CategoryDetailViewModel = viewModel(
+                              factory = AppViewModelProvider.Factory
+                          ),){
+    val uiState by categoryDetailViewModel.uiState.collectAsStateWithLifecycle()
+
+    when (val state = uiState) {
+        is CategoryDetailUiState.Error -> {
+            ShowErrorScreen(
+                errorMessage = state.exception.message ?: "Error",
+                onClick = { navController.popBackStack() }
+            )
+        }
+        CategoryDetailUiState.Loading -> {
+            ShowLoadingScreen()
+        }
+        is CategoryDetailUiState.Success -> {
+            ShowCategorySuccessScreen(
+                state.category,
+                navController,
+                categoryDetailViewModel
+            )
+        }
+    }
+}
+
+@Composable
+fun ShowCategorySuccessScreen(
+    category: Category,
+    navController: NavHostController,
+    categoryDetailViewModel: CategoryDetailViewModel
+) {
+    Text(text="Success Screen")
+}
diff --git a/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/transactions/TransactionDetailScreen.kt b/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/transactions/TransactionDetailScreen.kt
index 2ed972e..9cb3fa9 100644
--- a/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/transactions/TransactionDetailScreen.kt
+++ b/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/transactions/TransactionDetailScreen.kt
@@ -38,7 +38,7 @@ fun TransactionDetailScreen(
     val transactionUiState: TransactionWithCategoryUiState by transactionViewModel.uiState.collectAsStateWithLifecycle()
 
     Scaffold (
-        topBar = {TopBar()},
+        topBar = {TopBar(navController)},
         content = {
             innerPadding ->
             when (transactionUiState) {
diff --git a/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/transactions/TransactionsScreen.kt b/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/transactions/TransactionsScreen.kt
index eb2de35..921f714 100644
--- a/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/transactions/TransactionsScreen.kt
+++ b/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/transactions/TransactionsScreen.kt
@@ -68,7 +68,7 @@ fun TransactionsScreen(
 ) {
     val transactionsUiState: TransactionsWithCategoryUiState by transactionViewModel.transactionsWithCategory.collectAsStateWithLifecycle()
     Scaffold(
-        topBar = { TopBar() },
+        topBar = { TopBar(navController) },
         content = { innerPadding ->
             when (transactionsUiState) {
                 is TransactionsWithCategoryUiState.Loading -> {
diff --git a/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/utils/AppViewModelProvider.kt b/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/utils/AppViewModelProvider.kt
index f854683..9480208 100644
--- a/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/utils/AppViewModelProvider.kt
+++ b/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/utils/AppViewModelProvider.kt
@@ -6,6 +6,7 @@ import androidx.lifecycle.viewmodel.CreationExtras
 import androidx.lifecycle.viewmodel.initializer
 import androidx.lifecycle.viewmodel.viewModelFactory
 import cz.cvut.fel.pda.financemanagement.FinanceManagementApplication
+import cz.cvut.fel.pda.financemanagement.ui.screens.cateegory.CategoryDetailViewModel
 import cz.cvut.fel.pda.financemanagement.ui.screens.cateegory.CategoryViewModel
 import cz.cvut.fel.pda.financemanagement.ui.screens.transactions.TransactionDetailViewModel
 import cz.cvut.fel.pda.financemanagement.ui.screens.transactions.TransactionViewModel
@@ -28,6 +29,12 @@ object AppViewModelProvider {
                 financemanagementApplication().container.categoryRepository,
             )
         }
+        initializer {
+            CategoryDetailViewModel(
+                financemanagementApplication().container.categoryRepository,
+                this.createSavedStateHandle()
+            )
+        }
     }
 }
 
-- 
GitLab


From 24ffd1d64ad2ce6ee4c8e6f070d4e044281f9247 Mon Sep 17 00:00:00 2001
From: dovicrad <dovicrad@fel.cvut.cz>
Date: Mon, 29 Apr 2024 18:13:50 +0200
Subject: [PATCH 08/12] :cooking: add transaction editing

---
 .../transaction/OfflineTransactionRepository.kt     |  4 ++--
 .../database/transaction/TransactionDao.kt          |  4 ++--
 .../database/transaction/TransactionRepository.kt   |  4 ++--
 ...thTransaction.kt => CategoryWithTransactions.kt} |  2 +-
 .../ui/screens/cateegory/CategoriesScreen.kt        |  2 +-
 .../screens/transactions/TransactionDetailScreen.kt | 13 +++++++++++++
 6 files changed, 21 insertions(+), 8 deletions(-)
 rename app/src/main/java/cz/cvut/fel/pda/financemanagement/model/{CategoryWithTransaction.kt => CategoryWithTransactions.kt} (91%)

diff --git a/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/transaction/OfflineTransactionRepository.kt b/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/transaction/OfflineTransactionRepository.kt
index d1be722..e0bc608 100644
--- a/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/transaction/OfflineTransactionRepository.kt
+++ b/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/transaction/OfflineTransactionRepository.kt
@@ -1,6 +1,6 @@
 package cz.cvut.fel.pda.financemanagement.database.transaction
 
-import cz.cvut.fel.pda.financemanagement.model.CategoryWithTransaction
+import cz.cvut.fel.pda.financemanagement.model.CategoryWithTransactions
 import cz.cvut.fel.pda.financemanagement.model.TransactionWithCategory
 import kotlinx.coroutines.flow.Flow
 
@@ -10,7 +10,7 @@ class OfflineTransactionRepository(private val transactionDao: TransactionDao):
     override fun getTransactionForIdStream(id: Long): Flow<Transaction?> = transactionDao.getTransactionForId(id)
     override fun getTransactionWithCategoryForIdStream(id: Long): Flow<TransactionWithCategory> = transactionDao.getCategoryWithTransactionForId(id)
 
-    override fun getCategoryWithTransactions(): Flow<List<CategoryWithTransaction>> = transactionDao.getCategoryWithTransaction()
+    override fun getCategoryWithTransactions(): Flow<List<CategoryWithTransactions>> = transactionDao.getCategoryWithTransaction()
 
     override suspend fun insertTransactions(vararg transactions: Transaction) = transactionDao.insertTransactions(*transactions)
     override suspend fun deleteTransaction(transaction: Transaction) = transactionDao.delete(transaction)
diff --git a/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/transaction/TransactionDao.kt b/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/transaction/TransactionDao.kt
index 3755614..2abaedb 100644
--- a/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/transaction/TransactionDao.kt
+++ b/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/transaction/TransactionDao.kt
@@ -6,7 +6,7 @@ import androidx.room.Insert
 import androidx.room.OnConflictStrategy
 import androidx.room.Query
 import androidx.room.Update
-import cz.cvut.fel.pda.financemanagement.model.CategoryWithTransaction
+import cz.cvut.fel.pda.financemanagement.model.CategoryWithTransactions
 import cz.cvut.fel.pda.financemanagement.model.TransactionWithCategory
 import kotlinx.coroutines.flow.Flow
 
@@ -31,7 +31,7 @@ interface TransactionDao {
     INNER JOIN `transaction` ON `transaction`.categoryId = `category`.id
     ORDER BY `category`.id ASC
 """)
-    fun getCategoryWithTransaction(): Flow<List<CategoryWithTransaction>>
+    fun getCategoryWithTransaction(): Flow<List<CategoryWithTransactions>>
 
     @Insert(onConflict = OnConflictStrategy.REPLACE)
     suspend fun insertTransactions(vararg transactions: Transaction)
diff --git a/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/transaction/TransactionRepository.kt b/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/transaction/TransactionRepository.kt
index 60d929f..6dd9d71 100644
--- a/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/transaction/TransactionRepository.kt
+++ b/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/transaction/TransactionRepository.kt
@@ -1,6 +1,6 @@
 package cz.cvut.fel.pda.financemanagement.database.transaction
 
-import cz.cvut.fel.pda.financemanagement.model.CategoryWithTransaction
+import cz.cvut.fel.pda.financemanagement.model.CategoryWithTransactions
 import cz.cvut.fel.pda.financemanagement.model.TransactionWithCategory
 import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.map
@@ -10,7 +10,7 @@ interface TransactionRepository {
     fun getTransactionForIdStream(id: Long): Flow<Transaction?>
     fun getTransactionWithCategoryForIdStream(id: Long): Flow<TransactionWithCategory>
 
-    fun getCategoryWithTransactions(): Flow<List<CategoryWithTransaction>>
+    fun getCategoryWithTransactions(): Flow<List<CategoryWithTransactions>>
     fun getTransactionsWithCategory(): Flow<List<TransactionWithCategory>> {
         return getCategoryWithTransactions().map { categoryWithTransactionList ->
             categoryWithTransactionList.flatMap { categoryWithTransaction ->
diff --git a/app/src/main/java/cz/cvut/fel/pda/financemanagement/model/CategoryWithTransaction.kt b/app/src/main/java/cz/cvut/fel/pda/financemanagement/model/CategoryWithTransactions.kt
similarity index 91%
rename from app/src/main/java/cz/cvut/fel/pda/financemanagement/model/CategoryWithTransaction.kt
rename to app/src/main/java/cz/cvut/fel/pda/financemanagement/model/CategoryWithTransactions.kt
index 5d11a1e..727fb9c 100644
--- a/app/src/main/java/cz/cvut/fel/pda/financemanagement/model/CategoryWithTransaction.kt
+++ b/app/src/main/java/cz/cvut/fel/pda/financemanagement/model/CategoryWithTransactions.kt
@@ -5,7 +5,7 @@ import androidx.room.Relation
 import cz.cvut.fel.pda.financemanagement.database.category.Category
 import cz.cvut.fel.pda.financemanagement.database.transaction.Transaction
 
-data class CategoryWithTransaction(
+data class CategoryWithTransactions(
     @Embedded val category: Category,
     @Relation(
         parentColumn = "id",
diff --git a/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/cateegory/CategoriesScreen.kt b/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/cateegory/CategoriesScreen.kt
index 7be1f9c..9aa873b 100644
--- a/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/cateegory/CategoriesScreen.kt
+++ b/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/cateegory/CategoriesScreen.kt
@@ -63,7 +63,7 @@ fun CategoriesScreen(
             }
         },
         floatingActionButton = {
-             FloatingActionButton(onClick = {navController.navigate("${FinanceManagementScreens.EditCategory.name}/0    ")}) {
+             FloatingActionButton(onClick = {navController.navigate("${FinanceManagementScreens.EditCategory.name}/0")}) {
                 Icon(Icons.Default.Add, contentDescription = "Add")
              }
         },
diff --git a/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/transactions/TransactionDetailScreen.kt b/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/transactions/TransactionDetailScreen.kt
index 9cb3fa9..063175e 100644
--- a/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/transactions/TransactionDetailScreen.kt
+++ b/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/transactions/TransactionDetailScreen.kt
@@ -7,6 +7,10 @@ import androidx.compose.foundation.layout.Row
 import androidx.compose.foundation.layout.Spacer
 import androidx.compose.foundation.layout.height
 import androidx.compose.foundation.layout.padding
+import androidx.compose.material.icons.Icons
+import androidx.compose.material.icons.filled.Edit
+import androidx.compose.material3.FloatingActionButton
+import androidx.compose.material3.Icon
 import androidx.compose.material3.Scaffold
 import androidx.compose.material3.Text
 import androidx.compose.runtime.Composable
@@ -17,6 +21,8 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle
 import androidx.lifecycle.viewmodel.CreationExtras
 import androidx.lifecycle.viewmodel.compose.viewModel
 import androidx.navigation.NavHostController
+import cz.cvut.fel.pda.financemanagement.FinanceManagementApplication
+import cz.cvut.fel.pda.financemanagement.FinanceManagementScreens
 import cz.cvut.fel.pda.financemanagement.database.transaction.Transaction
 import cz.cvut.fel.pda.financemanagement.model.TransactionWithCategory
 import cz.cvut.fel.pda.financemanagement.ui.components.BottomNavigation
@@ -55,6 +61,13 @@ fun TransactionDetailScreen(
                 }
             }
         },
+        floatingActionButton = {
+            FloatingActionButton(onClick = {
+                navController.navigate("${FinanceManagementScreens.EditTransaction.name}/${transactionId}")
+            }) {
+                Icon(Icons.Default.Edit, contentDescription = "Edit Transaction")
+            }
+        },
         bottomBar = {
             BottomNavigation(navController = navController)
         }
-- 
GitLab


From faeaea29314bf51ba125cd5d3b4e18355c692c7a Mon Sep 17 00:00:00 2001
From: dovicrad <dovicrad@fel.cvut.cz>
Date: Mon, 29 Apr 2024 18:13:50 +0200
Subject: [PATCH 09/12] :cooking: add category type selection

---
 app/src/main/AndroidManifest.xml              |   2 +
 .../financemanagement/FinanceManagementApp.kt |  14 +-
 .../financemanagement/database/AppDatabase.kt |   4 +-
 .../database/category/Category.kt             |   6 +-
 .../{transaction => operation}/Operation.kt   |  10 +-
 .../OfflineTransactionRepository.kt           |   6 +-
 .../transaction/Transaction.kt                |   3 +-
 .../transaction/TransactionDao.kt             |   6 +-
 .../transaction/TransactionRepository.kt      |   6 +-
 .../pda/financemanagement/di/AppContainer.kt  |   4 +-
 ...saction.kt => CategoryWithTransactions.kt} |   4 +-
 .../model/TransactionWithCategory.kt          |   2 +-
 .../ui/components/BottomNavigation.kt         |   7 +-
 .../financemanagement/ui/components/TopBar.kt |   5 -
 .../screens/cateegory/EditCategoryScreen.kt   |  52 -----
 .../CategoriesScreen.kt                       |  32 +--
 .../screens/category/CategoryDetailScreen.kt  |  91 ++++++++
 .../CategoryDetailViewModel.kt                |  10 +-
 .../CategoryViewModel.kt                      |   2 +-
 .../ui/screens/category/EditCategoryScreen.kt | 195 ++++++++++++++++++
 .../transactions/EditTransactionScreen.kt     |   1 -
 .../transactions/TransactionDetailScreen.kt   |  15 +-
 .../TransactionDetailViewModel.kt             |   7 +-
 .../transactions/TransactionViewModel.kt      |   2 +-
 .../transactions/TransactionsScreen.kt        |   2 +-
 .../ui/utils/AppViewModelProvider.kt          |   4 +-
 26 files changed, 366 insertions(+), 126 deletions(-)
 rename app/src/main/java/cz/cvut/fel/pda/financemanagement/database/{transaction => operation}/Operation.kt (62%)
 rename app/src/main/java/cz/cvut/fel/pda/financemanagement/database/{ => operation}/transaction/OfflineTransactionRepository.kt (88%)
 rename app/src/main/java/cz/cvut/fel/pda/financemanagement/database/{ => operation}/transaction/Transaction.kt (77%)
 rename app/src/main/java/cz/cvut/fel/pda/financemanagement/database/{ => operation}/transaction/TransactionDao.kt (93%)
 rename app/src/main/java/cz/cvut/fel/pda/financemanagement/database/{ => operation}/transaction/TransactionRepository.kt (93%)
 rename app/src/main/java/cz/cvut/fel/pda/financemanagement/model/{CategoryWithTransaction.kt => CategoryWithTransactions.kt} (73%)
 delete mode 100644 app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/cateegory/EditCategoryScreen.kt
 rename app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/{cateegory => category}/CategoriesScreen.kt (84%)
 create mode 100644 app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/category/CategoryDetailScreen.kt
 rename app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/{cateegory => category}/CategoryDetailViewModel.kt (90%)
 rename app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/{cateegory => category}/CategoryViewModel.kt (96%)
 create mode 100644 app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/category/EditCategoryScreen.kt

diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index c49185b..b118bc2 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -1,6 +1,8 @@
 <?xml version="1.0" encoding="utf-8"?>
 <manifest xmlns:android="http://schemas.android.com/apk/res/android">
 
+    <uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
+
     <application
         android:name=".FinanceManagementApplication"
         android:allowBackup="true"
diff --git a/app/src/main/java/cz/cvut/fel/pda/financemanagement/FinanceManagementApp.kt b/app/src/main/java/cz/cvut/fel/pda/financemanagement/FinanceManagementApp.kt
index d7c98c5..6e2583a 100644
--- a/app/src/main/java/cz/cvut/fel/pda/financemanagement/FinanceManagementApp.kt
+++ b/app/src/main/java/cz/cvut/fel/pda/financemanagement/FinanceManagementApp.kt
@@ -9,20 +9,22 @@ import androidx.navigation.compose.composable
 import androidx.navigation.compose.rememberNavController
 import androidx.navigation.navArgument
 import cz.cvut.fel.pda.financemanagement.ui.screens.AccountsScreen
-import cz.cvut.fel.pda.financemanagement.ui.screens.cateegory.CategoriesScreen
 import cz.cvut.fel.pda.financemanagement.ui.screens.LoansScreen
-import cz.cvut.fel.pda.financemanagement.ui.screens.cateegory.EditCategoryScreen
+import cz.cvut.fel.pda.financemanagement.ui.screens.category.CategoriesScreen
+import cz.cvut.fel.pda.financemanagement.ui.screens.category.CategoryDetailScreen
+import cz.cvut.fel.pda.financemanagement.ui.screens.category.EditCategoryScreen
 import cz.cvut.fel.pda.financemanagement.ui.screens.transactions.EditTransactionScreen
 import cz.cvut.fel.pda.financemanagement.ui.screens.transactions.TransactionDetailScreen
 import cz.cvut.fel.pda.financemanagement.ui.screens.transactions.TransactionsScreen
 
 
-enum class FinanceManagementScreens() {
+enum class FinanceManagementScreens {
     Transactions,
     TransactionsDetail,
     EditTransaction,
 
     Categories,
+    CategoryDetail,
     EditCategory,
 
     Accounts,
@@ -69,5 +71,11 @@ fun FinanceManagementApp() {
                 it.arguments?.getLong("Id")
             )
         }
+        composable(route = "${FinanceManagementScreens.CategoryDetail.name}/{Id}",
+            arguments = listOf(navArgument("Id") { type = NavType.LongType })){
+            CategoryDetailScreen(navController = navController,
+                categoryId = it.arguments?.getLong("Id")
+            )
+        }
     }
 }
\ No newline at end of file
diff --git a/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/AppDatabase.kt b/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/AppDatabase.kt
index ac315bf..0e14141 100644
--- a/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/AppDatabase.kt
+++ b/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/AppDatabase.kt
@@ -7,8 +7,8 @@ import androidx.room.RoomDatabase
 import androidx.room.TypeConverters
 import cz.cvut.fel.pda.financemanagement.database.category.Category
 import cz.cvut.fel.pda.financemanagement.database.category.CategoryDao
-import cz.cvut.fel.pda.financemanagement.database.transaction.Transaction
-import cz.cvut.fel.pda.financemanagement.database.transaction.TransactionDao
+import cz.cvut.fel.pda.financemanagement.database.operation.transaction.Transaction
+import cz.cvut.fel.pda.financemanagement.database.operation.transaction.TransactionDao
 import cz.cvut.fel.pda.financemanagement.database.typeConvertion.Converters
 
 @Database(entities = [Transaction::class, Category::class], version = 7, exportSchema = false)
diff --git a/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/category/Category.kt b/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/category/Category.kt
index 9cc2b60..dc29cba 100644
--- a/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/category/Category.kt
+++ b/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/category/Category.kt
@@ -7,7 +7,7 @@ import androidx.room.PrimaryKey
 data class Category(
     @PrimaryKey(autoGenerate = true)
     val id: Long = 0,
-    val name: CategoryName,
+    val name: String,
     val type: CategoryType,
 )
 
@@ -15,7 +15,3 @@ enum class CategoryType {
     EXPENSE,
     INCOME,
 }
-
-enum class CategoryName {
-    GROCERIES,
-}
diff --git a/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/transaction/Operation.kt b/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/operation/Operation.kt
similarity index 62%
rename from app/src/main/java/cz/cvut/fel/pda/financemanagement/database/transaction/Operation.kt
rename to app/src/main/java/cz/cvut/fel/pda/financemanagement/database/operation/Operation.kt
index 5618432..4b22e67 100644
--- a/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/transaction/Operation.kt
+++ b/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/operation/Operation.kt
@@ -1,11 +1,9 @@
-package cz.cvut.fel.pda.financemanagement.database.transaction;
+package cz.cvut.fel.pda.financemanagement.database.operation
 
-import androidx.room.Entity;
-import androidx.room.PrimaryKey;
-
-import java.math.BigDecimal;
+import androidx.room.Entity
+import androidx.room.PrimaryKey
+import java.math.BigDecimal
 import java.time.LocalDateTime
-import java.util.Date
 
 @Entity(tableName = "operation")
 abstract class Operation {
diff --git a/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/transaction/OfflineTransactionRepository.kt b/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/operation/transaction/OfflineTransactionRepository.kt
similarity index 88%
rename from app/src/main/java/cz/cvut/fel/pda/financemanagement/database/transaction/OfflineTransactionRepository.kt
rename to app/src/main/java/cz/cvut/fel/pda/financemanagement/database/operation/transaction/OfflineTransactionRepository.kt
index d1be722..f27dd68 100644
--- a/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/transaction/OfflineTransactionRepository.kt
+++ b/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/operation/transaction/OfflineTransactionRepository.kt
@@ -1,6 +1,6 @@
-package cz.cvut.fel.pda.financemanagement.database.transaction
+package cz.cvut.fel.pda.financemanagement.database.operation.transaction
 
-import cz.cvut.fel.pda.financemanagement.model.CategoryWithTransaction
+import cz.cvut.fel.pda.financemanagement.model.CategoryWithTransactions
 import cz.cvut.fel.pda.financemanagement.model.TransactionWithCategory
 import kotlinx.coroutines.flow.Flow
 
@@ -10,7 +10,7 @@ class OfflineTransactionRepository(private val transactionDao: TransactionDao):
     override fun getTransactionForIdStream(id: Long): Flow<Transaction?> = transactionDao.getTransactionForId(id)
     override fun getTransactionWithCategoryForIdStream(id: Long): Flow<TransactionWithCategory> = transactionDao.getCategoryWithTransactionForId(id)
 
-    override fun getCategoryWithTransactions(): Flow<List<CategoryWithTransaction>> = transactionDao.getCategoryWithTransaction()
+    override fun getCategoryWithTransactions(): Flow<List<CategoryWithTransactions>> = transactionDao.getCategoryWithTransaction()
 
     override suspend fun insertTransactions(vararg transactions: Transaction) = transactionDao.insertTransactions(*transactions)
     override suspend fun deleteTransaction(transaction: Transaction) = transactionDao.delete(transaction)
diff --git a/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/transaction/Transaction.kt b/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/operation/transaction/Transaction.kt
similarity index 77%
rename from app/src/main/java/cz/cvut/fel/pda/financemanagement/database/transaction/Transaction.kt
rename to app/src/main/java/cz/cvut/fel/pda/financemanagement/database/operation/transaction/Transaction.kt
index 5042f03..750c837 100644
--- a/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/transaction/Transaction.kt
+++ b/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/operation/transaction/Transaction.kt
@@ -1,7 +1,8 @@
-package cz.cvut.fel.pda.financemanagement.database.transaction
+package cz.cvut.fel.pda.financemanagement.database.operation.transaction
 
 import androidx.room.Entity
 import androidx.room.PrimaryKey
+import cz.cvut.fel.pda.financemanagement.database.operation.Operation
 import java.math.BigDecimal
 import java.time.LocalDateTime
 
diff --git a/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/transaction/TransactionDao.kt b/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/operation/transaction/TransactionDao.kt
similarity index 93%
rename from app/src/main/java/cz/cvut/fel/pda/financemanagement/database/transaction/TransactionDao.kt
rename to app/src/main/java/cz/cvut/fel/pda/financemanagement/database/operation/transaction/TransactionDao.kt
index 3755614..bd0d257 100644
--- a/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/transaction/TransactionDao.kt
+++ b/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/operation/transaction/TransactionDao.kt
@@ -1,4 +1,4 @@
-package cz.cvut.fel.pda.financemanagement.database.transaction
+package cz.cvut.fel.pda.financemanagement.database.operation.transaction
 
 import androidx.room.Dao
 import androidx.room.Delete
@@ -6,7 +6,7 @@ import androidx.room.Insert
 import androidx.room.OnConflictStrategy
 import androidx.room.Query
 import androidx.room.Update
-import cz.cvut.fel.pda.financemanagement.model.CategoryWithTransaction
+import cz.cvut.fel.pda.financemanagement.model.CategoryWithTransactions
 import cz.cvut.fel.pda.financemanagement.model.TransactionWithCategory
 import kotlinx.coroutines.flow.Flow
 
@@ -31,7 +31,7 @@ interface TransactionDao {
     INNER JOIN `transaction` ON `transaction`.categoryId = `category`.id
     ORDER BY `category`.id ASC
 """)
-    fun getCategoryWithTransaction(): Flow<List<CategoryWithTransaction>>
+    fun getCategoryWithTransaction(): Flow<List<CategoryWithTransactions>>
 
     @Insert(onConflict = OnConflictStrategy.REPLACE)
     suspend fun insertTransactions(vararg transactions: Transaction)
diff --git a/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/transaction/TransactionRepository.kt b/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/operation/transaction/TransactionRepository.kt
similarity index 93%
rename from app/src/main/java/cz/cvut/fel/pda/financemanagement/database/transaction/TransactionRepository.kt
rename to app/src/main/java/cz/cvut/fel/pda/financemanagement/database/operation/transaction/TransactionRepository.kt
index 60d929f..69e0220 100644
--- a/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/transaction/TransactionRepository.kt
+++ b/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/operation/transaction/TransactionRepository.kt
@@ -1,6 +1,6 @@
-package cz.cvut.fel.pda.financemanagement.database.transaction
+package cz.cvut.fel.pda.financemanagement.database.operation.transaction
 
-import cz.cvut.fel.pda.financemanagement.model.CategoryWithTransaction
+import cz.cvut.fel.pda.financemanagement.model.CategoryWithTransactions
 import cz.cvut.fel.pda.financemanagement.model.TransactionWithCategory
 import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.map
@@ -10,7 +10,7 @@ interface TransactionRepository {
     fun getTransactionForIdStream(id: Long): Flow<Transaction?>
     fun getTransactionWithCategoryForIdStream(id: Long): Flow<TransactionWithCategory>
 
-    fun getCategoryWithTransactions(): Flow<List<CategoryWithTransaction>>
+    fun getCategoryWithTransactions(): Flow<List<CategoryWithTransactions>>
     fun getTransactionsWithCategory(): Flow<List<TransactionWithCategory>> {
         return getCategoryWithTransactions().map { categoryWithTransactionList ->
             categoryWithTransactionList.flatMap { categoryWithTransaction ->
diff --git a/app/src/main/java/cz/cvut/fel/pda/financemanagement/di/AppContainer.kt b/app/src/main/java/cz/cvut/fel/pda/financemanagement/di/AppContainer.kt
index 7ee3744..035c1c0 100644
--- a/app/src/main/java/cz/cvut/fel/pda/financemanagement/di/AppContainer.kt
+++ b/app/src/main/java/cz/cvut/fel/pda/financemanagement/di/AppContainer.kt
@@ -4,8 +4,8 @@ import android.content.Context
 import cz.cvut.fel.pda.financemanagement.database.AppDatabase
 import cz.cvut.fel.pda.financemanagement.database.category.CategoryRepository
 import cz.cvut.fel.pda.financemanagement.database.category.OfflineCategoryRepository
-import cz.cvut.fel.pda.financemanagement.database.transaction.OfflineTransactionRepository
-import cz.cvut.fel.pda.financemanagement.database.transaction.TransactionRepository
+import cz.cvut.fel.pda.financemanagement.database.operation.transaction.OfflineTransactionRepository
+import cz.cvut.fel.pda.financemanagement.database.operation.transaction.TransactionRepository
 
 interface AppContainer {
     val transactionRepository: TransactionRepository
diff --git a/app/src/main/java/cz/cvut/fel/pda/financemanagement/model/CategoryWithTransaction.kt b/app/src/main/java/cz/cvut/fel/pda/financemanagement/model/CategoryWithTransactions.kt
similarity index 73%
rename from app/src/main/java/cz/cvut/fel/pda/financemanagement/model/CategoryWithTransaction.kt
rename to app/src/main/java/cz/cvut/fel/pda/financemanagement/model/CategoryWithTransactions.kt
index 5d11a1e..81117af 100644
--- a/app/src/main/java/cz/cvut/fel/pda/financemanagement/model/CategoryWithTransaction.kt
+++ b/app/src/main/java/cz/cvut/fel/pda/financemanagement/model/CategoryWithTransactions.kt
@@ -3,9 +3,9 @@ package cz.cvut.fel.pda.financemanagement.model
 import androidx.room.Embedded
 import androidx.room.Relation
 import cz.cvut.fel.pda.financemanagement.database.category.Category
-import cz.cvut.fel.pda.financemanagement.database.transaction.Transaction
+import cz.cvut.fel.pda.financemanagement.database.operation.transaction.Transaction
 
-data class CategoryWithTransaction(
+data class CategoryWithTransactions(
     @Embedded val category: Category,
     @Relation(
         parentColumn = "id",
diff --git a/app/src/main/java/cz/cvut/fel/pda/financemanagement/model/TransactionWithCategory.kt b/app/src/main/java/cz/cvut/fel/pda/financemanagement/model/TransactionWithCategory.kt
index 661daa9..b24f6e5 100644
--- a/app/src/main/java/cz/cvut/fel/pda/financemanagement/model/TransactionWithCategory.kt
+++ b/app/src/main/java/cz/cvut/fel/pda/financemanagement/model/TransactionWithCategory.kt
@@ -3,7 +3,7 @@ package cz.cvut.fel.pda.financemanagement.model
 import androidx.room.Embedded
 import androidx.room.Relation
 import cz.cvut.fel.pda.financemanagement.database.category.Category
-import cz.cvut.fel.pda.financemanagement.database.transaction.Transaction
+import cz.cvut.fel.pda.financemanagement.database.operation.transaction.Transaction
 
 data class TransactionWithCategory(
     @Embedded val transaction: Transaction,
diff --git a/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/components/BottomNavigation.kt b/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/components/BottomNavigation.kt
index ef012a3..19e6087 100644
--- a/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/components/BottomNavigation.kt
+++ b/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/components/BottomNavigation.kt
@@ -34,12 +34,10 @@ fun BottomNavigation(navController: NavHostController) {
                 selected = currentRoute == it.second,
                 onClick = {
                     navController.navigate(it.second) {
-                        // Avoid multiple copies of the same destination when re-selecting the same item
                         launchSingleTop = true
                         popUpTo(navController.graph.findStartDestination().id) {
-                            saveState = true // Save the state of all destinations before popping them
+                            saveState = true
                         }
-                        // Restore state when navigating to a previously selected item
                         restoreState = true
                     }
                 }
@@ -50,8 +48,7 @@ fun BottomNavigation(navController: NavHostController) {
 
 @Composable
 fun GreyDot() {
-    Box(
-        modifier = Modifier
+    Box(modifier = Modifier
             .size(16.dp)
             .background(Color.DarkGray, CircleShape)
     )
diff --git a/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/components/TopBar.kt b/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/components/TopBar.kt
index 05a9f80..3c673a3 100644
--- a/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/components/TopBar.kt
+++ b/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/components/TopBar.kt
@@ -4,21 +4,16 @@ import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.fillMaxWidth
 import androidx.compose.material.icons.Icons
 import androidx.compose.material.icons.filled.Menu
-import androidx.compose.material3.DrawerValue
 import androidx.compose.material3.Icon
 import androidx.compose.material3.IconButton
-import androidx.compose.material3.ModalNavigationDrawer
 import androidx.compose.material3.Text
-import androidx.compose.material3.rememberDrawerState
 import androidx.compose.runtime.Composable
-import androidx.compose.runtime.rememberCoroutineScope
 import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.text.TextStyle
 import androidx.compose.ui.text.font.FontWeight
 import androidx.compose.ui.unit.sp
 import androidx.navigation.NavHostController
-import kotlinx.coroutines.launch
 
 @Composable
 fun TopBar(navHostController: NavHostController) {
diff --git a/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/cateegory/EditCategoryScreen.kt b/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/cateegory/EditCategoryScreen.kt
deleted file mode 100644
index 244583d..0000000
--- a/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/cateegory/EditCategoryScreen.kt
+++ /dev/null
@@ -1,52 +0,0 @@
-package cz.cvut.fel.pda.financemanagement.ui.screens.cateegory
-
-import androidx.compose.material3.Text
-import androidx.compose.runtime.Composable
-import androidx.compose.runtime.getValue
-import androidx.lifecycle.compose.collectAsStateWithLifecycle
-import androidx.lifecycle.viewmodel.compose.viewModel
-import androidx.navigation.NavHostController
-import cz.cvut.fel.pda.financemanagement.database.category.Category
-import cz.cvut.fel.pda.financemanagement.ui.components.ShowErrorScreen
-import cz.cvut.fel.pda.financemanagement.ui.components.ShowLoadingScreen
-import cz.cvut.fel.pda.financemanagement.ui.screens.transactions.ShowSuccessScreen
-import cz.cvut.fel.pda.financemanagement.ui.screens.transactions.TransactionDetailViewModel
-import cz.cvut.fel.pda.financemanagement.ui.screens.transactions.TransactionWithCategoryUiState
-import cz.cvut.fel.pda.financemanagement.ui.utils.AppViewModelProvider
-
-@Composable
-fun EditCategoryScreen(navController: NavHostController,
-                          categoryId: Long?,
-                          categoryDetailViewModel: CategoryDetailViewModel = viewModel(
-                              factory = AppViewModelProvider.Factory
-                          ),){
-    val uiState by categoryDetailViewModel.uiState.collectAsStateWithLifecycle()
-
-    when (val state = uiState) {
-        is CategoryDetailUiState.Error -> {
-            ShowErrorScreen(
-                errorMessage = state.exception.message ?: "Error",
-                onClick = { navController.popBackStack() }
-            )
-        }
-        CategoryDetailUiState.Loading -> {
-            ShowLoadingScreen()
-        }
-        is CategoryDetailUiState.Success -> {
-            ShowCategorySuccessScreen(
-                state.category,
-                navController,
-                categoryDetailViewModel
-            )
-        }
-    }
-}
-
-@Composable
-fun ShowCategorySuccessScreen(
-    category: Category,
-    navController: NavHostController,
-    categoryDetailViewModel: CategoryDetailViewModel
-) {
-    Text(text="Success Screen")
-}
diff --git a/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/cateegory/CategoriesScreen.kt b/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/category/CategoriesScreen.kt
similarity index 84%
rename from app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/cateegory/CategoriesScreen.kt
rename to app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/category/CategoriesScreen.kt
index 7be1f9c..6f27a75 100644
--- a/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/cateegory/CategoriesScreen.kt
+++ b/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/category/CategoriesScreen.kt
@@ -1,22 +1,31 @@
-package cz.cvut.fel.pda.financemanagement.ui.screens.cateegory
+package cz.cvut.fel.pda.financemanagement.ui.screens.category
 
+import androidx.compose.foundation.clickable
 import androidx.compose.foundation.layout.Column
 import androidx.compose.foundation.layout.PaddingValues
 import androidx.compose.foundation.layout.Row
+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.material.icons.Icons
 import androidx.compose.material.icons.filled.Add
 import androidx.compose.material3.FloatingActionButton
+import androidx.compose.material3.HorizontalDivider
 import androidx.compose.material3.Icon
 import androidx.compose.material3.Scaffold
 import androidx.compose.material3.Text
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.getValue
 import androidx.compose.ui.Modifier
+import androidx.compose.ui.text.TextStyle
+import androidx.compose.ui.text.font.FontWeight
+import androidx.compose.ui.unit.dp
+import androidx.compose.ui.unit.sp
 import androidx.lifecycle.compose.collectAsStateWithLifecycle
 import androidx.lifecycle.viewmodel.compose.viewModel
 import androidx.navigation.NavHostController
+import cz.cvut.fel.pda.financemanagement.FinanceManagementScreens
 import cz.cvut.fel.pda.financemanagement.database.category.Category
 import cz.cvut.fel.pda.financemanagement.database.category.CategoryType
 import cz.cvut.fel.pda.financemanagement.ui.components.BottomNavigation
@@ -24,13 +33,6 @@ import cz.cvut.fel.pda.financemanagement.ui.components.ShowErrorScreen
 import cz.cvut.fel.pda.financemanagement.ui.components.ShowLoadingScreen
 import cz.cvut.fel.pda.financemanagement.ui.components.TopBar
 import cz.cvut.fel.pda.financemanagement.ui.utils.AppViewModelProvider
-import androidx.compose.foundation.lazy.items
-import androidx.compose.material3.HorizontalDivider
-import androidx.compose.ui.text.TextStyle
-import androidx.compose.ui.text.font.FontWeight
-import androidx.compose.ui.unit.dp
-import androidx.compose.ui.unit.sp
-import cz.cvut.fel.pda.financemanagement.FinanceManagementScreens
 import java.util.Locale
 
 @Composable
@@ -63,7 +65,7 @@ fun CategoriesScreen(
             }
         },
         floatingActionButton = {
-             FloatingActionButton(onClick = {navController.navigate("${FinanceManagementScreens.EditCategory.name}/0    ")}) {
+             FloatingActionButton(onClick = {navController.navigate("${FinanceManagementScreens.EditCategory.name}/0")}) {
                 Icon(Icons.Default.Add, contentDescription = "Add")
              }
         },
@@ -81,25 +83,25 @@ fun CategoriesScreenContent(categories: List<Category>, navController: NavHostCo
     Column(modifier = Modifier.padding(innerPadding).padding(horizontal = 14.dp)) {
         Text(text = "Expense Categories:", style = TextStyle(fontSize = 16.sp, fontWeight = FontWeight.Bold))
         HorizontalDivider()
-        CategoriesList(expenseCategories)
+        CategoriesList(expenseCategories, navController)
         Text(text = "Income Categories:", style = TextStyle(fontSize = 16.sp, fontWeight = FontWeight.Bold))
         HorizontalDivider()
-        CategoriesList(incomeCategories)
+        CategoriesList(incomeCategories, navController)
     }
 }
 
 @Composable
-fun CategoriesList(categories: List<Category>) {
+fun CategoriesList(categories: List<Category>, navController: NavHostController) {
     LazyColumn {
         items(categories) { category ->
-            CategoryItem(category)
+            CategoryItem(category,navController)
         }
     }
 }
 
 @Composable
-fun CategoryItem(category: Category) {
-    Row {
+fun CategoryItem(category: Category, navController: NavHostController) {
+    Row(modifier = Modifier.padding(8.dp).clickable { navController.navigate("${FinanceManagementScreens.CategoryDetail}/${category.id}")}){
         Text(text = category.name.toString().lowercase().replaceFirstChar { it.titlecase(Locale.ROOT)})
     }
 }
diff --git a/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/category/CategoryDetailScreen.kt b/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/category/CategoryDetailScreen.kt
new file mode 100644
index 0000000..e182a49
--- /dev/null
+++ b/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/category/CategoryDetailScreen.kt
@@ -0,0 +1,91 @@
+package cz.cvut.fel.pda.financemanagement.ui.screens.category
+
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.PaddingValues
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.Spacer
+import androidx.compose.foundation.layout.height
+import androidx.compose.foundation.layout.padding
+import androidx.compose.material.icons.Icons
+import androidx.compose.material.icons.filled.Edit
+import androidx.compose.material3.FloatingActionButton
+import androidx.compose.material3.Icon
+import androidx.compose.material3.Scaffold
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.getValue
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.unit.dp
+import androidx.lifecycle.compose.collectAsStateWithLifecycle
+import androidx.lifecycle.viewmodel.compose.viewModel
+import androidx.navigation.NavHostController
+import cz.cvut.fel.pda.financemanagement.FinanceManagementScreens
+import cz.cvut.fel.pda.financemanagement.database.category.Category
+import cz.cvut.fel.pda.financemanagement.ui.components.BottomNavigation
+import cz.cvut.fel.pda.financemanagement.ui.components.ShowErrorScreen
+import cz.cvut.fel.pda.financemanagement.ui.components.ShowLoadingScreen
+import cz.cvut.fel.pda.financemanagement.ui.components.TopBar
+import cz.cvut.fel.pda.financemanagement.ui.utils.AppViewModelProvider
+
+
+@Composable
+fun CategoryDetailScreen(
+    navController: NavHostController,
+    categoryId: Long?,
+    categoryViewModel: CategoryDetailViewModel = viewModel(
+        factory = AppViewModelProvider.Factory
+    )
+){
+    categoryViewModel.setCategoryId(categoryId ?: 0L)
+    val  categoryDetailUiState:  CategoryDetailUiState by categoryViewModel.uiState.collectAsStateWithLifecycle()
+
+    Scaffold (
+        topBar = {TopBar(navController)},
+        content = {
+            innerPadding ->
+            when (categoryDetailUiState) {
+                is  CategoryDetailUiState.Loading -> {
+                    ShowLoadingScreen()
+                }
+                is  CategoryDetailUiState.Error -> {
+                    ShowErrorScreen(
+                        errorMessage = (categoryDetailUiState as  CategoryDetailUiState.Error).exception.message ?: "Error",
+                    )
+                }
+                is  CategoryDetailUiState.Success -> {
+                    CategoryScreenContent( (categoryDetailUiState as  CategoryDetailUiState.Success).category, innerPadding, navController)
+                }
+            }
+        },
+        floatingActionButton = {
+            FloatingActionButton(onClick = {
+                navController.navigate("${FinanceManagementScreens.EditCategory.name}/${categoryId}")
+            }) {
+                Icon(Icons.Default.Edit, contentDescription = "Edit Category")
+            }
+        },
+        bottomBar = {
+            BottomNavigation(navController = navController)
+        }
+    )
+}
+
+@Composable
+fun CategoryScreenContent(category: Category, innerPadding: PaddingValues, navController: NavHostController) {
+    Column(modifier = Modifier.padding(innerPadding)) {
+        Text(text = "Category Details")
+        Spacer(modifier = Modifier.height(16.dp))
+        Row {
+            Text(text = "ID: ")
+            Text(text = category.id.toString())
+        }
+        Row {
+            Text(text = "Name: ")
+            Text(text = category.name.toString())
+        }
+        Row {
+            Text(text = "Type: ")
+            Text(text = category.type.toString())
+        }
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/cateegory/CategoryDetailViewModel.kt b/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/category/CategoryDetailViewModel.kt
similarity index 90%
rename from app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/cateegory/CategoryDetailViewModel.kt
rename to app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/category/CategoryDetailViewModel.kt
index 1aa0979..92ef8e1 100644
--- a/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/cateegory/CategoryDetailViewModel.kt
+++ b/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/category/CategoryDetailViewModel.kt
@@ -1,17 +1,17 @@
-package cz.cvut.fel.pda.financemanagement.ui.screens.cateegory
+package cz.cvut.fel.pda.financemanagement.ui.screens.category
 
 import androidx.lifecycle.SavedStateHandle
 import androidx.lifecycle.ViewModel
 import androidx.lifecycle.viewModelScope
 import cz.cvut.fel.pda.financemanagement.database.category.Category
-import cz.cvut.fel.pda.financemanagement.database.category.CategoryName
-import cz.cvut.fel.pda.financemanagement.database.category.CategoryType
 import cz.cvut.fel.pda.financemanagement.database.category.CategoryRepository
+import cz.cvut.fel.pda.financemanagement.database.category.CategoryType
 import kotlinx.coroutines.flow.SharingStarted
 import kotlinx.coroutines.flow.StateFlow
 import kotlinx.coroutines.flow.map
 import kotlinx.coroutines.flow.stateIn
 import kotlinx.coroutines.launch
+
 class CategoryDetailViewModel(
     private val categoryRepository: CategoryRepository,
     savedStateHandle: SavedStateHandle
@@ -28,7 +28,7 @@ class CategoryDetailViewModel(
                     CategoryDetailUiState.Success(
                         Category(
                             id = 0,
-                            name = CategoryName.GROCERIES,
+                            name ="Groceries",
                             type = CategoryType.EXPENSE
                     )
                     )
@@ -45,7 +45,7 @@ class CategoryDetailViewModel(
     }
     fun saveCategory(
        type: CategoryType,
-       name: CategoryName,
+       name: String,
     ) {
         viewModelScope.launch {
             categoryRepository.insertCategories(
diff --git a/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/cateegory/CategoryViewModel.kt b/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/category/CategoryViewModel.kt
similarity index 96%
rename from app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/cateegory/CategoryViewModel.kt
rename to app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/category/CategoryViewModel.kt
index 4777dfb..0c639e7 100644
--- a/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/cateegory/CategoryViewModel.kt
+++ b/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/category/CategoryViewModel.kt
@@ -1,4 +1,4 @@
-package cz.cvut.fel.pda.financemanagement.ui.screens.cateegory
+package cz.cvut.fel.pda.financemanagement.ui.screens.category
 
 import androidx.lifecycle.ViewModel
 import androidx.lifecycle.viewModelScope
diff --git a/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/category/EditCategoryScreen.kt b/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/category/EditCategoryScreen.kt
new file mode 100644
index 0000000..2fa203d
--- /dev/null
+++ b/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/category/EditCategoryScreen.kt
@@ -0,0 +1,195 @@
+package cz.cvut.fel.pda.financemanagement.ui.screens.category
+
+import androidx.compose.foundation.border
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.PaddingValues
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.rememberScrollState
+import androidx.compose.foundation.shape.RoundedCornerShape
+import androidx.compose.foundation.verticalScroll
+import androidx.compose.material.icons.Icons
+import androidx.compose.material.icons.outlined.Close
+import androidx.compose.material3.Button
+import androidx.compose.material3.ButtonDefaults
+import androidx.compose.material3.DropdownMenu
+import androidx.compose.material3.DropdownMenuItem
+import androidx.compose.material3.ExperimentalMaterial3Api
+import androidx.compose.material3.Icon
+import androidx.compose.material3.IconButton
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.OutlinedTextField
+import androidx.compose.material3.Scaffold
+import androidx.compose.material3.SegmentedButton
+import androidx.compose.material3.SegmentedButtonDefaults
+import androidx.compose.material3.SingleChoiceSegmentedButtonRow
+import androidx.compose.material3.Switch
+import androidx.compose.material3.Text
+import androidx.compose.material3.TextButton
+import androidx.compose.material3.TopAppBar
+import androidx.compose.material3.TopAppBarDefaults
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.MutableState
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
+import androidx.compose.runtime.saveable.rememberSaveable
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.graphics.RectangleShape
+import androidx.compose.ui.text.toLowerCase
+import androidx.compose.ui.unit.dp
+import androidx.lifecycle.compose.collectAsStateWithLifecycle
+import androidx.lifecycle.viewmodel.compose.viewModel
+import androidx.navigation.NavHostController
+import cz.cvut.fel.pda.financemanagement.database.category.Category
+import cz.cvut.fel.pda.financemanagement.database.category.CategoryType
+import cz.cvut.fel.pda.financemanagement.ui.components.ShowErrorScreen
+import cz.cvut.fel.pda.financemanagement.ui.components.ShowLoadingScreen
+import cz.cvut.fel.pda.financemanagement.ui.utils.AppViewModelProvider
+import java.math.BigDecimal
+import java.util.Locale
+
+@Composable
+fun EditCategoryScreen(navController: NavHostController,
+                          categoryId: Long?,
+                          categoryDetailViewModel: CategoryDetailViewModel = viewModel(
+                              factory = AppViewModelProvider.Factory
+                          ),){
+    val uiState by categoryDetailViewModel.uiState.collectAsStateWithLifecycle()
+
+    when (val state = uiState) {
+        is CategoryDetailUiState.Error -> {
+            ShowErrorScreen(
+                errorMessage = state.exception.message ?: "Error",
+                onClick = { navController.popBackStack() }
+            )
+        }
+        CategoryDetailUiState.Loading -> {
+            ShowLoadingScreen()
+        }
+        is CategoryDetailUiState.Success -> {
+            ShowCategorySuccessScreen(
+                state.category,
+                navController,
+                categoryDetailViewModel
+            )
+        }
+    }
+}
+
+@OptIn(ExperimentalMaterial3Api::class)
+@Composable
+fun ShowCategorySuccessScreen(
+    category: Category,
+    navController: NavHostController,
+    categoryDetailViewModel: CategoryDetailViewModel
+) {
+    val type = rememberSaveable { mutableStateOf(category.type) }
+    val name = rememberSaveable { mutableStateOf(category.name) }
+    val options = listOf(CategoryType.INCOME, CategoryType.EXPENSE)
+    val selectedOption = remember { mutableStateOf(type.value) }
+
+
+    Scaffold(
+        topBar = {
+            TopAppBar(
+                title = { Text("Category edit") },
+                colors = TopAppBarDefaults.mediumTopAppBarColors(
+                    containerColor = MaterialTheme.colorScheme.primaryContainer
+                ),
+                modifier = Modifier,
+                navigationIcon = {
+                    IconButton(onClick = { navController.popBackStack() }) {
+                        Icon(
+                            imageVector = Icons.Outlined.Close,
+                            contentDescription = "cs"
+                        )
+                    }
+                },
+                actions = {
+                    TextButton(
+                        onClick = {
+                            categoryDetailViewModel.saveCategory(
+                                type = type.value,
+                                name = name.value
+                            )
+                            navController.popBackStack()
+                        },
+                        modifier = Modifier.padding(16.dp)
+                    ) {
+                        Text(text = "save")
+                    }
+                }
+            )
+        },
+        content = {
+            innerPadding ->
+            Column (
+                modifier = Modifier
+                    .fillMaxWidth()
+                    .verticalScroll(rememberScrollState())
+                    .padding(innerPadding), // use innerPadding here
+                horizontalAlignment = Alignment.CenterHorizontally
+            ) {
+                SingleChoiceSegmentedButtonRow {
+                    options.forEachIndexed{index, option ->
+                        SegmentedButton(
+                            selected = selectedOption.value == option,
+                            onClick = {
+                                selectedOption.value = option
+                                type.value = option
+                            },
+                            shape = SegmentedButtonDefaults.itemShape(index=index ,count = options.size)
+                        ) {
+                            Text(text = option.name.lowercase(Locale.getDefault()))
+                        }
+                    }
+                }
+
+                val spaceModifier = Modifier
+                    .fillMaxWidth()
+                    .padding(24.dp, 4.dp)
+                OutlinedTextField(
+                    value = name.value, // Use the correct variable
+                    onValueChange = { newValue ->
+                        name.value = newValue // Use the correct variable
+                    },
+                    label = { Text("name") }, // Use the correct label
+                    modifier = spaceModifier
+                )
+            }
+        }
+    )
+}
+@Composable
+fun EditTransactionDetailSuccessContent(
+    innerPadding: PaddingValues,
+    type: MutableState<CategoryType>, // Specify the correct type
+    name: MutableState<String>
+) {
+    val openDialog = remember { mutableStateOf(false) }
+
+    Column (
+        modifier = Modifier
+            .fillMaxWidth()
+            .verticalScroll(rememberScrollState())
+            .padding(innerPadding), // use innerPadding here
+        horizontalAlignment = Alignment.CenterHorizontally
+    ) {
+        val spaceModifier = Modifier
+            .fillMaxWidth()
+            .padding(24.dp, 4.dp)
+        OutlinedTextField(
+            value = name.value, // Use the correct variable
+            onValueChange = { newValue ->
+                name.value = newValue // Use the correct variable
+            },
+            label = { Text("name") }, // Use the correct label
+            modifier = spaceModifier
+        )
+        // Add OutlinedTextField for date and dropdown menu for category here
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/transactions/EditTransactionScreen.kt b/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/transactions/EditTransactionScreen.kt
index 5ea69ae..a1a78ef 100644
--- a/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/transactions/EditTransactionScreen.kt
+++ b/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/transactions/EditTransactionScreen.kt
@@ -30,7 +30,6 @@ import androidx.compose.ui.unit.dp
 import androidx.lifecycle.compose.collectAsStateWithLifecycle
 import androidx.lifecycle.viewmodel.compose.viewModel
 import androidx.navigation.NavHostController
-import cz.cvut.fel.pda.financemanagement.database.transaction.Transaction
 import cz.cvut.fel.pda.financemanagement.model.TransactionWithCategory
 import cz.cvut.fel.pda.financemanagement.ui.components.ShowErrorScreen
 import cz.cvut.fel.pda.financemanagement.ui.components.ShowLoadingScreen
diff --git a/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/transactions/TransactionDetailScreen.kt b/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/transactions/TransactionDetailScreen.kt
index 9cb3fa9..a4b4d04 100644
--- a/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/transactions/TransactionDetailScreen.kt
+++ b/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/transactions/TransactionDetailScreen.kt
@@ -1,12 +1,15 @@
 package cz.cvut.fel.pda.financemanagement.ui.screens.transactions
 
-import android.provider.Settings.Global.putLong
 import androidx.compose.foundation.layout.Column
 import androidx.compose.foundation.layout.PaddingValues
 import androidx.compose.foundation.layout.Row
 import androidx.compose.foundation.layout.Spacer
 import androidx.compose.foundation.layout.height
 import androidx.compose.foundation.layout.padding
+import androidx.compose.material.icons.Icons
+import androidx.compose.material.icons.filled.Edit
+import androidx.compose.material3.FloatingActionButton
+import androidx.compose.material3.Icon
 import androidx.compose.material3.Scaffold
 import androidx.compose.material3.Text
 import androidx.compose.runtime.Composable
@@ -14,10 +17,9 @@ import androidx.compose.runtime.getValue
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.unit.dp
 import androidx.lifecycle.compose.collectAsStateWithLifecycle
-import androidx.lifecycle.viewmodel.CreationExtras
 import androidx.lifecycle.viewmodel.compose.viewModel
 import androidx.navigation.NavHostController
-import cz.cvut.fel.pda.financemanagement.database.transaction.Transaction
+import cz.cvut.fel.pda.financemanagement.FinanceManagementScreens
 import cz.cvut.fel.pda.financemanagement.model.TransactionWithCategory
 import cz.cvut.fel.pda.financemanagement.ui.components.BottomNavigation
 import cz.cvut.fel.pda.financemanagement.ui.components.ShowErrorScreen
@@ -55,6 +57,13 @@ fun TransactionDetailScreen(
                 }
             }
         },
+        floatingActionButton = {
+            FloatingActionButton(onClick = {
+                navController.navigate("${FinanceManagementScreens.EditTransaction.name}/${transactionId}")
+            }) {
+                Icon(Icons.Default.Edit, contentDescription = "Edit Transaction")
+            }
+        },
         bottomBar = {
             BottomNavigation(navController = navController)
         }
diff --git a/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/transactions/TransactionDetailViewModel.kt b/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/transactions/TransactionDetailViewModel.kt
index a9eceea..e3271b5 100644
--- a/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/transactions/TransactionDetailViewModel.kt
+++ b/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/transactions/TransactionDetailViewModel.kt
@@ -4,10 +4,9 @@ import androidx.lifecycle.SavedStateHandle
 import androidx.lifecycle.ViewModel
 import androidx.lifecycle.viewModelScope
 import cz.cvut.fel.pda.financemanagement.database.category.Category
-import cz.cvut.fel.pda.financemanagement.database.category.CategoryName
 import cz.cvut.fel.pda.financemanagement.database.category.CategoryType
-import cz.cvut.fel.pda.financemanagement.database.transaction.Transaction
-import cz.cvut.fel.pda.financemanagement.database.transaction.TransactionRepository
+import cz.cvut.fel.pda.financemanagement.database.operation.transaction.Transaction
+import cz.cvut.fel.pda.financemanagement.database.operation.transaction.TransactionRepository
 import cz.cvut.fel.pda.financemanagement.model.TransactionWithCategory
 import kotlinx.coroutines.flow.SharingStarted
 import kotlinx.coroutines.flow.StateFlow
@@ -32,7 +31,7 @@ class TransactionDetailViewModel(
                     TransactionWithCategoryUiState.Success(
                         TransactionWithCategory(
                         transaction = Transaction(categoryId = 0L),
-                        category = Category(0, CategoryName.GROCERIES,CategoryType.INCOME)
+                        category = Category(0, "Groceries",CategoryType.INCOME)
                     )
                     )
                 } else {
diff --git a/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/transactions/TransactionViewModel.kt b/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/transactions/TransactionViewModel.kt
index b90f770..546fa27 100644
--- a/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/transactions/TransactionViewModel.kt
+++ b/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/transactions/TransactionViewModel.kt
@@ -2,7 +2,7 @@ package cz.cvut.fel.pda.financemanagement.ui.screens.transactions
 
 import androidx.lifecycle.ViewModel
 import androidx.lifecycle.viewModelScope
-import cz.cvut.fel.pda.financemanagement.database.transaction.TransactionRepository
+import cz.cvut.fel.pda.financemanagement.database.operation.transaction.TransactionRepository
 import cz.cvut.fel.pda.financemanagement.model.TransactionWithCategory
 import cz.cvut.fel.pda.financemanagement.model.common.Result
 import cz.cvut.fel.pda.financemanagement.model.common.asResult
diff --git a/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/transactions/TransactionsScreen.kt b/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/transactions/TransactionsScreen.kt
index 921f714..4f10d61 100644
--- a/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/transactions/TransactionsScreen.kt
+++ b/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/transactions/TransactionsScreen.kt
@@ -48,7 +48,7 @@ import androidx.navigation.compose.rememberNavController
 import cz.cvut.fel.pda.financemanagement.FinanceManagementScreens
 import cz.cvut.fel.pda.financemanagement.database.category.Category
 import cz.cvut.fel.pda.financemanagement.database.category.CategoryType
-import cz.cvut.fel.pda.financemanagement.database.transaction.Transaction
+import cz.cvut.fel.pda.financemanagement.database.operation.transaction.Transaction
 import cz.cvut.fel.pda.financemanagement.model.TransactionWithCategory
 import cz.cvut.fel.pda.financemanagement.ui.components.BottomNavigation
 import cz.cvut.fel.pda.financemanagement.ui.components.ShowErrorScreen
diff --git a/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/utils/AppViewModelProvider.kt b/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/utils/AppViewModelProvider.kt
index 9480208..2c9e889 100644
--- a/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/utils/AppViewModelProvider.kt
+++ b/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/utils/AppViewModelProvider.kt
@@ -6,8 +6,8 @@ import androidx.lifecycle.viewmodel.CreationExtras
 import androidx.lifecycle.viewmodel.initializer
 import androidx.lifecycle.viewmodel.viewModelFactory
 import cz.cvut.fel.pda.financemanagement.FinanceManagementApplication
-import cz.cvut.fel.pda.financemanagement.ui.screens.cateegory.CategoryDetailViewModel
-import cz.cvut.fel.pda.financemanagement.ui.screens.cateegory.CategoryViewModel
+import cz.cvut.fel.pda.financemanagement.ui.screens.category.CategoryDetailViewModel
+import cz.cvut.fel.pda.financemanagement.ui.screens.category.CategoryViewModel
 import cz.cvut.fel.pda.financemanagement.ui.screens.transactions.TransactionDetailViewModel
 import cz.cvut.fel.pda.financemanagement.ui.screens.transactions.TransactionViewModel
 
-- 
GitLab


From d0174093aa514ca9e9c0c9d855e63b7594a2703c Mon Sep 17 00:00:00 2001
From: dovicrad <dovicrad@fel.cvut.cz>
Date: Mon, 6 May 2024 16:05:42 +0200
Subject: [PATCH 10/12] :art: make category edit prettier

---
 .../ui/screens/category/EditCategoryScreen.kt | 98 ++++++++-----------
 1 file changed, 42 insertions(+), 56 deletions(-)

diff --git a/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/category/EditCategoryScreen.kt b/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/category/EditCategoryScreen.kt
index 2fa203d..1c16eb8 100644
--- a/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/category/EditCategoryScreen.kt
+++ b/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/category/EditCategoryScreen.kt
@@ -3,32 +3,24 @@ package cz.cvut.fel.pda.financemanagement.ui.screens.category
 import androidx.compose.foundation.border
 import androidx.compose.foundation.layout.Column
 import androidx.compose.foundation.layout.PaddingValues
-import androidx.compose.foundation.layout.Row
 import androidx.compose.foundation.layout.fillMaxWidth
 import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.size
 import androidx.compose.foundation.rememberScrollState
-import androidx.compose.foundation.shape.RoundedCornerShape
 import androidx.compose.foundation.verticalScroll
 import androidx.compose.material.icons.Icons
-import androidx.compose.material.icons.outlined.Close
-import androidx.compose.material3.Button
-import androidx.compose.material3.ButtonDefaults
-import androidx.compose.material3.DropdownMenu
-import androidx.compose.material3.DropdownMenuItem
+import androidx.compose.material.icons.outlined.Check
 import androidx.compose.material3.ExperimentalMaterial3Api
+import androidx.compose.material3.FloatingActionButton
+import androidx.compose.material3.HorizontalDivider
 import androidx.compose.material3.Icon
-import androidx.compose.material3.IconButton
 import androidx.compose.material3.MaterialTheme
 import androidx.compose.material3.OutlinedTextField
 import androidx.compose.material3.Scaffold
 import androidx.compose.material3.SegmentedButton
 import androidx.compose.material3.SegmentedButtonDefaults
 import androidx.compose.material3.SingleChoiceSegmentedButtonRow
-import androidx.compose.material3.Switch
 import androidx.compose.material3.Text
-import androidx.compose.material3.TextButton
-import androidx.compose.material3.TopAppBar
-import androidx.compose.material3.TopAppBarDefaults
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.MutableState
 import androidx.compose.runtime.getValue
@@ -38,18 +30,18 @@ import androidx.compose.runtime.saveable.rememberSaveable
 import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.graphics.Color
-import androidx.compose.ui.graphics.RectangleShape
-import androidx.compose.ui.text.toLowerCase
+import androidx.compose.ui.text.font.FontWeight
 import androidx.compose.ui.unit.dp
 import androidx.lifecycle.compose.collectAsStateWithLifecycle
 import androidx.lifecycle.viewmodel.compose.viewModel
 import androidx.navigation.NavHostController
 import cz.cvut.fel.pda.financemanagement.database.category.Category
 import cz.cvut.fel.pda.financemanagement.database.category.CategoryType
+import cz.cvut.fel.pda.financemanagement.ui.components.BottomNavigation
 import cz.cvut.fel.pda.financemanagement.ui.components.ShowErrorScreen
 import cz.cvut.fel.pda.financemanagement.ui.components.ShowLoadingScreen
+import cz.cvut.fel.pda.financemanagement.ui.components.TopBar
 import cz.cvut.fel.pda.financemanagement.ui.utils.AppViewModelProvider
-import java.math.BigDecimal
 import java.util.Locale
 
 @Composable
@@ -95,46 +87,26 @@ fun ShowCategorySuccessScreen(
 
     Scaffold(
         topBar = {
-            TopAppBar(
-                title = { Text("Category edit") },
-                colors = TopAppBarDefaults.mediumTopAppBarColors(
-                    containerColor = MaterialTheme.colorScheme.primaryContainer
-                ),
-                modifier = Modifier,
-                navigationIcon = {
-                    IconButton(onClick = { navController.popBackStack() }) {
-                        Icon(
-                            imageVector = Icons.Outlined.Close,
-                            contentDescription = "cs"
-                        )
-                    }
-                },
-                actions = {
-                    TextButton(
-                        onClick = {
-                            categoryDetailViewModel.saveCategory(
-                                type = type.value,
-                                name = name.value
-                            )
-                            navController.popBackStack()
-                        },
-                        modifier = Modifier.padding(16.dp)
-                    ) {
-                        Text(text = "save")
-                    }
-                }
-            )
+            TopBar(navHostController = navController)
         },
         content = {
             innerPadding ->
             Column (
                 modifier = Modifier
                     .fillMaxWidth()
+                    .padding(24.dp, 4.dp)
                     .verticalScroll(rememberScrollState())
-                    .padding(innerPadding), // use innerPadding here
-                horizontalAlignment = Alignment.CenterHorizontally
+                    .padding(innerPadding),
+
             ) {
-                SingleChoiceSegmentedButtonRow {
+                val spaceModifier = Modifier
+                    .padding(vertical = 14.dp)
+                Text(
+                    modifier = spaceModifier,
+                    style = MaterialTheme.typography.titleLarge.copy(fontWeight = FontWeight.Bold),
+                    color = Color.Black,
+                    text = if (category.id == 0L) "New Category" else "Edit Category")
+                SingleChoiceSegmentedButtonRow{
                     options.forEachIndexed{index, option ->
                         SegmentedButton(
                             selected = selectedOption.value == option,
@@ -144,23 +116,37 @@ fun ShowCategorySuccessScreen(
                             },
                             shape = SegmentedButtonDefaults.itemShape(index=index ,count = options.size)
                         ) {
-                            Text(text = option.name.lowercase(Locale.getDefault()))
+                            Text(text = option.name.lowercase(Locale.getDefault()).replaceFirstChar { it.titlecase(Locale.getDefault()) })
                         }
                     }
                 }
-
-                val spaceModifier = Modifier
-                    .fillMaxWidth()
-                    .padding(24.dp, 4.dp)
+                HorizontalDivider(modifier = spaceModifier)
                 OutlinedTextField(
-                    value = name.value, // Use the correct variable
+                    value = name.value,
                     onValueChange = { newValue ->
-                        name.value = newValue // Use the correct variable
+                        name.value = newValue
                     },
-                    label = { Text("name") }, // Use the correct label
-                    modifier = spaceModifier
+                    label = { Text("name") }
+                )
+            }
+        },
+        floatingActionButton = {
+            FloatingActionButton(
+                onClick = { categoryDetailViewModel.saveCategory(
+                name = name.value,
+                type = type.value
+            )
+                navController.popBackStack() })
+            {
+                Icon(
+                    Icons.Outlined.Check,
+                    contentDescription = "Save",
+                    modifier = Modifier.size(24.dp)
                 )
             }
+        },
+        bottomBar = {
+            BottomNavigation(navController = navController)
         }
     )
 }
-- 
GitLab


From e466c09ed66b3bf25f6af52a71e87c08613a2d6c Mon Sep 17 00:00:00 2001
From: dovicrad <dovicrad@fel.cvut.cz>
Date: Mon, 6 May 2024 23:39:32 +0200
Subject: [PATCH 11/12] :art: add selectable category to transactions

---
 .../OfflineTransactionRepository.kt           |  2 +-
 .../operation/transaction/TransactionDao.kt   |  6 ++
 .../transaction/TransactionRepository.kt      | 13 +--
 .../transactions/EditTransactionScreen.kt     | 82 ++++++++++++++++---
 .../TransactionDetailViewModel.kt             |  5 +-
 .../transactions/TransactionsScreen.kt        | 63 +++++++++-----
 6 files changed, 125 insertions(+), 46 deletions(-)

diff --git a/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/operation/transaction/OfflineTransactionRepository.kt b/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/operation/transaction/OfflineTransactionRepository.kt
index f27dd68..0719631 100644
--- a/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/operation/transaction/OfflineTransactionRepository.kt
+++ b/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/operation/transaction/OfflineTransactionRepository.kt
@@ -11,7 +11,7 @@ class OfflineTransactionRepository(private val transactionDao: TransactionDao):
     override fun getTransactionWithCategoryForIdStream(id: Long): Flow<TransactionWithCategory> = transactionDao.getCategoryWithTransactionForId(id)
 
     override fun getCategoryWithTransactions(): Flow<List<CategoryWithTransactions>> = transactionDao.getCategoryWithTransaction()
-
+    override fun getTransactionsWithCategory(): Flow<List<TransactionWithCategory>> = transactionDao.getTransactionWithCategory()
     override suspend fun insertTransactions(vararg transactions: Transaction) = transactionDao.insertTransactions(*transactions)
     override suspend fun deleteTransaction(transaction: Transaction) = transactionDao.delete(transaction)
     override suspend fun deleteAllTransactions() = transactionDao.deleteAll()
diff --git a/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/operation/transaction/TransactionDao.kt b/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/operation/transaction/TransactionDao.kt
index bd0d257..4801d00 100644
--- a/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/operation/transaction/TransactionDao.kt
+++ b/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/operation/transaction/TransactionDao.kt
@@ -26,6 +26,12 @@ interface TransactionDao {
 """)
     fun getCategoryWithTransactionForId(id: Long): Flow<TransactionWithCategory>
 
+    @Query("""
+    SELECT * FROM `category`
+    JOIN `transaction` ON `transaction`.categoryId = `category`.id
+""")
+    fun getTransactionWithCategory(): Flow<List<TransactionWithCategory>>
+
     @Query("""
     SELECT * FROM `category`
     INNER JOIN `transaction` ON `transaction`.categoryId = `category`.id
diff --git a/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/operation/transaction/TransactionRepository.kt b/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/operation/transaction/TransactionRepository.kt
index 69e0220..1576e07 100644
--- a/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/operation/transaction/TransactionRepository.kt
+++ b/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/operation/transaction/TransactionRepository.kt
@@ -11,18 +11,7 @@ interface TransactionRepository {
     fun getTransactionWithCategoryForIdStream(id: Long): Flow<TransactionWithCategory>
 
     fun getCategoryWithTransactions(): Flow<List<CategoryWithTransactions>>
-    fun getTransactionsWithCategory(): Flow<List<TransactionWithCategory>> {
-        return getCategoryWithTransactions().map { categoryWithTransactionList ->
-            categoryWithTransactionList.flatMap { categoryWithTransaction ->
-                categoryWithTransaction.transaction.map { transaction ->
-                    TransactionWithCategory(
-                        transaction = transaction,
-                        category = categoryWithTransaction.category
-                    )
-                }
-            }
-        }
-    }
+    fun getTransactionsWithCategory(): Flow<List<TransactionWithCategory>>
     suspend fun insertTransactions(vararg transactions: Transaction)
     suspend fun deleteTransaction(transaction: Transaction)
     suspend fun deleteAllTransactions()
diff --git a/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/transactions/EditTransactionScreen.kt b/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/transactions/EditTransactionScreen.kt
index a1a78ef..32d3b38 100644
--- a/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/transactions/EditTransactionScreen.kt
+++ b/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/transactions/EditTransactionScreen.kt
@@ -7,7 +7,10 @@ import androidx.compose.foundation.layout.padding
 import androidx.compose.foundation.rememberScrollState
 import androidx.compose.foundation.verticalScroll
 import androidx.compose.material.icons.Icons
+import androidx.compose.material.icons.filled.ArrowDropDown
 import androidx.compose.material.icons.outlined.Close
+import androidx.compose.material3.DropdownMenu
+import androidx.compose.material3.DropdownMenuItem
 import androidx.compose.material3.ExperimentalMaterial3Api
 import androidx.compose.material3.Icon
 import androidx.compose.material3.IconButton
@@ -30,9 +33,12 @@ import androidx.compose.ui.unit.dp
 import androidx.lifecycle.compose.collectAsStateWithLifecycle
 import androidx.lifecycle.viewmodel.compose.viewModel
 import androidx.navigation.NavHostController
+import cz.cvut.fel.pda.financemanagement.database.category.Category
 import cz.cvut.fel.pda.financemanagement.model.TransactionWithCategory
 import cz.cvut.fel.pda.financemanagement.ui.components.ShowErrorScreen
 import cz.cvut.fel.pda.financemanagement.ui.components.ShowLoadingScreen
+import cz.cvut.fel.pda.financemanagement.ui.screens.category.CategoriesUiState
+import cz.cvut.fel.pda.financemanagement.ui.screens.category.CategoryViewModel
 import cz.cvut.fel.pda.financemanagement.ui.utils.AppViewModelProvider
 import java.math.BigDecimal
 
@@ -41,8 +47,13 @@ fun EditTransactionScreen(navController: NavHostController,
                           transitionId: Long?,
                           transitionDetailViewModel: TransactionDetailViewModel = viewModel(
                               factory = AppViewModelProvider.Factory
-),){
+                          ),
+                          categoryViewModel: CategoryViewModel = viewModel(
+                              factory = AppViewModelProvider.Factory
+                          )
+                          ,){
     val uiState by transitionDetailViewModel.uiState.collectAsStateWithLifecycle()
+    val categoryUiState by categoryViewModel.categories.collectAsStateWithLifecycle()
 
     when (val state = uiState) {
         is TransactionWithCategoryUiState.Error -> {
@@ -51,15 +62,29 @@ fun EditTransactionScreen(navController: NavHostController,
                 onClick = { navController.popBackStack() }
             )
         }
-        TransactionWithCategoryUiState.Loading -> {
+        is TransactionWithCategoryUiState.Loading -> {
             ShowLoadingScreen()
         }
         is TransactionWithCategoryUiState.Success -> {
-            ShowSuccessScreen(
-                state.transaction,
-                navController,
-                transitionDetailViewModel
-            )
+            when(val categoryState = categoryUiState) {
+                is CategoriesUiState.Success -> {
+                    ShowSuccessScreen(
+                        state.transaction,
+                        categoryState.itemList,
+                        navController,
+                        transitionDetailViewModel,
+                    )
+                }
+                is CategoriesUiState.Loading -> {
+                    ShowLoadingScreen()
+                }
+                is CategoriesUiState.Error -> {
+                    ShowErrorScreen(
+                        errorMessage = categoryState.exception.message ?: "Error",
+                        onClick = { navController.popBackStack() }
+                    )
+                }
+            }
         }
     }
 }
@@ -68,10 +93,12 @@ fun EditTransactionScreen(navController: NavHostController,
 @Composable
 fun ShowSuccessScreen(
     transaction: TransactionWithCategory,
+    categories: List<Category>,
     navController: NavHostController,
-    transactionViewModel: TransactionDetailViewModel
+    transactionViewModel: TransactionDetailViewModel,
 ) {
     val amount = rememberSaveable { mutableStateOf(transaction.transaction.amount.toString()) }
+    val selectedCategory = remember{ mutableStateOf(categories.find { it.id == transaction.category.id } ?: categories[0]) }
 
     Scaffold(
         topBar = {
@@ -94,6 +121,7 @@ fun ShowSuccessScreen(
                         onClick = {
                             transactionViewModel.saveTransaction(
                                 amount = BigDecimal(amount.value),
+                                category = selectedCategory.value
                             )
                             navController.popBackStack()
                         },
@@ -104,20 +132,26 @@ fun ShowSuccessScreen(
                 }
             )
         },
+
         content = {innerPadding ->
-            EditTransactionDetailSuccessContent(innerPadding, amount)
+            EditTransactionDetailSuccessContent(innerPadding, amount, categories, selectedCategory)
         }
     )
 }
+
 @Composable
-fun EditTransactionDetailSuccessContent(innerPadding: PaddingValues, amount: MutableState<String>) {
-    val openDialog = remember { mutableStateOf(false) }
+fun EditTransactionDetailSuccessContent(innerPadding: PaddingValues,
+                                        amount: MutableState<String>,
+                                        categories: List<Category>,
+                                        selectedCategory: MutableState<Category>
+) {
+    val showDropdown = remember { mutableStateOf(false) }
 
     Column (
         modifier = Modifier
             .fillMaxWidth()
             .verticalScroll(rememberScrollState())
-            .padding(innerPadding), // use innerPadding here
+            .padding(innerPadding),
         horizontalAlignment = Alignment.CenterHorizontally
     ) {
         val spaceModifier = Modifier
@@ -133,5 +167,29 @@ fun EditTransactionDetailSuccessContent(innerPadding: PaddingValues, amount: Mut
             label = { Text("amount") },
             modifier = spaceModifier
         )
+        OutlinedTextField(
+            value = selectedCategory.value.name,
+            onValueChange = {},
+            label = { Text("Category") },
+            trailingIcon = {
+                IconButton(onClick = { showDropdown.value = true }) {
+                    Icon(Icons.Filled.ArrowDropDown, contentDescription = null)
+                }
+            },
+            readOnly = true
+        )
+        DropdownMenu(
+            expanded = showDropdown.value,
+            onDismissRequest = { showDropdown.value = false }
+        ) {
+            categories.forEach { category ->
+                DropdownMenuItem(onClick = {
+                    selectedCategory.value = category
+                    showDropdown.value = false
+                }, text = {
+                    Text(category.name)
+                })
+            }
+        }
     }
 }
\ No newline at end of file
diff --git a/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/transactions/TransactionDetailViewModel.kt b/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/transactions/TransactionDetailViewModel.kt
index e3271b5..1b96a25 100644
--- a/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/transactions/TransactionDetailViewModel.kt
+++ b/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/transactions/TransactionDetailViewModel.kt
@@ -46,14 +46,15 @@ class TransactionDetailViewModel(
         transactionId = id
     }
     fun saveTransaction(
-        amount: BigDecimal
+        amount: BigDecimal,
+        category: Category
     ) {
         viewModelScope.launch {
             transactionRepository.insertTransactions(
                 Transaction(
                     id = transactionId,
                     amount = amount,
-                    categoryId = 1L
+                    categoryId = category.id
                 )
             )
         }
diff --git a/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/transactions/TransactionsScreen.kt b/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/transactions/TransactionsScreen.kt
index 4f10d61..f5687b1 100644
--- a/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/transactions/TransactionsScreen.kt
+++ b/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/transactions/TransactionsScreen.kt
@@ -101,8 +101,10 @@ fun TransactionScreenContent(
 ) {
     val sortState = remember { mutableStateOf("Don't sort") }
     val sortedTransactions = when (sortState.value) {
-        "Sort by Amount" -> transactions.sortedBy { it.transaction.amount }
-        "Sort by Date" -> transactions.sortedBy { it.transaction.dateCreated }
+        "Sort by Amount Asc." -> transactions.sortedBy { it.transaction.amount }
+        "Sort by Date Asc." -> transactions.sortedBy { it.transaction.dateCreated }
+        "Sort by Amount Desc." -> transactions.sortedByDescending { it.transaction.amount }
+        "Sort by Date Desc." -> transactions.sortedByDescending { it.transaction.dateCreated }
         else -> transactions
     }
 
@@ -127,25 +129,29 @@ fun TransactionScreenContent(
 @Composable
 fun SortDropdown(sortState: MutableState<String>) {
     var expanded by remember { mutableStateOf(false) }
-    val options = listOf("Don't sort", "Sort by Amount", "Sort by Date")
+    val options = listOf("Don't sort", "Sort by Amount Asc.", "Sort by Date Asc.", "Sort by Amount Desc.", "Sort by Date Desc.")
 
-    Box(Modifier.clickable { expanded = true }) {
-        Text(text = sortState.value)
-        Icon(Icons.Filled.ArrowDropDown, contentDescription = "Sort options")
-        DropdownMenu(expanded = expanded, onDismissRequest = { expanded = false }) {
-            options.forEach { label ->
-                DropdownMenuItem(
-                    onClick = {
-                        sortState.value = label
-                        expanded = false
-                    },
-                    text = { Text(label) }
-                )
+    Row(verticalAlignment = Alignment.CenterVertically,
+        modifier = Modifier.clickable { expanded = true }) {
+        Box{
+            Text(text = sortState.value)
+            DropdownMenu(expanded = expanded, onDismissRequest = { expanded = false }) {
+                options.forEach { label ->
+                    DropdownMenuItem(
+                        onClick = {
+                            sortState.value = label
+                            expanded = false
+                        },
+                        text = { Text(label) }
+                    )
+                }
             }
         }
+        Icon(Icons.Filled.ArrowDropDown, contentDescription = "Sort options")
     }
 }
 
+
 @Composable
 fun TotalSumOfTransactions(transactions: List<TransactionWithCategory>) {
     val totalIncome = transactions.filter { it.category.type == CategoryType.INCOME }.sumOf { it.transaction.amount }
@@ -200,8 +206,10 @@ fun TransactionsList(
         }
     }
 }
+
 @Composable
 fun TransactionItem(transaction: Transaction, category: Category, navController: NavHostController) {
+    var showMenu by remember { mutableStateOf(false) }
     Row(
         modifier = Modifier
             .fillMaxWidth()
@@ -209,17 +217,34 @@ fun TransactionItem(transaction: Transaction, category: Category, navController:
             .border(1.dp, Color.Gray, shape = RoundedCornerShape(3.dp))
             .clickable { navController.navigate("${FinanceManagementScreens.TransactionsDetail.name}/${transaction.id}") }
             .padding(8.dp)
-            , horizontalArrangement = Arrangement.SpaceBetween
+        , horizontalArrangement = Arrangement.SpaceBetween
     ) {
         Column {
-            Text(text = category.name.toString(), style = TextStyle(fontSize = 16.sp, fontWeight = FontWeight.Bold))
+            Text(text = category.name, style = TextStyle(fontSize = 16.sp, fontWeight = FontWeight.Bold))
             Text(
                 text = if (category.type == CategoryType.EXPENSE) "-${transaction.amount}" else transaction.amount.toString(),
                 color = getCategoryColor(category),
                 style = TextStyle(fontSize = 16.sp, fontWeight = FontWeight.Bold)
             ) }
-        IconButton(onClick = { /* Handle click event here */ }) {
-            Icon(Icons.Filled.MoreVert, contentDescription = "Options")
+        Box {
+            IconButton(onClick = { showMenu = true }) {
+                Icon(Icons.Filled.MoreVert, contentDescription = "Options")
+            }
+            DropdownMenu(
+                expanded = showMenu,
+                onDismissRequest = { showMenu = false }
+            ) {
+                DropdownMenuItem(onClick = {
+                    navController.navigate("${FinanceManagementScreens.EditTransaction.name}/${transaction.id}")
+                    showMenu = false
+                }, text = { Text("Edit") }
+                )
+                DropdownMenuItem(onClick = {
+                    // Handle delete transaction here
+                    // transactionViewModel.deleteTransaction(transaction.id)
+                    showMenu = false
+                }, text = { Text("Delete")})
+            }
         }
     }
 }
-- 
GitLab


From de90814ca1d6e4a8fe56b91514de643950700824 Mon Sep 17 00:00:00 2001
From: dovicrad <dovicrad@fel.cvut.cz>
Date: Mon, 6 May 2024 23:56:08 +0200
Subject: [PATCH 12/12] :art: prettier Categories List

---
 .../transaction/TransactionRepository.kt      |  1 -
 .../ui/screens/category/CategoriesScreen.kt   | 44 +++++++++++++++++--
 .../ui/screens/category/EditCategoryScreen.kt |  1 -
 3 files changed, 41 insertions(+), 5 deletions(-)

diff --git a/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/operation/transaction/TransactionRepository.kt b/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/operation/transaction/TransactionRepository.kt
index 1576e07..6093e05 100644
--- a/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/operation/transaction/TransactionRepository.kt
+++ b/app/src/main/java/cz/cvut/fel/pda/financemanagement/database/operation/transaction/TransactionRepository.kt
@@ -3,7 +3,6 @@ package cz.cvut.fel.pda.financemanagement.database.operation.transaction
 import cz.cvut.fel.pda.financemanagement.model.CategoryWithTransactions
 import cz.cvut.fel.pda.financemanagement.model.TransactionWithCategory
 import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.map
 
 interface TransactionRepository {
     fun getAllTransactionsStream(): Flow<List<Transaction>>
diff --git a/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/category/CategoriesScreen.kt b/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/category/CategoriesScreen.kt
index 6f27a75..7064074 100644
--- a/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/category/CategoriesScreen.kt
+++ b/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/category/CategoriesScreen.kt
@@ -1,22 +1,31 @@
 package cz.cvut.fel.pda.financemanagement.ui.screens.category
 
 import androidx.compose.foundation.clickable
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.Column
 import androidx.compose.foundation.layout.PaddingValues
 import androidx.compose.foundation.layout.Row
-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.material.icons.Icons
 import androidx.compose.material.icons.filled.Add
+import androidx.compose.material.icons.filled.MoreVert
+import androidx.compose.material3.DropdownMenu
+import androidx.compose.material3.DropdownMenuItem
 import androidx.compose.material3.FloatingActionButton
 import androidx.compose.material3.HorizontalDivider
 import androidx.compose.material3.Icon
+import androidx.compose.material3.IconButton
 import androidx.compose.material3.Scaffold
 import androidx.compose.material3.Text
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
+import androidx.compose.runtime.setValue
+import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.text.TextStyle
 import androidx.compose.ui.text.font.FontWeight
@@ -101,7 +110,36 @@ fun CategoriesList(categories: List<Category>, navController: NavHostController)
 
 @Composable
 fun CategoryItem(category: Category, navController: NavHostController) {
-    Row(modifier = Modifier.padding(8.dp).clickable { navController.navigate("${FinanceManagementScreens.CategoryDetail}/${category.id}")}){
-        Text(text = category.name.toString().lowercase().replaceFirstChar { it.titlecase(Locale.ROOT)})
+    var showMenu by remember { mutableStateOf(false) }
+
+    Row(
+        modifier = Modifier.padding(8.dp).clickable { navController.navigate("${FinanceManagementScreens.CategoryDetail}/${category.id}") },
+        horizontalArrangement = Arrangement.SpaceBetween,
+        verticalAlignment = Alignment.CenterVertically
+    ) {
+        Text(
+            text = category.name.lowercase().replaceFirstChar { it.titlecase(Locale.ROOT) },
+            modifier = Modifier.weight(1f)
+        )
+        Box(modifier = Modifier.weight(1f)) {
+            IconButton(onClick = { showMenu = true }) {
+                Icon(Icons.Filled.MoreVert, contentDescription = "Options")
+            }
+            DropdownMenu(
+                expanded = showMenu,
+                onDismissRequest = { showMenu = false }
+            ) {
+                DropdownMenuItem(onClick = {
+                    navController.navigate("${FinanceManagementScreens.EditCategory.name}/${category.id}")
+                    showMenu = false
+                }, text = { Text("Edit") }
+                )
+                DropdownMenuItem(onClick = {
+                    // Handle delete transaction here
+                    // transactionViewModel.deleteTransaction(transaction.id)
+                    showMenu = false
+                }, text = { Text("Delete")})
+            }
+        }
     }
 }
diff --git a/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/category/EditCategoryScreen.kt b/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/category/EditCategoryScreen.kt
index 1c16eb8..601bc48 100644
--- a/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/category/EditCategoryScreen.kt
+++ b/app/src/main/java/cz/cvut/fel/pda/financemanagement/ui/screens/category/EditCategoryScreen.kt
@@ -1,6 +1,5 @@
 package cz.cvut.fel.pda.financemanagement.ui.screens.category
 
-import androidx.compose.foundation.border
 import androidx.compose.foundation.layout.Column
 import androidx.compose.foundation.layout.PaddingValues
 import androidx.compose.foundation.layout.fillMaxWidth
-- 
GitLab