diff --git a/app/src/main/java/com/example/abe/MainActivity.kt b/app/src/main/java/com/example/abe/MainActivity.kt
index bd2566f312523d89a3ba30bff8327ff5069e9ad9..2b23e9a0ea33fcc348575165fcbed005f1756634 100644
--- a/app/src/main/java/com/example/abe/MainActivity.kt
+++ b/app/src/main/java/com/example/abe/MainActivity.kt
@@ -3,18 +3,21 @@ package com.example.abe
 import android.app.Activity
 import android.content.Intent
 import android.os.Bundle
-import android.util.Log
 import androidx.activity.result.contract.ActivityResultContracts
 import androidx.activity.viewModels
 import androidx.appcompat.app.AppCompatActivity
 import androidx.fragment.app.DialogFragment
+import androidx.lifecycle.lifecycleScope
 import androidx.navigation.findNavController
 import androidx.navigation.ui.AppBarConfiguration
 import androidx.navigation.ui.setupActionBarWithNavController
 import androidx.navigation.ui.setupWithNavController
 import com.example.abe.databinding.ActivityMainBinding
 import com.example.abe.ui.transactions.ExportAlertDialogFragment
+import com.example.abe.ui.transactions.ExportAlertDialogTypeEnum
+import com.example.abe.ui.transactions.ExportLoadDialogFragment
 import com.google.android.material.bottomnavigation.BottomNavigationView
+import kotlinx.coroutines.launch
 
 class MainActivity : AppCompatActivity(), ExportAlertDialogFragment.ExportAlertDialogListener {
 
@@ -33,39 +36,76 @@ class MainActivity : AppCompatActivity(), ExportAlertDialogFragment.ExportAlertD
 
         val navController = findNavController(R.id.nav_host_fragment_activity_main)
 
-        val appBarConfiguration = AppBarConfiguration(setOf(
-                R.id.navigation_transactions))
+        val appBarConfiguration = AppBarConfiguration(
+            setOf(
+                R.id.navigation_transactions
+            )
+        )
         setupActionBarWithNavController(navController, appBarConfiguration)
         navView.setupWithNavController(navController)
     }
 
