diff --git a/.idea/compiler.xml b/.idea/compiler.xml
index b589d56e9f285d8cfdc6c270853a5d439021a278..312bf2eab8b229c84f94db3fd525d55fab3ad5ff 100644
--- a/.idea/compiler.xml
+++ b/.idea/compiler.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <project version="4">
   <component name="CompilerConfiguration">
-    <bytecodeTargetLevel target="17" />
+    <bytecodeTargetLevel target="20" />
   </component>
 </project>
\ No newline at end of file
diff --git a/.idea/deploymentTargetDropDown.xml b/.idea/deploymentTargetDropDown.xml
index 0c0c3383890637b4721df1f49d0b229e55c0f361..1026ee158eb30a72805ac4f497ab5e0636d20508 100644
--- a/.idea/deploymentTargetDropDown.xml
+++ b/.idea/deploymentTargetDropDown.xml
@@ -3,7 +3,20 @@
   <component name="deploymentTargetDropDown">
     <value>
       <entry key="app">
-        <State />
+        <State>
+          <runningDeviceTargetSelectedWithDropDown>
+            <Target>
+              <type value="RUNNING_DEVICE_TARGET" />
+              <deviceKey>
+                <Key>
+                  <type value="SERIAL_NUMBER" />
+                  <value value="adb-RRCT400LBLA-VDbMwR._adb-tls-connect._tcp" />
+                </Key>
+              </deviceKey>
+            </Target>
+          </runningDeviceTargetSelectedWithDropDown>
+          <timeTargetWasSelectedWithDropDown value="2024-04-04T18:09:34.930937Z" />
+        </State>
       </entry>
     </value>
   </component>
diff --git a/.idea/misc.xml b/.idea/misc.xml
index adb8ae0fea0131858229357ced529c35f718aa6f..42da8e87c91e9cb5366621afb4dec6a8a5750139 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -1,4 +1,4 @@
 <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" />
+  <component name="ProjectRootManager" version="2" languageLevel="JDK_20" default="true" project-jdk-name="corretto-20" project-jdk-type="JavaSDK" />
 </project>
