Merge pull request #17 from shaulascr/gracia

gracia
This commit is contained in:
Gracia Hotmauli
2025-04-25 12:26:55 +07:00
committed by GitHub
100 changed files with 1778 additions and 438 deletions

View File

@ -94,6 +94,8 @@ dependencies {
implementation("androidx.swiperefreshlayout:swiperefreshlayout:1.1.0")
implementation("de.hdodenhof:circleimageview:3.1.0")
//maps
implementation("org.osmdroid:osmdroid-android:6.0.3")
// implementation(libs.hilt.android)
// kapt("com.google.dagger:hilt-compiler:2.48")

View File

@ -6,13 +6,13 @@
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<!-- <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />-->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="32"/>
<application
android:allowBackup="true"
android:enableOnBackInvokedCallback="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher"
@ -23,6 +23,15 @@
android:theme="@style/Theme.Ecommerce_serang"
android:usesCleartextTraffic="true"
tools:targetApi="31">
<activity
android:name=".ui.order.detail.AddEvidencePaymentActivity"
android:exported="false" />
<activity
android:name=".ui.order.history.HistoryActivity"
android:exported="false" />
<activity
android:name=".ui.order.detail.PaymentActivity"
android:exported="false" />
<activity
android:name=".ui.order.detail.AddEvidencePaymentActivity"
android:exported="false" />
@ -57,7 +66,7 @@
android:name=".ui.profile.mystore.profile.payment_info.PaymentInfoActivity"
android:exported="false" />
<activity
android:name=".ui.profile.mystore.profile.address.StoreAddressActivity"
android:name=".ui.profile.mystore.profile.address.DetailStoreAddressActivity"
android:exported="false" />
<activity
android:name=".ui.profile.mystore.product.ProductActivity"
@ -81,7 +90,7 @@
android:name=".ui.profile.mystore.balance.BalanceTopUpActivity"
android:exported="false" />
<activity
android:name=".ui.profile.mystore.product.StoreProductDetailActivity"
android:name=".ui.profile.mystore.product.DetailStoreProductActivity"
android:exported="false" />
<activity
android:name=".ui.profile.mystore.profile.DetailStoreProfileActivity"

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,59 @@
package com.alya.ecommerce_serang.data.api.dto
import com.alya.ecommerce_serang.data.api.response.store.orders.Address
import com.alya.ecommerce_serang.data.api.response.store.orders.OrderItemsItem
import com.alya.ecommerce_serang.data.api.response.store.orders.Payment
import com.alya.ecommerce_serang.data.api.response.store.orders.Shipment
import com.alya.ecommerce_serang.data.api.response.store.orders.Voucher
import com.google.gson.annotations.SerializedName
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,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

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

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

View File

@ -0,0 +1,118 @@
package com.alya.ecommerce_serang.data.api.response.store.orders
import com.alya.ecommerce_serang.data.api.dto.OrdersItem
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
)

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

