diff --git a/app/src/main/java/com/onionsquad/bondoman/room/TransactionCategory.kt b/app/src/main/java/com/onionsquad/bondoman/room/TransactionCategory.kt
index a49c47934f831c523c9dea980de5a3570f1b1dd0..f37764b16572f2d510b4d0c2a12c54abae909df7 100644
--- a/app/src/main/java/com/onionsquad/bondoman/room/TransactionCategory.kt
+++ b/app/src/main/java/com/onionsquad/bondoman/room/TransactionCategory.kt
@@ -2,5 +2,6 @@ package com.onionsquad.bondoman.room
 
 enum class TransactionCategory {
     INCOME,
-    OUTCOME
+    OUTCOME,
+    UNKNOWN
 }
\ No newline at end of file
diff --git a/app/src/main/java/com/onionsquad/bondoman/ui/transaction/TransactionAdapter.kt b/app/src/main/java/com/onionsquad/bondoman/ui/transaction/TransactionAdapter.kt
new file mode 100644
index 0000000000000000000000000000000000000000..11d9bfd2ba181b7c590583959b7eafd6a14f76aa
--- /dev/null
+++ b/app/src/main/java/com/onionsquad/bondoman/ui/transaction/TransactionAdapter.kt
@@ -0,0 +1,46 @@
+package com.onionsquad.bondoman.ui.transaction
+
+import android.view.LayoutInflater
+import android.view.ViewGroup
+import androidx.recyclerview.widget.RecyclerView
+import com.onionsquad.bondoman.databinding.TransactionCardBinding
+import com.onionsquad.bondoman.room.TransactionEntity
+
+class TransactionAdapter(
+    private val viewModel: TransactionViewModel,
+    private var transactionList: List<TransactionEntity> = emptyList()
+) : RecyclerView.Adapter<TransactionAdapter.ViewHolder>() {
+
+    inner class ViewHolder(private val binding: TransactionCardBinding) : RecyclerView.ViewHolder(binding.root) {
+        fun bind(transaction: TransactionEntity) {
+            binding.titleTextView.text = transaction.title
+            binding.amountTextView.text = transaction.amount.toString()
+            binding.categoryTextView.text = transaction.category.toString()
+            binding.dateTextView.text = transaction.date.toString()
+            binding.locationTextView.text = transaction.location
+
+            binding.deleteButton.setOnClickListener {
+                viewModel.deleteTransaction(transaction)
+            }
+        }
+    }
+
+    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
+        val binding = TransactionCardBinding.inflate(LayoutInflater.from(parent.context), parent, false)
+        return ViewHolder(binding)
+    }
+
+    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
+        val transaction = transactionList[position]
+        holder.bind(transaction)
+    }
+
+    override fun getItemCount(): Int {
+        return transactionList.size
+    }
+
+    fun setTransactionList(transactionList: List<TransactionEntity>) {
+        this.transactionList = transactionList
+        notifyDataSetChanged()
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/onionsquad/bondoman/ui/transaction/TransactionFragment.kt b/app/src/main/java/com/onionsquad/bondoman/ui/transaction/TransactionFragment.kt
index 4ff1ccc32f50abe95a0e0e74e85e2595bf8997e6..7af3c31b9b13576aaee461b52885ff04ae8710f7 100644
--- a/app/src/main/java/com/onionsquad/bondoman/ui/transaction/TransactionFragment.kt
+++ b/app/src/main/java/com/onionsquad/bondoman/ui/transaction/TransactionFragment.kt
@@ -7,38 +7,60 @@ import android.view.View
 import android.view.ViewGroup
 import androidx.fragment.app.Fragment
 import androidx.lifecycle.ViewModelProvider
+import androidx.recyclerview.widget.LinearLayoutManager
 import com.onionsquad.bondoman.AddTransactionActivity
 import com.onionsquad.bondoman.databinding.FragmentTransactionBinding
 import com.onionsquad.bondoman.repository.TransactionRepository
 import com.onionsquad.bondoman.room.TransactionDatabase
 
 class TransactionFragment : Fragment() {
-
     private var _binding: FragmentTransactionBinding? = null
-
-    // This property is only valid between onCreateView and
-    // onDestroyView.
     private val binding get() = _binding!!
 
     private val database by lazy { TransactionDatabase.getInstance(requireContext().applicationContext) }
     private val repository by lazy { TransactionRepository(database.transactionDao()) }
+    private lateinit var transactionViewModel: TransactionViewModel
+    private lateinit var transactionAdapter: TransactionAdapter
 
     override fun onCreateView(
-            inflater: LayoutInflater,
-            container: ViewGroup?,
-            savedInstanceState: Bundle?
+        inflater: LayoutInflater,
+        container: ViewGroup?,
+        savedInstanceState: Bundle?
     ): View {
+        _binding = FragmentTransactionBinding.inflate(inflater, container, false)
+        return binding.root
+    }
+
+    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+        super.onViewCreated(view, savedInstanceState)
+
+        setupViewModel()
+        setupRecyclerView()
+        setupClickListeners()
+    }
+
+    private fun setupViewModel() {
         val factory = TransactionViewModelFactory(repository)
-        val transactionViewModel = ViewModelProvider(this, factory)[TransactionViewModel::class.java]
+        transactionViewModel = ViewModelProvider(this, factory)[TransactionViewModel::class.java]
 
-        _binding = FragmentTransactionBinding.inflate(inflater, container, false)
+        transactionViewModel.listTransactions.observe(viewLifecycleOwner) { transactionList ->
+            transactionAdapter.setTransactionList(transactionList)
+        }
+    }
+
+    private fun setupRecyclerView() {
+        transactionAdapter = TransactionAdapter(transactionViewModel)
+        binding.transactionList.apply {
+            layoutManager = LinearLayoutManager(context)
+            adapter = transactionAdapter
+        }
+    }
 
-        binding.button.setOnClickListener {
+    private fun setupClickListeners() {
+        binding.addTransactionButton.setOnClickListener {
             val intent = Intent(activity, AddTransactionActivity::class.java)
             startActivity(intent)
         }
-
-        return binding.root
     }
 
     override fun onDestroyView() {
diff --git a/app/src/main/java/com/onionsquad/bondoman/util/Converters.kt b/app/src/main/java/com/onionsquad/bondoman/util/Converters.kt
index eb9f90aed7e011b1929c61ffa87bda7f5b612595..ce6beddb309958907a9a4f30e9e9f53511b04ac0 100644
--- a/app/src/main/java/com/onionsquad/bondoman/util/Converters.kt
+++ b/app/src/main/java/com/onionsquad/bondoman/util/Converters.kt
@@ -25,6 +25,10 @@ object Converters {
 
     @TypeConverter
     fun toTransactionCategory(categoryString: String): TransactionCategory {
-        return TransactionCategory.valueOf(categoryString)
+        return try {
+            TransactionCategory.valueOf(categoryString)
+        } catch (e: IllegalArgumentException) {
+            TransactionCategory.UNKNOWN
+        }
     }
 }
\ No newline at end of file
diff --git a/app/src/main/res/drawable/ic_add.xml b/app/src/main/res/drawable/ic_add.xml
new file mode 100644
index 0000000000000000000000000000000000000000..8140012280ccf471ae3e11e44058ebfb0a4fa6e4
--- /dev/null
+++ b/app/src/main/res/drawable/ic_add.xml
@@ -0,0 +1,9 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="24"
+    android:viewportHeight="24">
+    <path
+        android:fillColor="@android:color/white"
+        android:pathData="M19,13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"/>
+</vector>
\ No newline at end of file
diff --git a/app/src/main/res/drawable/ic_delete.xml b/app/src/main/res/drawable/ic_delete.xml
new file mode 100644
index 0000000000000000000000000000000000000000..68a0c25ba815cfe6d897f662124ab27949e4917b
--- /dev/null
+++ b/app/src/main/res/drawable/ic_delete.xml
@@ -0,0 +1,9 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="24"
+    android:viewportHeight="24">
+    <path
+        android:fillColor="@android:color/black"
+        android:pathData="M6,19c0,1.1 0.9,2 2,2h8c1.1,0 2,-0.9 2,-2V7H6v12zM19,4h-3.5l-1,-1h-5l-1,1H5v2h14V4z"/>
+</vector>
\ No newline at end of file
diff --git a/app/src/main/res/drawable/ic_edit.xml b/app/src/main/res/drawable/ic_edit.xml
new file mode 100644
index 0000000000000000000000000000000000000000..07b29ac812158f3085d22bee97750c64f4ac298f
--- /dev/null
+++ b/app/src/main/res/drawable/ic_edit.xml
@@ -0,0 +1,9 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="24"
+    android:viewportHeight="24">
+    <path
+        android:fillColor="@android:color/black"
+        android:pathData="M3,17.25V21h3.75L17.81,9.94l-3.75,-3.75L3,17.25zM20.71,7.04c0.39,-0.39 0.39,-1.02 0,-1.41l-2.34,-2.34c-0.39,-0.39 -1.02,-0.39 -1.41,0l-1.83,1.83 3.75,3.75 1.83,-1.83z"/>
+</vector>
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_transaction.xml b/app/src/main/res/layout/fragment_transaction.xml
index 26af3dd3316b3d39d8d4a93547724bcb95a87311..ad431af9019f5407aa1dcaec30e2bf8df35d828d 100644
--- a/app/src/main/res/layout/fragment_transaction.xml
+++ b/app/src/main/res/layout/fragment_transaction.xml
@@ -6,15 +6,24 @@
     android:layout_height="match_parent"
     tools:context=".ui.transaction.TransactionFragment">
 
-    <Button
-        android:id="@+id/button"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:text="Button"
-        android:visibility="visible"
+    <androidx.recyclerview.widget.RecyclerView
+        android:id="@+id/transactionList"
+        android:layout_width="0dp"
+        android:layout_height="0dp"
+        app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
         app:layout_constraintBottom_toBottomOf="parent"
         app:layout_constraintEnd_toEndOf="parent"
         app:layout_constraintStart_toStartOf="parent"
-        app:layout_constraintTop_toTopOf="parent" />
+        app:layout_constraintTop_toTopOf="parent"
+        tools:listitem="@layout/transaction_card" />
+
+    <com.google.android.material.floatingactionbutton.FloatingActionButton
+        android:id="@+id/addTransactionButton"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_margin="16dp"
+        android:src="@drawable/ic_add"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintEnd_toEndOf="parent" />
 
 </androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
diff --git a/app/src/main/res/layout/transaction_card.xml b/app/src/main/res/layout/transaction_card.xml
new file mode 100644
index 0000000000000000000000000000000000000000..3a2757012d4ac15a56c0d87efaae0173f1d23bcf
--- /dev/null
+++ b/app/src/main/res/layout/transaction_card.xml
@@ -0,0 +1,79 @@
+<?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="wrap_content"
+    android:layout_margin="10dp">
+
+    <TextView
+        android:id="@+id/dateTextView"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:textSize="16sp"
+        android:textStyle="bold"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toTopOf="parent"
+        tools:text="29/02/2024" />
+
+    <TextView
+        android:id="@+id/categoryTextView"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="8dp"
+        android:textSize="14sp"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toBottomOf="@id/dateTextView"
+        tools:text="Pembelian" />
+
+    <TextView
+        android:id="@+id/titleTextView"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:textSize="18sp"
+        android:textStyle="bold"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toBottomOf="@id/categoryTextView"
+        tools:text="Transaction Name" />
+
+    <TextView
+        android:id="@+id/amountTextView"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:textSize="16sp"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintTop_toTopOf="parent"
+        tools:text="IDR 15.000" />
+
+    <TextView
+        android:id="@+id/locationTextView"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:textSize="14sp"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintTop_toBottomOf="@id/amountTextView"
+        tools:text="Location" />
+
+    <ImageButton
+        android:id="@+id/editButton"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="8dp"
+        android:layout_marginEnd="10dp"
+        android:background="?attr/selectableItemBackgroundBorderless"
+        android:src="@drawable/ic_edit"
+        app:layout_constraintEnd_toStartOf="@+id/deleteButton"
+        app:layout_constraintTop_toBottomOf="@id/titleTextView" />
+
+    <ImageButton
+        android:id="@+id/deleteButton"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginStart="8dp"
+        android:layout_marginTop="8dp"
+        android:background="?attr/selectableItemBackgroundBorderless"
+        android:src="@drawable/ic_delete"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintTop_toBottomOf="@id/titleTextView" />
+
+</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file