fix address store, address user, add

This commit is contained in:
shaulascr
2025-08-14 16:47:11 +07:00
parent 1f41b4681f
commit 8d9815d89f
13 changed files with 376 additions and 56 deletions

View File

@ -0,0 +1,9 @@
package com.alya.ecommerce_serang.data.api.response.auth
import com.google.gson.annotations.SerializedName
data class ResetPassResponse(
@field:SerializedName("message")
val message: String
)

View File

@ -0,0 +1,69 @@
package com.alya.ecommerce_serang.data.api.response.customer.profile
import com.google.gson.annotations.SerializedName
data class AddressDetailResponse(
@field:SerializedName("address")
val address: Address,
@field:SerializedName("message")
val message: String
)
data class AddressDetail(
@field:SerializedName("village_id")
val villageId: String,
@field:SerializedName("is_store_location")
val isStoreLocation: Boolean,
@field:SerializedName("latitude")
val latitude: String,
@field:SerializedName("province_name")
val provinceName: String,
@field:SerializedName("subdistrict_id")
val subdistrictId: String,
@field:SerializedName("city_name")
val cityName: String,
@field:SerializedName("user_id")
val userId: Int,
@field:SerializedName("province_id")
val provinceId: String,
@field:SerializedName("phone")
val phone: String,
@field:SerializedName("street")
val street: String,
@field:SerializedName("subdistrict")
val subdistrict: String,
@field:SerializedName("recipient")
val recipient: String,
@field:SerializedName("id")
val id: Int,
@field:SerializedName("detail")
val detail: String,
@field:SerializedName("village_name")
val villageName: String,
@field:SerializedName("postal_code")
val postalCode: String,
@field:SerializedName("longitude")
val longitude: String,
@field:SerializedName("city_id")
val cityId: String
)

View File

