diff --git a/app/src/main/java/com/alya/ecommerce_serang/ui/auth/RegisterActivity.kt b/app/src/main/java/com/alya/ecommerce_serang/ui/auth/RegisterActivity.kt index d040cf7..5948017 100644 --- a/app/src/main/java/com/alya/ecommerce_serang/ui/auth/RegisterActivity.kt +++ b/app/src/main/java/com/alya/ecommerce_serang/ui/auth/RegisterActivity.kt @@ -86,19 +86,72 @@ class RegisterActivity : AppCompatActivity() { } } + // In RegisterActivity, add debug to navigateToStep: + fun navigateToStep(step: Int, userData: RegisterRequest?) { - val fragment = when (step) { - 1 -> RegisterStep1Fragment.newInstance() - 2 -> RegisterStep2Fragment.newInstance(userData) - 3 -> RegisterStep3Fragment.newInstance() - else -> null + Log.d("RegisterActivity", "=== NAVIGATE TO STEP START ===") + Log.d("RegisterActivity", "Target step: $step") + Log.d("RegisterActivity", "Current fragment count: ${supportFragmentManager.fragments.size}") + Log.d("RegisterActivity", "UserData: ${userData?.email}") + + Log.d("RegisterActivity", "Navigation called from:") + Thread.currentThread().stackTrace.take(10).forEach { element -> + Log.d("RegisterActivity", " at ${element.className}.${element.methodName}(${element.fileName}:${element.lineNumber})") } - fragment?.let { - supportFragmentManager.beginTransaction() - .replace(R.id.fragment_container, it) - .addToBackStack(null) - .commit() + + try { + val fragment = when (step) { + 1 -> { + Log.d("RegisterActivity", "Creating RegisterStep1Fragment") + RegisterStep1Fragment.newInstance() + } + 2 -> { + Log.d("RegisterActivity", "Creating RegisterStep2Fragment") + RegisterStep2Fragment.newInstance(userData) + } + 3 -> { + Log.d("RegisterActivity", "Creating RegisterStep3Fragment") + RegisterStep3Fragment.newInstance() + } + else -> { + Log.e("RegisterActivity", "Invalid step: $step") + return + } + } + + Log.d("RegisterActivity", "Fragment created, starting transaction") + + val transaction = supportFragmentManager.beginTransaction() + transaction.replace(R.id.fragment_container, fragment) + + Log.d("RegisterActivity", "About to commit transaction") + transaction.commit() + + Log.d("RegisterActivity", "Transaction committed") + + // Update ViewModel step + registerViewModel.setStep(step) + Log.d("RegisterActivity", "ViewModel step updated to: $step") + + } catch (e: Exception) { + Log.e("RegisterActivity", "Exception in navigateToStep: ${e.message}", e) + e.printStackTrace() + } + + Log.d("RegisterActivity", "=== NAVIGATE TO STEP END ===") + } + + // Handle Android back button - close activity or go to step 1 + override fun onBackPressed() { + val currentStep = registerViewModel.currentStep.value ?: 1 + + if (currentStep == 1) { + // On step 1, exit the activity + super.onBackPressed() + } else { + // On other steps, go back to step 1 + navigateToStep(1, null) } } } \ No newline at end of file diff --git a/app/src/main/java/com/alya/ecommerce_serang/ui/auth/fragments/RegisterStep2Fragment.kt b/app/src/main/java/com/alya/ecommerce_serang/ui/auth/fragments/RegisterStep2Fragment.kt index 0d60c7e..c273c9c 100644 --- a/app/src/main/java/com/alya/ecommerce_serang/ui/auth/fragments/RegisterStep2Fragment.kt +++ b/app/src/main/java/com/alya/ecommerce_serang/ui/auth/fragments/RegisterStep2Fragment.kt @@ -1,6 +1,7 @@ package com.alya.ecommerce_serang.ui.auth.fragments import android.content.Context +import android.content.Intent import android.os.Build import android.os.Bundle import android.os.CountDownTimer @@ -32,6 +33,9 @@ class RegisterStep2Fragment : Fragment() { private var _binding: FragmentRegisterStep2Binding? = null private val binding get() = _binding!! private lateinit var sessionManager: SessionManager + private var countDownTimer: CountDownTimer? = null + private var timeRemaining = 30 + private var isTimerRunning = false // In RegisterStep2Fragment AND RegisterStep3Fragment: private val registerViewModel: RegisterViewModel by activityViewModels { @@ -42,8 +46,8 @@ class RegisterStep2Fragment : Fragment() { RegisterViewModel(userRepository, orderRepository, requireContext()) } } - private var countDownTimer: CountDownTimer? = null - private var timeRemaining = 30 // 30 seconds cooldown for resend +// private var countDownTimer: CountDownTimer? = null +// private var timeRemaining = 30 // 30 seconds cooldown for resend companion object { @@ -112,13 +116,23 @@ class RegisterStep2Fragment : Fragment() { } } - binding.btnBack.setOnClickListener { - parentFragmentManager.popBackStack() - } - observeRegistrationState() observeLoginState() Log.d(TAG, "Registration and login state observers set up") + binding.btnBack.setOnClickListener { + Log.d(TAG, "Back button clicked - cleaning up timer and going to step 1") + + // Stop the timer before navigating + stopTimer() + // Small delay to ensure timer is properly canceled + binding.root.postDelayed({ +// (activity as? RegisterActivity)?.navigateToStep(1, null) + val intent = Intent(requireContext(), RegisterActivity::class.java) + startActivity(intent) + requireActivity().finish() + + }, 100) + } } private fun verifyOtp(userData: RegisterRequest?) { @@ -172,37 +186,9 @@ class RegisterStep2Fragment : Fragment() { } ?: Log.e(TAG, "Cannot resend OTP: email is null") } - private fun startResendCooldown() { - Log.d(TAG, "startResendCooldown called") - timeRemaining = 30 - binding.tvResendOtp.isEnabled = false - binding.tvResendOtp.setTextColor(ContextCompat.getColor(requireContext(), R.color.soft_gray)) - - countDownTimer?.cancel() - countDownTimer = object : CountDownTimer(30000, 1000) { - override fun onTick(millisUntilFinished: Long) { - timeRemaining = (millisUntilFinished / 1000).toInt() - binding.tvTimer.text = "Kirim ulang OTP dalam waktu 00:${String.format("%02d", timeRemaining)}" - if (timeRemaining % 5 == 0) { - Log.d(TAG, "Cooldown remaining: $timeRemaining seconds") - } - } - - override fun onFinish() { - Log.d(TAG, "Cooldown finished, enabling resend button") - binding.tvTimer.text = "Dapat mengirim ulang kode OTP" - binding.tvResendOtp.isEnabled = true - binding.tvResendOtp.setTextColor(ContextCompat.getColor(requireContext(), R.color.blue1)) - timeRemaining = 0 - } - }.start() - } - private fun observeRegistrationState() { registerViewModel.message.observe(viewLifecycleOwner) { message -> Log.d(TAG, "Message from server: $message") - // You can use the message here if needed, e.g., for showing in a specific UI element - // or for storing for later use } registerViewModel.registerState.observe(viewLifecycleOwner) { result -> when (result) { @@ -314,9 +300,117 @@ class RegisterStep2Fragment : Fragment() { } - override fun onDestroyView() { - super.onDestroyView() + private fun startResendCooldown() { + Log.d(TAG, "startResendCooldown called") + + // Cancel any existing timer first + stopTimer() + + timeRemaining = 30 + isTimerRunning = true + binding.tvResendOtp.isEnabled = false + binding.tvResendOtp.setTextColor(ContextCompat.getColor(requireContext(), R.color.soft_gray)) + + countDownTimer = object : CountDownTimer(30000, 1000) { + override fun onTick(millisUntilFinished: Long) { + if (!isTimerRunning) { + cancel() + return + } + + timeRemaining = (millisUntilFinished / 1000).toInt() + + // Check if fragment is still attached before updating UI + if (isAdded && _binding != null) { + binding.tvTimer.text = "Kirim ulang OTP dalam waktu 00:${String.format("%02d", timeRemaining)}" + if (timeRemaining % 5 == 0) { + Log.d(TAG, "Cooldown remaining: $timeRemaining seconds") + } + } + } + + override fun onFinish() { + if (!isTimerRunning) return + + Log.d(TAG, "Cooldown finished, enabling resend button") + + // Check if fragment is still attached before updating UI + if (isAdded && _binding != null) { + binding.tvTimer.text = "Dapat mengirim ulang kode OTP" + binding.tvResendOtp.isEnabled = true + binding.tvResendOtp.setTextColor(ContextCompat.getColor(requireContext(), R.color.blue1)) + timeRemaining = 0 + } + isTimerRunning = false + } + }.start() + } + + private fun stopTimer() { + Log.d(TAG, "stopTimer called") + isTimerRunning = false countDownTimer?.cancel() + countDownTimer = null + } + + + override fun onPause() { + super.onPause() + Log.d(TAG, "onPause - stopping timer") + stopTimer() + } + + override fun onStop() { + super.onStop() + Log.d(TAG, "onStop - stopping timer") + stopTimer() + } + + override fun onDestroyView() { + Log.d(TAG, "onDestroyView - cleaning up") + super.onDestroyView() + + // Ensure timer is stopped + stopTimer() + _binding = null } -} \ No newline at end of file + + override fun onDetach() { + super.onDetach() + Log.d(TAG, "onDetach - final cleanup") + stopTimer() + } +} + +// override fun onDestroyView() { +// super.onDestroyView() +// countDownTimer?.cancel() +// _binding = null +// } + +// private fun startResendCooldown() { +// Log.d(TAG, "startResendCooldown called") +// timeRemaining = 30 +// binding.tvResendOtp.isEnabled = false +// binding.tvResendOtp.setTextColor(ContextCompat.getColor(requireContext(), R.color.soft_gray)) +// +// countDownTimer?.cancel() +// countDownTimer = object : CountDownTimer(30000, 1000) { +// override fun onTick(millisUntilFinished: Long) { +// timeRemaining = (millisUntilFinished / 1000).toInt() +// binding.tvTimer.text = "Kirim ulang OTP dalam waktu 00:${String.format("%02d", timeRemaining)}" +// if (timeRemaining % 5 == 0) { +// Log.d(TAG, "Cooldown remaining: $timeRemaining seconds") +// } +// } +// +// override fun onFinish() { +// Log.d(TAG, "Cooldown finished, enabling resend button") +// binding.tvTimer.text = "Dapat mengirim ulang kode OTP" +// binding.tvResendOtp.isEnabled = true +// binding.tvResendOtp.setTextColor(ContextCompat.getColor(requireContext(), R.color.blue1)) +// timeRemaining = 0 +// } +// }.start() +// } \ No newline at end of file diff --git a/app/src/main/java/com/alya/ecommerce_serang/ui/home/HomeFragment.kt b/app/src/main/java/com/alya/ecommerce_serang/ui/home/HomeFragment.kt index 8bbfbf4..25f5704 100644 --- a/app/src/main/java/com/alya/ecommerce_serang/ui/home/HomeFragment.kt +++ b/app/src/main/java/com/alya/ecommerce_serang/ui/home/HomeFragment.kt @@ -6,6 +6,7 @@ import android.util.Log import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import android.widget.Toast import androidx.core.view.isVisible import androidx.fragment.app.Fragment import androidx.fragment.app.viewModels @@ -32,6 +33,7 @@ import com.alya.ecommerce_serang.utils.SessionManager import com.alya.ecommerce_serang.utils.setLightStatusBar import com.alya.ecommerce_serang.utils.viewmodel.HomeUiState import com.alya.ecommerce_serang.utils.viewmodel.HomeViewModel +import kotlinx.coroutines.delay import kotlinx.coroutines.launch //@AndroidEntryPoint @@ -140,12 +142,13 @@ class HomeFragment : Fragment() { viewModel.uiState.collect { state -> when (state) { is HomeUiState.Loading -> { - binding.loading.root.isVisible = true + binding.loadingAll.root.visibility = View.VISIBLE binding.error.root.isVisible = false binding.home.isVisible = false + delay(5000) } is HomeUiState.Success -> { - binding.loading.root.isVisible = false + binding.loadingAll.root.visibility = View.GONE binding.error.root.isVisible = false binding.home.isVisible = true val products = state.products @@ -154,10 +157,12 @@ class HomeFragment : Fragment() { productAdapter?.updateLimitedProducts(products) } is HomeUiState.Error -> { - binding.loading.root.isVisible = false + binding.loadingAll.root.visibility = View.GONE binding.error.root.isVisible = true binding.home.isVisible = false - binding.error.errorMessage.text = state.message +// binding.error.errorMessage.text = state.message + Log.e("HomeFragment", "Error load data: ${state.message}") + Toast.makeText(requireContext(), "Terjadi kendala. Muat ulang halaman", Toast.LENGTH_SHORT) .show() binding.error.retryButton.setOnClickListener { viewModel.retry() } diff --git a/app/src/main/java/com/alya/ecommerce_serang/ui/home/SearchHomeFragment.kt b/app/src/main/java/com/alya/ecommerce_serang/ui/home/SearchHomeFragment.kt index aca01ec..c265181 100644 --- a/app/src/main/java/com/alya/ecommerce_serang/ui/home/SearchHomeFragment.kt +++ b/app/src/main/java/com/alya/ecommerce_serang/ui/home/SearchHomeFragment.kt @@ -7,12 +7,15 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.view.inputmethod.InputMethodManager +import android.widget.TextView +import androidx.core.content.ContextCompat import androidx.core.view.isVisible import androidx.fragment.app.Fragment import androidx.fragment.app.viewModels import androidx.navigation.fragment.findNavController import androidx.navigation.fragment.navArgs import androidx.recyclerview.widget.GridLayoutManager +import com.alya.ecommerce_serang.R import com.alya.ecommerce_serang.data.api.dto.ProductsItem import com.alya.ecommerce_serang.data.api.retrofit.ApiConfig import com.alya.ecommerce_serang.data.repository.ProductRepository @@ -106,6 +109,11 @@ class SearchHomeFragment : Fragment() { } }) + val searchText = findViewById(androidx.appcompat.R.id.search_src_text) + searchText.textSize = 14f // in sp + searchText.setHintTextColor(ContextCompat.getColor(context, R.color.black_200)) + searchText.setTextColor(ContextCompat.getColor(context, R.color.black)) + if (args.query.isNullOrEmpty()) { requestFocus() post { 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 1c23baf..84b4caa 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 @@ -154,8 +154,18 @@ class CheckoutActivity : AppCompatActivity() { // Observe address details viewModel.addressDetails.observe(this) { address -> - binding.tvPlacesAddress.text = address?.recipient - binding.tvAddress.text = "${address?.street}, ${address?.subdistrict}" + if (address != null) { + // Show selected address + binding.containerEmptyAddress.visibility = View.GONE + binding.containerAddress.visibility = View.VISIBLE + + binding.tvPlacesAddress.text = address.recipient + binding.tvAddress.text = "${address.street}, ${address.subdistrict}" + } else { + // Show empty address state + binding.containerEmptyAddress.visibility = View.VISIBLE + binding.containerAddress.visibility = View.GONE + } } viewModel.availablePaymentMethods.observe(this) { paymentMethods -> @@ -172,9 +182,7 @@ class CheckoutActivity : AppCompatActivity() { // Update the adapter ONLY if it exists paymentAdapter?.let { adapter -> - // This line was causing issues - using setSelectedPayment instead of setSelectedPaymentName adapter.setSelectedPaymentId(selectedPayment.id) - Log.d("CheckoutActivity", "Updated adapter with selected payment: ${selectedPayment.id}") } } @@ -183,13 +191,13 @@ class CheckoutActivity : AppCompatActivity() { // Observe loading state viewModel.isLoading.observe(this) { isLoading -> binding.btnPay.isEnabled = !isLoading - } // Observe error messages viewModel.errorMessage.observe(this) { message -> if (message.isNotEmpty()) { - Toast.makeText(this, message, Toast.LENGTH_SHORT).show() + Toast.makeText(this, "Terdapat kendala di pemesanan", Toast.LENGTH_SHORT).show() + Log.e("CheckoutActivity", "Error from errorMessage: $message") } } @@ -207,11 +215,16 @@ class CheckoutActivity : AppCompatActivity() { if (paymentMethods.isEmpty()) { Log.e("CheckoutActivity", "Payment methods list is empty") Toast.makeText(this, "Tidak ditemukan metode pembayaran", Toast.LENGTH_SHORT).show() - binding.tvEmptyPayment.visibility = View.VISIBLE + + // Show empty payment state + binding.containerEmptyPayment.visibility = View.VISIBLE + binding.rvPaymentInfo.visibility = View.GONE return } - binding.tvEmptyPayment.visibility = View.GONE + binding.containerEmptyPayment.visibility = View.GONE + binding.rvPaymentInfo.visibility = View.VISIBLE + // Debug logging Log.d("CheckoutActivity", "Setting up payment methods: ${paymentMethods.size} methods available") @@ -268,6 +281,16 @@ class CheckoutActivity : AppCompatActivity() { this.adapter = adapter isNestedScrollingEnabled = false } + +// if (checkoutData.cartItems.isEmpty()) { +// // Show empty products state +// binding.containerEmptyProducts.visibility = View.VISIBLE +// binding.rvProductItems.visibility = View.GONE +// return +// } + + binding.containerEmptyProducts.visibility = View.GONE + binding.rvProductItems.visibility = View.VISIBLE } private fun updateOrderSummary() { @@ -292,7 +315,8 @@ class CheckoutActivity : AppCompatActivity() { private fun updateShippingUI(shipName: String, shipService: String, shipEtd: String, shipPrice: Int) { if (shipName.isNotEmpty() && shipService.isNotEmpty()) { - // Display shipping name and service in one line + // Hide empty state and show selected shipping + binding.containerEmptyShipping.visibility = View.GONE binding.cardShipment.visibility = View.VISIBLE binding.tvCourierName.text = "$shipName $shipService" @@ -300,6 +324,8 @@ class CheckoutActivity : AppCompatActivity() { binding.tvShippingPrice.text = formatCurrency(shipPrice.toDouble()) binding.rbJne.isChecked = true } else { + // Show empty shipping state + binding.containerEmptyShipping.visibility = View.VISIBLE binding.cardShipment.visibility = View.GONE } } @@ -312,10 +338,10 @@ class CheckoutActivity : AppCompatActivity() { } // Shipping method selection - binding.layoutShippingMethod.setOnClickListener { + binding.tvShippingOption.setOnClickListener { val addressId = viewModel.addressDetails.value?.id ?: 0 if (addressId <= 0) { - Toast.makeText(this, "Silahkan pilih metode pengiriman dahulu", Toast.LENGTH_SHORT).show() + Toast.makeText(this, "Silahkan pilih alamat dahulu", Toast.LENGTH_SHORT).show() return@setOnClickListener } diff --git a/app/src/main/java/com/alya/ecommerce_serang/ui/order/address/AddressActivity.kt b/app/src/main/java/com/alya/ecommerce_serang/ui/order/address/AddressActivity.kt index 1237eaa..8c0612d 100644 --- a/app/src/main/java/com/alya/ecommerce_serang/ui/order/address/AddressActivity.kt +++ b/app/src/main/java/com/alya/ecommerce_serang/ui/order/address/AddressActivity.kt @@ -52,12 +52,12 @@ class AddressActivity : AppCompatActivity() { windowInsets } + viewModel.fetchAddresses() setupToolbar() setupRecyclerView() setupObservers() - viewModel.fetchAddresses() } @@ -126,6 +126,11 @@ class AddressActivity : AppCompatActivity() { finish() } + override fun onResume() { + super.onResume() + viewModel.fetchAddresses() + } + companion object { const val EXTRA_ADDRESS_ID = "extra_address_id" } 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 806c878..e3f53c8 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 @@ -61,8 +61,8 @@ class AddEvidencePaymentActivity : AppCompatActivity() { } private val paymentMethods = arrayOf( + "Pilih Metode Pembayaran", "Transfer Bank", - "QRIS", ) // private val getContent = registerForActivityResult(ActivityResultContracts.GetContent()) { uri: Uri? -> @@ -313,10 +313,10 @@ class AddEvidencePaymentActivity : AppCompatActivity() { return } - if (binding.spinnerPaymentMethod.selectedItemPosition == 0) { - Toast.makeText(this, "Silahkan pilih metode pembayaran", Toast.LENGTH_SHORT).show() - return - } +// if (binding.spinnerPaymentMethod.selectedItemPosition == 0) { +// Toast.makeText(this, "Silahkan pilih metode pembayaran", Toast.LENGTH_SHORT).show() +// return +// } binding.etAccountNumber.visibility = View.GONE // if (binding.etAccountNumber.text.toString().trim().isEmpty()) { @@ -324,10 +324,10 @@ class AddEvidencePaymentActivity : AppCompatActivity() { // return // } - if (binding.tvPaymentDate.text.toString() == "Pilih tanggal") { - Toast.makeText(this, "Silahkan pilih tanggal pembayaran", Toast.LENGTH_SHORT).show() - return - } +// if (binding.tvPaymentDate.text.toString() == "Pilih tanggal") { +// Toast.makeText(this, "Silahkan pilih tanggal pembayaran", Toast.LENGTH_SHORT).show() +// return +// } // All validations passed, proceed with upload uploadPaymentProof() 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 8db8d17..d211fa8 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 @@ -547,15 +547,6 @@ class OrderHistoryAdapter( // Use ViewModel to fetch order details viewModel.getOrderDetails(order.orderId) - // Create loading dialog -// val loadingDialog = Dialog(itemView.context).apply { -// requestWindowFeature(Window.FEATURE_NO_TITLE) -// setContentView(R.layout.dialog_loading) -// window?.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT)) -// setCancelable(false) -// } -// loadingDialog.show() - viewModel.error.observe(itemView.findViewTreeLifecycleOwner()!!) { errorMsg -> if (!errorMsg.isNullOrEmpty()) { Toast.makeText(itemView.context, errorMsg, Toast.LENGTH_SHORT).show() diff --git a/app/src/main/java/com/alya/ecommerce_serang/ui/product/DetailProductActivity.kt b/app/src/main/java/com/alya/ecommerce_serang/ui/product/DetailProductActivity.kt index f56f96a..e89cb1e 100644 --- a/app/src/main/java/com/alya/ecommerce_serang/ui/product/DetailProductActivity.kt +++ b/app/src/main/java/com/alya/ecommerce_serang/ui/product/DetailProductActivity.kt @@ -112,13 +112,17 @@ class DetailProductActivity : AppCompatActivity() { when (result) { is Result.Success -> { updateStoreInfo(result.data) + binding.progressBarDetailStore.visibility = View.GONE } is Result.Error -> { // Show error message, maybe a Toast or Snackbar - Toast.makeText(this, "Failed to load store: ${result.exception.message}", Toast.LENGTH_SHORT).show() + binding.progressBarDetailStore.visibility = View.GONE + Log.e("DetailProfileActivity", "Failed to load store: ${result.exception.message}") + Toast.makeText(this, "Kendala memuat toko", Toast.LENGTH_SHORT).show() } is Result.Loading -> { // Show loading indicator if needed + binding.progressBarDetailStore.visibility = View.VISIBLE } } } @@ -160,6 +164,10 @@ class DetailProductActivity : AppCompatActivity() { val products = viewModel.otherProducts.value.orEmpty() if (products.isNotEmpty()) { updateOtherProducts(products, storeMap) + } else { + binding.emptyOtherProducts.visibility = View.VISIBLE + binding.recyclerViewOtherProducts.visibility = View.GONE + binding.tvViewAllProducts.visibility = View.GONE } } } @@ -190,12 +198,14 @@ class DetailProductActivity : AppCompatActivity() { private fun updateOtherProducts(products: List, storeMap: Map) { if (products.isEmpty()) { Log.d("DetailProductActivity", "Product list is empty, hiding RecyclerView") - binding.recyclerViewOtherProducts.visibility = View.VISIBLE + binding.recyclerViewOtherProducts.visibility = View.GONE + binding.emptyOtherProducts.visibility = View.VISIBLE binding.tvViewAllProducts.visibility = View.GONE } else { Log.d("DetailProductActivity", "Displaying product list in RecyclerView") binding.recyclerViewOtherProducts.visibility = View.VISIBLE binding.tvViewAllProducts.visibility = View.VISIBLE + binding.emptyOtherProducts.visibility = View.GONE productAdapter = OtherProductAdapter(products, onClick = { product -> handleProductClick(product) @@ -316,11 +326,13 @@ class DetailProductActivity : AppCompatActivity() { val limitedReviewList = if (reviewList.isNotEmpty()) listOf(reviewList.first()) else emptyList() if (reviewList.isEmpty()) { binding.recyclerViewReviews.visibility = View.GONE + binding.emptyReview.visibility = View.VISIBLE binding.tvViewAllReviews.visibility = View.GONE // binding.tvNoReviews.visibility = View.VISIBLE } else { binding.recyclerViewReviews.visibility = View.VISIBLE binding.tvViewAllReviews.visibility = View.VISIBLE + binding.emptyReview.visibility = View.GONE } // binding.tvNoReviews.visibility = View.GONE reviewsAdapter = ReviewsAdapter( @@ -519,7 +531,11 @@ class DetailProductActivity : AppCompatActivity() { attachProduct = true // This will auto-attach the product! ) + } + override fun onResume() { + super.onResume() + loadData() } companion object { diff --git a/app/src/main/java/com/alya/ecommerce_serang/ui/product/storeDetail/StoreDetailActivity.kt b/app/src/main/java/com/alya/ecommerce_serang/ui/product/storeDetail/StoreDetailActivity.kt index 9aa1472..ab00e14 100644 --- a/app/src/main/java/com/alya/ecommerce_serang/ui/product/storeDetail/StoreDetailActivity.kt +++ b/app/src/main/java/com/alya/ecommerce_serang/ui/product/storeDetail/StoreDetailActivity.kt @@ -64,10 +64,9 @@ class StoreDetailActivity : AppCompatActivity() { ) windowInsets } - + loadData() setupUI() setupObservers() - loadData() } private fun setupUI() { @@ -88,15 +87,18 @@ class StoreDetailActivity : AppCompatActivity() { viewModel.storeDetail.observe(this) { result -> when (result) { is Result.Success -> { + binding.progressBarDetailProdItem.visibility = View.GONE updateStoreInfo(result.data) viewModel.loadOtherProducts(result.data.storeId) } is Result.Error -> { // Show error message, maybe a Toast or Snackbar + binding.progressBarDetailProdItem.visibility = View.GONE Toast.makeText(this, "Failed to load store: ${result.exception.message}", Toast.LENGTH_SHORT).show() } is Result.Loading -> { // Show loading indicator if needed + binding.progressBarDetailProdItem.visibility = View.VISIBLE } } } @@ -109,6 +111,9 @@ class StoreDetailActivity : AppCompatActivity() { val products = viewModel.otherProducts.value.orEmpty() if (products.isNotEmpty()) { updateProducts(products, storeMap) + } else { + binding.progressBarDetailProdItem.visibility = View.VISIBLE + binding.rvProducts.visibility = View.GONE } } } @@ -146,7 +151,7 @@ class StoreDetailActivity : AppCompatActivity() { .into(binding.ivStoreImage) val ratingStr = it.storeRating - val ratingValue = ratingStr?.toFloatOrNull() + val ratingValue = ratingStr.toFloatOrNull() if (ratingValue != null && ratingValue > 0f) { binding.tvStoreRating.text = String.format("%.1f", ratingValue) @@ -161,10 +166,12 @@ class StoreDetailActivity : AppCompatActivity() { private fun updateProducts(products: List, storeMap: Map) { if (products.isEmpty()) { binding.rvProducts.visibility = View.GONE + binding.progressBarDetailProdItem.visibility = View.VISIBLE Log.d("StoreDetailActivity", "Product list is empty, hiding RecyclerView") } else { Log.d("StoreDetailActivity", "Displaying product list in RecyclerView") + binding.progressBarDetailProdItem.visibility = View.GONE binding.rvProducts.visibility = View.VISIBLE productAdapter = HorizontalProductAdapter(products, onClick = { product -> handleProductClick(product) diff --git a/app/src/main/java/com/alya/ecommerce_serang/ui/profile/DetailProfileActivity.kt b/app/src/main/java/com/alya/ecommerce_serang/ui/profile/DetailProfileActivity.kt index 42069e5..6fb2b5a 100644 --- a/app/src/main/java/com/alya/ecommerce_serang/ui/profile/DetailProfileActivity.kt +++ b/app/src/main/java/com/alya/ecommerce_serang/ui/profile/DetailProfileActivity.kt @@ -90,6 +90,8 @@ class DetailProfileActivity : AppCompatActivity() { Log.e("DetailProfileActivity", "Error from ViewModel: $error") Toast.makeText(this, error, Toast.LENGTH_SHORT).show() } + + } private fun setupClickListeners() { 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 0e2431d..612ab4f 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 @@ -95,12 +95,14 @@ class ProfileFragment : Fragment() { binding.cardLogout.visibility = View.GONE } + + viewModel.loadUserProfile() + viewModel.checkStoreUser() + observeUserProfile() observeStoreStatus() - viewModel.loadUserProfile() - viewModel.checkStoreUser() binding.cardBukaToko.setOnClickListener{ // if (hasStore == true) startActivity(Intent(requireContext(), MyStoreActivity::class.java)) @@ -232,4 +234,11 @@ class ProfileFragment : Fragment() { } } + override fun onResume() { + super.onResume() + viewModel.loadUserProfile() + viewModel.checkStoreUser() + } + + } \ No newline at end of file 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 1b17534..2b1284f 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,6 +2,7 @@ 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 @@ -24,7 +25,6 @@ import com.alya.ecommerce_serang.BuildConfig.BASE_URL import com.alya.ecommerce_serang.R import com.alya.ecommerce_serang.data.api.dto.UserProfile import com.alya.ecommerce_serang.data.api.retrofit.ApiConfig -import com.alya.ecommerce_serang.data.api.retrofit.ApiService import com.alya.ecommerce_serang.data.repository.Result import com.alya.ecommerce_serang.data.repository.UserRepository import com.alya.ecommerce_serang.databinding.ActivityEditProfileCustBinding @@ -33,7 +33,6 @@ import com.alya.ecommerce_serang.utils.SessionManager import com.alya.ecommerce_serang.utils.viewmodel.ProfileViewModel import com.bumptech.glide.Glide import com.google.gson.Gson -import java.io.File import java.text.SimpleDateFormat import java.util.Calendar import java.util.Locale @@ -41,9 +40,9 @@ import java.util.TimeZone class EditProfileCustActivity : AppCompatActivity() { private lateinit var binding: ActivityEditProfileCustBinding - private lateinit var apiService: ApiService private lateinit var sessionManager: SessionManager private var selectedImageUri: Uri? = null + private var currentUser: UserProfile? = null private val viewModel: ProfileViewModel by viewModels { BaseViewModelFactory { @@ -54,7 +53,7 @@ class EditProfileCustActivity : AppCompatActivity() { } private val getContent = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result -> - if (result.resultCode == Activity.RESULT_OK) { + if (result.resultCode == RESULT_OK) { val data: Intent? = result.data data?.data?.let { selectedImageUri = it @@ -105,8 +104,8 @@ class EditProfileCustActivity : AppCompatActivity() { } userProfile?.let { + currentUser = it populateFields(it) - setupClickListeners() observeViewModel() } @@ -118,7 +117,7 @@ class EditProfileCustActivity : AppCompatActivity() { binding.etNumberPhoneUser.setText(profile.phone) // Format birth date for display - profile.birthDate?.let { + profile.birthDate.let { binding.etDateBirth.setText(formatDate(it)) } @@ -156,7 +155,7 @@ class EditProfileCustActivity : AppCompatActivity() { } binding.btnSave.setOnClickListener { - saveProfile() + if (hasChanged()) confirmUpdate() else finish() } } @@ -213,25 +212,38 @@ class EditProfileCustActivity : AppCompatActivity() { datePickerDialog.show() } + 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() + } + + private fun hasChanged(): Boolean { + val name = binding.etNameUser.text.toString() != currentUser?.name + val username = binding.etUsername.text.toString() != currentUser?.username + val email = binding.etEmailUser.text.toString() != currentUser?.email + val phone = binding.etNumberPhoneUser.text.toString() != currentUser?.phone + val displayDate = binding.etDateBirth.text.toString() != currentUser?.birthDate.toString() + val imgProfile = selectedImageUri != null + return name || username || email || phone || displayDate || imgProfile + } + private fun saveProfile() { val name = binding.etNameUser.text.toString() val username = binding.etUsername.text.toString() val email = binding.etEmailUser.text.toString() val phone = binding.etNumberPhoneUser.text.toString() val displayDate = binding.etDateBirth.text.toString() + val imgProfile = selectedImageUri - if (name.isEmpty() || username.isEmpty() || email.isEmpty() || phone.isEmpty() || displayDate.isEmpty()) { - Toast.makeText(this, "Semua field harus diisi", Toast.LENGTH_SHORT).show() - return - } - - // Convert date to server format val serverBirthDate = convertToServerDateFormat(displayDate) Log.d(TAG, "Starting profile save with direct method") Log.d(TAG, "Selected image URI: $selectedImageUri") - // Disable the button to prevent multiple clicks binding.btnSave.isEnabled = false // Call the repository method via ViewModel @@ -242,82 +254,10 @@ class EditProfileCustActivity : AppCompatActivity() { phone = phone, birthDate = serverBirthDate, email = email, - imageUri = selectedImageUri + imageUri = imgProfile ) } - private fun getRealPathFromURI(uri: Uri): String? { - Log.d(TAG, "Getting real path from URI: $uri") - - // Handle different URI schemes - when { - // File URI - uri.scheme == "file" -> { - val path = uri.path - Log.d(TAG, "URI is file scheme, path: $path") - return path - } - - // Content URI - uri.scheme == "content" -> { - try { - val projection = arrayOf(MediaStore.Images.Media.DATA) - contentResolver.query(uri, projection, null, null, null)?.use { cursor -> - if (cursor.moveToFirst()) { - val columnIndex = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA) - val path = cursor.getString(columnIndex) - Log.d(TAG, "Found path from content URI: $path") - return path - } else { - Log.e(TAG, "Cursor is empty") - } - } ?: Log.e(TAG, "Cursor is null") - - // If the above fails, try the documented API way - contentResolver.openInputStream(uri)?.use { inputStream -> - // Create a temp file - val fileName = getFileName(uri) ?: "temp_img_${System.currentTimeMillis()}.jpg" - val tempFile = File(cacheDir, fileName) - tempFile.outputStream().use { outputStream -> - inputStream.copyTo(outputStream) - } - Log.d(TAG, "Created temporary file: ${tempFile.absolutePath}") - return tempFile.absolutePath - } - } catch (e: Exception) { - Log.e(TAG, "Error getting real path: ${e.message}", e) - } - } - } - - Log.e(TAG, "Could not get real path for URI: $uri") - return null - } - - private fun getFileName(uri: Uri): String? { - var result: String? = null - if (uri.scheme == "content") { - contentResolver.query(uri, null, null, null, null)?.use { cursor -> - if (cursor.moveToFirst()) { - val columnIndex = cursor.getColumnIndex(MediaStore.Images.Media.DISPLAY_NAME) - if (columnIndex >= 0) { - result = cursor.getString(columnIndex) - Log.d(TAG, "Found filename from content URI: $result") - } - } - } - } - if (result == null) { - result = uri.path - val cut = result?.lastIndexOf('/') ?: -1 - if (cut != -1) { - result = result?.substring(cut + 1) - } - Log.d(TAG, "Extracted filename from path: $result") - } - return result - } - private fun formatDate(dateString: String?): String { if (dateString.isNullOrEmpty()) return "N/A" diff --git a/app/src/main/java/com/alya/ecommerce_serang/ui/profile/mystore/MyStoreActivity.kt b/app/src/main/java/com/alya/ecommerce_serang/ui/profile/mystore/MyStoreActivity.kt index 4141b0b..7df2ca9 100644 --- a/app/src/main/java/com/alya/ecommerce_serang/ui/profile/mystore/MyStoreActivity.kt +++ b/app/src/main/java/com/alya/ecommerce_serang/ui/profile/mystore/MyStoreActivity.kt @@ -59,20 +59,20 @@ class MyStoreActivity : AppCompatActivity() { finish() } - viewModel.loadMyStore() - viewModel.loadMyStoreProducts() - viewModel.myStoreProfile.observe(this){ user -> user?.let { myStoreProfileOverview(it.store) } } + viewModel.loadMyStore() + viewModel.loadMyStoreProducts() + viewModel.fetchBalance() + viewModel.errorMessage.observe(this) { error -> Toast.makeText(this, error, Toast.LENGTH_SHORT).show() } setUpClickListeners() getCountOrder() observeViewModel() - viewModel.fetchBalance() fetchBalance() } @@ -206,6 +206,13 @@ class MyStoreActivity : AppCompatActivity() { } } + override fun onResume() { + super.onResume() + viewModel.loadMyStore() + viewModel.loadMyStoreProducts() + viewModel.fetchBalance() + } + companion object { private const val PROFILE_REQUEST_CODE = 100 } diff --git a/app/src/main/java/com/alya/ecommerce_serang/ui/profile/mystore/sells/SellsAdapter.kt b/app/src/main/java/com/alya/ecommerce_serang/ui/profile/mystore/sells/SellsAdapter.kt index 8765e20..c303f94 100644 --- a/app/src/main/java/com/alya/ecommerce_serang/ui/profile/mystore/sells/SellsAdapter.kt +++ b/app/src/main/java/com/alya/ecommerce_serang/ui/profile/mystore/sells/SellsAdapter.kt @@ -97,7 +97,7 @@ class SellsAdapter( val product = order.orderItems?.firstOrNull() tvSellsProductName.text = product?.productName tvSellsProductQty.text = "x${product?.quantity}" - tvSellsProductPrice.text = product?.price?.let { formatPrice(it.toInt()) } + tvSellsProductPrice.text = product?.price?.let { formatPrice(it.toDouble().toInt()) } val fullImageUrl = when (val img = product?.productImage) { is String -> { @@ -170,7 +170,7 @@ class SellsAdapter( val product = order.orderItems?.firstOrNull() tvSellsProductName.text = product?.productName tvSellsProductQty.text = "x${product?.quantity}" - tvSellsProductPrice.text = product?.price?.let { formatPrice(it.toInt()) } + tvSellsProductPrice.text = product?.price?.let { formatPrice(it.toDouble().toInt()) } val fullImageUrl = when (val img = product?.productImage) { is String -> { @@ -186,7 +186,7 @@ class SellsAdapter( .into(ivSellsProduct) tvSellsQty.text = "${order.orderItems?.size} produk" - tvSellsPrice.text = order.totalAmount?.let { formatPrice(it.toInt()) } + tvSellsPrice.text = order.totalAmount?.let { formatPrice(it.toDouble().toInt()) } } "paid" -> { layoutOrders.visibility = View.GONE 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 48680cd..bfc63cd 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 @@ -83,10 +83,10 @@ class SellsListFragment : Fragment() { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) + loadSells() setupRecyclerView() observeSellsList() observePaymentConfirmation() - loadSells() // getAllOrderCountsAndNavigate() } @@ -211,6 +211,12 @@ class SellsListFragment : Fragment() { } } + override fun onResume() { + super.onResume() + viewModel.getSellList(status) + observeSellsList() + } + override fun onDestroyView() { super.onDestroyView() _binding = null diff --git a/app/src/main/res/drawable/baseline_account_circle_100.xml b/app/src/main/res/drawable/baseline_account_circle_100.xml new file mode 100644 index 0000000..015a0e2 --- /dev/null +++ b/app/src/main/res/drawable/baseline_account_circle_100.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/app/src/main/res/drawable/baseline_circle_24.xml b/app/src/main/res/drawable/baseline_circle_24.xml new file mode 100644 index 0000000..7030f2f --- /dev/null +++ b/app/src/main/res/drawable/baseline_circle_24.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/app/src/main/res/drawable/baseline_local_grocery_store_24.xml b/app/src/main/res/drawable/baseline_local_grocery_store_24.xml new file mode 100644 index 0000000..5476e7e --- /dev/null +++ b/app/src/main/res/drawable/baseline_local_grocery_store_24.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/app/src/main/res/drawable/baseline_payment_24.xml b/app/src/main/res/drawable/baseline_payment_24.xml new file mode 100644 index 0000000..bf9bfd1 --- /dev/null +++ b/app/src/main/res/drawable/baseline_payment_24.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/app/src/main/res/drawable/bg_button_active.xml b/app/src/main/res/drawable/bg_button_active.xml index ef9d73a..8332ec4 100644 --- a/app/src/main/res/drawable/bg_button_active.xml +++ b/app/src/main/res/drawable/bg_button_active.xml @@ -3,6 +3,6 @@ android:shape="rectangle"> - + diff --git a/app/src/main/res/layout/activity_add_evidence_payment.xml b/app/src/main/res/layout/activity_add_evidence_payment.xml index 216d05e..d4ee31b 100644 --- a/app/src/main/res/layout/activity_add_evidence_payment.xml +++ b/app/src/main/res/layout/activity_add_evidence_payment.xml @@ -113,6 +113,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="16dp" + android:visibility="gone" android:text="Metode Pembayaran *" android:fontFamily="@font/dmsans_semibold" android:textSize="16sp" /> @@ -122,6 +123,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="8dp" + android:visibility="gone" android:background="@drawable/edit_text_background" android:minHeight="50dp" android:padding="12dp" /> diff --git a/app/src/main/res/layout/activity_checkout.xml b/app/src/main/res/layout/activity_checkout.xml index 10944b5..43e7a44 100644 --- a/app/src/main/res/layout/activity_checkout.xml +++ b/app/src/main/res/layout/activity_checkout.xml @@ -34,69 +34,50 @@ android:orientation="vertical"> - + android:layout_marginHorizontal="16dp" + android:layout_marginTop="16dp" + app:cardCornerRadius="12dp" + app:cardElevation="2dp" + app:cardBackgroundColor="@color/white" + app:strokeColor="#E0E0E0" + app:strokeWidth="1dp"> - + android:padding="20dp"> + + android:orientation="horizontal" + android:gravity="center_vertical" + app:layout_constraintTop_toTopOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintEnd_toEndOf="parent"> + app:tint="@color/blue_300" /> - - - - - - - + android:text="Alamat Pengiriman" + android:textSize="16sp" + android:textColor="@android:color/black" + android:fontFamily="@font/dmsans_medium" + android:layout_marginStart="12dp" /> + android:textSize="14sp" + android:fontFamily="@font/dmsans_medium" + android:background="?attr/selectableItemBackgroundBorderless" + android:paddingHorizontal="8dp" + android:paddingVertical="4dp" /> - - - + + + + + + + + + + + + + + + + + + + + + - + android:layout_marginHorizontal="16dp" + android:layout_marginTop="8dp" + app:cardBackgroundColor="@color/white" + app:strokeColor="#E0E0E0" + app:strokeWidth="1dp"> - + android:padding="20dp"> - - - - - - - - - - - - - - + - - - - - - - + android:gravity="center_vertical" + app:layout_constraintTop_toTopOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintEnd_toEndOf="parent"> - + - + android:text="Produk Pesanan" + android:textSize="16sp" + android:textColor="@android:color/black" + android:fontFamily="@font/dmsans_medium" + android:layout_marginStart="12dp" /> + - + + - - + android:textColor="#757575" + android:textSize="14sp" + android:gravity="center" /> + + - - - + + - - + + + + + android:layout_marginHorizontal="16dp" + android:layout_marginTop="8dp" + app:cardBackgroundColor="@color/white" + app:strokeColor="#E0E0E0" + app:strokeWidth="1dp"> - + android:padding="20dp"> - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + android:padding="20dp"> - - + + + + + + + + + + + + + + + + + + + + + + + @@ -303,7 +547,7 @@ android:id="@+id/tv_item_total" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:text="Rp65.000" + android:text="Rp0" android:textSize="14sp" /> @@ -324,7 +568,7 @@ android:id="@+id/tv_shipping_fee" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:text="Rp15.000" + android:text="Rp0" android:textSize="14sp" /> @@ -351,8 +595,8 @@ android:id="@+id/tv_total" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:text="Rp75.000" - android:textColor="#3D84FF" + android:text="Rp0" + android:textColor="@color/blue_400" android:textSize="16sp" android:fontFamily="@font/dmsans_bold" /> @@ -388,7 +632,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Rp75.000" - android:textColor="#3D84FF" + android:textColor="@color/blue_400" android:textSize="18sp" android:fontFamily="@font/dmsans_bold" /> @@ -401,7 +645,7 @@ android:textAllCaps="false" android:paddingHorizontal="32dp" app:cornerRadius="8dp" - android:backgroundTint="#3D84FF" /> + android:backgroundTint="@color/blue_500" /> \ No newline at end of file diff --git a/app/src/main/res/layout/activity_detail_product.xml b/app/src/main/res/layout/activity_detail_product.xml index 187e853..5ee1000 100644 --- a/app/src/main/res/layout/activity_detail_product.xml +++ b/app/src/main/res/layout/activity_detail_product.xml @@ -231,6 +231,18 @@ android:textSize="14sp" /> + + + + + + @@ -87,6 +87,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Ubah Profil" + style="@style/button.large.active.medium" android:layout_marginTop="16dp" app:layout_constraintTop_toBottomOf="@id/profile_image" app:layout_constraintStart_toStartOf="parent" diff --git a/app/src/main/res/layout/activity_edit_profile_cust.xml b/app/src/main/res/layout/activity_edit_profile_cust.xml index ca3cde3..1b7cb50 100644 --- a/app/src/main/res/layout/activity_edit_profile_cust.xml +++ b/app/src/main/res/layout/activity_edit_profile_cust.xml @@ -61,7 +61,7 @@ android:id="@+id/profile_image" android:layout_width="100dp" android:layout_height="100dp" - android:src="@drawable/baseline_account_circle_24" + android:src="@drawable/baseline_account_circle_100" app:layout_constraintTop_toTopOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintEnd_toEndOf="parent"/> @@ -188,6 +188,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Simpan" + style="@style/button.large.active.medium" android:layout_marginTop="32dp" android:layout_marginHorizontal="16dp" android:layout_marginBottom="16dp" diff --git a/app/src/main/res/layout/activity_store_detail.xml b/app/src/main/res/layout/activity_store_detail.xml index 0e71ad2..ad1b6d4 100644 --- a/app/src/main/res/layout/activity_store_detail.xml +++ b/app/src/main/res/layout/activity_store_detail.xml @@ -15,156 +15,207 @@ android:layout_marginTop="16dp" app:layout_constraintTop_toTopOf="parent" /> - - + - - - + android:padding="24dp"> - + + - - - + + + + + + - + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toEndOf="@id/storeImageCard" + app:layout_constraintTop_toBottomOf="@id/tvStoreName" + tools:text="Makanan Ringan" /> - + + - + - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + android:layout_marginTop="24dp" + app:dividerColor="@color/black_200" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@id/storeInfoCard" /> - - - - - - - - - - - - - - - - - - - - - + - \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_home.xml b/app/src/main/res/layout/fragment_home.xml index 516685d..2c3e32b 100644 --- a/app/src/main/res/layout/fragment_home.xml +++ b/app/src/main/res/layout/fragment_home.xml @@ -168,8 +168,13 @@ app:layout_constraintTop_toBottomOf="@id/searchContainer" /> + android:id="@+id/loadingAll" + layout="@layout/view_loading" + android:visibility="gone" + app:layout_constraintTop_toTopOf="parent" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintEnd_toEndOf="parent"/> diff --git a/app/src/main/res/layout/item_shipping_order.xml b/app/src/main/res/layout/item_shipping_order.xml index cb0ae51..7fc90a4 100644 --- a/app/src/main/res/layout/item_shipping_order.xml +++ b/app/src/main/res/layout/item_shipping_order.xml @@ -9,10 +9,9 @@ android:id="@+id/content" android:layout_width="match_parent" android:layout_height="match_parent" - android:gravity="start" + android:gravity="center" android:layout_marginStart="16dp" android:layout_marginVertical="8dp" - android:layout_marginBottom="4dp" android:layout_gravity="center_horizontal" android:orientation="horizontal"> - - - - - - + android:layout_height="wrap_content" + android:orientation="horizontal" + android:gravity="center_vertical" + android:weightSum="1"> + + + + + + + + + + diff --git a/app/src/main/res/layout/view_error.xml b/app/src/main/res/layout/view_error.xml index 971a5e9..7023bee 100644 --- a/app/src/main/res/layout/view_error.xml +++ b/app/src/main/res/layout/view_error.xml @@ -22,7 +22,8 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="16dp" - android:text="Retry" + android:text="Muat Ulang" + style="@style/Widget.Material3.FloatingActionButton.Large.Surface" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" diff --git a/app/src/main/res/layout/view_loading.xml b/app/src/main/res/layout/view_loading.xml index 1e763bf..25c63f7 100644 --- a/app/src/main/res/layout/view_loading.xml +++ b/app/src/main/res/layout/view_loading.xml @@ -6,12 +6,13 @@ + app:layout_constraintTop_toTopOf="parent" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toEndOf="parent"/> \ No newline at end of file diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml index adeeaac..c0a2cc1 100644 --- a/app/src/main/res/values/themes.xml +++ b/app/src/main/res/values/themes.xml @@ -269,7 +269,7 @@