diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 6a794d7..5ce0012 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -29,6 +29,9 @@
android:theme="@style/Theme.Ecommerce_serang"
android:usesCleartextTraffic="true"
tools:targetApi="31">
+
@@ -64,7 +67,7 @@
+ android:exported="false" />
@@ -157,6 +160,7 @@
+
@@ -168,6 +172,4 @@
android:value="fcm_default_channel" />
-
-
\ No newline at end of file
diff --git a/app/src/main/java/com/alya/ecommerce_serang/data/api/response/auth/HasStoreResponse.kt b/app/src/main/java/com/alya/ecommerce_serang/data/api/response/auth/HasStoreResponse.kt
new file mode 100644
index 0000000..cd0a881
--- /dev/null
+++ b/app/src/main/java/com/alya/ecommerce_serang/data/api/response/auth/HasStoreResponse.kt
@@ -0,0 +1,9 @@
+package com.alya.ecommerce_serang.data.api.response.auth
+
+import com.google.gson.annotations.SerializedName
+
+data class HasStoreResponse(
+
+ @field:SerializedName("hasStore")
+ val hasStore: Boolean
+)
diff --git a/app/src/main/java/com/alya/ecommerce_serang/data/api/response/auth/ListStoreTypeResponse.kt b/app/src/main/java/com/alya/ecommerce_serang/data/api/response/auth/ListStoreTypeResponse.kt
new file mode 100644
index 0000000..c30af1f
--- /dev/null
+++ b/app/src/main/java/com/alya/ecommerce_serang/data/api/response/auth/ListStoreTypeResponse.kt
@@ -0,0 +1,21 @@
+package com.alya.ecommerce_serang.data.api.response.auth
+
+import com.google.gson.annotations.SerializedName
+
+data class ListStoreTypeResponse(
+
+ @field:SerializedName("storeTypes")
+ val storeTypes: List,
+
+ @field:SerializedName("message")
+ val message: String
+)
+
+data class StoreTypesItem(
+
+ @field:SerializedName("name")
+ val name: String,
+
+ @field:SerializedName("id")
+ val id: Int
+)
diff --git a/app/src/main/java/com/alya/ecommerce_serang/data/api/response/auth/RegisterStoreResponse.kt b/app/src/main/java/com/alya/ecommerce_serang/data/api/response/auth/RegisterStoreResponse.kt
new file mode 100644
index 0000000..973e594
--- /dev/null
+++ b/app/src/main/java/com/alya/ecommerce_serang/data/api/response/auth/RegisterStoreResponse.kt
@@ -0,0 +1,57 @@
+package com.alya.ecommerce_serang.data.api.response.auth
+
+import com.google.gson.annotations.SerializedName
+
+data class RegisterStoreResponse(
+
+ @field:SerializedName("store")
+ val store: Store,
+
+ @field:SerializedName("message")
+ val message: String
+)
+
+data class Store(
+
+ @field:SerializedName("image")
+ val image: String,
+
+ @field:SerializedName("ktp")
+ val ktp: String,
+
+ @field:SerializedName("nib")
+ val nib: String,
+
+ @field:SerializedName("npwp")
+ val npwp: String,
+
+ @field:SerializedName("address_id")
+ val addressId: Int,
+
+ @field:SerializedName("description")
+ val description: String,
+
+ @field:SerializedName("store_type_id")
+ val storeTypeId: Int,
+
+ @field:SerializedName("is_on_leave")
+ val isOnLeave: Boolean,
+
+ @field:SerializedName("balance")
+ val balance: String,
+
+ @field:SerializedName("user_id")
+ val userId: Int,
+
+ @field:SerializedName("name")
+ val name: String,
+
+ @field:SerializedName("persetujuan")
+ val persetujuan: String,
+
+ @field:SerializedName("id")
+ val id: Int,
+
+ @field:SerializedName("status")
+ val status: String
+)
diff --git a/app/src/main/java/com/alya/ecommerce_serang/data/api/retrofit/ApiService.kt b/app/src/main/java/com/alya/ecommerce_serang/data/api/retrofit/ApiService.kt
index 05322c5..3c67690 100644
--- a/app/src/main/java/com/alya/ecommerce_serang/data/api/retrofit/ApiService.kt
+++ b/app/src/main/java/com/alya/ecommerce_serang/data/api/retrofit/ApiService.kt
@@ -21,9 +21,12 @@ import com.alya.ecommerce_serang.data.api.dto.StoreAddressResponse
import com.alya.ecommerce_serang.data.api.dto.UpdateCart
import com.alya.ecommerce_serang.data.api.dto.UpdateChatRequest
import com.alya.ecommerce_serang.data.api.response.auth.CheckStoreResponse
+import com.alya.ecommerce_serang.data.api.response.auth.HasStoreResponse
+import com.alya.ecommerce_serang.data.api.response.auth.ListStoreTypeResponse
import com.alya.ecommerce_serang.data.api.response.auth.LoginResponse
import com.alya.ecommerce_serang.data.api.response.auth.OtpResponse
import com.alya.ecommerce_serang.data.api.response.auth.RegisterResponse
+import com.alya.ecommerce_serang.data.api.response.auth.RegisterStoreResponse
import com.alya.ecommerce_serang.data.api.response.chat.ChatHistoryResponse
import com.alya.ecommerce_serang.data.api.response.chat.ChatListResponse
import com.alya.ecommerce_serang.data.api.response.chat.SendChatResponse
@@ -73,6 +76,7 @@ import retrofit2.http.Multipart
import retrofit2.http.POST
import retrofit2.http.PUT
import retrofit2.http.Part
+import retrofit2.http.PartMap
import retrofit2.http.Path
import retrofit2.http.Query
@@ -85,17 +89,41 @@ interface ApiService {
@GET("checkstore")
suspend fun checkStore (): Response
-// @Multipart
-// @POST("registerstore")
-// suspend fun registerStore(
-//
-// ): Response<>
+ @Multipart
+ @POST("registerstore")
+ suspend fun registerStore(
+ @Part("description") description: RequestBody,
+ @Part("store_type_id") storeTypeId: RequestBody,
+ @Part("latitude") latitude: RequestBody,
+ @Part("longitude") longitude: RequestBody,
+ @Part("street") street: RequestBody,
+ @Part("subdistrict") subdistrict: RequestBody,
+ @Part("city_id") cityId: RequestBody,
+ @Part("province_id") provinceId: RequestBody,
+ @Part("postal_code") postalCode: RequestBody,
+ @Part("detail") detail: RequestBody,
+ @Part("bank_name") bankName: RequestBody,
+ @Part("bank_num") bankNum: RequestBody,
+ @Part("store_name") storeName: RequestBody,
+ @Part storeimg: MultipartBody.Part?,
+ @Part ktp: MultipartBody.Part?,
+ @Part npwp: MultipartBody.Part?,
+ @Part nib: MultipartBody.Part?,
+ @Part persetujuan: MultipartBody.Part?,
+ @PartMap couriers: Map,
+ @Part qris: MultipartBody.Part?,
+ @Part("account_name") accountName: RequestBody,
+ ): Response
@POST("otp")
suspend fun getOTP(
@Body otpRequest: OtpRequest
):OtpResponse
+ @GET("checkstore")
+ suspend fun checkStoreUser(
+ ): HasStoreResponse
+
@POST("login")
suspend fun login(
@Body loginRequest: LoginRequest
@@ -105,6 +133,10 @@ interface ApiService {
suspend fun allCategory(
): Response
+ @GET("storetype")
+ suspend fun listTypeStore(
+ ): Response
+
@GET("product")
suspend fun getAllProduct(): Response
diff --git a/app/src/main/java/com/alya/ecommerce_serang/data/repository/UserRepository.kt b/app/src/main/java/com/alya/ecommerce_serang/data/repository/UserRepository.kt
index ff202ee..8f16c34 100644
--- a/app/src/main/java/com/alya/ecommerce_serang/data/repository/UserRepository.kt
+++ b/app/src/main/java/com/alya/ecommerce_serang/data/repository/UserRepository.kt
@@ -7,13 +7,22 @@ import com.alya.ecommerce_serang.data.api.dto.LoginRequest
import com.alya.ecommerce_serang.data.api.dto.OtpRequest
import com.alya.ecommerce_serang.data.api.dto.RegisterRequest
import com.alya.ecommerce_serang.data.api.dto.UserProfile
+import com.alya.ecommerce_serang.data.api.response.auth.HasStoreResponse
+import com.alya.ecommerce_serang.data.api.response.auth.ListStoreTypeResponse
import com.alya.ecommerce_serang.data.api.response.auth.LoginResponse
import com.alya.ecommerce_serang.data.api.response.auth.OtpResponse
+import com.alya.ecommerce_serang.data.api.response.auth.RegisterStoreResponse
+import com.alya.ecommerce_serang.data.api.response.customer.order.ListCityResponse
+import com.alya.ecommerce_serang.data.api.response.customer.order.ListProvinceResponse
import com.alya.ecommerce_serang.data.api.response.customer.profile.EditProfileResponse
import com.alya.ecommerce_serang.data.api.retrofit.ApiService
import com.alya.ecommerce_serang.utils.FileUtils
import okhttp3.MediaType.Companion.toMediaTypeOrNull
+import okhttp3.MultipartBody
+import okhttp3.RequestBody
+import okhttp3.RequestBody.Companion.asRequestBody
import okhttp3.RequestBody.Companion.toRequestBody
+import java.io.File
class UserRepository(private val apiService: ApiService) {
//post data without message/response
@@ -21,6 +30,31 @@ class UserRepository(private val apiService: ApiService) {
return apiService.getOTP(OtpRequest(email))
}
+ suspend fun listStoreType(): Result{
+ return try{
+ val response = apiService.listTypeStore()
+ if (response.isSuccessful) {
+ response.body()?.let {
+ Result.Success(it)
+ } ?: Result.Error(Exception("No store type"))
+ } else {
+ throw Exception("No response ${response.errorBody()?.string()}")
+ }
+ } catch (e:Exception){
+ Result.Error(e)
+ }
+ }
+
+ suspend fun getListProvinces(): ListProvinceResponse? {
+ val response = apiService.getListProv()
+ return if (response.isSuccessful) response.body() else null
+ }
+
+ suspend fun getListCities(provId : Int): ListCityResponse? {
+ val response = apiService.getCityProvId(provId)
+ return if (response.isSuccessful) response.body() else null
+ }
+
suspend fun registerUser(request: RegisterRequest): String {
val response = apiService.register(request) // API call
@@ -32,6 +66,169 @@ class UserRepository(private val apiService: ApiService) {
}
}
+ suspend fun registerStoreUser(
+ context: Context,
+ description: String,
+ storeTypeId: Int,
+ latitude: String,
+ longitude: String,
+ street: String,
+ subdistrict: String,
+ cityId: Int,
+ provinceId: Int,
+ postalCode: Int,
+ detail: String?,
+ bankName: String,
+ bankNum: Int,
+ storeName: String,
+ storeImg: Uri?,
+ ktp: Uri?,
+ npwp: Uri?,
+ nib: Uri?,
+ persetujuan: Uri?,
+ couriers: List,
+ qris: Uri?,
+ accountName: String
+ ): Result {
+ return try {
+ val descriptionPart = description.toRequestBody("text/plain".toMediaTypeOrNull())
+ val storeTypeIdPart = storeTypeId.toString().toRequestBody("text/plain".toMediaTypeOrNull())
+ val latitudePart = latitude.toRequestBody("text/plain".toMediaTypeOrNull())
+ val longitudePart = longitude.toRequestBody("text/plain".toMediaTypeOrNull())
+ val streetPart = street.toRequestBody("text/plain".toMediaTypeOrNull())
+ val subdistrictPart = subdistrict.toRequestBody("text/plain".toMediaTypeOrNull())
+ val cityIdPart = cityId.toString().toRequestBody("text/plain".toMediaTypeOrNull())
+ val provinceIdPart = provinceId.toString().toRequestBody("text/plain".toMediaTypeOrNull())
+ val postalCodePart = postalCode.toString().toRequestBody("text/plain".toMediaTypeOrNull())
+ val detailPart = detail?.toRequestBody("text/plain".toMediaTypeOrNull())
+ val bankNamePart = bankName.toRequestBody("text/plain".toMediaTypeOrNull())
+ val bankNumPart = bankNum.toString().toRequestBody("text/plain".toMediaTypeOrNull())
+ val storeNamePart = storeName.toRequestBody("text/plain".toMediaTypeOrNull())
+ val accountNamePart = accountName.toRequestBody("text/plain".toMediaTypeOrNull())
+
+
+ // Create a Map for courier values
+ val courierMap = HashMap()
+ couriers.forEach { courier ->
+ courierMap["couriers[]"] = courier.toRequestBody("text/plain".toMediaTypeOrNull())
+ }
+
+ // Convert URIs to MultipartBody.Part
+ val storeImgPart = storeImg?.let {
+ val inputStream = context.contentResolver.openInputStream(it)
+ val file = File(context.cacheDir, "store_img_${System.currentTimeMillis()}")
+ inputStream?.use { input ->
+ file.outputStream().use { output ->
+ input.copyTo(output)
+ }
+ }
+ val mimeType = context.contentResolver.getType(it) ?: "application/octet-stream"
+ val requestFile = file.asRequestBody(mimeType.toMediaTypeOrNull())
+ MultipartBody.Part.createFormData("storeimg", file.name, requestFile)
+ }
+
+ val ktpPart = ktp?.let {
+ val inputStream = context.contentResolver.openInputStream(it)
+ val file = File(context.cacheDir, "ktp_${System.currentTimeMillis()}")
+ inputStream?.use { input ->
+ file.outputStream().use { output ->
+ input.copyTo(output)
+ }
+ }
+ val mimeType = context.contentResolver.getType(it) ?: "application/octet-stream"
+ val requestFile = file.asRequestBody(mimeType.toMediaTypeOrNull())
+ MultipartBody.Part.createFormData("ktp", file.name, requestFile)
+ }
+
+ val npwpPart = npwp?.let {
+ val inputStream = context.contentResolver.openInputStream(it)
+ val file = File(context.cacheDir, "npwp_${System.currentTimeMillis()}")
+ inputStream?.use { input ->
+ file.outputStream().use { output ->
+ input.copyTo(output)
+ }
+ }
+ val mimeType = context.contentResolver.getType(it) ?: "application/octet-stream"
+ val requestFile = file.asRequestBody(mimeType.toMediaTypeOrNull())
+ MultipartBody.Part.createFormData("npwp", file.name, requestFile)
+ }
+
+ val nibPart = nib?.let {
+ val inputStream = context.contentResolver.openInputStream(it)
+ val file = File(context.cacheDir, "nib_${System.currentTimeMillis()}")
+ inputStream?.use { input ->
+ file.outputStream().use { output ->
+ input.copyTo(output)
+ }
+ }
+ val mimeType = context.contentResolver.getType(it) ?: "application/octet-stream"
+ val requestFile = file.asRequestBody(mimeType.toMediaTypeOrNull())
+ MultipartBody.Part.createFormData("nib", file.name, requestFile)
+ }
+
+ val persetujuanPart = persetujuan?.let {
+ val inputStream = context.contentResolver.openInputStream(it)
+ val file = File(context.cacheDir, "persetujuan_${System.currentTimeMillis()}")
+ inputStream?.use { input ->
+ file.outputStream().use { output ->
+ input.copyTo(output)
+ }
+ }
+ val mimeType = context.contentResolver.getType(it) ?: "application/octet-stream"
+ val requestFile = file.asRequestBody(mimeType.toMediaTypeOrNull())
+ MultipartBody.Part.createFormData("persetujuan", file.name, requestFile)
+ }
+
+ val qrisPart = qris?.let {
+ val inputStream = context.contentResolver.openInputStream(it)
+ val file = File(context.cacheDir, "qris_${System.currentTimeMillis()}")
+ inputStream?.use { input ->
+ file.outputStream().use { output ->
+ input.copyTo(output)
+ }
+ }
+ val mimeType = context.contentResolver.getType(it) ?: "application/octet-stream"
+ val requestFile = file.asRequestBody(mimeType.toMediaTypeOrNull())
+ MultipartBody.Part.createFormData("qris", file.name, requestFile)
+ }
+
+ // Make the API call
+ val response = apiService.registerStore(
+ descriptionPart,
+ storeTypeIdPart,
+ latitudePart,
+ longitudePart,
+ streetPart,
+ subdistrictPart,
+ cityIdPart,
+ provinceIdPart,
+ postalCodePart,
+ detailPart ?: "".toRequestBody("text/plain".toMediaTypeOrNull()),
+ bankNamePart,
+ bankNumPart,
+ storeNamePart,
+ storeImgPart,
+ ktpPart,
+ npwpPart,
+ nibPart,
+ persetujuanPart,
+ courierMap,
+ qrisPart,
+ accountNamePart
+ )
+
+ // Check if response is successful
+ if (response.isSuccessful) {
+ Result.Success(response.body() ?: throw Exception("Response body is null"))
+ } else {
+ Result.Error(Exception("Registration failed with code: ${response.code()}"))
+ }
+
+ } catch (e: Exception) {
+ Result.Error(e)
+ }
+ }
+
suspend fun login(email: String, password: String): Result {
return try {
val response = apiService.login(LoginRequest(email, password))
@@ -130,6 +327,10 @@ class UserRepository(private val apiService: ApiService) {
Result.Error(e)
}
}
+
+ suspend fun checkStore(): HasStoreResponse{
+ return apiService.checkStoreUser()
+ }
companion object{
private const val TAG = "UserRepository"
diff --git a/app/src/main/java/com/alya/ecommerce_serang/ui/auth/RegisterStoreActivity.kt b/app/src/main/java/com/alya/ecommerce_serang/ui/auth/RegisterStoreActivity.kt
new file mode 100644
index 0000000..4cdfb77
--- /dev/null
+++ b/app/src/main/java/com/alya/ecommerce_serang/ui/auth/RegisterStoreActivity.kt
@@ -0,0 +1,601 @@
+package com.alya.ecommerce_serang.ui.auth
+
+import android.Manifest
+import android.app.Activity
+import android.content.Intent
+import android.content.pm.PackageManager
+import android.net.Uri
+import android.os.Bundle
+import android.provider.MediaStore
+import android.text.Editable
+import android.text.TextWatcher
+import android.util.Log
+import android.view.View
+import android.view.ViewGroup
+import android.widget.AdapterView
+import android.widget.ArrayAdapter
+import android.widget.ImageView
+import android.widget.LinearLayout
+import android.widget.TextView
+import android.widget.Toast
+import androidx.activity.enableEdgeToEdge
+import androidx.activity.viewModels
+import androidx.appcompat.app.AppCompatActivity
+import androidx.core.app.ActivityCompat
+import androidx.core.content.ContextCompat
+import androidx.core.view.ViewCompat
+import androidx.core.view.WindowCompat
+import androidx.core.view.WindowInsetsCompat
+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.Result
+import com.alya.ecommerce_serang.data.repository.UserRepository
+import com.alya.ecommerce_serang.databinding.ActivityRegisterStoreBinding
+import com.alya.ecommerce_serang.ui.order.address.CityAdapter
+import com.alya.ecommerce_serang.ui.order.address.ProvinceAdapter
+import com.alya.ecommerce_serang.utils.BaseViewModelFactory
+import com.alya.ecommerce_serang.utils.SessionManager
+
+class RegisterStoreActivity : AppCompatActivity() {
+
+ private lateinit var binding: ActivityRegisterStoreBinding
+ private lateinit var sessionManager: SessionManager
+
+ private lateinit var provinceAdapter: ProvinceAdapter
+ private lateinit var cityAdapter: CityAdapter
+ // Request codes for file picking
+ private val PICK_STORE_IMAGE_REQUEST = 1001
+ private val PICK_KTP_REQUEST = 1002
+ private val PICK_NPWP_REQUEST = 1003
+ private val PICK_NIB_REQUEST = 1004
+ private val PICK_PERSETUJUAN_REQUEST = 1005
+ private val PICK_QRIS_REQUEST = 1006
+
+ // Location request code
+ private val LOCATION_PERMISSION_REQUEST = 2001
+
+ private val viewModel: RegisterStoreViewModel by viewModels {
+ BaseViewModelFactory {
+ val apiService = ApiConfig.getApiService(sessionManager)
+ val orderRepository = UserRepository(apiService)
+ RegisterStoreViewModel(orderRepository)
+ }
+ }
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ binding = ActivityRegisterStoreBinding.inflate(layoutInflater)
+ setContentView(binding.root)
+
+ sessionManager = SessionManager(this)
+
+ WindowCompat.setDecorFitsSystemWindows(window, false)
+
+ enableEdgeToEdge()
+
+ // Apply insets to your root layout
+ ViewCompat.setOnApplyWindowInsetsListener(binding.root) { view, windowInsets ->
+ val systemBars = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars())
+ view.setPadding(
+ systemBars.left,
+ systemBars.top,
+ systemBars.right,
+ systemBars.bottom
+ )
+ windowInsets
+ }
+
+ provinceAdapter = ProvinceAdapter(this)
+ cityAdapter = CityAdapter(this)
+
+ setupDataBinding()
+ setupSpinners() // Location spinners
+
+ // Setup observers
+ setupStoreTypesObserver() // Store type observer
+ setupObservers()
+
+ setupMap()
+ setupDocumentUploads()
+ setupCourierSelection()
+
+ viewModel.fetchStoreTypes()
+ viewModel.getProvinces()
+
+
+ // Setup register button
+ 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 setupObservers() {
+ // Observe province state
+ viewModel.provincesState.observe(this) { state ->
+ when (state) {
+ is Result.Loading -> {
+ Log.d(TAG, "Loading provinces...")
+ binding.provinceProgressBar?.visibility = View.VISIBLE
+ binding.spinnerProvince.isEnabled = false
+ }
+ is Result.Success -> {
+ Log.d(TAG, "Provinces loaded: ${state.data.size}")
+ binding.provinceProgressBar?.visibility = View.GONE
+ binding.spinnerProvince.isEnabled = true
+
+ // Update adapter with data
+ provinceAdapter.updateData(state.data)
+ }
+ is Result.Error -> {
+// Log.e(TAG, "Error loading provinces: ${state.}")
+ binding.provinceProgressBar?.visibility = View.GONE
+ binding.spinnerProvince.isEnabled = true
+
+// Toast.makeText(this, "Gagal memuat provinsi: ${state.message}", Toast.LENGTH_SHORT).show()
+ }
+ }
+ }
+
+ // Observe city state
+ viewModel.citiesState.observe(this) { state ->
+ when (state) {
+ is Result.Loading -> {
+ Log.d(TAG, "Loading cities...")
+ binding.cityProgressBar?.visibility = View.VISIBLE
+ binding.spinnerCity.isEnabled = false
+ }
+ is Result.Success -> {
+ Log.d(TAG, "Cities loaded: ${state.data.size}")
+ binding.cityProgressBar?.visibility = View.GONE
+ binding.spinnerCity.isEnabled = true
+
+ // Update adapter with data
+ cityAdapter.updateData(state.data)
+ }
+ is Result.Error -> {
+// Log.e(TAG, "Error loading cities: ${state.message}")
+ binding.cityProgressBar?.visibility = View.GONE
+ binding.spinnerCity.isEnabled = true
+
+// Toast.makeText(this, "Gagal memuat kota: ${state.message}", Toast.LENGTH_SHORT).show()
+ }
+ }
+ }
+
+ // Observe registration state
+ viewModel.registerState.observe(this) { result ->
+ when (result) {
+ is Result.Loading -> {
+ showLoading(true)
+ }
+ is Result.Success -> {
+ showLoading(false)
+ Toast.makeText(this, "Toko berhasil didaftarkan", Toast.LENGTH_SHORT).show()
+ finish() // Return to previous screen
+ }
+ is Result.Error -> {
+ showLoading(false)
+ Toast.makeText(this, "Gagal mendaftarkan toko: ${result.exception.message}", Toast.LENGTH_SHORT).show()
+ }
+ }
+ }
+ }
+
+ private fun setupStoreTypesObserver() {
+ // Observe loading state
+ viewModel.isLoadingType.observe(this) { isLoading ->
+ if (isLoading) {
+ // Show loading indicator for store types spinner
+ binding.spinnerStoreType.isEnabled = false
+ binding.storeTypeProgressBar?.visibility = View.VISIBLE
+ } else {
+ binding.spinnerStoreType.isEnabled = true
+ binding.storeTypeProgressBar?.visibility = View.GONE
+ }
+ }
+
+ // Observe error messages
+ viewModel.errorMessage.observe(this) { errorMsg ->
+ if (errorMsg.isNotEmpty()) {
+ Toast.makeText(this, "Error loading store types: $errorMsg", Toast.LENGTH_SHORT).show()
+ }
+ }
+
+ // Observe store types data
+ viewModel.storeTypes.observe(this) { storeTypes ->
+ Log.d(TAG, "Store types loaded: ${storeTypes.size}")
+ if (storeTypes.isNotEmpty()) {
+ // Add "Pilih Jenis UMKM" as the first item if it's not already there
+ val displayList = if (storeTypes.any { it.name == "Pilih Jenis UMKM" || it.id == 0 }) {
+ storeTypes
+ } else {
+ val defaultItem = StoreTypesItem(name = "Pilih Jenis UMKM", id = 0)
+ listOf(defaultItem) + storeTypes
+ }
+
+ // Setup spinner with API data
+ setupStoreTypeSpinner(displayList)
+ }
+ }
+ }
+
+ private fun setupStoreTypeSpinner(storeTypes: List) {
+ Log.d(TAG, "Setting up store type spinner with ${storeTypes.size} items")
+
+ // Create a custom adapter to display just the name but hold the whole object
+ val adapter = object : ArrayAdapter(
+ this,
+ android.R.layout.simple_spinner_item,
+ storeTypes
+ ) {
+ override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
+ val view = super.getView(position, convertView, parent)
+ (view as TextView).text = getItem(position)?.name ?: ""
+ return view
+ }
+
+ override fun getDropDownView(position: Int, convertView: View?, parent: ViewGroup): View {
+ val view = super.getDropDownView(position, convertView, parent)
+ (view as TextView).text = getItem(position)?.name ?: ""
+ return view
+ }
+
+ // Override toString to ensure proper display
+ override fun getItem(position: Int): StoreTypesItem? {
+ return super.getItem(position)
+ }
+ }
+
+ adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
+
+ // Set adapter to spinner
+ binding.spinnerStoreType.adapter = adapter
+
+ // Set item selection listener
+ binding.spinnerStoreType.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
+ override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
+ val selectedItem = adapter.getItem(position)
+ Log.d(TAG, "Store type selected: position=$position, item=${selectedItem?.name}, id=${selectedItem?.id}")
+
+ if (selectedItem != null && selectedItem.id > 0) {
+ // Store the actual ID from the API, not just position
+ viewModel.storeTypeId.value = selectedItem.id
+ Log.d(TAG, "Set storeTypeId to ${selectedItem.id}")
+ }
+ }
+
+ override fun onNothingSelected(parent: AdapterView<*>?) {
+ Log.d(TAG, "No store type selected")
+ }
+ }
+
+ // Hide progress bar after setup
+ binding.storeTypeProgressBar?.visibility = View.GONE
+ }
+
+ private fun setupSpinners() {
+ // Setup province spinner
+ binding.spinnerProvince.adapter = provinceAdapter
+ binding.spinnerProvince.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
+ override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
+ Log.d(TAG, "Province selected at position: $position")
+ val provinceId = provinceAdapter.getProvinceId(position)
+ if (provinceId != null) {
+ Log.d(TAG, "Setting province ID: $provinceId")
+ viewModel.provinceId.value = provinceId
+ viewModel.getCities(provinceId)
+
+ // Reset city selection when province changes
+ cityAdapter.clear()
+ binding.spinnerCity.setSelection(0)
+ } else {
+ Log.e(TAG, "Invalid province ID for position: $position")
+ }
+ }
+
+ override fun onNothingSelected(parent: AdapterView<*>?) {
+ // Do nothing
+ }
+ }
+
+ // Setup city spinner
+ binding.spinnerCity.adapter = cityAdapter
+ binding.spinnerCity.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
+ override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
+ Log.d(TAG, "City selected at position: $position")
+ val cityId = cityAdapter.getCityId(position)
+ if (cityId != null) {
+ Log.d(TAG, "Setting city ID: $cityId")
+ viewModel.cityId.value = cityId
+ viewModel.selectedCityId = cityId
+ } else {
+ Log.e(TAG, "Invalid city ID for position: $position")
+ }
+ }
+
+ override fun onNothingSelected(parent: AdapterView<*>?) {
+ // Do nothing
+ }
+ }
+
+ // Add initial hints to the spinners
+ if (provinceAdapter.isEmpty) {
+ provinceAdapter.add("Pilih Provinsi")
+ }
+
+ if (cityAdapter.isEmpty) {
+ cityAdapter.add("Pilih Kabupaten/Kota")
+ }
+ }
+
+// private fun setupSubdistrictSpinner(cityId: Int) {
+// // This would typically be populated from API based on cityId
+// val subdistricts = listOf("Pilih Kecamatan", "Kecamatan 1", "Kecamatan 2", "Kecamatan 3")
+// val subdistrictAdapter = ArrayAdapter(this, R.layout.simple_spinner_dropdown_item, subdistricts)
+// binding.spinnerSubdistrict.adapter = subdistrictAdapter
+// binding.spinnerSubdistrict.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
+// override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
+// if (position > 0) {
+// viewModel.subdistrict.value = subdistricts[position]
+// }
+// }
+// override fun onNothingSelected(parent: AdapterView<*>?) {}
+// }
+// }
+
+ private fun setupDocumentUploads() {
+ // Store Image
+ binding.containerStoreImg.setOnClickListener {
+ pickImage(PICK_STORE_IMAGE_REQUEST)
+ }
+
+ // KTP
+ binding.containerKtp.setOnClickListener {
+ pickImage(PICK_KTP_REQUEST)
+ }
+
+ // NIB
+ binding.containerNib.setOnClickListener {
+ pickDocument(PICK_NIB_REQUEST)
+ }
+
+ // NPWP
+ binding.containerNpwp?.setOnClickListener {
+ pickImage(PICK_NPWP_REQUEST)
+ }
+
+ // SPPIRT
+ binding.containerSppirt.setOnClickListener {
+ pickDocument(PICK_PERSETUJUAN_REQUEST)
+ }
+
+ // Halal
+ binding.containerHalal.setOnClickListener {
+ pickDocument(PICK_QRIS_REQUEST)
+ }
+ }
+
+ private fun pickImage(requestCode: Int) {
+ val intent = Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI)
+ startActivityForResult(intent, requestCode)
+ }
+
+ private fun pickDocument(requestCode: Int) {
+ val intent = Intent(Intent.ACTION_OPEN_DOCUMENT)
+ intent.addCategory(Intent.CATEGORY_OPENABLE)
+ intent.type = "*/*"
+ val mimeTypes = arrayOf("application/pdf", "image/jpeg", "image/png")
+ intent.putExtra(Intent.EXTRA_MIME_TYPES, mimeTypes)
+ startActivityForResult(intent, requestCode)
+ }
+
+ private fun setupCourierSelection() {
+ binding.checkboxJne.setOnCheckedChangeListener { _, isChecked ->
+ handleCourierSelection("jne", isChecked)
+ }
+
+ binding.checkboxJnt.setOnCheckedChangeListener { _, isChecked ->
+ handleCourierSelection("jnt", isChecked)
+ }
+
+ binding.checkboxPos.setOnCheckedChangeListener { _, isChecked ->
+ handleCourierSelection("pos", isChecked)
+ }
+ }
+
+ private fun handleCourierSelection(courier: String, isSelected: Boolean) {
+ if (isSelected) {
+ if (!viewModel.selectedCouriers.contains(courier)) {
+ viewModel.selectedCouriers.add(courier)
+ }
+ } else {
+ viewModel.selectedCouriers.remove(courier)
+ }
+ }
+
+ private fun setupMap() {
+ // This would typically integrate with Google Maps SDK
+ // For simplicity, we're just using a placeholder
+ binding.mapContainer.setOnClickListener {
+ // Request location permission if not granted
+ if (ContextCompat.checkSelfPermission(
+ this,
+ Manifest.permission.ACCESS_FINE_LOCATION
+ ) != PackageManager.PERMISSION_GRANTED
+ ) {
+ ActivityCompat.requestPermissions(
+ this,
+ arrayOf(Manifest.permission.ACCESS_FINE_LOCATION),
+ LOCATION_PERMISSION_REQUEST
+
+ )
+ viewModel.latitude.value = "-6.2088"
+ viewModel.longitude.value = "106.8456"
+ Toast.makeText(this, "Lokasi dipilih", Toast.LENGTH_SHORT).show()
+ } else {
+ // Show map selection UI
+ // This would typically launch Maps UI for location selection
+ // For now, we'll just set some dummy coordinates
+ viewModel.latitude.value = "-6.2088"
+ viewModel.longitude.value = "106.8456"
+ Toast.makeText(this, "Lokasi dipilih", Toast.LENGTH_SHORT).show()
+ }
+ }
+ }
+
+ private fun setupDataBinding() {
+ // Two-way data binding for text fields
+ binding.etStoreName.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.storeName.value = s.toString()
+ }
+ })
+
+ binding.etStoreDescription.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.storeDescription.value = s.toString()
+ }
+ })
+
+ binding.etStreet.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.street.value = s.toString()
+ }
+ })
+
+ binding.etPostalCode.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?) {
+ try {
+ viewModel.postalCode.value = s.toString().toInt()
+ } catch (e: NumberFormatException) {
+ // Handle invalid input
+ //show toast
+ }
+ }
+ })
+
+ binding.etAddressDetail.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.addressDetail.value = s.toString()
+ }
+ })
+
+ binding.etBankNumber.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.bankNumber.value = s.toString().toInt()
+ }
+ })
+
+ 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()
+ }
+ })
+ }
+
+ override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
+ super.onActivityResult(requestCode, resultCode, data)
+ if (resultCode == Activity.RESULT_OK && data != null) {
+ val uri = data.data
+ when (requestCode) {
+ PICK_STORE_IMAGE_REQUEST -> {
+ viewModel.storeImageUri = uri
+ updateImagePreview(uri, binding.imgStore, binding.layoutUploadStoreImg)
+ }
+ PICK_KTP_REQUEST -> {
+ viewModel.ktpUri = uri
+ updateImagePreview(uri, binding.imgKtp, binding.layoutUploadKtp)
+ }
+ PICK_NPWP_REQUEST -> {
+ viewModel.npwpUri = uri
+ updateDocumentPreview(binding.layoutUploadNpwp)
+ }
+ PICK_NIB_REQUEST -> {
+ viewModel.nibUri = uri
+ updateDocumentPreview(binding.layoutUploadNib)
+ }
+ PICK_PERSETUJUAN_REQUEST -> {
+ viewModel.persetujuanUri = uri
+ updateDocumentPreview(binding.layoutUploadSppirt)
+ }
+ PICK_QRIS_REQUEST -> {
+ viewModel.qrisUri = uri
+ updateDocumentPreview(binding.layoutUploadHalal)
+ }
+ }
+ }
+ }
+
+ private fun updateImagePreview(uri: Uri?, imageView: ImageView, uploadLayout: LinearLayout) {
+ uri?.let {
+ imageView.setImageURI(it)
+ imageView.visibility = View.VISIBLE
+ uploadLayout.visibility = View.GONE
+ }
+ }
+
+ private fun updateDocumentPreview(uploadLayout: LinearLayout) {
+ // For documents, we just show a success indicator
+ val checkIcon = ImageView(this)
+ checkIcon.setImageResource(android.R.drawable.ic_menu_gallery)
+ val successText = TextView(this)
+ successText.text = "Dokumen berhasil diunggah"
+
+ uploadLayout.removeAllViews()
+ uploadLayout.addView(checkIcon)
+ uploadLayout.addView(successText)
+ }
+
+ //later implement get location form gps
+ override fun onRequestPermissionsResult(
+ requestCode: Int,
+ permissions: Array,
+ grantResults: IntArray
+ ) {
+ super.onRequestPermissionsResult(requestCode, permissions, grantResults)
+ if (requestCode == LOCATION_PERMISSION_REQUEST) {
+ if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
+ // Permission granted, proceed with location selection
+ viewModel.latitude.value = "-6.2088"
+ viewModel.longitude.value = "106.8456"
+ Toast.makeText(this, "Lokasi dipilih", Toast.LENGTH_SHORT).show()
+ } else {
+ viewModel.latitude.value = "-6.2088"
+ viewModel.longitude.value = "106.8456"
+ }
+ }
+ }
+
+ private fun showLoading(isLoading: Boolean) {
+ if (isLoading) {
+ // Show loading indicator
+ binding.btnRegister.isEnabled = false
+ binding.btnRegister.text = "Mendaftar..."
+ } else {
+ // Hide loading indicator
+ binding.btnRegister.isEnabled = true
+ binding.btnRegister.text = "Daftar"
+ }
+ }
+
+ companion object {
+ private const val TAG = "RegisterStoreActivity"
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/alya/ecommerce_serang/ui/auth/RegisterStoreViewModel.kt b/app/src/main/java/com/alya/ecommerce_serang/ui/auth/RegisterStoreViewModel.kt
new file mode 100644
index 0000000..41bfbf1
--- /dev/null
+++ b/app/src/main/java/com/alya/ecommerce_serang/ui/auth/RegisterStoreViewModel.kt
@@ -0,0 +1,202 @@
+package com.alya.ecommerce_serang.ui.auth
+
+import android.content.Context
+import android.net.Uri
+import android.util.Log
+import androidx.lifecycle.LiveData
+import androidx.lifecycle.MutableLiveData
+import androidx.lifecycle.ViewModel
+import androidx.lifecycle.viewModelScope
+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.repository.Result
+import com.alya.ecommerce_serang.data.repository.UserRepository
+import kotlinx.coroutines.launch
+
+class RegisterStoreViewModel(
+ private val repository: UserRepository
+) : ViewModel() {
+
+ // LiveData for UI state
+ private val _registerState = MutableLiveData>()
+ val registerState: LiveData> = _registerState
+
+ private val _storeTypes = MutableLiveData>()
+ val storeTypes: LiveData> = _storeTypes
+
+ // LiveData for error messages
+ private val _errorMessage = MutableLiveData()
+ val errorMessage: LiveData = _errorMessage
+
+ // LiveData for loading state
+ private val _isLoadingType = MutableLiveData()
+ val isLoadingType: LiveData = _isLoadingType
+
+ private val _provincesState = MutableLiveData>>()
+ val provincesState: LiveData>> = _provincesState
+
+ private val _citiesState = MutableLiveData>>()
+ val citiesState: LiveData>> = _citiesState
+
+ var selectedProvinceId: Int? = null
+ var selectedCityId: Int? = null
+
+ // Form fields
+ val storeName = MutableLiveData()
+ val storeDescription = MutableLiveData()
+ val storeTypeId = MutableLiveData()
+ val latitude = MutableLiveData()
+ val longitude = MutableLiveData()
+ val street = MutableLiveData()
+ val subdistrict = MutableLiveData()
+ val cityId = MutableLiveData()
+ val provinceId = MutableLiveData()
+ val postalCode = MutableLiveData()
+ val addressDetail = MutableLiveData()
+ val bankName = MutableLiveData()
+ val bankNumber = MutableLiveData()
+ val accountName = MutableLiveData()
+
+ // Files
+ var storeImageUri: Uri? = null
+ var ktpUri: Uri? = null
+ var npwpUri: Uri? = null
+ var nibUri: Uri? = null
+ var persetujuanUri: Uri? = null
+ var qrisUri: Uri? = null
+
+ // Selected couriers
+ val selectedCouriers = mutableListOf()
+
+ fun registerStore(context: Context) {
+ viewModelScope.launch {
+ try {
+ _registerState.value = Result.Loading
+
+ val result = repository.registerStoreUser(
+ context = context,
+ description = storeDescription.value ?: "",
+ storeTypeId = storeTypeId.value ?: 0,
+ latitude = latitude.value ?: "",
+ longitude = longitude.value ?: "",
+ street = street.value ?: "",
+ subdistrict = subdistrict.value ?: "",
+ cityId = cityId.value ?: 0,
+ provinceId = provinceId.value ?: 0,
+ postalCode = postalCode.value ?: 0,
+ detail = addressDetail.value,
+ bankName = bankName.value ?: "",
+ bankNum = bankNumber.value ?: 0,
+ storeName = storeName.value ?: "",
+ storeImg = storeImageUri,
+ ktp = ktpUri,
+ npwp = npwpUri,
+ nib = nibUri,
+ persetujuan = persetujuanUri,
+ couriers = selectedCouriers,
+ qris = qrisUri,
+ accountName = accountName.value ?: ""
+ )
+
+ _registerState.value = result
+ } catch (e: Exception) {
+ _registerState.value = com.alya.ecommerce_serang.data.repository.Result.Error(e)
+ }
+ }
+ }
+
+// // Helper function to convert Uri to File
+// private fun getFileFromUri(context: Context, uri: Uri): File {
+// val inputStream = context.contentResolver.openInputStream(uri)
+// val tempFile = File(context.cacheDir, "temp_file_${System.currentTimeMillis()}")
+// inputStream?.use { input ->
+// tempFile.outputStream().use { output ->
+// input.copyTo(output)
+// }
+// }
+// return tempFile
+// }
+
+ fun validateForm(): Boolean {
+ // Implement form validation logic
+ return !(storeName.value.isNullOrEmpty() ||
+ storeTypeId.value == null ||
+ street.value.isNullOrEmpty() ||
+ subdistrict.value.isNullOrEmpty() ||
+ cityId.value == null ||
+ provinceId.value == null ||
+ postalCode.value == null ||
+ bankName.value.isNullOrEmpty() ||
+ bankNumber.value == null ||
+ selectedCouriers.isEmpty() ||
+ ktpUri == null ||
+ nibUri == null)
+ }
+
+
+
+ // Function to fetch store types
+ fun fetchStoreTypes() {
+ _isLoadingType.value = true
+ viewModelScope.launch {
+ when (val result = repository.listStoreType()) {
+ is Result.Success -> {
+ _storeTypes.value = result.data.storeTypes
+ _isLoadingType.value = false
+ }
+ is Result.Error -> {
+ _errorMessage.value = result.exception.message ?: "Unknown error occurred"
+ _isLoadingType.value = false
+ }
+ is Result.Loading -> {
+ _isLoadingType.value = true
+ }
+ }
+ }
+ }
+
+ fun getProvinces() {
+ _provincesState.value = Result.Loading
+ viewModelScope.launch {
+ try {
+ val result = repository.getListProvinces()
+ if (result?.provinces != null) {
+ _provincesState.postValue(Result.Success(result.provinces))
+ Log.d(TAG, "Provinces loaded: ${result.provinces.size}")
+ } else {
+ _provincesState.postValue(Result.Error(Exception("Failed to load provinces")))
+ Log.e(TAG, "Province result was null or empty")
+ }
+ } catch (e: Exception) {
+ _provincesState.postValue(Result.Error(Exception(e.message ?: "Error loading provinces")))
+ Log.e(TAG, "Error fetching provinces", e)
+ }
+ }
+ }
+
+ fun getCities(provinceId: Int){
+ _citiesState.value = Result.Loading
+ viewModelScope.launch {
+ try {
+ selectedProvinceId = provinceId
+ val result = repository.getListCities(provinceId)
+ result?.let {
+ _citiesState.postValue(Result.Success(it.cities))
+ Log.d(TAG, "Cities loaded for province $provinceId: ${it.cities.size}")
+ } ?: run {
+ _citiesState.postValue(Result.Error(Exception("Failed to load cities")))
+ Log.e(TAG, "City result was null for province $provinceId")
+ }
+ } catch (e: Exception) {
+ _citiesState.postValue(Result.Error(Exception(e.message ?: "Error loading cities")))
+ Log.e(TAG, "Error fetching cities for province $provinceId", e)
+ }
+ }
+ }
+
+ companion object {
+ private const val TAG = "RegisterStoreUserViewModel"
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/alya/ecommerce_serang/ui/profile/ProfileFragment.kt b/app/src/main/java/com/alya/ecommerce_serang/ui/profile/ProfileFragment.kt
index d1921f9..959175f 100644
--- a/app/src/main/java/com/alya/ecommerce_serang/ui/profile/ProfileFragment.kt
+++ b/app/src/main/java/com/alya/ecommerce_serang/ui/profile/ProfileFragment.kt
@@ -15,6 +15,7 @@ import com.alya.ecommerce_serang.data.api.dto.UserProfile
import com.alya.ecommerce_serang.data.api.retrofit.ApiConfig
import com.alya.ecommerce_serang.data.repository.UserRepository
import com.alya.ecommerce_serang.databinding.FragmentProfileBinding
+import com.alya.ecommerce_serang.ui.auth.RegisterStoreActivity
import com.alya.ecommerce_serang.ui.order.history.HistoryActivity
import com.alya.ecommerce_serang.ui.profile.mystore.MyStoreActivity
import com.alya.ecommerce_serang.utils.BaseViewModelFactory
@@ -53,10 +54,21 @@ class ProfileFragment : Fragment() {
super.onViewCreated(view, savedInstanceState)
observeUserProfile()
viewModel.loadUserProfile()
+ viewModel.checkStoreUser()
binding.cardBukaToko.setOnClickListener{
- val intentBuka = Intent(requireContext(), MyStoreActivity::class.java)
- startActivity(intentBuka)
+ val hasStore = viewModel.checkStore.value
+// val hasStore = false
+
+ Log.d("Profile Fragment", "Check store $hasStore")
+
+ if (hasStore == true){
+ val intentBuka = Intent(requireContext(), MyStoreActivity::class.java)
+ startActivity(intentBuka)
+ } else {
+ val intentBuka = Intent(requireContext(), RegisterStoreActivity::class.java)
+ startActivity(intentBuka)
+ }
}
binding.btnDetailProfile.setOnClickListener{
diff --git a/app/src/main/java/com/alya/ecommerce_serang/utils/viewmodel/ProfileViewModel.kt b/app/src/main/java/com/alya/ecommerce_serang/utils/viewmodel/ProfileViewModel.kt
index 3a08b14..21347a2 100644
--- a/app/src/main/java/com/alya/ecommerce_serang/utils/viewmodel/ProfileViewModel.kt
+++ b/app/src/main/java/com/alya/ecommerce_serang/utils/viewmodel/ProfileViewModel.kt
@@ -8,6 +8,7 @@ import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.alya.ecommerce_serang.data.api.dto.UserProfile
+import com.alya.ecommerce_serang.data.api.response.auth.HasStoreResponse
import com.alya.ecommerce_serang.data.api.response.customer.profile.EditProfileResponse
import com.alya.ecommerce_serang.data.repository.Result
import com.alya.ecommerce_serang.data.repository.UserRepository
@@ -23,6 +24,9 @@ class ProfileViewModel(private val userRepository: UserRepository) : ViewModel()
private val _editProfileResult = MutableLiveData>()
val editProfileResult: LiveData> = _editProfileResult
+ private val _checkStore = MutableLiveData()
+ val checkStore: LiveData = _checkStore
+
fun loadUserProfile(){
viewModelScope.launch {
when (val result = userRepository.fetchUserProfile()){
@@ -33,6 +37,28 @@ class ProfileViewModel(private val userRepository: UserRepository) : ViewModel()
}
}
+ fun checkStoreUser(){
+ viewModelScope.launch {
+ try {
+ // Call the repository function to request OTP
+ val response: HasStoreResponse = userRepository.checkStore()
+
+ // Log and store success message
+ Log.d("RegisterViewModel", "OTP Response: ${response.hasStore}")
+ _checkStore.value = response.hasStore // Store the message for UI feedback
+
+ } catch (exception: Exception) {
+ // Handle any errors and update state
+ _checkStore.value = false
+
+ // Log the error for debugging
+ Log.e("RegisterViewModel", "Error:", exception)
+ }
+ }
+ }
+
+
+
fun editProfileDirect(
context: Context,
username: String,
diff --git a/app/src/main/res/layout/activity_register_store.xml b/app/src/main/res/layout/activity_register_store.xml
new file mode 100644
index 0000000..f84430b
--- /dev/null
+++ b/app/src/main/res/layout/activity_register_store.xml
@@ -0,0 +1,578 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file