add product

This commit is contained in:
Gracia
2025-04-11 02:32:30 +07:00
parent d11022d502
commit e9e3597363
32 changed files with 496 additions and 66 deletions

2
.idea/gradle.xml generated
View File

@ -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
View File

@ -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">

View File

@ -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"

View File

@ -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
)

View File

@ -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
)

View File

@ -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>
}

View File

@ -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? {

View File

@ -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() {

View File

@ -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

View File

@ -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() {

View File

@ -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

View File

@ -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() {

View File

@ -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

View File

@ -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

View File

@ -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() {

View File

@ -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

View File

@ -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
}
}
}

View File

@ -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)
}

View File

@ -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))
}
}
}

View File

@ -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

View File

@ -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() {

View File

@ -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

View File

@ -1,4 +1,4 @@
package com.alya.ecommerce_serang.ui.chat
package com.alya.ecommerce_serang.utils.viewmodel
import androidx.lifecycle.ViewModel

View File

@ -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

View File

@ -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
}

View File

@ -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

View File

@ -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 {

View File

@ -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

View File

@ -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() {
}
}
}
}
}

View File

@ -1,4 +1,4 @@
package com.alya.ecommerce_serang.ui.profile.mystore.review
package com.alya.ecommerce_serang.utils.viewmodel
import androidx.lifecycle.ViewModel

View File

@ -1,4 +1,4 @@
package com.alya.ecommerce_serang.ui.profile.mystore.sells
package com.alya.ecommerce_serang.utils.viewmodel
import androidx.lifecycle.ViewModel

View File

@ -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 -->
<!-- &lt;!&ndash; Kondisi Produk &ndash;&gt;-->
<!-- <LinearLayout-->
<!-- android:layout_width="match_parent"-->
<!-- android:layout_height="wrap_content"-->
<!-- android:orientation="vertical"-->
<!-- android:layout_marginBottom="24dp">-->
<!-- &lt;!&ndash; Label Kondisi Produk &ndash;&gt;-->
<!-- <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>-->
<!-- &lt;!&ndash; Spinner Dropdown dengan Chevron &ndash;&gt;-->
<!-- <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"/>-->
<!-- &lt;!&ndash; Chevron Down Icon &ndash;&gt;-->
<!-- <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>