From 0f5df1f57f87c8609bf938c38cff30baa08c71c1 Mon Sep 17 00:00:00 2001 From: shaulascr Date: Wed, 9 Apr 2025 16:35:42 +0700 Subject: [PATCH] show list address --- .../data/repository/OrderRepository.kt | 6 ++ .../ui/order/AddAddressActivity.kt | 34 ++++----- .../ui/order/AddressActivity.kt | 70 +++++++++++++++---- .../ui/order/AddressAdapter.kt | 67 ++++++++++++++++++ .../ui/order/AddressViewModel.kt | 31 ++++++++ 5 files changed, 174 insertions(+), 34 deletions(-) create mode 100644 app/src/main/java/com/alya/ecommerce_serang/ui/order/AddressAdapter.kt create mode 100644 app/src/main/java/com/alya/ecommerce_serang/ui/order/AddressViewModel.kt diff --git a/app/src/main/java/com/alya/ecommerce_serang/data/repository/OrderRepository.kt b/app/src/main/java/com/alya/ecommerce_serang/data/repository/OrderRepository.kt index c924899..1932d38 100644 --- a/app/src/main/java/com/alya/ecommerce_serang/data/repository/OrderRepository.kt +++ b/app/src/main/java/com/alya/ecommerce_serang/data/repository/OrderRepository.kt @@ -8,6 +8,7 @@ import com.alya.ecommerce_serang.data.api.response.order.ListCityResponse import com.alya.ecommerce_serang.data.api.response.order.ListProvinceResponse import com.alya.ecommerce_serang.data.api.response.product.ProductResponse import com.alya.ecommerce_serang.data.api.response.product.StoreResponse +import com.alya.ecommerce_serang.data.api.response.profile.AddressResponse import com.alya.ecommerce_serang.data.api.response.profile.CreateAddressResponse import com.alya.ecommerce_serang.data.api.retrofit.ApiService import retrofit2.Response @@ -37,6 +38,11 @@ class OrderRepository(private val apiService: ApiService) { return if (response.isSuccessful) response.body() else null } + suspend fun getAddress(): AddressResponse?{ + val response = apiService.getAddress() + return if (response.isSuccessful) response.body() else null + } + //post data with message/response suspend fun addAddress(createAddressRequest: CreateAddressRequest): Result { return try { diff --git a/app/src/main/java/com/alya/ecommerce_serang/ui/order/AddAddressActivity.kt b/app/src/main/java/com/alya/ecommerce_serang/ui/order/AddAddressActivity.kt index 86b16d5..69e72db 100644 --- a/app/src/main/java/com/alya/ecommerce_serang/ui/order/AddAddressActivity.kt +++ b/app/src/main/java/com/alya/ecommerce_serang/ui/order/AddAddressActivity.kt @@ -10,7 +10,6 @@ import android.widget.Toast import androidx.activity.result.contract.ActivityResultContracts import androidx.activity.viewModels import androidx.appcompat.app.AppCompatActivity -import androidx.constraintlayout.motion.widget.Debug.getLocation import androidx.lifecycle.Lifecycle import androidx.lifecycle.lifecycleScope import androidx.lifecycle.repeatOnLifecycle @@ -64,16 +63,18 @@ class AddAddressActivity : AppCompatActivity() { } - private fun viewModelAddAddress(request: CreateAddressRequest) { - // Call the private fun in your ViewModel using reflection or expose it in ViewModel - val method = AddAddressViewModel::class.java.getDeclaredMethod("addAddress", CreateAddressRequest::class.java) - method.isAccessible = true - method.invoke(viewModel, request) - } +// private fun viewModelAddAddress(request: CreateAddressRequest) { +// // Call the private fun in your ViewModel using reflection or expose it in ViewModel +// val method = AddAddressViewModel::class.java.getDeclaredMethod("addAddress", CreateAddressRequest::class.java) +// method.isAccessible = true +// method.invoke(viewModel, request) +// } // UI setup methods - private fun setupToolbar() { - binding.toolbar.setNavigationOnClickListener { finish() } +private fun setupToolbar() { + binding.toolbar.setNavigationOnClickListener { + onBackPressedDispatcher.onBackPressed() } +} private fun setupAutoComplete() { // Set adapters @@ -164,17 +165,6 @@ class AddAddressActivity : AppCompatActivity() { } } } - -// private fun showProvinceLoading(isLoading: Boolean) { -// // Implement province loading indicator -// binding.provinceProgressBar?.visibility = if (isLoading) View.VISIBLE else View.GONE -// } -// -// private fun showCityLoading(isLoading: Boolean) { -// // Implement city loading indicator -// binding.cityProgressBar?.visibility = if (isLoading) View.VISIBLE else View.GONE -// } -// private fun showSubmitLoading(isLoading: Boolean) { binding.buttonSimpan.isEnabled = !isLoading binding.buttonSimpan.text = if (isLoading) "Menyimpan..." else "Simpan" @@ -187,7 +177,7 @@ class AddAddressActivity : AppCompatActivity() { private fun showSuccessAndFinish(message: String) { Toast.makeText(this, "Sukses: $message", Toast.LENGTH_SHORT).show() - finish() + onBackPressed() } private fun validateAndSubmitForm() { @@ -245,7 +235,7 @@ class AddAddressActivity : AppCompatActivity() { private val locationPermissionLauncher = registerForActivityResult(ActivityResultContracts.RequestPermission()) { granted -> - if (granted) getLocation() else Toast.makeText(this, "Izin lokasi ditolak",Toast.LENGTH_SHORT).show() + if (granted) requestLocation() else Toast.makeText(this, "Izin lokasi ditolak",Toast.LENGTH_SHORT).show() } private fun requestLocationPermission() { diff --git a/app/src/main/java/com/alya/ecommerce_serang/ui/order/AddressActivity.kt b/app/src/main/java/com/alya/ecommerce_serang/ui/order/AddressActivity.kt index 4475a96..bbc5e0c 100644 --- a/app/src/main/java/com/alya/ecommerce_serang/ui/order/AddressActivity.kt +++ b/app/src/main/java/com/alya/ecommerce_serang/ui/order/AddressActivity.kt @@ -1,21 +1,67 @@ package com.alya.ecommerce_serang.ui.order +import android.content.Intent import android.os.Bundle -import androidx.activity.enableEdgeToEdge +import androidx.activity.viewModels import androidx.appcompat.app.AppCompatActivity -import androidx.core.view.ViewCompat -import androidx.core.view.WindowInsetsCompat -import com.alya.ecommerce_serang.R +import androidx.recyclerview.widget.LinearLayoutManager +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.OrderRepository +import com.alya.ecommerce_serang.databinding.ActivityAddressBinding +import com.alya.ecommerce_serang.utils.BaseViewModelFactory +import com.alya.ecommerce_serang.utils.SessionManager class AddressActivity : AppCompatActivity() { - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - enableEdgeToEdge() - setContentView(R.layout.activity_address) - ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main)) { v, insets -> - val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars()) - v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom) - insets + private lateinit var binding: ActivityAddressBinding + private lateinit var apiService: ApiService + private lateinit var sessionManager: SessionManager + private lateinit var adapter: AddressAdapter + + private val viewModel: AddressViewModel by viewModels { + BaseViewModelFactory { + val apiService = ApiConfig.getApiService(sessionManager) + val orderRepository = OrderRepository(apiService) + AddressViewModel(orderRepository) } } + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + binding = ActivityAddressBinding.inflate(layoutInflater) + setContentView(binding.root) + + sessionManager = SessionManager(this) + apiService = ApiConfig.getApiService(sessionManager) + + adapter = AddressAdapter { selectedId -> + viewModel.selectAddress(selectedId) + } + + binding.toolbar.setNavigationOnClickListener { + onBackPressedWithResult() + } + + binding.rvSellerOrder.layoutManager = LinearLayoutManager(this) + binding.rvSellerOrder.adapter = adapter + + viewModel.fetchAddresses() + + viewModel.addresses.observe(this) { addressList -> + adapter.submitList(addressList) + } + + viewModel.selectedAddressId.observe(this) { selectedId -> + adapter.setSelectedAddressId(selectedId) + } + } + + private fun onBackPressedWithResult() { + viewModel.selectedAddressId.value?.let { + val intent = Intent() + intent.putExtra("selected_address_id", it) + setResult(RESULT_OK, intent) + } + finish() + } } \ No newline at end of file diff --git a/app/src/main/java/com/alya/ecommerce_serang/ui/order/AddressAdapter.kt b/app/src/main/java/com/alya/ecommerce_serang/ui/order/AddressAdapter.kt new file mode 100644 index 0000000..e6a7e82 --- /dev/null +++ b/app/src/main/java/com/alya/ecommerce_serang/ui/order/AddressAdapter.kt @@ -0,0 +1,67 @@ +package com.alya.ecommerce_serang.ui.order + +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.TextView +import androidx.core.content.ContextCompat +import androidx.recyclerview.widget.DiffUtil +import androidx.recyclerview.widget.ListAdapter +import androidx.recyclerview.widget.RecyclerView +import com.alya.ecommerce_serang.R +import com.alya.ecommerce_serang.data.api.response.profile.AddressesItem +import com.google.android.material.card.MaterialCardView + +class AddressAdapter( + private val onAddressClick: (Int) -> Unit +) : ListAdapter(DIFF_CALLBACK) { + + private var selectedAddressId: Int? = null + + fun setSelectedAddressId(id: Int?) { + selectedAddressId = id + notifyDataSetChanged() + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): AddressViewHolder { + val view = LayoutInflater.from(parent.context) + .inflate(R.layout.item_card_address, parent, false) + return AddressViewHolder(view) + } + + override fun onBindViewHolder(holder: AddressViewHolder, position: Int) { + val address = getItem(position) + holder.bind(address, selectedAddressId == address.id) + holder.itemView.setOnClickListener { + onAddressClick(address.id) + } + } + + class AddressViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { + private val tvName: TextView = itemView.findViewById(R.id.tv_name_address) + private val tvDetail: TextView = itemView.findViewById(R.id.tv_detail_address) + private val card: MaterialCardView = itemView as MaterialCardView + + fun bind(address: AddressesItem, isSelected: Boolean) { + tvName.text = address.recipient + tvDetail.text = "${address.street}, ${address.subdistrict}, ${address.phone}" + + card.setCardBackgroundColor( + ContextCompat.getColor( + itemView.context, + if (isSelected) R.color.blue_50 else R.color.white + ) + ) + } + } + + companion object { + val DIFF_CALLBACK = object : DiffUtil.ItemCallback() { + override fun areItemsTheSame(oldItem: AddressesItem, newItem: AddressesItem) = + oldItem.id == newItem.id + + override fun areContentsTheSame(oldItem: AddressesItem, newItem: AddressesItem) = + oldItem == newItem + } + } +} diff --git a/app/src/main/java/com/alya/ecommerce_serang/ui/order/AddressViewModel.kt b/app/src/main/java/com/alya/ecommerce_serang/ui/order/AddressViewModel.kt new file mode 100644 index 0000000..6bbcb8e --- /dev/null +++ b/app/src/main/java/com/alya/ecommerce_serang/ui/order/AddressViewModel.kt @@ -0,0 +1,31 @@ +package com.alya.ecommerce_serang.ui.order + +import androidx.lifecycle.LiveData +import androidx.lifecycle.MutableLiveData +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import com.alya.ecommerce_serang.data.api.response.profile.AddressesItem +import com.alya.ecommerce_serang.data.repository.OrderRepository +import kotlinx.coroutines.launch + +class AddressViewModel(private val repository: OrderRepository): ViewModel() { + + private val _addresses = MutableLiveData>() + val addresses: LiveData> get() = _addresses + + private val _selectedAddressId = MutableLiveData() + val selectedAddressId: LiveData get() = _selectedAddressId + + fun fetchAddresses() { + viewModelScope.launch { + val response = repository.getAddress() + response?.let { + _addresses.value = it.addresses + } + } + } + + fun selectAddress(id: Int) { + _selectedAddressId.value = id + } +} \ No newline at end of file