update refresh change tab

This commit is contained in:
shaulascr
2025-07-02 08:53:16 +07:00
parent 331410eb98
commit f7f198e46f
5 changed files with 362 additions and 149 deletions

View File

@ -10,6 +10,7 @@ import com.alya.ecommerce_serang.data.api.dto.CompletedOrderRequest
import com.alya.ecommerce_serang.data.api.dto.OrdersItem import com.alya.ecommerce_serang.data.api.dto.OrdersItem
import com.alya.ecommerce_serang.data.api.response.customer.order.CancelOrderResponse import com.alya.ecommerce_serang.data.api.response.customer.order.CancelOrderResponse
import com.alya.ecommerce_serang.data.api.response.customer.order.OrderListItemsItem import com.alya.ecommerce_serang.data.api.response.customer.order.OrderListItemsItem
import com.alya.ecommerce_serang.data.api.response.customer.order.OrderListResponse
import com.alya.ecommerce_serang.data.api.response.customer.order.Orders import com.alya.ecommerce_serang.data.api.response.customer.order.Orders
import com.alya.ecommerce_serang.data.api.response.order.CompletedOrderResponse import com.alya.ecommerce_serang.data.api.response.order.CompletedOrderResponse
import com.alya.ecommerce_serang.data.repository.OrderRepository import com.alya.ecommerce_serang.data.repository.OrderRepository
@ -18,6 +19,13 @@ import com.alya.ecommerce_serang.ui.order.address.ViewState
import kotlinx.coroutines.async import kotlinx.coroutines.async
import kotlinx.coroutines.awaitAll import kotlinx.coroutines.awaitAll
import kotlinx.coroutines.coroutineScope import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import java.io.File import java.io.File
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
@ -29,8 +37,8 @@ class HistoryViewModel(private val repository: OrderRepository) : ViewModel() {
private const val TAG = "HistoryViewModel" private const val TAG = "HistoryViewModel"
} }
private val _orders = MutableLiveData<ViewState<List<OrdersItem>>>() // private val _orders = MutableLiveData<ViewState<List<OrdersItem>>>()
val orders: LiveData<ViewState<List<OrdersItem>>> = _orders // val orders: LiveData<ViewState<List<OrdersItem>>> = _orders
private val _orderCompletionStatus = MutableLiveData<Result<CompletedOrderResponse>>() private val _orderCompletionStatus = MutableLiveData<Result<CompletedOrderResponse>>()
val orderCompletionStatus: LiveData<Result<CompletedOrderResponse>> = _orderCompletionStatus val orderCompletionStatus: LiveData<Result<CompletedOrderResponse>> = _orderCompletionStatus
@ -59,81 +67,156 @@ class HistoryViewModel(private val repository: OrderRepository) : ViewModel() {
private val _error = MutableLiveData<String>() private val _error = MutableLiveData<String>()
val error: LiveData<String> get() = _error val error: LiveData<String> get() = _error
fun getOrderList(status: String) { private val _selectedStatus = MutableStateFlow("all")
_orders.value = ViewState.Loading val selectedStatus: StateFlow<String> = _selectedStatus.asStateFlow()
viewModelScope.launch {
try { val orders: StateFlow<ViewState<List<OrdersItem>>> =
if (status == "all") { _selectedStatus
// Get all orders by combining all statuses .flatMapLatest { status ->
getAllOrdersCombined() flow<ViewState<List<OrdersItem>>> {
} else { Log.d(TAG, "⏳ Loading orders for status = $status")
// Get orders for specific status emit(ViewState.Loading)
when (val result = repository.getOrderList(status)) {
is Result.Success -> { val viewState =
_orders.value = ViewState.Success(result.data.orders) if (status == "all") {
Log.d(TAG, "Orders loaded successfully: ${result.data.orders.size} items") getAllOrdersCombined().also {
Log.d(TAG, "✅ Combined orders size = ${(it as? ViewState.Success)?.data?.size}")
}
} else {
when (val r = repository.getOrderList(status)) {
is Result.Loading -> {
Log.d(TAG, " repository.getOrderList($status) → Loading")
ViewState.Loading
}
is Result.Success -> {
Log.d(TAG, "✅ repository.getOrderList($status) success, size = ${r.data.orders.size}")
// Tag each order so the fragments filter works
val tagged = r.data.orders.onEach { it.displayStatus = status }
ViewState.Success(tagged)
}
is Result.Error -> {
Log.e(TAG, "❌ repository.getOrderList($status) error = ${r.exception.message}")
ViewState.Error(r.exception.message ?: "Unknown error")
}
}
} }
is Result.Error -> {
_orders.value = ViewState.Error(result.exception.message ?: "Unknown error occurred") emit(viewState)
Log.e(TAG, "Error loading orders", result.exception)
}
is Result.Loading -> {
// Keep loading state
}
}
} }
} catch (e: Exception) {
_orders.value = ViewState.Error("An unexpected error occurred: ${e.message}")
Log.e(TAG, "Exception in getOrderList", e)
} }
} .stateIn(
} viewModelScope,
SharingStarted.WhileSubscribed(5_000),
ViewState.Loading // ② initial value, still fine
)
private suspend fun getAllOrdersCombined() {
try {
val allStatuses = listOf("unpaid", "paid", "processed", "shipped", "completed", "canceled")
val allOrders = mutableListOf<OrdersItem>()
// Use coroutineScope to allow launching async blocks // fun getOrderList(status: String) {
coroutineScope { // _orders.value = ViewState.Loading
val deferreds = allStatuses.map { status -> // viewModelScope.launch {
// try {
// if (status == "all") {
// // Get all orders by combining all statuses
// getAllOrdersCombined()
// } else {
// // Get orders for specific status
// when (val result = repository.getOrderList(status)) {
// is Result.Success -> {
// _orders.value = ViewState.Success(result.data.orders)
// Log.d(TAG, "Orders loaded successfully: ${result.data.orders.size} items")
// }
// is Result.Error -> {
// _orders.value = ViewState.Error(result.exception.message ?: "Unknown error occurred")
// Log.e(TAG, "Error loading orders", result.exception)
// }
// is Result.Loading -> {
// // Keep loading state
// }
// }
// }
// } catch (e: Exception) {
// _orders.value = ViewState.Error("An unexpected error occurred: ${e.message}")
// Log.e(TAG, "Exception in getOrderList", e)
// }
// }
// }
// private suspend fun getAllOrdersCombined() {
// try {
// val allStatuses = listOf("unpaid", "paid", "processed", "shipped", "completed", "canceled")
// val allOrders = mutableListOf<OrdersItem>()
//
// // Use coroutineScope to allow launching async blocks
// coroutineScope {
// val deferreds = allStatuses.map { status ->
// async {
// when (val result = repository.getOrderList(status)) {
// is Result.Success -> {
// // Tag each order with the status it was fetched from
// result.data.orders.onEach { it.displayStatus = status }
// }
// is Result.Error -> {
// Log.e(TAG, "Error loading orders for status $status", result.exception)
// emptyList<OrdersItem>()
// }
// is Result.Loading -> emptyList<OrdersItem>()
// }
// }
// }
//
// // Await all results and combine
// deferreds.awaitAll().forEach { orders ->
// allOrders.addAll(orders)
// }
// }
//
// // Sort orders
// val sortedOrders = allOrders.sortedByDescending { order ->
// try {
// SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.getDefault()).parse(order.createdAt)
// } catch (e: Exception) {
// null
// }
// }
//
// _orders.value = ViewState.Success(sortedOrders)
// Log.d(TAG, "All orders loaded successfully: ${sortedOrders.size} items")
//
// } catch (e: Exception) {
// _orders.value = ViewState.Error("An unexpected error occurred: ${e.message}")
// Log.e(TAG, "Exception in getAllOrdersCombined", e)
// }
// }
private suspend fun getAllOrdersCombined(): ViewState<List<OrdersItem>> = try {
val statuses = listOf("unpaid", "paid", "processed", "shipped", "completed", "canceled")
val all = coroutineScope {
statuses
.map { status ->
async { async {
when (val result = repository.getOrderList(status)) { when (val r = repository.getOrderList(status)) {
is Result.Success -> { is Result.Success -> r.data.orders.onEach { it.displayStatus = status }
// Tag each order with the status it was fetched from else -> emptyList()
result.data.orders.onEach { it.displayStatus = status }
}
is Result.Error -> {
Log.e(TAG, "Error loading orders for status $status", result.exception)
emptyList<OrdersItem>()
}
is Result.Loading -> emptyList<OrdersItem>()
} }
} }
} }
.awaitAll()
// Await all results and combine .flatten()
deferreds.awaitAll().forEach { orders ->
allOrders.addAll(orders)
}
}
// Sort orders
val sortedOrders = allOrders.sortedByDescending { order ->
try {
SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.getDefault()).parse(order.createdAt)
} catch (e: Exception) {
null
}
}
_orders.value = ViewState.Success(sortedOrders)
Log.d(TAG, "All orders loaded successfully: ${sortedOrders.size} items")
} catch (e: Exception) {
_orders.value = ViewState.Error("An unexpected error occurred: ${e.message}")
Log.e(TAG, "Exception in getAllOrdersCombined", e)
} }
val sorted = all.sortedByDescending { order ->
try {
SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.getDefault())
.parse(order.createdAt)
} catch (_: Exception) { null }
}
ViewState.Success(sorted)
} catch (e: Exception) {
ViewState.Error("Failed to load orders: ${e.message}")
} }
fun confirmOrderCompleted(orderId: Int, status: String) { fun confirmOrderCompleted(orderId: Int, status: String) {
@ -209,9 +292,52 @@ class HistoryViewModel(private val repository: OrderRepository) : ViewModel() {
} }
} }
fun refreshOrders(status: String = "all") { // fun refreshOrders(status: String = "all") {
Log.d(TAG, "Refreshing orders with status: $status") // Log.d(TAG, "Refreshing orders with status: $status")
// Don't set Loading here if you want to show current data while refreshing // // Don't set Loading here if you want to show current data while refreshing
getOrderList(status) // getOrderList(status)
// }
fun updateStatus(status: String, forceRefresh: Boolean = false) {
Log.d(TAG, "↪️ updateStatus(status = $status, forceRefresh = $forceRefresh)")
// Noop guard (optional): skip if user reselects same tab and no refresh asked
if (_selectedStatus.value == status && !forceRefresh) {
Log.d(TAG, "🔸 Status unchanged & forceRefresh = false → skip update")
return
}
_selectedStatus.value = status
Log.d(TAG, "✅ _selectedStatus set to \"$status\"")
if (forceRefresh) {
Log.d(TAG, "🔄 forceRefresh = true → launching refresh()")
viewModelScope.launch { refresh(status) }
}
} }
private suspend fun refresh(status: String) {
Log.d(TAG, "⏳ refresh(\"$status\") started")
try {
if (status == "all") {
Log.d(TAG, "🌐 Calling getAllOrdersCombined()")
getAllOrdersCombined() // network → cache
} else {
Log.d(TAG, "🌐 repository.getOrderList(\"$status\")")
repository.getOrderList(status) // network → cache
}
Log.d(TAG, "✅ refresh(\"$status\") completed (repository updated)")
// Flow that watches DB/cache will emit automatically
} catch (e: Exception) {
Log.e(TAG, "❌ refresh(\"$status\") failed: ${e.message}", e)
}
}
private fun Result<OrderListResponse>.toViewState(): ViewState<List<OrdersItem>> =
when (this) {
is Result.Success -> ViewState.Success(data.orders)
is Result.Error -> ViewState.Error(exception.message ?: "Unknown error")
is Result.Loading -> ViewState.Loading // should rarely reach UI
}
} }

