update display product list and paid status

This commit is contained in:
shaulascr
2025-06-17 16:20:30 +07:00
committed by Gracia Hotmauli
parent 6659ba4288
commit b37848e513
14 changed files with 181 additions and 152 deletions

View File

@ -12,7 +12,6 @@ import com.bumptech.glide.Glide
class HomeCategoryAdapter( class HomeCategoryAdapter(
private var categories:List<CategoryItem>, private var categories:List<CategoryItem>,
//A lambda function that will be invoked when a category item is clicked.
private val onClick:(category:CategoryItem) -> Unit private val onClick:(category:CategoryItem) -> Unit
): RecyclerView.Adapter<HomeCategoryAdapter.ViewHolder>() { ): RecyclerView.Adapter<HomeCategoryAdapter.ViewHolder>() {

View File

@ -15,7 +15,7 @@ import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle import androidx.lifecycle.repeatOnLifecycle
import androidx.navigation.findNavController import androidx.navigation.findNavController
import androidx.recyclerview.widget.GridLayoutManager import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView
import com.alya.ecommerce_serang.data.api.dto.CategoryItem import com.alya.ecommerce_serang.data.api.dto.CategoryItem
import com.alya.ecommerce_serang.data.api.dto.ProductsItem import com.alya.ecommerce_serang.data.api.dto.ProductsItem
import com.alya.ecommerce_serang.data.api.response.customer.product.StoreItem import com.alya.ecommerce_serang.data.api.response.customer.product.StoreItem
@ -83,20 +83,15 @@ class HomeFragment : Fragment() {
binding.newProducts.apply { binding.newProducts.apply {
adapter = productAdapter adapter = productAdapter
layoutManager = GridLayoutManager( layoutManager = GridLayoutManager(requireContext(), 2)
context,
2,
LinearLayoutManager.HORIZONTAL,
false
)
} }
binding.categories.apply { binding.categories.apply {
adapter = categoryAdapter adapter = categoryAdapter
layoutManager = GridLayoutManager( layoutManager = GridLayoutManager(
context, context,
3, 3, // 3 columns
LinearLayoutManager.HORIZONTAL, RecyclerView.VERTICAL, // vertical layout
false false
) )
} }

View File

@ -91,7 +91,7 @@ class HistoryViewModel(private val repository: OrderRepository) : ViewModel() {
private suspend fun getAllOrdersCombined() { private suspend fun getAllOrdersCombined() {
try { try {
val allStatuses = listOf("pending", "unpaid", "processed", "shipped", "completed", "canceled") val allStatuses = listOf("unpaid", "paid", "processed", "shipped", "completed", "canceled")
val allOrders = mutableListOf<OrdersItem>() val allOrders = mutableListOf<OrdersItem>()
// Use coroutineScope to allow launching async blocks // Use coroutineScope to allow launching async blocks
@ -211,10 +211,7 @@ 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")
// Clear current orders before fetching new ones // Don't set Loading here if you want to show current data while refreshing
_orders.value = ViewState.Loading
// Re-fetch the orders with the current status
getOrderList(status) getOrderList(status)
} }
} }

View File

@ -4,7 +4,6 @@ import android.app.Activity
import android.app.Dialog import android.app.Dialog
import android.content.ContextWrapper import android.content.ContextWrapper
import android.content.Intent import android.content.Intent
import android.graphics.Color
import android.net.Uri import android.net.Uri
import android.provider.MediaStore import android.provider.MediaStore
import android.util.Log import android.util.Log
@ -15,10 +14,10 @@ import android.view.Window
import android.widget.ArrayAdapter import android.widget.ArrayAdapter
import android.widget.AutoCompleteTextView import android.widget.AutoCompleteTextView
import android.widget.ImageView import android.widget.ImageView
import android.widget.ProgressBar
import android.widget.TextView import android.widget.TextView
import android.widget.Toast import android.widget.Toast
import androidx.fragment.app.FragmentActivity import androidx.fragment.app.FragmentActivity
import androidx.lifecycle.Observer
import androidx.lifecycle.findViewTreeLifecycleOwner import androidx.lifecycle.findViewTreeLifecycleOwner
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
@ -40,9 +39,16 @@ import java.util.TimeZone
class OrderHistoryAdapter( class OrderHistoryAdapter(
private val onOrderClickListener: (OrdersItem) -> Unit, private val onOrderClickListener: (OrdersItem) -> Unit,
private val viewModel: HistoryViewModel // Add this parameter private val viewModel: HistoryViewModel,
private val callbacks: OrderActionCallbacks
) : RecyclerView.Adapter<OrderHistoryAdapter.OrderViewHolder>() { ) : RecyclerView.Adapter<OrderHistoryAdapter.OrderViewHolder>() {
interface OrderActionCallbacks {
fun onOrderCancelled(orderId: String, success: Boolean, message: String)
fun onOrderCompleted(orderId: Int, success: Boolean, message: String)
fun onShowLoading(show: Boolean)
}
private val orders = mutableListOf<OrdersItem>() private val orders = mutableListOf<OrdersItem>()
private var fragmentStatus: String = "all" private var fragmentStatus: String = "all"
@ -140,28 +146,6 @@ class OrderHistoryAdapter(
deadlineLabel.visibility = View.GONE deadlineLabel.visibility = View.GONE
when (status) { when (status) {
"pending" -> {
statusOrder.apply {
visibility = View.VISIBLE
text = itemView.context.getString(R.string.pending_orders)
}
deadlineLabel.apply {
visibility = View.VISIBLE
text = itemView.context.getString(R.string.dl_pending)
}
btnLeft.apply {
visibility = View.VISIBLE
text = itemView.context.getString(R.string.canceled_order_btn)
setOnClickListener {
showCancelOrderBottomSheet(order.orderId)
viewModel.refreshOrders()
}
}
deadlineDate.apply {
visibility = View.VISIBLE
text = formatDate(order.createdAt)
}
}
"unpaid" -> { "unpaid" -> {
statusOrder.apply { statusOrder.apply {
visibility = View.VISIBLE visibility = View.VISIBLE
@ -176,7 +160,6 @@ class OrderHistoryAdapter(
text = itemView.context.getString(R.string.canceled_order_btn) text = itemView.context.getString(R.string.canceled_order_btn)
setOnClickListener { setOnClickListener {
showCancelOrderBottomSheet(order.orderId) showCancelOrderBottomSheet(order.orderId)
viewModel.refreshOrders()
} }
} }
@ -198,6 +181,28 @@ class OrderHistoryAdapter(
text = formatDatePay(order.updatedAt) text = formatDatePay(order.updatedAt)
} }
} }
"paid" -> {
statusOrder.apply {
visibility = View.VISIBLE
text = itemView.context.getString(R.string.paid_orders)
}
deadlineLabel.apply {
visibility = View.VISIBLE
text = itemView.context.getString(R.string.dl_paid)
}
btnLeft.apply {
visibility = View.VISIBLE
text = itemView.context.getString(R.string.canceled_order_btn)
setOnClickListener {
showCancelOrderDialog(order.orderId.toString())
viewModel.refreshOrders()
}
}
// deadlineDate.apply {
// visibility = View.VISIBLE
// text = formatDatePay(order.updatedAt)
// }
}
"processed" -> { "processed" -> {
// Untuk status processed, tampilkan "Hubungi Penjual" // Untuk status processed, tampilkan "Hubungi Penjual"
statusOrder.apply { statusOrder.apply {
@ -239,11 +244,14 @@ class OrderHistoryAdapter(
visibility = View.VISIBLE visibility = View.VISIBLE
text = itemView.context.getString(R.string.claim_order) text = itemView.context.getString(R.string.claim_order)
setOnClickListener { setOnClickListener {
// Handle click event callbacks.onShowLoading(true)
// Call ViewModel
viewModel.confirmOrderCompleted(order.orderId, "completed") viewModel.confirmOrderCompleted(order.orderId, "completed")
viewModel.refreshOrders() viewModel.refreshOrders()
} }
} }
deadlineDate.apply { deadlineDate.apply {
visibility = View.VISIBLE visibility = View.VISIBLE
@ -454,52 +462,32 @@ class OrderHistoryAdapter(
} }
} }
// Show loading indicator callbacks.onShowLoading(true)
val loadingView = View(context).apply {
layoutParams = ViewGroup.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT
)
setBackgroundColor(Color.parseColor("#80000000"))
val progressBar = ProgressBar(context).apply { // Call ViewModel method but don't observe here
layoutParams = ViewGroup.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT
)
}
// addView(progressBar)
// (progressBar.layoutParams as? ViewGroup.MarginLayoutParams)?.apply {
// gravity = Gravity.CENTER
// }
}
dialog.addContentView(loadingView, loadingView.layoutParams)
// Call the ViewModel to cancel the order with image
viewModel.cancelOrderWithImage(orderId, reason, imageFile) viewModel.cancelOrderWithImage(orderId, reason, imageFile)
// Observe for success/failure // Create a one-time observer that will be removed automatically
viewModel.isSuccess.observe(itemView.findViewTreeLifecycleOwner()!!) { isSuccess -> val observer = object : Observer<Boolean> {
// Remove loading indicator override fun onChanged(isSuccess: Boolean) {
(loadingView.parent as? ViewGroup)?.removeView(loadingView) callbacks.onShowLoading(false)
if (isSuccess) { if (isSuccess) {
Toast.makeText(context, context.getString(R.string.order_canceled_successfully), Toast.LENGTH_SHORT).show() val message = viewModel.message.value ?: context.getString(R.string.order_canceled_successfully)
dialog.dismiss() callbacks.onOrderCancelled(orderId, true, message)
dialog.dismiss()
// Find the order in the list and remove it or update its status } else {
val position = orders.indexOfFirst { it.orderId.toString() == orderId } val message = viewModel.message.value ?: context.getString(R.string.failed_to_cancel_order)
if (position != -1) { callbacks.onOrderCancelled(orderId, false, message)
orders.removeAt(position)
notifyItemRemoved(position)
notifyItemRangeChanged(position, orders.size)
} }
} else {
Toast.makeText(context, viewModel.message.value ?: context.getString(R.string.failed_to_cancel_order), Toast.LENGTH_SHORT).show() // Remove this observer after first use
viewModel.isSuccess.removeObserver(this)
} }
} }
// Add observer only once
viewModel.isSuccess.observe(itemView.findViewTreeLifecycleOwner()!!, observer)
} }
dialog.show() dialog.show()
} }
@ -534,10 +522,7 @@ class OrderHistoryAdapter(
val bottomSheet = CancelOrderBottomSheet( val bottomSheet = CancelOrderBottomSheet(
orderId = orderId, orderId = orderId,
onOrderCancelled = { onOrderCancelled = {
// Handle the successful cancellation callbacks.onOrderCancelled(orderId.toString(), true, "Order cancelled successfully")
// Refresh the data
viewModel.refreshOrders() // Assuming there's a method to refresh orders
// Show a success message // Show a success message
Toast.makeText(context, "Order cancelled successfully", Toast.LENGTH_SHORT).show() Toast.makeText(context, "Order cancelled successfully", Toast.LENGTH_SHORT).show()
} }

View File

@ -44,8 +44,8 @@ class OrderHistoryFragment : Fragment() {
TabLayoutMediator(binding.tabLayout, binding.viewPager) { tab, position -> TabLayoutMediator(binding.tabLayout, binding.viewPager) { tab, position ->
tab.text = when (position) { tab.text = when (position) {
0 -> getString(R.string.all_orders) 0 -> getString(R.string.all_orders)
1 -> getString(R.string.pending_orders) 1 -> getString(R.string.unpaid_orders)
2 -> getString(R.string.unpaid_orders) 2 -> getString(R.string.paid_orders)
3 -> getString(R.string.processed_orders) 3 -> getString(R.string.processed_orders)
4 -> getString(R.string.shipped_orders) 4 -> getString(R.string.shipped_orders)
5 -> getString(R.string.completed_orders) 5 -> getString(R.string.completed_orders)

View File

@ -21,7 +21,7 @@ import com.alya.ecommerce_serang.ui.order.history.detailorder.DetailOrderStatusA
import com.alya.ecommerce_serang.utils.BaseViewModelFactory import com.alya.ecommerce_serang.utils.BaseViewModelFactory
import com.alya.ecommerce_serang.utils.SessionManager import com.alya.ecommerce_serang.utils.SessionManager
class OrderListFragment : Fragment() { class OrderListFragment : Fragment(), OrderHistoryAdapter.OrderActionCallbacks {
private var _binding: FragmentOrderListBinding? = null private var _binding: FragmentOrderListBinding? = null
private val binding get() = _binding!! private val binding get() = _binding!!
@ -72,6 +72,7 @@ class OrderListFragment : Fragment() {
setupRecyclerView() setupRecyclerView()
observeOrderList() observeOrderList()
observeViewModel()
observeOrderCompletionStatus() observeOrderCompletionStatus()
loadOrders() loadOrders()
} }
@ -81,7 +82,8 @@ class OrderListFragment : Fragment() {
onOrderClickListener = { order -> onOrderClickListener = { order ->
navigateToOrderDetail(order) navigateToOrderDetail(order)
}, },
viewModel = viewModel viewModel = viewModel,
callbacks = this // Pass this fragment as callback
) )
orderAdapter.setFragmentStatus(status) orderAdapter.setFragmentStatus(status)
@ -120,6 +122,40 @@ class OrderListFragment : Fragment() {
} }
} }
private fun observeViewModel() {
// 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
}
}
}
}
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)
@ -142,6 +178,30 @@ class OrderListFragment : Fragment() {
detailOrderLauncher.launch(intent) detailOrderLauncher.launch(intent)
} }
override fun onOrderCancelled(orderId: String, success: Boolean, message: String) {
if (success) {
Toast.makeText(requireContext(), message, Toast.LENGTH_SHORT).show()
loadOrders() // Refresh the list
} else {
Toast.makeText(requireContext(), message, Toast.LENGTH_SHORT).show()
}
}
override fun onOrderCompleted(orderId: Int, success: Boolean, message: String) {
if (success) {
Toast.makeText(requireContext(), message, Toast.LENGTH_SHORT).show()
loadOrders() // Refresh the list
} else {
Toast.makeText(requireContext(), message, Toast.LENGTH_SHORT).show()
}
}
override fun onShowLoading(show: Boolean) {
binding.progressBar.visibility = if (show) View.VISIBLE else View.GONE
}
override fun onDestroyView() { override fun onDestroyView() {
super.onDestroyView() super.onDestroyView()
_binding = null _binding = null

View File

@ -11,8 +11,8 @@ class OrderViewPagerAdapter(
// Define all possible order statuses // Define all possible order statuses
private val orderStatuses = listOf( private val orderStatuses = listOf(
"all", // All orders "all", // All orders
"pending", // Menunggu Tagihan "unpaid", // Menunggu Tagihan
"unpaid", // Belum Dibayar "paid", // Belum Dibayar
"processed", // Diproses "processed", // Diproses
"shipped", // Dikirim "shipped", // Dikirim
"completed", // Selesai "completed", // Selesai

View File

@ -234,8 +234,8 @@ class DetailOrderStatusActivity : AppCompatActivity() {
// Set status header // Set status header
val statusText = when(status) { val statusText = when(status) {
"pending" -> "Belum Bayar"
"unpaid" -> "Belum Bayar" "unpaid" -> "Belum Bayar"
"paid" -> "Sudah Dibayar"
"processed" -> "Diproses" "processed" -> "Diproses"
"shipped" -> "Dikirim" "shipped" -> "Dikirim"
"delivered" -> "Diterima" "delivered" -> "Diterima"
@ -248,22 +248,6 @@ class DetailOrderStatusActivity : AppCompatActivity() {
Log.d(TAG, "adjustButtonsBasedOnStatus: Status header set to '$statusText'") Log.d(TAG, "adjustButtonsBasedOnStatus: Status header set to '$statusText'")
when (status) { when (status) {
"pending"->{
binding.tvStatusHeader.text = "Menunggu Tagihan"
binding.tvStatusNote.visibility = View.VISIBLE
binding.tvStatusNote.text = "Pesanan ini harus dibayar sebelum ${formatDatePay(orders.updatedAt)}"
// Set buttons
binding.btnSecondary.apply {
visibility = View.VISIBLE
text = "Batalkan Pesanan"
setOnClickListener {
Log.d(TAG, "Cancel Order button clicked")
showCancelOrderBottomSheet(orders.orderId)
viewModel.getOrderDetails(orders.orderId)
}
}
}
"unpaid" -> { "unpaid" -> {
Log.d(TAG, "adjustButtonsBasedOnStatus: Setting up UI for pending/unpaid order") Log.d(TAG, "adjustButtonsBasedOnStatus: Setting up UI for pending/unpaid order")
@ -295,7 +279,25 @@ class DetailOrderStatusActivity : AppCompatActivity() {
} }
} }
} }
"paid" -> {
Log.d(TAG, "adjustButtonsBasedOnStatus: Setting up UI for pending/unpaid order")
// Show status note
binding.tvStatusHeader.text = "Sudah Dibayar"
binding.tvStatusNote.visibility = View.VISIBLE
binding.tvStatusNote.text = "Menunggu pesanan dikonfirmasi penjual ${formatDatePay(orders.updatedAt)}"
// Set buttons
binding.btnSecondary.apply {
visibility = View.VISIBLE
text = "Batalkan Pesanan"
setOnClickListener {
Log.d(TAG, "Cancel Order button clicked")
showCancelOrderDialog(orders.orderId.toString())
viewModel.getOrderDetails(orders.orderId)
}
}
}
"processed" -> { "processed" -> {
Log.d(TAG, "adjustButtonsBasedOnStatus: Setting up UI for processed order") Log.d(TAG, "adjustButtonsBasedOnStatus: Setting up UI for processed order")

View File

@ -11,7 +11,7 @@ import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.ViewCompat import androidx.core.view.ViewCompat
import androidx.core.view.WindowCompat import androidx.core.view.WindowCompat
import androidx.core.view.WindowInsetsCompat import androidx.core.view.WindowInsetsCompat
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.GridLayoutManager
import com.alya.ecommerce_serang.BuildConfig.BASE_URL import com.alya.ecommerce_serang.BuildConfig.BASE_URL
import com.alya.ecommerce_serang.R import com.alya.ecommerce_serang.R
import com.alya.ecommerce_serang.data.api.dto.ProductsItem import com.alya.ecommerce_serang.data.api.dto.ProductsItem
@ -169,11 +169,7 @@ class StoreDetailActivity : AppCompatActivity() {
binding.rvProducts.apply { binding.rvProducts.apply {
adapter = productAdapter adapter = productAdapter
layoutManager = LinearLayoutManager( layoutManager = GridLayoutManager(context, 2)
context,
LinearLayoutManager.HORIZONTAL,
false
)
} }
} }

View File

@ -158,14 +158,13 @@
<androidx.recyclerview.widget.RecyclerView <androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv_products" android:id="@+id/rv_products"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="0dp"
android:layout_marginTop="16dp" android:layout_marginTop="16dp"
android:layout_marginBottom="16dp" android:layout_marginBottom="16dp"
android:orientation="vertical" app:layoutManager="androidx.recyclerview.widget.GridLayoutManager"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
app:layout_constraintTop_toBottomOf="@id/divider_product" app:layout_constraintTop_toBottomOf="@id/divider_product"
tools:itemCount="5" app:spanCount="2"
tools:listitem="@layout/item_section_horizontal" /> tools:listitem="@layout/item_product_grid" />
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -15,34 +15,25 @@
android:layout_marginTop="16dp" android:layout_marginTop="16dp"
app:layout_constraintTop_toTopOf="parent" /> app:layout_constraintTop_toTopOf="parent" />
<!-- Home content in ScrollView --> <androidx.core.widget.NestedScrollView
<ScrollView
android:id="@+id/home" android:id="@+id/home"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="0dp" android:layout_height="0dp"
android:fillViewport="true"
android:overScrollMode="never"
app:layout_constraintTop_toBottomOf="@id/searchContainer" app:layout_constraintTop_toBottomOf="@id/searchContainer"
app:layout_constraintBottom_toBottomOf="parent"> app:layout_constraintBottom_toBottomOf="parent">
<!-- Your existing home content here -->
<androidx.constraintlayout.widget.ConstraintLayout <androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content"> android:layout_height="wrap_content"
android:paddingBottom="16dp">
<!-- <androidx.viewpager2.widget.ViewPager2-->
<!-- android:id="@+id/banners"-->
<!-- android:layout_width="match_parent"-->
<!-- android:layout_height="132dp"-->
<!-- android:layout_marginTop="8dp"-->
<!-- android:background="@drawable/banner_default"-->
<!-- android:orientation="vertical"-->
<!-- app:layout_constraintTop_toTopOf="parent"-->
<!-- tools:layout_editor_absoluteX="0dp" />-->
<TextView <TextView
android:id="@+id/categoriesText" android:id="@+id/categoriesText"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="32dp" android:layout_marginStart="16dp"
android:layout_marginTop="16dp" android:layout_marginTop="16dp"
android:text="@string/fragment_home_categories" android:text="@string/fragment_home_categories"
android:textColor="@color/blue_500" android:textColor="@color/blue_500"
@ -56,7 +47,7 @@
style="@style/Widget.MaterialComponents.Button.TextButton" style="@style/Widget.MaterialComponents.Button.TextButton"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginEnd="32dp" android:layout_marginEnd="16dp"
android:text="@string/show_all" android:text="@string/show_all"
android:textAllCaps="false" android:textAllCaps="false"
android:textColor="@color/blue_600" android:textColor="@color/blue_600"
@ -64,28 +55,28 @@
app:layout_constraintBaseline_toBaselineOf="@id/categoriesText" app:layout_constraintBaseline_toBaselineOf="@id/categoriesText"
app:layout_constraintEnd_toEndOf="parent" /> app:layout_constraintEnd_toEndOf="parent" />
<!-- Fix margin by adding padding inside RecyclerView -->
<androidx.recyclerview.widget.RecyclerView <androidx.recyclerview.widget.RecyclerView
android:id="@+id/categories" android:id="@+id/categories"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginHorizontal="16dp"
android:layout_marginTop="8dp" android:layout_marginTop="8dp"
android:paddingStart="4dp"
android:paddingEnd="4dp"
android:clipChildren="false" android:clipChildren="false"
android:clipToPadding="false" android:clipToPadding="false"
android:orientation="horizontal" android:overScrollMode="never"
android:layout_marginHorizontal="16dp" android:nestedScrollingEnabled="false"
app:spanCount="2"
app:layoutManager="androidx.recyclerview.widget.GridLayoutManager"
app:layout_constraintTop_toBottomOf="@id/categoriesText" app:layout_constraintTop_toBottomOf="@id/categoriesText"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
tools:layout_editor_absoluteX="0dp"
tools:listitem="@layout/item_category_home" /> tools:listitem="@layout/item_category_home" />
<TextView <TextView
android:id="@+id/new_products_text" android:id="@+id/new_products_text"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="32dp" android:layout_marginStart="16dp"
android:layout_marginTop="16dp" android:layout_marginTop="16dp"
android:text="@string/sold_product_text" android:text="@string/sold_product_text"
android:textColor="@color/blue_500" android:textColor="@color/blue_500"
@ -93,12 +84,13 @@
android:textSize="18sp" android:textSize="18sp"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/categories" /> app:layout_constraintTop_toBottomOf="@id/categories" />
<com.google.android.material.button.MaterialButton <com.google.android.material.button.MaterialButton
android:id="@+id/productshowAll" android:id="@+id/productshowAll"
style="@style/Widget.MaterialComponents.Button.TextButton" style="@style/Widget.MaterialComponents.Button.TextButton"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginEnd="32dp" android:layout_marginEnd="16dp"
android:text="@string/show_all" android:text="@string/show_all"
android:textAllCaps="false" android:textAllCaps="false"
android:textColor="@color/blue_600" android:textColor="@color/blue_600"
@ -106,19 +98,22 @@
app:layout_constraintBaseline_toBaselineOf="@id/new_products_text" app:layout_constraintBaseline_toBaselineOf="@id/new_products_text"
app:layout_constraintEnd_toEndOf="parent" /> app:layout_constraintEnd_toEndOf="parent" />
<!-- Disable internal scroll, height wraps content -->
<androidx.recyclerview.widget.RecyclerView <androidx.recyclerview.widget.RecyclerView
android:id="@+id/new_products" android:id="@+id/new_products"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="16dp" android:layout_marginTop="16dp"
android:layout_marginBottom="16dp" android:paddingHorizontal="16dp"
android:orientation="vertical" android:nestedScrollingEnabled="false"
android:overScrollMode="never"
app:layoutManager="androidx.recyclerview.widget.GridLayoutManager" app:layoutManager="androidx.recyclerview.widget.GridLayoutManager"
app:spanCount="2"
app:layout_constraintTop_toBottomOf="@id/new_products_text" app:layout_constraintTop_toBottomOf="@id/new_products_text"
tools:itemCount="5" tools:listitem="@layout/item_product_grid" />
tools:listitem="@layout/item_section_horizontal" />
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>
</ScrollView> </androidx.core.widget.NestedScrollView>
<androidx.recyclerview.widget.RecyclerView <androidx.recyclerview.widget.RecyclerView
android:id="@+id/searchResultsRecyclerView" android:id="@+id/searchResultsRecyclerView"

View File

@ -1,7 +1,8 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="110dp" android:layout_width="match_parent"
android:layout_height="115dp" android:layout_height="wrap_content"
android:layout_margin="4dp"
xmlns:app="http://schemas.android.com/apk/res-auto"> xmlns:app="http://schemas.android.com/apk/res-auto">
<androidx.cardview.widget.CardView <androidx.cardview.widget.CardView

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android" <androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="180dp" android:layout_width="180dp"
android:layout_height="wrap_content" android:layout_height="320dp"
android:layout_margin="8dp" android:layout_margin="8dp"
app:cardCornerRadius="12dp" app:cardCornerRadius="12dp"
app:cardElevation="4dp" app:cardElevation="4dp"

View File

@ -90,7 +90,7 @@
<string name="dl_pending">Batas Tagihan</string> <string name="dl_pending">Batas Tagihan</string>
<string name="dl_unpaid">Batas Pembayaran</string> <string name="dl_unpaid">Batas Pembayaran</string>
<string name="dl_processed">Batas Pengiriman</string> <string name="dl_processed">Batas Pengiriman</string>
<string name="dal_paid">Semua Pesanan </string> <string name="dl_paid">Batas Konfirmasi Penjual</string>
<string name="dl_delivered">Semua Pesanan </string> <string name="dl_delivered">Semua Pesanan </string>
<string name="dl_completed">Semua Pesanan </string> <string name="dl_completed">Semua Pesanan </string>
<string name="dl_shipped">Tanggal Pesanan Sampai</string> <string name="dl_shipped">Tanggal Pesanan Sampai</string>