@ -11,47 +11,49 @@ 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.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.order.AddEvidenceResponse
import com.alya.ecommerce_serang.data.api.response.order.ComplaintResponse
import com.alya.ecommerce_serang.data.api.response.order.CompletedOrderResponse
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.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.order.OrderDetailResponse
import com.alya.ecommerce_serang.data.api.response.order.OrderListResponse
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.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.orders.OrderListResponse
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.Field
import retrofit2.http.FormUrlEncoded
import retrofit2.http.GET
import retrofit2.http.Header
import retrofit2.http.HeaderMap
import retrofit2.http.Multipart
import retrofit2.http.POST
import retrofit2.http.PUT
import retrofit2.http.Part
import retrofit2.http.Path
import retrofit2.http.Query
interface ApiService {
@POST("registeruser")
@ -158,11 +160,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>
@ -190,6 +204,26 @@ interface ApiService {
suspend fun getListProv(
): Response<ListProvinceResponse>
@GET("mystore/orders")
suspend fun getAllOrders(): Response<OrderListResponse>
@GET("mystore/orders/{status}")
suspend fun getOrdersByStatus(
@Query("status") status: String
): Response<OrderListResponse>
@PUT("store/order/update")
suspend fun confirmOrder(
@Body confirmOrder : CompletedOrderRequest
): Response<CompletedOrderResponse>
@Multipart
@POST("addcomplaint")
suspend fun addComplaint(
@Part("order_id") orderId: RequestBody,
@Part("description") description: RequestBody,
@Part complaintimg: MultipartBody.Part
): Response<ComplaintResponse>
@PUT("store/order/update")
suspend fun confirmOrder(
@Body confirmOrder : CompletedOrderRequest

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

@ -233,6 +233,35 @@ class OrderRepository(private val apiService: ApiService) {
return if (response.isSuccessful) response.body() else null
}
suspend fun fetchSells(): List<OrdersItem?> {
return try {
val response = apiService.getAllOrders() // Replace with the actual method from your ApiService
if (response.isSuccessful) {
response.body()?.orders ?: emptyList() // Assuming the response body has 'orders'
} else {
Log.e("OrderRepository", "Error fetching all sells. Code: ${response.code()}")
emptyList()
}
} catch (e: Exception) {
Log.e("OrderRepository", "Exception fetching sells", e)
emptyList()
}
}
suspend fun fetchOrdersByStatus(status: String): List<OrdersItem?> {
return try {
val response = apiService.getOrdersByStatus(status) // Replace with actual method for status-based fetch
if (response.isSuccessful) {
response.body()?.orders?.filterNotNull() ?: emptyList() // Assuming the response body has 'orders'
} else {
Log.e("OrderRepository", "Error fetching orders by status ($status). Code: ${response.code()}")
emptyList()
}
} catch (e: Exception) {
Log.e("OrderRepository", "Exception fetching orders by status", e)
emptyList()
}
}
suspend fun fetchUserProfile(): Result<UserProfile?> {
return try {
val response = apiService.getUserProfile()

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

@ -15,7 +15,7 @@ import androidx.recyclerview.widget.RecyclerView
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

@ -19,8 +19,8 @@ import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity
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

@ -8,8 +8,8 @@ import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
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.repository.OrderRepository
import com.alya.ecommerce_serang.data.repository.Result
import com.alya.ecommerce_serang.data.repository.UserRepository

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

@ -3,8 +3,8 @@ package com.alya.ecommerce_serang.ui.order.address
import android.content.Context
import android.util.Log
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

@ -64,8 +64,8 @@ class MyStoreActivity : AppCompatActivity() {
private fun myStoreProfileOverview(store: Store){
binding.tvStoreName.setText(store.storeName.toString())
binding.tvStoreType.setText(store.storeType.toString())
binding.tvStoreName.text = store.storeName
binding.tvStoreType.text = store.storeType
store.storeImage.let {
Glide.with(this)

View File

@ -15,28 +15,33 @@ 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
import com.alya.ecommerce_serang.databinding.ActivityStoreProductDetailBinding
import com.alya.ecommerce_serang.databinding.ActivityDetailStoreProductBinding
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() {
class DetailStoreProductActivity : AppCompatActivity() {
private lateinit var binding: ActivityStoreProductDetailBinding
private lateinit var binding: ActivityDetailStoreProductBinding
private lateinit var sessionManager: SessionManager
private lateinit var categoryList: List<CategoryItem>
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 {
@ -76,12 +81,53 @@ class StoreProductDetailActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityStoreProductDetailBinding.inflate(layoutInflater)
binding = ActivityDetailStoreProductBinding.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

@ -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, DetailStoreProductActivity::class.java)
intent.putExtra("is_editing", false)
startActivity(intent)
}
}

View File

@ -1,13 +1,16 @@
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 com.alya.ecommerce_serang.R
import android.widget.Toast
import androidx.lifecycle.ViewModelProvider
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 +30,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(), DetailStoreProductActivity::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

@ -7,11 +7,11 @@ import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import com.alya.ecommerce_serang.R
class StoreAddressActivity : AppCompatActivity() {
class DetailStoreAddressActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
setContentView(R.layout.activity_store_address)
setContentView(R.layout.activity_detail_store_address)
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)

View File

@ -3,6 +3,7 @@ package com.alya.ecommerce_serang.ui.profile.mystore.sells
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import com.alya.ecommerce_serang.R
import com.alya.ecommerce_serang.ui.profile.mystore.sells.all_sells.AllSellsFragment
class SellsActivity : AppCompatActivity() {
@ -11,7 +12,7 @@ class SellsActivity : AppCompatActivity() {
setContentView(R.layout.activity_sells)
if (savedInstanceState == null) {
supportFragmentManager.beginTransaction()
.replace(R.id.sells_fragment_container, SellsFragment())
.replace(R.id.sells_fragment_container, AllSellsFragment())
.commit()
}
}

View File

@ -0,0 +1,152 @@
package com.alya.ecommerce_serang.ui.profile.mystore.sells
import android.view.LayoutInflater
import android.view.View
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.dto.OrdersItem
class SellsAdapter : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
private var orderList: List<OrdersItem?> = emptyList()
// View Types for different statuses
private val TYPE_PENDING = 0
private val TYPE_PAYMENT = 1
private val TYPE_SHIPMENT = 2
private val TYPE_COMPLETED = 3
private val TYPE_FAILED_PAYMENT = 4
private val TYPE_FAILED_SHIPMENT = 5
// Method to submit list to the adapter
fun submitList(orders: List<OrdersItem?>?) {
orderList = orders ?: emptyList()
notifyDataSetChanged()
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
return when (viewType) {
TYPE_PENDING -> {
val view = LayoutInflater.from(parent.context).inflate(R.layout.item_sells_order, parent, false)
OrderViewHolder(view)
}
TYPE_PAYMENT -> {
val view = LayoutInflater.from(parent.context).inflate(R.layout.item_sells_payment, parent, false)
PaymentViewHolder(view)
}
TYPE_SHIPMENT -> {
val view = LayoutInflater.from(parent.context).inflate(R.layout.item_sells_shipment, parent, false)
ShipmentViewHolder(view)
}
// TYPE_COMPLETED -> {
// val view = LayoutInflater.from(parent.context).inflate(R.layout.item_sells_completed, parent, false)
// CompletedViewHolder(view)
// }
// TYPE_FAILED_PAYMENT -> {
// val view = LayoutInflater.from(parent.context).inflate(R.layout.item_sells_failed_payment, parent, false)
// FailedPaymentViewHolder(view)
// }
// TYPE_FAILED_SHIPMENT -> {
// val view = LayoutInflater.from(parent.context).inflate(R.layout.item_sells_failed_shipment, parent, false)
// FailedShipmentViewHolder(view)
// }
else -> {
val view = LayoutInflater.from(parent.context).inflate(R.layout.item_sells_order, parent, false)
OrderViewHolder(view)
}
}
}
// Determine the view type based on the order status
override fun getItemViewType(position: Int): Int {
val order = orderList[position]
return when (order?.status) {
"pending" -> TYPE_PENDING
"paid" -> TYPE_PAYMENT
"shipped" -> TYPE_SHIPMENT
"completed" -> TYPE_COMPLETED
"failedPayment" -> TYPE_FAILED_PAYMENT
"failedShipment" -> TYPE_FAILED_SHIPMENT
else -> TYPE_PENDING // Default to pending if no status is matched
}
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
val order = orderList[position]
when (holder) {
is OrderViewHolder -> holder.bind(order)
is PaymentViewHolder -> holder.bind(order)
is ShipmentViewHolder -> holder.bind(order)
is CompletedViewHolder -> holder.bind(order)
is FailedPaymentViewHolder -> holder.bind(order)
is FailedShipmentViewHolder -> holder.bind(order)
}
}
override fun getItemCount(): Int = orderList.size
// ViewHolder for 'pending' status (Order)
class OrderViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
private val tvOrderNumber: TextView = itemView.findViewById(R.id.tv_order_number)
private val tvOrderCustomer: TextView = itemView.findViewById(R.id.tv_order_customer)
private val tvOrderPrice: TextView = itemView.findViewById(R.id.tv_order_price)
fun bind(order: OrdersItem?) {
tvOrderNumber.text = "Order #${order?.orderId}"
tvOrderCustomer.text = order?.username
tvOrderPrice.text = "Total: ${order?.totalAmount}"
}
}
// ViewHolder for 'paid' status (Payment)
class PaymentViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
private val tvPaymentNumber: TextView = itemView.findViewById(R.id.tv_payment_number)
private val tvPaymentCustomer: TextView = itemView.findViewById(R.id.tv_payment_customer)
private val tvPaymentPrice: TextView = itemView.findViewById(R.id.tv_payment_price)
fun bind(order: OrdersItem?) {
tvPaymentNumber.text = "Order #${order?.orderId}"
tvPaymentCustomer.text = order?.username
tvPaymentPrice.text = "Paid: ${order?.totalAmount}"
}
}
// ViewHolder for 'shipped' status (Shipment)
class ShipmentViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
private val tvShipmentNumber: TextView = itemView.findViewById(R.id.tv_shipment_number)
private val tvShipmentLocation: TextView = itemView.findViewById(R.id.tv_shipment_location)
fun bind(order: OrdersItem?) {
tvShipmentNumber.text = "Shipment #${order?.orderId}"
tvShipmentLocation.text = "Location: ${order?.address?.subdistrict}"
}
}
// ViewHolder for 'completed' status
class CompletedViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
//private val tvCompletedNumber: TextView = itemView.findViewById(R.id.tv_completed_number)
fun bind(order: OrdersItem?) {
// tvCompletedNumber.text = "Completed Order #${order?.orderId}"
}
}
// ViewHolder for 'failedPayment' status
class FailedPaymentViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
//private val tvFailedPaymentNumber: TextView = itemView.findViewById(R.id.tv_failed_payment_number)
fun bind(order: OrdersItem?) {
//tvFailedPaymentNumber.text = "Failed Payment Order #${order?.orderId}"
}
}
// ViewHolder for 'failedShipment' status
class FailedShipmentViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
//private val tvFailedShipmentNumber: TextView = itemView.findViewById(R.id.tv_failed_shipment_number)
fun bind(order: OrdersItem?) {
//tvFailedShipmentNumber.text = "Failed Shipment Order #${order?.orderId}"
}
}
}

View File

@ -24,7 +24,9 @@ class SellsFragment : Fragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
viewModel = ViewModelProvider(this).get(SellsViewModel::class.java)
// val repository = OrderRepository(ApiService.create())
viewModel = ViewModelProvider(this)[SellsViewModel::class.java]
val tabs = listOf(
"Semua Pesanan", "Perlu Tagihan", "Konfirmasi Pembayaran",

View File

@ -6,7 +6,7 @@ import com.alya.ecommerce_serang.ui.profile.mystore.sells.all_sells.AllSellsFrag
import com.alya.ecommerce_serang.ui.profile.mystore.sells.cancellation.CancellationFragment
import com.alya.ecommerce_serang.ui.profile.mystore.sells.failed_payment.FailedPaymentFragment
import com.alya.ecommerce_serang.ui.profile.mystore.sells.failed_shipment.FailedShipmentFragment
import com.alya.ecommerce_serang.ui.profile.mystore.sells.finished.FinishedFragment
import com.alya.ecommerce_serang.ui.profile.mystore.sells.completed.CompletedFragment
import com.alya.ecommerce_serang.ui.profile.mystore.sells.order.OrderFragment
import com.alya.ecommerce_serang.ui.profile.mystore.sells.payment.PaymentFragment
import com.alya.ecommerce_serang.ui.profile.mystore.sells.shipment.ShipmentFragment
@ -24,7 +24,7 @@ class SellsPagerAdapter(fragment: Fragment, private val itemCount: Int) :
2 -> PaymentFragment()
3 -> ShipmentFragment()
4 -> ShippedFragment()
5 -> FinishedFragment()
5 -> CompletedFragment()
6 -> CancellationFragment()
7 -> FailedPaymentFragment()
8 -> FailedShipmentFragment()

View File

@ -5,14 +5,37 @@ import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import com.alya.ecommerce_serang.R
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider
import androidx.recyclerview.widget.LinearLayoutManager
import com.alya.ecommerce_serang.databinding.FragmentAllSellsBinding
import com.alya.ecommerce_serang.ui.profile.mystore.sells.SellsAdapter
import com.alya.ecommerce_serang.utils.viewmodel.SellsViewModel
class AllSellsFragment : Fragment() {
private lateinit var viewModel: SellsViewModel
private lateinit var binding: FragmentAllSellsBinding
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_all_sells, container, false)
binding = FragmentAllSellsBinding.inflate(inflater, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
viewModel = ViewModelProvider(this).get(SellsViewModel::class.java)
val adapter = SellsAdapter()
binding.rvAllSells.layoutManager = LinearLayoutManager(context)
binding.rvAllSells.adapter = adapter
viewModel.loadOrdersByStatus("all")
viewModel.sellsList.observe(viewLifecycleOwner, Observer { sells ->
adapter.submitList(sells)
})
}
}

View File

@ -5,14 +5,37 @@ import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider
import androidx.recyclerview.widget.LinearLayoutManager
import com.alya.ecommerce_serang.R
import com.alya.ecommerce_serang.databinding.FragmentCancellationBinding
import com.alya.ecommerce_serang.utils.viewmodel.SellsViewModel
class CancellationFragment : Fragment() {
private lateinit var viewModel: SellsViewModel
private lateinit var binding: FragmentCancellationBinding
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_cancellation, container, false)
binding = FragmentCancellationBinding.inflate(inflater, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
viewModel = ViewModelProvider(this).get(SellsViewModel::class.java)
// val adapter = SellsAdapter()
// binding.rvCancellation.layoutManager = LinearLayoutManager(context)
// binding.rvCancellation.adapter = adapter
//
// viewModel.loadOrdersByStatus("cancelled")
// viewModel.sellsList.observe(viewLifecycleOwner, Observer { cancellations ->
// adapter.submitList(cancellations)
// })
}
}

View File

@ -0,0 +1,41 @@
package com.alya.ecommerce_serang.ui.profile.mystore.sells.completed
import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider
import androidx.recyclerview.widget.LinearLayoutManager
import com.alya.ecommerce_serang.R
import com.alya.ecommerce_serang.databinding.FragmentCompletedBinding
import com.alya.ecommerce_serang.utils.viewmodel.SellsViewModel
class CompletedFragment : Fragment() {
private lateinit var viewModel: SellsViewModel
private lateinit var binding: FragmentCompletedBinding
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
binding = FragmentCompletedBinding.inflate(inflater, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
viewModel = ViewModelProvider(this).get(SellsViewModel::class.java)
// val adapter = SellsAdapter()
// binding.rvCompleted.layoutManager = LinearLayoutManager(context)
// binding.rvCompleted.adapter = adapter
//
// viewModel.loadOrdersByStatus("delivered")
// viewModel.sellsList.observe(viewLifecycleOwner, Observer { completed ->
// adapter.submitList(completed)
// })
}
}

View File

@ -6,14 +6,37 @@ import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider
import androidx.recyclerview.widget.LinearLayoutManager
import com.alya.ecommerce_serang.R
import com.alya.ecommerce_serang.databinding.FragmentFailedPaymentBinding
import com.alya.ecommerce_serang.utils.viewmodel.SellsViewModel
class FailedPaymentFragment : Fragment() {
private lateinit var viewModel: SellsViewModel
private lateinit var binding: FragmentFailedPaymentBinding
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_failed_payment, container, false)
binding = FragmentFailedPaymentBinding.inflate(inflater, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
viewModel = ViewModelProvider(this).get(SellsViewModel::class.java)
// val adapter = SellsAdapter()
// binding.rvFailedPayment.layoutManager = LinearLayoutManager(context)
// binding.rvFailedPayment.adapter = adapter
//
// viewModel.loadOrdersByStatus("failedPayment")
// viewModel.sellsList.observe(viewLifecycleOwner, Observer { failedPayments ->
// adapter.submitList(failedPayments)
// })
}
}