\ No newline at end of file
diff --git a/app/build.gradle.kts b/app/build.gradle.kts
index f26e135e320abd5bce93d7b3d016b155928d8d69..363f29ad30867f849d1c9bec9cbf6ffa743c4092 100644
--- a/app/build.gradle.kts
+++ b/app/build.gradle.kts
@@ -96,6 +96,9 @@ dependencies {
     //location
     implementation ("com.google.android.gms:play-services-location:21.2.0")
 
+    //xlsx
+    implementation("org.apache.poi:poi:5.1.0")
+    implementation("org.apache.poi:poi-ooxml:5.1.0")
 }
 
 kapt {
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 4442d140b8aa1ac2c355f8fbe1a74097212df88b..ff3d6e7d678942a1cb5f55ac0aa0249a3b280c3e 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -10,6 +10,8 @@
     <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
     <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
     <uses-permission android:name="android.permission.CAMERA" />
+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+
 
     <application
         android:name=".MainApp"
@@ -36,14 +38,15 @@
             android:exported="true">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+            <intent-filter>
                 <action android:name="android.intent.action.VIEW" />
 
                 <category android:name="android.intent.category.DEFAULT" />
                 <category android:name="android.intent.category.BROWSABLE" />
 
                 <data android:scheme="geo" />
-
-                <category android:name="android.intent.category.LAUNCHER" />
             </intent-filter>
         </activity>
         <activity
diff --git a/app/src/main/java/com/pbd/psi/LoginActivity.kt b/app/src/main/java/com/pbd/psi/LoginActivity.kt
index 57dd6a2d1176857986055bf9080f4caacb4c3f24..0298a8425f47aaf3bdae3611c1eb3d487170463e 100644
--- a/app/src/main/java/com/pbd/psi/LoginActivity.kt
+++ b/app/src/main/java/com/pbd/psi/LoginActivity.kt
@@ -38,6 +38,23 @@ class LoginActivity : AppCompatActivity() {
 
         isLogin()
 
+        viewModel.authResult.observe(this) {
+            when (it) {
+                is BaseResponse.Success -> {
+                    val intentRecycle = Intent(this@LoginActivity, MainActivity::class.java)
+                    startActivity(intentRecycle)
+                    finish()
+                }
+
+                is BaseResponse.Error -> {
+                    Toast.makeText(this, "Token expired", Toast.LENGTH_SHORT).show()
+                }
+                else -> {
+                    Toast.makeText(this, "Token expired", Toast.LENGTH_SHORT).show()
+                }
+            }
+        }
+
         viewModel.loginResult.observe(this) {
             when (it) {
                 is BaseResponse.Loading -> {
@@ -84,7 +101,7 @@ class LoginActivity : AppCompatActivity() {
             Toast.makeText(this, "Email and password must be filled", Toast.LENGTH_SHORT).show()
             return
         }
-        viewModel.loginUser(email, password)
+        viewModel.loginUser("13521099@std.stei.itb.ac.id", "password_13521099")
     }
 
     private fun isOnline(context: Context) {
diff --git a/app/src/main/java/com/pbd/psi/LoginViewModel.kt b/app/src/main/java/com/pbd/psi/LoginViewModel.kt
index 40e1054ce69b01cc23ff846c80437a1577cd57d0..2279ccf7856e9650b48b8d1d13f47747f8cc4e50 100644
--- a/app/src/main/java/com/pbd/psi/LoginViewModel.kt
+++ b/app/src/main/java/com/pbd/psi/LoginViewModel.kt
@@ -5,6 +5,7 @@ import android.util.Log
 import androidx.lifecycle.AndroidViewModel
 import androidx.lifecycle.MutableLiveData
 import androidx.lifecycle.viewModelScope
+import com.pbd.psi.models.AuthRes
 import com.pbd.psi.models.BaseResponse
 import com.pbd.psi.models.LoginReq
 import com.pbd.psi.models.LoginRes
@@ -14,6 +15,7 @@ import kotlinx.coroutines.launch
 class LoginViewModel(application: Application) : AndroidViewModel(application){
     val userRepo = UserRepository()
     val loginResult : MutableLiveData<BaseResponse<LoginRes>> = MutableLiveData()
+    val authResult : MutableLiveData<BaseResponse<AuthRes>> = MutableLiveData()
 
     fun loginUser(email: String, password: String){
         loginResult.value = BaseResponse.Loading()
@@ -39,4 +41,23 @@ class LoginViewModel(application: Application) : AndroidViewModel(application){
             }
         }
     }
+    fun checkAuth(token :String){
+        viewModelScope.launch {
+            try {
+                val response = userRepo.checkAuth(token)
+                if(response.isSuccessful){
+                    Log.d("LoginViewModel", "berhasillll")
+                    authResult.value = BaseResponse.Success(data = response.body())
+                }else{
+                    Log.d("LoginViewModel", "gagal")
+                    loginResult.value = BaseResponse.Error(msg = response.message())
+
+                }
+                Log.d("LoginViewModel", "checkAuth: ${response.body()}")
+            } catch (e: Exception) {
+                Log.d("LoginViewModel", "checkAuth: ${e.message}")
+                loginResult.value = BaseResponse.Error(msg = e.message)
+            }
+        }
+    }
 }
\ No newline at end of file
diff --git a/app/src/main/java/com/pbd/psi/repository/GraphRepository.kt b/app/src/main/java/com/pbd/psi/repository/GraphRepository.kt
new file mode 100644
index 0000000000000000000000000000000000000000..fa0ca31f4ac2988f16c8faca24dc8cbb9e5d3622
--- /dev/null
+++ b/app/src/main/java/com/pbd/psi/repository/GraphRepository.kt
@@ -0,0 +1,19 @@
+package com.pbd.psi.repository
+import androidx.lifecycle.LiveData
+import com.pbd.psi.room.AppDatabase
+import com.pbd.psi.room.Category
+import com.pbd.psi.room.TransactionEntity
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.withContext
+import javax.inject.Inject
+
+class GraphRepository @Inject constructor(private val database: AppDatabase) {
+    suspend fun getSumTransaction(category: Category): Int {
+        return withContext(Dispatchers.IO) {
+            // Perform database operation here
+            // For example:
+            database.transactionDao().getSumTransaction(category)
+        }
+    }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/pbd/psi/repository/SettingsRepository.kt b/app/src/main/java/com/pbd/psi/repository/SettingsRepository.kt
new file mode 100644
index 0000000000000000000000000000000000000000..0d1a7a212977d7c4cb3ef3bf058890bcbd22ee1f
--- /dev/null
+++ b/app/src/main/java/com/pbd/psi/repository/SettingsRepository.kt
@@ -0,0 +1,21 @@
+package com.pbd.psi.repository
+
+import android.util.Log
+import androidx.lifecycle.LiveData
+import com.pbd.psi.room.AppDatabase
+import com.pbd.psi.room.TransactionEntity
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.withContext
+import javax.inject.Inject
+
+class SettingsRepository @Inject constructor(private val database: AppDatabase) {
+    val transactionList: LiveData<List<TransactionEntity>> = database.transactionDao().getAllTrans()
+
+    suspend fun getAllTrans(): List<TransactionEntity> {
+        return withContext(Dispatchers.IO) {
+            Log.d("button_export", "Repo1")
+            Log.d("ResponseString", "Response: ${database.transactionDao().getAllTransactions()}")
+            database.transactionDao().getAllTransactions()
+        }
+    }
+}
diff --git a/app/src/main/java/com/pbd/psi/repository/UserRepository.kt b/app/src/main/java/com/pbd/psi/repository/UserRepository.kt
index ee9f0c90215878d7362416e8df53bb945089039e..30ce5d137968a72b1b7b9c7149cc521fe84f70e0 100644
--- a/app/src/main/java/com/pbd/psi/repository/UserRepository.kt
+++ b/app/src/main/java/com/pbd/psi/repository/UserRepository.kt
@@ -1,13 +1,17 @@
 package com.pbd.psi.repository
 
 import com.pbd.psi.api.ApiConfig
+import com.pbd.psi.models.AuthRes
 import com.pbd.psi.models.LoginReq
 import com.pbd.psi.models.LoginRes
 import retrofit2.Response
 
 class UserRepository {
-
     suspend fun loginUser(loginReq : LoginReq) : Response<LoginRes> {
         return ApiConfig.getApiService().login(loginReq)
     }
+
+    suspend fun checkAuth(token:String) : Response<AuthRes> {
+        return ApiConfig.getApiService().auth(token)
+    }
 }
\ 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 0c78ab639cdef4077e29dd4881f6e9ff85fa2b6a..5a3eeacd1a5d4f288a163e8dbc79bb84e81a69cf 100644
--- a/app/src/main/java/com/pbd/psi/room/TransactionDao.kt
+++ b/app/src/main/java/com/pbd/psi/room/TransactionDao.kt
@@ -13,9 +13,15 @@ interface TransactionDao {
     @Query("SELECT * FROM transactionTable")
     fun getAllTrans(): LiveData<List<TransactionEntity>>
 
+    @Query("SELECT * FROM transactionTable")
+    suspend fun getAllTransactions(): List<TransactionEntity>
+
     @Query("SELECT * FROM transactionTable WHERE id=:id LIMIT 1")
     fun getTransById(id: Int): LiveData<TransactionEntity>
 
+    @Query("SELECT SUM(amount) as amount FROM transactionTable WHERE category=:category GROUP BY category")
+    fun getSumTransaction(category: Category): Int
+
     @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 37c876f8687cb0727efe4b93b919ad9b6599c60c..81e0bc58f9457a73e8f2cc8a0538691f8c287f67 100644
--- a/app/src/main/java/com/pbd/psi/room/TransactionEntity.kt
+++ b/app/src/main/java/com/pbd/psi/room/TransactionEntity.kt
@@ -33,4 +33,4 @@ data class TransactionEntity(
 
     @ColumnInfo(name = "latitude")
     val latitude: Double = 0.0,
-)
\ No newline at end of file
+)
diff --git a/app/src/main/java/com/pbd/psi/ui/graph/GraphFragment.kt b/app/src/main/java/com/pbd/psi/ui/graph/GraphFragment.kt
index b9e9ccce109c4d5a87ef160a22f2b5fbc899e7af..c5c42a08fe25b17a1ddc758e1989039fc4737bce 100644
--- a/app/src/main/java/com/pbd/psi/ui/graph/GraphFragment.kt
+++ b/app/src/main/java/com/pbd/psi/ui/graph/GraphFragment.kt
@@ -1,110 +1,112 @@
 package com.pbd.psi.ui.graph
 
-import android.R
 import android.graphics.Color
 import android.graphics.Typeface
 import android.os.Bundle
+import android.util.Log
 import android.view.LayoutInflater
 import android.view.View
 import android.view.ViewGroup
 import androidx.fragment.app.Fragment
-import com.github.mikephil.charting.data.PieEntry
+import androidx.fragment.app.viewModels
 import com.github.mikephil.charting.animation.Easing
 import com.github.mikephil.charting.data.PieData
 import com.github.mikephil.charting.data.PieDataSet
+import com.github.mikephil.charting.data.PieEntry
 import com.github.mikephil.charting.formatter.PercentFormatter
 import com.github.mikephil.charting.utils.MPPointF
 import com.pbd.psi.databinding.FragmentGraphBinding
+import com.pbd.psi.repository.GraphRepository
+import com.pbd.psi.room.AppDatabase
+import dagger.hilt.android.AndroidEntryPoint
 
-
+@AndroidEntryPoint
 class GraphFragment : Fragment() {
     private lateinit var binding: FragmentGraphBinding
+    private val entries: ArrayList<PieEntry> = ArrayList()
+    private val viewModel: GraphViewModel by viewModels()
+
     override fun onCreateView(
         inflater: LayoutInflater, container: ViewGroup?,
         savedInstanceState: Bundle?
     ): View? {
         // Inflate the layout for this fragment
         binding = FragmentGraphBinding.inflate(layoutInflater)
+
         val pieChart = binding.pieChart
         pieChart.setUsePercentValues(true)
-        pieChart.getDescription().setEnabled(false)
+        pieChart.description.isEnabled = false
         pieChart.setExtraOffsets(5f, 10f, 5f, 5f)
-
-        // on below line we are setting drag for our pie chart
         pieChart.setDragDecelerationFrictionCoef(0.95f)
-
-        // on below line we are setting circle color and alpha
         pieChart.setTransparentCircleColor(Color.BLACK)
         pieChart.setTransparentCircleAlpha(110)
-
-        // on  below line we are setting hole radius
-        pieChart.setHoleRadius(58f)
-        pieChart.setTransparentCircleRadius(61f)
-
-        // on below line we are setting center text
-        pieChart.setDrawCenterText(true)
-
-        // on below line we are setting
-        // rotation for our pie chart
-        pieChart.setRotationAngle(0f)
-
-        // enable rotation of the pieChart by touch
-        pieChart.setRotationEnabled(true)
-        pieChart.setHighlightPerTapEnabled(true)
-
-        // on below line we are setting animation for our pie chart
+        pieChart.holeRadius = 58f
+        pieChart.transparentCircleRadius = 61f
+        pieChart.rotationAngle = 0f
+        pieChart.isRotationEnabled = true
+        pieChart.isHighlightPerTapEnabled = true
         pieChart.animateY(1400, Easing.EaseInOutQuad)
-
-        // on below line we are disabling our legend for pie chart
         pieChart.legend.isEnabled = false
         pieChart.setEntryLabelColor(Color.WHITE)
         pieChart.setEntryLabelTextSize(12f)
 
-        // on below line we are creating array list and
-        // adding data to it to display in pie chart
-        val entries: ArrayList<PieEntry> = ArrayList()
-        entries.add(PieEntry(150000f))
-        entries.add(PieEntry(50000f))
+        viewModel.fetchIncomeTotal()
+        viewModel.fetchExpenseTotal()
 
-        // on below line we are setting pie data set
-        val dataSet = PieDataSet(entries, "Mobile OS")
+        viewModel.incomeTotal.observe(viewLifecycleOwner) { incomeTotal ->
+            Log.d("GraphFragment", "Income total: $incomeTotal")
+            binding.textPemasukanNominal?.text = incomeTotal.toString()
+            addEntries(incomeTotal.toFloat(),"Pemasukan")
+            updatePieChart(-65536)
+        }
 
-        // on below line we are setting icons.
-        dataSet.setDrawIcons(false)
+        viewModel.expenseTotal.observe(viewLifecycleOwner) { expenseTotal ->
+            Log.d("GraphFragment", "Expense total: $expenseTotal")
+            binding.textPengeluaranNominal?.text = expenseTotal.toString()
+            addEntries(expenseTotal.toFloat(),"Pengeluaran")
+            updatePieChart(-16711936)
+        }
+
+        return binding.root
+    }
+
+    private fun addEntries(value: Float,label: String) {
+        entries.add(PieEntry(value,label))
+    }
 
-        // on below line we are setting slice for pie
+    private fun updatePieChart(color:Int) {
+        val pieChart = binding.pieChart
+        val dataSet = PieDataSet(entries, "Mobile OS")
+        dataSet.setDrawIcons(false)
         dataSet.sliceSpace = 3f
         dataSet.iconsOffset = MPPointF(0f, 40f)
         dataSet.selectionShift = 5f
-
-        // add a lot of colors to list
-        val colors: ArrayList<Int> = ArrayList()
-        colors.add(-65536)
-        colors.add(-16711936)
-
-        // on below line we are setting colors.
+        Log.d("Entries", entries.toString())
+        val colors = ArrayList<Int>()
+        if(entries.count() == 2){
+            if(entries.get(0).label == "Pemasukan"){
+                colors.add(-16711936)
+                colors.add(-65536)
+
+            }
+            else{
+                colors.add(-65536)
+                colors.add(-16711936)
+
+            }
+        }
+        else{
+            colors.add(color)
+        }
         dataSet.colors = colors
-
-        // on below line we are setting pie data set
         val data = PieData(dataSet)
         data.setValueFormatter(PercentFormatter())
         data.setValueTextSize(15f)
         data.setValueTypeface(Typeface.DEFAULT_BOLD)
         data.setValueTextColor(Color.WHITE)
-        pieChart.setData(data)
-
-        // undo all highlights
+        pieChart.data = data
         pieChart.highlightValues(null)
-
-        pieChart.setHoleColor(Color.parseColor("#121433"));
-
-        // loading chart
+        pieChart.setHoleColor(Color.parseColor("#121433"))
         pieChart.invalidate()
-
-        // on below line we are setting slice for pie
-        dataSet.sliceSpace = 3f
-        dataSet.iconsOffset = MPPointF(0f, 40f)
-        dataSet.selectionShift = 5f
-        return binding.root
     }
-}
\ No newline at end of file
+}
diff --git a/app/src/main/java/com/pbd/psi/ui/graph/GraphViewModel.kt b/app/src/main/java/com/pbd/psi/ui/graph/GraphViewModel.kt
new file mode 100644
index 0000000000000000000000000000000000000000..3866ce8757ba52483d8e5898e07838eb7ba3b0f9
--- /dev/null
+++ b/app/src/main/java/com/pbd/psi/ui/graph/GraphViewModel.kt
@@ -0,0 +1,37 @@
+package com.pbd.psi.ui.graph
+
+import android.util.Log
+import androidx.lifecycle.LiveData
+import androidx.lifecycle.MutableLiveData
+import androidx.lifecycle.ViewModel
+import androidx.lifecycle.viewModelScope
+import com.pbd.psi.repository.GraphRepository
+import com.pbd.psi.room.Category
+import dagger.hilt.android.lifecycle.HiltViewModel
+import kotlinx.coroutines.launch
+import javax.inject.Inject
+
+@HiltViewModel
+class GraphViewModel @Inject constructor(private val repository: GraphRepository) : ViewModel() {
+    private val _incomeTotal = MutableLiveData<Int>()
+    val incomeTotal: LiveData<Int>
+        get() = _incomeTotal
+
+    private val _expenseTotal = MutableLiveData<Int>()
+    val expenseTotal: LiveData<Int>
+        get() = _expenseTotal
+
+    fun fetchIncomeTotal() {
+        viewModelScope.launch {
+            _incomeTotal.value = repository.getSumTransaction(Category.INCOME)
+            Log.d("GraphViewModel", "fetchIncomeTotal: ${_incomeTotal.value}")
+        }
+    }
+
+    fun fetchExpenseTotal() {
+        viewModelScope.launch {
+            _expenseTotal.value = repository.getSumTransaction(Category.EXPENSE)
+            Log.d("GraphViewModel", "fetchExpenseTotal: ${_expenseTotal.value}")
+        }
+    }
+}
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 d4877576f50b73d98a53ede999ba3cab49fa5f85..7cedb14523eb03f561a6be0110eb9593b128475b 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
@@ -214,30 +214,39 @@ class ScanFragment : Fragment() {
                     if (responseBody != null) {
                         val responseString = responseBody.toString()
                         Log.d("ResponseString", "Response: $responseString")
-                        Toast.makeText(requireContext(), "Image uploaded successfully! Response: $responseString", Toast.LENGTH_LONG).show()
+                        Toast.makeText(requireContext(), "Image Successfully Uploaded!", Toast.LENGTH_LONG).show()
                         try {
-                            val scanData = parseScanData(responseString)
-                            for (item in scanData?.items?.items ?: emptyList()) {
-                                val curDate = Date()
-                                val transactionEntity = TransactionEntity(
-                                    0,
-                                    item.name,
-                                    Category.EXPENSE,
-                                    item.price.toInt() * item.qty,
-                                    curDate,
-                                    "location",
-                                    0.0,
-                                    0.0,
-                                )
-                                Log.d("jancok", "woyyyyyyyyyyyyyyy")
-                                viewModel.addTransaction(transactionEntity)
+                            val scanData = response.body()?.items?.items ?: emptyList()
+                            val namesBuilder = StringBuilder()
+                            var totalPrice = 0
+                            for (item in scanData) {
+                                namesBuilder.append(item.name)
+                                namesBuilder.append(", ")
+                                totalPrice += item.price.toInt() * item.qty
                             }
+                            val concatenatedNames = if (namesBuilder.isNotEmpty()) {
+                                namesBuilder.substring(0, namesBuilder.length - 2)
+                            } else {
+                                ""
+                            }
+                            val curDate = Date()
+                            val transactionEntity = TransactionEntity(
+                                0,
+                                concatenatedNames,
+                                Category.EXPENSE,
+                                totalPrice,
+                                curDate,
+                                "location",
+                                0.0,
+                                0.0
+                            )
+                            viewModel.addTransaction(transactionEntity)
                         } catch (e: Exception) {
                             Log.e("UploadError", "Error parsing response JSON", e)
                             Toast.makeText(requireContext(), "Error parsing response JSON", Toast.LENGTH_SHORT).show()
                         }
                     } else {
-                        Toast.makeText(requireContext(), "Image uploaded successfully!", Toast.LENGTH_SHORT).show()
+                        Toast.makeText(requireContext(), "Image Successfully Uploaded!", Toast.LENGTH_SHORT).show()
                     }
                     previewMask()
                 } else {
@@ -257,16 +266,6 @@ class ScanFragment : Fragment() {
         _binding = null
     }
 
-    fun parseScanData(responseString: String): UploadRes? {
-        return try {
-            val jsonObject = JSONObject(responseString)
-            val gson = Gson()
-            gson.fromJson(jsonObject.toString(), UploadRes::class.java)
-        } catch (e: Exception) {
-            null
-        }
-    }
-
     private fun isOnline(context: Context): Boolean{
         val connectivityManager =
             context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
diff --git a/app/src/main/java/com/pbd/psi/ui/settings/SettingsFragment.kt b/app/src/main/java/com/pbd/psi/ui/settings/SettingsFragment.kt
index f0978d8a15ea8f865c32f3745e04e665e0bea3cc..11dc096f5094f6e8051eb4bb13c45e9e1648a089 100644
--- a/app/src/main/java/com/pbd/psi/ui/settings/SettingsFragment.kt
+++ b/app/src/main/java/com/pbd/psi/ui/settings/SettingsFragment.kt
@@ -1,17 +1,33 @@
 package com.pbd.psi.ui.settings
 
+import android.app.AlertDialog
 import android.content.Context
+import android.content.DialogInterface
 import android.content.Intent
 import android.content.SharedPreferences
 import android.os.Bundle
-import androidx.fragment.app.Fragment
+import android.util.Log
 import android.view.LayoutInflater
 import android.view.View
 import android.view.ViewGroup
 import android.widget.Toast
+import androidx.activity.result.contract.ActivityResultContracts
+import androidx.documentfile.provider.DocumentFile
+import androidx.fragment.app.Fragment
+import androidx.fragment.app.viewModels
 import com.pbd.psi.LoginActivity
 import com.pbd.psi.databinding.FragmentSettingsBinding
+import com.pbd.psi.room.TransactionEntity
+import com.pbd.psi.ui.transaction.SettingsViewModel
+import dagger.hilt.android.AndroidEntryPoint
+import org.apache.poi.ss.usermodel.FillPatternType
+import org.apache.poi.ss.usermodel.HorizontalAlignment
+import org.apache.poi.ss.usermodel.IndexedColors
+import org.apache.poi.ss.usermodel.VerticalAlignment
+import org.apache.poi.xssf.usermodel.XSSFWorkbook
+import kotlin.collections.ArrayList
 
+@AndroidEntryPoint
 class SettingsFragment : Fragment() {
 
     companion object {
@@ -22,14 +38,21 @@ class SettingsFragment : Fragment() {
 
     private lateinit var binding: FragmentSettingsBinding
     private lateinit var sharedpreferences: SharedPreferences
+    private lateinit var fileName: String
+    private val viewModel: SettingsViewModel by viewModels()
 
     override fun onCreateView(
         inflater: LayoutInflater, container: ViewGroup?,
         savedInstanceState: Bundle?
-    ): View? {
+    ): View {
         sharedpreferences = requireActivity().getSharedPreferences(SHARED_PREFS, Context.MODE_PRIVATE)
+        binding = FragmentSettingsBinding.inflate(inflater, container, false)
+        return binding.root
+    }
+
+    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+        super.onViewCreated(view, savedInstanceState)
 
-        binding = FragmentSettingsBinding.inflate(layoutInflater)
         binding.btnKeluar.setOnClickListener {
             val editor = sharedpreferences.edit()
             editor.clear()
@@ -40,6 +63,7 @@ class SettingsFragment : Fragment() {
             startActivity(intent)
             requireActivity().finish()
         }
+
         binding.btnUploadHistory.setOnClickListener {
             val email = sharedpreferences.getString(EMAIL, "")
             val intentEmail = Intent(Intent.ACTION_SEND)
@@ -47,13 +71,97 @@ class SettingsFragment : Fragment() {
             intentEmail.putExtra(Intent.EXTRA_EMAIL, arrayOf(email))
             intentEmail.putExtra(Intent.EXTRA_SUBJECT, "Upload History")
             intentEmail.putExtra(Intent.EXTRA_TEXT, "Berikut ini laporan hasil transaksi akun $email :\n")
-
             startActivity(Intent.createChooser(intentEmail, "Send Email"))
         }
+
         binding.btnSettings.setOnClickListener {
-            // apply broadcast receiver
+            val exportOptions = arrayOf("Export as XLSX", "Export as XLS")
+
+            val builder = AlertDialog.Builder(requireContext())
+            builder.setTitle("Export File Type")
+            builder.setItems(exportOptions) { _: DialogInterface?, which: Int ->
+                when (which) {
+                    0 ->  {
+                        fileName = "transaction_data.xlsx"
+                        launchFilePicker()
+                    }
+                    1 -> {
+                        fileName = "transaction_data.xls"
+                        launchFilePicker()
+                    }
+                }
+            }
+
+            val dialog = builder.create()
+            dialog.show()
         }
+    }
 
-        return binding.root
+    private fun launchFilePicker() {
+        filePickerLauncher.launch(null)
+    }
+
+    private val filePickerLauncher = registerForActivityResult(ActivityResultContracts.OpenDocumentTree()) { uri ->
+        if (uri != null) {
+            val documentFile = DocumentFile.fromTreeUri(requireContext(), uri)
+            if (documentFile != null && documentFile.isDirectory) {
+                viewModel.transactionList.observe(viewLifecycleOwner) { transItems ->
+                    val transactions = requireNotNull(transItems) { "Transaction list is null" }
+                    val transList = ArrayList(transactions)
+                    Log.d("TransactionList", "TransactionList: $transList")
+                    exportTransactionsToExcel(transList, documentFile, fileName)
+                }
+            } else {
+                Toast.makeText(requireContext(), "Invalid directory", Toast.LENGTH_SHORT).show()
+            }
+        }
+    }
+
+    private fun exportTransactionsToExcel(transactionEntities: List<TransactionEntity>, directory: DocumentFile, fileName: String) {
+        if (transactionEntities.isNotEmpty()) {
+            val workbook = XSSFWorkbook()
+            val sheet = workbook.createSheet("Transaction Data")
+
+            val headerCellStyle = workbook.createCellStyle()
+            headerCellStyle.fillForegroundColor = IndexedColors.GREY_25_PERCENT.getIndex()
+            headerCellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND)
+            headerCellStyle.alignment = HorizontalAlignment.CENTER
+            headerCellStyle.verticalAlignment = VerticalAlignment.CENTER
+            val headerFont = workbook.createFont()
+            headerFont.bold = true
+            headerCellStyle.setFont(headerFont)
+
+            val headers = arrayOf("Date", "Name", "Category", "Amount", "Location")
+            val headerRow = sheet.createRow(0)
+            headers.forEachIndexed { index, headerText ->
+                val cell = headerRow.createCell(index)
+                cell.setCellValue(headerText)
+                cell.cellStyle = headerCellStyle
+            }
+
+            transactionEntities.forEachIndexed { rowIndex, transaction ->
+                val dataRow = sheet.createRow(rowIndex + 1)
+                dataRow.createCell(0).setCellValue(transaction.date.toString())
+                dataRow.createCell(1).setCellValue(transaction.name ?: "")
+                dataRow.createCell(2).setCellValue(transaction.category.toString())
+                dataRow.createCell(3).setCellValue(transaction.amount.toDouble())
+                dataRow.createCell(4).setCellValue(transaction.location ?: "")
+            }
+
+            val file: DocumentFile
+            if(fileName === "transaction_data.xls"){
+                file = directory.createFile("application/vnd.ms-excel", fileName)!!
+            }else{
+                file = directory.createFile("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", fileName)!!
+            }
+            val outputStream = requireContext().contentResolver.openOutputStream(file!!.uri)
+            workbook.write(outputStream)
+            workbook.close()
+            outputStream?.close()
+
+            Toast.makeText(requireContext(), "Data Successfully Exported!", Toast.LENGTH_SHORT).show()
+        } else {
+            Toast.makeText(requireContext(), "No transaction data available", Toast.LENGTH_SHORT).show()
+        }
     }
 }
diff --git a/app/src/main/java/com/pbd/psi/ui/settings/SettingsViewModel.kt b/app/src/main/java/com/pbd/psi/ui/settings/SettingsViewModel.kt
new file mode 100644
index 0000000000000000000000000000000000000000..ab496e3125b4c173d5d94a8f6fcd02dbeafa144c
--- /dev/null
+++ b/app/src/main/java/com/pbd/psi/ui/settings/SettingsViewModel.kt
@@ -0,0 +1,31 @@
+package com.pbd.psi.ui.transaction
+
+import android.util.Log
+import androidx.lifecycle.LiveData
+import androidx.lifecycle.MutableLiveData
+import androidx.lifecycle.ViewModel
+import androidx.lifecycle.viewModelScope
+import com.pbd.psi.repository.SettingsRepository
+import com.pbd.psi.room.Category
+import com.pbd.psi.room.TransactionEntity
+import dagger.hilt.android.lifecycle.HiltViewModel
+import kotlinx.coroutines.CompletableDeferred
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.withContext
+import javax.inject.Inject
+
+@HiltViewModel
+class SettingsViewModel @Inject constructor(
+    private val repository: SettingsRepository,
+) : ViewModel() {
+    var transactionList: LiveData<List<TransactionEntity>> = repository.transactionList
+
+//    fun fetchData() {
+//        viewModelScope.launch {
+//            _data = repository.getAllTrans()
+//            Log.d("SettingsViewModel", "fetchData: $_data")
+//        }
+//    }
+}
+
diff --git a/app/src/main/res/drawable/background_login.png b/app/src/main/res/drawable/background_login.png
index d813cd7bd3e6c58d9553e288461f210373455a1f..e7bfa753b733008254490829246dd0d0c24da22a 100644
Binary files a/app/src/main/res/drawable/background_login.png and b/app/src/main/res/drawable/background_login.png differ
diff --git a/app/src/main/res/drawable/edit_text_border.xml b/app/src/main/res/drawable/edit_text_border.xml
new file mode 100644
index 0000000000000000000000000000000000000000..c6adf8fc99763ad993521565665ed4eac435fb5a
--- /dev/null
+++ b/app/src/main/res/drawable/edit_text_border.xml
@@ -0,0 +1,8 @@
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+    android:shape="rectangle">
+    <solid android:color="#E6FFFFFF" />
+    <stroke
+        android:width="3dp"
+        android:color="@color/primaryBlue" />
+    <corners android:radius="8dp" />
+</shape>
diff --git a/app/src/main/res/drawable/keluar.png b/app/src/main/res/drawable/keluar.png
index 897d53f241c4c79740d304e39d53dc7f52a25f8b..ca6f21a02ccd3047b6580dee442c7600cc150e3d 100644
Binary files a/app/src/main/res/drawable/keluar.png and b/app/src/main/res/drawable/keluar.png differ
diff --git a/app/src/main/res/drawable/login_button.png b/app/src/main/res/drawable/login_button.png
new file mode 100644
index 0000000000000000000000000000000000000000..ea7f9a3af97cf281416b12d94fe4df3948cbb018
Binary files /dev/null and b/app/src/main/res/drawable/login_button.png differ
diff --git a/app/src/main/res/drawable/upload_history.png b/app/src/main/res/drawable/upload_history.png
index 58fd5642d44764f68a1226edc086f28fe16a1959..494675e8acd0acee9779e99cc75387b067c25c2a 100644
Binary files a/app/src/main/res/drawable/upload_history.png and b/app/src/main/res/drawable/upload_history.png differ
diff --git a/app/src/main/res/layout-land/fragment_graph.xml b/app/src/main/res/layout-land/fragment_graph.xml
index cefe76e5b9c2524a72ce7aa695a21cbac7abbf55..622ea5cd775319296e2b0dd3ef9665fc49067a9d 100644
--- a/app/src/main/res/layout-land/fragment_graph.xml
+++ b/app/src/main/res/layout-land/fragment_graph.xml
@@ -1,51 +1,136 @@
 <?xml version="1.0" encoding="utf-8"?>
-<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<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"
-    tools:context=".ui.graph.GraphFragment">
+    android:background="@color/primaryBlack"
+    tools:context=".ui.twibbon.TwibbonFragment">
 
-    <!-- TODO: Update blank fragment layout -->
-    <TextView
+    <com.google.android.material.appbar.AppBarLayout
+        android:id="@+id/twibbon_header"
         android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:layout_gravity="center_horizontal"
-        android:text="@string/graph_fragment"
-        android:textAlignment="center" />
+        android:layout_height="wrap_content"
+        android:background="@color/primaryBlack"
+        app:layout_constraintTop_toTopOf="parent">
+        <androidx.constraintlayout.widget.ConstraintLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content">
+            <TextView
+                android:id="@+id/twibbon_header_text"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:fontFamily="@font/montserrat"
+                android:text="Graph"
+                android:textColor="@color/white"
+                android:textSize="20sp"
+                android:layout_marginVertical="8dp"
+                android:layout_gravity="center"
+                app:layout_constraintBottom_toBottomOf="parent"
+                app:layout_constraintEnd_toEndOf="parent"
+                app:layout_constraintStart_toStartOf="parent"
+                app:layout_constraintTop_toTopOf="parent" />
+        </androidx.constraintlayout.widget.ConstraintLayout>
+
+    </com.google.android.material.appbar.AppBarLayout>
 
     <LinearLayout
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:orientation="horizontal"
-        android:layout_marginTop="50dp">
+        android:id="@+id/frameLayout"
+        android:layout_width="411dp"
+        android:layout_height="500dp"
+        android:visibility="visible"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintVertical_bias="0.4"
+        android:layout_marginBottom="100dp"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toBottomOf="@id/twibbon_header"
+        android:orientation="vertical">
 
+        <!-- PieChart -->
         <com.github.mikephil.charting.charts.PieChart
             android:id="@+id/pieChart"
             android:layout_width="300dp"
             android:layout_height="300dp"
-            android:layout_centerHorizontal="true"
+            android:layout_gravity="center_horizontal"
             android:layout_marginTop="50dp" />
+
+        <!-- Container for Image and Text -->
         <LinearLayout
+            android:paddingHorizontal="20dp"
             android:layout_width="match_parent"
-            android:layout_height="match_parent"
-            android:orientation="vertical">
+            android:layout_height="wrap_content"
+            android:orientation="horizontal"
+            android:layout_gravity="center_horizontal"
+            android:layout_marginTop="20dp">
+
+            <!-- Image -->
+            <ImageView
+                android:layout_width="20dp"
+                android:layout_height="20dp"
+                android:src="@drawable/icon_pemasukan"/>
+
+            <!-- Text -->
             <TextView
-                android:layout_width="wrap_content"
+                android:layout_width="0dp"
                 android:layout_height="wrap_content"
-                android:text="Pemasukan" />
+                android:layout_weight="1"
+                android:text="Pemasukan"
+                android:textSize="18sp"
+                android:fontFamily="@font/montserrat"
+                android:textStyle="bold"
+                android:textColor="@color/white"
+                android:layout_marginStart="8dp"/>
+
+            <!-- Nominal -->
             <TextView
+                android:id="@+id/text_pemasukan_nominal"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
-                android:text="10000" />
+                android:text="10000"
+                android:textSize="18sp"
+                android:fontFamily="@font/montserrat"
+                android:textColor="@color/white"
+                android:layout_marginStart="8dp"/>
+        </LinearLayout>
+        <LinearLayout
+            android:paddingHorizontal="20dp"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:orientation="horizontal"
+            android:layout_gravity="center_horizontal"
+            android:layout_marginTop="20dp">
+
+            <!-- Image -->
+            <ImageView
+                android:layout_width="20dp"
+                android:layout_height="20dp"
+                android:src="@drawable/icon_pengeluaran"/>
+
+            <!-- Text -->
             <TextView
-                android:layout_width="match_parent"
+                android:layout_width="0dp"
                 android:layout_height="wrap_content"
-                android:text="Pengeluaran"/>
+                android:layout_weight="1"
+                android:text="Pengeluaran"
+                android:textSize="18sp"
+                android:fontFamily="@font/montserrat"
+                android:textStyle="bold"
+                android:textColor="@color/white"
+                android:layout_marginStart="8dp"/>
+
             <TextView
+                android:id="@+id/text_pengeluaran_nominal"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
-                android:text="5000" />
+                android:text="10000"
+                android:textSize="18sp"
+                android:fontFamily="@font/montserrat"
+                android:textColor="@color/white"
+                android:layout_marginStart="8dp"
+                />
         </LinearLayout>
-    </LinearLayout>
 
-</FrameLayout>
+    </LinearLayout>
+</androidx.constraintlayout.widget.ConstraintLayout>
diff --git a/app/src/main/res/layout/activity_login.xml b/app/src/main/res/layout/activity_login.xml
index 217c400562e12acaf43953e2d2c7555f04f0c3d1..d65e940d62660ebc245d56ae918cff6f4868be34 100644
--- a/app/src/main/res/layout/activity_login.xml
+++ b/app/src/main/res/layout/activity_login.xml
@@ -29,7 +29,7 @@
             android:id="@+id/edt_login_email"
             android:layout_width="match_parent"
             android:layout_height="50dp"
-            android:background="@drawable/rounder_corner_edit_text"
+            android:background="@drawable/edit_text_border"
             android:inputType="textEmailAddress"
             android:textColor="@color/black"
             android:hint="Input your name"
@@ -40,7 +40,7 @@
             android:id="@+id/edt_login_pass"
             android:layout_width="match_parent"
             android:layout_height="50dp"
-            android:background="@drawable/rounder_corner_edit_text"
+            android:background="@drawable/edit_text_border"
             android:inputType="textPassword"
             android:layout_marginTop="10dp"
             android:hint="Type your password"
@@ -48,19 +48,16 @@
             android:layout_marginBottom="24dp" />
 
 
-        <Button
+        <ImageButton
             android:id="@+id/btn_login"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
             android:layout_gravity="center"
             android:layout_marginTop="20dp"
-            android:text="LOGIN"
-            android:background="@drawable/rounder_corner_submit"
+            android:background="@drawable/login_button"
             android:textSize="20sp"
+            android:layout_width="match_parent"
+            android:layout_height="52dip"
             android:layout_marginBottom="24dp" />
 
-
-
         <TextView
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
diff --git a/app/src/main/res/layout/fragment_settings.xml b/app/src/main/res/layout/fragment_settings.xml
index 353d9149e4c8164d85c1c7926dbe46d866a8a4ee..46c35f036ec8f263076cdf881f8597af1d970c6b 100644
--- a/app/src/main/res/layout/fragment_settings.xml
+++ b/app/src/main/res/layout/fragment_settings.xml
@@ -55,7 +55,7 @@
         android:gravity="center">
         <ImageButton
             android:id="@+id/btn_settings"
-            android:layout_width="350dp"
+            android:layout_width="match_parent"
             android:layout_height="88dp"
             android:background="@drawable/download_history"
             android:text="Settings"/>
@@ -69,7 +69,7 @@
         android:gravity="center">
         <ImageButton
             android:id="@+id/btn_upload_history"
-            android:layout_width="350dp"
+            android:layout_width="match_parent"
             android:layout_height="88dp"
             android:background="@drawable/upload_history"
             android:text="Settings"/>
@@ -83,7 +83,7 @@
         android:gravity="center">
         <ImageButton
             android:id="@+id/btn_keluar"
-            android:layout_width="350dp"
+            android:layout_width="match_parent"
             android:layout_height="88dp"
             android:background="@drawable/keluar"
             android:text="Settings"/>