mirror of
https://github.com/shaulascr/ecommerce_serang.git
synced 2025-08-13 10:42:21 +00:00
show list address
This commit is contained in:
@ -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.order.ListProvinceResponse
|
||||||
import com.alya.ecommerce_serang.data.api.response.product.ProductResponse
|
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.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.response.profile.CreateAddressResponse
|
||||||
import com.alya.ecommerce_serang.data.api.retrofit.ApiService
|
import com.alya.ecommerce_serang.data.api.retrofit.ApiService
|
||||||
import retrofit2.Response
|
import retrofit2.Response
|
||||||
@ -37,6 +38,11 @@ class OrderRepository(private val apiService: ApiService) {
|
|||||||
return if (response.isSuccessful) response.body() else null
|
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
|
//post data with message/response
|
||||||
suspend fun addAddress(createAddressRequest: CreateAddressRequest): Result<CreateAddressResponse> {
|
suspend fun addAddress(createAddressRequest: CreateAddressRequest): Result<CreateAddressResponse> {
|
||||||
return try {
|
return try {
|
||||||
|
@ -10,7 +10,6 @@ import android.widget.Toast
|
|||||||
import androidx.activity.result.contract.ActivityResultContracts
|
import androidx.activity.result.contract.ActivityResultContracts
|
||||||
import androidx.activity.viewModels
|
import androidx.activity.viewModels
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.constraintlayout.motion.widget.Debug.getLocation
|
|
||||||
import androidx.lifecycle.Lifecycle
|
import androidx.lifecycle.Lifecycle
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
import androidx.lifecycle.repeatOnLifecycle
|
import androidx.lifecycle.repeatOnLifecycle
|
||||||
@ -64,16 +63,18 @@ class AddAddressActivity : AppCompatActivity() {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun viewModelAddAddress(request: CreateAddressRequest) {
|
// private fun viewModelAddAddress(request: CreateAddressRequest) {
|
||||||
// Call the private fun in your ViewModel using reflection or expose it in ViewModel
|
// // Call the private fun in your ViewModel using reflection or expose it in ViewModel
|
||||||
val method = AddAddressViewModel::class.java.getDeclaredMethod("addAddress", CreateAddressRequest::class.java)
|
// val method = AddAddressViewModel::class.java.getDeclaredMethod("addAddress", CreateAddressRequest::class.java)
|
||||||
method.isAccessible = true
|
// method.isAccessible = true
|
||||||
method.invoke(viewModel, request)
|
// method.invoke(viewModel, request)
|
||||||
}
|
// }
|
||||||
// UI setup methods
|
// UI setup methods
|
||||||
private fun setupToolbar() {
|
private fun setupToolbar() {
|
||||||
binding.toolbar.setNavigationOnClickListener { finish() }
|
binding.toolbar.setNavigationOnClickListener {
|
||||||
|
onBackPressedDispatcher.onBackPressed()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun setupAutoComplete() {
|
private fun setupAutoComplete() {
|
||||||
// Set adapters
|
// 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) {
|
private fun showSubmitLoading(isLoading: Boolean) {
|
||||||
binding.buttonSimpan.isEnabled = !isLoading
|
binding.buttonSimpan.isEnabled = !isLoading
|
||||||
binding.buttonSimpan.text = if (isLoading) "Menyimpan..." else "Simpan"
|
binding.buttonSimpan.text = if (isLoading) "Menyimpan..." else "Simpan"
|
||||||
@ -187,7 +177,7 @@ class AddAddressActivity : AppCompatActivity() {
|
|||||||
|
|
||||||
private fun showSuccessAndFinish(message: String) {
|
private fun showSuccessAndFinish(message: String) {
|
||||||
Toast.makeText(this, "Sukses: $message", Toast.LENGTH_SHORT).show()
|
Toast.makeText(this, "Sukses: $message", Toast.LENGTH_SHORT).show()
|
||||||
finish()
|
onBackPressed()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun validateAndSubmitForm() {
|
private fun validateAndSubmitForm() {
|
||||||
@ -245,7 +235,7 @@ class AddAddressActivity : AppCompatActivity() {
|
|||||||
|
|
||||||
private val locationPermissionLauncher =
|
private val locationPermissionLauncher =
|
||||||
registerForActivityResult(ActivityResultContracts.RequestPermission()) { granted ->
|
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() {
|
private fun requestLocationPermission() {
|
||||||
|
@ -1,21 +1,67 @@
|
|||||||
package com.alya.ecommerce_serang.ui.order
|
package com.alya.ecommerce_serang.ui.order
|
||||||
|
|
||||||
|
import android.content.Intent
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import androidx.activity.enableEdgeToEdge
|
import androidx.activity.viewModels
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.core.view.ViewCompat
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
import androidx.core.view.WindowInsetsCompat
|
import com.alya.ecommerce_serang.data.api.retrofit.ApiConfig
|
||||||
import com.alya.ecommerce_serang.R
|
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() {
|
class AddressActivity : AppCompatActivity() {
|
||||||
|
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?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
enableEdgeToEdge()
|
binding = ActivityAddressBinding.inflate(layoutInflater)
|
||||||
setContentView(R.layout.activity_address)
|
setContentView(binding.root)
|
||||||
ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main)) { v, insets ->
|
|
||||||
val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
|
sessionManager = SessionManager(this)
|
||||||
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom)
|
apiService = ApiConfig.getApiService(sessionManager)
|
||||||
insets
|
|
||||||
|
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()
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -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
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user