View File

@ -5,14 +5,37 @@ import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider
import androidx.recyclerview.widget.LinearLayoutManager
import com.alya.ecommerce_serang.R
import com.alya.ecommerce_serang.databinding.FragmentFailedShipmentBinding
import com.alya.ecommerce_serang.utils.viewmodel.SellsViewModel
class FailedShipmentFragment : Fragment() {
private lateinit var viewModel: SellsViewModel
private lateinit var binding: FragmentFailedShipmentBinding
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_failed_shipment, container, false)
binding = FragmentFailedShipmentBinding.inflate(inflater, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
viewModel = ViewModelProvider(this).get(SellsViewModel::class.java)
// val adapter = SellsAdapter()
// binding.rvFailedShipment.layoutManager = LinearLayoutManager(context)
// binding.rvFailedShipment.adapter = adapter
//
// viewModel.loadOrdersByStatus("failedShipment")
// viewModel.sellsList.observe(viewLifecycleOwner, Observer { failedShipments ->
// adapter.submitList(failedShipments)
// })
}
}

View File

@ -1,18 +0,0 @@
package com.alya.ecommerce_serang.ui.profile.mystore.sells.finished
import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import com.alya.ecommerce_serang.R
class FinishedFragment : Fragment() {
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_finished, container, false)
}
}

