diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 6f6b4a6508b015f0f355760ab2f5ee9a6b26d983..ba3d673f0c73cade4a1404107aaeacbf88fbcaa3 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -4,6 +4,7 @@ plugins { id("androidx.navigation.safeargs.kotlin") id("kotlin-android") id ("kotlin-kapt") + id ("com.google.dagger.hilt.android") } android { @@ -68,6 +69,9 @@ dependencies { testImplementation("junit:junit:4.13.2") androidTestImplementation("androidx.test.ext:junit:1.1.5") androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1") + implementation ("androidx.activity:activity-ktx") + implementation ("androidx.lifecycle:lifecycle-viewmodel-ktx") + implementation ("androidx.hilt:hilt-navigation-compose:1.2.0") //api implementation("com.squareup.retrofit2:retrofit:2.9.0") @@ -80,11 +84,17 @@ dependencies { implementation("androidx.room:room-runtime:$roomVersion") annotationProcessor("androidx.room:room-compiler:$roomVersion") implementation("androidx.room:room-ktx:$roomVersion") - kapt("androidx.room:room-compiler:$roomVersion") + kapt ("androidx.room:room-compiler:$roomVersion") + implementation ("com.google.dagger:hilt-android:2.51.1") + kapt ("com.google.dagger:hilt-compiler:2.51.1") //chart implementation("androidx.multidex:multidex:2.0.1") implementation ("com.github.PhilJay:MPAndroidChart:v3.1.0") +} + +kapt { + correctErrorTypes=true } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index ff6f987a152208ca9cf5e204aae5ae5310903879..e91049ca88dc03240700f528604b14485506a2c6 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:tools="http://schemas.android.com/tools" > + xmlns:tools="http://schemas.android.com/tools"> <uses-feature android:name="android.hardware.camera.any" /> @@ -11,6 +11,7 @@ <uses-permission android:name="android.permission.CAMERA" /> <application + android:name=".MainApp" android:allowBackup="true" android:dataExtractionRules="@xml/data_extraction_rules" android:fullBackupContent="@xml/backup_rules" @@ -18,9 +19,11 @@ android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" - android:name="androidx.multidex.MultiDexApplication" android:theme="@style/Theme.PSI" - tools:targetApi="31" > + tools:targetApi="31"> + <activity + android:name=".TransactionDetailActivity" + android:exported="false" /> <activity android:name=".AddTransactionActivity" android:exported="false" /> @@ -29,7 +32,7 @@ android:exported="false" /> <activity android:name=".SplashActivity" - android:exported="true" > + android:exported="true"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <action android:name="android.intent.action.VIEW" /> diff --git a/app/src/main/java/com/pbd/psi/AddTransactionActivity.kt b/app/src/main/java/com/pbd/psi/AddTransactionActivity.kt index 2832a65587e5ac86648744f7abc4b63f3bd8fc8c..82c0fb8404eebc204bc0cd109551392fd0cb2029 100644 --- a/app/src/main/java/com/pbd/psi/AddTransactionActivity.kt +++ b/app/src/main/java/com/pbd/psi/AddTransactionActivity.kt @@ -4,7 +4,9 @@ import androidx.appcompat.app.AppCompatActivity import android.os.Bundle import com.pbd.psi.databinding.ActivityAddTransactionBinding import com.pbd.psi.ui.add_transaction.AddTransactionFragment +import dagger.hilt.android.AndroidEntryPoint +@AndroidEntryPoint class AddTransactionActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -14,7 +16,7 @@ class AddTransactionActivity : AppCompatActivity() { val fragment = AddTransactionFragment() supportFragmentManager .beginTransaction() - .replace(R.id.placeholderForm, fragment) + .replace(binding.placeholderForm.id, fragment) .commit() binding.backButtonAdd.setOnClickListener{ diff --git a/app/src/main/java/com/pbd/psi/MainActivity.kt b/app/src/main/java/com/pbd/psi/MainActivity.kt index 3413b39200bc98457d5c0378aa5511d4d80d2455..f70ed410ddf326e3a8c7a2d96f8f51caac2c5b00 100644 --- a/app/src/main/java/com/pbd/psi/MainActivity.kt +++ b/app/src/main/java/com/pbd/psi/MainActivity.kt @@ -17,7 +17,9 @@ import com.google.android.material.bottomnavigation.BottomNavigationView import com.pbd.psi.databinding.ActivityMainBinding import com.pbd.psi.databinding.FragmentSettingsBinding import com.pbd.psi.services.BackgroundService +import dagger.hilt.android.AndroidEntryPoint +@AndroidEntryPoint class MainActivity : AppCompatActivity() { companion object { const val SHARED_PREFS = "shared_prefs" diff --git a/app/src/main/java/com/pbd/psi/MainApp.kt b/app/src/main/java/com/pbd/psi/MainApp.kt new file mode 100644 index 0000000000000000000000000000000000000000..a03cde5b8511f8d378d68ae0364543f72871f862 --- /dev/null +++ b/app/src/main/java/com/pbd/psi/MainApp.kt @@ -0,0 +1,8 @@ +package com.pbd.psi +import android.app.Application +import dagger.hilt.android.HiltAndroidApp + +@HiltAndroidApp +class MainApp: Application(){ + +} \ No newline at end of file diff --git a/app/src/main/java/com/pbd/psi/TransactionDetailActivity.kt b/app/src/main/java/com/pbd/psi/TransactionDetailActivity.kt new file mode 100644 index 0000000000000000000000000000000000000000..e2eae49a3e7bd5c715cba3825a3a7392cb1da2cd --- /dev/null +++ b/app/src/main/java/com/pbd/psi/TransactionDetailActivity.kt @@ -0,0 +1,32 @@ +package com.pbd.psi + +import androidx.appcompat.app.AppCompatActivity +import android.os.Bundle +import androidx.activity.viewModels +import androidx.lifecycle.LiveData +import androidx.lifecycle.Observer +import com.pbd.psi.databinding.ActivityTransactionDetailBinding +import com.pbd.psi.room.TransactionEntity +import com.pbd.psi.ui.transaction_detail.TransactionDetailViewModel +import dagger.hilt.android.AndroidEntryPoint + +@AndroidEntryPoint +class TransactionDetailActivity : AppCompatActivity() { + + private val viewModel: TransactionDetailViewModel by viewModels() + private lateinit var transactionInfo:LiveData<TransactionEntity> + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + val binding = ActivityTransactionDetailBinding.inflate(layoutInflater) + setContentView(binding.root) + + val intent = intent + val itemId = intent.getIntExtra("id", -1) + transactionInfo = viewModel.getTransById(itemId) + transactionInfo.observe(this, Observer { trans -> + binding.updateName.setText(trans.name) + }) + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/pbd/psi/repository/ScanRepository.kt b/app/src/main/java/com/pbd/psi/repository/ScanRepository.kt index 457a8f11b5b0a0c932980509ba98f8b997523d43..a7750209a3becc7ffb721bdaf1d6bf365f621518 100644 --- a/app/src/main/java/com/pbd/psi/repository/ScanRepository.kt +++ b/app/src/main/java/com/pbd/psi/repository/ScanRepository.kt @@ -3,8 +3,9 @@ package com.pbd.psi.repository import androidx.lifecycle.LiveData import com.pbd.psi.room.AppDatabase import com.pbd.psi.room.TransactionEntity +import javax.inject.Inject -class ScanRepository(private val database: AppDatabase) { +class ScanRepository @Inject constructor(private val database: AppDatabase) { val transactionList: LiveData<List<TransactionEntity>> = database.transactionDao().getAllTrans() diff --git a/app/src/main/java/com/pbd/psi/repository/TransactionRepository.kt b/app/src/main/java/com/pbd/psi/repository/TransactionRepository.kt index 33f3c342ebaae0c80a9f1257296d7cf6e17a2ead..427c134a2910f311a84a221fd2506e87474072b5 100644 --- a/app/src/main/java/com/pbd/psi/repository/TransactionRepository.kt +++ b/app/src/main/java/com/pbd/psi/repository/TransactionRepository.kt @@ -1,19 +1,21 @@ package com.pbd.psi.repository import androidx.lifecycle.LiveData +import androidx.lifecycle.MutableLiveData import com.pbd.psi.room.AppDatabase import com.pbd.psi.room.TransactionEntity +import javax.inject.Inject -class TransactionRepository(private val database: AppDatabase) { +class TransactionRepository @Inject constructor(private val database: AppDatabase) { val transactionList: LiveData<List<TransactionEntity>> = database.transactionDao().getAllTrans() - fun getTransById(id: Int){ - database.transactionDao().getTransById(id) + fun getTransById(id: Int):LiveData<TransactionEntity> { + return database.transactionDao().getTransById(id) } suspend fun addTransaction(transaction: TransactionEntity) { - database.transactionDao().addTransaction(transaction) + database.transactionDao().addTransaction(transaction) } suspend fun updateTransaction(transaction: TransactionEntity) { diff --git a/app/src/main/java/com/pbd/psi/room/AppDatabase.kt b/app/src/main/java/com/pbd/psi/room/AppDatabase.kt index 5618357d314912f972a9e2767a1e61366d7abccc..831d99beaff927ad90cfb6af4354ba1a2563fd7c 100644 --- a/app/src/main/java/com/pbd/psi/room/AppDatabase.kt +++ b/app/src/main/java/com/pbd/psi/room/AppDatabase.kt @@ -1,37 +1,13 @@ package com.pbd.psi.room import androidx.room.Database -import androidx.room.Room import androidx.room.RoomDatabase -import android.content.Context -import androidx.room.TypeConverter import androidx.room.TypeConverters -@Database(entities = [TransactionEntity::class], version = 1) +@Database(entities = [TransactionEntity::class], version = 1, exportSchema = false) @TypeConverters(Converters::class) -abstract class AppDatabase() : RoomDatabase() { +abstract class AppDatabase : RoomDatabase() { abstract fun transactionDao(): TransactionDao - companion object { - @Volatile - private var Instance: AppDatabase? = null - - fun getDatabase(context: Context): AppDatabase{ - synchronized(this){ - var instance = Instance - - if (instance == null) { - instance = Room.databaseBuilder( - context.applicationContext, - AppDatabase::class.java, - "app_database" - ).build() - Instance = instance - } - - return instance - } - } - } } diff --git a/app/src/main/java/com/pbd/psi/room/DatabaseModule.kt b/app/src/main/java/com/pbd/psi/room/DatabaseModule.kt new file mode 100644 index 0000000000000000000000000000000000000000..a99e2fde75f6dab286ba0a0d2a4d60435438f990 --- /dev/null +++ b/app/src/main/java/com/pbd/psi/room/DatabaseModule.kt @@ -0,0 +1,33 @@ +package com.pbd.psi.room + +import android.app.Application +import android.content.Context +import androidx.room.Room +import com.pbd.psi.repository.TransactionRepository +import dagger.Module +import dagger.Provides +import dagger.hilt.InstallIn +import dagger.hilt.android.qualifiers.ApplicationContext +import dagger.hilt.components.SingletonComponent +import javax.inject.Singleton + +@Module +@InstallIn(SingletonComponent::class) +object DatabaseModule { + @Provides + @Singleton + fun provideAppDatabase(@ApplicationContext app: Context): AppDatabase { + return Room.databaseBuilder( + app, + AppDatabase::class.java, + "resto_db", + ) + .fallbackToDestructiveMigration() + .build() + } + + @Provides + @Singleton + fun provideTransactionDao(db: AppDatabase) = db.transactionDao() + +} \ No newline at end of file diff --git a/app/src/main/java/com/pbd/psi/room/TransactionDao.kt b/app/src/main/java/com/pbd/psi/room/TransactionDao.kt index b052ffc021876e4fde6d937958dbbacf4464231b..0c78ab639cdef4077e29dd4881f6e9ff85fa2b6a 100644 --- a/app/src/main/java/com/pbd/psi/room/TransactionDao.kt +++ b/app/src/main/java/com/pbd/psi/room/TransactionDao.kt @@ -1,6 +1,7 @@ package com.pbd.psi.room import androidx.lifecycle.LiveData +import androidx.lifecycle.MutableLiveData import androidx.room.Dao import androidx.room.Delete import androidx.room.Insert @@ -12,8 +13,8 @@ interface TransactionDao { @Query("SELECT * FROM transactionTable") fun getAllTrans(): LiveData<List<TransactionEntity>> - @Query("SELECT * FROM transactionTable WHERE id=:id") - fun getTransById(id: Int): TransactionEntity + @Query("SELECT * FROM transactionTable WHERE id=:id LIMIT 1") + fun getTransById(id: Int): LiveData<TransactionEntity> @Insert(onConflict = OnConflictStrategy.ABORT) suspend fun addTransaction(trans: TransactionEntity) diff --git a/app/src/main/java/com/pbd/psi/room/TransactionEntity.kt b/app/src/main/java/com/pbd/psi/room/TransactionEntity.kt index 4c2bcbe46222ed145179549dd8664ef399a164b9..37c876f8687cb0727efe4b93b919ad9b6599c60c 100644 --- a/app/src/main/java/com/pbd/psi/room/TransactionEntity.kt +++ b/app/src/main/java/com/pbd/psi/room/TransactionEntity.kt @@ -3,6 +3,7 @@ package com.pbd.psi.room import androidx.room.ColumnInfo import androidx.room.Entity import androidx.room.PrimaryKey +import java.io.Serializable import java.util.Date diff --git a/app/src/main/java/com/pbd/psi/ui/add_transaction/AddTransactionFragment.kt b/app/src/main/java/com/pbd/psi/ui/add_transaction/AddTransactionFragment.kt index 99a6cbeaa37d981e1b98a61e96bb3d29a4f0d839..794ffce576fd80d51d1f600b7e1a00537bc1ba6a 100644 --- a/app/src/main/java/com/pbd/psi/ui/add_transaction/AddTransactionFragment.kt +++ b/app/src/main/java/com/pbd/psi/ui/add_transaction/AddTransactionFragment.kt @@ -7,27 +7,33 @@ import android.view.View import android.view.ViewGroup import android.widget.EditText import android.widget.Toast +import androidx.fragment.app.viewModels +import androidx.hilt.navigation.compose.hiltViewModel +import androidx.lifecycle.ViewModel +import androidx.lifecycle.ViewModelProvider import com.pbd.psi.R import com.pbd.psi.databinding.FragmentAddTransactionBinding import com.pbd.psi.repository.TransactionRepository import com.pbd.psi.room.AppDatabase import com.pbd.psi.room.Category +import dagger.hilt.android.AndroidEntryPoint +@AndroidEntryPoint class AddTransactionFragment : Fragment() { - - private lateinit var binding: FragmentAddTransactionBinding - + private var _binding: FragmentAddTransactionBinding? = null + private val binding get() = _binding!! + private val viewModel: AddTransactionViewModel by viewModels() override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View { - binding = FragmentAddTransactionBinding.inflate(inflater, container, false) + _binding = FragmentAddTransactionBinding.inflate(inflater, container, false) return binding.root } - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - super.onViewCreated(view, savedInstanceState) + override fun onStart() { + super.onStart() binding.submitButton.setOnClickListener{ val inputName = binding.titleInput.text.toString() val inputAmountStr = binding.amountInput.text.toString() @@ -35,18 +41,18 @@ class AddTransactionFragment : Fragment() { // Check if inputAmountStr is empty or not a valid integer if (inputAmountStr.isNotEmpty()) { val inputAmount = inputAmountStr.toInt() - val appDatabase = AppDatabase.getDatabase(requireContext()) - val repository = TransactionRepository(appDatabase) - val viewModel = AddTransactionViewModel(repository) viewModel.addTransaction(inputName, Category.EXPENSE, inputAmount) - Toast.makeText(requireContext(), "success", Toast.LENGTH_SHORT).show() + } else { // Handle case where amount input is empty Toast.makeText(requireContext(), "Please enter a valid amount", Toast.LENGTH_SHORT).show() } } - } + override fun onDestroyView() { + super.onDestroyView() + _binding = null + } } \ No newline at end of file diff --git a/app/src/main/java/com/pbd/psi/ui/add_transaction/AddTransactionViewModel.kt b/app/src/main/java/com/pbd/psi/ui/add_transaction/AddTransactionViewModel.kt index 692dcdee42b29a7ccf3271e928196b086e62598b..af1b58b95c22938911cc7f332f40421eb4e79b37 100644 --- a/app/src/main/java/com/pbd/psi/ui/add_transaction/AddTransactionViewModel.kt +++ b/app/src/main/java/com/pbd/psi/ui/add_transaction/AddTransactionViewModel.kt @@ -2,14 +2,23 @@ package com.pbd.psi.ui.add_transaction import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel +import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.viewModelScope import com.pbd.psi.repository.TransactionRepository import com.pbd.psi.room.Category import com.pbd.psi.room.TransactionEntity +import dagger.hilt.android.lifecycle.HiltViewModel +import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import java.time.LocalDateTime import java.util.Date -class AddTransactionViewModel(private val repository: TransactionRepository) : ViewModel() { +import javax.inject.Inject + +@HiltViewModel +class AddTransactionViewModel + @Inject constructor( + private val repository: TransactionRepository + ) : ViewModel() { fun addTransaction(name: String, category: Category, amount: Int) = viewModelScope.launch { val curDate = Date() val transaction = TransactionEntity(0, name, category, amount, curDate, "dummy location", 10.0, 10.0) diff --git a/app/src/main/java/com/pbd/psi/ui/scan/ScanFragment.kt b/app/src/main/java/com/pbd/psi/ui/scan/ScanFragment.kt index b7b3c9cb2c6bc46cabee628c24f383975c944b98..d4877576f50b73d98a53ede999ba3cab49fa5f85 100644 --- a/app/src/main/java/com/pbd/psi/ui/scan/ScanFragment.kt +++ b/app/src/main/java/com/pbd/psi/ui/scan/ScanFragment.kt @@ -25,13 +25,12 @@ import androidx.camera.lifecycle.ProcessCameraProvider import androidx.core.content.ContextCompat import androidx.core.view.isVisible import androidx.fragment.app.Fragment +import androidx.fragment.app.viewModels import com.google.gson.Gson import com.pbd.psi.LoginActivity import com.pbd.psi.api.ApiConfig import com.pbd.psi.databinding.FragmentScanBinding import com.pbd.psi.models.UploadRes -import com.pbd.psi.repository.ScanRepository -import com.pbd.psi.room.AppDatabase import com.pbd.psi.room.TransactionEntity import okhttp3.MediaType.Companion.toMediaTypeOrNull import okhttp3.MultipartBody @@ -42,14 +41,16 @@ import retrofit2.Callback import retrofit2.Response import androidx.navigation.fragment.findNavController import com.pbd.psi.room.Category +import dagger.hilt.android.AndroidEntryPoint import java.io.ByteArrayOutputStream import java.util.Date +@AndroidEntryPoint class ScanFragment : Fragment() { private var _binding: FragmentScanBinding? = null private val binding get() = _binding!! - + private val viewModel: ScanViewModel by viewModels() private var imageCapture: ImageCapture? = null private var previewFrozen: Boolean = false @@ -215,9 +216,6 @@ class ScanFragment : Fragment() { Log.d("ResponseString", "Response: $responseString") Toast.makeText(requireContext(), "Image uploaded successfully! Response: $responseString", Toast.LENGTH_LONG).show() try { - val appDatabase = AppDatabase.getDatabase(requireContext()) - val repository = ScanRepository(appDatabase) - val viewModel = ScanViewModel(repository) val scanData = parseScanData(responseString) for (item in scanData?.items?.items ?: emptyList()) { val curDate = Date() diff --git a/app/src/main/java/com/pbd/psi/ui/scan/ScanViewModel.kt b/app/src/main/java/com/pbd/psi/ui/scan/ScanViewModel.kt index 066659bf2887490441609dbd4dcb37454536317a..1eec7e11b96ea7440e429d47a306d2950edf0cd0 100644 --- a/app/src/main/java/com/pbd/psi/ui/scan/ScanViewModel.kt +++ b/app/src/main/java/com/pbd/psi/ui/scan/ScanViewModel.kt @@ -4,9 +4,12 @@ import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.pbd.psi.repository.ScanRepository import com.pbd.psi.room.TransactionEntity +import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.launch +import javax.inject.Inject -class ScanViewModel(private val repository: ScanRepository) : ViewModel() { +@HiltViewModel +class ScanViewModel @Inject constructor(private val repository: ScanRepository) : ViewModel() { fun addTransaction(transactionEntity: TransactionEntity) { viewModelScope.launch { repository.addTransaction(transactionEntity) diff --git a/app/src/main/java/com/pbd/psi/ui/scan/ScanViewModelFactory.kt b/app/src/main/java/com/pbd/psi/ui/scan/ScanViewModelFactory.kt deleted file mode 100644 index d92111774d7c7c744c50094ab9a11f9cf27fd6fb..0000000000000000000000000000000000000000 --- a/app/src/main/java/com/pbd/psi/ui/scan/ScanViewModelFactory.kt +++ /dev/null @@ -1,15 +0,0 @@ -import androidx.lifecycle.ViewModel -import androidx.lifecycle.ViewModelProvider -import com.pbd.psi.repository.ScanRepository -import com.pbd.psi.ui.scan.ScanViewModel - -class ScanViewModelFactory(private val repository: ScanRepository) : ViewModelProvider.Factory { - - override fun <T : ViewModel> create(modelClass: Class<T>): T { - if (modelClass.isAssignableFrom(ScanViewModel::class.java)) { - @Suppress("UNCHECKED_CAST") - return ScanViewModel(repository) as T - } - throw IllegalArgumentException("Unknown ViewModel class") - } -} diff --git a/app/src/main/java/com/pbd/psi/ui/transaction/TransactionFragment.kt b/app/src/main/java/com/pbd/psi/ui/transaction/TransactionFragment.kt index 1abb08b0f3b7eea593d32c43e44afcec915c62f3..f9e30dd874daa0a70092501cd104cc4b2ee16dce 100644 --- a/app/src/main/java/com/pbd/psi/ui/transaction/TransactionFragment.kt +++ b/app/src/main/java/com/pbd/psi/ui/transaction/TransactionFragment.kt @@ -2,31 +2,31 @@ package com.pbd.psi.ui.transaction import android.content.Intent import android.os.Bundle +import android.util.Log import androidx.fragment.app.Fragment import android.view.LayoutInflater import android.view.View import android.view.ViewGroup -import android.widget.LinearLayout import androidx.fragment.app.viewModels +import androidx.navigation.navGraphViewModels import androidx.recyclerview.widget.LinearLayoutManager import com.pbd.psi.AddTransactionActivity -import com.pbd.psi.R +import com.pbd.psi.TransactionDetailActivity import com.pbd.psi.databinding.FragmentTransactionBinding import com.pbd.psi.repository.TransactionRepository import com.pbd.psi.room.AppDatabase +import dagger.hilt.android.AndroidEntryPoint +@AndroidEntryPoint class TransactionFragment : Fragment() { private lateinit var binding: FragmentTransactionBinding private val transactionAdapter by lazy { TransactionViewAdapter() } - + private val viewModel: TransactionViewModel by viewModels() override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View { binding = FragmentTransactionBinding.inflate(inflater, container, false) - val appDatabase = AppDatabase.getDatabase(requireContext()) - val repository = TransactionRepository(appDatabase) - val viewModel = TransactionViewModel(repository) viewModel.transactionList.observe(viewLifecycleOwner) { transItems -> val transactions = requireNotNull(transItems) { "Transaction list is null" } val transList = ArrayList(transactions) @@ -42,6 +42,14 @@ class TransactionFragment : Fragment() { layoutManager = LinearLayoutManager(context) adapter = transactionAdapter } + transactionAdapter.itemClickListener = { view, item -> + Log.d("woy tot", "cuy cuy") + val intent = Intent(requireContext(), TransactionDetailActivity::class.java).apply { + putExtra("id", item) + } + startActivity(intent) + + } binding.addButton.setOnClickListener{ val intent = Intent(requireContext(), AddTransactionActivity::class.java) startActivity(intent) diff --git a/app/src/main/java/com/pbd/psi/ui/transaction/TransactionViewAdapter.kt b/app/src/main/java/com/pbd/psi/ui/transaction/TransactionViewAdapter.kt index 00ee32701eda0351bbc8aee7b71ba5e235f8a4ee..7229bd28802983fa16035f46b91fc6dca36038a5 100644 --- a/app/src/main/java/com/pbd/psi/ui/transaction/TransactionViewAdapter.kt +++ b/app/src/main/java/com/pbd/psi/ui/transaction/TransactionViewAdapter.kt @@ -1,6 +1,9 @@ package com.pbd.psi.ui.transaction +import android.content.Intent import android.view.LayoutInflater +import android.view.View +import android.view.View.OnClickListener import android.view.ViewGroup import androidx.recyclerview.widget.RecyclerView import com.pbd.psi.R @@ -13,10 +16,14 @@ import java.lang.IllegalArgumentException class TransactionViewAdapter : RecyclerView.Adapter<TransactionViewHolder>() { var transactionItems = arrayListOf<TransactionEntity>() + set(value) { field = value notifyDataSetChanged() } + + var itemClickListener: ((view: View,item: Int) -> Unit)? = null + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TransactionViewHolder { when(viewType){ R.layout.income_card -> return TransactionViewHolder.IncomeViewHolder( @@ -39,15 +46,18 @@ class TransactionViewAdapter : RecyclerView.Adapter<TransactionViewHolder>() { } override fun onBindViewHolder(holder: TransactionViewHolder, position: Int) { + holder.itemClickListener = itemClickListener when(holder){ is TransactionViewHolder.IncomeViewHolder -> holder.bind( + transactionItems[position].id, transactionItems[position].name, transactionItems[position].date.toString(), transactionItems[position].amount ) - is TransactionViewHolder.ExpenseViewHolder -> + is TransactionViewHolder.ExpenseViewHolder -> { holder.bind( + transactionItems[position].id, transactionItems[position].name, transactionItems[position].date.toString(), transactionItems[position].amount, @@ -55,6 +65,7 @@ class TransactionViewAdapter : RecyclerView.Adapter<TransactionViewHolder>() { transactionItems[position].longitude, transactionItems[position].latitude, ) + } } } diff --git a/app/src/main/java/com/pbd/psi/ui/transaction/TransactionViewHolder.kt b/app/src/main/java/com/pbd/psi/ui/transaction/TransactionViewHolder.kt index 40085d38eeb2907a145fda793e7e834f33cb1942..ee1cdbf01ec761e69fc014468d56921a023127e3 100644 --- a/app/src/main/java/com/pbd/psi/ui/transaction/TransactionViewHolder.kt +++ b/app/src/main/java/com/pbd/psi/ui/transaction/TransactionViewHolder.kt @@ -1,16 +1,24 @@ package com.pbd.psi.ui.transaction +import android.content.Context import android.content.Intent import android.net.Uri +import android.view.View import android.widget.Toast import androidx.recyclerview.widget.RecyclerView import androidx.viewbinding.ViewBinding +import com.pbd.psi.AddTransactionActivity +import com.pbd.psi.TransactionDetailActivity import com.pbd.psi.databinding.ExpenseCardBinding import com.pbd.psi.databinding.IncomeCardBinding +import com.pbd.psi.room.TransactionEntity sealed class TransactionViewHolder(binding: ViewBinding) : RecyclerView.ViewHolder(binding.root) { + + var itemClickListener: ((view: View, item: Int) -> Unit)? = null + class ExpenseViewHolder(private val binding: ExpenseCardBinding) : TransactionViewHolder(binding){ - fun bind(name: String, date: String, nominal: Int, location: String, longitude: Double, latitude: Double){ + fun bind(id: Int,name: String, date: String, nominal: Int, location: String, longitude: Double, latitude: Double){ binding.expenseName.text = name binding.expenseDate.text = date binding.expenseNominal.text = "-Rp".plus(nominal.formatDecimalSeparator()) @@ -26,18 +34,25 @@ sealed class TransactionViewHolder(binding: ViewBinding) : RecyclerView.ViewHold Toast.makeText(locationContext, "Please install google maps to access location", Toast.LENGTH_SHORT).show(); } } - } + binding.root.setOnClickListener { + itemClickListener?.invoke(it, id) + } + } } class IncomeViewHolder(private val binding: IncomeCardBinding) : TransactionViewHolder(binding) { - fun bind(name: String, date: String, nominal: Int){ + fun bind(id: Int,name: String, date: String, nominal: Int){ binding.incomeName.text = name binding.incomeDate.text = date binding.incomeNominal.text = "Rp".plus(nominal.formatDecimalSeparator()) + binding.root.setOnClickListener { + itemClickListener?.invoke(it, id) + } } } + protected fun Int.formatDecimalSeparator(): String { return toString().reversed().chunked(3).joinToString(".").reversed() } diff --git a/app/src/main/java/com/pbd/psi/ui/transaction/TransactionViewModel.kt b/app/src/main/java/com/pbd/psi/ui/transaction/TransactionViewModel.kt index 82d73e99e87706ecb12f6f712c0819e71fb5b854..161f7c054f2c57664abe60290c37ec54f84ffdad 100644 --- a/app/src/main/java/com/pbd/psi/ui/transaction/TransactionViewModel.kt +++ b/app/src/main/java/com/pbd/psi/ui/transaction/TransactionViewModel.kt @@ -5,23 +5,14 @@ import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.pbd.psi.repository.TransactionRepository import com.pbd.psi.room.TransactionEntity +import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.launch +import javax.inject.Inject -class TransactionViewModel( + +@HiltViewModel +class TransactionViewModel @Inject constructor( private val repository: TransactionRepository, ) : ViewModel() { var transactionList: LiveData<List<TransactionEntity>> = repository.transactionList - - fun getTransById(id: Int) = viewModelScope.launch { - repository.getTransById(id) - } - - fun updateTransaction(trans: TransactionEntity) = viewModelScope.launch { - repository.updateTransaction(trans) - } - - fun deleteTransaction(trans: TransactionEntity) = viewModelScope.launch { - repository.deleteTransaction(trans) - } - } \ No newline at end of file diff --git a/app/src/main/java/com/pbd/psi/ui/transaction_detail/TransactionDetailViewModel.kt b/app/src/main/java/com/pbd/psi/ui/transaction_detail/TransactionDetailViewModel.kt new file mode 100644 index 0000000000000000000000000000000000000000..5e7d1e0de6097393f962a9485340549d96584078 --- /dev/null +++ b/app/src/main/java/com/pbd/psi/ui/transaction_detail/TransactionDetailViewModel.kt @@ -0,0 +1,28 @@ +package com.pbd.psi.ui.transaction_detail + +import androidx.lifecycle.LiveData +import androidx.lifecycle.MutableLiveData +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import com.pbd.psi.repository.TransactionRepository +import com.pbd.psi.room.TransactionEntity +import dagger.hilt.android.lifecycle.HiltViewModel +import kotlinx.coroutines.launch +import javax.inject.Inject + +@HiltViewModel +class TransactionDetailViewModel @Inject constructor( + private val repository: TransactionRepository +) : ViewModel() { + fun updateTransaction(trans: TransactionEntity) = viewModelScope.launch { + repository.updateTransaction(trans) + } + + fun getTransById(id: Int): LiveData<TransactionEntity> { + return repository.getTransById(id) + } + + fun deleteTransaction(trans: TransactionEntity) = viewModelScope.launch { + repository.deleteTransaction(trans) + } +} \ No newline at end of file diff --git a/app/src/main/res/layout/activity_transaction_detail.xml b/app/src/main/res/layout/activity_transaction_detail.xml new file mode 100644 index 0000000000000000000000000000000000000000..73581ec2089cb267b0a5a4974f996f592d896717 --- /dev/null +++ b/app/src/main/res/layout/activity_transaction_detail.xml @@ -0,0 +1,84 @@ +<?xml version="1.0" encoding="utf-8"?> +<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto" + xmlns:tools="http://schemas.android.com/tools" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:orientation="vertical" + android:background="@color/primaryBlack" + tools:context=".TransactionDetailActivity"> + <com.google.android.material.appbar.AppBarLayout + android:id="@+id/transaction_detail_header" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:background="@color/primaryBlack" + app:layout_constraintBottom_toTopOf="@+id/detail_placeholder" + app:layout_constraintTop_toTopOf="parent"> + + <androidx.constraintlayout.widget.ConstraintLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginHorizontal="15dp" + android:layout_marginVertical="15dp"> + + <ImageView + android:id="@+id/back_button_detail" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:contentDescription="@string/back_button" + android:src="@drawable/back_icon" + app:layout_constraintEnd_toStartOf="@+id/add_header_text" + app:layout_constraintTop_toTopOf="parent" /> + + <TextView + android:id="@+id/add_header_text" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginStart="15dp" + android:fontFamily="@font/montserrat" + android:text="@string/detail_transaction" + android:textColor="@color/white" + android:textSize="20sp" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintStart_toEndOf="@+id/back_button_detail" + app:layout_constraintTop_toTopOf="parent" /> + </androidx.constraintlayout.widget.ConstraintLayout> + </com.google.android.material.appbar.AppBarLayout> + <FrameLayout + android:id="@+id/detail_placeholder" + android:layout_width="match_parent" + android:layout_height="0dp" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@+id/transaction_detail_header" + app:layout_constraintEnd_toEndOf="parent"> + <ImageView + android:id="@+id/update_category" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:contentDescription="@string/category_symbol" + android:src="@drawable/expense_symbol" + app:layout_constraintTop_toTopOf="parent" + android:layout_marginTop="100dp" + android:scaleType="fitCenter" /> + + <TextView + android:id="@+id/update_date" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:textAlignment="center" + app:layout_constraintTop_toBottomOf="@+id/update_category" + android:text="@string/category_symbol"/> + <EditText + android:id="@+id/update_name" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:hint="@string/title_hint" + android:autofillHints="name" + android:background="@drawable/edit_text_holder" + android:inputType="text" + android:textAlignment="center" + app:layout_constraintTop_toBottomOf="@+id/update_date" + android:text="@string/category_symbol"/> + </FrameLayout> +</androidx.constraintlayout.widget.ConstraintLayout> \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 96f586da2afa17ac25f4d658312f2d1c9b323f99..9cf64da4fb7bb53add7ac1ce630a440941451923 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -45,9 +45,13 @@ <string name="title_hint">Nama</string> <string name="amount_hint">Nominal</string> + <!-- Transaction Detail--> + <string name="detail_transaction">Detail Transaksi</string> + <!-- Content Description--> <string name="back_button">Back</string> + <string name="category_symbol">category</string> <!-- Settings--> <string name="setting_header">Setting</string> diff --git a/build.gradle.kts b/build.gradle.kts index 6a2adf508e870441a64a3bd4b798d86249ab239e..829f518295b4e4e3ff7a57c999d823e07a7fd8b0 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -10,6 +10,7 @@ buildscript { dependencies { classpath("androidx.navigation:navigation-safe-args-gradle-plugin:2.7.7") classpath("com.github.dcendents:android-maven-gradle-plugin:2.0") + classpath ("com.google.dagger:hilt-android-gradle-plugin:2.51.1") } }