@ -14,7 +14,7 @@ data class AddressResponse(
data class AddressesItem( data class AddressesItem(
@field:SerializedName("village_id") @field:SerializedName("village_id")
val villageId: String, val villageId: String?,
@field:SerializedName("is_store_location") @field:SerializedName("is_store_location")
val isStoreLocation: Boolean, val isStoreLocation: Boolean,
@ -29,7 +29,7 @@ data class AddressesItem(
val provinceId: String, val provinceId: String,
@field:SerializedName("phone") @field:SerializedName("phone")
val phone: String, val phone: String?,
@field:SerializedName("street") @field:SerializedName("street")
val street: String, val street: String,
@ -38,7 +38,7 @@ data class AddressesItem(
val subdistrict: String, val subdistrict: String,
@field:SerializedName("recipient") @field:SerializedName("recipient")
val recipient: String, val recipient: String?,
@field:SerializedName("id") @field:SerializedName("id")
val id: Int, val id: Int,

View File

@ -0,0 +1,57 @@
package com.alya.ecommerce_serang.data.api.response.customer.profile
import com.google.gson.annotations.SerializedName
data class UpdateAddressResponse(
@field:SerializedName("address")
val address: Address,
@field:SerializedName("message")
val message: String
)
data class Address(
@field:SerializedName("village_id")
val villageId: String,
@field:SerializedName("is_store_location")
val isStoreLocation: Boolean,
@field:SerializedName("latitude")
val latitude: String,
@field:SerializedName("user_id")
val userId: Int,
@field:SerializedName("province_id")
val provinceId: String,
@field:SerializedName("phone")
val phone: Any,
@field:SerializedName("street")
val street: String,
@field:SerializedName("subdistrict")
val subdistrict: String,
@field:SerializedName("recipient")
val recipient: Any,
@field:SerializedName("id")
val id: Int,
@field:SerializedName("detail")
val detail: String,
@field:SerializedName("postal_code")
val postalCode: String,
@field:SerializedName("longitude")
val longitude: String,
@field:SerializedName("city_id")
val cityId: String
)

View File

@ -238,7 +238,8 @@ class RegisterStep3Fragment : Fragment() {
binding.autoCompleteKecamatan.setOnItemClickListener{ _, _, position, _ -> binding.autoCompleteKecamatan.setOnItemClickListener{ _, _, position, _ ->
val subdistrictId = subdistrictAdapter.getSubdistrictId(position) val subdistrictId = subdistrictAdapter.getSubdistrictId(position)
Log.d(TAG, "Subdistrict selected at position $position, ID: $subdistrictId") val subdistictName = subdistrictAdapter.getSubdistrictName(position)
Log.d(TAG, "Subdistrict selected at position $position, ID: $subdistrictId, name: $subdistictName")
subdistrictId?.let { id -> subdistrictId?.let { id ->
Log.d(TAG, "Selected subdistrict ID set to: $id") Log.d(TAG, "Selected subdistrict ID set to: $id")
@ -246,6 +247,11 @@ class RegisterStep3Fragment : Fragment() {
registerViewModel.getVillages(id) registerViewModel.getVillages(id)
binding.autoCompleteDesa.text.clear() binding.autoCompleteDesa.text.clear()
} }
subdistictName?.let { name ->
Log.d(TAG, "Selected name subdistrict set to: $name")
registerViewModel.subdistrictName = name
}
} }
binding.autoCompleteDesa.setOnItemClickListener{ _, _, position, _ -> binding.autoCompleteDesa.setOnItemClickListener{ _, _, position, _ ->
@ -375,7 +381,7 @@ class RegisterStep3Fragment : Fragment() {
val provinceId = registerViewModel.selectedProvinceId?.toInt() ?: 0 val provinceId = registerViewModel.selectedProvinceId?.toInt() ?: 0
val cityId = registerViewModel.selectedCityId.toString() val cityId = registerViewModel.selectedCityId.toString()
val subDistrict = registerViewModel.selectedSubdistrict.toString() val subDistrict = registerViewModel.subdistrictName.toString()
// val postalCode = registerViewModel.selectedPostalCode.toString() // val postalCode = registerViewModel.selectedPostalCode.toString()
val villageId = registerViewModel.selectedVillages ?: "" val villageId = registerViewModel.selectedVillages ?: ""
@ -423,7 +429,7 @@ class RegisterStep3Fragment : Fragment() {
val provinceId = registerViewModel.selectedProvinceId val provinceId = registerViewModel.selectedProvinceId
val cityId = registerViewModel.selectedCityId val cityId = registerViewModel.selectedCityId
val subDistrict = registerViewModel.selectedSubdistrict.toString() val subDistrict = registerViewModel.selectedSubdistrict
val postalCode = registerViewModel.selectedPostalCode val postalCode = registerViewModel.selectedPostalCode
Log.d(TAG, "Validating - Street: $street, SubDistrict: $subDistrict, PostalCode: $postalCode") Log.d(TAG, "Validating - Street: $street, SubDistrict: $subDistrict, PostalCode: $postalCode")
@ -462,6 +468,12 @@ class RegisterStep3Fragment : Fragment() {
return false return false
} }
if (subDistrict == null) {
showError("Pilih kota/kabupaten terlebih dahulu")
binding.autoCompleteKecamatan.requestFocus()
return false
}
return true return true
} }

View File

@ -74,6 +74,10 @@ class SubdsitrictAdapter(
fun getSubdistrictId(position: Int): String? { fun getSubdistrictId(position: Int): String? {
return cities.getOrNull(position)?.subdistrictId?.toString() return cities.getOrNull(position)?.subdistrictId?.toString()
} }
fun getSubdistrictName(position: Int): String? {
return cities.getOrNull(position)?.subdistrictName?.toString()
}
} }
class VillagesAdapter( class VillagesAdapter(

View File

@ -485,7 +485,7 @@ class RegisterStoreActivity : AppCompatActivity() {
} }
// Hide progress bar if it was showing // Hide progress bar if it was showing
binding.storeTypeProgressBar.visibility = View.GONE binding.bankNameProgressBar.visibility = View.GONE
} else { } else {
Log.e(TAG, "Invalid bank name for position: $position") Log.e(TAG, "Invalid bank name for position: $position")

View File

@ -13,10 +13,12 @@ import com.alya.ecommerce_serang.BuildConfig
import com.alya.ecommerce_serang.R import com.alya.ecommerce_serang.R
import com.alya.ecommerce_serang.data.api.dto.City import com.alya.ecommerce_serang.data.api.dto.City
import com.alya.ecommerce_serang.data.api.dto.Province import com.alya.ecommerce_serang.data.api.dto.Province
import com.alya.ecommerce_serang.data.api.response.customer.order.SubdistrictsItem
import com.alya.ecommerce_serang.data.api.response.customer.profile.AddressesItem import com.alya.ecommerce_serang.data.api.response.customer.profile.AddressesItem
import com.alya.ecommerce_serang.data.api.retrofit.ApiConfig import com.alya.ecommerce_serang.data.api.retrofit.ApiConfig
import com.alya.ecommerce_serang.data.api.retrofit.ApiService import com.alya.ecommerce_serang.data.api.retrofit.ApiService
import com.alya.ecommerce_serang.data.repository.AddressRepository import com.alya.ecommerce_serang.data.repository.AddressRepository
import com.alya.ecommerce_serang.data.repository.Result
import com.alya.ecommerce_serang.databinding.ActivityDetailStoreAddressBinding import com.alya.ecommerce_serang.databinding.ActivityDetailStoreAddressBinding
import com.alya.ecommerce_serang.utils.BaseViewModelFactory import com.alya.ecommerce_serang.utils.BaseViewModelFactory
import com.alya.ecommerce_serang.utils.SessionManager import com.alya.ecommerce_serang.utils.SessionManager
@ -30,11 +32,15 @@ class DetailStoreAddressActivity : AppCompatActivity() {
private var selectedProvinceId: String? = null private var selectedProvinceId: String? = null
private var selectedCityId: String? = null private var selectedCityId: String? = null
private var selectedSubdistrict: String? = null
private var provinces: List<Province> = emptyList() private var provinces: List<Province> = emptyList()
private var cities: List<City> = emptyList() private var cities: List<City> = emptyList()
private var subdistrict: List<SubdistrictsItem> = emptyList()
private var currentAddress: AddressesItem? = null private var currentAddress: AddressesItem? = null
private val TAG = "StoreAddressActivity" // private lateinit var subdistrictAdapter: SubdsitrictAdapter
private val TAG = "DetailStoreAddressActivity"
private val viewModel: AddressViewModel by viewModels { private val viewModel: AddressViewModel by viewModels {
BaseViewModelFactory { BaseViewModelFactory {
@ -59,13 +65,15 @@ class DetailStoreAddressActivity : AppCompatActivity() {
binding.tvError.visibility = View.GONE binding.tvError.visibility = View.GONE
// Set up header title // Set up header title
binding.header.headerTitle.text = "Atur Alamat Toko" binding.headerAddressStore.headerTitle.text = "Atur Alamat Toko"
// Set up back button // Set up back button
binding.header.headerLeftIcon.setOnClickListener { binding.headerAddressStore.headerLeftIcon.setOnClickListener {
onBackPressedDispatcher.onBackPressed() onBackPressedDispatcher.onBackPressed()
} }
// subdistrictAdapter = SubdsitrictAdapter(this)
setupSpinners() setupSpinners()
setupObservers() setupObservers()
setupSaveButton() setupSaveButton()
@ -114,11 +122,26 @@ class DetailStoreAddressActivity : AppCompatActivity() {
binding.spinnerCity.onItemSelectedListener = object : AdapterView.OnItemSelectedListener { binding.spinnerCity.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) { override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
selectedCityId = if (position > 0) cities[position - 1].cityId else null selectedCityId = if (position > 0) cities[position - 1].cityId else null
viewModel.getSubdistrict(selectedCityId.toString())
checkAllFieldsFilled() checkAllFieldsFilled()
} }
override fun onNothingSelected(p0: AdapterView<*>?) {} override fun onNothingSelected(p0: AdapterView<*>?) {}
} }
binding.spinnerSubdistrict.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
selectedSubdistrict = if (position > 0) subdistrict[position - 1].subdistrictName else null
checkAllFieldsFilled()
}
override fun onNothingSelected(p0: AdapterView<*>?) {}
}
} }
private fun setupObservers() { private fun setupObservers() {
@ -177,6 +200,43 @@ class DetailStoreAddressActivity : AppCompatActivity() {
} }
} }
viewModel.subdistrictState.observe(this) { result ->
when (result) {
is com.alya.ecommerce_serang.data.repository.Result.Loading -> {
showSubLoading(true)
}
is com.alya.ecommerce_serang.data.repository.Result.Success -> {
showSubLoading(false)
subdistrict = result.data
val subdistrictNames = mutableListOf("Pilih Kecamatan")
subdistrictNames.addAll(result.data.map { it.subdistrictName })
val adapter = ArrayAdapter(
this,
android.R.layout.simple_spinner_item,
subdistrictNames
)
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
binding.spinnerSubdistrict.adapter = adapter
// Compare by name, since stored value is the subdistrict name
viewModel.storeAddress.value?.let { address ->
val index = subdistrict.indexOfFirst { it.subdistrictName == address.subdistrict }
if (index != -1) {
binding.spinnerSubdistrict.setSelection(index + 1)
}
}
}
is Result.Error -> {
showSubLoading(false)
Log.e(TAG, "Error: ${result.exception.message}", result.exception)
}
}
}
// Observe store address data // Observe store address data
viewModel.storeAddress.observe(this) { address -> viewModel.storeAddress.observe(this) { address ->
currentAddress = address currentAddress = address
@ -184,13 +244,14 @@ class DetailStoreAddressActivity : AppCompatActivity() {
address?.let { address?.let {
// Set the fields // Set the fields
binding.edtStreet.setText(it.street) binding.edtStreet.setText(it.street)
binding.edtSubdistrict.setText(it.subdistrict) // binding.edtSubdistrict.setText(it.subdistrict)
binding.edtDetailAddress.setText(it.detail ?: "") binding.edtDetailAddress.setText(it.detail ?: "")
binding.edtPostalCode.setText(it.postalCode) binding.edtPostalCode.setText(it.postalCode)
binding.edtLatitude.setText(it.latitude.toString()) binding.edtLatitude.setText(it.latitude.toString())
binding.edtLongitude.setText(it.longitude.toString()) binding.edtLongitude.setText(it.longitude.toString())
selectedProvinceId = it.provinceId selectedProvinceId = it.provinceId
selectedCityId = it.cityId selectedCityId = it.cityId
selectedSubdistrict = it.subdistrict
// Find province index and select it after provinces are loaded // Find province index and select it after provinces are loaded
if (provinces.isNotEmpty()) { if (provinces.isNotEmpty()) {
@ -229,7 +290,6 @@ class DetailStoreAddressActivity : AppCompatActivity() {
private fun setupSaveButton() { private fun setupSaveButton() {
binding.btnSaveAddress.setOnClickListener { binding.btnSaveAddress.setOnClickListener {
val street = binding.edtStreet.text.toString() val street = binding.edtStreet.text.toString()
val subdistrict = binding.edtSubdistrict.text.toString()
val detail = binding.edtDetailAddress.text.toString() val detail = binding.edtDetailAddress.text.toString()
val postalCode = binding.edtPostalCode.text.toString() val postalCode = binding.edtPostalCode.text.toString()
val latitude = binding.edtLatitude.text.toString() val latitude = binding.edtLatitude.text.toString()
@ -237,6 +297,8 @@ class DetailStoreAddressActivity : AppCompatActivity() {
val city = cities.find { it.cityId == selectedCityId } val city = cities.find { it.cityId == selectedCityId }
val province = provinces.find { it.provinceId == selectedProvinceId } val province = provinces.find { it.provinceId == selectedProvinceId }
val subdistrictName = subdistrict.find { it.subdistrictName == selectedSubdistrict }?.subdistrictName.toString()
Log.d(TAG, "Subdistrict name: $subdistrictName")
// Validate required fields // Validate required fields
if (selectedProvinceId.isNullOrEmpty() || city == null || street.isEmpty() || subdistrict.isEmpty() || postalCode.isEmpty()) { if (selectedProvinceId.isNullOrEmpty() || city == null || street.isEmpty() || subdistrict.isEmpty() || postalCode.isEmpty()) {
@ -249,11 +311,15 @@ class DetailStoreAddressActivity : AppCompatActivity() {
provinceId = selectedProvinceId!!, provinceId = selectedProvinceId!!,
cityId = city.cityId, cityId = city.cityId,
street = street, street = street,
subdistrict = subdistrict, subdistrict = subdistrictName,
detail = detail, detail = detail,
postalCode = postalCode, postalCode = postalCode,
latitude = latitude, latitude = latitude,
longitude = longitude longitude = longitude,
phone = oldAddress.phone,
recipient = oldAddress.recipient ?: "",
isStoreLocation = oldAddress.isStoreLocation,
villageId = oldAddress.villageId
) )
viewModel.saveStoreAddress(oldAddress, newAddress) viewModel.saveStoreAddress(oldAddress, newAddress)
// Save address // Save address
@ -279,15 +345,14 @@ class DetailStoreAddressActivity : AppCompatActivity() {
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {} override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {}
} }
binding.edtStreet.addTextChangedListener(watcher) binding.edtStreet.addTextChangedListener(watcher)
binding.edtSubdistrict.addTextChangedListener(watcher)
binding.edtPostalCode.addTextChangedListener(watcher) binding.edtPostalCode.addTextChangedListener(watcher)
} }
private fun checkAllFieldsFilled() { private fun checkAllFieldsFilled() {
val allValid = !selectedProvinceId.isNullOrEmpty() val allValid = !selectedProvinceId.isNullOrEmpty()
&& !selectedCityId.isNullOrEmpty() && !selectedCityId.isNullOrEmpty()
&& !selectedSubdistrict.isNullOrEmpty()
&& binding.edtStreet.text.isNotBlank() && binding.edtStreet.text.isNotBlank()
&& binding.edtSubdistrict.text.isNotBlank()
&& binding.edtPostalCode.text.isNotBlank() && binding.edtPostalCode.text.isNotBlank()
binding.btnSaveAddress.let { binding.btnSaveAddress.let {
@ -299,6 +364,7 @@ class DetailStoreAddressActivity : AppCompatActivity() {
it.isEnabled = false it.isEnabled = false
it.setBackgroundResource(R.drawable.bg_button_disabled) it.setBackgroundResource(R.drawable.bg_button_disabled)
it.setTextColor(getColor(R.color.black_300)) it.setTextColor(getColor(R.color.black_300))
Toast.makeText(this, "Periksa dan lenkapi alamat anda", Toast.LENGTH_SHORT).show()
} }
} }
} }
@ -313,6 +379,12 @@ class DetailStoreAddressActivity : AppCompatActivity() {
binding.spinnerCity.visibility = if (isLoading) View.GONE else View.VISIBLE binding.spinnerCity.visibility = if (isLoading) View.GONE else View.VISIBLE
} }
private fun showSubLoading(isLoading: Boolean) {
binding.subdistrictProgressBar.visibility = if (isLoading) View.VISIBLE else View.GONE
binding.spinnerSubdistrict.visibility = if (isLoading) View.GONE else View.VISIBLE
}
private fun showError(message: String) { private fun showError(message: String) {
binding.progressBar.visibility = View.GONE binding.progressBar.visibility = View.GONE
binding.tvError.visibility = View.VISIBLE binding.tvError.visibility = View.VISIBLE

View File

@ -6,9 +6,12 @@ import android.net.Uri
import android.os.Bundle import android.os.Bundle
import android.util.Log import android.util.Log
import android.view.View import android.view.View
import android.widget.AdapterView
import android.widget.Button import android.widget.Button
import android.widget.EditText import android.widget.EditText
import android.widget.ImageView import android.widget.ImageView
import android.widget.ProgressBar
import android.widget.Spinner
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
@ -18,6 +21,7 @@ import com.alya.ecommerce_serang.data.api.dto.PaymentInfo
import com.alya.ecommerce_serang.data.api.retrofit.ApiConfig import com.alya.ecommerce_serang.data.api.retrofit.ApiConfig
import com.alya.ecommerce_serang.data.repository.PaymentInfoRepository import com.alya.ecommerce_serang.data.repository.PaymentInfoRepository
import com.alya.ecommerce_serang.databinding.ActivityPaymentInfoBinding import com.alya.ecommerce_serang.databinding.ActivityPaymentInfoBinding
import com.alya.ecommerce_serang.ui.order.address.BankAdapter
import com.alya.ecommerce_serang.utils.BaseViewModelFactory import com.alya.ecommerce_serang.utils.BaseViewModelFactory
import com.alya.ecommerce_serang.utils.SessionManager import com.alya.ecommerce_serang.utils.SessionManager
import com.alya.ecommerce_serang.utils.UriToFileConverter import com.alya.ecommerce_serang.utils.UriToFileConverter
@ -32,6 +36,7 @@ class PaymentInfoActivity : AppCompatActivity() {
private lateinit var sessionManager: SessionManager private lateinit var sessionManager: SessionManager
private var selectedQrisImageUri: Uri? = null private var selectedQrisImageUri: Uri? = null
private var selectedQrisImageFile: File? = null private var selectedQrisImageFile: File? = null
private lateinit var bankAdapter: BankAdapter
// Store form data between dialog reopenings // Store form data between dialog reopenings
private var savedBankName: String = "" private var savedBankName: String = ""
@ -95,6 +100,7 @@ class PaymentInfoActivity : AppCompatActivity() {
onBackPressedDispatcher.onBackPressed() onBackPressedDispatcher.onBackPressed()
} }
bankAdapter = BankAdapter(this)
setupRecyclerView() setupRecyclerView()
setupObservers() setupObservers()
@ -173,10 +179,47 @@ class PaymentInfoActivity : AppCompatActivity() {
builder.setView(dialogView) builder.setView(dialogView)
val dialog = builder.create() val dialog = builder.create()
val spinnerBankName = dialogView.findViewById<Spinner>(R.id.spinner_bank_name)
val progressBarBank = dialogView.findViewById<ProgressBar>(R.id.bank_name_progress_bar)
spinnerBankName.adapter = bankAdapter
spinnerBankName.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
override fun onItemSelected(
parent: AdapterView<*>?,
view: View?,
position: Int,
id: Long
) {
Log.d(TAG, "Bank selected at position: $position")
val bankName = bankAdapter.getBankName(position)
if (bankName != null) {
Log.d(TAG, "Setting bank name: $bankName")
viewModel.bankName.value = bankName
viewModel.selectedBankName = bankName
// Optional: Log the selected bank details
val selectedBank = bankAdapter.getBankItem(position)
selectedBank?.let {
Log.d(TAG, "Selected bank: ${it.bankName} (Code: ${it.bankCode})")
}
// Hide progress bar if it was showing
progressBarBank.visibility = View.GONE
} else {
Log.e(TAG, "Invalid bank name for position: $position")
}
}
override fun onNothingSelected(parent: AdapterView<*>?) {
Log.d(TAG, "No bank selected")
viewModel.selectedBankName = null
}
}
// Get references to views in the dialog // Get references to views in the dialog
val btnAddQris = dialogView.findViewById<Button>(R.id.btn_add_qris) val btnAddQris = dialogView.findViewById<Button>(R.id.btn_add_qris)
val bankNameEditText = dialogView.findViewById<EditText>(R.id.edt_bank_name) // val spinnerBankName = dialogView.findViewById<Spinner>(R.id.spinner_bank_name)
val bankNumberEditText = dialogView.findViewById<EditText>(R.id.edt_bank_number) val bankNumberEditText = dialogView.findViewById<EditText>(R.id.edt_bank_number)
val accountNameEditText = dialogView.findViewById<EditText>(R.id.edt_account_name) val accountNameEditText = dialogView.findViewById<EditText>(R.id.edt_account_name)
val qrisPreview = dialogView.findViewById<ImageView>(R.id.iv_qris_preview) val qrisPreview = dialogView.findViewById<ImageView>(R.id.iv_qris_preview)
@ -185,7 +228,10 @@ class PaymentInfoActivity : AppCompatActivity() {
// When reopening, restore the previously entered values // When reopening, restore the previously entered values
if (isReopened) { if (isReopened) {
bankNameEditText.setText(savedBankName) val savedPosition = bankAdapter.findPositionByName(savedBankName)
if (savedPosition >= 0) {
spinnerBankName.setSelection(savedPosition)
}
bankNumberEditText.setText(savedBankNumber) bankNumberEditText.setText(savedBankNumber)
accountNameEditText.setText(savedAccountName) accountNameEditText.setText(savedAccountName)
@ -199,7 +245,7 @@ class PaymentInfoActivity : AppCompatActivity() {
btnAddQris.setOnClickListener { btnAddQris.setOnClickListener {
// Save the current values before dismissing // Save the current values before dismissing
savedBankName = bankNameEditText.text.toString().trim() savedBankName = viewModel.selectedBankName ?: ""
savedBankNumber = bankNumberEditText.text.toString().trim() savedBankNumber = bankNumberEditText.text.toString().trim()
savedAccountName = accountNameEditText.text.toString().trim() savedAccountName = accountNameEditText.text.toString().trim()
@ -212,13 +258,13 @@ class PaymentInfoActivity : AppCompatActivity() {
} }
btnSave.setOnClickListener { btnSave.setOnClickListener {
val bankName = bankNameEditText.text.toString().trim() val bankName = viewModel.selectedBankName ?: ""
val bankNumber = bankNumberEditText.text.toString().trim() val bankNumber = bankNumberEditText.text.toString().trim()
val accountName = accountNameEditText.text.toString().trim() val accountName = accountNameEditText.text.toString().trim()
// Validation // Validation
if (bankName.isEmpty()) { if (bankName.isEmpty()) {
showSnackbar("Nama bank tidak boleh kosong") showSnackbar("Pilih nama bank terlebih dahulu")
return@setOnClickListener return@setOnClickListener
} }

View File

@ -30,6 +30,9 @@ class PaymentInfoViewModel(private val repository: PaymentInfoRepository) : View
private val _deletePaymentSuccess = MutableLiveData<Boolean>() private val _deletePaymentSuccess = MutableLiveData<Boolean>()
val deletePaymentSuccess: LiveData<Boolean> = _deletePaymentSuccess val deletePaymentSuccess: LiveData<Boolean> = _deletePaymentSuccess
var selectedBankName: String? = null
val bankName = MutableLiveData<String>()
fun getPaymentInfo() { fun getPaymentInfo() {
_isLoading.value = true _isLoading.value = true
viewModelScope.launch { viewModelScope.launch {

View File

@ -72,6 +72,7 @@ class RegisterViewModel(private val repository: UserRepository, private val orde
var selectedProvinceId: Int? = null var selectedProvinceId: Int? = null
var selectedCityId: String? = null var selectedCityId: String? = null
var selectedSubdistrict: String? = null var selectedSubdistrict: String? = null
var subdistrictName: String? = null
var selectedVillages: String? = null var selectedVillages: String? = null
var selectedPostalCode: String? = null var selectedPostalCode: String? = null

View File

@ -10,7 +10,7 @@
tools:context=".ui.profile.mystore.profile.address.DetailStoreAddressActivity"> tools:context=".ui.profile.mystore.profile.address.DetailStoreAddressActivity">
<include <include
android:id="@+id/header" android:id="@+id/header_address_store"
layout="@layout/header" /> layout="@layout/header" />
<ScrollView <ScrollView
@ -154,6 +154,58 @@
</LinearLayout> </LinearLayout>
<!-- Kecamatan -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_marginBottom="24dp">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Kecamatan"
style="@style/body_medium"
android:layout_marginEnd="4dp"/>
<!-- Spinner Dropdown dengan Chevron -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:background="@drawable/bg_text_field"
android:gravity="center_vertical"
android:layout_marginTop="10dp">
<Spinner
android:id="@+id/spinner_subdistrict"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:padding="8dp"
style="@style/body_small"
android:background="@null"/>
<ProgressBar
android:id="@+id/subdistrict_progress_bar"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_gravity="center"
android:visibility="gone"/>
<!-- Chevron Down Icon -->
<ImageView
android:layout_width="16dp"
android:layout_height="16dp"
android:src="@drawable/ic_down"
android:layout_marginEnd="8dp"
android:contentDescription="Chevron Down" />
</LinearLayout>
</LinearLayout>
<!-- Jalan --> <!-- Jalan -->
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
@ -180,32 +232,6 @@
</LinearLayout> </LinearLayout>
<!-- Kecamatan -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_marginBottom="24dp">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Kecamatan"
style="@style/body_medium"
android:layout_marginEnd="4dp"/>
<EditText
android:id="@+id/edt_subdistrict"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/bg_text_field"
android:padding="8dp"
style="@style/body_small"
android:hint="Isi nama kecamatan di sini"
android:layout_marginTop="10dp"/>
</LinearLayout>
<!-- Kode Pos --> <!-- Kode Pos -->
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"

View File

@ -14,18 +14,39 @@
android:textStyle="bold" android:textStyle="bold"
android:layout_marginBottom="16dp" /> android:layout_marginBottom="16dp" />
<com.google.android.material.textfield.TextInputLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginBottom="8dp" android:orientation="horizontal"
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"> android:background="@drawable/bg_text_field"
android:gravity="center_vertical"
android:layout_marginTop="10dp">
<com.google.android.material.textfield.TextInputEditText <Spinner
android:id="@+id/edt_bank_name" android:id="@+id/spinner_bank_name"
android:layout_width="match_parent" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:hint="Nama Bank" /> android:layout_weight="1"
</com.google.android.material.textfield.TextInputLayout> android:padding="8dp"
style="@style/body_small"
android:background="@null"/>
<ProgressBar
android:id="@+id/bank_name_progress_bar"
android:layout_width="24dp"
android:layout_height="24dp"
android:padding="4dp"
android:visibility="gone"/>
<!-- Chevron Down Icon -->
<ImageView
android:layout_width="16dp"
android:layout_height="16dp"
android:src="@drawable/ic_down"
android:layout_marginEnd="8dp"
android:contentDescription="Chevron Down" />
</LinearLayout>
<com.google.android.material.textfield.TextInputLayout <com.google.android.material.textfield.TextInputLayout
android:layout_width="match_parent" android:layout_width="match_parent"