View File

@ -0,0 +1,60 @@
package com.alya.ecommerce_serang.ui.profile.mystore.sells.order
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Button
import android.widget.ImageView
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import com.alya.ecommerce_serang.R
import com.alya.ecommerce_serang.data.api.dto.OrdersItem
class OrderAdapter : RecyclerView.Adapter<OrderAdapter.OrderViewHolder>() {
private var orderList: List<OrdersItem?>? = emptyList()
fun submitList(orders: List<OrdersItem?>?) {
orderList = orders
notifyDataSetChanged()
}
override fun onCreateViewHolder(
parent: ViewGroup,
viewType: Int
): OrderViewHolder {
val view = LayoutInflater.from(parent.context).inflate(R.layout.item_sells_order, parent, false)
return OrderViewHolder(view)
}
override fun onBindViewHolder(holder: OrderViewHolder, position: Int) {
val order = orderList?.get(position)
holder.bind(order)
}
override fun getItemCount(): Int = orderList?.size ?: 0
class OrderViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
private val tvOrderNumber: TextView = itemView.findViewById(R.id.tv_order_number)
private val tvOrderCustomer: TextView = itemView.findViewById(R.id.tv_order_customer)
private val tvOrderDue: TextView = itemView.findViewById(R.id.tv_order_due)
private val ivOrderProduct: ImageView = itemView.findViewById(R.id.iv_order_product)
private val tvOrderProductName: TextView = itemView.findViewById(R.id.tv_order_product_name)
private val tvOrderProductVariant: TextView = itemView.findViewById(R.id.tv_order_product_variant)
private val tvOrderProductQty: TextView = itemView.findViewById(R.id.tv_order_product_qty)
private val tvOrderProductPrice: TextView = itemView.findViewById(R.id.tv_order_product_price)
private val tvOrderQty: TextView = itemView.findViewById(R.id.tv_order_qty)
private val tvOrderPrice: TextView = itemView.findViewById(R.id.tv_order_price)
private val tvSeeMore: TextView = itemView.findViewById(R.id.tv_see_more)
private val btnEditOrder: Button = itemView.findViewById(R.id.btn_edit_order)
private val btnConfirmOrder: Button = itemView.findViewById(R.id.btn_confirm_order)
fun bind(order: OrdersItem?) {
tvOrderNumber.text = "No. Pesanan: ${order?.orderId}"
tvOrderCustomer.text = order?.username
tvOrderDue.text = order?.createdAt + 7
tvOrderQty.text = "${order?.orderItems?.size} produk"
tvOrderPrice.text = "Rp${order?.totalAmount}"
}
}
}

