diff --git a/.idea/gradle.xml b/.idea/gradle.xml
index 7b3006b..d124cf2 100644
--- a/.idea/gradle.xml
+++ b/.idea/gradle.xml
@@ -6,14 +6,13 @@
-
+
-
diff --git a/app/build.gradle.kts b/app/build.gradle.kts
index 2a25f1f..07c27e4 100644
--- a/app/build.gradle.kts
+++ b/app/build.gradle.kts
@@ -1,3 +1,5 @@
+import org.gradle.api.tasks.compile.JavaCompile
+
plugins {
alias(libs.plugins.android.application)
alias(libs.plugins.jetbrains.kotlin.android)
@@ -84,3 +86,4 @@ dependencies {
// kapt("androidx.hilt:hilt-compiler:1.0.0")
}
+
diff --git a/app/src/main/java/com/alya/ecommerce_serang/data/api/response/ViewStoreProductsResponse.kt b/app/src/main/java/com/alya/ecommerce_serang/data/api/response/ViewStoreProductsResponse.kt
new file mode 100644
index 0000000..c933ac7
--- /dev/null
+++ b/app/src/main/java/com/alya/ecommerce_serang/data/api/response/ViewStoreProductsResponse.kt
@@ -0,0 +1,13 @@
+package com.alya.ecommerce_serang.data.api.response
+
+import com.alya.ecommerce_serang.data.api.dto.ProductsItem
+import com.google.gson.annotations.SerializedName
+
+data class ViewStoreProductsResponse(
+
+ @field:SerializedName("message")
+ val message: String? = null,
+
+ @field:SerializedName("products")
+ val products: List? = null
+)
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 f616739..1ad98bf 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
@@ -13,6 +13,7 @@ import com.alya.ecommerce_serang.data.api.response.ProfileResponse
import com.alya.ecommerce_serang.data.api.response.RegisterResponse
import com.alya.ecommerce_serang.data.api.response.ReviewProductResponse
import com.alya.ecommerce_serang.data.api.response.StoreResponse
+import com.alya.ecommerce_serang.data.api.response.ViewStoreProductsResponse
import retrofit2.Call
import retrofit2.Response
import retrofit2.http.Body
@@ -64,4 +65,8 @@ interface ApiService {
@GET("mystore")
suspend fun getStore (): Response
+
+ @GET("mystore/product") // Replace with actual endpoint
+ suspend fun getStoreProduct(): Response
+
}
\ No newline at end of file
diff --git a/app/src/main/java/com/alya/ecommerce_serang/data/model/BalanceTransaction.kt b/app/src/main/java/com/alya/ecommerce_serang/data/model/BalanceTransaction.kt
deleted file mode 100644
index 227f35d..0000000
--- a/app/src/main/java/com/alya/ecommerce_serang/data/model/BalanceTransaction.kt
+++ /dev/null
@@ -1,8 +0,0 @@
-package com.alya.ecommerce_serang.data.model
-
-data class BalanceTransaction(
- val date: String,
- val balanceTransTitle: String,
- val balanceTransDesc: String,
- val balanceTransAmount: String,
-)
diff --git a/app/src/main/java/com/alya/ecommerce_serang/data/repository/ProductRepository.kt b/app/src/main/java/com/alya/ecommerce_serang/data/repository/ProductRepository.kt
index 519b5d4..f65d677 100644
--- a/app/src/main/java/com/alya/ecommerce_serang/data/repository/ProductRepository.kt
+++ b/app/src/main/java/com/alya/ecommerce_serang/data/repository/ProductRepository.kt
@@ -79,6 +79,16 @@ class ProductRepository(private val apiService: ApiService) {
null
}
}
+
+ suspend fun fetchMyStoreProducts(): List {
+ val response = apiService.getStoreProduct()
+ if (response.isSuccessful) {
+ val responseBody = response.body()
+ return responseBody?.products?.filterNotNull() ?: emptyList()
+ } else {
+ throw Exception("Failed to fetch store products: ${response.message()}")
+ }
+ }
}
// suspend fun fetchStoreDetail(storeId: Int): Store? {
diff --git a/app/src/main/java/com/alya/ecommerce_serang/ui/product/ProductViewModel.kt b/app/src/main/java/com/alya/ecommerce_serang/ui/product/ProductViewModel.kt
index e349bfa..c048a13 100644
--- a/app/src/main/java/com/alya/ecommerce_serang/ui/product/ProductViewModel.kt
+++ b/app/src/main/java/com/alya/ecommerce_serang/ui/product/ProductViewModel.kt
@@ -4,10 +4,12 @@ import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
+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
import com.alya.ecommerce_serang.data.api.response.ReviewsItem
import com.alya.ecommerce_serang.data.repository.ProductRepository
+import com.alya.ecommerce_serang.data.repository.Result
import kotlinx.coroutines.launch
class ProductViewModel(private val repository: ProductRepository) : ViewModel() {
@@ -21,6 +23,10 @@ class ProductViewModel(private val repository: ProductRepository) : ViewModel()
private val _reviewProduct = MutableLiveData>()
val reviewProduct: LiveData> get() = _reviewProduct
+ // For List of Products in My Store
+ private val _productList = MutableLiveData>>()
+ val productList: LiveData>> get() = _productList
+
fun loadProductDetail(productId: Int) {
viewModelScope.launch {
val result = repository.fetchProductDetail(productId)
@@ -34,11 +40,24 @@ class ProductViewModel(private val repository: ProductRepository) : ViewModel()
_reviewProduct.value = reviews ?: emptyList()
}
}
-}
-// fun loadStoreDetail(storeId: Int){
+ fun loadMyStoreProducts() {
+ viewModelScope.launch {
+ _productList.value = Result.Loading
+ try {
+ val result = repository.fetchMyStoreProducts()
+ _productList.value = Result.Success(result)
+ } catch (e: Exception) {
+ _productList.value = Result.Error(e)
+ }
+ }
+ }
+
+ // Optional: for store detail if you need it later
+// fun loadStoreDetail(storeId: Int) {
// viewModelScope.launch {
// val storeResult = repository.fetchStoreDetail(storeId)
// _storeDetail.value = storeResult
// }
-// }
\ No newline at end of file
+// }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/alya/ecommerce_serang/ui/profile/mystore/balance/BalanceTransactionAdapter.kt b/app/src/main/java/com/alya/ecommerce_serang/ui/profile/mystore/balance/BalanceTransactionAdapter.kt
index efa6f87..e106b1d 100644
--- a/app/src/main/java/com/alya/ecommerce_serang/ui/profile/mystore/balance/BalanceTransactionAdapter.kt
+++ b/app/src/main/java/com/alya/ecommerce_serang/ui/profile/mystore/balance/BalanceTransactionAdapter.kt
@@ -1,7 +1,5 @@
package com.alya.ecommerce_serang.ui.profile.mystore.balance
-import com.alya.ecommerce_serang.data.model.BalanceTransaction
-
/* class BalanceTransactionAdapter(private val balanceTransactionList: List) :
RecyclerView.Adapter() {
diff --git a/app/src/main/java/com/alya/ecommerce_serang/ui/profile/mystore/product/ProductActivity.kt b/app/src/main/java/com/alya/ecommerce_serang/ui/profile/mystore/product/ProductActivity.kt
index 9505316..3b9db9b 100644
--- a/app/src/main/java/com/alya/ecommerce_serang/ui/profile/mystore/product/ProductActivity.kt
+++ b/app/src/main/java/com/alya/ecommerce_serang/ui/profile/mystore/product/ProductActivity.kt
@@ -1,21 +1,86 @@
package com.alya.ecommerce_serang.ui.profile.mystore.product
+import android.content.Intent
import android.os.Bundle
-import androidx.activity.enableEdgeToEdge
+import android.view.View
+import android.widget.Toast
+import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity
-import androidx.core.view.ViewCompat
-import androidx.core.view.WindowInsetsCompat
-import com.alya.ecommerce_serang.R
+import androidx.recyclerview.widget.LinearLayoutManager
+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.BaseViewModelFactory
+import com.alya.ecommerce_serang.utils.SessionManager
class ProductActivity : AppCompatActivity() {
- override fun onCreate(savedInstanceState: Bundle?) {
- super.onCreate(savedInstanceState)
- enableEdgeToEdge()
- setContentView(R.layout.activity_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
+
+ private lateinit var binding: ActivityProductBinding
+ private lateinit var sessionManager: SessionManager
+
+ 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 = ActivityProductBinding.inflate(layoutInflater)
+ setContentView(binding.root)
+
+ setupHeader()
+ setupRecyclerView()
+
+ observeViewModel()
+
+ binding.progressBar.visibility = View.VISIBLE
+ viewModel.loadMyStoreProducts()
+
+ }
+
+ private fun observeViewModel() {
+ viewModel.productList.observe(this) { result ->
+ when (result) {
+ is Result.Loading -> {
+ binding.progressBar.visibility = View.VISIBLE
+ }
+ is Result.Success -> {
+ binding.progressBar.visibility = View.GONE
+ val products = result.data
+ binding.rvStoreProduct.adapter = ProductAdapter(products) {
+ Toast.makeText(this, "Clicked: ${it.name}", Toast.LENGTH_SHORT).show()
+ }
+ }
+ is Result.Error -> {
+ binding.progressBar.visibility = View.GONE
+ Toast.makeText(this, "Failed to load products: ${result.exception.message}", Toast.LENGTH_SHORT).show()
+ }
+ }
+ }
+ }
+
+ private fun setupHeader() {
+ binding.header.headerTitle.text = "Produk Saya"
+ binding.header.headerRightText.visibility = View.VISIBLE
+
+ binding.header.headerLeftIcon.setOnClickListener {
+ onBackPressedDispatcher.onBackPressed()
+ }
+
+ binding.header.headerRightText.setOnClickListener {
+ startActivity(Intent(this, AddProductActivity::class.java))
+ }
+ }
+
+
+
+ private fun setupRecyclerView() {
+ binding.rvStoreProduct.layoutManager = LinearLayoutManager(this)
+ }
}
\ No newline at end of file
diff --git a/app/src/main/java/com/alya/ecommerce_serang/ui/profile/mystore/product/ProductAdapter.kt b/app/src/main/java/com/alya/ecommerce_serang/ui/profile/mystore/product/ProductAdapter.kt
new file mode 100644
index 0000000..09ff20c
--- /dev/null
+++ b/app/src/main/java/com/alya/ecommerce_serang/ui/profile/mystore/product/ProductAdapter.kt
@@ -0,0 +1,63 @@
+package com.alya.ecommerce_serang.ui.profile.mystore.product
+
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.ImageView
+import android.widget.TextView
+import androidx.core.content.ContextCompat
+import androidx.recyclerview.widget.RecyclerView
+import com.alya.ecommerce_serang.R
+import com.alya.ecommerce_serang.data.api.dto.ProductsItem
+import com.bumptech.glide.Glide
+
+class ProductAdapter(
+ private val products: List,
+ private val onItemClick: (ProductsItem) -> Unit
+) : RecyclerView.Adapter() {
+
+ inner class ProductViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
+ private val ivProduct: ImageView = itemView.findViewById(R.id.iv_product)
+ private val tvProductName: TextView = itemView.findViewById(R.id.tv_product_name)
+ private val tvProductPrice: TextView = itemView.findViewById(R.id.tv_product_price)
+ private val tvProductStock: TextView = itemView.findViewById(R.id.tv_product_stock)
+ private val tvProductStatus: TextView = itemView.findViewById(R.id.tv_product_status)
+
+ fun bind(product: ProductsItem) {
+ tvProductName.text = product.name
+ tvProductPrice.text = "Rp${product.price}"
+ tvProductStock.text = "Stok: ${product.stock}"
+ tvProductStatus.text = product.status
+
+ // Change color depending on status
+ tvProductStatus.setTextColor(
+ ContextCompat.getColor(
+ itemView.context,
+ if (product.status.equals("active", true))
+ R.color.darkblue_500 else R.color.black_500
+ )
+ )
+
+ Glide.with(itemView.context)
+ .load(product.image)
+ .placeholder(R.drawable.placeholder_image)
+ .into(ivProduct)
+
+ itemView.setOnClickListener {
+ onItemClick(product)
+ }
+ }
+ }
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ProductViewHolder {
+ val view = LayoutInflater.from(parent.context)
+ .inflate(R.layout.item_store_product, parent, false)
+ return ProductViewHolder(view)
+ }
+
+ override fun getItemCount(): Int = products.size
+
+ override fun onBindViewHolder(holder: ProductViewHolder, position: Int) {
+ holder.bind(products[position])
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/res/drawable/bg_product_active.xml b/app/src/main/res/drawable/bg_product_active.xml
new file mode 100644
index 0000000..a652973
--- /dev/null
+++ b/app/src/main/res/drawable/bg_product_active.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/bg_product_inactive.xml b/app/src/main/res/drawable/bg_product_inactive.xml
new file mode 100644
index 0000000..923c799
--- /dev/null
+++ b/app/src/main/res/drawable/bg_product_inactive.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/ic_search.png b/app/src/main/res/drawable/ic_search.png
new file mode 100644
index 0000000..4c0332e
Binary files /dev/null and b/app/src/main/res/drawable/ic_search.png differ
diff --git a/app/src/main/res/layout/activity_add_product.xml b/app/src/main/res/layout/activity_add_product.xml
index ba6e432..6f34b56 100644
--- a/app/src/main/res/layout/activity_add_product.xml
+++ b/app/src/main/res/layout/activity_add_product.xml
@@ -2,13 +2,16 @@
-
+
-
+
-
+
-
+
-
+
-
+ tools:context=".ui.profile.mystore.product.ProductActivity"
+ android:orientation="vertical">
-
\ No newline at end of file
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_shipping_confirmation.xml b/app/src/main/res/layout/activity_shipping_confirmation.xml
index 91a3aa9..f20c38c 100644
--- a/app/src/main/res/layout/activity_shipping_confirmation.xml
+++ b/app/src/main/res/layout/activity_shipping_confirmation.xml
@@ -2,13 +2,16 @@
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml
index c277cdb..2b6ba3d 100644
--- a/app/src/main/res/values/themes.xml
+++ b/app/src/main/res/values/themes.xml
@@ -293,4 +293,9 @@
- 50%
+
+
\ No newline at end of file
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
index 5751043..1e6e224 100644
--- a/gradle/libs.versions.toml
+++ b/gradle/libs.versions.toml
@@ -1,5 +1,5 @@
[versions]
-agp = "8.5.2"
+agp = "8.9.1"
glide = "4.16.0"
hiltAndroid = "2.51"
hiltLifecycleViewmodel = "1.0.0-alpha03"
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index 6ab86ee..00bf192 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,6 @@
#Wed Oct 16 14:37:43 ICT 2024
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.11.1-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists