diff --git a/.idea/deploymentTargetDropDown.xml b/.idea/deploymentTargetDropDown.xml
index e660996cbf03445ae8fb3a3acaa65ae3862be6d1..bea9a884573a8a489d0d04539efdfc9b1dd36aa8 100644
--- a/.idea/deploymentTargetDropDown.xml
+++ b/.idea/deploymentTargetDropDown.xml
@@ -20,18 +20,18 @@
       </entry>
       <entry key="app">
         <State>
-          <runningDeviceTargetSelectedWithDropDown>
+          <targetSelectedWithDropDown>
             <Target>
-              <type value="RUNNING_DEVICE_TARGET" />
+              <type value="QUICK_BOOT_TARGET" />
               <deviceKey>
                 <Key>
-                  <type value="SERIAL_NUMBER" />
-                  <value value="RR8N2068CCP" />
+                  <type value="VIRTUAL_DEVICE_PATH" />
+                  <value value="C:\Users\Muhamad\.android\avd\Resizable_API_33_1.avd" />
                 </Key>
               </deviceKey>
             </Target>
-          </runningDeviceTargetSelectedWithDropDown>
-          <timeTargetWasSelectedWithDropDown value="2024-03-12T08:14:37.565277300Z" />
+          </targetSelectedWithDropDown>
+          <timeTargetWasSelectedWithDropDown value="2024-03-12T10:09:47.875397900Z" />
         </State>
       </entry>
     </value>