View File

@ -5,14 +5,36 @@ import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import com.alya.ecommerce_serang.R
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider
import androidx.recyclerview.widget.LinearLayoutManager
import com.alya.ecommerce_serang.databinding.FragmentOrderBinding
import com.alya.ecommerce_serang.utils.viewmodel.SellsViewModel
class OrderFragment : Fragment() {
private lateinit var viewModel: SellsViewModel
private lateinit var binding: FragmentOrderBinding
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_order, container, false)
binding = FragmentOrderBinding.inflate(inflater, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
viewModel = ViewModelProvider(this).get(SellsViewModel::class.java)
val adapter = OrderAdapter()
binding.rvOrder.layoutManager = LinearLayoutManager(context)
binding.rvOrder.adapter = adapter
viewModel.loadOrdersByStatus("pending")
viewModel.sellsList.observe(viewLifecycleOwner, Observer { orders ->
adapter.submitList(orders)
})
}
}

View File

@ -0,0 +1,61 @@
package com.alya.ecommerce_serang.ui.profile.mystore.sells.payment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Button
import android.widget.ImageView
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import com.alya.ecommerce_serang.R
import com.alya.ecommerce_serang.data.api.dto.OrdersItem
class PaymentAdapter : RecyclerView.Adapter<PaymentAdapter.PaymentViewHolder>() {
private var paymentList: List<OrdersItem?>? = emptyList()
fun submitList(orders: List<OrdersItem?>?) {
paymentList = orders
notifyDataSetChanged()
}
override fun onCreateViewHolder(
parent: ViewGroup,
viewType: Int
): PaymentViewHolder {
val view = LayoutInflater.from(parent.context).inflate(R.layout.item_sells_payment, parent, false)
return PaymentViewHolder(view)
}
override fun onBindViewHolder(holder: PaymentViewHolder, position: Int) {
val order = paymentList?.get(position)
holder.bind(order)
}
override fun getItemCount(): Int = paymentList?.size ?: 0
class PaymentViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView){
private val tvPaymentNumber: TextView = itemView.findViewById(R.id.tv_payment_number)
private val tvPaymentDue: TextView = itemView.findViewById(R.id.tv_payment_due)
private val ivPaymentProduct: ImageView = itemView.findViewById(R.id.iv_payment_product)
private val tvPaymentProductName: TextView = itemView.findViewById(R.id.tv_payment_product_name)
private val tvPaymentProductVariant: TextView = itemView.findViewById(R.id.tv_payment_product_variant)
private val tvPaymentProductQty: TextView = itemView.findViewById(R.id.tv_payment_product_qty)
private val tvPaymentProductPrice: TextView = itemView.findViewById(R.id.tv_payment_product_price)
private val tvPaymentQty: TextView = itemView.findViewById(R.id.tv_payment_qty)
private val tvPaymentPrice: TextView = itemView.findViewById(R.id.tv_payment_price)
private val tvPaymentCustomer: TextView = itemView.findViewById(R.id.tv_payment_customer)
private val tvPaymentLocation: TextView = itemView.findViewById(R.id.tv_payment_location)
private val tvSeeMore: TextView = itemView.findViewById(R.id.tv_see_more)
private val btnConfirmPayment: Button = itemView.findViewById(R.id.btn_confirm_payment)
fun bind(order: OrdersItem?) {
tvPaymentNumber.text = "No. Pesanan: ${order?.orderId}"
tvPaymentDue.text = order?.createdAt + 7
tvPaymentQty.text = "${order?.orderItems?.size} produk"
tvPaymentPrice.text = "Rp${order?.totalAmount}"
tvPaymentCustomer.text = order?.username
tvPaymentLocation.text = order?.address?.subdistrict
}
}
}

View File

@ -5,14 +5,36 @@ import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import com.alya.ecommerce_serang.R
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider
import androidx.recyclerview.widget.LinearLayoutManager
import com.alya.ecommerce_serang.databinding.FragmentPaymentBinding
import com.alya.ecommerce_serang.utils.viewmodel.SellsViewModel
class PaymentFragment : Fragment() {
private lateinit var viewModel: SellsViewModel
private lateinit var binding: FragmentPaymentBinding
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_payment, container, false)
binding = FragmentPaymentBinding.inflate(inflater, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
viewModel = ViewModelProvider(this).get(SellsViewModel::class.java)
val adapter = PaymentAdapter()
binding.rvPayment.layoutManager = LinearLayoutManager(context)
binding.rvPayment.adapter = adapter
viewModel.loadOrdersByStatus("paid")
viewModel.sellsList.observe(viewLifecycleOwner, Observer { payments ->
adapter.submitList(payments)
})
}
}