-    override fun onNewExcelFormatClick(dialog: DialogFragment) {
-        val intent = Intent(Intent.ACTION_CREATE_DOCUMENT).apply {
-            addCategory(Intent.CATEGORY_OPENABLE)
-            setType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
-            putExtra(Intent.EXTRA_TITLE, viewModel.getExportFileName())
-            viewModel.newExcelFormat = true
+    override fun onNewExcelFormatClick(dialog: DialogFragment, type: ExportAlertDialogTypeEnum) {
+        viewModel.newExcelFormat = true
+        when (type) {
+            ExportAlertDialogTypeEnum.EXPORT -> {
+                val intent = Intent(Intent.ACTION_CREATE_DOCUMENT).apply {
+                    addCategory(Intent.CATEGORY_OPENABLE)
+                    setType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
+                    putExtra(Intent.EXTRA_TITLE, viewModel.getExportFileName())
+                }
+                resultLauncher.launch(intent)
+            }
+
+            ExportAlertDialogTypeEnum.SEND_EMAIL -> {
+                sendEmail()
+            }
         }
-        resultLauncher.launch(intent)
     }
 
-    override fun onOldExcelFormatClick(dialog: DialogFragment) {
-        val intent = Intent(Intent.ACTION_CREATE_DOCUMENT).apply {
-            addCategory(Intent.CATEGORY_OPENABLE)
-            setType("application/vnd.ms-excel")
-            putExtra(Intent.EXTRA_TITLE, viewModel.getExportFileName())
-            viewModel.newExcelFormat = false
+    override fun onOldExcelFormatClick(dialog: DialogFragment, type: ExportAlertDialogTypeEnum) {
+        viewModel.newExcelFormat = false
+        when (type) {
+            ExportAlertDialogTypeEnum.EXPORT -> {
+                val intent = Intent(Intent.ACTION_CREATE_DOCUMENT).apply {
+                    addCategory(Intent.CATEGORY_OPENABLE)
+                    setType("application/vnd.ms-excel")
+                    putExtra(Intent.EXTRA_TITLE, viewModel.getExportFileName())
+                }
+                resultLauncher.launch(intent)
+            }
+
+            ExportAlertDialogTypeEnum.SEND_EMAIL -> {
+                sendEmail()
+            }
         }
-        resultLauncher.launch(intent)
     }
 
-    private var resultLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
-        if (result.resultCode == Activity.RESULT_OK) {
-            val data: Intent? = result.data
-            data?.data?.also {uri ->
-                viewModel.exportTransactionsToExcel(
-                    applicationContext.contentResolver, uri)
+    private fun sendEmail() {
+        lifecycleScope.launch {
+            val exportLoadDialog = ExportLoadDialogFragment()
+
+            exportLoadDialog.show(supportFragmentManager, "LOAD_DIALOG")
+            val intent = viewModel.createEmailIntent(applicationContext)
+            exportLoadDialog.dismiss()
+
+            if (intent.resolveActivity(packageManager) != null) {
+                startActivity(Intent.createChooser(intent, "Choose email app.."))
             }
         }
     }
+
+    private var resultLauncher =
+        registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
+            if (result.resultCode == Activity.RESULT_OK) {
+                val data: Intent? = result.data
+                data?.data?.also { uri ->
+                    lifecycleScope.launch {
+                        viewModel.exportTransactionsToExcel(
+                            applicationContext.contentResolver, uri
+                        )
+                    }
+                }
+            }
+        }
 }
\ No newline at end of file
diff --git a/app/src/main/java/com/example/abe/MainActivityViewModel.kt b/app/src/main/java/com/example/abe/MainActivityViewModel.kt
index ecb143ad5f294243fb29e6240aa47fdde2aaf97e..10860c081fb0a7dbd90fa400127a1393c496743b 100644
--- a/app/src/main/java/com/example/abe/MainActivityViewModel.kt
+++ b/app/src/main/java/com/example/abe/MainActivityViewModel.kt
@@ -1,13 +1,16 @@
 package com.example.abe
 
 import android.content.ContentResolver
+import android.content.Context
+import android.content.Intent
 import android.net.Uri
+import androidx.core.content.FileProvider
 import androidx.lifecycle.ViewModel
 import androidx.lifecycle.ViewModelProvider
 import com.example.abe.data.TransactionRepository
 import com.example.abe.domain.FormatCurrencyUseCase
 import com.example.abe.domain.GenerateExcelUseCase
-import com.example.abe.ui.transactions.TransactionViewModel
+import java.io.File
 import java.text.SimpleDateFormat
 import java.util.Date
 import java.util.Locale
@@ -20,7 +23,7 @@ class MainActivityViewModel(private val transactionRepository: TransactionReposi
         return "Daftar-Transaksi_$date"
     }
 
-    fun exportTransactionsToExcel(contentResolver: ContentResolver, uri: Uri) {
+    suspend fun exportTransactionsToExcel(contentResolver: ContentResolver, uri: Uri) {
         val headerList = listOf("ID Transaksi", "Email", "Judul", "Nominal", "Pengeluaran", "Waktu Transasksi")
         val transactions = transactionRepository.allTransaction.value
         val dataList = mutableListOf<List<String>>()
@@ -43,6 +46,35 @@ class MainActivityViewModel(private val transactionRepository: TransactionReposi
         val generateExcel = GenerateExcelUseCase(newExcelFormat, contentResolver,  uri, "Transaksi", headerList, dataList)
         generateExcel()
     }
+
+    suspend fun createEmailIntent(context: Context): Intent {
+        clearExportCacheFiles(context)
+        val newFile = File(context.externalCacheDir, if (newExcelFormat) "export.xlsx" else "export.xls")
+        val contentUri =
+            FileProvider.getUriForFile(context, "com.example.abe.fileprovider", newFile)
+        exportTransactionsToExcel(context.contentResolver, contentUri)
+
+        val intent = Intent(Intent.ACTION_SEND).apply {
+            putExtra(Intent.EXTRA_EMAIL, arrayOf("13521134@std.stei.itb.ac.id"))
+            putExtra(Intent.EXTRA_SUBJECT, "test subject")
+
+            addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
+            setDataAndType(contentUri, context.contentResolver.getType(contentUri))
+            putExtra(Intent.EXTRA_STREAM, contentUri)
+        }
+
+        return intent
+    }
+
+    fun clearExportCacheFiles(context: Context) {
+        context.externalCacheDir?.apply {
+            val files = listFiles() ?: emptyArray()
+            files.forEach { file ->
+                if (file.name.startsWith("export"))
+                    file.delete()
+            }
+        }
+    }
 }
 
 class MainActivityViewModelFactory(private val repository: TransactionRepository): ViewModelProvider.Factory {
diff --git a/app/src/main/java/com/example/abe/domain/GenerateExcelUseCase.kt b/app/src/main/java/com/example/abe/domain/GenerateExcelUseCase.kt
index 357dff8a784172d1f4917e6a764bf3ce076e3af9..7764d3cd64172152c8153ee919b8b52ae57aa278 100644
--- a/app/src/main/java/com/example/abe/domain/GenerateExcelUseCase.kt
+++ b/app/src/main/java/com/example/abe/domain/GenerateExcelUseCase.kt
@@ -3,9 +3,9 @@ package com.example.abe.domain
 import android.content.ContentResolver
 import android.net.Uri
 import android.util.Log
-import org.apache.poi.hssf.usermodel.HSSFCellStyle
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.withContext
 import org.apache.poi.hssf.usermodel.HSSFWorkbook
-import org.apache.poi.hssf.util.HSSFColor
 import org.apache.poi.ss.usermodel.CellStyle
 import org.apache.poi.ss.usermodel.FillPatternType
 import org.apache.poi.ss.usermodel.IndexedColors
@@ -15,10 +15,6 @@ import org.apache.poi.ss.usermodel.Workbook
 import org.apache.poi.xssf.usermodel.IndexedColorMap
 import org.apache.poi.xssf.usermodel.XSSFColor
 import org.apache.poi.xssf.usermodel.XSSFWorkbook
-import java.io.File
-import java.io.FileOutputStream
-import java.net.URI
-import kotlin.io.path.toPath
 
 class GenerateExcelUseCase(
     private val newFormat: Boolean,
@@ -28,20 +24,25 @@ class GenerateExcelUseCase(
     private val headerList: List<String>,
     private val dataList: List<List<String>>
 ) {
-    operator fun invoke() {
-        val workbook = createWorkbook()
-
-        try {
-            val outputStream = contentResolver.openOutputStream(uri)
-            workbook.write(outputStream)
-            outputStream?.close()
-        } catch (e: Exception) {
-            e.printStackTrace()
+    suspend operator fun invoke() {
+        withContext(Dispatchers.Default) {
+            val workbook = createWorkbook()
+
+            withContext(Dispatchers.IO) {
+                try {
+                    val outputStream = contentResolver.openOutputStream(uri)
+                    workbook.write(outputStream)
+                    outputStream?.close()
+                    Log.d("ABE-EXPORT", "Finish writing file")
+                } catch (e: Exception) {
+                    e.printStackTrace()
+                }
+            }
         }
     }
 
     private fun createWorkbook(): Workbook {
-        val workbook = if(newFormat) XSSFWorkbook() else HSSFWorkbook()
+        val workbook = if (newFormat) XSSFWorkbook() else HSSFWorkbook()
         val sheet: Sheet = workbook.createSheet(sheetName)
 
         val cellStyle = getHeaderStyle(workbook)
@@ -70,7 +71,7 @@ class GenerateExcelUseCase(
         val cellStyle: CellStyle = workbook.createCellStyle()
 
         val colorMap: IndexedColorMap = (workbook as XSSFWorkbook).stylesSource.indexedColors
-        var color = XSSFColor(IndexedColors.LIGHT_CORNFLOWER_BLUE, colorMap).indexed
+        val color = XSSFColor(IndexedColors.LIGHT_CORNFLOWER_BLUE, colorMap).indexed
         cellStyle.fillForegroundColor = color
         cellStyle.fillPattern = FillPatternType.SOLID_FOREGROUND
 
@@ -85,7 +86,7 @@ class GenerateExcelUseCase(
             for ((colIndex, cellData) in rowList.withIndex()) {
                 createCell(row, colIndex, cellData)
             }
-         }
+        }
     }
 
     private fun createCell(row: Row, columnIndex: Int, value: String?) {
diff --git a/app/src/main/java/com/example/abe/ui/transactions/ExportAlertDialogFragment.kt b/app/src/main/java/com/example/abe/ui/transactions/ExportAlertDialogFragment.kt
index 5d80dfc237a8b9c55e3767b20aa7af3e1dd11cf8..5055babbecb4ef463fd94cda93903296d4a88efd 100644
--- a/app/src/main/java/com/example/abe/ui/transactions/ExportAlertDialogFragment.kt
+++ b/app/src/main/java/com/example/abe/ui/transactions/ExportAlertDialogFragment.kt
@@ -3,16 +3,33 @@ package com.example.abe.ui.transactions
 import android.app.AlertDialog
 import android.app.Dialog
 import android.content.Context
-import android.content.DialogInterface
 import android.os.Bundle
 import androidx.fragment.app.DialogFragment
 
-class ExportAlertDialogFragment: DialogFragment() {
-    internal lateinit var listener: ExportAlertDialogListener
+class ExportAlertDialogFragment : DialogFragment() {
+    private lateinit var listener: ExportAlertDialogListener
+    private lateinit var type: ExportAlertDialogTypeEnum
+
+    companion object {
+        private const val TYPE = "type"
+
+        fun newInstance(
+            type: ExportAlertDialogTypeEnum
+        ): ExportAlertDialogFragment = ExportAlertDialogFragment().apply {
+            arguments = Bundle().apply {
+                putString(TYPE, type.toString())
+            }
+        }
+    }
 
     interface ExportAlertDialogListener {
-        fun onNewExcelFormatClick(dialog: DialogFragment)
-        fun onOldExcelFormatClick(dialog: DialogFragment)
+        fun onNewExcelFormatClick(dialog: DialogFragment, type: ExportAlertDialogTypeEnum)
+        fun onOldExcelFormatClick(dialog: DialogFragment, type: ExportAlertDialogTypeEnum)
+    }
+
+    override fun onCreate(savedInstanceState: Bundle?) {
+        super.onCreate(savedInstanceState)
+        type = ExportAlertDialogTypeEnum.valueOf(arguments?.getString(TYPE) ?: "EXPORT")
     }
 
     override fun onAttach(context: Context) {
@@ -20,8 +37,10 @@ class ExportAlertDialogFragment: DialogFragment() {
         try {
             listener = context as ExportAlertDialogListener
         } catch (e: ClassCastException) {
-            throw ClassCastException((context.toString() +
-                    " must implement NoticeDialogListener"))
+            throw ClassCastException(
+                (context.toString() +
+                        " must implement NoticeDialogListener")
+            )
         }
     }
 
@@ -30,10 +49,10 @@ class ExportAlertDialogFragment: DialogFragment() {
             val builder = AlertDialog.Builder(it)
             builder.setMessage("Choose Excel File Format")
                 .setPositiveButton("Xlxs") { dialog, id ->
-                    listener.onNewExcelFormatClick(this)
+                    listener.onNewExcelFormatClick(this, type)
                 }
                 .setNegativeButton("Xls") { dialog, id ->
-                    listener.onOldExcelFormatClick(this)
+                    listener.onOldExcelFormatClick(this, type)
                 }
             builder.create()
         } ?: throw IllegalStateException("Activity cannot be null")
diff --git a/app/src/main/java/com/example/abe/ui/transactions/ExportAlertDialogTypeEnum.kt b/app/src/main/java/com/example/abe/ui/transactions/ExportAlertDialogTypeEnum.kt
new file mode 100644
index 0000000000000000000000000000000000000000..7812b2bfed3315afd441a6b9dc8ed78341ee9d1a
--- /dev/null
+++ b/app/src/main/java/com/example/abe/ui/transactions/ExportAlertDialogTypeEnum.kt
@@ -0,0 +1,6 @@
+package com.example.abe.ui.transactions
+
+enum class ExportAlertDialogTypeEnum {
+    SEND_EMAIL,
+    EXPORT
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/example/abe/ui/transactions/ExportLoadDialogFragment.kt b/app/src/main/java/com/example/abe/ui/transactions/ExportLoadDialogFragment.kt
new file mode 100644
index 0000000000000000000000000000000000000000..71a0d4d7e13a1047a0c2dccb840dbc84a5f2ff2c
--- /dev/null
+++ b/app/src/main/java/com/example/abe/ui/transactions/ExportLoadDialogFragment.kt
@@ -0,0 +1,20 @@
+package com.example.abe.ui.transactions
+
+import android.app.AlertDialog
+import android.app.Dialog
+import android.os.Bundle
+import androidx.fragment.app.DialogFragment
+import com.example.abe.R
+
+class ExportLoadDialogFragment: DialogFragment() {
+    override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
+        isCancelable = false
+        return activity?.let {
+            val builder = AlertDialog.Builder(it)
+
+            val inflater = requireActivity().layoutInflater
+            builder.setView(inflater.inflate(R.layout.dialog_load_excel, null))
+            builder.create()
+        } ?: throw IllegalStateException("Activity cannot be null")
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/example/abe/ui/transactions/TransactionFragment.kt b/app/src/main/java/com/example/abe/ui/transactions/TransactionFragment.kt
index 684ccf47ddfe62187e1a609dba5a1ea4f3697961..ddb0c363f660e446a7a14e4895edbfd331c01c68 100644
--- a/app/src/main/java/com/example/abe/ui/transactions/TransactionFragment.kt
+++ b/app/src/main/java/com/example/abe/ui/transactions/TransactionFragment.kt
@@ -1,6 +1,5 @@
 package com.example.abe.ui.transactions
 
-import android.content.Intent
 import android.os.Bundle
 import android.view.LayoutInflater
 import android.view.View
@@ -38,30 +37,20 @@ class TransactionFragment : Fragment() {
         binding.rvTransactions.adapter = transactionsAdapter
         binding.rvTransactions.layoutManager = LinearLayoutManager(context)
 
-        viewModel.allTransactions.observe(viewLifecycleOwner) {transactions ->
+        viewModel.allTransactions.observe(viewLifecycleOwner) { transactions ->
             transactions?.let {
                 transactionsAdapter.submitList(it)
             }
         }
 
         binding.fabExport.setOnClickListener {
-            ExportAlertDialogFragment().show(requireActivity().supportFragmentManager, "EXPORT_DIALOG")
+            ExportAlertDialogFragment.newInstance(ExportAlertDialogTypeEnum.EXPORT)
+                .show(requireActivity().supportFragmentManager, "EXPORT_DIALOG")
         }
 
         binding.fabEmail.setOnClickListener {
-            val contentUri = viewModel.generateExcelInCache(requireActivity().applicationContext)
-
-            val intent = Intent(Intent.ACTION_SEND).apply {
-                putExtra(Intent.EXTRA_EMAIL, arrayOf("13521134@std.stei.itb.ac.id"))
-                putExtra(Intent.EXTRA_SUBJECT, "test subject")
-
-                addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
-                setDataAndType(contentUri, requireContext().contentResolver.getType(contentUri))
-                putExtra(Intent.EXTRA_STREAM, contentUri)
-            }
-            if (intent.resolveActivity(requireActivity().packageManager) != null) {
-                startActivity(intent)
-            }
+            ExportAlertDialogFragment.newInstance(ExportAlertDialogTypeEnum.SEND_EMAIL)
+                .show(requireActivity().supportFragmentManager, "EXPORT_DIALOG")
         }
 
         return binding.root
diff --git a/app/src/main/java/com/example/abe/ui/transactions/TransactionViewModel.kt b/app/src/main/java/com/example/abe/ui/transactions/TransactionViewModel.kt
index 728824e7ecfedc59797c335ea9abbffe98e6dd6b..3e0b8126cb562afdd6d9a91b1f59fdf733afbe91 100644
--- a/app/src/main/java/com/example/abe/ui/transactions/TransactionViewModel.kt
+++ b/app/src/main/java/com/example/abe/ui/transactions/TransactionViewModel.kt
@@ -1,53 +1,17 @@
 package com.example.abe.ui.transactions
 
-import android.content.Context
-import android.net.Uri
-import androidx.core.content.FileProvider
 import androidx.lifecycle.ViewModel
 import androidx.lifecycle.ViewModelProvider
 import com.example.abe.data.TransactionRepository
-import com.example.abe.domain.FormatCurrencyUseCase
-import com.example.abe.domain.GenerateExcelUseCase
-import java.io.File
-import java.text.SimpleDateFormat
-import java.util.Locale
 
 
 class TransactionViewModel(private val transactionRepository: TransactionRepository) : ViewModel() {
 
     val allTransactions = transactionRepository.allTransaction
-
-    fun generateExcelInCache(context: Context): Uri {
-        val headerList = listOf("ID Transaksi", "Email", "Judul", "Nominal", "Pengeluaran", "Waktu Transasksi")
-        val transactions = transactionRepository.allTransaction.value
-        val dataList = mutableListOf<List<String>>()
-        val currencyFormatter = FormatCurrencyUseCase()
-
-        if (transactions != null) {
-            for (trx in transactions) {
-                val rowData = listOf<String>(
-                    trx.id.toString(),
-                    trx.email,
-                    trx.title,
-                    currencyFormatter(trx.amount),
-                    if (trx.isExpense) "Ya" else "Tidak",
-                    SimpleDateFormat("d MMM yyyy" , Locale.ENGLISH).format(trx.timestamp)
-                )
-                dataList.add(rowData)
-            }
-        }
-
-        val newFile = File(context.externalCacheDir, "export.xlsx")
-        val contentUri =
-            FileProvider.getUriForFile(context, "com.example.abe.fileprovider", newFile)
-        val generateExcel = GenerateExcelUseCase(true, context.contentResolver,  contentUri, "Transaksi", headerList, dataList)
-        generateExcel()
-
-        return contentUri
-    }
 }
 
-class TransactionViewModelFactory(private val repository: TransactionRepository): ViewModelProvider.Factory {
+class TransactionViewModelFactory(private val repository: TransactionRepository) :
+    ViewModelProvider.Factory {
     override fun <T : ViewModel> create(modelClass: Class<T>): T {
         if (modelClass.isAssignableFrom(TransactionViewModel::class.java)) {
             @Suppress("UNCHECKED_CAST")
diff --git a/app/src/main/res/layout/dialog_load_excel.xml b/app/src/main/res/layout/dialog_load_excel.xml
new file mode 100644
index 0000000000000000000000000000000000000000..51649f4b189d4c7af56fa928cd6a0e0265a37395
--- /dev/null
+++ b/app/src/main/res/layout/dialog_load_excel.xml
@@ -0,0 +1,30 @@
+<?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"
+    android:orientation="vertical"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:padding="24dp">
+
+    <TextView
+        android:id="@+id/textView"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:text="Loading File Attachment"
+        android:textColor="@android:color/black"
+        android:textSize="16sp"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toTopOf="parent" />
+
+    <com.google.android.material.progressindicator.CircularProgressIndicator
+        android:layout_width="64dp"
+        android:layout_height="62dp"
+        android:layout_marginTop="24dp"
+        android:indeterminate="true"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toBottomOf="@+id/textView"
+        app:trackThickness="5dp"
+        app:indicatorSize="50dp"/>
+
+</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file