show list address

This commit is contained in:
shaulascr
2025-04-09 16:35:42 +07:00
parent 0c128337ae
commit 0f5df1f57f
5 changed files with 174 additions and 34 deletions

View File

@ -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<CreateAddressResponse> {
return try {

View File

@ -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() {

View File

@ -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()
}
}

View File

@ -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<AddressesItem, AddressAdapter.AddressViewHolder>(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<AddressesItem>() {
override fun areItemsTheSame(oldItem: AddressesItem, newItem: AddressesItem) =
oldItem.id == newItem.id
override fun areContentsTheSame(oldItem: AddressesItem, newItem: AddressesItem) =
oldItem == newItem
}
}
}

View File

@ -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<List<AddressesItem>>()
val addresses: LiveData<List<AddressesItem>> get() = _addresses
private val _selectedAddressId = MutableLiveData<Int?>()
val selectedAddressId: LiveData<Int?> get() = _selectedAddressId
fun fetchAddresses() {
viewModelScope.launch {
val response = repository.getAddress()
response?.let {
_addresses.value = it.addresses
}
}
}
fun selectAddress(id: Int) {
_selectedAddressId.value = id
}
}