View File

@ -0,0 +1,56 @@
package com.alya.ecommerce_serang.ui.profile.mystore.sells.shipment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Button
import android.widget.ImageView
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import com.alya.ecommerce_serang.R
import com.alya.ecommerce_serang.data.api.dto.OrdersItem
class ShipmentAdapter : RecyclerView.Adapter<ShipmentAdapter.ShipmentViewHolder>() {
private var shipmentList: List<OrdersItem> = emptyList()
fun submitList(orders: List<OrdersItem>) {
shipmentList = orders
notifyDataSetChanged()
}
override fun onCreateViewHolder(
parent: ViewGroup,
viewType: Int
): ShipmentAdapter.ShipmentViewHolder {
val view = LayoutInflater.from(parent.context).inflate(R.layout.item_sells_shipment, parent, false)
return ShipmentViewHolder(view)
}
override fun onBindViewHolder(holder: ShipmentAdapter.ShipmentViewHolder, position: Int) {
val order = shipmentList[position]
holder.bind(order)
}
override fun getItemCount(): Int = shipmentList.size
class ShipmentViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
private val tvShipmentNumber: TextView = itemView.findViewById(R.id.tv_shipment_number)
private val tvShipmentDue: TextView = itemView.findViewById(R.id.tv_shipment_due)
private val ivShipmentProduct: ImageView = itemView.findViewById(R.id.iv_shipment_product)
private val tvShipmentProductName: TextView = itemView.findViewById(R.id.tv_shipment_product_name)
private val tvShipmentProductVariant: TextView = itemView.findViewById(R.id.tv_shipment_product_variant)
private val tvShipmentProductQty: TextView = itemView.findViewById(R.id.tv_shipment_product_qty)
private val tvShipmentCustomer: TextView = itemView.findViewById(R.id.tv_shipment_customer)
private val tvShipmentLocation: TextView = itemView.findViewById(R.id.tv_shipment_location)
private val tvSeeMore: TextView = itemView.findViewById(R.id.tv_see_more)
private val btnConfirmPayment: Button = itemView.findViewById(R.id.btn_confirm_payment)
fun bind(order: OrdersItem) {
tvShipmentNumber.text = "No. Pesanan: ${order.orderId}"
tvShipmentDue.text = order.createdAt + 7
tvShipmentCustomer.text = order.username
tvShipmentLocation.text = order.address?.subdistrict
}
}
}

View File

@ -5,14 +5,37 @@ import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider
import androidx.recyclerview.widget.LinearLayoutManager
import com.alya.ecommerce_serang.R
import com.alya.ecommerce_serang.databinding.FragmentShipmentBinding
import com.alya.ecommerce_serang.utils.viewmodel.SellsViewModel
class ShipmentFragment : Fragment() {
private lateinit var viewModel: SellsViewModel
private lateinit var binding: FragmentShipmentBinding
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_shipment, container, false)
binding = FragmentShipmentBinding.inflate(inflater, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
viewModel = ViewModelProvider(this).get(SellsViewModel::class.java)
val adapter = ShipmentAdapter()
binding.rvShipment.layoutManager = LinearLayoutManager(context)
// binding.rvShipment.adapter = adapter
//
// viewModel.loadOrdersByStatus("processed")
// viewModel.sellsList.observe(viewLifecycleOwner, Observer { shipments ->
// adapter.submitList(shipments)
// })
}
}

View File

@ -5,14 +5,37 @@ import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider
import androidx.recyclerview.widget.LinearLayoutManager
import com.alya.ecommerce_serang.R
import com.alya.ecommerce_serang.databinding.FragmentShippedBinding
import com.alya.ecommerce_serang.utils.viewmodel.SellsViewModel
class ShippedFragment : Fragment() {
private lateinit var viewModel: SellsViewModel
private lateinit var binding: FragmentShippedBinding
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_shipped, container, false)
binding = FragmentShippedBinding.inflate(inflater, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
viewModel = ViewModelProvider(this).get(SellsViewModel::class.java)
// val adapter = SellsAdapter()
// binding.rvShipped.layoutManager = LinearLayoutManager(context)
// binding.rvShipped.adapter = adapter
//
// viewModel.loadOrdersByStatus("shipped")
// viewModel.sellsList.observe(viewLifecycleOwner, Observer { shipped ->
// adapter.submitList(shipped)
// })
}
}

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

