mirror of
https://github.com/shaulascr/ecommerce_serang.git
synced 2025-12-15 15:41:02 +00:00
approval status
This commit is contained in:
4
.idea/deploymentTargetSelector.xml
generated
4
.idea/deploymentTargetSelector.xml
generated
@ -4,10 +4,10 @@
|
||||
<selectionStates>
|
||||
<SelectionState runConfigName="app">
|
||||
<option name="selectionMode" value="DROPDOWN" />
|
||||
<DropdownSelection timestamp="2025-05-08T14:50:55.425322500Z">
|
||||
<DropdownSelection timestamp="2025-08-17T17:32:55.497700100Z">
|
||||
<Target type="DEFAULT_BOOT">
|
||||
<handle>
|
||||
<DeviceId pluginId="LocalEmulator" identifier="path=C:\Users\Gracia Hotmauli\.android\avd\Pixel_8_2_2.avd" />
|
||||
<DeviceId pluginId="LocalEmulator" identifier="path=C:\Users\Gracia Hotmauli\.android\avd\Pixel_9_2.avd" />
|
||||
</handle>
|
||||
</Target>
|
||||
</DropdownSelection>
|
||||
|
||||
@ -29,6 +29,9 @@
|
||||
android:theme="@style/Theme.Ecommerce_serang"
|
||||
android:usesCleartextTraffic="true"
|
||||
tools:targetApi="31">
|
||||
<activity
|
||||
android:name=".ui.profile.ChangePasswordActivity"
|
||||
android:exported="false" />
|
||||
<activity
|
||||
android:name=".ui.auth.ResetPassActivity"
|
||||
android:exported="false" />
|
||||
|
||||
@ -10,9 +10,6 @@ data class Store(
|
||||
@field:SerializedName("store_status")
|
||||
val storeStatus: String,
|
||||
|
||||
@field:SerializedName("sppirt")
|
||||
val sppirt: String,
|
||||
|
||||
@field:SerializedName("user_name")
|
||||
val userName: String,
|
||||
|
||||
@ -37,9 +34,6 @@ data class Store(
|
||||
@field:SerializedName("user_phone")
|
||||
val userPhone: String,
|
||||
|
||||
@field:SerializedName("halal")
|
||||
val halal: String,
|
||||
|
||||
@field:SerializedName("id")
|
||||
val id: Int,
|
||||
|
||||
|
||||
@ -1,18 +1,13 @@
|
||||
package com.alya.ecommerce_serang.data.api.response.store
|
||||
|
||||
import com.alya.ecommerce_serang.data.api.dto.Store
|
||||
import com.alya.ecommerce_serang.data.api.response.store.profile.Payment
|
||||
import com.alya.ecommerce_serang.data.api.response.store.profile.Shipping
|
||||
import com.google.gson.annotations.SerializedName
|
||||
|
||||
data class StoreResponse(
|
||||
val message: String,
|
||||
val store: Store
|
||||
)
|
||||
|
||||
data class Store(
|
||||
@SerializedName("store_id") val storeId: Int,
|
||||
@SerializedName("store_status") val storeStatus: String,
|
||||
@SerializedName("store_name") val storeName: String,
|
||||
@SerializedName("user_name") val userName: String,
|
||||
val email: String,
|
||||
@SerializedName("user_phone") val userPhone: String,
|
||||
val balance: String
|
||||
val store: Store,
|
||||
val shipping: List<Shipping> = emptyList(),
|
||||
val payment: List<Payment> = emptyList()
|
||||
)
|
||||
@ -4,7 +4,7 @@ import android.util.Log
|
||||
import com.alya.ecommerce_serang.data.api.dto.ProductsItem
|
||||
import com.alya.ecommerce_serang.data.api.dto.Store
|
||||
import com.alya.ecommerce_serang.data.api.response.auth.ListStoreTypeResponse
|
||||
import com.alya.ecommerce_serang.data.api.response.customer.product.StoreResponse
|
||||
import com.alya.ecommerce_serang.data.api.response.store.StoreResponse
|
||||
import com.alya.ecommerce_serang.data.api.response.store.profile.StoreDataResponse
|
||||
import com.alya.ecommerce_serang.data.api.response.store.sells.OrderListResponse
|
||||
import com.alya.ecommerce_serang.data.api.retrofit.ApiService
|
||||
@ -15,13 +15,13 @@ import retrofit2.Response
|
||||
import java.io.IOException
|
||||
|
||||
class MyStoreRepository(private val apiService: ApiService) {
|
||||
suspend fun fetchMyStoreProfile(): Result<Store?> {
|
||||
suspend fun fetchMyStoreProfile(): Result<StoreResponse?> {
|
||||
return try {
|
||||
val response = apiService.getStore()
|
||||
val response = apiService.getMyStoreData()
|
||||
|
||||
if (response.isSuccessful) {
|
||||
val storeResponse: StoreResponse? = response.body()
|
||||
Result.Success(storeResponse?.store)
|
||||
val storeResponse = response.body()
|
||||
Result.Success(storeResponse)
|
||||
} else {
|
||||
val errorMessage = response.errorBody()?.string() ?: "Unknown API error"
|
||||
Log.e("MyStoreRepository", "Error: $errorMessage")
|
||||
|
||||
@ -0,0 +1,21 @@
|
||||
package com.alya.ecommerce_serang.ui.profile
|
||||
|
||||
import android.os.Bundle
|
||||
import androidx.activity.enableEdgeToEdge
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.view.ViewCompat
|
||||
import androidx.core.view.WindowInsetsCompat
|
||||
import com.alya.ecommerce_serang.R
|
||||
|
||||
class ChangePasswordActivity : AppCompatActivity() {
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
enableEdgeToEdge()
|
||||
setContentView(R.layout.activity_change_password)
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -84,14 +84,19 @@ class ProfileFragment : Fragment() {
|
||||
// else startActivity(Intent(requireContext(), RegisterStoreActivity::class.java))
|
||||
if (viewModel.checkStore.value == true) {
|
||||
myStoreViewModel.loadMyStore()
|
||||
myStoreViewModel.myStoreProfile.observe(viewLifecycleOwner) { store ->
|
||||
store?.let {
|
||||
when (store.storeStatus) {
|
||||
myStoreViewModel.myStoreProfile.observe(viewLifecycleOwner) { storeDataResponse ->
|
||||
storeDataResponse?.let { storeResponse ->
|
||||
val store = storeResponse.store
|
||||
when (store.approvalStatus) {
|
||||
"process" -> startActivity(Intent(requireContext(), StoreOnReviewActivity::class.java))
|
||||
"active" -> startActivity(Intent(requireContext(), MyStoreActivity::class.java))
|
||||
"inactive" -> startActivity(Intent(requireContext(), MyStoreActivity::class.java))
|
||||
"suspended" -> startActivity(Intent(requireContext(), StoreSuspendedActivity::class.java))
|
||||
else -> startActivity(Intent(requireContext(), RegisterStoreActivity::class.java))
|
||||
"rejected" -> startActivity(
|
||||
Intent(requireContext(), RegisterStoreActivity::class.java).putExtra("REAPPLY", true))
|
||||
else -> {
|
||||
when(store.storeStatus){
|
||||
"suspended" -> startActivity(Intent(requireContext(), StoreSuspendedActivity::class.java))
|
||||
else -> startActivity(Intent(requireContext(), MyStoreActivity::class.java))
|
||||
}
|
||||
}
|
||||
}
|
||||
} ?: run {
|
||||
Toast.makeText(requireContext(), "Gagal memuat data toko", Toast.LENGTH_SHORT).show()
|
||||
@ -115,6 +120,11 @@ class ProfileFragment : Fragment() {
|
||||
startActivity(intent)
|
||||
}
|
||||
|
||||
binding.cardChangePass.setOnClickListener{
|
||||
val intent = Intent(requireContext(), ChangePasswordActivity::class.java)
|
||||
startActivity(intent)
|
||||
}
|
||||
|
||||
binding.cardLogout.setOnClickListener{
|
||||
logout()
|
||||
}
|
||||
|
||||
@ -63,7 +63,7 @@ class MyStoreActivity : AppCompatActivity() {
|
||||
viewModel.loadMyStoreProducts()
|
||||
|
||||
viewModel.myStoreProfile.observe(this){ user ->
|
||||
user?.let { myStoreProfileOverview(it) }
|
||||
user?.let { myStoreProfileOverview(it.store) }
|
||||
}
|
||||
|
||||
viewModel.errorMessage.observe(this) { error ->
|
||||
|
||||
@ -27,6 +27,7 @@ import androidx.core.view.WindowInsetsCompat
|
||||
import com.alya.ecommerce_serang.R
|
||||
import com.alya.ecommerce_serang.data.api.response.auth.StoreTypesItem
|
||||
import com.alya.ecommerce_serang.data.api.retrofit.ApiConfig
|
||||
import com.alya.ecommerce_serang.data.repository.MyStoreRepository
|
||||
import com.alya.ecommerce_serang.data.repository.Result
|
||||
import com.alya.ecommerce_serang.data.repository.UserRepository
|
||||
import com.alya.ecommerce_serang.databinding.ActivityRegisterStoreBinding
|
||||
@ -35,8 +36,17 @@ import com.alya.ecommerce_serang.ui.order.address.CityAdapter
|
||||
import com.alya.ecommerce_serang.ui.order.address.ProvinceAdapter
|
||||
import com.alya.ecommerce_serang.ui.order.address.SubdsitrictAdapter
|
||||
import com.alya.ecommerce_serang.utils.BaseViewModelFactory
|
||||
import com.alya.ecommerce_serang.utils.FileUtils
|
||||
import com.alya.ecommerce_serang.utils.ImageUtils
|
||||
import com.alya.ecommerce_serang.utils.SessionManager
|
||||
import com.alya.ecommerce_serang.utils.viewmodel.MyStoreViewModel
|
||||
import com.alya.ecommerce_serang.utils.viewmodel.RegisterStoreViewModel
|
||||
import okhttp3.MediaType.Companion.toMediaTypeOrNull
|
||||
import okhttp3.MultipartBody
|
||||
import okhttp3.RequestBody
|
||||
import okhttp3.RequestBody.Companion.toRequestBody
|
||||
import java.io.File
|
||||
import androidx.core.net.toUri
|
||||
|
||||
class RegisterStoreActivity : AppCompatActivity() {
|
||||
|
||||
@ -53,6 +63,7 @@ class RegisterStoreActivity : AppCompatActivity() {
|
||||
private val PICK_KTP_REQUEST = 1002
|
||||
private val PICK_NPWP_REQUEST = 1003
|
||||
private val PICK_NIB_REQUEST = 1004
|
||||
private var isReapply: Boolean = false
|
||||
|
||||
// Location request code
|
||||
private val LOCATION_PERMISSION_REQUEST = 2001
|
||||
@ -64,6 +75,15 @@ class RegisterStoreActivity : AppCompatActivity() {
|
||||
RegisterStoreViewModel(orderRepository)
|
||||
}
|
||||
}
|
||||
|
||||
private val myStoreViewModel: MyStoreViewModel by viewModels {
|
||||
BaseViewModelFactory {
|
||||
val apiService = ApiConfig.getApiService(sessionManager)
|
||||
val myStoreRepository = MyStoreRepository(apiService)
|
||||
MyStoreViewModel(myStoreRepository)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
binding = ActivityRegisterStoreBinding.inflate(layoutInflater)
|
||||
@ -89,6 +109,8 @@ class RegisterStoreActivity : AppCompatActivity() {
|
||||
|
||||
setupHeader()
|
||||
|
||||
isReapply = intent.getBooleanExtra("REAPPLY", false)
|
||||
|
||||
provinceAdapter = ProvinceAdapter(this)
|
||||
cityAdapter = CityAdapter(this)
|
||||
subdistrictAdapter = SubdsitrictAdapter(this)
|
||||
@ -129,19 +151,140 @@ class RegisterStoreActivity : AppCompatActivity() {
|
||||
viewModel.cityId.observe(this) { validateRequiredFields() }
|
||||
viewModel.storeTypeId.observe(this) { validateRequiredFields() }
|
||||
|
||||
// Setup register button
|
||||
binding.btnRegister.setOnClickListener {
|
||||
Log.d(TAG, "Register button clicked")
|
||||
if (viewModel.validateForm()) {
|
||||
Log.d(TAG, "Form validation successful, proceeding with registration")
|
||||
viewModel.registerStore(this)
|
||||
} else {
|
||||
Log.e(TAG, "Form validation failed")
|
||||
Toast.makeText(this, "Harap lengkapi semua field yang wajib diisi", Toast.LENGTH_SHORT).show()
|
||||
if (isReapply) {
|
||||
binding.btnRegister.text = "Ajukan Kembali"
|
||||
binding.layoutRejected.visibility = View.VISIBLE
|
||||
|
||||
myStoreViewModel.loadMyStore()
|
||||
|
||||
myStoreViewModel.myStoreProfile.observe(this) { storeDataResponse ->
|
||||
storeDataResponse?.let { storeResponse ->
|
||||
val store = storeResponse.store
|
||||
binding.tvRejectedReason.text = store.approvalReason
|
||||
|
||||
// Prefill basic fields
|
||||
binding.etStoreName.setText(store.storeName)
|
||||
binding.etStoreDescription.setText(store.storeDescription)
|
||||
binding.etStreet.setText(store.street)
|
||||
binding.etPostalCode.setText(store.postalCode)
|
||||
binding.etAddressDetail.setText(store.detail)
|
||||
|
||||
viewModel.storeName.value = store.storeName
|
||||
viewModel.storeDescription.value = store.storeDescription
|
||||
viewModel.street.value = store.street
|
||||
viewModel.postalCode.value = store.postalCode.toIntOrNull() ?: 0
|
||||
viewModel.addressDetail.value = store.detail
|
||||
|
||||
// Prefill bank info
|
||||
storeResponse.payment.firstOrNull()?.let { payment ->
|
||||
viewModel.bankName.value = payment.bankName
|
||||
viewModel.bankNumber.value = payment.bankNum.toIntOrNull() ?: 0
|
||||
val bankPosition = bankAdapter.findPositionByName(payment.bankName)
|
||||
binding.spinnerBankName.setSelection(bankPosition, false)
|
||||
}
|
||||
|
||||
// Prefill couriers
|
||||
storeResponse.shipping.forEach { courier ->
|
||||
when (courier.courier) {
|
||||
"jne" -> binding.checkboxJne.isChecked = true
|
||||
"pos" -> binding.checkboxPos.isChecked = true
|
||||
"tiki" -> binding.checkboxTiki.isChecked = true
|
||||
}
|
||||
}
|
||||
|
||||
// Prefill document URIs
|
||||
store.ktp.let { ktpUri ->
|
||||
viewModel.ktpUri = ktpUri.toUri()
|
||||
updateImagePreview(viewModel.ktpUri, binding.imgKtp, binding.layoutUploadKtp)
|
||||
}
|
||||
store.npwp.let { npwpUri ->
|
||||
viewModel.npwpUri = npwpUri.toUri()
|
||||
updateDocumentPreview(binding.layoutUploadNpwp)
|
||||
}
|
||||
store.nib.let { nibUri ->
|
||||
viewModel.nibUri = nibUri.toUri()
|
||||
updateDocumentPreview(binding.layoutUploadNib)
|
||||
}
|
||||
|
||||
// Prefill spinner for store types
|
||||
preselectStoreType(store.storeTypeId)
|
||||
|
||||
// Prefill province, city, and subdistrict
|
||||
preselectProvinceCitySubdistrict(
|
||||
provinceId = store.provinceId,
|
||||
cityId = store.cityId,
|
||||
subdistrictId = store.subdistrict
|
||||
)
|
||||
|
||||
validateRequiredFields()
|
||||
}
|
||||
}
|
||||
|
||||
binding.btnRegister.setOnClickListener {
|
||||
doUpdateStoreProfile()
|
||||
}
|
||||
} else {
|
||||
binding.btnRegister.setOnClickListener {
|
||||
if (viewModel.validateForm()) viewModel.registerStore(this)
|
||||
else Toast.makeText(this, "Harap lengkapi semua field yang wajib diisi", Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun preselectStoreType(storeTypeId: Int) {
|
||||
// The adapter is created in setupStoreTypeSpinner(...)
|
||||
val adapter = binding.spinnerStoreType.adapter
|
||||
if (adapter != null) {
|
||||
val count = adapter.count
|
||||
for (i in 0 until count) {
|
||||
val item = adapter.getItem(i) as? StoreTypesItem
|
||||
if (item?.id == storeTypeId) {
|
||||
binding.spinnerStoreType.setSelection(i, false)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun preselectProvinceCitySubdistrict(
|
||||
provinceId: Int,
|
||||
cityId: String,
|
||||
subdistrictId: String
|
||||
) {
|
||||
// Province first (this will trigger cities fetch)
|
||||
val provCount = provinceAdapter.count
|
||||
for (i in 0 until provCount) {
|
||||
if (provinceAdapter.getProvinceId(i) == provinceId) {
|
||||
binding.spinnerProvince.setSelection(i, false)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
Log.d(TAG, "onCreate: RegisterStoreActivity setup completed")
|
||||
// When cities arrive, select the city, then load subdistricts
|
||||
viewModel.citiesState.observe(this) { state ->
|
||||
if (state is Result.Success) {
|
||||
val cityCount = cityAdapter.count
|
||||
for (i in 0 until cityCount) {
|
||||
if (cityAdapter.getCityId(i) == cityId) {
|
||||
binding.spinnerCity.setSelection(i, false)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// When subdistricts arrive, select the subdistrict
|
||||
viewModel.subdistrictState.observe(this) { state ->
|
||||
if (state is Result.Success) {
|
||||
val subCount = subdistrictAdapter.count
|
||||
for (i in 0 until subCount) {
|
||||
if (subdistrictAdapter.getSubdistrictId(i) == subdistrictId) {
|
||||
binding.spinnerSubdistrict.setSelection(i, false)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun setupHeader() {
|
||||
@ -177,10 +320,11 @@ class RegisterStoreActivity : AppCompatActivity() {
|
||||
if (isFormValid) {
|
||||
binding.btnRegister.setBackgroundResource(R.drawable.bg_button_active)
|
||||
binding.btnRegister.setTextColor(ContextCompat.getColor(this, R.color.white))
|
||||
binding.btnRegister.isEnabled = true
|
||||
} else {
|
||||
binding.btnRegister.setBackgroundResource(R.drawable.bg_button_disabled)
|
||||
binding.btnRegister.setTextColor(ContextCompat.getColor(this, R.color.black_300))
|
||||
|
||||
binding.btnRegister.isEnabled = false
|
||||
}
|
||||
}
|
||||
|
||||
@ -848,6 +992,63 @@ class RegisterStoreActivity : AppCompatActivity() {
|
||||
}
|
||||
}
|
||||
|
||||
private fun doUpdateStoreProfile() {
|
||||
val nameBody: RequestBody = (viewModel.storeName.value ?: "")
|
||||
.toRequestBody("text/plain".toMediaTypeOrNull())
|
||||
val typeBody: RequestBody = ((viewModel.storeTypeId.value ?: 0).toString())
|
||||
.toRequestBody("text/plain".toMediaTypeOrNull())
|
||||
val descBody: RequestBody = (viewModel.storeDescription.value ?: "")
|
||||
.toRequestBody("text/plain".toMediaTypeOrNull())
|
||||
val onLeaveBody: RequestBody = "false"
|
||||
.toRequestBody("text/plain".toMediaTypeOrNull())
|
||||
|
||||
// --- Build Multipart for store image (optional) ---
|
||||
// Prefer compressing images to keep payload small; fall back to raw copy if needed.
|
||||
val storeImgPart: MultipartBody.Part? = viewModel.storeImageUri?.let { uri ->
|
||||
try {
|
||||
// (A) Optional safety check: only allow jpg/png/webp
|
||||
val allowed = Regex("^(jpg|jpeg|png|webp)$", RegexOption.IGNORE_CASE)
|
||||
if (!ImageUtils.isAllowedFileType(this, uri, allowed)) {
|
||||
Toast.makeText(this, "Format gambar tidak didukung", Toast.LENGTH_SHORT).show()
|
||||
null
|
||||
} else {
|
||||
// (B) Compress for upload (ke cacheDir), then build multipart
|
||||
val compressed: File = ImageUtils.compressImage(
|
||||
context = this,
|
||||
uri = uri,
|
||||
filename = "storeimg", // prefix
|
||||
maxWidth = 1024,
|
||||
maxHeight = 1024,
|
||||
quality = 80
|
||||
)
|
||||
FileUtils.createMultipartFromFile("storeimg", compressed)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
// If compression fails, try raw copy as fallback
|
||||
val rawFile = FileUtils.createTempFileFromUri(this, uri)
|
||||
rawFile?.let { FileUtils.createMultipartFromFile("storeimg", it) }
|
||||
}
|
||||
}
|
||||
|
||||
myStoreViewModel.updateStoreProfile(
|
||||
storeName = nameBody,
|
||||
storeType = typeBody,
|
||||
description = descBody,
|
||||
isOnLeave = onLeaveBody,
|
||||
storeImage = storeImgPart
|
||||
)
|
||||
|
||||
myStoreViewModel.updateStoreProfileResult.observe(this) {
|
||||
Toast.makeText(this, "Pengajuan ulang berhasil dikirim", Toast.LENGTH_SHORT).show()
|
||||
finish()
|
||||
}
|
||||
myStoreViewModel.errorMessage.observe(this) {
|
||||
if (!it.isNullOrEmpty()) {
|
||||
Toast.makeText(this, it, Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val TAG = "RegisterStoreActivity"
|
||||
}
|
||||
|
||||
@ -91,10 +91,10 @@ class DetailStoreProfileActivity : AppCompatActivity() {
|
||||
viewModel.fetchStoreTypes()
|
||||
|
||||
viewModel.myStoreProfile.observe(this) {
|
||||
currentStore = it
|
||||
currentStore = it?.store
|
||||
currentStoreLoaded = true
|
||||
if (storeTypesLoaded) setupStoreTypeSpinner(storeTypesList)
|
||||
updateUI(it)
|
||||
updateUI(it?.store)
|
||||
}
|
||||
|
||||
viewModel.storeTypes.observe(this) {
|
||||
|
||||
@ -10,6 +10,8 @@ import com.alya.ecommerce_serang.data.api.dto.ProductsItem
|
||||
import com.alya.ecommerce_serang.data.api.dto.Store
|
||||
import com.alya.ecommerce_serang.data.api.response.auth.StoreTypesItem
|
||||
import com.alya.ecommerce_serang.data.api.response.store.StoreResponse
|
||||
import com.alya.ecommerce_serang.data.api.response.store.profile.Payment
|
||||
import com.alya.ecommerce_serang.data.api.response.store.profile.Shipping
|
||||
import com.alya.ecommerce_serang.data.api.response.store.profile.StoreDataResponse
|
||||
import com.alya.ecommerce_serang.data.repository.MyStoreRepository
|
||||
import com.alya.ecommerce_serang.data.repository.Result
|
||||
@ -23,12 +25,18 @@ import java.util.Locale
|
||||
class MyStoreViewModel(private val repository: MyStoreRepository): ViewModel() {
|
||||
private var TAG = "MyStoreViewModel"
|
||||
|
||||
private val _myStoreProfile = MutableLiveData<Store?>()
|
||||
val myStoreProfile: LiveData<Store?> = _myStoreProfile
|
||||
private val _myStoreProfile = MutableLiveData<StoreResponse?>()
|
||||
val myStoreProfile: LiveData<StoreResponse?> = _myStoreProfile
|
||||
|
||||
private val _storeTypes = MutableLiveData<List<StoreTypesItem>>()
|
||||
val storeTypes: LiveData<List<StoreTypesItem>> = _storeTypes
|
||||
|
||||
private val _shipping = MutableLiveData<List<Shipping>>()
|
||||
val shipping: LiveData<List<Shipping>> = _shipping
|
||||
|
||||
private val _payment = MutableLiveData<List<Payment>>()
|
||||
val payment: LiveData<List<Payment>> = _payment
|
||||
|
||||
private val _isLoadingType = MutableLiveData<Boolean>()
|
||||
val isLoadingType: LiveData<Boolean> = _isLoadingType
|
||||
|
||||
@ -47,7 +55,12 @@ class MyStoreViewModel(private val repository: MyStoreRepository): ViewModel() {
|
||||
fun loadMyStore(){
|
||||
viewModelScope.launch {
|
||||
when (val result = repository.fetchMyStoreProfile()){
|
||||
is Result.Success -> _myStoreProfile.postValue(result.data)
|
||||
is Result.Success -> {
|
||||
val storeData = result.data
|
||||
_myStoreProfile.postValue(storeData)
|
||||
_shipping.postValue(storeData?.shipping)
|
||||
_payment.postValue(storeData?.payment)
|
||||
}
|
||||
is Result.Error -> _errorMessage.postValue(result.exception.message ?: "Unknown Error")
|
||||
is Result.Loading -> null
|
||||
}
|
||||
|
||||
BIN
app/src/main/res/drawable/ic_change_pass.png
Normal file
BIN
app/src/main/res/drawable/ic_change_pass.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 5.8 KiB |
102
app/src/main/res/layout/activity_change_password.xml
Normal file
102
app/src/main/res/layout/activity_change_password.xml
Normal file
@ -0,0 +1,102 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/main"
|
||||
android:fitsSystemWindows="true"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
tools:context=".ui.profile.ChangePasswordActivity">
|
||||
|
||||
<include
|
||||
android:id="@+id/headerStoreProduct"
|
||||
layout="@layout/header" />
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingHorizontal="32dp"
|
||||
android:paddingVertical="16dp">
|
||||
|
||||
<!-- Password label-->
|
||||
<TextView
|
||||
android:id="@+id/tv_password_label"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:fontFamily="@font/dmsans_medium"
|
||||
android:text="Kata Sandi Lama"
|
||||
android:textSize="18sp"
|
||||
android:layout_marginVertical="8dp"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent" />
|
||||
|
||||
<!-- Password input -->
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
android:id="@+id/til_login_password"
|
||||
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="12dp"
|
||||
app:passwordToggleEnabled="true"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/tv_password_label"
|
||||
app:layout_constraintEnd_toEndOf="parent">
|
||||
|
||||
<com.google.android.material.textfield.TextInputEditText
|
||||
android:id="@+id/et_login_password"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:hint="Masukkan kata sandi akun"
|
||||
android:inputType="textPassword" />
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
|
||||
<!-- Password label-->
|
||||
<TextView
|
||||
android:id="@+id/tv_new_password_label"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:fontFamily="@font/dmsans_medium"
|
||||
android:text="Kata Sandi Baru"
|
||||
android:textSize="18sp"
|
||||
android:layout_marginVertical="8dp"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/til_login_password"
|
||||
app:layout_constraintEnd_toEndOf="parent" />
|
||||
|
||||
<!-- Password input -->
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
android:id="@+id/til_login_new_password"
|
||||
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="12dp"
|
||||
app:passwordToggleEnabled="true"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/tv_new_password_label"
|
||||
app:layout_constraintEnd_toEndOf="parent">
|
||||
|
||||
<com.google.android.material.textfield.TextInputEditText
|
||||
android:id="@+id/et_login_new_password"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:hint="Masukkan kata sandi baru"
|
||||
android:inputType="textPassword" />
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
|
||||
<!-- Change Pass button -->
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/btn_change_pass"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Ubah Kata Sandi"
|
||||
app:cornerRadius="8dp"
|
||||
android:layout_marginVertical="16dp"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/til_login_new_password" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
</LinearLayout>
|
||||
@ -136,6 +136,7 @@
|
||||
android:id="@+id/tv_registrasi"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="5dp"
|
||||
android:text="@string/signup"
|
||||
android:textColor="@color/blue1"
|
||||
android:textStyle="bold" />
|
||||
|
||||
@ -69,6 +69,35 @@
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/layout_rejected"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:orientation="vertical"
|
||||
android:gravity="center"
|
||||
android:background="@drawable/bg_product_active"
|
||||
android:padding="8dp"
|
||||
android:visibility="gone">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
style="@style/label_small"
|
||||
android:textAlignment="center"
|
||||
android:text="Permintaan Buka Toko Anda sebelumnya ditolak! Silahkan lakukan penyesuaian berdasarkan alasan berikut:"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_rejected_reason"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
style="@style/body_medium"
|
||||
android:fontFamily="@font/dmsans_bold"
|
||||
android:layout_marginTop="8dp"
|
||||
android:text="KTP tidak sesuai"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<!-- Nama Toko -->
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
|
||||
@ -304,6 +304,55 @@
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
</androidx.cardview.widget.CardView>
|
||||
|
||||
<!-- Change Password Card -->
|
||||
<androidx.cardview.widget.CardView
|
||||
android:id="@+id/card_change_pass"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:foreground="?attr/selectableItemBackground"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
app:cardCornerRadius="8dp"
|
||||
app:cardElevation="2dp">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="16dp">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/ivChangePass"
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:src="@drawable/ic_change_pass"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvChangePass"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="16dp"
|
||||
android:text="Ubah Kata Sandi"
|
||||
android:textSize="14sp"
|
||||
app:layout_constraintStart_toEndOf="@id/ivChangePass"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@id/ivChangePassArrow" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/ivChangePassArrow"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:src="@drawable/ic_arrow_right"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
</androidx.cardview.widget.CardView>
|
||||
|
||||
<!-- About Card -->
|
||||
<androidx.cardview.widget.CardView
|
||||
android:id="@+id/card_about"
|
||||
|
||||
Reference in New Issue
Block a user