diff --git a/app/src/main/java/com/alya/ecommerce_serang/data/api/dto/OrdersItem.kt b/app/src/main/java/com/alya/ecommerce_serang/data/api/dto/OrdersItem.kt index 439b949..f2acc27 100644 --- a/app/src/main/java/com/alya/ecommerce_serang/data/api/dto/OrdersItem.kt +++ b/app/src/main/java/com/alya/ecommerce_serang/data/api/dto/OrdersItem.kt @@ -90,7 +90,7 @@ data class OrdersItem( val orderId: Int, @field:SerializedName("city_id") - val cityId: Int, + val cityId: String, var displayStatus: String? = null ) diff --git a/app/src/main/java/com/alya/ecommerce_serang/data/api/response/customer/order/OrderDetailResponse.kt b/app/src/main/java/com/alya/ecommerce_serang/data/api/response/customer/order/OrderDetailResponse.kt index 0156579..99226f6 100644 --- a/app/src/main/java/com/alya/ecommerce_serang/data/api/response/customer/order/OrderDetailResponse.kt +++ b/app/src/main/java/com/alya/ecommerce_serang/data/api/response/customer/order/OrderDetailResponse.kt @@ -119,7 +119,7 @@ data class Orders( val orderId: Int, @field:SerializedName("city_id") - val cityId: Int + val cityId: String ) data class OrderListItemsItem( diff --git a/app/src/main/java/com/alya/ecommerce_serang/data/api/response/customer/product/StoreResponse.kt b/app/src/main/java/com/alya/ecommerce_serang/data/api/response/customer/product/StoreResponse.kt index 3e3b358..9828543 100644 --- a/app/src/main/java/com/alya/ecommerce_serang/data/api/response/customer/product/StoreResponse.kt +++ b/app/src/main/java/com/alya/ecommerce_serang/data/api/response/customer/product/StoreResponse.kt @@ -114,7 +114,7 @@ data class Store( val storeDescription: String, @field:SerializedName("city_id") - val cityId: Int + val cityId: String ) data class ShippingItem( diff --git a/app/src/main/java/com/alya/ecommerce_serang/data/api/response/store/profile/StoreDataResponse.kt b/app/src/main/java/com/alya/ecommerce_serang/data/api/response/store/profile/StoreDataResponse.kt index fa7ad97..cddab4e 100644 --- a/app/src/main/java/com/alya/ecommerce_serang/data/api/response/store/profile/StoreDataResponse.kt +++ b/app/src/main/java/com/alya/ecommerce_serang/data/api/response/store/profile/StoreDataResponse.kt @@ -35,7 +35,7 @@ data class Store( val detail: String, @SerializedName("is_store_location") val isStoreLocation: Boolean, @SerializedName("user_id") val userId: Int, - @SerializedName("city_id") val cityId: Int, + @SerializedName("city_id") val cityId: String, @SerializedName("province_id") val provinceId: Int, val phone: String?, val recipient: String?, diff --git a/app/src/main/java/com/alya/ecommerce_serang/data/api/response/store/sells/OrderDetailResponse.kt b/app/src/main/java/com/alya/ecommerce_serang/data/api/response/store/sells/OrderDetailResponse.kt index 745df63..125548f 100644 --- a/app/src/main/java/com/alya/ecommerce_serang/data/api/response/store/sells/OrderDetailResponse.kt +++ b/app/src/main/java/com/alya/ecommerce_serang/data/api/response/store/sells/OrderDetailResponse.kt @@ -132,5 +132,5 @@ data class Orders( val username: String? = null, @field:SerializedName("city_id") - val cityId: Int? = null + val cityId: String? = null ) \ No newline at end of file diff --git a/app/src/main/java/com/alya/ecommerce_serang/data/api/response/store/sells/OrderListResponse.kt b/app/src/main/java/com/alya/ecommerce_serang/data/api/response/store/sells/OrderListResponse.kt index 5efc65d..d11accf 100644 --- a/app/src/main/java/com/alya/ecommerce_serang/data/api/response/store/sells/OrderListResponse.kt +++ b/app/src/main/java/com/alya/ecommerce_serang/data/api/response/store/sells/OrderListResponse.kt @@ -129,7 +129,7 @@ data class OrdersItem( val status: String? = null, @field:SerializedName("city_id") - val cityId: Int? = null, + val cityId: String? = null, var displayStatus: String? = null ) diff --git a/app/src/main/java/com/alya/ecommerce_serang/ui/order/address/ProvinceAdapter.kt b/app/src/main/java/com/alya/ecommerce_serang/ui/order/address/ProvinceAdapter.kt index 85f674b..d9dee88 100644 --- a/app/src/main/java/com/alya/ecommerce_serang/ui/order/address/ProvinceAdapter.kt +++ b/app/src/main/java/com/alya/ecommerce_serang/ui/order/address/ProvinceAdapter.kt @@ -3,6 +3,7 @@ package com.alya.ecommerce_serang.ui.order.address import android.content.Context import android.util.Log import android.widget.ArrayAdapter +import android.widget.Spinner import com.alya.ecommerce_serang.data.api.response.customer.order.CitiesItem import com.alya.ecommerce_serang.data.api.response.customer.order.ProvincesItem import com.alya.ecommerce_serang.data.api.response.customer.order.SubdistrictsItem @@ -97,4 +98,75 @@ class VillagesAdapter( fun getPostalCode(position: Int): String?{ return villages.getOrNull(position)?.postalCode } +} + +class BankAdapter( + context: Context, + resource: Int = android.R.layout.simple_dropdown_item_1line +) : ArrayAdapter(context, resource, ArrayList()) { + + data class BankItem( + val bankName: String, + val bankCode: String? = null, + val description: String? = null + ) + + private val banks = ArrayList() + + init { + loadHardcodedData() + } + + private fun loadHardcodedData() { + val defaultBanks = listOf( + BankItem("Bank Mandiri", "008", "PT Bank Mandiri (Persero) Tbk"), + BankItem("Bank BRI", "002", "PT Bank Rakyat Indonesia (Persero) Tbk"), + BankItem("Bank BCA", "014", "PT Bank Central Asia Tbk"), + BankItem("Bank BNI", "009", "PT Bank Negara Indonesia (Persero) Tbk"), + BankItem("Bank BTN", "200", "PT Bank Tabungan Negara (Persero) Tbk"), + BankItem("Bank CIMB Niaga", "022", "PT Bank CIMB Niaga Tbk"), + BankItem("Bank Danamon", "011", "PT Bank Danamon Indonesia Tbk"), + BankItem("Bank Permata", "013", "PT Bank Permata Tbk"), + BankItem("Bank OCBC NISP", "028", "PT Bank OCBC NISP Tbk"), + BankItem("Bank Maybank", "016", "PT Bank Maybank Indonesia Tbk"), + BankItem("Bank Panin", "019", "PT Bank Panin Dubai Syariah Tbk"), + BankItem("Bank UOB", "023", "PT Bank UOB Indonesia"), + BankItem("Bank Mega", "426", "PT Bank Mega Tbk"), + BankItem("Bank Bukopin", "441", "PT Bank Bukopin Tbk"), + BankItem("Bank BJB", "110", "PT Bank Pembangunan Daerah Jawa Barat dan Banten Tbk") + ) + updateData(defaultBanks) + } + + fun updateData(newBanks: List) { + banks.clear() + banks.addAll(newBanks) + + clear() + addAll(banks.map { it.bankName }) + notifyDataSetChanged() + } + + fun getBankName(position: Int): String? { + return banks.getOrNull(position)?.bankName + } + + fun getBankItem(position: Int): BankItem? { + return banks.getOrNull(position) + } + + fun getBankCode(position: Int): String? { + return banks.getOrNull(position)?.bankCode + } + + fun findPositionByName(bankName: String): Int { + return banks.indexOfFirst { it.bankName == bankName } + } + + fun setDefaultSelection(spinner: Spinner, defaultBankName: String) { + val position = findPositionByName(defaultBankName) + if (position >= 0) { + spinner.setSelection(position) + } + } } \ No newline at end of file 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 34ba43a..dad73a6 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 @@ -32,6 +32,7 @@ import com.google.android.material.button.MaterialButton import com.google.android.material.textfield.TextInputLayout import com.google.gson.Gson import java.io.File +import java.text.NumberFormat import java.text.SimpleDateFormat import java.util.Calendar import java.util.Locale @@ -88,7 +89,8 @@ class OrderHistoryAdapter( tvStoreName.text = storeName // Set total amount - tvTotalAmount.text = order.totalAmount + tvTotalAmount.text = formatCurrency(order.totalAmount.toDouble()) + // Set item count val itemCount = order.orderItems.size @@ -599,6 +601,11 @@ class OrderHistoryAdapter( } } + private fun formatCurrency(amount: Double): String { + val formatter = NumberFormat.getCurrencyInstance(Locale("in", "ID")) + return formatter.format(amount).replace(",00", "") + } + } companion object { diff --git a/app/src/main/java/com/alya/ecommerce_serang/ui/order/history/OrderProductAdapter.kt b/app/src/main/java/com/alya/ecommerce_serang/ui/order/history/OrderProductAdapter.kt index da1a17c..3fe5f6b 100644 --- a/app/src/main/java/com/alya/ecommerce_serang/ui/order/history/OrderProductAdapter.kt +++ b/app/src/main/java/com/alya/ecommerce_serang/ui/order/history/OrderProductAdapter.kt @@ -10,6 +10,8 @@ import com.alya.ecommerce_serang.BuildConfig.BASE_URL import com.alya.ecommerce_serang.R import com.alya.ecommerce_serang.data.api.response.customer.order.OrderItemsItem import com.bumptech.glide.Glide +import java.text.NumberFormat +import java.util.Locale class OrderProductAdapter : RecyclerView.Adapter() { @@ -46,7 +48,7 @@ class OrderProductAdapter : RecyclerView.Adapter { @@ -65,10 +67,9 @@ class OrderProductAdapter : RecyclerView.Adapter + when (state) { + is Result.Loading -> { + Log.d(TAG, "setupobservers: Loading Subdistrict...") + binding.subdistrictProgressBar.visibility = View.VISIBLE + binding.spinnerSubdistrict.isEnabled = false + } + is Result.Success -> { + Log.d(TAG, "setupobservers: Subdistrict loaded successfullti: ${state.data.size} subdistrict") + binding.subdistrictProgressBar.visibility = View.GONE + binding.spinnerSubdistrict.isEnabled = true + + subdistrictAdapter.updateData(state.data) + } + is Result.Error -> { + Log.e(TAG, "setupObservers: Error loading subdistrict: ${state.exception.message}") + binding.subdistrictProgressBar.visibility = View.GONE + binding.spinnerCity.isEnabled = true + } + } + } + // Observe registration state viewModel.registerState.observe(this) { result -> when (result) { @@ -398,6 +427,11 @@ class RegisterStoreActivity : AppCompatActivity() { if (cityId != null) { Log.d(TAG, "Setting city ID: $cityId") viewModel.cityId.value = cityId + Log.d(TAG, "Fetching subdistrict for city ID: $cityId") + viewModel.getSubdistrict(cityId) + + subdistrictAdapter.clear() + binding.spinnerSubdistrict.setSelection(0) viewModel.selectedCityId = cityId } else { Log.e(TAG, "Invalid city ID for position: $position") @@ -409,6 +443,61 @@ class RegisterStoreActivity : AppCompatActivity() { } } + //Setup Subdistrict spinner + binding.spinnerSubdistrict.adapter = subdistrictAdapter + binding.spinnerSubdistrict.onItemSelectedListener = object : AdapterView.OnItemSelectedListener { + override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) { + Log.d(TAG, "Subdistrict selected at position: $position") + val subdistrictId = subdistrictAdapter.getSubdistrictId(position) + if (subdistrictId != null) { + Log.d(TAG, "Setting subdistrict ID: $subdistrictId") + viewModel.subdistrict.value = subdistrictId + viewModel.selectedSubdistrict = subdistrictId + } else { + Log.e(TAG, "Invalid subdistrict ID for position: $position") + } + } + + override fun onNothingSelected(parent: AdapterView<*>?) { + Log.d(TAG, "No city selected") + } + } + + binding.spinnerBankName.adapter = bankAdapter + binding.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 + binding.storeTypeProgressBar.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 + } + } + // Add initial hints to the spinners if (provinceAdapter.isEmpty) { Log.d(TAG, "Adding default province hint") @@ -420,6 +509,16 @@ class RegisterStoreActivity : AppCompatActivity() { cityAdapter.add("Pilih Kabupaten/Kota") } + if (subdistrictAdapter.isEmpty) { + Log.d(TAG, "Adding default kecamatan hint") + subdistrictAdapter.add("Pilih Kecamatan") + } + + if (bankAdapter.isEmpty) { + Log.d(TAG, "Adding default bank hint") + bankAdapter.add("Pilih Bank") + } + Log.d(TAG, "setupSpinners: Province and city spinners setup completed") } @@ -620,26 +719,26 @@ class RegisterStoreActivity : AppCompatActivity() { validateRequiredFields() } }) +// +// binding.etSubdistrict.addTextChangedListener(object : TextWatcher { +// override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {} +// override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {} +// override fun afterTextChanged(s: Editable?) { +// viewModel.subdistrict.value = s.toString() +// Log.d(TAG, "Subdistrict updated: ${s.toString()}") +// validateRequiredFields() +// } +// }) - binding.etSubdistrict.addTextChangedListener(object : TextWatcher { - override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {} - override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {} - override fun afterTextChanged(s: Editable?) { - viewModel.subdistrict.value = s.toString() - Log.d(TAG, "Subdistrict updated: ${s.toString()}") - validateRequiredFields() - } - }) - - binding.etBankName.addTextChangedListener(object: TextWatcher { - override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {} - override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {} - override fun afterTextChanged(s: Editable?) { - viewModel.bankName.value = s.toString() - Log.d(TAG, "Bank name updated: ${s.toString()}") - validateRequiredFields() - } - }) +// binding.etBankName.addTextChangedListener(object: TextWatcher { +// override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {} +// override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {} +// override fun afterTextChanged(s: Editable?) { +// viewModel.bankName.value = s.toString() +// Log.d(TAG, "Bank name updated: ${s.toString()}") +// validateRequiredFields() +// } +// }) binding.etAccountName.addTextChangedListener(object : TextWatcher { override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {} diff --git a/app/src/main/java/com/alya/ecommerce_serang/utils/viewmodel/RegisterStoreViewModel.kt b/app/src/main/java/com/alya/ecommerce_serang/utils/viewmodel/RegisterStoreViewModel.kt index 7bd27c8..9962e75 100644 --- a/app/src/main/java/com/alya/ecommerce_serang/utils/viewmodel/RegisterStoreViewModel.kt +++ b/app/src/main/java/com/alya/ecommerce_serang/utils/viewmodel/RegisterStoreViewModel.kt @@ -11,6 +11,8 @@ import com.alya.ecommerce_serang.data.api.response.auth.RegisterStoreResponse import com.alya.ecommerce_serang.data.api.response.auth.StoreTypesItem import com.alya.ecommerce_serang.data.api.response.customer.order.CitiesItem import com.alya.ecommerce_serang.data.api.response.customer.order.ProvincesItem +import com.alya.ecommerce_serang.data.api.response.customer.order.SubdistrictsItem +import com.alya.ecommerce_serang.data.api.response.customer.order.VillagesItem import com.alya.ecommerce_serang.data.repository.Result import com.alya.ecommerce_serang.data.repository.UserRepository import com.alya.ecommerce_serang.utils.ImageUtils @@ -41,8 +43,17 @@ class RegisterStoreViewModel( private val _citiesState = MutableLiveData>>() val citiesState: LiveData>> = _citiesState + private val _subdistrictState = MutableLiveData>>() + val subdistrictState: LiveData>> = _subdistrictState + + private val _villagesState = MutableLiveData>>() + val villagesState: LiveData>> = _villagesState + var selectedProvinceId: Int? = null var selectedCityId: String? = null + var selectedSubdistrict: String? = null + var selectedVillages: String? = null + var selectedBankName: String? = null // Form fields val storeName = MutableLiveData() @@ -265,6 +276,52 @@ class RegisterStoreViewModel( } } + fun getSubdistrict(cityId: String) { + _subdistrictState.value = Result.Loading + viewModelScope.launch { + try { + + selectedSubdistrict = cityId + val result = repository.getListSubdistrict(cityId) + result?.let { + _subdistrictState.postValue(Result.Success(it.subdistricts)) + Log.d(TAG, "Cities loaded for province $cityId: ${it.subdistricts.size}") + } ?: run { + _subdistrictState.postValue(Result.Error(Exception("Failed to load cities"))) + Log.e(TAG, "City result was null for province $cityId") + } + } catch (e: Exception) { + _subdistrictState.postValue(Result.Error(Exception(e.message ?: "Error loading cities"))) + Log.e(TAG, "Error fetching cities for province $cityId", e) + } + } + } + + fun getVillages(subdistrictId: String) { + _villagesState.value = Result.Loading + viewModelScope.launch { + try { + + selectedVillages = subdistrictId + val result = repository.getListVillages(subdistrictId) + result?.let { + _villagesState.postValue(Result.Success(it.villages)) + Log.d(TAG, "Cities loaded for province $subdistrictId: ${it.villages.size}") + } ?: run { + _villagesState.postValue(Result.Error(Exception("Failed to load cities"))) + Log.e(TAG, "City result was null for province $subdistrictId") + } + } catch (e: Exception) { + _villagesState.postValue(Result.Error(Exception(e.message ?: "Error loading cities"))) + Log.e(TAG, "Error fetching cities for province $subdistrictId", e) + } + } + } + + fun isBankSelected(): Boolean { + return !selectedBankName.isNullOrEmpty() + } + companion object { private const val TAG = "RegisterStoreUserViewModel" } diff --git a/app/src/main/res/layout/activity_register_store.xml b/app/src/main/res/layout/activity_register_store.xml index 1fdc074..d4517bb 100644 --- a/app/src/main/res/layout/activity_register_store.xml +++ b/app/src/main/res/layout/activity_register_store.xml @@ -347,41 +347,57 @@ + android:orientation="horizontal"> - + android:text="6. Kecamatan" + style="@style/body_medium" + android:layout_marginEnd="4dp"/> - - - - - - - + + + + + + + android:background="@null"/> + + + + + @@ -503,7 +519,8 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" - android:layout_marginBottom="24dp"> + android:layout_marginBottom="24dp" + android:visibility="gone"> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + User is typing... Mohon untuk melengkapi formulir pendaftaran ini agar dapat mengakses fitur penjual pada aplikasi. + + + Allo Bank Indonesia + Bank Digital BCA + Bank Central Asia (BCA) + Bank BCA Syariah + Bank Jago + Bank Mandiri + Bank Kb Bukopi + Bank Jabar Banten Syariah + Bank Mandiri Taspen + Bank Maybank Indonesia + Bank Negara Indonesia (BNI) + Bank Permata + Bank Rakyat Indonesia (BRI) + Bank Saqu Indonesia + Bank Seabank Indonesia + Bank Sinarmas + Bank Syariah Indonesia (BSI) + Bank Tabungan Negara (BTN) + Bank UOB Indonesia + BPD Jawa Barat dan Banten + Super Bank Indonesia + + \ No newline at end of file