Merge branch 'screen-features'

This commit is contained in:
shaulascr
2025-05-28 17:33:06 +07:00
6 changed files with 107 additions and 34 deletions

View File

@ -27,7 +27,7 @@ data class OrdersItem(
val street: String,
@field:SerializedName("cancel_date")
val cancelDate: String? = null,
val cancelDate: String,
@field:SerializedName("longitude")
val longitude: String,
@ -42,7 +42,7 @@ data class OrdersItem(
val autoCompletedAt: String? = null,
@field:SerializedName("is_store_location")
val isStoreLocation: Boolean? = null,
val isStoreLocation: Boolean? = false,
@field:SerializedName("voucher_name")
val voucherName: String? = null,
@ -81,7 +81,7 @@ data class OrdersItem(
val paymentInfoId: Int? = null,
@field:SerializedName("detail")
val detail: String,
val detail: String? = null,
@field:SerializedName("postal_code")
val postalCode: String,
@ -90,5 +90,7 @@ data class OrdersItem(
val orderId: Int,
@field:SerializedName("city_id")
val cityId: Int
val cityId: Int,
var displayStatus: String? = null
)

View File

@ -511,4 +511,5 @@ class OrderRepository(private val apiService: ApiService) {
}
}
}

View File

@ -15,8 +15,13 @@ 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.Result
import com.alya.ecommerce_serang.ui.order.address.ViewState
import kotlinx.coroutines.async
import kotlinx.coroutines.awaitAll
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.launch
import java.io.File
import java.text.SimpleDateFormat
import java.util.Locale
class HistoryViewModel(private val repository: OrderRepository) : ViewModel() {
@ -57,28 +62,80 @@ class HistoryViewModel(private val repository: OrderRepository) : ViewModel() {
fun getOrderList(status: String) {
_orders.value = ViewState.Loading
viewModelScope.launch {
_orders.value = ViewState.Loading
try {
when (val result = repository.getOrderList(status)) {
is Result.Success -> {
_orders.value = ViewState.Success(result.data.orders)
Log.d("HistoryViewModel", "Orders loaded successfully: ${result.data.orders.size} items")
}
is Result.Error -> {
_orders.value = ViewState.Error(result.exception.message ?: "Unknown error occurred")
Log.e("HistoryViewModel", "Error loading orders", result.exception)
}
is Result.Loading -> {
null
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("HistoryViewModel", "Exception in getOrderList", e)
Log.e(TAG, "Exception in getOrderList", e)
}
}
}
private suspend fun getAllOrdersCombined() {
try {
val allStatuses = listOf("pending", "unpaid", "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)
}
}
fun confirmOrderCompleted(orderId: Int, status: String) {
Log.d(TAG, "Confirming order completed: orderId=$orderId, status=$status")
viewModelScope.launch {

View File

@ -119,8 +119,8 @@ class OrderHistoryAdapter(
onOrderClickListener(order)
}
//adjust each fragment
adjustButtonsAndText(fragmentStatus, order)
val actualStatus = if (fragmentStatus == "all") order.displayStatus ?: "" else fragmentStatus
adjustButtonsAndText(actualStatus, order)
}
@ -253,7 +253,7 @@ class OrderHistoryAdapter(
"completed" -> {
statusOrder.apply {
visibility = View.VISIBLE
text = itemView.context.getString(R.string.shipped_orders)
text = itemView.context.getString(R.string.completed_orders)
}
deadlineLabel.apply {
visibility = View.VISIBLE
@ -268,12 +268,26 @@ class OrderHistoryAdapter(
// Handle click event
}
}
deadlineDate.apply {
visibility = View.VISIBLE
text = formatDate(order.updatedAt)
}
}
"canceled" -> {
statusOrder.apply {
visibility = View.VISIBLE
text = itemView.context.getString(R.string.canceled_orders)
}
deadlineLabel.apply {
visibility = View.VISIBLE
text = itemView.context.getString(R.string.dl_canceled)
}
deadlineDate.apply {
visibility = View.VISIBLE
text = formatDate(order.cancelDate)
}
}
}
}

View File

@ -27,7 +27,6 @@ class OrderListFragment : Fragment() {
private val binding get() = _binding!!
private lateinit var sessionManager: SessionManager
private val viewModel: HistoryViewModel by viewModels {
BaseViewModelFactory {
val apiService = ApiConfig.getApiService(sessionManager)
@ -80,10 +79,9 @@ class OrderListFragment : Fragment() {
private fun setupRecyclerView() {
orderAdapter = OrderHistoryAdapter(
onOrderClickListener = { order ->
// Handle order click
navigateToOrderDetail(order)
},
viewModel = viewModel // Pass the ViewModel to the adapter
viewModel = viewModel
)
orderAdapter.setFragmentStatus(status)
@ -95,6 +93,7 @@ class OrderListFragment : Fragment() {
}
private fun observeOrderList() {
// Now we only need to observe one LiveData for all cases
viewModel.orders.observe(viewLifecycleOwner) { result ->
when (result) {
is ViewState.Success -> {
@ -115,13 +114,14 @@ class OrderListFragment : Fragment() {
Toast.makeText(requireContext(), result.message, Toast.LENGTH_SHORT).show()
}
is ViewState.Loading -> {
null
binding.progressBar.visibility = View.VISIBLE
}
}
}
}
private fun loadOrders() {
// Simple - just call getOrderList for any status including "all"
viewModel.getOrderList(status)
}
@ -130,15 +130,15 @@ class OrderListFragment : Fragment() {
) { result ->
if (result.resultCode == Activity.RESULT_OK) {
// Refresh order list when returning with OK result
viewModel.getOrderList(status)
loadOrders()
}
}
private fun navigateToOrderDetail(order: OrdersItem) {
val intent = Intent(requireContext(), DetailOrderStatusActivity::class.java).apply {
putExtra("ORDER_ID", order.orderId)
putExtra("ORDER_STATUS", status) // Pass the current status
}
val actualStatus = if (status == "all") order.displayStatus ?: "" else status
putExtra("ORDER_STATUS", actualStatus) }
detailOrderLauncher.launch(intent)
}
@ -147,11 +147,11 @@ class OrderListFragment : Fragment() {
_binding = null
}
private fun observeOrderCompletionStatus(){
viewModel.orderCompletionStatus.observe(viewLifecycleOwner){ result ->
when(result){
private fun observeOrderCompletionStatus() {
viewModel.orderCompletionStatus.observe(viewLifecycleOwner) { result ->
when (result) {
is Result.Loading -> {
// Handle loading state if needed
}
is Result.Success -> {
Toast.makeText(requireContext(), "Order completed successfully!", Toast.LENGTH_SHORT).show()
@ -163,5 +163,4 @@ class OrderListFragment : Fragment() {
}
}
}
}

View File

@ -85,7 +85,7 @@
<string name="dl_delivered">Semua Pesanan </string>
<string name="dl_completed">Semua Pesanan </string>
<string name="dl_shipped">Tanggal Pesanan Sampai</string>
<string name="dl_canceled">Semua Pesanan </string>
<string name="dl_canceled">Tanggal Pesanan Dibatalkan </string>
<string name="sent_evidence">Kirim Bukti Pembayaran </string>
<string name="canceled_order_btn">Batalkan Pesanan </string>