From 7fc6458f9ba72de12ad78462af1dd3c2075c813e Mon Sep 17 00:00:00 2001 From: shaulascr Date: Wed, 27 Aug 2025 20:24:39 +0700 Subject: [PATCH] update dialog pop up and fix display picture --- .../ecommerce_serang/ui/auth/LoginActivity.kt | 20 +++- .../ui/auth/ResetPassActivity.kt | 34 +++--- .../auth/fragments/RegisterStep3Fragment.kt | 13 ++- .../ecommerce_serang/ui/cart/CartActivity.kt | 11 +- .../ecommerce_serang/ui/cart/CartViewModel.kt | 38 ++++++ .../ecommerce_serang/ui/cart/StoreAdapter.kt | 38 +++--- .../ui/order/CartCheckoutAdapter.kt | 109 +++++++++++++----- .../ui/order/CheckoutActivity.kt | 61 +++++++--- .../ui/order/CheckoutSellerAdapter.kt | 36 ++++-- .../ui/order/CheckoutViewModel.kt | 45 +++++++- .../ui/order/SingleItemCartAdapter.kt | 21 +++- .../ui/order/SingleProductAdapter.kt | 10 +- .../detail/AddEvidencePaymentActivity.kt | 16 ++- .../ui/order/detail/PaymentActivity.kt | 1 - .../ui/order/history/HistoryActivity.kt | 8 ++ .../ui/order/history/HistoryViewModel.kt | 20 ++-- .../ui/order/history/OrderHistoryAdapter.kt | 37 +++++- .../ui/order/history/OrderListFragment.kt | 16 ++- .../cancelorder/CancelOrderBottomSheet.kt | 7 -- .../category/CategoryProductsActivity.kt | 9 +- .../ui/profile/ProfileFragment.kt | 16 +-- .../editprofile/EditProfileCustActivity.kt | 19 +-- .../mystore/balance/BalanceTopUpActivity.kt | 27 ++--- .../profile/DetailStoreProfileActivity.kt | 21 ++-- .../mystore/sells/SellsListFragment.kt | 2 +- .../utils/HorizontalMarginItemDecoration.kt | 22 ---- .../ecommerce_serang/utils/PopUpDialog.kt | 1 - app/src/main/res/drawable/splash_drawable.xml | 4 +- app/src/main/res/layout/dialog_popup.xml | 22 +++- app/src/main/res/layout/fragment_profile.xml | 4 +- .../res/layout/item_dialog_add_evidence.xml | 11 +- .../main/res/layout/item_order_history.xml | 16 ++- app/src/main/res/values/themes.xml | 1 - 33 files changed, 499 insertions(+), 217 deletions(-) delete mode 100644 app/src/main/java/com/alya/ecommerce_serang/utils/HorizontalMarginItemDecoration.kt diff --git a/app/src/main/java/com/alya/ecommerce_serang/ui/auth/LoginActivity.kt b/app/src/main/java/com/alya/ecommerce_serang/ui/auth/LoginActivity.kt index 5c03fe7..ba3fce8 100644 --- a/app/src/main/java/com/alya/ecommerce_serang/ui/auth/LoginActivity.kt +++ b/app/src/main/java/com/alya/ecommerce_serang/ui/auth/LoginActivity.kt @@ -5,10 +5,9 @@ import android.content.Intent import android.os.Bundle import android.util.Log import android.widget.Toast -import androidx.activity.enableEdgeToEdge import androidx.activity.viewModels import androidx.appcompat.app.AppCompatActivity -import androidx.core.view.WindowCompat +import com.alya.ecommerce_serang.R import com.alya.ecommerce_serang.data.api.dto.FcmReq import com.alya.ecommerce_serang.data.api.retrofit.ApiConfig import com.alya.ecommerce_serang.data.repository.Result @@ -16,6 +15,7 @@ import com.alya.ecommerce_serang.data.repository.UserRepository import com.alya.ecommerce_serang.databinding.ActivityLoginBinding import com.alya.ecommerce_serang.ui.MainActivity import com.alya.ecommerce_serang.utils.BaseViewModelFactory +import com.alya.ecommerce_serang.utils.PopUpDialog import com.alya.ecommerce_serang.utils.SessionManager import com.alya.ecommerce_serang.utils.viewmodel.LoginViewModel import com.google.firebase.FirebaseApp @@ -39,9 +39,9 @@ class LoginActivity : AppCompatActivity() { binding = ActivityLoginBinding.inflate(layoutInflater) setContentView(binding.root) - - WindowCompat.setDecorFitsSystemWindows(window, false) - enableEdgeToEdge() +// +// WindowCompat.setDecorFitsSystemWindows(window, false) +// enableEdgeToEdge() setupListeners() observeLoginState() @@ -83,6 +83,11 @@ class LoginActivity : AppCompatActivity() { retrieveFCMToken() // sessionManager.saveUserId(response.userId) + PopUpDialog.showConfirmDialog( + context = this, + iconRes = R.drawable.checkmark__1_, + title = "Berhasil Masuk" + ) Toast.makeText(this, "Berhasil masuk", Toast.LENGTH_SHORT).show() startActivity(Intent(this, MainActivity::class.java)) @@ -90,6 +95,11 @@ class LoginActivity : AppCompatActivity() { } is com.alya.ecommerce_serang.data.repository.Result.Error -> { Log.e("LoginActivity", "Login Failed: ${result.exception.message}") + PopUpDialog.showConfirmDialog( + context = this, + iconRes = R.drawable.ic_cancel, + title = "Gagal Masuk" + ) Toast.makeText(this, "Gagal masuk", Toast.LENGTH_LONG).show() } is Result.Loading -> { diff --git a/app/src/main/java/com/alya/ecommerce_serang/ui/auth/ResetPassActivity.kt b/app/src/main/java/com/alya/ecommerce_serang/ui/auth/ResetPassActivity.kt index 81bd108..30ed174 100644 --- a/app/src/main/java/com/alya/ecommerce_serang/ui/auth/ResetPassActivity.kt +++ b/app/src/main/java/com/alya/ecommerce_serang/ui/auth/ResetPassActivity.kt @@ -5,13 +5,14 @@ import android.util.Log import android.view.View import android.widget.Toast import androidx.activity.viewModels -import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AppCompatActivity +import com.alya.ecommerce_serang.R import com.alya.ecommerce_serang.data.api.retrofit.ApiConfig import com.alya.ecommerce_serang.data.repository.Result import com.alya.ecommerce_serang.data.repository.UserRepository import com.alya.ecommerce_serang.databinding.ActivityResetPassBinding import com.alya.ecommerce_serang.utils.BaseViewModelFactory +import com.alya.ecommerce_serang.utils.PopUpDialog import com.alya.ecommerce_serang.utils.viewmodel.LoginViewModel class ResetPassActivity : AppCompatActivity() { @@ -36,7 +37,7 @@ class ResetPassActivity : AppCompatActivity() { setupToolbar() setupUI() - + observeResetPassword() } private fun setupToolbar(){ @@ -98,26 +99,23 @@ class ResetPassActivity : AppCompatActivity() { private fun handleSuccess(message: String) { Toast.makeText(this, message, Toast.LENGTH_LONG).show() - // Show success dialog and navigate back to login - AlertDialog.Builder(this) - .setTitle("Berhasil Ubah Password") - .setMessage(message) - .setPositiveButton("OK") { _, _ -> - // Navigate back to login activity - finish() - } - .setCancelable(false) - .show() + PopUpDialog.showConfirmDialog( + context = this, + iconRes = R.drawable.checkmark__1_, + title = "Berhasil Ubah Password", + positiveText = "OK" + ) } private fun handleError(errorMessage: String) { Log.e(TAG, "Error: $errorMessage") - // Optionally show error dialog - AlertDialog.Builder(this) - .setTitle("Gagal Ubah Password") - .setMessage(errorMessage) - .setPositiveButton("OK", null) - .show() + PopUpDialog.showConfirmDialog( + context = this, + iconRes = R.drawable.ic_cancel, + title = "Gagal Ubah Password", + message = errorMessage, + positiveText = "OK" + ) } } \ No newline at end of file diff --git a/app/src/main/java/com/alya/ecommerce_serang/ui/auth/fragments/RegisterStep3Fragment.kt b/app/src/main/java/com/alya/ecommerce_serang/ui/auth/fragments/RegisterStep3Fragment.kt index 07e45c4..5e75394 100644 --- a/app/src/main/java/com/alya/ecommerce_serang/ui/auth/fragments/RegisterStep3Fragment.kt +++ b/app/src/main/java/com/alya/ecommerce_serang/ui/auth/fragments/RegisterStep3Fragment.kt @@ -27,6 +27,7 @@ import com.alya.ecommerce_serang.ui.order.address.SubdsitrictAdapter import com.alya.ecommerce_serang.ui.order.address.ViewState import com.alya.ecommerce_serang.ui.order.address.VillagesAdapter import com.alya.ecommerce_serang.utils.BaseViewModelFactory +import com.alya.ecommerce_serang.utils.PopUpDialog import com.alya.ecommerce_serang.utils.SessionManager import com.alya.ecommerce_serang.utils.viewmodel.RegisterViewModel import com.google.android.material.progressindicator.LinearProgressIndicator @@ -108,7 +109,16 @@ class RegisterStep3Fragment : Fragment() { } binding.btnRegister.setOnClickListener { - submitAddress() + PopUpDialog.showConfirmDialog( + context = requireContext(), + title = "Apakah anda yakin data anda sudah benar?", + message = "Pastikan data yang dimasukkan sudah benar", + positiveText = "Ya", + negativeText = "Tidak", + onYesClicked = { + submitAddress() + } + ) } // Observe address submission state @@ -498,6 +508,7 @@ class RegisterStep3Fragment : Fragment() { private fun showRegistrationSuccess() { // Now we can show the success message for the overall registration process + Toast.makeText(requireContext(), "Berhasil mendaftarkan akun", Toast.LENGTH_LONG).show() sessionManager.clearAll() diff --git a/app/src/main/java/com/alya/ecommerce_serang/ui/cart/CartActivity.kt b/app/src/main/java/com/alya/ecommerce_serang/ui/cart/CartActivity.kt index 58b4951..ece2788 100644 --- a/app/src/main/java/com/alya/ecommerce_serang/ui/cart/CartActivity.kt +++ b/app/src/main/java/com/alya/ecommerce_serang/ui/cart/CartActivity.kt @@ -43,8 +43,6 @@ class CartActivity : AppCompatActivity() { super.onCreate(savedInstanceState) sessionManager = SessionManager(this) apiService = ApiConfig.getApiService(sessionManager) - - binding = ActivityCartBinding.inflate(layoutInflater) setContentView(binding.root) @@ -201,7 +199,8 @@ class CartActivity : AppCompatActivity() { viewModel.errorMessage.observe(this) { errorMessage -> errorMessage?.let { - Toast.makeText(this, it, Toast.LENGTH_SHORT).show() + binding.emptyCart.visibility = View.VISIBLE + Log.e("CartActivity", "Error message: $it") } } @@ -254,6 +253,10 @@ class CartActivity : AppCompatActivity() { storeAdapter.updateWholesaleStatus(wholesaleStatusMap, wholesalePriceMap) } } + + viewModel.productImages.observe(this) { productImages -> + storeAdapter.updateProductImages(productImages) + } } private fun showEmptyState(isEmpty: Boolean) { @@ -272,5 +275,5 @@ class CartActivity : AppCompatActivity() { val format = NumberFormat.getCurrencyInstance(Locale("id", "ID")) return format.format(amount).replace("Rp", "Rp ") } -} +} \ No newline at end of file diff --git a/app/src/main/java/com/alya/ecommerce_serang/ui/cart/CartViewModel.kt b/app/src/main/java/com/alya/ecommerce_serang/ui/cart/CartViewModel.kt index 2554cd1..738cc18 100644 --- a/app/src/main/java/com/alya/ecommerce_serang/ui/cart/CartViewModel.kt +++ b/app/src/main/java/com/alya/ecommerce_serang/ui/cart/CartViewModel.kt @@ -8,6 +8,7 @@ import androidx.lifecycle.viewModelScope import com.alya.ecommerce_serang.data.api.dto.UpdateCart import com.alya.ecommerce_serang.data.api.response.customer.cart.DataItemCart import com.alya.ecommerce_serang.data.api.response.customer.product.CartItemCheckoutInfo +import com.alya.ecommerce_serang.data.api.response.customer.product.Product import com.alya.ecommerce_serang.data.repository.OrderRepository import com.alya.ecommerce_serang.data.repository.Result import kotlinx.coroutines.launch @@ -52,6 +53,12 @@ class CartViewModel(private val repository: OrderRepository) : ViewModel() { private val _hasConsistentWholesaleStatus = MutableLiveData(true) val hasConsistentWholesaleStatus: LiveData = _hasConsistentWholesaleStatus + private val _productDetail = MutableLiveData() + val productDetail: LiveData get() = _productDetail + + private val _productImages = MutableLiveData>() + val productImages: LiveData> = _productImages + fun getCart() { _isLoading.value = true _errorMessage.value = null @@ -62,6 +69,12 @@ class CartViewModel(private val repository: OrderRepository) : ViewModel() { _cartItems.value = result.data _isLoading.value = false + result.data.forEach { store -> + store.cartItems.forEach { item -> + loadProductImage(item.productId) + } + } + // After loading cart items, check wholesale status checkWholesaleStatus() } @@ -404,4 +417,29 @@ class CartViewModel(private val repository: OrderRepository) : ViewModel() { _hasConsistentWholesaleStatus.value = allSameStatus } + + fun loadProductImage(productId: Int) { + viewModelScope.launch { + try { + val result = repository.fetchProductDetail(productId) + val imageUrl = result?.product?.image ?: "" + + val currentMap = _productImages.value?.toMutableMap() ?: mutableMapOf() + currentMap[productId] = imageUrl + _productImages.value = currentMap + + } catch (e: Exception) { + Log.e("CartViewModel", "Error loading product image: ${e.message}") + } + } + } + +// fun loadProductDetail(productId: Int) { +// viewModelScope.launch { +// val result = repository.fetchProductDetail(productId) +// val currentMap = _productImages.value?.toMutableMap() ?: mutableMapOf() +// currentMap[productId] = result?.product?.image ?: "" +// _productImages.value = currentMap +// } +// } } \ No newline at end of file diff --git a/app/src/main/java/com/alya/ecommerce_serang/ui/cart/StoreAdapter.kt b/app/src/main/java/com/alya/ecommerce_serang/ui/cart/StoreAdapter.kt index 9460c03..9f40ec0 100644 --- a/app/src/main/java/com/alya/ecommerce_serang/ui/cart/StoreAdapter.kt +++ b/app/src/main/java/com/alya/ecommerce_serang/ui/cart/StoreAdapter.kt @@ -11,6 +11,7 @@ import androidx.constraintlayout.widget.ConstraintLayout import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.ListAdapter import androidx.recyclerview.widget.RecyclerView +import com.alya.ecommerce_serang.BuildConfig.BASE_URL import com.alya.ecommerce_serang.R import com.alya.ecommerce_serang.data.api.response.customer.cart.CartItemsItem import com.alya.ecommerce_serang.data.api.response.customer.cart.DataItemCart @@ -30,6 +31,12 @@ class StoreAdapter( private var activeStoreId: Int? = null private var wholesaleStatusMap: Map = mapOf() private var wholesalePriceMap: Map = mapOf() + private var productImages: Map = emptyMap() + + fun updateProductImages(newImages: Map) { + productImages = newImages + notifyDataSetChanged() + } companion object { private const val VIEW_TYPE_STORE = 0 @@ -135,7 +142,8 @@ class StoreAdapter( wholesalePrice, { isChecked -> onItemCheckChanged(cartItem.cartItemId, store.storeId, isChecked) }, { quantity -> onItemQuantityChanged(cartItem.cartItemId, quantity) }, - { onItemDeleted(cartItem.cartItemId) } + { onItemDeleted(cartItem.cartItemId) }, + productImages ) } } @@ -197,7 +205,8 @@ class StoreAdapter( wholesalePrice: Double?, onCheckedChange: (Boolean) -> Unit, onQuantityChanged: (Int) -> Unit, - onDelete: () -> Unit + onDelete: () -> Unit, + productImages: Map ) { // Set product name tvProductName.text = cartItem.productName @@ -216,20 +225,6 @@ class StoreAdapter( // Set quantity tvQuantity.text = cartItem.quantity.toString() - // Visual indication for wholesale items -// if (isWholesale) { -// // You can add a background or border to indicate wholesale items -// // For example: -//// itemView.setBackgroundResource(R.drawable.bg_wholesale_item) -// // If you don't have this drawable, you can use a simple color tint instead: -// itemView.setBackgroundColor(ContextCompat.getColor(itemView.context, R.color.wholesale_item_bg)) -// } else { -// // Reset to default background -//// itemView.setBackgroundResource(R.drawable.bg_normal_item) -// // Or if you don't have this drawable: -// itemView.setBackgroundColor(ContextCompat.getColor(itemView.context, R.color.normal_item_bg)) -// } - // Set checkbox state without triggering listener cbItem.setOnCheckedChangeListener(null) cbItem.isChecked = isSelected @@ -247,11 +242,16 @@ class StoreAdapter( onCheckedChange(isChecked) } - // Load product image + val fullImageUrl = when (val img = productImages[cartItem.productId]) { + is String -> { + if (img.startsWith("/")) BASE_URL + img.substring(1) else img + } + else -> null + } + Glide.with(itemView.context) - .load("https://example.com/images/${cartItem.productId}.jpg") // Assume image URL based on product ID + .load(fullImageUrl) .placeholder(R.drawable.placeholder_image) - .error(R.drawable.placeholder_image) .into(ivProduct) // Quantity control diff --git a/app/src/main/java/com/alya/ecommerce_serang/ui/order/CartCheckoutAdapter.kt b/app/src/main/java/com/alya/ecommerce_serang/ui/order/CartCheckoutAdapter.kt index ca38224..2f6cc45 100644 --- a/app/src/main/java/com/alya/ecommerce_serang/ui/order/CartCheckoutAdapter.kt +++ b/app/src/main/java/com/alya/ecommerce_serang/ui/order/CartCheckoutAdapter.kt @@ -1,9 +1,11 @@ package com.alya.ecommerce_serang.ui.order +import android.util.Log import android.view.LayoutInflater import android.view.ViewGroup import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView +import com.alya.ecommerce_serang.BuildConfig.BASE_URL import com.alya.ecommerce_serang.R import com.alya.ecommerce_serang.data.api.dto.CheckoutData import com.alya.ecommerce_serang.data.api.response.customer.cart.CartItemsItem @@ -13,37 +15,57 @@ import com.bumptech.glide.Glide import java.text.NumberFormat import java.util.Locale -class CartCheckoutAdapter(private val checkoutData: CheckoutData) : - RecyclerView.Adapter() { +class CartCheckoutAdapter( + private val checkoutData: CheckoutData +) : RecyclerView.Adapter() { - class SellerViewHolder(val binding: ItemOrderSellerBinding) : RecyclerView.ViewHolder(binding.root) + private var productImages: Map = emptyMap() + private val viewHolders = mutableListOf() // Keep references - override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): SellerViewHolder { - val binding = ItemOrderSellerBinding.inflate( - LayoutInflater.from(parent.context), parent, false - ) - return SellerViewHolder(binding) - } - - override fun getItemCount(): Int = 1 // Only one seller - - override fun onBindViewHolder(holder: SellerViewHolder, position: Int) { - with(holder.binding) { - // Set seller name - tvStoreName.text = checkoutData.sellerName - - // Set up products RecyclerView with multiple items - rvSellerOrderProduct.apply { - layoutManager = LinearLayoutManager(context) - adapter = MultiCartItemsAdapter(checkoutData.cartItems) + class SellerViewHolder(val binding: ItemOrderSellerBinding) : RecyclerView.ViewHolder(binding.root) { + val childAdapter = MultiCartItemsAdapter(emptyList(), emptyMap()) + init { + binding.rvSellerOrderProduct.apply { + layoutManager = LinearLayoutManager(binding.root.context) + adapter = childAdapter isNestedScrollingEnabled = false } } } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): SellerViewHolder { + val binding = ItemOrderSellerBinding.inflate(LayoutInflater.from(parent.context), parent, false) + val holder = SellerViewHolder(binding) + viewHolders.add(holder) // Keep reference + return holder + } + + fun updateProductImages(newImages: Map) { + productImages = newImages + // Update all existing child adapters + viewHolders.forEach { holder -> + holder.childAdapter.updateProductImages(newImages) + } + } + + override fun getItemCount(): Int = 1 + + override fun onBindViewHolder(holder: SellerViewHolder, position: Int) { + holder.binding.tvStoreName.text = checkoutData.sellerName + holder.childAdapter.updateData(checkoutData.cartItems) + holder.childAdapter.updateProductImages(productImages) // Apply current images + } + + override fun onViewRecycled(holder: SellerViewHolder) { + super.onViewRecycled(holder) + viewHolders.remove(holder) // Clean up reference + } } -class MultiCartItemsAdapter(private val cartItems: List) : - RecyclerView.Adapter() { +class MultiCartItemsAdapter( + private var cartItems: List = emptyList(), + private var productImages: Map = emptyMap() +) : RecyclerView.Adapter() { class CartItemViewHolder(val binding: ItemOrderProductBinding) : RecyclerView.ViewHolder(binding.root) @@ -56,24 +78,57 @@ class MultiCartItemsAdapter(private val cartItems: List) : override fun getItemCount(): Int = cartItems.size + fun updateProductImages(images: Map) { + Log.d("MultiCartItemsAdapter", "updateProductImages called with: $images") + Log.d("MultiCartItemsAdapter", "Current cartItems productIds: ${cartItems.map { it.productId }}") + productImages = images + notifyDataSetChanged() + Log.d("MultiCartItemsAdapter", "notifyDataSetChanged() called") + } + override fun onBindViewHolder(holder: CartItemViewHolder, position: Int) { val item = cartItems[position] + Log.d("MultiCartItemsAdapter", "onBindViewHolder - position: $position, productId: ${item.productId}") + Log.d("MultiCartItemsAdapter", "Available images: $productImages") with(holder.binding) { - // Set cart item details tvProductName.text = item.productName tvProductQuantity.text = "${item.quantity} buah" tvProductPrice.text = formatCurrency(item.price.toDouble()) - // Load placeholder image + val img = productImages[item.productId] + Log.d("MultiCartItemsAdapter", "Image for productId ${item.productId}: $img") + + val fullImageUrl = when (img) { + is String -> { + val url = if (img.startsWith("/")) BASE_URL + img.substring(1) else img + Log.d("MultiCartItemsAdapter", "Full image URL: $url") + url + } + else -> { + Log.d("MultiCartItemsAdapter", "No image found, using placeholder") + null + } + } + + Log.d("MultiCartItemsAdapter", "Loading image with Glide: $fullImageUrl") Glide.with(ivProduct.context) - .load(R.drawable.placeholder_image) + .load(fullImageUrl) + .placeholder(R.drawable.placeholder_image) + .error(R.drawable.placeholder_image) // Add error handling .into(ivProduct) } } + // Minimal helpers to update adapter data from parent adapter + fun updateData(items: List) { + cartItems = items + notifyDataSetChanged() + } + + private fun formatCurrency(amount: Double): String { val formatter = NumberFormat.getCurrencyInstance(Locale("in", "ID")) return formatter.format(amount).replace(",00", "") } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/alya/ecommerce_serang/ui/order/CheckoutActivity.kt b/app/src/main/java/com/alya/ecommerce_serang/ui/order/CheckoutActivity.kt index 21a2ee1..40689cc 100644 --- a/app/src/main/java/com/alya/ecommerce_serang/ui/order/CheckoutActivity.kt +++ b/app/src/main/java/com/alya/ecommerce_serang/ui/order/CheckoutActivity.kt @@ -36,6 +36,8 @@ class CheckoutActivity : AppCompatActivity() { private lateinit var binding: ActivityCheckoutBinding private lateinit var sessionManager: SessionManager private var paymentAdapter: PaymentMethodAdapter? = null + private var cartCheckoutAdapter: CartCheckoutAdapter? = null + private var checkoutSellerAdapter: CheckoutSellerAdapter? = null private var paymentMethodsLoaded = false private val viewModel: CheckoutViewModel by viewModels { @@ -210,6 +212,13 @@ class CheckoutActivity : AppCompatActivity() { finish() } } + + viewModel.productImages.observe(this) { images -> + Log.d("CheckoutActivity", "Product images updated: ${images.keys}") + // Update adapter when images arrive + cartCheckoutAdapter?.updateProductImages(images) + checkoutSellerAdapter?.updateProductImages(images) + } } private fun setupPaymentMethodsRecyclerView(paymentMethods: List) { @@ -271,24 +280,44 @@ class CheckoutActivity : AppCompatActivity() { } private fun setupProductRecyclerView(checkoutData: CheckoutData) { - val adapter = if (checkoutData.isBuyNow || checkoutData.cartItems.size <= 1) { - CheckoutSellerAdapter(checkoutData) + if (checkoutData.isBuyNow || checkoutData.cartItems.size <= 1) { + Log.d("CheckoutActivity", "Using CheckoutSellerAdapter") + val adapter = CheckoutSellerAdapter(checkoutData) + + // Keep reference for image updates - create a field in your activity + checkoutSellerAdapter = adapter + + binding.rvProductItems.apply { + layoutManager = LinearLayoutManager(this@CheckoutActivity) + this.adapter = adapter + isNestedScrollingEnabled = false + } + + // Load images for cart items + if (!checkoutData.isBuyNow) { + checkoutData.cartItems.forEach { item -> + viewModel.loadProductImage(item.productId) + } + } } else { - CartCheckoutAdapter(checkoutData) - } + Log.d("CheckoutActivity", "Using CartCheckoutAdapter") + Log.d("CheckoutActivity", "Cart items count: ${checkoutData.cartItems.size}") - binding.rvProductItems.apply { - layoutManager = LinearLayoutManager(this@CheckoutActivity) - this.adapter = adapter - isNestedScrollingEnabled = false - } + // Create adapter and keep reference + cartCheckoutAdapter = CartCheckoutAdapter(checkoutData) -// if (checkoutData.cartItems.isEmpty()) { -// // Show empty products state -// binding.containerEmptyProducts.visibility = View.VISIBLE -// binding.rvProductItems.visibility = View.GONE -// return -// } + binding.rvProductItems.apply { + layoutManager = LinearLayoutManager(this@CheckoutActivity) + adapter = cartCheckoutAdapter + isNestedScrollingEnabled = false + } + + // Load images for each product + checkoutData.cartItems.forEach { item -> + Log.d("CheckoutActivity", "Loading image for productId: ${item.productId}") + viewModel.loadProductImage(item.productId) + } + } binding.containerEmptyProducts.visibility = View.GONE binding.rvProductItems.visibility = View.VISIBLE @@ -375,7 +404,7 @@ class CheckoutActivity : AppCompatActivity() { if (validateOrder()) { PopUpDialog.showConfirmDialog( context = this, - title = "Apakah anda yakin inging membuat pesanan?", + title = "Apakah anda yakin membuat pesanan?", message = "Pastikan data yang dimasukkan sudah benar", positiveText = "Ya", negativeText = "Tidak", diff --git a/app/src/main/java/com/alya/ecommerce_serang/ui/order/CheckoutSellerAdapter.kt b/app/src/main/java/com/alya/ecommerce_serang/ui/order/CheckoutSellerAdapter.kt index 1d436b4..ffb0c50 100644 --- a/app/src/main/java/com/alya/ecommerce_serang/ui/order/CheckoutSellerAdapter.kt +++ b/app/src/main/java/com/alya/ecommerce_serang/ui/order/CheckoutSellerAdapter.kt @@ -11,31 +11,53 @@ import com.alya.ecommerce_serang.databinding.ItemOrderSellerBinding class CheckoutSellerAdapter(private val checkoutData: CheckoutData) : RecyclerView.Adapter() { + private var productImages: Map = emptyMap() + private var currentViewHolder: SellerViewHolder? = null + class SellerViewHolder(val binding: ItemOrderSellerBinding) : RecyclerView.ViewHolder(binding.root) override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): SellerViewHolder { val binding = ItemOrderSellerBinding.inflate( LayoutInflater.from(parent.context), parent, false ) - return SellerViewHolder(binding) + val holder = SellerViewHolder(binding) + currentViewHolder = holder + return holder } - override fun getItemCount(): Int = 1 // Only one seller + fun updateProductImages(newImages: Map) { + productImages = newImages + currentViewHolder?.let { holder -> + // Update the nested adapter + val adapter = holder.binding.rvSellerOrderProduct.adapter + when (adapter) { + is SingleCartItemAdapter -> adapter.updateProductImages(newImages) + is SingleProductAdapter -> { + // For SingleProductAdapter, you might need to update differently + // since it uses checkoutData.productImageUrl + } + } + } + } + + override fun getItemCount(): Int = 1 override fun onBindViewHolder(holder: SellerViewHolder, position: Int) { + currentViewHolder = holder with(holder.binding) { - // Set seller name tvStoreName.text = checkoutData.sellerName - // Set up products RecyclerView rvSellerOrderProduct.apply { layoutManager = LinearLayoutManager(context) adapter = if (checkoutData.isBuyNow) { - // Single product for Buy Now SingleProductAdapter(checkoutData) } else { - // Single cart item - SingleCartItemAdapter(checkoutData.cartItems.first()) + SingleCartItemAdapter(checkoutData.cartItems.first()).also { adapter -> + // Apply existing images if available + if (productImages.isNotEmpty()) { + adapter.updateProductImages(productImages) + } + } } isNestedScrollingEnabled = false } diff --git a/app/src/main/java/com/alya/ecommerce_serang/ui/order/CheckoutViewModel.kt b/app/src/main/java/com/alya/ecommerce_serang/ui/order/CheckoutViewModel.kt index 66c45f8..c6a177b 100644 --- a/app/src/main/java/com/alya/ecommerce_serang/ui/order/CheckoutViewModel.kt +++ b/app/src/main/java/com/alya/ecommerce_serang/ui/order/CheckoutViewModel.kt @@ -40,6 +40,11 @@ class CheckoutViewModel(private val repository: OrderRepository) : ViewModel() { private val _orderCreated = MutableLiveData() val orderCreated: LiveData = _orderCreated + private val _productImages = MutableLiveData>(emptyMap()) + val productImages: LiveData> = _productImages + + private val currentImages = mutableMapOf() + // Initialize "Buy Now" checkout fun initializeBuyNow( storeId: Int, @@ -156,9 +161,13 @@ class CheckoutViewModel(private val repository: OrderRepository) : ViewModel() { ) Log.d(TAG, "CheckoutData initialized with ${matchingItems.size} items") - matchingItems.forEachIndexed { index, item -> - val isWholesale = isWholesaleMap[item.cartItemId] ?: false - Log.d(TAG, "Item $index: ${item.productName}, Price: ${item.price}, IsWholesale: $isWholesale") + matchingItems.forEach { item -> + Log.d("CheckoutViewModel", "About to load image for productId: ${item.productId}") + loadProductImage(item.productId) + } + + matchingItems.forEach { item -> + loadProductImage(item.productId) } // Calculate totals with updated prices @@ -179,6 +188,8 @@ class CheckoutViewModel(private val repository: OrderRepository) : ViewModel() { } } + + fun getPaymentMethods() { viewModelScope.launch { try { @@ -417,6 +428,31 @@ class CheckoutViewModel(private val repository: OrderRepository) : ViewModel() { } } + fun loadProductImage(productId: Int) { + Log.d("CheckoutViewModel", "loadProductImage called for productId: $productId") + viewModelScope.launch { + try { + Log.d("CheckoutViewModel", "Fetching product detail for productId: $productId") + val productDetail = repository.fetchProductDetail(productId) + Log.d("CheckoutViewModel", "Product detail result: $productDetail") + + val imageUrl = productDetail?.product?.image + Log.d("CheckoutViewModel", "Extracted image URL: $imageUrl") + + currentImages[productId] = imageUrl.toString() + Log.d("CheckoutViewModel", "Updated currentImages: $currentImages") + + _productImages.postValue(currentImages.toMap()) + Log.d("CheckoutViewModel", "Posted to _productImages LiveData") + } catch (e: Exception) { + Log.e("CheckoutViewModel", "Error loading image for productId $productId", e) + // fallback if error + currentImages[productId] = "" + _productImages.postValue(currentImages.toMap()) + } + } + } + // Get shipping price private fun getShippingPrice(): Double { val data = _checkoutData.value ?: return 0.0 @@ -431,4 +467,5 @@ class CheckoutViewModel(private val repository: OrderRepository) : ViewModel() { companion object { private const val TAG = "CheckoutViewModel" } -} \ No newline at end of file +} + diff --git a/app/src/main/java/com/alya/ecommerce_serang/ui/order/SingleItemCartAdapter.kt b/app/src/main/java/com/alya/ecommerce_serang/ui/order/SingleItemCartAdapter.kt index 753eef3..cd57484 100644 --- a/app/src/main/java/com/alya/ecommerce_serang/ui/order/SingleItemCartAdapter.kt +++ b/app/src/main/java/com/alya/ecommerce_serang/ui/order/SingleItemCartAdapter.kt @@ -3,6 +3,7 @@ package com.alya.ecommerce_serang.ui.order import android.view.LayoutInflater import android.view.ViewGroup import androidx.recyclerview.widget.RecyclerView +import com.alya.ecommerce_serang.BuildConfig.BASE_URL import com.alya.ecommerce_serang.R import com.alya.ecommerce_serang.data.api.response.customer.cart.CartItemsItem import com.alya.ecommerce_serang.databinding.ItemOrderProductBinding @@ -13,6 +14,8 @@ import java.util.Locale class SingleCartItemAdapter(private val cartItem: CartItemsItem) : RecyclerView.Adapter() { + private var productImages: Map = emptyMap() + class CartItemViewHolder(val binding: ItemOrderProductBinding) : RecyclerView.ViewHolder(binding.root) override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CartItemViewHolder { @@ -24,16 +27,28 @@ class SingleCartItemAdapter(private val cartItem: CartItemsItem) : override fun getItemCount(): Int = 1 + fun updateProductImages(newImages: Map) { + productImages = newImages + notifyDataSetChanged() + } + override fun onBindViewHolder(holder: CartItemViewHolder, position: Int) { with(holder.binding) { - // Set cart item details tvProductName.text = cartItem.productName tvProductQuantity.text = "${cartItem.quantity} buah" tvProductPrice.text = formatCurrency(cartItem.price.toDouble()) - // Load placeholder image + // Get the image for this product + val img = productImages[cartItem.productId] + val fullImageUrl = when (img) { + is String -> { + if (img.startsWith("/")) BASE_URL + img.substring(1) else img + } + else -> null + } + Glide.with(ivProduct.context) - .load(R.drawable.placeholder_image) + .load(fullImageUrl) .placeholder(R.drawable.placeholder_image) .error(R.drawable.placeholder_image) .into(ivProduct) diff --git a/app/src/main/java/com/alya/ecommerce_serang/ui/order/SingleProductAdapter.kt b/app/src/main/java/com/alya/ecommerce_serang/ui/order/SingleProductAdapter.kt index 0255a93..89baf7b 100644 --- a/app/src/main/java/com/alya/ecommerce_serang/ui/order/SingleProductAdapter.kt +++ b/app/src/main/java/com/alya/ecommerce_serang/ui/order/SingleProductAdapter.kt @@ -3,6 +3,7 @@ package com.alya.ecommerce_serang.ui.order import android.view.LayoutInflater import android.view.ViewGroup import androidx.recyclerview.widget.RecyclerView +import com.alya.ecommerce_serang.BuildConfig.BASE_URL import com.alya.ecommerce_serang.R import com.alya.ecommerce_serang.data.api.dto.CheckoutData import com.alya.ecommerce_serang.data.api.dto.OrderRequestBuy @@ -36,9 +37,16 @@ class SingleProductAdapter(private val checkoutData: CheckoutData) : tvProductPrice.text = formatCurrency(checkoutData.productPrice) + val fullImageUrl = when (val img = checkoutData.productImageUrl) { + is String -> { + if (img.startsWith("/")) BASE_URL + img.substring(1) else img + } + else -> null + } + // Load product image Glide.with(ivProduct.context) - .load(checkoutData.productImageUrl) + .load(fullImageUrl) .apply( RequestOptions() .placeholder(R.drawable.placeholder_image) diff --git a/app/src/main/java/com/alya/ecommerce_serang/ui/order/detail/AddEvidencePaymentActivity.kt b/app/src/main/java/com/alya/ecommerce_serang/ui/order/detail/AddEvidencePaymentActivity.kt index e3f53c8..022be0b 100644 --- a/app/src/main/java/com/alya/ecommerce_serang/ui/order/detail/AddEvidencePaymentActivity.kt +++ b/app/src/main/java/com/alya/ecommerce_serang/ui/order/detail/AddEvidencePaymentActivity.kt @@ -33,6 +33,7 @@ import com.alya.ecommerce_serang.data.repository.OrderRepository import com.alya.ecommerce_serang.data.repository.Result import com.alya.ecommerce_serang.databinding.ActivityAddEvidencePaymentBinding import com.alya.ecommerce_serang.utils.BaseViewModelFactory +import com.alya.ecommerce_serang.utils.PopUpDialog import com.alya.ecommerce_serang.utils.SessionManager import okhttp3.MediaType.Companion.toMediaTypeOrNull import okhttp3.MultipartBody @@ -166,6 +167,7 @@ class AddEvidencePaymentActivity : AppCompatActivity() { // Submit button binding.btnSubmit.setOnClickListener { + validateAndUpload() Log.d(TAG, "AddEvidencePaymentActivity onCreate completed") } @@ -313,12 +315,14 @@ class AddEvidencePaymentActivity : AppCompatActivity() { return } + //in case applied metode pembayaran yang lain // if (binding.spinnerPaymentMethod.selectedItemPosition == 0) { // Toast.makeText(this, "Silahkan pilih metode pembayaran", Toast.LENGTH_SHORT).show() // return // } binding.etAccountNumber.visibility = View.GONE + //in case applied nomor rekening // if (binding.etAccountNumber.text.toString().trim().isEmpty()) { // Toast.makeText(this, "Silahkan isi nomor rekening/HP", Toast.LENGTH_SHORT).show() // return @@ -330,8 +334,16 @@ class AddEvidencePaymentActivity : AppCompatActivity() { // } // All validations passed, proceed with upload - uploadPaymentProof() - + PopUpDialog.showConfirmDialog( + context = this, + title = "Apakah bukti yang dikirimkan sudah benar?", + message = "Pastikan bukti yang dikirimkan valid", + positiveText = "Ya", + negativeText = "Tidak", + onYesClicked = { + uploadPaymentProof() + } + ) } private fun uploadPaymentProof() { diff --git a/app/src/main/java/com/alya/ecommerce_serang/ui/order/detail/PaymentActivity.kt b/app/src/main/java/com/alya/ecommerce_serang/ui/order/detail/PaymentActivity.kt index 6d7d8b5..28549ab 100644 --- a/app/src/main/java/com/alya/ecommerce_serang/ui/order/detail/PaymentActivity.kt +++ b/app/src/main/java/com/alya/ecommerce_serang/ui/order/detail/PaymentActivity.kt @@ -232,7 +232,6 @@ class PaymentActivity : AppCompatActivity() { else -> emptyList() } - // Tampilkan instruksi dalam dialog val dialog = AlertDialog.Builder(this) .setTitle("Petunjuk Transfer $type") .setItems(instructions.toTypedArray(), null) diff --git a/app/src/main/java/com/alya/ecommerce_serang/ui/order/history/HistoryActivity.kt b/app/src/main/java/com/alya/ecommerce_serang/ui/order/history/HistoryActivity.kt index d7a9911..625c21b 100644 --- a/app/src/main/java/com/alya/ecommerce_serang/ui/order/history/HistoryActivity.kt +++ b/app/src/main/java/com/alya/ecommerce_serang/ui/order/history/HistoryActivity.kt @@ -57,6 +57,14 @@ class HistoryActivity : AppCompatActivity() { } } +// override fun onDialogConfirmed() { +// // Option 1: refresh activity +// recreate() +// +// // Or Option 2: reload only data +// // viewModel.loadOrders() +// } + private fun setupToolbar() { setSupportActionBar(binding.toolbar) supportActionBar?.setDisplayShowTitleEnabled(false) diff --git a/app/src/main/java/com/alya/ecommerce_serang/ui/order/history/HistoryViewModel.kt b/app/src/main/java/com/alya/ecommerce_serang/ui/order/history/HistoryViewModel.kt index 702d3f3..0bcf642 100644 --- a/app/src/main/java/com/alya/ecommerce_serang/ui/order/history/HistoryViewModel.kt +++ b/app/src/main/java/com/alya/ecommerce_serang/ui/order/history/HistoryViewModel.kt @@ -231,19 +231,21 @@ class HistoryViewModel(private val repository: OrderRepository) : ViewModel() { } } - private suspend fun refresh(status: String) { + 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 + viewModelScope.launch { + 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 } - 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) } diff --git a/app/src/main/java/com/alya/ecommerce_serang/ui/order/history/OrderHistoryAdapter.kt b/app/src/main/java/com/alya/ecommerce_serang/ui/order/history/OrderHistoryAdapter.kt index 18f21f2..c9ce4a5 100644 --- a/app/src/main/java/com/alya/ecommerce_serang/ui/order/history/OrderHistoryAdapter.kt +++ b/app/src/main/java/com/alya/ecommerce_serang/ui/order/history/OrderHistoryAdapter.kt @@ -28,6 +28,7 @@ import com.alya.ecommerce_serang.ui.order.detail.PaymentActivity import com.alya.ecommerce_serang.ui.order.history.cancelorder.CancelOrderBottomSheet import com.alya.ecommerce_serang.ui.order.review.CreateReviewActivity import com.alya.ecommerce_serang.ui.product.ReviewProductActivity +import com.alya.ecommerce_serang.utils.PopUpDialog import com.google.android.material.button.MaterialButton import com.google.android.material.textfield.TextInputLayout import com.google.gson.Gson @@ -41,7 +42,8 @@ import java.util.TimeZone class OrderHistoryAdapter( private val onOrderClickListener: (OrdersItem) -> Unit, private val viewModel: HistoryViewModel, - private val callbacks: OrderActionCallbacks + private val callbacks: OrderActionCallbacks, + private val listener: OnDialogActionListener ) : RecyclerView.Adapter() { interface OrderActionCallbacks { @@ -237,9 +239,18 @@ class OrderHistoryAdapter( callbacks.onShowLoading(true) // Call ViewModel - viewModel.confirmOrderCompleted(order.orderId, "completed") + PopUpDialog.showConfirmDialog( + context = itemView.context, + title = "Apakah anda yakin pesanan sudah sampai?", + message = "Pastikan pesanan sudah samapi di alamat tujuan", + positiveText = "Ya", + negativeText = "Tidak", + onYesClicked = { + viewModel.confirmOrderCompleted(order.orderId, "completed") + listener.onDialogConfirmed() + } + ) // viewModel.refreshOrders() - } } @@ -520,9 +531,19 @@ class OrderHistoryAdapter( val bottomSheet = CancelOrderBottomSheet( orderId = orderId, onOrderCancelled = { - callbacks.onOrderCancelled(orderId.toString(), true, "Order cancelled successfully") - // Show a success message - Toast.makeText(context, "Pesanan berhasil dibatalkan", Toast.LENGTH_SHORT).show() + + PopUpDialog.showConfirmDialog( + context = itemView.context, + title = "Apakah anda yakin ingin membatalkan pesanan?", + positiveText = "Ya", + negativeText = "Tidak", + onYesClicked = { + callbacks.onOrderCancelled(orderId.toString(), true, "Order cancelled successfully") + // Show a success message + Toast.makeText(context, "Pesanan berhasil dibatalkan", Toast.LENGTH_SHORT).show() + listener.onDialogConfirmed() + } + ) } ) @@ -602,4 +623,8 @@ class OrderHistoryAdapter( } } } +} + +interface OnDialogActionListener { + fun onDialogConfirmed() } \ No newline at end of file diff --git a/app/src/main/java/com/alya/ecommerce_serang/ui/order/history/OrderListFragment.kt b/app/src/main/java/com/alya/ecommerce_serang/ui/order/history/OrderListFragment.kt index 1c73594..8630d6a 100644 --- a/app/src/main/java/com/alya/ecommerce_serang/ui/order/history/OrderListFragment.kt +++ b/app/src/main/java/com/alya/ecommerce_serang/ui/order/history/OrderListFragment.kt @@ -24,7 +24,7 @@ import com.alya.ecommerce_serang.ui.order.history.detailorder.DetailOrderStatusA import com.alya.ecommerce_serang.utils.BaseViewModelFactory import com.alya.ecommerce_serang.utils.SessionManager -class OrderListFragment : Fragment(), OrderHistoryAdapter.OrderActionCallbacks { +class OrderListFragment : Fragment(), OrderHistoryAdapter.OrderActionCallbacks, OnDialogActionListener { private var _binding: FragmentOrderListBinding? = null private val binding get() = _binding!! @@ -93,7 +93,8 @@ class OrderListFragment : Fragment(), OrderHistoryAdapter.OrderActionCallbacks { navigateToOrderDetail(order) }, viewModel = viewModel, - callbacks = this // Pass this fragment as callback + callbacks = this, + listener = this// Pass this fragment as callback ) orderAdapter.setFragmentStatus(status) @@ -175,7 +176,6 @@ class OrderListFragment : Fragment(), OrderHistoryAdapter.OrderActionCallbacks { override fun onOrderCancelled(orderId: String, success: Boolean, message: String) { if (success) { - Toast.makeText(requireContext(), "Berhasil batalkan pesanan", Toast.LENGTH_SHORT).show() Log.d("OrderListFragment", "Order cancel success: $message") // loadOrders() // Refresh the list if (success) viewModel.updateStatus(status, forceRefresh = true) @@ -210,4 +210,14 @@ class OrderListFragment : Fragment(), OrderHistoryAdapter.OrderActionCallbacks { super.onResume() observeOrderList() } + + override fun onDialogConfirmed() { + + viewModel.refresh(status) + // Option 1: refresh seluruh fragment + requireActivity().supportFragmentManager.beginTransaction() + .detach(this) + .attach(this) + .commit() + } } \ No newline at end of file diff --git a/app/src/main/java/com/alya/ecommerce_serang/ui/order/history/cancelorder/CancelOrderBottomSheet.kt b/app/src/main/java/com/alya/ecommerce_serang/ui/order/history/cancelorder/CancelOrderBottomSheet.kt index 81be667..c4b33c7 100644 --- a/app/src/main/java/com/alya/ecommerce_serang/ui/order/history/cancelorder/CancelOrderBottomSheet.kt +++ b/app/src/main/java/com/alya/ecommerce_serang/ui/order/history/cancelorder/CancelOrderBottomSheet.kt @@ -130,13 +130,6 @@ class CancelOrderBottomSheet( is Result.Success -> { // Hide loading indicator showLoading(false) - - // Show success message - Toast.makeText( - context, - "Pesanan berhasil dibatalkan", - Toast.LENGTH_SHORT - ).show() Log.d(TAG, "Cancel order status: SUCCESS, message: ${result.data.message}") // Notify callback and close dialog diff --git a/app/src/main/java/com/alya/ecommerce_serang/ui/product/category/CategoryProductsActivity.kt b/app/src/main/java/com/alya/ecommerce_serang/ui/product/category/CategoryProductsActivity.kt index fb80bbb..e6cec5b 100644 --- a/app/src/main/java/com/alya/ecommerce_serang/ui/product/category/CategoryProductsActivity.kt +++ b/app/src/main/java/com/alya/ecommerce_serang/ui/product/category/CategoryProductsActivity.kt @@ -91,10 +91,11 @@ class CategoryProductsActivity : AppCompatActivity() { // title = category.name } - val fullImageUrl = if (category.image.startsWith("/")) { - BASE_URL + category.image.removePrefix("/") // Append base URL if the path starts with "/" - } else { - category.image // Use as is if it's already a full URL + val fullImageUrl = when (val img = category.image) { + is String -> { + if (img.startsWith("/")) BASE_URL + img.substring(1) else img + } + else -> null } // Load category image diff --git a/app/src/main/java/com/alya/ecommerce_serang/ui/profile/ProfileFragment.kt b/app/src/main/java/com/alya/ecommerce_serang/ui/profile/ProfileFragment.kt index 5c76fe8..76ad4e7 100644 --- a/app/src/main/java/com/alya/ecommerce_serang/ui/profile/ProfileFragment.kt +++ b/app/src/main/java/com/alya/ecommerce_serang/ui/profile/ProfileFragment.kt @@ -1,6 +1,5 @@ package com.alya.ecommerce_serang.ui.profile -import android.app.AlertDialog import android.app.ProgressDialog import android.content.Intent import android.os.Bundle @@ -27,6 +26,7 @@ import com.alya.ecommerce_serang.ui.profile.mystore.RegisterStoreActivity import com.alya.ecommerce_serang.ui.profile.mystore.StoreOnReviewActivity import com.alya.ecommerce_serang.ui.profile.mystore.StoreSuspendedActivity import com.alya.ecommerce_serang.utils.BaseViewModelFactory +import com.alya.ecommerce_serang.utils.PopUpDialog import com.alya.ecommerce_serang.utils.SessionManager import com.alya.ecommerce_serang.utils.viewmodel.MyStoreViewModel import com.alya.ecommerce_serang.utils.viewmodel.ProfileViewModel @@ -200,14 +200,16 @@ class ProfileFragment : Fragment() { private fun logout(){ - AlertDialog.Builder(requireContext()) - .setTitle("Konfirmasi") - .setMessage("Apakah anda yakin ingin keluar?") - .setPositiveButton("Ya") { _, _ -> + PopUpDialog.showConfirmDialog( + context = requireContext(), + title = "Konfirmasi", + message = "Apakah anda yakin ingin keluar?", + positiveText = "Ya", + negativeText = "Tidak", + onYesClicked = { actionLogout() } - .setNegativeButton("Tidak", null) - .show() + ) } private fun actionLogout(){ diff --git a/app/src/main/java/com/alya/ecommerce_serang/ui/profile/editprofile/EditProfileCustActivity.kt b/app/src/main/java/com/alya/ecommerce_serang/ui/profile/editprofile/EditProfileCustActivity.kt index 2b1284f..b3c9db4 100644 --- a/app/src/main/java/com/alya/ecommerce_serang/ui/profile/editprofile/EditProfileCustActivity.kt +++ b/app/src/main/java/com/alya/ecommerce_serang/ui/profile/editprofile/EditProfileCustActivity.kt @@ -2,7 +2,6 @@ package com.alya.ecommerce_serang.ui.profile.editprofile import android.Manifest import android.app.Activity -import android.app.AlertDialog import android.app.DatePickerDialog import android.content.Intent import android.content.pm.PackageManager @@ -29,6 +28,7 @@ import com.alya.ecommerce_serang.data.repository.Result import com.alya.ecommerce_serang.data.repository.UserRepository import com.alya.ecommerce_serang.databinding.ActivityEditProfileCustBinding import com.alya.ecommerce_serang.utils.BaseViewModelFactory +import com.alya.ecommerce_serang.utils.PopUpDialog import com.alya.ecommerce_serang.utils.SessionManager import com.alya.ecommerce_serang.utils.viewmodel.ProfileViewModel import com.bumptech.glide.Glide @@ -213,12 +213,17 @@ class EditProfileCustActivity : AppCompatActivity() { } private fun confirmUpdate() { - AlertDialog.Builder(this) - .setTitle("Konfirmasi Perubahan") - .setMessage("Apakah Anda yakin ingin menyimpan perubahan profil toko Anda?") - .setPositiveButton("Ya") { _, _ -> saveProfile() } - .setNegativeButton("Batal", null) - .show() + + PopUpDialog.showConfirmDialog( + context = this, + title = "Apakah Anda yakin ingin menyimpan perubahan profil?", + message = "Pastikan data yang dimasukkan sudah benar", + positiveText = "Ya", + negativeText = "Tidak", + onYesClicked = { + saveProfile() + } + ) } private fun hasChanged(): Boolean { diff --git a/app/src/main/java/com/alya/ecommerce_serang/ui/profile/mystore/balance/BalanceTopUpActivity.kt b/app/src/main/java/com/alya/ecommerce_serang/ui/profile/mystore/balance/BalanceTopUpActivity.kt index 8c9b45f..549778e 100644 --- a/app/src/main/java/com/alya/ecommerce_serang/ui/profile/mystore/balance/BalanceTopUpActivity.kt +++ b/app/src/main/java/com/alya/ecommerce_serang/ui/profile/mystore/balance/BalanceTopUpActivity.kt @@ -24,6 +24,7 @@ import com.alya.ecommerce_serang.R import com.alya.ecommerce_serang.data.api.response.store.profile.Payment import com.alya.ecommerce_serang.data.api.retrofit.ApiConfig import com.alya.ecommerce_serang.utils.ImageUtils.compressImage +import com.alya.ecommerce_serang.utils.PopUpDialog import com.alya.ecommerce_serang.utils.SessionManager import kotlinx.coroutines.launch import okhttp3.MediaType.Companion.toMediaTypeOrNull @@ -374,14 +375,11 @@ class BalanceTopUpActivity : AppCompatActivity() { // Show a dialog with the success message runOnUiThread { - AlertDialog.Builder(this@BalanceTopUpActivity) - .setTitle("Berhasil") - .setMessage(successMessage) - .setPositiveButton("OK") { dialog, _ -> - dialog.dismiss() - finish() - } - .show() + PopUpDialog.showConfirmDialog( + context = this@BalanceTopUpActivity, + iconRes = R.drawable.checkmark__1_, + title = "Berhasil melakukan Top-Up" + ) } } else { // Get more detailed error information @@ -408,13 +406,12 @@ class BalanceTopUpActivity : AppCompatActivity() { // Show a dialog with the error message runOnUiThread { - AlertDialog.Builder(this@BalanceTopUpActivity) - .setTitle("Error Response") - .setMessage(errorMessage) - .setPositiveButton("OK") { dialog, _ -> - dialog.dismiss() - } - .show() + + PopUpDialog.showConfirmDialog( + context = this@BalanceTopUpActivity, + iconRes = R.drawable.ic_cancel, + title = "Gagal melakukan Top-Up" + ) } } } catch (e: Exception) { diff --git a/app/src/main/java/com/alya/ecommerce_serang/ui/profile/mystore/profile/DetailStoreProfileActivity.kt b/app/src/main/java/com/alya/ecommerce_serang/ui/profile/mystore/profile/DetailStoreProfileActivity.kt index 93c45f0..c6ab9d1 100644 --- a/app/src/main/java/com/alya/ecommerce_serang/ui/profile/mystore/profile/DetailStoreProfileActivity.kt +++ b/app/src/main/java/com/alya/ecommerce_serang/ui/profile/mystore/profile/DetailStoreProfileActivity.kt @@ -29,9 +29,10 @@ import com.alya.ecommerce_serang.databinding.DialogStoreImageBinding import com.alya.ecommerce_serang.ui.profile.mystore.profile.address.DetailStoreAddressActivity import com.alya.ecommerce_serang.ui.profile.mystore.profile.payment_info.PaymentInfoActivity import com.alya.ecommerce_serang.ui.profile.mystore.profile.shipping_service.ShippingServiceActivity -import com.alya.ecommerce_serang.utils.viewmodel.MyStoreViewModel import com.alya.ecommerce_serang.utils.BaseViewModelFactory +import com.alya.ecommerce_serang.utils.PopUpDialog import com.alya.ecommerce_serang.utils.SessionManager +import com.alya.ecommerce_serang.utils.viewmodel.MyStoreViewModel import com.bumptech.glide.Glide import okhttp3.MediaType.Companion.toMediaTypeOrNull import okhttp3.MultipartBody @@ -39,7 +40,6 @@ import okhttp3.RequestBody import okhttp3.RequestBody.Companion.asRequestBody import java.io.File import java.io.FileOutputStream -import kotlin.getValue class DetailStoreProfileActivity : AppCompatActivity() { private lateinit var binding: ActivityDetailStoreProfileBinding @@ -244,12 +244,17 @@ class DetailStoreProfileActivity : AppCompatActivity() { } private fun confirmUpdate() { - AlertDialog.Builder(this) - .setTitle("Konfirmasi Perubahan") - .setMessage("Apakah Anda yakin ingin menyimpan perubahan profil toko Anda?") - .setPositiveButton("Ya") { _, _ -> updateStoreProfile() } - .setNegativeButton("Batal", null) - .show() + + PopUpDialog.showConfirmDialog( + context = this, + title = "Apakah Anda yakin ingin menyimpan perubahan profil?", + message = "Pastikan data yang dimasukkan sudah benar", + positiveText = "Ya", + negativeText = "Tidak", + onYesClicked = { + updateStoreProfile() + } + ) } private fun showImageOptions() { diff --git a/app/src/main/java/com/alya/ecommerce_serang/ui/profile/mystore/sells/SellsListFragment.kt b/app/src/main/java/com/alya/ecommerce_serang/ui/profile/mystore/sells/SellsListFragment.kt index 70fea0b..0c46db4 100644 --- a/app/src/main/java/com/alya/ecommerce_serang/ui/profile/mystore/sells/SellsListFragment.kt +++ b/app/src/main/java/com/alya/ecommerce_serang/ui/profile/mystore/sells/SellsListFragment.kt @@ -142,7 +142,7 @@ class SellsListFragment : Fragment() { binding.progressBar.visibility = View.GONE binding.tvEmptyState.visibility = View.VISIBLE - Toast.makeText(requireContext(), result.message, Toast.LENGTH_SHORT).show() +// Toast.makeText(requireContext(), result.message, Toast.LENGTH_SHORT).show() } is ViewState.Loading -> { binding.progressBar.visibility = View.VISIBLE diff --git a/app/src/main/java/com/alya/ecommerce_serang/utils/HorizontalMarginItemDecoration.kt b/app/src/main/java/com/alya/ecommerce_serang/utils/HorizontalMarginItemDecoration.kt deleted file mode 100644 index 28d9a19..0000000 --- a/app/src/main/java/com/alya/ecommerce_serang/utils/HorizontalMarginItemDecoration.kt +++ /dev/null @@ -1,22 +0,0 @@ -package com.alya.ecommerce_serang.utils - -import android.content.Context -import android.graphics.Rect -import android.view.View -import androidx.annotation.DimenRes -import androidx.recyclerview.widget.RecyclerView - -class HorizontalMarginItemDecoration(context: Context, @DimenRes horizontalMarginInDp: Int) : - RecyclerView.ItemDecoration() { - - private val horizontalMarginInPx: Int = - context.resources.getDimension(horizontalMarginInDp).toInt() - - override fun getItemOffsets( - outRect: Rect, view: View, parent: RecyclerView, state: RecyclerView.State - ) { - outRect.right = horizontalMarginInPx - outRect.left = horizontalMarginInPx - } - -} \ No newline at end of file diff --git a/app/src/main/java/com/alya/ecommerce_serang/utils/PopUpDialog.kt b/app/src/main/java/com/alya/ecommerce_serang/utils/PopUpDialog.kt index bab0022..6648154 100644 --- a/app/src/main/java/com/alya/ecommerce_serang/utils/PopUpDialog.kt +++ b/app/src/main/java/com/alya/ecommerce_serang/utils/PopUpDialog.kt @@ -78,7 +78,6 @@ object PopUpDialog { dialog.dismiss() } - dialog.show() } } \ No newline at end of file diff --git a/app/src/main/res/drawable/splash_drawable.xml b/app/src/main/res/drawable/splash_drawable.xml index bd2465d..ddc1aba 100644 --- a/app/src/main/res/drawable/splash_drawable.xml +++ b/app/src/main/res/drawable/splash_drawable.xml @@ -4,8 +4,8 @@ \ No newline at end of file diff --git a/app/src/main/res/layout/dialog_popup.xml b/app/src/main/res/layout/dialog_popup.xml index 7bb9dc2..6aa77bc 100644 --- a/app/src/main/res/layout/dialog_popup.xml +++ b/app/src/main/res/layout/dialog_popup.xml @@ -12,11 +12,13 @@ @@ -27,8 +29,14 @@ android:layout_height="wrap_content" android:text="Judul" android:layout_marginTop="16dp" + android:paddingHorizontal="16dp" + android:paddingTop="4dp" + android:ellipsize="end" + android:scrollHorizontally="false" + android:singleLine="false" android:gravity="center" - android:textSize="18sp" + android:textSize="16sp" + android:maxLines="3" android:fontFamily="@font/dmsans_semibold" android:textColor="?attr/colorOnSurface" /> @@ -38,9 +46,15 @@ android:layout_height="wrap_content" android:layout_marginTop="12dp" android:gravity="center" + android:maxLines="3" + android:paddingHorizontal="16dp" + android:paddingTop="4dp" + android:ellipsize="end" + android:scrollHorizontally="false" + android:singleLine="false" android:text="Pesan Dialog" android:fontFamily="@font/dmsans_regular" - android:textSize="14sp" + android:textSize="12sp" android:textColor="?attr/colorOnSurfaceVariant" /> diff --git a/app/src/main/res/layout/fragment_profile.xml b/app/src/main/res/layout/fragment_profile.xml index 64ad5c7..f41add7 100644 --- a/app/src/main/res/layout/fragment_profile.xml +++ b/app/src/main/res/layout/fragment_profile.xml @@ -25,7 +25,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginStart="16dp" - android:text="Gracia Hotmauli" + android:text="Nama Pengguna" android:textSize="18sp" android:textStyle="bold" app:layout_constraintStart_toEndOf="@id/profileImage" @@ -35,7 +35,7 @@ android:id="@+id/tvUsername" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:text="\@gracia34" + android:text="Username" android:textColor="#757575" app:layout_constraintStart_toStartOf="@id/tvName" app:layout_constraintTop_toBottomOf="@id/tvName" /> diff --git a/app/src/main/res/layout/item_dialog_add_evidence.xml b/app/src/main/res/layout/item_dialog_add_evidence.xml index 9756df8..df302fa 100644 --- a/app/src/main/res/layout/item_dialog_add_evidence.xml +++ b/app/src/main/res/layout/item_dialog_add_evidence.xml @@ -3,8 +3,6 @@ xmlns:card_view="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="wrap_content" - android:layout_margin="8dp" - card_view:cardCornerRadius="12dp" card_view:cardElevation="6dp" android:foreground="?android:attr/selectableItemBackground"> @@ -18,17 +16,10 @@ android:id="@+id/tvOption" android:layout_width="match_parent" android:layout_height="wrap_content" - android:fontFamily="@font/dmsans_semibold" + android:fontFamily="@font/dmsans_regular" android:text="Item 1" - android:textColor="@color/black_500" android:textSize="16sp" /> - diff --git a/app/src/main/res/layout/item_order_history.xml b/app/src/main/res/layout/item_order_history.xml index 2436eab..793fcb6 100644 --- a/app/src/main/res/layout/item_order_history.xml +++ b/app/src/main/res/layout/item_order_history.xml @@ -133,21 +133,33 @@ @style/ShapeAppearance.MyApp.MediumComponent - @color/white @font/dmsans_regular @android:color/transparent