diff --git a/app/src/main/java/com/example/bondoman/ui/hub/HubActivity.kt b/app/src/main/java/com/example/bondoman/ui/hub/HubActivity.kt
index ca22a2217b729828bb9cabbd08aa053ea9b6ca26..10ff1d7b50b85d3dd2415bae0b05286b23d40364 100644
--- a/app/src/main/java/com/example/bondoman/ui/hub/HubActivity.kt
+++ b/app/src/main/java/com/example/bondoman/ui/hub/HubActivity.kt
@@ -36,7 +36,6 @@ class HubActivity : AppCompatActivity() {
         // Initialize navbar and fragments
         val orientation = resources.configuration.orientation
         if(orientation == Configuration.ORIENTATION_LANDSCAPE){
-            println("Window is landscape")
             landscape_binding = ActivityHubLandscapeBinding.inflate(layoutInflater)
             setContentView(landscape_binding.root)
 
@@ -58,7 +57,6 @@ class HubActivity : AppCompatActivity() {
             navView.setupWithNavController(navController)
         }
         else{
-            println("Window is portrait")
             portrait_binding = ActivityHubBinding.inflate(layoutInflater)
             setContentView(portrait_binding.root)
 
diff --git a/app/src/main/java/com/example/bondoman/ui/hub/settings/SettingsFragment.kt b/app/src/main/java/com/example/bondoman/ui/hub/settings/SettingsFragment.kt
index 860130cdd04421ea69d9192e58b8b4a25d22e2e5..b8d1a71ec5c7d94a46350d276e5f057c6d67e1f4 100644
--- a/app/src/main/java/com/example/bondoman/ui/hub/settings/SettingsFragment.kt
+++ b/app/src/main/java/com/example/bondoman/ui/hub/settings/SettingsFragment.kt
@@ -3,6 +3,7 @@ package com.example.bondoman.ui.hub.settings
 import android.Manifest
 import android.content.Intent
 import android.content.pm.PackageManager
+import android.net.Uri
 import android.os.Bundle
 import android.os.Environment
 import android.view.LayoutInflater
@@ -17,7 +18,6 @@ import androidx.fragment.app.Fragment
 import androidx.lifecycle.ViewModelProvider
 import androidx.lifecycle.lifecycleScope
 import com.example.bondoman.R
-import com.example.bondoman.database.entity.TransactionEntity
 import com.example.bondoman.databinding.FragmentSettingsBinding
 import com.example.bondoman.ui.login.LoginActivity
 import com.example.bondoman.viewmodel.transaction.TransactionViewModel
@@ -84,7 +84,14 @@ class SettingsFragment : Fragment() {
                 headerCellStyle.setBorderRight(BorderStyle.THIN)
 
                 // Initialize headers
-                val headers = arrayOf("No", "Title", "Category", "Amount", "Location", "Timestamp")
+                val headers = arrayOf(
+                    getString(R.string.transaction_label_number),
+                    getString(R.string.transaction_label_title),
+                    getString(R.string.transaction_label_category),
+                    getString(R.string.transaction_label_amount),
+                    getString(R.string.transaction_label_location),
+                    getString(R.string.transaction_label_timestamp)
+                )
                 val firstRow = workSheet.createRow(0)
                 for ((index, header) in headers.withIndex()) {
                     val cell = firstRow.createCell(index)
@@ -136,7 +143,7 @@ class SettingsFragment : Fragment() {
                 workbook.write(file.outputStream())
                 workbook.close()
 
-                Toast.makeText(requireContext(), "File saved at $path", Toast.LENGTH_SHORT).show()
+                Toast.makeText(requireContext(),  getString(R.string.save_toast_success) + "$path", Toast.LENGTH_SHORT).show()
 
                 // Open file immediately
                 val intent = Intent(Intent.ACTION_VIEW)
@@ -145,14 +152,114 @@ class SettingsFragment : Fragment() {
                 startActivity(intent)
             }
             else{
-                Toast.makeText(requireContext(), "Error: Data Unavailable", Toast.LENGTH_SHORT).show()
+                Toast.makeText(requireContext(), getString(R.string.settings_toast_uninitialized_viewmodel), Toast.LENGTH_SHORT).show()
             }
         }
     }
 
-    //TODO: Implement
     private fun sendTransaction(view: View){
-        println("Transaction sent")
+        // Init with viewmodel
+        val transactionViewModel = ViewModelProvider(requireActivity()).get(TransactionViewModel::class.java)
+        transactionViewModel.list.observe(viewLifecycleOwner) { transactionList ->
+            if (transactionList != null){
+
+                // Initialize excel file
+                val workbook = XSSFWorkbook()
+                val workSheet = workbook.createSheet("Transactions")
+                val headerCellStyle = workbook.createCellStyle()
+                headerCellStyle.setFillForegroundColor(IndexedColors.LIGHT_GREEN.index)
+                headerCellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND)
+                headerCellStyle.setBorderTop(BorderStyle.THIN)
+                headerCellStyle.setBorderBottom(BorderStyle.THIN)
+                headerCellStyle.setBorderLeft(BorderStyle.THIN)
+                headerCellStyle.setBorderRight(BorderStyle.THIN)
+
+                // Initialize headers
+                val headers = arrayOf(
+                    getString(R.string.transaction_label_number),
+                    getString(R.string.transaction_label_title),
+                    getString(R.string.transaction_label_category),
+                    getString(R.string.transaction_label_amount),
+                    getString(R.string.transaction_label_location),
+                    getString(R.string.transaction_label_timestamp)
+                )
+                val firstRow = workSheet.createRow(0)
+                for ((index, header) in headers.withIndex()) {
+                    val cell = firstRow.createCell(index)
+                    cell.setCellValue(header)
+                    cell.cellStyle = headerCellStyle
+
+                    workSheet.setColumnWidth(index, 6000)
+                }
+                workSheet.setColumnWidth(0, 2000)
+
+                // Insert data
+                val cellStyle = headerCellStyle.copy()
+                cellStyle.setFillForegroundColor(IndexedColors.WHITE.index)
+                cellStyle.wrapText = true
+
+                for ((index, transaction) in transactionList.withIndex()){
+                    val row = workSheet.createRow(1 + index)
+
+                    var cell = row.createCell(0)
+                    cell.setCellValue((1 + index).toString())
+                    cell.cellStyle = cellStyle
+
+                    cell = row.createCell(1)
+                    cell.setCellValue(transaction.title)
+                    cell.cellStyle = cellStyle
+
+                    cell = row.createCell(2)
+                    cell.setCellValue(transaction.category)
+                    cell.cellStyle = cellStyle
+
+                    cell = row.createCell(3)
+                    cell.setCellValue(transaction.amount.toDouble())
+                    cell.cellStyle = cellStyle
+
+                    cell = row.createCell(4)
+                    cell.setCellValue(transaction.location)
+                    cell.cellStyle = cellStyle
+
+                    cell = row.createCell(5)
+                    cell.setCellValue(transaction.timestamp)
+                    cell.cellStyle = cellStyle
+                }
+
+                // Output file
+                val path = requireContext().cacheDir
+                val file = File(
+                    path,
+                    "BondomanTransaction" + SimpleDateFormat("yyyy_MM_dd_HH_mm_ss", Locale.getDefault()).format(Date()) + ".xlsx"
+                )
+                workbook.write(file.outputStream())
+                workbook.close()
+
+                // Prep email
+                // TODO: set email recipient as the logged in account
+                val emailRecipient = arrayOf("13521095@std.stei.itb.ac.id")
+//                val emailIntent = Intent(Intent.ACTION_SENDTO,  Uri.fromParts("mailto",emailRecipient, null))
+                val emailIntent = Intent(Intent.ACTION_SEND)
+                emailIntent.type = "text/plain"
+                emailIntent.putExtra(Intent.EXTRA_EMAIL, emailRecipient)
+                emailIntent.putExtra(Intent.EXTRA_SUBJECT, getString(R.string.email_subject))
+                emailIntent.putExtra(Intent.EXTRA_TEXT, getString(R.string.email_text) + SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault()).format(Date()))
+                emailIntent.putExtra(Intent.EXTRA_STREAM, FileProvider.getUriForFile(requireContext(), requireContext().packageName + ".provider", file))
+                emailIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
+
+                // Send email
+                try {
+                    startActivity(Intent.createChooser(emailIntent, "Send Email"))
+                    Toast.makeText(requireContext(), getString(R.string.email_toast_success), Toast.LENGTH_SHORT).show()
+                } catch (e: Exception){
+                    println(e.message)
+                    Toast.makeText(requireContext(), getString(R.string.email_toast_fail), Toast.LENGTH_SHORT).show()
+                }
+            }
+            else{
+                Toast.makeText(requireContext(), getString(R.string.settings_toast_uninitialized_viewmodel), Toast.LENGTH_SHORT).show()
+            }
+        }
     }
 
     //TODO: Implement
diff --git a/app/src/main/java/com/example/bondoman/ui/transaction/TransactionActivity.kt b/app/src/main/java/com/example/bondoman/ui/transaction/TransactionActivity.kt
index 289747c42a05599857e4ed7ab743ba42370e270b..4b6cfe357f4868c21da5bf842f6b56d98671d7e3 100644
--- a/app/src/main/java/com/example/bondoman/ui/transaction/TransactionActivity.kt
+++ b/app/src/main/java/com/example/bondoman/ui/transaction/TransactionActivity.kt
@@ -57,10 +57,10 @@ class TransactionActivity : AppCompatActivity() {
             val amount = binding.amountInput.text.toString()
 
             if (title.isEmpty()){
-                Toast.makeText(this, "Please enter a title", Toast.LENGTH_SHORT).show()
+                Toast.makeText(this, getString(R.string.transaction_add_toast_error_title), Toast.LENGTH_SHORT).show()
             }
             else if (amount.isEmpty()){
-                Toast.makeText(this, "Please enter an amount", Toast.LENGTH_SHORT).show()
+                Toast.makeText(this, getString(R.string.transaction_add_toast_error_amount), Toast.LENGTH_SHORT).show()
             }
             else{
                 transactionViewModel.insert(
@@ -74,7 +74,7 @@ class TransactionActivity : AppCompatActivity() {
                         timestamp = SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault()).format(Date())
                     )
                 )
-                Toast.makeText(this, "Transaction saved successfully", Toast.LENGTH_SHORT).show()
+                Toast.makeText(this, getString(R.string.transaction_add_toast_success), Toast.LENGTH_SHORT).show()
 //                TODO: Delete, this is for testing purposes
 //                transactionViewModel.deleteAll()
                 onBackPressed()
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index d0dcc486c44283c089540290d5beb522e7da6941..cfe0d3882913d8cab94e2e361cfb08ffa1f5d063 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -10,19 +10,34 @@
     <string name="login_label_password">Password</string>
     <string name="login_label_enter">Login</string>
 
+    <string name="transaction_label_number">No</string>
     <string name="transaction_label_title">Title</string>
     <string name="transaction_label_amount">Amount</string>
     <string name="transaction_label_category">Category</string>
     <string name="transaction_label_location">Location</string>
+    <string name="transaction_label_timestamp">Timestamp</string>
     <string name="transaction_label_submit">Submit</string>
 
     <string name="transaction_category_income">Income</string>
     <string name="transaction_category_expenses">Expenses</string>
 
+    <string name="transaction_add_toast_error_title">Please enter a title</string>
+    <string name="transaction_add_toast_error_amount">Please enter an amount</string>
+    <string name="transaction_add_toast_success">Transaction saved successfully</string>
+
     <string name="settings_save_transaction">Save transaction list</string>
     <string name="settings_send_transaction">Send transaction list</string>
     <string name="settings_logout">Log out</string>
 
+    <string name="email_subject">Bondoman: Transaction Data</string>
+    <string name="email_text">Attached are transaction
+        data from Bondoman, data is recorded at </string>
+    <string name="email_toast_success">Sending file...</string>
+    <string name="email_toast_fail">Failed to send file</string>
+
+    <string name="save_toast_success">File saved at </string>
+    <string name="settings_toast_uninitialized_viewmodel">Error: Data Unavailable</string>
+
     <string-array name="category_choices">
         <item>Income</item>
         <item>Expenses</item>
diff --git a/app/src/main/res/xml/provider_paths.xml b/app/src/main/res/xml/provider_paths.xml
index 4495c28c86d1340dba06826bf7a03519fe25aa88..4e0091cf0a8b1fe2986d4a692cffa2690d3f8ae7 100644
--- a/app/src/main/res/xml/provider_paths.xml
+++ b/app/src/main/res/xml/provider_paths.xml
@@ -1,4 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
 <paths>
     <external-path name="external_files" path="."/>
+    <cache-path name="cache" path="." />
 </paths>
\ No newline at end of file