mirror of
https://github.com/shaulascr/ecommerce_serang.git
synced 2025-08-10 09:22:21 +00:00
add product
This commit is contained in:
2
.idea/gradle.xml
generated
2
.idea/gradle.xml
generated
@ -6,7 +6,7 @@
|
||||
<GradleProjectSettings>
|
||||
<option name="testRunner" value="CHOOSE_PER_TEST" />
|
||||
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
||||
<option name="gradleJvm" value="jbr-21" />
|
||||
<option name="gradleJvm" value="openjdk-24" />
|
||||
<option name="modules">
|
||||
<set>
|
||||
<option value="$PROJECT_DIR$" />
|
||||
|
3
.idea/misc.xml
generated
3
.idea/misc.xml
generated
@ -1,9 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="CodeInsightWorkspaceSettings">
|
||||
<option name="optimizeImportsOnTheFly" value="true" />
|
||||
</component>
|
||||
<component name="ExternalStorageConfigurationManager" enabled="true" />
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_21" default="true" project-jdk-name="jbr-21" project-jdk-type="JavaSDK">
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_X" default="true" project-jdk-name="24" project-jdk-type="JavaSDK">
|
||||
<output url="file://$PROJECT_DIR$/build/classes" />
|
||||
</component>
|
||||
<component name="ProjectType">
|
||||
|
@ -48,7 +48,7 @@
|
||||
android:name=".ui.profile.mystore.balance.BalanceTopUpActivity"
|
||||
android:exported="false" />
|
||||
<activity
|
||||
android:name=".ui.profile.mystore.product.AddProductActivity"
|
||||
android:name=".ui.profile.mystore.product.StoreProductDetailActivity"
|
||||
android:exported="false" />
|
||||
<activity
|
||||
android:name=".ui.profile.mystore.profile.DetailStoreProfileActivity"
|
||||
|
@ -0,0 +1,54 @@
|
||||
package com.alya.ecommerce_serang.data.api.dto
|
||||
|
||||
import com.google.gson.annotations.SerializedName
|
||||
|
||||
data class Product(
|
||||
|
||||
@field:SerializedName("store_id")
|
||||
val storeId: Int? = null,
|
||||
|
||||
@field:SerializedName("image")
|
||||
val image: String? = null,
|
||||
|
||||
@field:SerializedName("sppirt")
|
||||
val sppirt: String? = null,
|
||||
|
||||
@field:SerializedName("rating")
|
||||
val rating: String? = null,
|
||||
|
||||
@field:SerializedName("description")
|
||||
val description: String? = null,
|
||||
|
||||
@field:SerializedName("weight")
|
||||
val weight: Int? = null,
|
||||
|
||||
@field:SerializedName("is_pre_order")
|
||||
val isPreOrder: Boolean? = null,
|
||||
|
||||
@field:SerializedName("category_id")
|
||||
val categoryId: Int? = null,
|
||||
|
||||
@field:SerializedName("price")
|
||||
val price: String? = null,
|
||||
|
||||
@field:SerializedName("name")
|
||||
val name: String? = null,
|
||||
|
||||
@field:SerializedName("halal")
|
||||
val halal: String? = null,
|
||||
|
||||
@field:SerializedName("id")
|
||||
val id: Int? = null,
|
||||
|
||||
@field:SerializedName("min_order")
|
||||
val minOrder: Int? = null,
|
||||
|
||||
@field:SerializedName("total_sold")
|
||||
val totalSold: Int? = null,
|
||||
|
||||
@field:SerializedName("stock")
|
||||
val stock: Int? = null,
|
||||
|
||||
@field:SerializedName("status")
|
||||
val status: String? = null
|
||||
)
|
@ -0,0 +1,27 @@
|
||||
package com.alya.ecommerce_serang.data.api.response
|
||||
|
||||
import com.google.gson.annotations.SerializedName
|
||||
|
||||
data class CreateProductResponse(
|
||||
|
||||
@field:SerializedName("product")
|
||||
val product: Product? = null,
|
||||
|
||||
@field:SerializedName("message")
|
||||
val message: String? = null,
|
||||
|
||||
@field:SerializedName("preorder")
|
||||
val preorder: Preorder? = null
|
||||
)
|
||||
|
||||
data class Preorder(
|
||||
|
||||
@field:SerializedName("duration")
|
||||
val duration: Int? = null,
|
||||
|
||||
@field:SerializedName("product_id")
|
||||
val productId: Int? = null,
|
||||
|
||||
@field:SerializedName("id")
|
||||
val id: Int? = null
|
||||
)
|
@ -17,6 +17,8 @@ import com.alya.ecommerce_serang.data.api.response.ViewStoreProductsResponse
|
||||
import retrofit2.Call
|
||||
import retrofit2.Response
|
||||
import retrofit2.http.Body
|
||||
import retrofit2.http.Field
|
||||
import retrofit2.http.FormUrlEncoded
|
||||
import retrofit2.http.GET
|
||||
import retrofit2.http.POST
|
||||
import retrofit2.http.Path
|
||||
@ -69,4 +71,22 @@ interface ApiService {
|
||||
@GET("mystore/product") // Replace with actual endpoint
|
||||
suspend fun getStoreProduct(): Response<ViewStoreProductsResponse>
|
||||
|
||||
@GET("category")
|
||||
fun getCategories(): Call<CategoryResponse>
|
||||
|
||||
@POST("store/createproduct")
|
||||
@FormUrlEncoded
|
||||
suspend fun addProduct(
|
||||
@Field("name") name: String,
|
||||
@Field("description") description: String,
|
||||
@Field("price") price: Int,
|
||||
@Field("stock") stock: Int,
|
||||
@Field("min_order") minOrder: Int,
|
||||
@Field("weight") weight: Int,
|
||||
@Field("is_pre_order") isPreOrder: Boolean,
|
||||
@Field("duration") duration: Int,
|
||||
@Field("category_id") categoryId: Int,
|
||||
@Field("is_active") isActive: String
|
||||
): Response<Unit>
|
||||
|
||||
}
|
@ -89,6 +89,44 @@ class ProductRepository(private val apiService: ApiService) {
|
||||
throw Exception("Failed to fetch store products: ${response.message()}")
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun addProduct(
|
||||
name: String,
|
||||
description: String,
|
||||
price: Int,
|
||||
stock: Int,
|
||||
minOrder: Int,
|
||||
weight: Int,
|
||||
isPreOrder: Boolean,
|
||||
duration: Int,
|
||||
categoryId: Int,
|
||||
isActive: Boolean
|
||||
): Result<Unit> = withContext(Dispatchers.IO) {
|
||||
try {
|
||||
val status = if (isActive) "active" else "inactive"
|
||||
val response = apiService.addProduct(
|
||||
name = name,
|
||||
description = description,
|
||||
price = price,
|
||||
stock = stock,
|
||||
minOrder = minOrder,
|
||||
weight = weight,
|
||||
isPreOrder = isPreOrder,
|
||||
duration = duration,
|
||||
categoryId = categoryId,
|
||||
isActive = status
|
||||
)
|
||||
|
||||
if (response.isSuccessful) {
|
||||
Result.Success(Unit)
|
||||
} else {
|
||||
Result.Error(Exception("Failed to add product. Code: ${response.code()}"))
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Result.Error(e)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// suspend fun fetchStoreDetail(storeId: Int): Store? {
|
||||
|
@ -13,6 +13,7 @@ import com.alya.ecommerce_serang.databinding.ActivityLoginBinding
|
||||
import com.alya.ecommerce_serang.ui.MainActivity
|
||||
import com.alya.ecommerce_serang.utils.BaseViewModelFactory
|
||||
import com.alya.ecommerce_serang.utils.SessionManager
|
||||
import com.alya.ecommerce_serang.utils.viewmodel.LoginViewModel
|
||||
|
||||
class LoginActivity : AppCompatActivity() {
|
||||
|
||||
|
@ -15,6 +15,7 @@ import com.alya.ecommerce_serang.databinding.ActivityRegisterBinding
|
||||
import com.alya.ecommerce_serang.ui.MainActivity
|
||||
import com.alya.ecommerce_serang.utils.BaseViewModelFactory
|
||||
import com.alya.ecommerce_serang.utils.SessionManager
|
||||
import com.alya.ecommerce_serang.utils.viewmodel.RegisterViewModel
|
||||
|
||||
class RegisterActivity : AppCompatActivity() {
|
||||
private lateinit var binding: ActivityRegisterBinding
|
||||
|
@ -7,6 +7,7 @@ import android.view.ViewGroup
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.viewModels
|
||||
import com.alya.ecommerce_serang.R
|
||||
import com.alya.ecommerce_serang.utils.viewmodel.ChatViewModel
|
||||
|
||||
class ChatFragment : Fragment() {
|
||||
|
||||
|
@ -24,6 +24,8 @@ import com.alya.ecommerce_serang.utils.BaseViewModelFactory
|
||||
import com.alya.ecommerce_serang.utils.HorizontalMarginItemDecoration
|
||||
import com.alya.ecommerce_serang.utils.SessionManager
|
||||
import com.alya.ecommerce_serang.utils.setLightStatusBar
|
||||
import com.alya.ecommerce_serang.utils.viewmodel.HomeUiState
|
||||
import com.alya.ecommerce_serang.utils.viewmodel.HomeViewModel
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
//@AndroidEntryPoint
|
||||
|
@ -18,6 +18,7 @@ import com.alya.ecommerce_serang.databinding.ActivityDetailProductBinding
|
||||
import com.alya.ecommerce_serang.ui.home.HorizontalProductAdapter
|
||||
import com.alya.ecommerce_serang.utils.BaseViewModelFactory
|
||||
import com.alya.ecommerce_serang.utils.SessionManager
|
||||
import com.alya.ecommerce_serang.utils.viewmodel.ProductViewModel
|
||||
import com.bumptech.glide.Glide
|
||||
|
||||
class DetailProductActivity : AppCompatActivity() {
|
||||
|
@ -13,6 +13,7 @@ import com.alya.ecommerce_serang.data.repository.ProductRepository
|
||||
import com.alya.ecommerce_serang.databinding.ActivityReviewProductBinding
|
||||
import com.alya.ecommerce_serang.utils.BaseViewModelFactory
|
||||
import com.alya.ecommerce_serang.utils.SessionManager
|
||||
import com.alya.ecommerce_serang.utils.viewmodel.ProductViewModel
|
||||
|
||||
class ReviewProductActivity : AppCompatActivity() {
|
||||
private lateinit var binding: ActivityReviewProductBinding
|
||||
|
@ -12,6 +12,7 @@ import com.alya.ecommerce_serang.data.repository.UserRepository
|
||||
import com.alya.ecommerce_serang.databinding.ActivityDetailProfileBinding
|
||||
import com.alya.ecommerce_serang.utils.BaseViewModelFactory
|
||||
import com.alya.ecommerce_serang.utils.SessionManager
|
||||
import com.alya.ecommerce_serang.utils.viewmodel.ProfileViewModel
|
||||
import com.bumptech.glide.Glide
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.Locale
|
||||
|
@ -18,6 +18,7 @@ import com.alya.ecommerce_serang.databinding.FragmentProfileBinding
|
||||
import com.alya.ecommerce_serang.ui.profile.mystore.MyStoreActivity
|
||||
import com.alya.ecommerce_serang.utils.BaseViewModelFactory
|
||||
import com.alya.ecommerce_serang.utils.SessionManager
|
||||
import com.alya.ecommerce_serang.utils.viewmodel.ProfileViewModel
|
||||
import com.bumptech.glide.Glide
|
||||
|
||||
class ProfileFragment : Fragment() {
|
||||
|
@ -22,6 +22,7 @@ import com.alya.ecommerce_serang.ui.profile.mystore.sells.payment.PaymentFragmen
|
||||
import com.alya.ecommerce_serang.ui.profile.mystore.sells.shipment.ShipmentFragment
|
||||
import com.alya.ecommerce_serang.utils.BaseViewModelFactory
|
||||
import com.alya.ecommerce_serang.utils.SessionManager
|
||||
import com.alya.ecommerce_serang.utils.viewmodel.MyStoreViewModel
|
||||
import com.bumptech.glide.Glide
|
||||
import kotlin.getValue
|
||||
|
||||
|
@ -1,21 +0,0 @@
|
||||
package com.alya.ecommerce_serang.ui.profile.mystore.product
|
||||
|
||||
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 AddProductActivity : AppCompatActivity() {
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
enableEdgeToEdge()
|
||||
setContentView(R.layout.activity_add_product)
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
@ -11,7 +11,7 @@ import com.alya.ecommerce_serang.data.api.retrofit.ApiConfig
|
||||
import com.alya.ecommerce_serang.data.repository.ProductRepository
|
||||
import com.alya.ecommerce_serang.data.repository.Result
|
||||
import com.alya.ecommerce_serang.databinding.ActivityProductBinding
|
||||
import com.alya.ecommerce_serang.ui.product.ProductViewModel
|
||||
import com.alya.ecommerce_serang.utils.viewmodel.ProductViewModel
|
||||
import com.alya.ecommerce_serang.utils.BaseViewModelFactory
|
||||
import com.alya.ecommerce_serang.utils.SessionManager
|
||||
|
||||
@ -74,12 +74,10 @@ class ProductActivity : AppCompatActivity() {
|
||||
}
|
||||
|
||||
binding.header.headerRightText.setOnClickListener {
|
||||
startActivity(Intent(this, AddProductActivity::class.java))
|
||||
startActivity(Intent(this, StoreProductDetailActivity::class.java))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
private fun setupRecyclerView() {
|
||||
binding.rvStoreProduct.layoutManager = LinearLayoutManager(this)
|
||||
}
|
||||
|
@ -0,0 +1,175 @@
|
||||
package com.alya.ecommerce_serang.ui.profile.mystore.product
|
||||
|
||||
import android.os.Bundle
|
||||
import android.text.Editable
|
||||
import android.text.TextWatcher
|
||||
import android.view.View
|
||||
import android.widget.ArrayAdapter
|
||||
import android.widget.Toast
|
||||
import com.alya.ecommerce_serang.R
|
||||
import androidx.activity.viewModels
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.content.ContextCompat
|
||||
import com.alya.ecommerce_serang.data.api.dto.CategoryItem
|
||||
import com.alya.ecommerce_serang.data.api.retrofit.ApiConfig
|
||||
import com.alya.ecommerce_serang.data.repository.ProductRepository
|
||||
import com.alya.ecommerce_serang.data.repository.Result
|
||||
import com.alya.ecommerce_serang.databinding.ActivityStoreProductDetailBinding
|
||||
import com.alya.ecommerce_serang.utils.viewmodel.ProductViewModel
|
||||
import com.alya.ecommerce_serang.utils.BaseViewModelFactory
|
||||
import com.alya.ecommerce_serang.utils.SessionManager
|
||||
import kotlin.getValue
|
||||
|
||||
class StoreProductDetailActivity : AppCompatActivity() {
|
||||
|
||||
private lateinit var binding: ActivityStoreProductDetailBinding
|
||||
private lateinit var sessionManager: SessionManager
|
||||
private lateinit var categoryList: List<CategoryItem>
|
||||
|
||||
private val viewModel: ProductViewModel by viewModels {
|
||||
BaseViewModelFactory {
|
||||
sessionManager = SessionManager(this)
|
||||
val apiService = ApiConfig.getApiService(sessionManager)
|
||||
val productRepository = ProductRepository(apiService)
|
||||
ProductViewModel(productRepository)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
binding = ActivityStoreProductDetailBinding.inflate(layoutInflater)
|
||||
setContentView(binding.root)
|
||||
|
||||
setupHeader()
|
||||
observeCategories()
|
||||
viewModel.loadCategories()
|
||||
|
||||
// Setup Pre-Order visibility
|
||||
binding.switchIsPreOrder.setOnCheckedChangeListener { _, isChecked ->
|
||||
binding.layoutDurasi.visibility = if (isChecked) View.VISIBLE else View.GONE
|
||||
validateForm()
|
||||
}
|
||||
|
||||
setupFormValidation()
|
||||
validateForm()
|
||||
|
||||
binding.btnSaveProduct.setOnClickListener {
|
||||
if (binding.btnSaveProduct.isEnabled) addProduct()
|
||||
}
|
||||
}
|
||||
|
||||
private fun setupHeader() {
|
||||
binding.header.headerTitle.text = "Tambah Produk"
|
||||
|
||||
binding.header.headerLeftIcon.setOnClickListener {
|
||||
onBackPressedDispatcher.onBackPressed()
|
||||
}
|
||||
}
|
||||
|
||||
private fun observeCategories() {
|
||||
viewModel.categoryList.observe(this) { result ->
|
||||
when (result) {
|
||||
is Result.Loading -> {
|
||||
// Optionally show loading spinner
|
||||
}
|
||||
is Result.Success -> {
|
||||
categoryList = result.data
|
||||
setupCategorySpinner(categoryList)
|
||||
}
|
||||
is Result.Error -> {
|
||||
Toast.makeText(
|
||||
this,
|
||||
"Failed to load categories: ${result.exception.message}",
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun setupCategorySpinner(categories: List<CategoryItem>) {
|
||||
val categoryNames = categories.map { it.name }
|
||||
val adapter = ArrayAdapter(this, android.R.layout.simple_spinner_item, categoryNames)
|
||||
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
|
||||
|
||||
binding.spinnerKategoriProduk.adapter = adapter
|
||||
}
|
||||
|
||||
private fun addProduct() {
|
||||
val name = binding.edtNamaProduk.text.toString()
|
||||
val description = binding.edtDeskripsiProduk.text.toString()
|
||||
val price = binding.edtHargaProduk.text.toString().toIntOrNull() ?: 0
|
||||
val stock = binding.edtStokProduk.text.toString().toIntOrNull() ?: 0
|
||||
val minOrder = binding.edtMinOrder.text.toString().toIntOrNull() ?: 1
|
||||
val weight = binding.edtBeratProduk.text.toString().toIntOrNull() ?: 0
|
||||
val isPreOrder = binding.switchIsPreOrder.isChecked
|
||||
val duration = binding.edtDurasi.text.toString().toIntOrNull() ?: 0
|
||||
val isActive = binding.switchIsActive.isChecked
|
||||
val categoryPosition = binding.spinnerKategoriProduk.selectedItemPosition
|
||||
val categoryId = categoryList.getOrNull(categoryPosition)?.id ?: 0
|
||||
|
||||
if (isPreOrder && duration == 0) {
|
||||
Toast.makeText(this, "Durasi wajib diisi jika pre-order diaktifkan.", Toast.LENGTH_SHORT).show()
|
||||
return
|
||||
}
|
||||
|
||||
viewModel.addProduct(
|
||||
name, description, price, stock, minOrder, weight, isPreOrder, duration, categoryId, isActive
|
||||
).observe(this) { result ->
|
||||
when (result) {
|
||||
is Result.Loading -> binding.btnSaveProduct.isEnabled = false
|
||||
is Result.Success -> {
|
||||
Toast.makeText(this, "Produk berhasil ditambahkan!", Toast.LENGTH_SHORT).show()
|
||||
finish()
|
||||
}
|
||||
is Result.Error -> {
|
||||
binding.btnSaveProduct.isEnabled = true
|
||||
Toast.makeText(this, "Gagal: ${result.exception.message}", Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun setupFormValidation() {
|
||||
val watcher = 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?) {
|
||||
validateForm()
|
||||
}
|
||||
}
|
||||
|
||||
// Watch all fields
|
||||
binding.edtNamaProduk.addTextChangedListener(watcher)
|
||||
binding.edtDeskripsiProduk.addTextChangedListener(watcher)
|
||||
binding.edtHargaProduk.addTextChangedListener(watcher)
|
||||
binding.edtStokProduk.addTextChangedListener(watcher)
|
||||
binding.edtMinOrder.addTextChangedListener(watcher)
|
||||
binding.edtBeratProduk.addTextChangedListener(watcher)
|
||||
binding.edtDurasi.addTextChangedListener(watcher)
|
||||
}
|
||||
|
||||
private fun validateForm() {
|
||||
val isNameValid = binding.edtNamaProduk.text.toString().isNotBlank()
|
||||
val isDescriptionValid = binding.edtDeskripsiProduk.text.toString().isNotBlank()
|
||||
val isPriceValid = binding.edtHargaProduk.text.toString().isNotBlank()
|
||||
val isStockValid = binding.edtStokProduk.text.toString().isNotBlank()
|
||||
val isMinOrderValid = binding.edtMinOrder.text.toString().isNotBlank()
|
||||
val isWeightValid = binding.edtBeratProduk.text.toString().isNotBlank()
|
||||
val isPreOrderChecked = binding.switchIsPreOrder.isChecked
|
||||
val isDurationValid = !isPreOrderChecked || binding.edtDurasi.text.toString().isNotBlank()
|
||||
|
||||
val isFormValid = isNameValid && isDescriptionValid && isPriceValid &&
|
||||
isStockValid && isMinOrderValid && isWeightValid && isDurationValid
|
||||
|
||||
if (isFormValid) {
|
||||
binding.btnSaveProduct.isEnabled = true
|
||||
binding.btnSaveProduct.setBackgroundResource(R.drawable.bg_button_active)
|
||||
binding.btnSaveProduct.setTextColor(ContextCompat.getColor(this, R.color.white))
|
||||
} else {
|
||||
binding.btnSaveProduct.isEnabled = false
|
||||
binding.btnSaveProduct.setBackgroundResource(R.drawable.bg_button_disabled)
|
||||
binding.btnSaveProduct.setTextColor(ContextCompat.getColor(this, R.color.black_300))
|
||||
}
|
||||
}
|
||||
}
|
@ -10,7 +10,7 @@ import com.alya.ecommerce_serang.data.api.retrofit.ApiConfig
|
||||
import com.alya.ecommerce_serang.data.api.retrofit.ApiService
|
||||
import com.alya.ecommerce_serang.data.repository.MyStoreRepository
|
||||
import com.alya.ecommerce_serang.databinding.ActivityDetailStoreProfileBinding
|
||||
import com.alya.ecommerce_serang.ui.profile.mystore.MyStoreViewModel
|
||||
import com.alya.ecommerce_serang.utils.viewmodel.MyStoreViewModel
|
||||
import com.alya.ecommerce_serang.utils.BaseViewModelFactory
|
||||
import com.alya.ecommerce_serang.utils.SessionManager
|
||||
import com.bumptech.glide.Glide
|
||||
|
@ -7,6 +7,7 @@ import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import com.alya.ecommerce_serang.R
|
||||
import com.alya.ecommerce_serang.utils.viewmodel.ReviewViewModel
|
||||
|
||||
class ReviewFragment : Fragment() {
|
||||
|
||||
|
@ -10,6 +10,7 @@ import androidx.viewpager2.widget.ViewPager2
|
||||
|
||||
import com.google.android.material.tabs.TabLayoutMediator
|
||||
import com.alya.ecommerce_serang.R
|
||||
import com.alya.ecommerce_serang.utils.viewmodel.SellsViewModel
|
||||
|
||||
class SellsFragment : Fragment() {
|
||||
private lateinit var viewModel: SellsViewModel
|
||||
|
@ -1,4 +1,4 @@
|
||||
package com.alya.ecommerce_serang.ui.chat
|
||||
package com.alya.ecommerce_serang.utils.viewmodel
|
||||
|
||||
import androidx.lifecycle.ViewModel
|
||||
|
@ -1,4 +1,4 @@
|
||||
package com.alya.ecommerce_serang.ui.home
|
||||
package com.alya.ecommerce_serang.utils.viewmodel
|
||||
|
||||
import android.util.Log
|
||||
import androidx.lifecycle.ViewModel
|
@ -1,4 +1,4 @@
|
||||
package com.alya.ecommerce_serang.ui.auth
|
||||
package com.alya.ecommerce_serang.utils.viewmodel
|
||||
|
||||
import androidx.lifecycle.LiveData
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
@ -10,12 +10,12 @@ import com.alya.ecommerce_serang.data.repository.UserRepository
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
class LoginViewModel(private val repository: UserRepository) : ViewModel() {
|
||||
private val _loginState = MutableLiveData<com.alya.ecommerce_serang.data.repository.Result<LoginResponse>>()
|
||||
private val _loginState = MutableLiveData<Result<LoginResponse>>()
|
||||
val loginState: LiveData<Result<LoginResponse>> get() = _loginState
|
||||
|
||||
fun login(email: String, password: String) {
|
||||
viewModelScope.launch {
|
||||
_loginState.value = com.alya.ecommerce_serang.data.repository.Result.Loading
|
||||
_loginState.value = Result.Loading
|
||||
val result = repository.login(email, password)
|
||||
_loginState.value = result
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package com.alya.ecommerce_serang.ui.profile.mystore
|
||||
package com.alya.ecommerce_serang.utils.viewmodel
|
||||
|
||||
import androidx.lifecycle.LiveData
|
||||
import androidx.lifecycle.MutableLiveData
|
@ -1,9 +1,11 @@
|
||||
package com.alya.ecommerce_serang.ui.product
|
||||
package com.alya.ecommerce_serang.utils.viewmodel
|
||||
|
||||
import androidx.lifecycle.LiveData
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.liveData
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.alya.ecommerce_serang.data.api.dto.CategoryItem
|
||||
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.Product
|
||||
@ -23,10 +25,12 @@ class ProductViewModel(private val repository: ProductRepository) : ViewModel()
|
||||
private val _reviewProduct = MutableLiveData<List<ReviewsItem>>()
|
||||
val reviewProduct: LiveData<List<ReviewsItem>> get() = _reviewProduct
|
||||
|
||||
// For List of Products in My Store
|
||||
private val _productList = MutableLiveData<Result<List<ProductsItem>>>()
|
||||
val productList: LiveData<Result<List<ProductsItem>>> get() = _productList
|
||||
|
||||
private val _categoryList = MutableLiveData<Result<List<CategoryItem>>>()
|
||||
val categoryList: LiveData<Result<List<CategoryItem>>> get() = _categoryList
|
||||
|
||||
fun loadProductDetail(productId: Int) {
|
||||
viewModelScope.launch {
|
||||
val result = repository.fetchProductDetail(productId)
|
||||
@ -53,6 +57,34 @@ class ProductViewModel(private val repository: ProductRepository) : ViewModel()
|
||||
}
|
||||
}
|
||||
|
||||
fun loadCategories() {
|
||||
viewModelScope.launch {
|
||||
_categoryList.value = Result.Loading
|
||||
_categoryList.value = repository.getAllCategories()
|
||||
}
|
||||
}
|
||||
|
||||
fun addProduct(
|
||||
name: String,
|
||||
description: String,
|
||||
price: Int,
|
||||
stock: Int,
|
||||
minOrder: Int,
|
||||
weight: Int,
|
||||
isPreOrder: Boolean,
|
||||
duration: Int,
|
||||
categoryId: Int,
|
||||
isActive: Boolean
|
||||
): LiveData<Result<Unit>> = liveData {
|
||||
emit(Result.Loading)
|
||||
val result = repository.addProduct(
|
||||
name, description, price, stock, minOrder, weight, isPreOrder, duration, categoryId, isActive
|
||||
)
|
||||
emit(result)
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Optional: for store detail if you need it later
|
||||
// fun loadStoreDetail(storeId: Int) {
|
||||
// viewModelScope.launch {
|
@ -1,4 +1,4 @@
|
||||
package com.alya.ecommerce_serang.ui.profile
|
||||
package com.alya.ecommerce_serang.utils.viewmodel
|
||||
|
||||
import androidx.lifecycle.LiveData
|
||||
import androidx.lifecycle.MutableLiveData
|
@ -1,4 +1,4 @@
|
||||
package com.alya.ecommerce_serang.ui.auth
|
||||
package com.alya.ecommerce_serang.utils.viewmodel
|
||||
|
||||
import android.util.Log
|
||||
import androidx.lifecycle.LiveData
|
||||
@ -86,8 +86,4 @@ class RegisterViewModel(private val repository: UserRepository) : ViewModel() {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package com.alya.ecommerce_serang.ui.profile.mystore.review
|
||||
package com.alya.ecommerce_serang.utils.viewmodel
|
||||
|
||||
import androidx.lifecycle.ViewModel
|
||||
|
@ -1,4 +1,4 @@
|
||||
package com.alya.ecommerce_serang.ui.profile.mystore.sells
|
||||
package com.alya.ecommerce_serang.utils.viewmodel
|
||||
|
||||
import androidx.lifecycle.ViewModel
|
||||
|
@ -7,7 +7,7 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
tools:context=".ui.profile.mystore.product.AddProductActivity">
|
||||
tools:context=".ui.profile.mystore.product.StoreProductDetailActivity">
|
||||
|
||||
<include
|
||||
android:id="@+id/header"
|
||||
@ -214,7 +214,7 @@
|
||||
</LinearLayout>
|
||||
|
||||
<EditText
|
||||
android:id="@+id/DeskripsiProduk"
|
||||
android:id="@+id/edt_deskripsi_produk"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="70dp"
|
||||
android:background="@drawable/bg_text_field"
|
||||
@ -434,14 +434,109 @@
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<!-- Kondisi Produk -->
|
||||
<!-- <!– Kondisi Produk –>-->
|
||||
<!-- <LinearLayout-->
|
||||
<!-- android:layout_width="match_parent"-->
|
||||
<!-- android:layout_height="wrap_content"-->
|
||||
<!-- android:orientation="vertical"-->
|
||||
<!-- android:layout_marginBottom="24dp">-->
|
||||
|
||||
<!-- <!– Label Kondisi Produk –>-->
|
||||
<!-- <LinearLayout-->
|
||||
<!-- android:layout_width="match_parent"-->
|
||||
<!-- android:layout_height="wrap_content"-->
|
||||
<!-- android:orientation="horizontal">-->
|
||||
|
||||
<!-- <TextView-->
|
||||
<!-- android:layout_width="wrap_content"-->
|
||||
<!-- android:layout_height="wrap_content"-->
|
||||
<!-- android:text="Kondisi Produk"-->
|
||||
<!-- style="@style/body_medium"-->
|
||||
<!-- android:layout_marginEnd="4dp"/>-->
|
||||
|
||||
<!-- <TextView-->
|
||||
<!-- android:layout_width="0dp"-->
|
||||
<!-- android:layout_height="wrap_content"-->
|
||||
<!-- android:layout_weight="1"-->
|
||||
<!-- android:text="*"-->
|
||||
<!-- style="@style/body_medium"-->
|
||||
<!-- android:textColor="@color/red_required"-->
|
||||
<!-- android:layout_gravity="end"/>-->
|
||||
|
||||
<!-- </LinearLayout>-->
|
||||
|
||||
<!-- <!– Spinner Dropdown dengan Chevron –>-->
|
||||
<!-- <LinearLayout-->
|
||||
<!-- android:layout_width="match_parent"-->
|
||||
<!-- android:layout_height="wrap_content"-->
|
||||
<!-- android:orientation="horizontal"-->
|
||||
<!-- android:background="@drawable/bg_text_field"-->
|
||||
<!-- android:gravity="center_vertical"-->
|
||||
<!-- android:layout_marginTop="10dp">-->
|
||||
|
||||
<!-- <Spinner-->
|
||||
<!-- android:id="@+id/spinner_kondisi_produk"-->
|
||||
<!-- android:layout_width="0dp"-->
|
||||
<!-- android:layout_height="wrap_content"-->
|
||||
<!-- android:layout_weight="1"-->
|
||||
<!-- android:padding="8dp"-->
|
||||
<!-- style="@style/body_small"-->
|
||||
<!-- android:background="@null"/>-->
|
||||
|
||||
<!-- <!– Chevron Down Icon –>-->
|
||||
<!-- <ImageView-->
|
||||
<!-- android:layout_width="16dp"-->
|
||||
<!-- android:layout_height="16dp"-->
|
||||
<!-- android:src="@drawable/ic_down"-->
|
||||
<!-- android:layout_marginEnd="8dp"-->
|
||||
<!-- android:contentDescription="Chevron Down" />-->
|
||||
|
||||
<!-- </LinearLayout>-->
|
||||
|
||||
<!-- </LinearLayout>-->
|
||||
|
||||
<!-- Pre-Order -->
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:layout_marginBottom="24dp">
|
||||
|
||||
<!-- Label Kondisi Produk -->
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center">
|
||||
|
||||
<TextView
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:text="Pre-Order"
|
||||
style="@style/body_medium"
|
||||
android:layout_marginEnd="4dp"/>
|
||||
|
||||
<Switch
|
||||
android:id="@+id/switch_is_pre_order"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="end"
|
||||
tools:ignore="UseSwitchCompatOrMaterialXml" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<!-- Durasi Pre-Order -->
|
||||
<LinearLayout
|
||||
android:id="@+id/layout_durasi"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:layout_marginBottom="24dp"
|
||||
android:visibility="gone">
|
||||
|
||||
<!-- Label Durasi Pre-Order -->
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
@ -450,10 +545,11 @@
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Kondisi Produk"
|
||||
android:text="Durasi Pre-Order"
|
||||
style="@style/body_medium"
|
||||
android:layout_marginEnd="4dp"/>
|
||||
|
||||
|
||||
<TextView
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
@ -465,31 +561,32 @@
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<!-- Spinner Dropdown dengan Chevron -->
|
||||
<!-- Input Durasi Pre-Order dengan Suffix "hari" -->
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:background="@drawable/bg_text_field"
|
||||
android:gravity="center_vertical"
|
||||
android:layout_marginTop="10dp">
|
||||
android:gravity="center">
|
||||
|
||||
<Spinner
|
||||
android:id="@+id/spinner_kondisi_produk"
|
||||
<EditText
|
||||
android:id="@+id/edt_durasi"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:padding="8dp"
|
||||
android:hint="Isi durasi pre-order di sini"
|
||||
android:inputType="number"
|
||||
style="@style/body_small"
|
||||
android:background="@null"/>
|
||||
android:background="@null"
|
||||
android:padding="8dp"/>
|
||||
|
||||
<!-- Chevron Down Icon -->
|
||||
<ImageView
|
||||
android:layout_width="16dp"
|
||||
android:layout_height="16dp"
|
||||
android:src="@drawable/ic_down"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:contentDescription="Chevron Down" />
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="hari"
|
||||
style="@style/label_medium_prominent"
|
||||
android:textColor="@color/black_300"
|
||||
android:padding="8dp"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
@ -530,7 +627,8 @@
|
||||
<Button
|
||||
android:id="@+id/btn_save_product"
|
||||
android:text="Simpan Produk"
|
||||
style="@style/button.large.disabled.long"/>
|
||||
style="@style/button.large.disabled.long"
|
||||
android:enabled="false"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
Reference in New Issue
Block a user