@ -1,7 +1,26 @@
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.OrdersItem
import com.alya.ecommerce_serang.data.repository.OrderRepository
import kotlinx.coroutines.launch
class SellsViewModel : ViewModel() {
// TODO: Implement the ViewModel
class SellsViewModel(private val repository: OrderRepository) : ViewModel() {
private val _sellsList = MutableLiveData<List<OrdersItem?>>()
val sellsList: LiveData<List<OrdersItem?>> get() = _sellsList
fun loadOrdersByStatus(status: String) {
viewModelScope.launch {
val result = if (status == "all") {
repository.fetchSells()
} else {
repository.fetchOrdersByStatus(status)
}
_sellsList.value = result
}
}
}

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

@ -0,0 +1,285 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:fitsSystemWindows="true"
android:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".ui.profile.mystore.profile.address.DetailStoreAddressActivity">
<include
android:id="@+id/header"
layout="@layout/header" />
<ScrollView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingVertical="@dimen/vertical_safe_area"
android:paddingHorizontal="@dimen/horizontal_safe_area"
android:layout_marginTop="19dp">
<!-- Nama Lokasi -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_marginBottom="24dp">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Nama Lokasi"
style="@style/body_medium"
android:layout_marginEnd="4dp"/>
<EditText
android:id="@+id/edt_nama_lokasi"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/bg_text_field_disabled"
android:text="Alamat Toko"
android:padding="8dp"
style="@style/body_small"
android:layout_marginTop="10dp"
android:enabled="false"/>
</LinearLayout>
<!-- Jalan -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_marginBottom="24dp">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Jalan"
style="@style/body_medium"
android:layout_marginEnd="4dp"/>
<EditText
android:id="@+id/edt_street"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/bg_text_field"
android:padding="8dp"
style="@style/body_small"
android:layout_marginTop="10dp"/>
</LinearLayout>
<!-- Kecamatan -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_marginBottom="24dp">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Kecamatan"
style="@style/body_medium"
android:layout_marginEnd="4dp"/>
<EditText
android:id="@+id/edt_subdistrict"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/bg_text_field"
android:padding="8dp"
style="@style/body_small"
android:layout_marginTop="10dp"/>
</LinearLayout>
<!-- Kota/Kabupaten -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_marginBottom="24dp">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Kota atau Kabupaten"
style="@style/body_medium"
android:layout_marginEnd="4dp"/>
<!-- 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_city"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:padding="8dp"
style="@style/body_small"
android:background="@null"/>
<!-- Chevron Down Icon -->
<ImageView
android:layout_width="16dp"
android:layout_height="16dp"
android:src="@drawable/ic_down"
android:layout_marginEnd="8dp"
android:contentDescription="Chevron Down" />
</LinearLayout>
</LinearLayout>
<!-- Provinsi -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_marginBottom="24dp">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Provinsi"
style="@style/body_medium"
android:layout_marginEnd="4dp"/>
<!-- 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_province"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:padding="8dp"
style="@style/body_small"
android:background="@null"/>
<!-- Chevron Down Icon -->
<ImageView
android:layout_width="16dp"
android:layout_height="16dp"
android:src="@drawable/ic_down"
android:layout_marginEnd="8dp"
android:contentDescription="Chevron Down" />
</LinearLayout>
</LinearLayout>
<!-- Kode Pos -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_marginBottom="24dp">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Kode Pos"
style="@style/body_medium"
android:layout_marginEnd="4dp"/>
<EditText
android:id="@+id/edt_postal_code"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/bg_text_field"
android:padding="8dp"
style="@style/body_small"
android:layout_marginTop="10dp"/>
</LinearLayout>
<!-- Detail Alamat -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_marginBottom="24dp">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Detail Alamat"
style="@style/body_medium"
android:layout_marginEnd="4dp"/>
<EditText
android:id="@+id/edt_detail_address"
android:layout_width="match_parent"
android:layout_height="70dp"
android:background="@drawable/bg_text_field"
android:hint="Isi detail alamat di sini, contoh: Blok, No. Kavling, dsb."
android:padding="8dp"
style="@style/body_small"
android:inputType="text|textMultiLine"
android:gravity="top"
android:layout_marginTop="10dp"/>
</LinearLayout>
<!-- Pinpoint Lokasi -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_marginBottom="24dp">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Pinpoint Lokasi"
style="@style/body_medium"
android:layout_marginEnd="4dp"/>
<!-- Map -->
<org.osmdroid.views.MapView android:id="@+id/map"
android:layout_width="match_parent"
android:layout_height="220dp" />
<TextView
android:id="@+id/tv_location_display"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Lokasi: Tidak dipilih"
style="@style/body_medium"/>
</LinearLayout>
<Button
android:id="@+id/btn_save_address"
android:text="Simpan Perubahan"
style="@style/button.large.disabled.long"
android:enabled="false"/>
</LinearLayout>
</ScrollView>
</LinearLayout>

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.StoreProductDetailActivity">
tools:context=".ui.profile.mystore.product.DetailStoreProductActivity">
<include
android:id="@+id/header"
@ -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

View File

@ -142,6 +142,36 @@
</LinearLayout>
<!-- Toko Aktif -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<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="Toko Aktif"
style="@style/label_large"/>
<Switch
android:id="@+id/switch_is_active"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end"
tools:ignore="UseSwitchCompatOrMaterialXml" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
<!-- Alamat Toko -->
@ -170,32 +200,6 @@
</LinearLayout>
<!-- Status Toko -->
<LinearLayout
android:id="@+id/layout_status"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:paddingVertical="10dp"
android:paddingHorizontal="@dimen/horizontal_safe_area"
android:gravity="center">
<TextView
style="@style/label_large"
android:id="@+id/tv_status"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Atur Status Toko" />
<ImageView
android:id="@+id/iv_status"
android:layout_width="20dp"
android:layout_height="20dp"
android:src="@drawable/ic_navigate_next"/>
</LinearLayout>
<!-- Metode Pembayaran -->
<LinearLayout
android:id="@+id/layout_payment_method"

View File

@ -1,8 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
<androidx.coordinatorlayout.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/sells_fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.profile.mystore.sells.SellsActivity"/>
tools:context=".ui.profile.mystore.sells.SellsActivity">
<FrameLayout
android:id="@+id/sells_fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>

View File

@ -1,11 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:fitsSystemWindows="true"
android:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.profile.mystore.profile.address.StoreAddressActivity">
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -1,17 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
<androidx.recyclerview.widget.RecyclerView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/rv_all_sells"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="13dp"
tools:context=".ui.profile.mystore.sells.all_sells.AllSellsFragment">
<TextView
android:id="@+id/tv_semua_pesanan"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Semua Pesanan"
style="@style/label_medium_prominent"
android:textColor="@color/black_300"/>
</FrameLayout>
android:layout_height="match_parent"/>

View File

@ -1,17 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
<androidx.recyclerview.widget.RecyclerView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/rv_cancellation"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.profile.mystore.sells.cancellation.CancellationFragment"
android:padding="13dp">
<TextView
android:id="@+id/tv_pembatalan"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Pembatalan"
style="@style/label_medium_prominent"
android:textColor="@color/black_300"/>
</FrameLayout>
android:layout_height="match_parent"/>

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.recyclerview.widget.RecyclerView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/rv_completed"
android:layout_width="match_parent"
android:layout_height="match_parent"/>

View File

@ -1,17 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
<androidx.recyclerview.widget.RecyclerView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/rv_failed_payment"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.profile.mystore.sells.failed_payment.FailedPaymentFragment"
android:padding="13dp">
<TextView
android:id="@+id/tv_klaim_pembayaran"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Klaim Pembayaran"
style="@style/label_medium_prominent"
android:textColor="@color/black_300"/>
</FrameLayout>
android:layout_height="match_parent"/>

View File

@ -1,17 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
<androidx.recyclerview.widget.RecyclerView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/rv_failed_shipment"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.profile.mystore.sells.failed_shipment.FailedShipmentFragment"
android:padding="13dp">
<TextView
android:id="@+id/tv_pengiriman_gagal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Pengiriman Gagal"
style="@style/label_medium_prominent"
android:textColor="@color/black_300"/>
</FrameLayout>
android:layout_height="match_parent"/>

View File

@ -1,17 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.profile.mystore.sells.finished.FinishedFragment"
android:padding="13dp">
<TextView
android:id="@+id/tv_selesai"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Selesai"
style="@style/label_medium_prominent"
android:textColor="@color/black_300"/>
</FrameLayout>

View File

@ -1,17 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
<androidx.recyclerview.widget.RecyclerView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/rv_order"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.profile.mystore.sells.order.OrderFragment"
android:padding="13dp">
<TextView
android:id="@+id/tv_perlu_tagihan"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Perlu Tagihan"
style="@style/label_medium_prominent"
android:textColor="@color/black_300"/>
</FrameLayout>
tools:listitem="@layout/item_sells_order" />

View File

@ -1,17 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
<androidx.recyclerview.widget.RecyclerView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/rv_payment"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.profile.mystore.sells.payment.PaymentFragment"
android:padding="13dp">
<TextView
android:id="@+id/tv_konfirmasi_pembayaran"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Konfirmasi Pembayaran"
style="@style/label_medium_prominent"
android:textColor="@color/black_300"/>
</FrameLayout>
tools:listitem="@layout/item_sells_payment"/>

View File

@ -1,19 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
<androidx.coordinatorlayout.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/sells"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".ui.profile.mystore.sells.SellsFragment">
<com.google.android.material.tabs.TabLayout
android:id="@+id/tab_layout_sells"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabMode="scrollable" />
app:tabMode="scrollable"
app:tabTextAppearance="@style/label_medium_prominent"
app:tabSelectedTextAppearance="@style/label_medium_prominent"
app:tabIndicatorColor="@color/blue_500"
app:tabSelectedTextColor="@color/blue_500"
app:tabTextColor="@color/black_300"
app:tabBackground="@color/white"
app:tabPadding="13dp"/>
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/view_pager_sells"
@ -21,4 +27,4 @@
android:layout_height="0dp"
android:layout_weight="1" />
</LinearLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>

View File

@ -1,17 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
<androidx.recyclerview.widget.RecyclerView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/rv_shipment"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.profile.mystore.sells.shipment.ShipmentFragment"
android:padding="13dp">
<TextView
android:id="@+id/tv_perlu_dikirim"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Perlu Dikirim"
style="@style/label_medium_prominent"
android:textColor="@color/black_300"/>
</FrameLayout>
tools:listitem="@layout/item_sells_shipment" />

View File

@ -1,17 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
<androidx.recyclerview.widget.RecyclerView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/rv_shipped"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.profile.mystore.sells.shipped.ShippedFragment"
android:padding="13dp">
<TextView
android:id="@+id/tv_dikirim"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Dikirim"
style="@style/label_medium_prominent"
android:textColor="@color/black_300"/>
</FrameLayout>
android:layout_height="match_parent"/>

View File

@ -20,6 +20,8 @@ lifecycleViewmodelKtx = "2.8.7"
fragmentKtx = "1.5.6"
navigationFragmentKtx = "2.8.5"
navigationUiKtx = "2.8.5"
playServicesLocation = "21.3.0"
playServicesMaps = "19.2.0"
recyclerview = "1.4.0"
[libraries]
@ -40,6 +42,8 @@ androidx-lifecycle-viewmodel-ktx = { group = "androidx.lifecycle", name = "lifec
androidx-fragment-ktx = { group = "androidx.fragment", name = "fragment-ktx", version.ref = "fragmentKtx" }
androidx-navigation-fragment-ktx = { group = "androidx.navigation", name = "navigation-fragment-ktx", version.ref = "navigationFragmentKtx" }
androidx-navigation-ui-ktx = { group = "androidx.navigation", name = "navigation-ui-ktx", version.ref = "navigationUiKtx" }
play-services-location = { module = "com.google.android.gms:play-services-location", version.ref = "playServicesLocation" }
play-services-maps = { module = "com.google.android.gms:play-services-maps", version.ref = "playServicesMaps" }
[plugins]
android-application = { id = "com.android.application", version.ref = "agp" }