update product

This commit is contained in:
Gracia
2025-04-19 20:49:38 +07:00
parent 3b0b2d602f
commit 181106eaf5
58 changed files with 731 additions and 221 deletions

View File

@ -22,7 +22,7 @@
android:usesCleartextTraffic="true"
tools:targetApi="31">
<activity
android:name=".data.api.response.cart.CartActivity"
android:name=".data.api.response.customer.cart.CartActivity"
android:exported="false" />
<activity
android:name=".ui.order.address.EditAddressActivity"

View File

@ -1,6 +1,6 @@
package com.alya.ecommerce_serang.data.api.dto
import com.alya.ecommerce_serang.data.api.response.cart.CartItemsItem
import com.alya.ecommerce_serang.data.api.response.customer.cart.CartItemsItem
data class CheckoutData(
val orderRequest: Any, // Can be OrderRequest or OrderRequestBuy

View File

@ -0,0 +1,15 @@
package com.alya.ecommerce_serang.data.api.dto
import com.google.gson.annotations.SerializedName
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

@ -25,11 +25,14 @@ data class Product(
@field:SerializedName("is_pre_order")
val isPreOrder: Boolean? = null,
@field:SerializedName("condition")
val condition: String? = null,
@field:SerializedName("category_id")
val categoryId: Int? = null,
@field:SerializedName("price")
val price: Int? = null,
val price: String? = null,
@field:SerializedName("name")
val name: String? = null,

View File

@ -1,4 +1,4 @@
package com.alya.ecommerce_serang.data.api.response.cart
package com.alya.ecommerce_serang.data.api.response.customer.cart
import com.google.gson.annotations.SerializedName

View File

@ -1,4 +1,4 @@
package com.alya.ecommerce_serang.data.api.response.cart
package com.alya.ecommerce_serang.data.api.response.customer.cart
import android.os.Bundle
import androidx.activity.enableEdgeToEdge

View File

@ -1,4 +1,4 @@
package com.alya.ecommerce_serang.data.api.response.cart
package com.alya.ecommerce_serang.data.api.response.customer.cart
import com.google.gson.annotations.SerializedName

View File

@ -1,4 +1,4 @@
package com.alya.ecommerce_serang.data.api.response.cart
package com.alya.ecommerce_serang.data.api.response.customer.cart
import com.google.gson.annotations.SerializedName

View File

@ -1,4 +1,4 @@
package com.alya.ecommerce_serang.data.api.response.order
package com.alya.ecommerce_serang.data.api.response.customer.order
import com.google.gson.annotations.SerializedName

View File

@ -1,4 +1,4 @@
package com.alya.ecommerce_serang.data.api.response.order
package com.alya.ecommerce_serang.data.api.response.customer.order
import com.google.gson.annotations.SerializedName

View File

@ -1,4 +1,4 @@
package com.alya.ecommerce_serang.data.api.response.order
package com.alya.ecommerce_serang.data.api.response.customer.order
import com.google.gson.annotations.SerializedName

View File

@ -1,4 +1,4 @@
package com.alya.ecommerce_serang.data.api.response.order
package com.alya.ecommerce_serang.data.api.response.customer.order
import com.google.gson.annotations.SerializedName

View File

@ -1,4 +1,4 @@
package com.alya.ecommerce_serang.data.api.response.order
package com.alya.ecommerce_serang.data.api.response.customer.order
import com.google.gson.annotations.SerializedName

View File

@ -1,4 +1,4 @@
package com.alya.ecommerce_serang.data.api.response.order
package com.alya.ecommerce_serang.data.api.response.customer.order
import com.google.gson.annotations.SerializedName

View File

@ -1,4 +1,4 @@
package com.alya.ecommerce_serang.data.api.response.product
package com.alya.ecommerce_serang.data.api.response.customer.product
import com.alya.ecommerce_serang.data.api.dto.ProductsItem
import com.google.gson.annotations.SerializedName

View File

@ -1,4 +1,4 @@
package com.alya.ecommerce_serang.data.api.response.product
package com.alya.ecommerce_serang.data.api.response.customer.product
import com.google.gson.annotations.SerializedName

View File

@ -1,4 +1,4 @@
package com.alya.ecommerce_serang.data.api.response.product
package com.alya.ecommerce_serang.data.api.response.customer.product
import com.alya.ecommerce_serang.data.api.dto.CategoryItem
import com.google.gson.annotations.SerializedName

View File

@ -1,4 +1,4 @@
package com.alya.ecommerce_serang.data.api.response.product
package com.alya.ecommerce_serang.data.api.response.customer.product
import com.google.gson.annotations.SerializedName

View File

@ -1,4 +1,4 @@
package com.alya.ecommerce_serang.data.api.response.product
package com.alya.ecommerce_serang.data.api.response.customer.product
import com.google.gson.annotations.SerializedName

View File

@ -1,4 +1,4 @@
package com.alya.ecommerce_serang.data.api.response.product
package com.alya.ecommerce_serang.data.api.response.customer.product
import com.google.gson.annotations.SerializedName

View File

@ -1,4 +1,4 @@
package com.alya.ecommerce_serang.data.api.response.product
package com.alya.ecommerce_serang.data.api.response.customer.product
import com.alya.ecommerce_serang.data.api.dto.Store
import com.google.gson.annotations.SerializedName

View File

@ -1,4 +1,4 @@
package com.alya.ecommerce_serang.data.api.response.profile
package com.alya.ecommerce_serang.data.api.response.customer.profile
import com.google.gson.annotations.SerializedName

View File

@ -1,4 +1,4 @@
package com.alya.ecommerce_serang.data.api.response.profile
package com.alya.ecommerce_serang.data.api.response.customer.profile
import com.google.gson.annotations.SerializedName

View File

@ -1,4 +1,4 @@
package com.alya.ecommerce_serang.data.api.response.profile
package com.alya.ecommerce_serang.data.api.response.customer.profile
import com.alya.ecommerce_serang.data.api.dto.UserProfile
import com.google.gson.annotations.SerializedName

View File

@ -0,0 +1,9 @@
package com.alya.ecommerce_serang.data.api.response.store.orders
import com.google.gson.annotations.SerializedName
data class AddShippingReceiptResponse(
@field:SerializedName("message")
val message: String? = null
)

View File

@ -0,0 +1,48 @@
package com.alya.ecommerce_serang.data.api.response.store.orders
import com.google.gson.annotations.SerializedName
data class KonfirmasiTagihanResponse(
@field:SerializedName("message")
val message: String? = null,
@field:SerializedName("updatedOrder")
val updatedOrder: UpdatedOrder? = null,
@field:SerializedName("updatedItems")
val updatedItems: List<Any?>? = null
)
data class UpdatedOrder(
@field:SerializedName("payment_method_id")
val paymentMethodId: Int? = null,
@field:SerializedName("updated_at")
val updatedAt: String? = null,
@field:SerializedName("total_amount")
val totalAmount: String? = null,
@field:SerializedName("user_id")
val userId: Int? = null,
@field:SerializedName("address_id")
val addressId: Int? = null,
@field:SerializedName("is_negotiable")
val isNegotiable: Boolean? = null,
@field:SerializedName("created_at")
val createdAt: String? = null,
@field:SerializedName("voucher_id")
val voucherId: Any? = null,
@field:SerializedName("id")
val id: Int? = null,
@field:SerializedName("status")
val status: String? = null
)

View File

@ -0,0 +1,168 @@
package com.alya.ecommerce_serang.data.api.response.store.orders
import com.google.gson.annotations.SerializedName
data class OrderListResponse(
@field:SerializedName("orders")
val orders: List<OrdersItem?>? = null,
@field:SerializedName("message")
val message: String? = null
)
data class Voucher(
@field:SerializedName("name")
val name: Any? = null,
@field:SerializedName("voucher_id")
val voucherId: Any? = null,
@field:SerializedName("voucher_code")
val voucherCode: Any? = null
)
data class Shipment(
@field:SerializedName("receipt_num")
val receiptNum: Any? = null,
@field:SerializedName("courier")
val courier: Any? = null,
@field:SerializedName("price")
val price: Any? = null,
@field:SerializedName("service")
val service: Any? = null,
@field:SerializedName("shipment_id")
val shipmentId: Any? = null,
@field:SerializedName("status")
val status: Any? = null
)
data class OrderItemsItem(
@field:SerializedName("review_id")
val reviewId: Int? = null,
@field:SerializedName("quantity")
val quantity: Int? = null,
@field:SerializedName("price")
val price: Int? = null,
@field:SerializedName("subtotal")
val subtotal: Int? = null,
@field:SerializedName("product_image")
val productImage: String? = null,
@field:SerializedName("store_name")
val storeName: String? = null,
@field:SerializedName("product_price")
val productPrice: Int? = null,
@field:SerializedName("product_name")
val productName: String? = null
)
data class Address(
@field:SerializedName("is_store_location")
val isStoreLocation: Boolean? = null,
@field:SerializedName("province_id")
val provinceId: Int? = null,
@field:SerializedName("street")
val street: String? = null,
@field:SerializedName("subdistrict")
val subdistrict: String? = null,
@field:SerializedName("latitude")
val latitude: Any? = null,
@field:SerializedName("address_id")
val addressId: Int? = null,
@field:SerializedName("detail")
val detail: String? = null,
@field:SerializedName("postal_code")
val postalCode: String? = null,
@field:SerializedName("longitude")
val longitude: Any? = null,
@field:SerializedName("city_id")
val cityId: Int? = null
)
data class Payment(
@field:SerializedName("evidence")
val evidence: Any? = null,
@field:SerializedName("uploaded_at")
val uploadedAt: Any? = null,
@field:SerializedName("payment_id")
val paymentId: Any? = null
)
data class OrdersItem(
@field:SerializedName("address")
val address: Address? = null,
@field:SerializedName("shipment")
val shipment: Shipment? = null,
@field:SerializedName("voucher")
val voucher: Voucher? = null,
@field:SerializedName("address_id")
val addressId: Int? = null,
@field:SerializedName("is_negotiable")
val isNegotiable: Boolean? = null,
@field:SerializedName("created_at")
val createdAt: String? = null,
@field:SerializedName("payment_method_id")
val paymentMethodId: Int? = null,
@field:SerializedName("updated_at")
val updatedAt: String? = null,
@field:SerializedName("user_id")
val userId: Int? = null,
@field:SerializedName("total_amount")
val totalAmount: String? = null,
@field:SerializedName("voucher_id")
val voucherId: Any? = null,
@field:SerializedName("payment")
val payment: Payment? = null,
@field:SerializedName("order_id")
val orderId: Int? = null,
@field:SerializedName("username")
val username: String? = null,
@field:SerializedName("status")
val status: String? = null,
@field:SerializedName("order_items")
val orderItems: List<OrderItemsItem?>? = null
)

View File

@ -0,0 +1,9 @@
package com.alya.ecommerce_serang.data.api.response.store.orders
import com.google.gson.annotations.SerializedName
data class PaymentConfirmationResponse(
@field:SerializedName("message")
val message: String? = null
)

View File

@ -0,0 +1,75 @@
package com.alya.ecommerce_serang.data.api.response.store.orders
import com.google.gson.annotations.SerializedName
data class UpdateOrderItemResponse(
@field:SerializedName("message")
val message: String? = null,
@field:SerializedName("updatedOrder")
val updatedOrder: UpdatedOrder? = null,
@field:SerializedName("updatedItems")
val updatedItems: List<UpdatedItemsItem?>? = null
)
data class UpdatedItemsItem(
@field:SerializedName("quantity")
val quantity: Int? = null,
@field:SerializedName("price")
val price: String? = null,
@field:SerializedName("subtotal")
val subtotal: String? = null,
@field:SerializedName("product_id")
val productId: Int? = null,
@field:SerializedName("id")
val id: Int? = null,
@field:SerializedName("order_id")
val orderId: Int? = null
)
data class UpdatedOrder(
@field:SerializedName("auto_canceled_at")
val autoCanceledAt: String? = null,
@field:SerializedName("payment_method_id")
val paymentMethodId: Int? = null,
@field:SerializedName("auto_completed_at")
val autoCompletedAt: String? = null,
@field:SerializedName("updated_at")
val updatedAt: String? = null,
@field:SerializedName("total_amount")
val totalAmount: String? = null,
@field:SerializedName("user_id")
val userId: Int? = null,
@field:SerializedName("address_id")
val addressId: Int? = null,
@field:SerializedName("is_negotiable")
val isNegotiable: Boolean? = null,
@field:SerializedName("created_at")
val createdAt: String? = null,
@field:SerializedName("voucher_id")
val voucherId: Any? = null,
@field:SerializedName("id")
val id: Int? = null,
@field:SerializedName("status")
val status: String? = null
)

View File

@ -1,5 +1,7 @@
package com.alya.ecommerce_serang.data.api.response.product
package com.alya.ecommerce_serang.data.api.response.store.product
import com.alya.ecommerce_serang.data.api.dto.Preorder
import com.alya.ecommerce_serang.data.api.dto.Product
import com.google.gson.annotations.SerializedName
data class CreateProductResponse(
@ -13,15 +15,3 @@ data class CreateProductResponse(
@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

@ -0,0 +1,9 @@
package com.alya.ecommerce_serang.data.api.response.store.product
import com.google.gson.annotations.SerializedName
data class DeleteProductResponse(
@field:SerializedName("message")
val message: String? = null
)

View File

@ -0,0 +1,13 @@
package com.alya.ecommerce_serang.data.api.response.store.product
import com.alya.ecommerce_serang.data.api.dto.Product
import com.google.gson.annotations.SerializedName
data class UpdateProductResponse(
@field:SerializedName("product")
val product: Product? = null,
@field:SerializedName("message")
val message: String? = null
)

View File

@ -1,4 +1,4 @@
package com.alya.ecommerce_serang.data.api.response
package com.alya.ecommerce_serang.data.api.response.store.product
import com.alya.ecommerce_serang.data.api.dto.ProductsItem
import com.google.gson.annotations.SerializedName
@ -10,4 +10,4 @@ data class ViewStoreProductsResponse(
@field:SerializedName("products")
val products: List<ProductsItem?>? = null
)
)

View File

@ -9,40 +9,42 @@ import com.alya.ecommerce_serang.data.api.dto.OrderRequestBuy
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.UpdateCart
import com.alya.ecommerce_serang.data.api.response.product.CreateProductResponse
import com.alya.ecommerce_serang.data.api.response.ViewStoreProductsResponse
import com.alya.ecommerce_serang.data.api.response.store.product.CreateProductResponse
import com.alya.ecommerce_serang.data.api.response.store.product.ViewStoreProductsResponse
import okhttp3.MultipartBody
import okhttp3.RequestBody
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.cart.AddCartResponse
import com.alya.ecommerce_serang.data.api.response.cart.ListCartResponse
import com.alya.ecommerce_serang.data.api.response.cart.UpdateCartResponse
import com.alya.ecommerce_serang.data.api.response.order.CourierCostResponse
import com.alya.ecommerce_serang.data.api.response.order.CreateOrderResponse
import com.alya.ecommerce_serang.data.api.response.order.ListCityResponse
import com.alya.ecommerce_serang.data.api.response.order.ListProvinceResponse
import com.alya.ecommerce_serang.data.api.response.product.AllProductResponse
import com.alya.ecommerce_serang.data.api.response.product.CategoryResponse
import com.alya.ecommerce_serang.data.api.response.product.DetailStoreProductResponse
import com.alya.ecommerce_serang.data.api.response.product.ProductResponse
import com.alya.ecommerce_serang.data.api.response.product.ReviewProductResponse
import com.alya.ecommerce_serang.data.api.response.product.StoreResponse
import com.alya.ecommerce_serang.data.api.response.profile.AddressResponse
import com.alya.ecommerce_serang.data.api.response.profile.CreateAddressResponse
import com.alya.ecommerce_serang.data.api.response.profile.ProfileResponse
import com.alya.ecommerce_serang.data.api.response.customer.cart.AddCartResponse
import com.alya.ecommerce_serang.data.api.response.customer.cart.ListCartResponse
import com.alya.ecommerce_serang.data.api.response.customer.cart.UpdateCartResponse
import com.alya.ecommerce_serang.data.api.response.customer.order.CourierCostResponse
import com.alya.ecommerce_serang.data.api.response.customer.order.CreateOrderResponse
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.product.AllProductResponse
import com.alya.ecommerce_serang.data.api.response.customer.product.CategoryResponse
import com.alya.ecommerce_serang.data.api.response.customer.product.DetailStoreProductResponse
import com.alya.ecommerce_serang.data.api.response.customer.product.ProductResponse
import com.alya.ecommerce_serang.data.api.response.customer.product.ReviewProductResponse
import com.alya.ecommerce_serang.data.api.response.customer.product.StoreResponse
import com.alya.ecommerce_serang.data.api.response.customer.profile.AddressResponse
import com.alya.ecommerce_serang.data.api.response.customer.profile.CreateAddressResponse
import com.alya.ecommerce_serang.data.api.response.customer.profile.ProfileResponse
import com.alya.ecommerce_serang.data.api.response.store.product.DeleteProductResponse
import com.alya.ecommerce_serang.data.api.response.store.product.UpdateProductResponse
import retrofit2.Call
import retrofit2.Response
import retrofit2.http.Body
import retrofit2.http.DELETE
import retrofit2.http.GET
import retrofit2.http.Header
import retrofit2.http.HeaderMap
import retrofit2.http.Multipart
import retrofit2.http.POST
import retrofit2.http.Part
import retrofit2.http.PUT
import retrofit2.http.Path
import retrofit2.http.Query
interface ApiService {
@POST("registeruser")
@ -126,11 +128,23 @@ interface ApiService {
@Part("duration") duration: RequestBody,
@Part("category_id") categoryId: RequestBody,
@Part("status") status: RequestBody,
@Part("condition") condition: RequestBody,
@Part image: MultipartBody.Part?,
@Part sppirt: MultipartBody.Part?,
@Part halal: MultipartBody.Part?
): Response<CreateProductResponse>
@PUT("store/editproduct/{id}")
suspend fun updateProduct(
@Path("id") productId: Int?,
@Body updatedProduct: Map<String, Any?>
): Response<UpdateProductResponse>
@DELETE("store/deleteproduct/{id}")
suspend fun deleteProduct(
@Path("id") productId: Int
): Response<DeleteProductResponse>
@GET("cart_item")
suspend fun getCart (): Response<ListCartResponse>

View File

@ -2,7 +2,7 @@ package com.alya.ecommerce_serang.data.repository
import android.util.Log
import com.alya.ecommerce_serang.data.api.dto.Store
import com.alya.ecommerce_serang.data.api.response.product.StoreResponse
import com.alya.ecommerce_serang.data.api.response.customer.product.StoreResponse
import com.alya.ecommerce_serang.data.api.retrofit.ApiService
import retrofit2.HttpException
import java.io.IOException

View File

@ -5,16 +5,16 @@ import com.alya.ecommerce_serang.data.api.dto.CourierCostRequest
import com.alya.ecommerce_serang.data.api.dto.CreateAddressRequest
import com.alya.ecommerce_serang.data.api.dto.OrderRequest
import com.alya.ecommerce_serang.data.api.dto.OrderRequestBuy
import com.alya.ecommerce_serang.data.api.response.cart.DataItem
import com.alya.ecommerce_serang.data.api.response.order.CourierCostResponse
import com.alya.ecommerce_serang.data.api.response.order.CreateOrderResponse
import com.alya.ecommerce_serang.data.api.response.order.ListCityResponse
import com.alya.ecommerce_serang.data.api.response.order.ListProvinceResponse
import com.alya.ecommerce_serang.data.api.response.product.ProductResponse
import com.alya.ecommerce_serang.data.api.response.product.StoreProduct
import com.alya.ecommerce_serang.data.api.response.product.StoreResponse
import com.alya.ecommerce_serang.data.api.response.profile.AddressResponse
import com.alya.ecommerce_serang.data.api.response.profile.CreateAddressResponse
import com.alya.ecommerce_serang.data.api.response.customer.cart.DataItem
import com.alya.ecommerce_serang.data.api.response.customer.order.CourierCostResponse
import com.alya.ecommerce_serang.data.api.response.customer.order.CreateOrderResponse
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.product.ProductResponse
import com.alya.ecommerce_serang.data.api.response.customer.product.StoreProduct
import com.alya.ecommerce_serang.data.api.response.customer.product.StoreResponse
import com.alya.ecommerce_serang.data.api.response.customer.profile.AddressResponse
import com.alya.ecommerce_serang.data.api.response.customer.profile.CreateAddressResponse
import com.alya.ecommerce_serang.data.api.retrofit.ApiService
import retrofit2.Response

View File

@ -3,20 +3,20 @@ package com.alya.ecommerce_serang.data.repository
import android.util.Log
import com.alya.ecommerce_serang.data.api.dto.CartItem
import com.alya.ecommerce_serang.data.api.dto.CategoryItem
import com.alya.ecommerce_serang.data.api.dto.Preorder
import com.alya.ecommerce_serang.data.api.dto.ProductsItem
import com.alya.ecommerce_serang.data.api.response.product.CreateProductResponse
import com.alya.ecommerce_serang.data.api.response.cart.AddCartResponse
import com.alya.ecommerce_serang.data.api.response.product.ProductResponse
import com.alya.ecommerce_serang.data.api.response.product.ReviewsItem
import com.alya.ecommerce_serang.data.api.response.product.StoreProduct
import com.alya.ecommerce_serang.data.api.response.store.product.CreateProductResponse
import com.alya.ecommerce_serang.data.api.response.customer.cart.AddCartResponse
import com.alya.ecommerce_serang.data.api.response.customer.product.ProductResponse
import com.alya.ecommerce_serang.data.api.response.customer.product.ReviewsItem
import com.alya.ecommerce_serang.data.api.response.customer.product.StoreProduct
import com.alya.ecommerce_serang.data.api.response.store.product.UpdateProductResponse
import com.alya.ecommerce_serang.data.api.retrofit.ApiService
import com.alya.ecommerce_serang.utils.SessionManager
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import okhttp3.MediaType.Companion.toMediaTypeOrNull
import okhttp3.MultipartBody
import okhttp3.RequestBody
import java.io.File
class ProductRepository(private val apiService: ApiService) {
suspend fun getAllProducts(): Result<List<ProductsItem>> =
@ -158,9 +158,10 @@ class ProductRepository(private val apiService: ApiService) {
minOrder: Int,
weight: Int,
isPreOrder: Boolean,
duration: Int,
preorder: Preorder,
categoryId: Int,
status: String,
condition: String,
imagePart: MultipartBody.Part?,
sppirtPart: MultipartBody.Part?,
halalPart: MultipartBody.Part?
@ -174,9 +175,10 @@ class ProductRepository(private val apiService: ApiService) {
minOrder = RequestBody.create("text/plain".toMediaTypeOrNull(), minOrder.toString()),
weight = RequestBody.create("text/plain".toMediaTypeOrNull(), weight.toString()),
isPreOrder = RequestBody.create("text/plain".toMediaTypeOrNull(), isPreOrder.toString()),
duration = RequestBody.create("text/plain".toMediaTypeOrNull(), duration.toString()),
duration = RequestBody.create("text/plain".toMediaTypeOrNull(), preorder.duration.toString()),
categoryId = RequestBody.create("text/plain".toMediaTypeOrNull(), categoryId.toString()),
status = RequestBody.create("text/plain".toMediaTypeOrNull(), status),
condition = RequestBody.create("text/plain".toMediaTypeOrNull(), condition),
image = imagePart,
sppirt = sppirtPart,
halal = halalPart
@ -192,6 +194,31 @@ class ProductRepository(private val apiService: ApiService) {
}
}
suspend fun updateProduct(productId: Int?, updatedProduct: Map<String, Any?>) : UpdateProductResponse {
// Build the request with the updated fields
val response = apiService.updateProduct(productId, updatedProduct)
if (response.isSuccessful) {
return response.body()!!
} else {
throw Exception("Gagal memperbarui produk: ${response.code()}")
}
}
suspend fun deleteProduct(productId: Int): Result<Unit> {
return withContext(Dispatchers.IO) {
try {
val response = apiService.deleteProduct(productId)
if (response.isSuccessful) {
Result.Success(Unit)
} else {
Result.Error(Exception("Gagal menghapus produk: ${response.code()}"))
}
} catch (e: Exception) {
Result.Error(e)
}
}
}
companion object {
private const val TAG = "ProductRepository"

View File

@ -6,7 +6,7 @@ import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.alya.ecommerce_serang.R
import com.alya.ecommerce_serang.data.api.dto.CheckoutData
import com.alya.ecommerce_serang.data.api.response.cart.CartItemsItem
import com.alya.ecommerce_serang.data.api.response.customer.cart.CartItemsItem
import com.alya.ecommerce_serang.databinding.ItemOrderProductBinding
import com.alya.ecommerce_serang.databinding.ItemOrderSellerBinding
import com.bumptech.glide.Glide

View File

@ -11,7 +11,7 @@ import androidx.recyclerview.widget.LinearLayoutManager
import com.alya.ecommerce_serang.data.api.dto.CheckoutData
import com.alya.ecommerce_serang.data.api.dto.OrderRequest
import com.alya.ecommerce_serang.data.api.dto.OrderRequestBuy
import com.alya.ecommerce_serang.data.api.response.product.PaymentInfoItem
import com.alya.ecommerce_serang.data.api.response.customer.product.PaymentInfoItem
import com.alya.ecommerce_serang.data.api.retrofit.ApiConfig
import com.alya.ecommerce_serang.data.repository.OrderRepository
import com.alya.ecommerce_serang.databinding.ActivityCheckoutBinding

View File

@ -8,10 +8,10 @@ import androidx.lifecycle.viewModelScope
import com.alya.ecommerce_serang.data.api.dto.CheckoutData
import com.alya.ecommerce_serang.data.api.dto.OrderRequest
import com.alya.ecommerce_serang.data.api.dto.OrderRequestBuy
import com.alya.ecommerce_serang.data.api.response.cart.CartItemsItem
import com.alya.ecommerce_serang.data.api.response.cart.DataItem
import com.alya.ecommerce_serang.data.api.response.product.PaymentInfoItem
import com.alya.ecommerce_serang.data.api.response.profile.AddressesItem
import com.alya.ecommerce_serang.data.api.response.customer.cart.CartItemsItem
import com.alya.ecommerce_serang.data.api.response.customer.cart.DataItem
import com.alya.ecommerce_serang.data.api.response.customer.product.PaymentInfoItem
import com.alya.ecommerce_serang.data.api.response.customer.profile.AddressesItem
import com.alya.ecommerce_serang.data.repository.OrderRepository
import com.alya.ecommerce_serang.data.repository.Result
import kotlinx.coroutines.launch

View File

@ -4,7 +4,7 @@ import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.alya.ecommerce_serang.R
import com.alya.ecommerce_serang.data.api.response.product.PaymentInfoItem
import com.alya.ecommerce_serang.data.api.response.customer.product.PaymentInfoItem
import com.alya.ecommerce_serang.databinding.ItemPaymentMethodBinding
import com.bumptech.glide.Glide
import com.bumptech.glide.request.RequestOptions

View File

@ -3,8 +3,8 @@ package com.alya.ecommerce_serang.ui.order
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.alya.ecommerce_serang.data.api.response.order.CourierCostsItem
import com.alya.ecommerce_serang.data.api.response.order.ServicesItem
import com.alya.ecommerce_serang.data.api.response.customer.order.CourierCostsItem
import com.alya.ecommerce_serang.data.api.response.customer.order.ServicesItem
import com.alya.ecommerce_serang.databinding.ItemShippingOrderBinding
class ShippingAdapter(

View File

@ -6,7 +6,7 @@ import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.alya.ecommerce_serang.data.api.dto.CostProduct
import com.alya.ecommerce_serang.data.api.dto.CourierCostRequest
import com.alya.ecommerce_serang.data.api.response.order.CourierCostsItem
import com.alya.ecommerce_serang.data.api.response.customer.order.CourierCostsItem
import com.alya.ecommerce_serang.data.repository.OrderRepository
import com.alya.ecommerce_serang.data.repository.Result
import kotlinx.coroutines.launch

View File

@ -4,7 +4,7 @@ import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.alya.ecommerce_serang.R
import com.alya.ecommerce_serang.data.api.response.cart.CartItemsItem
import com.alya.ecommerce_serang.data.api.response.customer.cart.CartItemsItem
import com.alya.ecommerce_serang.databinding.ItemOrderProductBinding
import com.bumptech.glide.Glide
import java.text.NumberFormat

View File

@ -15,8 +15,8 @@ import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
import com.alya.ecommerce_serang.data.api.dto.CreateAddressRequest
import com.alya.ecommerce_serang.data.api.dto.UserProfile
import com.alya.ecommerce_serang.data.api.response.order.CitiesItem
import com.alya.ecommerce_serang.data.api.response.order.ProvincesItem
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.api.retrofit.ApiConfig
import com.alya.ecommerce_serang.data.api.retrofit.ApiService
import com.alya.ecommerce_serang.data.repository.OrderRepository

View File

@ -5,8 +5,8 @@ import androidx.lifecycle.SavedStateHandle
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.alya.ecommerce_serang.data.api.dto.CreateAddressRequest
import com.alya.ecommerce_serang.data.api.response.order.CitiesItem
import com.alya.ecommerce_serang.data.api.response.order.ProvincesItem
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.OrderRepository
import com.alya.ecommerce_serang.data.repository.Result
import kotlinx.coroutines.flow.MutableStateFlow

View File

@ -9,7 +9,7 @@ import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView
import com.alya.ecommerce_serang.R
import com.alya.ecommerce_serang.data.api.response.profile.AddressesItem
import com.alya.ecommerce_serang.data.api.response.customer.profile.AddressesItem
import com.google.android.material.card.MaterialCardView
class AddressAdapter(

View File

@ -4,7 +4,7 @@ import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.alya.ecommerce_serang.data.api.response.profile.AddressesItem
import com.alya.ecommerce_serang.data.api.response.customer.profile.AddressesItem
import com.alya.ecommerce_serang.data.repository.OrderRepository
import kotlinx.coroutines.launch

View File

@ -2,8 +2,8 @@ package com.alya.ecommerce_serang.ui.order.address
import android.content.Context
import android.widget.ArrayAdapter
import com.alya.ecommerce_serang.data.api.response.order.CitiesItem
import com.alya.ecommerce_serang.data.api.response.order.ProvincesItem
import com.alya.ecommerce_serang.data.api.response.customer.order.CitiesItem
import com.alya.ecommerce_serang.data.api.response.customer.order.ProvincesItem
// UI adapters and helpers
class ProvinceAdapter(

View File

@ -16,9 +16,9 @@ import com.alya.ecommerce_serang.BuildConfig.BASE_URL
import com.alya.ecommerce_serang.R
import com.alya.ecommerce_serang.data.api.dto.CartItem
import com.alya.ecommerce_serang.data.api.dto.ProductsItem
import com.alya.ecommerce_serang.data.api.response.product.Product
import com.alya.ecommerce_serang.data.api.response.product.ReviewsItem
import com.alya.ecommerce_serang.data.api.response.product.StoreProduct
import com.alya.ecommerce_serang.data.api.response.customer.product.Product
import com.alya.ecommerce_serang.data.api.response.customer.product.ReviewsItem
import com.alya.ecommerce_serang.data.api.response.customer.product.StoreProduct
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.ProductRepository

View File

@ -7,10 +7,10 @@ import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.alya.ecommerce_serang.data.api.dto.CartItem
import com.alya.ecommerce_serang.data.api.dto.ProductsItem
import com.alya.ecommerce_serang.data.api.response.cart.AddCartResponse
import com.alya.ecommerce_serang.data.api.response.product.Product
import com.alya.ecommerce_serang.data.api.response.product.ReviewsItem
import com.alya.ecommerce_serang.data.api.response.product.StoreProduct
import com.alya.ecommerce_serang.data.api.response.customer.cart.AddCartResponse
import com.alya.ecommerce_serang.data.api.response.customer.product.Product
import com.alya.ecommerce_serang.data.api.response.customer.product.ReviewsItem
import com.alya.ecommerce_serang.data.api.response.customer.product.StoreProduct
import com.alya.ecommerce_serang.data.repository.ProductRepository
import com.alya.ecommerce_serang.data.repository.Result
import kotlinx.coroutines.launch

View File

@ -6,7 +6,7 @@ import android.view.ViewGroup
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import com.alya.ecommerce_serang.R
import com.alya.ecommerce_serang.data.api.response.product.ReviewsItem
import com.alya.ecommerce_serang.data.api.response.customer.product.ReviewsItem
import java.text.SimpleDateFormat
import java.util.Locale
import java.util.TimeZone

View File

@ -36,7 +36,6 @@ class ProductActivity : AppCompatActivity() {
setupHeader()
setupRecyclerView()
observeViewModel()
binding.progressBar.visibility = View.VISIBLE
@ -59,7 +58,7 @@ class ProductActivity : AppCompatActivity() {
}
is Result.Error -> {
binding.progressBar.visibility = View.GONE
Toast.makeText(this, "Failed to load products: ${result.exception.message}", Toast.LENGTH_SHORT).show()
Toast.makeText(this, "Gagal memuat produk: ${result.exception.message}", Toast.LENGTH_SHORT).show()
}
}
}
@ -74,7 +73,9 @@ class ProductActivity : AppCompatActivity() {
}
binding.header.headerRightText.setOnClickListener {
startActivity(Intent(this, StoreProductDetailActivity::class.java))
val intent = Intent(this, StoreProductDetailActivity::class.java)
intent.putExtra("is_editing", false)
startActivity(intent)
}
}

View File

@ -1,13 +1,18 @@
package com.alya.ecommerce_serang.ui.profile.mystore.product
import android.app.AlertDialog
import android.content.Intent
import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.lifecycle.ViewModelProvider
import com.alya.ecommerce_serang.R
import com.alya.ecommerce_serang.data.api.dto.ProductsItem
import com.alya.ecommerce_serang.databinding.FragmentProductOptionsBottomSheetBinding
import com.alya.ecommerce_serang.utils.viewmodel.ProductViewModel
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
class ProductOptionsBottomSheetFragment(private val product: ProductsItem) : BottomSheetDialogFragment() {
@ -27,15 +32,25 @@ class ProductOptionsBottomSheetFragment(private val product: ProductsItem) : Bot
super.onViewCreated(view, savedInstanceState)
binding.btnEditProduct.setOnClickListener {
// Handle editing product
// Example: Open the edit activity or fragment
val intent = Intent(requireContext(), StoreProductDetailActivity::class.java)
intent.putExtra("product_id", product.id)
intent.putExtra("is_editing", true)
startActivity(intent)
dismiss()
}
binding.btnDeleteProduct.setOnClickListener {
// Handle deleting product
// Example: Show confirmation dialog
dismiss()
AlertDialog.Builder(requireContext())
.setTitle("Hapus Produk?")
.setMessage("Produk yang dihapus tidak dapat dikembalikan.")
.setPositiveButton("Ya, Hapus") { _, _ ->
val viewModel = ViewModelProvider(this).get(ProductViewModel::class.java)
viewModel.deleteProduct(product.id)
Toast.makeText(context, "Produk berhasil dihapus", Toast.LENGTH_SHORT).show()
dismiss()
}
.setNegativeButton("Batalkan", null)
.show()
}
}

View File

@ -15,6 +15,8 @@ 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.dto.Preorder
import com.alya.ecommerce_serang.data.api.dto.Product
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
@ -22,12 +24,14 @@ 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 com.bumptech.glide.Glide
import okhttp3.MediaType.Companion.toMediaTypeOrNull
import okhttp3.MultipartBody
import okhttp3.RequestBody
import java.io.File
import java.io.FileOutputStream
import kotlin.getValue
import androidx.core.net.toUri
class StoreProductDetailActivity : AppCompatActivity() {
@ -37,6 +41,7 @@ class StoreProductDetailActivity : AppCompatActivity() {
private var imageUri: Uri? = null
private var sppirtUri: Uri? = null
private var halalUri: Uri? = null
private var productId: Int? = null
private val viewModel: ProductViewModel by viewModels {
BaseViewModelFactory {
@ -79,9 +84,50 @@ class StoreProductDetailActivity : AppCompatActivity() {
binding = ActivityStoreProductDetailBinding.inflate(layoutInflater)
setContentView(binding.root)
setupHeader()
val isEditing = intent.getBooleanExtra("is_editing", false)
productId = intent.getIntExtra("product_id", -1)
// Fetch categories
binding.header.headerTitle.text = if (isEditing) "Ubah Produk" else "Tambah Produk"
// if (isEditing && productId != null) {
// viewModel.productDetail.observe(this) { product ->
// product?.let {
// populateForm(it)
// }
// }
// viewModel.loadProductDetail(productId!!)
// }
setupCategorySpinner()
setupImagePickers()
var conditionList = listOf("Baru", "Pernah Dipakai")
val adapterCondition = ArrayAdapter(this, android.R.layout.simple_spinner_item, conditionList)
adapterCondition.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
binding.spinnerKondisiProduk.adapter = adapterCondition
// Setup Pre-Order visibility
binding.switchIsPreOrder.setOnCheckedChangeListener { _, isChecked ->
binding.layoutDurasi.visibility = if (isChecked) View.VISIBLE else View.GONE
validateForm()
}
validateForm()
binding.btnSaveProduct.setOnClickListener {
if (isEditing) {
updateProduct(productId)
} else {
addProduct()
}
}
binding.header.headerLeftIcon.setOnClickListener {
onBackPressedDispatcher.onBackPressed()
}
}
private fun setupCategorySpinner() {
viewModel.loadCategories()
viewModel.categoryList.observe(this) { result ->
if (result is Result.Success) {
@ -91,13 +137,9 @@ class StoreProductDetailActivity : AppCompatActivity() {
binding.spinnerKategoriProduk.adapter = adapter
}
}
}
// Setup Pre-Order visibility
binding.switchIsPreOrder.setOnCheckedChangeListener { _, isChecked ->
binding.layoutDurasi.visibility = if (isChecked) View.VISIBLE else View.GONE
validateForm()
}
private fun setupImagePickers() {
binding.tvTambahFoto.setOnClickListener {
val intent = Intent(Intent.ACTION_PICK).apply { type = "image/*" }
imagePickerLauncher.launch(intent)
@ -125,15 +167,37 @@ class StoreProductDetailActivity : AppCompatActivity() {
halalUri = null
binding.switcherHalal.showPrevious()
}
}
private fun populateForm(product: Product) {
binding.edtNamaProduk.setText(product.name)
binding.edtDeskripsiProduk.setText(product.description)
binding.edtHargaProduk.setText(product.price.toString())
binding.edtStokProduk.setText(product.stock.toString())
binding.edtMinOrder.setText(product.minOrder.toString())
binding.edtBeratProduk.setText(product.weight.toString())
binding.switchIsPreOrder.isChecked = product.isPreOrder ?: false
binding.switchIsActive.isChecked = product.status == "active"
binding.spinnerKondisiProduk.setSelection(if (product.condition == "Baru") 0 else 1)
product.categoryId?.let {
binding.spinnerKategoriProduk.setSelection(categoryList.indexOfFirst { it.id == product.categoryId })
}
Glide.with(this).load(product.image).into(binding.ivPreviewFoto)
binding.switcherFotoProduk.showNext()
product.sppirt?.let {
binding.tvSppirtName.text = getFileName(it.toUri())
binding.switcherSppirt.showNext()
}
product.halal?.let {
binding.tvHalalName.text = getFileName(it.toUri())
binding.switcherHalal.showNext()
}
validateForm()
binding.btnSaveProduct.setOnClickListener {
if (!binding.btnSaveProduct.isEnabled) {
return@setOnClickListener
}
submitProduct()
}
}
private fun isValidFile(uri: Uri): Boolean {
@ -145,6 +209,36 @@ class StoreProductDetailActivity : AppCompatActivity() {
return uri.lastPathSegment?.split("/")?.last() ?: "unknown_file"
}
private fun uriToNamedFile(uri: Uri, context: Context, prefix: String): File {
val extension = context.contentResolver.getType(uri)?.substringAfter("/") ?: "jpg"
val filename = "$prefix-${System.currentTimeMillis()}.$extension"
val file = File(context.cacheDir, filename)
context.contentResolver.openInputStream(uri)?.use { input ->
FileOutputStream(file).use { output -> input.copyTo(output) }
}
return file
}
fun getMimeType(file: File): String {
val extension = file.extension
return when (extension.lowercase()) {
"jpg", "jpeg" -> "image/jpeg"
"png" -> "image/png"
"pdf" -> "application/pdf"
else -> "application/octet-stream"
}
}
fun createPartFromFile(field: String, file: File?): MultipartBody.Part? {
return file?.let {
val mimeType = getMimeType(it).toMediaTypeOrNull()
val requestBody = RequestBody.create(mimeType, it)
MultipartBody.Part.createFormData(field, it.name, requestBody)
}
}
private fun validateForm() {
val valid = binding.edtNamaProduk.text.isNotBlank() &&
binding.edtDeskripsiProduk.text.isNotBlank() &&
@ -164,19 +258,7 @@ class StoreProductDetailActivity : AppCompatActivity() {
)
}
private fun uriToNamedFile(uri: Uri, context: Context, prefix: String): File {
val extension = context.contentResolver.getType(uri)?.substringAfter("/") ?: "jpg"
val filename = "$prefix-${System.currentTimeMillis()}.$extension"
val file = File(context.cacheDir, filename)
context.contentResolver.openInputStream(uri)?.use { input ->
FileOutputStream(file).use { output -> input.copyTo(output) }
}
return file
}
private fun submitProduct() {
private fun addProduct() {
val name = binding.edtNamaProduk.text.toString()
val description = binding.edtDeskripsiProduk.text.toString()
val price = binding.edtHargaProduk.text.toString().toInt()
@ -186,6 +268,7 @@ class StoreProductDetailActivity : AppCompatActivity() {
val isPreOrder = binding.switchIsPreOrder.isChecked
val duration = if (isPreOrder) binding.edtDurasi.text.toString().toInt() else 0
val status = if (binding.switchIsActive.isChecked) "active" else "inactive"
val condition = binding.spinnerKondisiProduk.selectedItem.toString()
val categoryId = categoryList.getOrNull(binding.spinnerKategoriProduk.selectedItemPosition)?.id ?: 0
val imageFile = imageUri?.let { uriToNamedFile(it, this, "productimg") }
@ -199,8 +282,10 @@ class StoreProductDetailActivity : AppCompatActivity() {
val sppirtPart = sppirtFile?.let { createPartFromFile("sppirt", it) }
val halalPart = halalFile?.let { createPartFromFile("halal", it) }
val preorder = Preorder(productId = productId, duration = duration)
viewModel.addProduct(
name, description, price, stock, minOrder, weight, isPreOrder, duration, categoryId, status, imagePart, sppirtPart, halalPart
name, description, price, stock, minOrder, weight, isPreOrder, preorder, categoryId, status, condition, imagePart, sppirtPart, halalPart
)
viewModel.productCreationResult.observe(this) { result ->
@ -208,7 +293,7 @@ class StoreProductDetailActivity : AppCompatActivity() {
is Result.Loading -> binding.btnSaveProduct.isEnabled = false
is Result.Success -> {
val product = result.data.product
Toast.makeText(this, "Product Created: ${product?.productName}", Toast.LENGTH_SHORT).show()
Toast.makeText(this, "Product Created: ${product?.name}", Toast.LENGTH_SHORT).show()
finish()
}
is Result.Error -> {
@ -219,26 +304,24 @@ class StoreProductDetailActivity : AppCompatActivity() {
}
}
fun getMimeType(file: File): String {
val extension = file.extension
return when (extension.lowercase()) {
"jpg", "jpeg" -> "image/jpeg"
"png" -> "image/png"
"pdf" -> "application/pdf"
else -> "application/octet-stream"
}
}
private fun updateProduct(productId: Int?) {
val updatedProduct = mapOf(
"name" to binding.edtNamaProduk.text.toString(),
"description" to binding.edtDeskripsiProduk.text.toString(),
"price" to binding.edtHargaProduk.text.toString(),
"stock" to binding.edtStokProduk.text.toString().toInt(),
"min_order" to binding.edtMinOrder.text.toString().toInt(),
"weight" to binding.edtBeratProduk.text.toString().toInt(),
"is_pre_order" to binding.switchIsPreOrder.isChecked,
"duration" to binding.edtDurasi.text.toString().toInt(),
"category_id" to categoryList[binding.spinnerKategoriProduk.selectedItemPosition].id,
"status" to if (binding.switchIsActive.isChecked) "active" else "inactive",
"condition" to binding.spinnerKondisiProduk.selectedItem.toString(),
"productimg" to imageUri?.path,
"sppirt" to sppirtUri?.path,
"halal" to halalUri?.path
)
fun createPartFromFile(field: String, file: File?): MultipartBody.Part? {
return file?.let {
val mimeType = getMimeType(it).toMediaTypeOrNull()
val requestBody = RequestBody.create(mimeType, it)
MultipartBody.Part.createFormData(field, it.name, requestBody)
}
}
private fun setupHeader() {
binding.header.headerTitle.text = "Tambah Produk"
binding.header.headerLeftIcon.setOnClickListener { onBackPressedDispatcher.onBackPressed() }
viewModel.updateProduct(productId, updatedProduct)
}
}

View File

@ -5,11 +5,13 @@ import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.alya.ecommerce_serang.data.api.dto.CategoryItem
import com.alya.ecommerce_serang.data.api.dto.Preorder
import com.alya.ecommerce_serang.data.api.dto.ProductsItem
import com.alya.ecommerce_serang.data.api.response.product.CreateProductResponse
import com.alya.ecommerce_serang.data.api.response.product.Product
import com.alya.ecommerce_serang.data.api.response.product.ReviewsItem
import com.alya.ecommerce_serang.data.api.response.product.StoreProduct
import com.alya.ecommerce_serang.data.api.response.store.product.CreateProductResponse
import com.alya.ecommerce_serang.data.api.response.customer.product.Product
import com.alya.ecommerce_serang.data.api.response.customer.product.ReviewsItem
import com.alya.ecommerce_serang.data.api.response.customer.product.StoreProduct
import com.alya.ecommerce_serang.data.api.response.store.product.UpdateProductResponse
import com.alya.ecommerce_serang.data.repository.ProductRepository
import com.alya.ecommerce_serang.data.repository.Result
import kotlinx.coroutines.launch
@ -20,6 +22,9 @@ class ProductViewModel(private val repository: ProductRepository) : ViewModel()
private val _productCreationResult = MutableLiveData<Result<CreateProductResponse>>()
val productCreationResult: LiveData<Result<CreateProductResponse>> get() = _productCreationResult
private val _productUpdateResult = MutableLiveData<Result<UpdateProductResponse>>()
val productUpdateResult: LiveData<Result<UpdateProductResponse>> get() = _productUpdateResult
private val _productDetail = MutableLiveData<Product?>()
val productDetail: LiveData<Product?> get() = _productDetail
@ -49,6 +54,12 @@ class ProductViewModel(private val repository: ProductRepository) : ViewModel()
}
}
fun loadPreorderProducts(productId: Int) {
viewModelScope.launch {
}
}
fun loadMyStoreProducts() {
viewModelScope.launch {
_productList.value = Result.Loading
@ -76,9 +87,10 @@ class ProductViewModel(private val repository: ProductRepository) : ViewModel()
minOrder: Int,
weight: Int,
isPreOrder: Boolean,
duration: Int,
preorder: Preorder,
categoryId: Int,
status: String,
condition: String,
imagePart: MultipartBody.Part?,
sppirtPart: MultipartBody.Part?,
halalPart: MultipartBody.Part?
@ -86,12 +98,31 @@ class ProductViewModel(private val repository: ProductRepository) : ViewModel()
_productCreationResult.value = Result.Loading
viewModelScope.launch {
val result = repository.addProduct(
name, description, price, stock, minOrder, weight, isPreOrder, duration, categoryId, status, imagePart, sppirtPart, halalPart
name, description, price, stock, minOrder, weight, isPreOrder, preorder, categoryId, status, condition, imagePart, sppirtPart, halalPart
)
_productCreationResult.value = result
}
}
fun updateProduct(productId: Int?, updatedProduct: Map<String, Any?>) {
_productUpdateResult.value = Result.Loading
viewModelScope.launch {
try {
val response = repository.updateProduct(productId, updatedProduct)
_productUpdateResult.value = Result.Success(response)
} catch (e: Exception) {
_productUpdateResult.value = Result.Error(e)
}
}
}
fun deleteProduct(productId: Int) {
viewModelScope.launch {
val result = repository.deleteProduct(productId)
// handle the response (loading, success, or error)
}
}
// Optional: for store detail if you need it later
// fun loadStoreDetail(storeId: Int) {
// viewModelScope.launch {

View File

@ -5,6 +5,6 @@
android:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".data.api.response.cart.CartActivity">
tools:context=".data.api.response.customer.cart.CartActivity">
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -481,66 +481,66 @@
</LinearLayout>
<!-- &lt;!&ndash; Kondisi Produk &ndash;&gt;-->
<!-- <LinearLayout-->
<!-- android:layout_width="match_parent"-->
<!-- android:layout_height="wrap_content"-->
<!-- android:orientation="vertical"-->
<!-- android:layout_marginBottom="24dp">-->
<!-- Kondisi Produk -->
<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">-->
<!-- 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="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"/>-->
<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>-->
</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 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"/>-->
<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" />-->
<!-- 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>
<!-- </LinearLayout>-->
</LinearLayout>
<!-- Pre-Order -->
<LinearLayout