View File

@ -195,7 +195,7 @@ class OrderHistoryAdapter(
text = itemView.context.getString(R.string.canceled_order_btn) text = itemView.context.getString(R.string.canceled_order_btn)
setOnClickListener { setOnClickListener {
showCancelOrderDialog(order.orderId.toString()) showCancelOrderDialog(order.orderId.toString())
viewModel.refreshOrders() // viewModel.refreshOrders()
} }
} }
// deadlineDate.apply { // deadlineDate.apply {
@ -238,7 +238,7 @@ class OrderHistoryAdapter(
text = itemView.context.getString(R.string.claim_complaint) text = itemView.context.getString(R.string.claim_complaint)
setOnClickListener { setOnClickListener {
showCancelOrderDialog(order.orderId.toString()) showCancelOrderDialog(order.orderId.toString())
viewModel.refreshOrders() // viewModel.refreshOrders()
} }
} }
btnRight.apply { btnRight.apply {
@ -249,7 +249,7 @@ class OrderHistoryAdapter(
// Call ViewModel // Call ViewModel
viewModel.confirmOrderCompleted(order.orderId, "completed") viewModel.confirmOrderCompleted(order.orderId, "completed")
viewModel.refreshOrders() // viewModel.refreshOrders()
} }

View File

@ -5,8 +5,13 @@ import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
import androidx.viewpager2.widget.ViewPager2
import com.alya.ecommerce_serang.R import com.alya.ecommerce_serang.R
import com.alya.ecommerce_serang.data.api.retrofit.ApiConfig
import com.alya.ecommerce_serang.data.repository.OrderRepository
import com.alya.ecommerce_serang.databinding.FragmentOrderHistoryBinding import com.alya.ecommerce_serang.databinding.FragmentOrderHistoryBinding
import com.alya.ecommerce_serang.utils.BaseViewModelFactory
import com.alya.ecommerce_serang.utils.SessionManager import com.alya.ecommerce_serang.utils.SessionManager
import com.google.android.material.tabs.TabLayoutMediator import com.google.android.material.tabs.TabLayoutMediator
@ -16,6 +21,12 @@ class OrderHistoryFragment : Fragment() {
private val binding get() = _binding!! private val binding get() = _binding!!
private lateinit var sessionManager: SessionManager private lateinit var sessionManager: SessionManager
private val historyVm: HistoryViewModel by activityViewModels {
BaseViewModelFactory {
val api = ApiConfig.getApiService(SessionManager(requireContext()))
HistoryViewModel(OrderRepository(api))
}
}
private lateinit var viewPagerAdapter: OrderViewPagerAdapter private lateinit var viewPagerAdapter: OrderViewPagerAdapter
@ -33,6 +44,8 @@ class OrderHistoryFragment : Fragment() {
sessionManager = SessionManager(requireContext()) sessionManager = SessionManager(requireContext())
setupViewPager() setupViewPager()
} }
private fun setupViewPager() { private fun setupViewPager() {
@ -53,6 +66,16 @@ class OrderHistoryFragment : Fragment() {
else -> "Tab $position" else -> "Tab $position"
} }
}.attach() }.attach()
binding.viewPager.registerOnPageChangeCallback(
object : ViewPager2.OnPageChangeCallback() {
override fun onPageSelected(position: Int) {
val status = viewPagerAdapter.orderStatuses[position]
/* setStatus() is the API we added earlier; TRUE → always requery */
historyVm.updateStatus(status, forceRefresh = true)
}
}
)
} }
override fun onDestroyView() { override fun onDestroyView() {

View File

@ -8,8 +8,10 @@ import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.Toast import android.widget.Toast
import androidx.activity.result.contract.ActivityResultContracts import androidx.activity.result.contract.ActivityResultContracts
import androidx.core.view.isVisible
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.fragment.app.viewModels import androidx.fragment.app.activityViewModels
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import com.alya.ecommerce_serang.data.api.dto.OrdersItem import com.alya.ecommerce_serang.data.api.dto.OrdersItem
import com.alya.ecommerce_serang.data.api.retrofit.ApiConfig import com.alya.ecommerce_serang.data.api.retrofit.ApiConfig
@ -27,17 +29,26 @@ class OrderListFragment : Fragment(), OrderHistoryAdapter.OrderActionCallbacks {
private val binding get() = _binding!! private val binding get() = _binding!!
private lateinit var sessionManager: SessionManager private lateinit var sessionManager: SessionManager
private val viewModel: HistoryViewModel by viewModels { private val viewModel: HistoryViewModel by activityViewModels {
BaseViewModelFactory { BaseViewModelFactory {
val apiService = ApiConfig.getApiService(sessionManager) val api = ApiConfig.getApiService(SessionManager(requireContext()))
val orderRepository = OrderRepository(apiService) HistoryViewModel(OrderRepository(api))
HistoryViewModel(orderRepository)
} }
} }
private lateinit var orderAdapter: OrderHistoryAdapter private lateinit var orderAdapter: OrderHistoryAdapter
private var status: String = "all" private var status: String = "all"
private val detailOrderLauncher = registerForActivityResult(
ActivityResultContracts.StartActivityForResult()
) { result ->
if (result.resultCode == Activity.RESULT_OK) {
/* forcerefresh the current tab */
viewModel.updateStatus(status, forceRefresh = true)
}
}
companion object { companion object {
private const val ARG_STATUS = "status" private const val ARG_STATUS = "status"
@ -73,8 +84,8 @@ class OrderListFragment : Fragment(), OrderHistoryAdapter.OrderActionCallbacks {
setupRecyclerView() setupRecyclerView()
observeOrderList() observeOrderList()
observeViewModel() observeViewModel()
observeOrderCompletionStatus() // observeOrderCompletionStatus()
loadOrders() // loadOrders()
} }
private fun setupRecyclerView() { private fun setupRecyclerView() {
@ -96,27 +107,50 @@ class OrderListFragment : Fragment(), OrderHistoryAdapter.OrderActionCallbacks {
private fun observeOrderList() { private fun observeOrderList() {
// Now we only need to observe one LiveData for all cases // Now we only need to observe one LiveData for all cases
viewModel.orders.observe(viewLifecycleOwner) { result -> // viewModel.orders.observe(viewLifecycleOwner) { result ->
when (result) { // when (result) {
is ViewState.Success -> { // is ViewState.Success -> {
binding.progressBar.visibility = View.GONE // binding.progressBar.visibility = View.GONE
//
if (result.data.isNullOrEmpty()) { // if (result.data.isNullOrEmpty()) {
binding.tvEmptyState.visibility = View.VISIBLE // binding.tvEmptyState.visibility = View.VISIBLE
binding.rvOrders.visibility = View.GONE // binding.rvOrders.visibility = View.GONE
} else { // } else {
binding.tvEmptyState.visibility = View.GONE // binding.tvEmptyState.visibility = View.GONE
binding.rvOrders.visibility = View.VISIBLE // binding.rvOrders.visibility = View.VISIBLE
orderAdapter.submitList(result.data) // orderAdapter.submitList(result.data)
// }
// }
// is ViewState.Error -> {
// binding.progressBar.visibility = View.GONE
// binding.tvEmptyState.visibility = View.VISIBLE
// Toast.makeText(requireContext(), result.message, Toast.LENGTH_SHORT).show()
// }
// is ViewState.Loading -> {
// binding.progressBar.visibility = View.VISIBLE
// }
// }
// }
viewLifecycleOwner.lifecycleScope.launchWhenStarted {
viewModel.orders.collect { state ->
when (state) {
is ViewState.Loading -> {
binding.progressBar.isVisible = true
}
is ViewState.Error -> {
binding.progressBar.isVisible = false
binding.tvEmptyState.isVisible = true
binding.rvOrders.isVisible = false
Toast.makeText(requireContext(), state.message, Toast.LENGTH_SHORT).show()
}
is ViewState.Success -> {
binding.progressBar.isVisible = false
val list = state.data
.filter { status == "all" || it.displayStatus == status }
binding.tvEmptyState.isVisible = list.isEmpty()
binding.rvOrders.isVisible = list.isNotEmpty()
orderAdapter.submitList(list)
} }
}
is ViewState.Error -> {
binding.progressBar.visibility = View.GONE
binding.tvEmptyState.visibility = View.VISIBLE
Toast.makeText(requireContext(), result.message, Toast.LENGTH_SHORT).show()
}
is ViewState.Loading -> {
binding.progressBar.visibility = View.VISIBLE
} }
} }
} }
@ -124,51 +158,78 @@ class OrderListFragment : Fragment(), OrderHistoryAdapter.OrderActionCallbacks {
private fun observeViewModel() { private fun observeViewModel() {
// Observe order completion // Observe order completion
// viewModel.orderCompletionStatus.observe(viewLifecycleOwner) { result ->
// when (result) {
// is Result.Success -> {
// Toast.makeText(requireContext(), "Order completed successfully!", Toast.LENGTH_SHORT).show()
//// loadOrders() // Refresh here
// }
// is Result.Error -> {
// Toast.makeText(requireContext(), "Failed: ${result.exception.message}", Toast.LENGTH_SHORT).show()
// }
// is Result.Loading -> {
// // Show loading if needed
// }
// }
// }
//
// // Observe cancel order status
// viewModel.cancelOrderStatus.observe(viewLifecycleOwner) { result ->
// when (result) {
// is Result.Success -> {
// Toast.makeText(requireContext(), "Order cancelled successfully!", Toast.LENGTH_SHORT).show()
// loadOrders() // Refresh here
// }
// is Result.Error -> {
// Toast.makeText(requireContext(), "Failed to cancel: ${result.exception.message}", Toast.LENGTH_SHORT).show()
// }
// is Result.Loading -> {
// // Show loading if needed
// }
// }
// }
viewModel.orderCompletionStatus.observe(viewLifecycleOwner) { result -> viewModel.orderCompletionStatus.observe(viewLifecycleOwner) { result ->
when (result) { when (result) {
is Result.Success -> { is Result.Success -> {
Toast.makeText(requireContext(), "Order completed successfully!", Toast.LENGTH_SHORT).show() Toast.makeText(requireContext(),
loadOrders() // Refresh here "Order completed!", Toast.LENGTH_SHORT).show()
} viewModel.updateStatus(status, forceRefresh = true)
is Result.Error -> {
Toast.makeText(requireContext(), "Failed: ${result.exception.message}", Toast.LENGTH_SHORT).show()
}
is Result.Loading -> {
// Show loading if needed
} }
is Result.Error ->
Toast.makeText(requireContext(),
"Failed: ${result.exception.message}", Toast.LENGTH_SHORT).show()
else -> { /* Loading → no UI change */ }
} }
} }
// Observe cancel order status
viewModel.cancelOrderStatus.observe(viewLifecycleOwner) { result -> viewModel.cancelOrderStatus.observe(viewLifecycleOwner) { result ->
when (result) { when (result) {
is Result.Success -> { is Result.Success -> {
Toast.makeText(requireContext(), "Order cancelled successfully!", Toast.LENGTH_SHORT).show() Toast.makeText(requireContext(),
loadOrders() // Refresh here "Order cancelled!", Toast.LENGTH_SHORT).show()
} viewModel.updateStatus(status, forceRefresh = true)
is Result.Error -> {
Toast.makeText(requireContext(), "Failed to cancel: ${result.exception.message}", Toast.LENGTH_SHORT).show()
}
is Result.Loading -> {
// Show loading if needed
} }
is Result.Error ->
Toast.makeText(requireContext(),
"Failed: ${result.exception.message}", Toast.LENGTH_SHORT).show()
else -> { /* Loading */ }
} }
} }
} }
private fun loadOrders() { // private fun loadOrders() {
// Simple - just call getOrderList for any status including "all" // // Simple - just call getOrderList for any status including "all"
viewModel.getOrderList(status) // viewModel.getOrderList(status)
} // }
private val detailOrderLauncher = registerForActivityResult( // private val detailOrderLauncher = registerForActivityResult(
ActivityResultContracts.StartActivityForResult() // ActivityResultContracts.StartActivityForResult()
) { result -> // ) { result ->
if (result.resultCode == Activity.RESULT_OK) { // if (result.resultCode == Activity.RESULT_OK) {
// Refresh order list when returning with OK result // // Refresh order list when returning with OK result
loadOrders() //// loadOrders()
} // }
} // }
private fun navigateToOrderDetail(order: OrdersItem) { private fun navigateToOrderDetail(order: OrdersItem) {
val intent = Intent(requireContext(), DetailOrderStatusActivity::class.java).apply { val intent = Intent(requireContext(), DetailOrderStatusActivity::class.java).apply {
@ -183,7 +244,9 @@ class OrderListFragment : Fragment(), OrderHistoryAdapter.OrderActionCallbacks {
override fun onOrderCancelled(orderId: String, success: Boolean, message: String) { override fun onOrderCancelled(orderId: String, success: Boolean, message: String) {
if (success) { if (success) {
Toast.makeText(requireContext(), message, Toast.LENGTH_SHORT).show() Toast.makeText(requireContext(), message, Toast.LENGTH_SHORT).show()
loadOrders() // Refresh the list // loadOrders() // Refresh the list
if (success) viewModel.updateStatus(status, forceRefresh = true)
} else { } else {
Toast.makeText(requireContext(), message, Toast.LENGTH_SHORT).show() Toast.makeText(requireContext(), message, Toast.LENGTH_SHORT).show()
} }
@ -192,7 +255,8 @@ class OrderListFragment : Fragment(), OrderHistoryAdapter.OrderActionCallbacks {
override fun onOrderCompleted(orderId: Int, success: Boolean, message: String) { override fun onOrderCompleted(orderId: Int, success: Boolean, message: String) {
if (success) { if (success) {
Toast.makeText(requireContext(), message, Toast.LENGTH_SHORT).show() Toast.makeText(requireContext(), message, Toast.LENGTH_SHORT).show()
loadOrders() // Refresh the list // loadOrders() // Refresh the list
if (success) viewModel.updateStatus(status, forceRefresh = true)
} else { } else {
Toast.makeText(requireContext(), message, Toast.LENGTH_SHORT).show() Toast.makeText(requireContext(), message, Toast.LENGTH_SHORT).show()
} }
@ -207,20 +271,20 @@ class OrderListFragment : Fragment(), OrderHistoryAdapter.OrderActionCallbacks {
_binding = null _binding = null
} }
private fun observeOrderCompletionStatus() { // private fun observeOrderCompletionStatus() {
viewModel.orderCompletionStatus.observe(viewLifecycleOwner) { result -> // viewModel.orderCompletionStatus.observe(viewLifecycleOwner) { result ->
when (result) { // when (result) {
is Result.Loading -> { // is Result.Loading -> {
// Handle loading state if needed // // Handle loading state if needed
} // }
is Result.Success -> { // is Result.Success -> {
Toast.makeText(requireContext(), "Order completed successfully!", Toast.LENGTH_SHORT).show() // Toast.makeText(requireContext(), "Order completed successfully!", Toast.LENGTH_SHORT).show()
loadOrders() //// loadOrders()
} // }
is Result.Error -> { // is Result.Error -> {
Toast.makeText(requireContext(), "Failed to complete order: ${result.exception.message}", Toast.LENGTH_SHORT).show() // Toast.makeText(requireContext(), "Failed to complete order: ${result.exception.message}", Toast.LENGTH_SHORT).show()
} // }
} // }
} // }
} // }
} }

View File

@ -9,7 +9,7 @@ class OrderViewPagerAdapter(
) : FragmentStateAdapter(fragmentActivity) { ) : FragmentStateAdapter(fragmentActivity) {
// Define all possible order statuses // Define all possible order statuses
private val orderStatuses = listOf( val orderStatuses = listOf(
"all", // All orders "all", // All orders
"unpaid", // Menunggu Tagihan "unpaid", // Menunggu Tagihan
"paid", // Belum Dibayar "paid", // Belum Dibayar