This commit is contained in:
Gracia Hotmauli
2025-05-12 12:04:29 +07:00
parent bf6118ab39
commit b3ab3de964
50 changed files with 875 additions and 1092 deletions

View File

@ -4,6 +4,14 @@
<selectionStates>
<SelectionState runConfigName="app">
<option name="selectionMode" value="DROPDOWN" />
<DropdownSelection timestamp="2025-05-08T14:50:55.425322500Z">
<Target type="DEFAULT_BOOT">
<handle>
<DeviceId pluginId="LocalEmulator" identifier="path=C:\Users\Gracia Hotmauli\.android\avd\Pixel_8_2_2.avd" />
</handle>
</Target>
</DropdownSelection>
<DialogSelection />
</SelectionState>
</selectionStates>
</component>

View File

@ -7,13 +7,15 @@
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<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"/>
<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:enableOnBackInvokedCallback="true"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
@ -23,6 +25,15 @@
android:theme="@style/Theme.Ecommerce_serang"
android:usesCleartextTraffic="true"
tools:targetApi="31">
<activity
android:name=".ui.profile.mystore.sells.shipment.DetailShipmentActivity"
android:exported="false" />
<activity
android:name=".ui.profile.mystore.sells.payment.DetailPaymentActivity"
android:exported="false" />
<activity
android:name=".ui.profile.mystore.sells.order.DetailOrderActivity"
android:exported="false" />
<activity
android:name=".ui.order.detail.AddEvidencePaymentActivity"
android:exported="false" />
@ -71,12 +82,6 @@
<activity
android:name=".ui.profile.mystore.balance.BalanceActivity"
android:exported="false" />
<activity
android:name=".ui.profile.mystore.sells.shipment.ShippingConfirmationActivity"
android:exported="false" />
<activity
android:name=".ui.profile.mystore.sells.payment.ClaimPaymentActivity"
android:exported="false" />
<activity
android:name=".ui.profile.mystore.balance.BalanceTopUpActivity"
android:exported="false" />

View File

@ -1,5 +1,6 @@
package com.alya.ecommerce_serang.data.api.response.store.orders
import com.alya.ecommerce_serang.data.api.dto.UpdatedOrder
import com.google.gson.annotations.SerializedName
data class KonfirmasiTagihanResponse(

View File

@ -1,6 +1,5 @@
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(
@ -12,43 +11,133 @@ data class OrderListResponse(
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(
data class OrdersItem(
@field:SerializedName("receipt_num")
val receiptNum: Any? = null,
@field:SerializedName("courier")
val courier: Any? = null,
@field:SerializedName("payment_upload_at")
val paymentUploadAt: Any? = null,
@field:SerializedName("price")
val price: Any? = null,
@field:SerializedName("latitude")
val latitude: String? = null,
@field:SerializedName("pay_info_name")
val payInfoName: String? = null,
@field:SerializedName("created_at")
val createdAt: String? = null,
@field:SerializedName("voucher_code")
val voucherCode: Any? = null,
@field:SerializedName("updated_at")
val updatedAt: String? = null,
@field:SerializedName("etd")
val etd: String? = null,
@field:SerializedName("street")
val street: String? = null,
@field:SerializedName("cancel_date")
val cancelDate: String? = null,
@field:SerializedName("payment_evidence")
val paymentEvidence: Any? = null,
@field:SerializedName("longitude")
val longitude: String? = null,
@field:SerializedName("shipment_status")
val shipmentStatus: String? = null,
@field:SerializedName("order_items")
val orderItems: List<OrderItemsItem?>? = null,
@field:SerializedName("auto_completed_at")
val autoCompletedAt: Any? = null,
@field:SerializedName("is_store_location")
val isStoreLocation: Boolean? = null,
@field:SerializedName("qris_image")
val qrisImage: String? = null,
@field:SerializedName("voucher_name")
val voucherName: Any? = null,
@field:SerializedName("payment_status")
val paymentStatus: Any? = null,
@field:SerializedName("address_id")
val addressId: Int? = null,
@field:SerializedName("is_negotiable")
val isNegotiable: Boolean? = null,
@field:SerializedName("payment_amount")
val paymentAmount: Any? = null,
@field:SerializedName("cancel_reason")
val cancelReason: String? = null,
@field:SerializedName("user_id")
val userId: Int? = null,
@field:SerializedName("total_amount")
val totalAmount: String? = null,
@field:SerializedName("province_id")
val provinceId: Int? = null,
@field:SerializedName("courier")
val courier: String? = null,
@field:SerializedName("subdistrict")
val subdistrict: String? = null,
@field:SerializedName("service")
val service: Any? = null,
val service: String? = null,
@field:SerializedName("shipment_id")
val shipmentId: Any? = null,
@field:SerializedName("pay_info_num")
val payInfoNum: String? = null,
@field:SerializedName("shipment_price")
val shipmentPrice: String? = null,
@field:SerializedName("voucher_id")
val voucherId: Any? = null,
@field:SerializedName("payment_info_id")
val paymentInfoId: Int? = null,
@field:SerializedName("detail")
val detail: String? = null,
@field:SerializedName("postal_code")
val postalCode: String? = null,
@field:SerializedName("order_id")
val orderId: Int? = null,
@field:SerializedName("username")
val username: String? = null,
@field:SerializedName("status")
val status: Any? = null
val status: String? = null,
@field:SerializedName("city_id")
val cityId: Int? = null
)
data class OrderItemsItem(
@field:SerializedName("order_item_id")
val orderItemId: Int? = null,
@field:SerializedName("review_id")
val reviewId: Int? = null,
val reviewId: Any? = null,
@field:SerializedName("quantity")
val quantity: Int? = null,
@ -62,6 +151,9 @@ data class OrderItemsItem(
@field:SerializedName("product_image")
val productImage: String? = null,
@field:SerializedName("product_id")
val productId: Int? = null,
@field:SerializedName("store_name")
val storeName: String? = null,
@ -71,48 +163,3 @@ data class OrderItemsItem(
@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

@ -4,72 +4,27 @@ 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("total_amount")
val totalAmount: Int? = null,
@field:SerializedName("order_id")
val orderId: Int? = null
)
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("items")
val items: List<ItemsItem?>? = null,
@field:SerializedName("status")
val status: String? = null
)
data class ItemsItem(
@field:SerializedName("order_item_id")
val orderItemId: Int? = null,
@field:SerializedName("price")
val price: Int? = null,
@field:SerializedName("subtotal")
val subtotal: Int? = null
)

View File

@ -45,8 +45,6 @@ import retrofit2.Call
import retrofit2.Response
import retrofit2.http.Body
import retrofit2.http.DELETE
import retrofit2.http.Field
import retrofit2.http.FormUrlEncoded
import retrofit2.http.GET
import retrofit2.http.Multipart
import retrofit2.http.POST
@ -204,19 +202,22 @@ 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>
@GET("order/{status}")
suspend fun getSellList(
@Path("status") status: String
): Response<com.alya.ecommerce_serang.data.api.response.store.orders.OrderListResponse>
@PUT("store/order/update")
suspend fun confirmOrder(
@Body confirmOrder : CompletedOrderRequest
): Response<CompletedOrderResponse>
@PUT("store/order/update")
suspend fun updateOrder(
@Query("order_id") orderId: Int?,
@Query("status") status: String
): Response<com.alya.ecommerce_serang.data.api.response.store.orders.UpdateOrderItemResponse>
@Multipart
@POST("addcomplaint")
suspend fun addComplaint(

View File

@ -7,7 +7,6 @@ import com.alya.ecommerce_serang.data.api.dto.CourierCostRequest
import com.alya.ecommerce_serang.data.api.dto.CreateAddressRequest
import com.alya.ecommerce_serang.data.api.dto.OrderRequest
import com.alya.ecommerce_serang.data.api.dto.OrderRequestBuy
import com.alya.ecommerce_serang.data.api.dto.OrdersItem
import com.alya.ecommerce_serang.data.api.dto.UserProfile
import com.alya.ecommerce_serang.data.api.response.customer.cart.DataItem
import com.alya.ecommerce_serang.data.api.response.customer.order.CreateOrderResponse
@ -234,35 +233,6 @@ 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()
@ -461,5 +431,4 @@ suspend fun uploadPaymentProof(request: AddEvidenceMultipartRequest): Result<Add
emit(Result.Error(e))
}
}.flowOn(Dispatchers.IO)
}

View File

@ -0,0 +1,45 @@
package com.alya.ecommerce_serang.data.repository
import android.util.Log
import com.alya.ecommerce_serang.data.api.response.store.orders.OrderListResponse
import com.alya.ecommerce_serang.data.api.retrofit.ApiService
class SellsRepository(private val apiService: ApiService) {
suspend fun getSellList(status: String): Result<OrderListResponse> {
return try {
Log.d("SellsRepository", "Add Evidence : $status")
val response = apiService.getSellList(status)
if (response.isSuccessful) {
val allListSell = response.body()
if (allListSell != null) {
Log.d("SellsRepository", "Add Evidence successfully: ${allListSell.message}")
Result.Success(allListSell)
} else {
Log.e("SellsRepository", "Response body was null")
Result.Error(Exception("Empty response from server"))
}
} else {
val errorBody = response.errorBody()?.string() ?: "Unknown error"
Log.e("SellsRepository", "Error Add Evidence : $errorBody")
Result.Error(Exception(errorBody))
}
} catch (e: Exception) {
Log.e("SellsRepository", "Exception Add Evidence ", e)
Result.Error(e)
}
}
suspend fun updateOrderStatus(orderId: Int?, status: String) {
try {
val response = apiService.updateOrder(orderId, status)
if (response.isSuccessful) {
Log.d("SellsRepository", "Order status updated successfully: orderId=$orderId, status=$status")
} else {
Log.e("SellsRepository", "Error updating order status: orderId=$orderId, status=$status")
}
} catch (e: Exception) {
Log.e("SellsRepository", "Exception updating order status", e)
}
}
}

View File

@ -16,10 +16,7 @@ import com.alya.ecommerce_serang.ui.profile.mystore.balance.BalanceActivity
import com.alya.ecommerce_serang.ui.profile.mystore.product.ProductActivity
import com.alya.ecommerce_serang.ui.profile.mystore.profile.DetailStoreProfileActivity
import com.alya.ecommerce_serang.ui.profile.mystore.review.ReviewFragment
import com.alya.ecommerce_serang.ui.profile.mystore.sells.all_sells.AllSellsFragment
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
import com.alya.ecommerce_serang.ui.profile.mystore.sells.SellsListFragment
import com.alya.ecommerce_serang.utils.BaseViewModelFactory
import com.alya.ecommerce_serang.utils.SessionManager
import com.alya.ecommerce_serang.utils.viewmodel.MyStoreViewModel
@ -84,31 +81,19 @@ class MyStoreActivity : AppCompatActivity() {
}
binding.tvHistory.setOnClickListener {
supportFragmentManager.beginTransaction()
.replace(android.R.id.content, AllSellsFragment())
.addToBackStack(null)
.commit()
navigateToSellsFragment("all")
}
binding.layoutPerluTagihan.setOnClickListener {
supportFragmentManager.beginTransaction()
.replace(android.R.id.content, OrderFragment())
.addToBackStack(null)
.commit()
navigateToSellsFragment("pending")
}
binding.layoutPembayaran.setOnClickListener {
supportFragmentManager.beginTransaction()
.replace(android.R.id.content, PaymentFragment())
.addToBackStack(null)
.commit()
navigateToSellsFragment("paid")
}
binding.layoutPerluDikirim.setOnClickListener {
supportFragmentManager.beginTransaction()
.replace(android.R.id.content, ShipmentFragment())
.addToBackStack(null)
.commit()
navigateToSellsFragment("processed")
}
binding.layoutProductMenu.setOnClickListener {
@ -129,4 +114,12 @@ class MyStoreActivity : AppCompatActivity() {
.commit()
}
}
private fun navigateToSellsFragment(status: String) {
val sellsFragment = SellsListFragment.newInstance(status)
supportFragmentManager.beginTransaction()
.replace(android.R.id.content, sellsFragment)
.addToBackStack(null)
.commit()
}
}

View File

@ -2,18 +2,48 @@ package com.alya.ecommerce_serang.ui.profile.mystore.sells
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import androidx.activity.viewModels
import com.alya.ecommerce_serang.R
import com.alya.ecommerce_serang.ui.profile.mystore.sells.all_sells.AllSellsFragment
import com.alya.ecommerce_serang.data.api.retrofit.ApiConfig
import com.alya.ecommerce_serang.data.repository.SellsRepository
import com.alya.ecommerce_serang.databinding.ActivitySellsBinding
import com.alya.ecommerce_serang.utils.BaseViewModelFactory
import com.alya.ecommerce_serang.utils.SessionManager
import com.alya.ecommerce_serang.utils.viewmodel.SellsViewModel
class SellsActivity : AppCompatActivity() {
private lateinit var binding: ActivitySellsBinding
private lateinit var sessionManager: SessionManager
private val viewModel: SellsViewModel by viewModels {
BaseViewModelFactory {
val apiService = ApiConfig.getApiService(sessionManager)
val sellsRepository = SellsRepository(apiService)
SellsViewModel(sellsRepository)
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_sells)
binding = ActivitySellsBinding.inflate(layoutInflater)
setContentView(binding.root)
sessionManager = SessionManager(this)
setupHeader()
if (savedInstanceState == null) {
supportFragmentManager.beginTransaction()
.replace(R.id.sells_fragment_container, AllSellsFragment())
.replace(R.id.fragment_container_sells, SellsFragment())
.commit()
}
}
private fun setupHeader() {
binding.header.headerTitle.text = "Penjualan Saya"
binding.header.headerLeftIcon.setOnClickListener {
onBackPressedDispatcher.onBackPressed()
}
}
}

View File

@ -1,152 +1,188 @@
package com.alya.ecommerce_serang.ui.profile.mystore.sells
import android.util.Log
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
import com.alya.ecommerce_serang.data.api.response.store.orders.OrdersItem
import com.alya.ecommerce_serang.utils.viewmodel.SellsViewModel
import com.bumptech.glide.Glide
import java.text.SimpleDateFormat
import java.util.Calendar
import java.util.Locale
import java.util.TimeZone
class SellsAdapter : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
private var orderList: List<OrdersItem?> = emptyList()
class SellsAdapter(
private val onOrderClickListener: (OrdersItem) -> Unit,
private val viewModel: SellsViewModel
) : RecyclerView.Adapter<SellsAdapter.SellsViewHolder>() {
// 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
private val sells = mutableListOf<OrdersItem>()
private var fragmentStatus: String = "all"
// Method to submit list to the adapter
fun submitList(orders: List<OrdersItem?>?) {
orderList = orders ?: emptyList()
fun setFragmentStatus(status: String) {
fragmentStatus = status
}
fun submitList(newSells: List<OrdersItem>) {
sells.clear()
sells.addAll(newSells)
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)
fun findResource(status: String): Int {
return when (status) {
"pending" -> R.layout.item_sells_order
"paid" -> R.layout.item_sells_payment
"processed" -> R.layout.item_sells_shipment
else -> R.layout.item_sells_payment
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): SellsViewHolder {
val view = LayoutInflater.from(parent.context).inflate(findResource(fragmentStatus), parent, false)
return SellsViewHolder(view)
}
override fun onBindViewHolder(holder: SellsViewHolder, position: Int) {
holder.bind(sells[position])
}
override fun getItemCount(): Int = sells.size
inner class SellsViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
private val tvSellsTitle: TextView = itemView.findViewById(R.id.tv_sells_title)
private val tvSellsNumber: TextView = itemView.findViewById(R.id.tv_sells_number)
private val tvSellsDueDesc: TextView = itemView.findViewById(R.id.tv_sells_due_desc)
private val tvSellsDue: TextView = itemView.findViewById(R.id.tv_sells_due)
private val tvSellsLocation: TextView = itemView.findViewById(R.id.tv_sells_location)
private val tvSellsCustomer: TextView = itemView.findViewById(R.id.tv_sells_customer)
private val ivSellsProduct: ImageView = itemView.findViewById(R.id.iv_sells_product)
private val tvSellsProductName: TextView = itemView.findViewById(R.id.tv_sells_product_name)
private val tvSellsProductQty: TextView = itemView.findViewById(R.id.tv_sells_product_qty)
private val tvSellsProductPrice: TextView = itemView.findViewById(R.id.tv_sells_product_price)
private val tvSeeMore: TextView = itemView.findViewById(R.id.tv_see_more)
private val tvSellsQty: TextView = itemView.findViewById(R.id.tv_sells_qty)
private val tvSellsPrice: TextView = itemView.findViewById(R.id.tv_sells_price)
private val btnEditOrder: Button = itemView.findViewById(R.id.btn_edit_order)
private val btnConfirmOrder: Button = itemView.findViewById(R.id.btn_confirm_order)
private val btnConfirmPayment: Button = itemView.findViewById(R.id.btn_confirm_payment)
private val btnConfirmShipment: Button = itemView.findViewById(R.id.btn_confirm_shipment)
fun bind(sells: OrdersItem) {
tvSellsNumber.text = "No. Pesanan: ${sells.orderId}"
tvSellsLocation.text = sells.subdistrict
tvSellsCustomer.text = sells.username
val product = sells.orderItems?.get(0)
product?.let {
tvSellsProductName.text = it.productName
tvSellsProductQty.text = "x${it.quantity}"
tvSellsProductPrice.text = "Rp${it.price}"
Glide.with(itemView.context)
.load(it.productImage)
.placeholder(R.drawable.placeholder_image)
.into(ivSellsProduct)
}
TYPE_PAYMENT -> {
val view = LayoutInflater.from(parent.context).inflate(R.layout.item_sells_payment, parent, false)
PaymentViewHolder(view)
sells.orderItems?.size?.let {
if (it > 1) {
tvSeeMore.visibility = View.VISIBLE
tvSeeMore.text = "Lihat ${it.minus(1)} produk lainnya"
} else {
tvSeeMore.visibility = View.GONE
}
}
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)
tvSellsQty.text = "${sells.orderItems?.size} produk"
tvSellsPrice.text = "Rp${sells.totalAmount}"
adjustDisplay(fragmentStatus, sells)
}
private fun adjustDisplay(status: String, sells: OrdersItem) {
Log.d("SellsAdapter", "Adjusting display for status: $status")
when (status) {
"pending" -> {
tvSellsDue.text = formatDueDate(sells.updatedAt.toString(), 3)
btnEditOrder.setOnClickListener {
TODO("Go to DetailOrderActivity")
}
btnConfirmOrder.setOnClickListener {
viewModel.updateOrderStatus(sells.orderId, "unpaid")
}
}
"paid" -> {
tvSellsDue.text = formatDueDate(sells.updatedAt.toString(), 1)
btnConfirmPayment.setOnClickListener {
TODO("Go to DetailPaymentActivity")
}
}
"processed" -> {
tvSellsDue.text = formatDueDate(sells.updatedAt.toString(), 2)
btnConfirmShipment.setOnClickListener {
TODO("Go to DetailShipmentActivity")
}
}
"shipped" -> {
tvSellsTitle.text = "Pesanan Telah Dikirim"
tvSellsDueDesc.text = "Dikirimkan pada"
tvSellsDue.text = formatDueDate(sells.updatedAt.toString(), 0)
tvSellsDue.background = itemView.context.getDrawable(R.drawable.bg_product_inactive)
btnConfirmPayment.visibility = View.GONE
}
"delivered" -> {
tvSellsTitle.text = "Pesanan Telah Dikirim"
tvSellsDueDesc.text = "Dikirimkan pada"
tvSellsDue.text = formatDueDate(sells.updatedAt.toString(), 0)
tvSellsDue.background = itemView.context.getDrawable(R.drawable.bg_product_inactive)
btnConfirmPayment.visibility = View.GONE
}
"completed" -> {
tvSellsTitle.text = "Pesanan Selesai"
tvSellsDueDesc.text = "Selesai pada"
tvSellsDue.text = formatDueDate(sells.updatedAt.toString(), 0)
tvSellsDue.background = itemView.context.getDrawable(R.drawable.bg_product_inactive)
btnConfirmPayment.visibility = View.GONE
}
"canceled" -> {
tvSellsTitle.text = "Pesanan Dibatalkan"
tvSellsDueDesc.text = "Dibatalkan pada"
tvSellsDue.text = formatDueDate(sells.updatedAt.toString(), 0)
tvSellsDue.background = itemView.context.getDrawable(R.drawable.bg_product_inactive)
btnConfirmPayment.visibility = View.GONE
}
}
}
}
// Determine the view type based on the order status
override fun getItemViewType(position: Int): Int {
val order = orderList[position]
return when (order?.shipmentStatus) {
"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
}
}
private fun formatDueDate(date: String, dueDay: Int): String {
return try {
val inputFormat = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.getDefault())
inputFormat.timeZone = TimeZone.getTimeZone("UTC")
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)
}
}
val outputFormat = SimpleDateFormat("dd MM; HH.mm", Locale("id", "ID"))
override fun getItemCount(): Int = orderList.size
val date = inputFormat.parse(date)
// 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)
date?.let {
val calendar = Calendar.getInstance()
calendar.time = it
calendar.add(Calendar.DATE, dueDay)
fun bind(order: OrdersItem?) {
tvOrderNumber.text = "Order #${order?.orderId}"
tvOrderCustomer.text = order?.userId.toString()
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?.userId.toString()
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?.addressId.toString()}"
}
}
// 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}"
outputFormat.format(calendar.time)
} ?: date
} catch (e: Exception) {
Log.e("DueDateFormatting", "Error formatting date: ${e.message}")
date
}.toString()
}
}
}

View File

@ -1,45 +1,57 @@
package com.alya.ecommerce_serang.ui.profile.mystore.sells
import androidx.lifecycle.ViewModelProvider
import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.viewpager2.widget.ViewPager2
import com.google.android.material.tabs.TabLayoutMediator
import com.alya.ecommerce_serang.R
import com.alya.ecommerce_serang.utils.viewmodel.SellsViewModel
import com.alya.ecommerce_serang.databinding.FragmentSellsBinding
import com.alya.ecommerce_serang.utils.SessionManager
class SellsFragment : Fragment() {
private lateinit var viewModel: SellsViewModel
private var _binding: FragmentSellsBinding? = null
private val binding get() = _binding!!
private lateinit var sessionManager: SessionManager
private lateinit var viewPagerAdapter: SellsViewPagerAdapter
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.fragment_sells, container, false)
_binding = FragmentSellsBinding.inflate(inflater, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
sessionManager = SessionManager(requireContext())
// val repository = OrderRepository(ApiService.create())
viewModel = ViewModelProvider(this)[SellsViewModel::class.java]
viewPagerAdapter = SellsViewPagerAdapter(requireActivity())
binding.viewPagerSells.adapter = viewPagerAdapter
val tabs = listOf(
"Semua Pesanan", "Perlu Tagihan", "Konfirmasi Pembayaran",
"Perlu Dikirim", "Dikirim", "Selesai",
"Pembatalan", "Klaim Pembayaran", "Pengiriman Gagal"
"Semua Pesanan",
"Perlu Tagihan",
"Konfirmasi Pembayaran",
"Perlu Dikirim",
"Dikirim",
"Selesai",
"Pembatalan",
"Klaim Pembayaran",
"Pengiriman Gagal"
)
val adapter = SellsPagerAdapter(this, tabs.size)
val viewPager: ViewPager2 = view.findViewById(R.id.view_pager_sells)
viewPager.adapter = adapter
TabLayoutMediator(view.findViewById(R.id.tab_layout_sells), viewPager) { tab, position ->
TabLayoutMediator(binding.tabLayoutSells, binding.viewPagerSells) { tab, position ->
tab.text = tabs[position]
}.attach()
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
}

View File

@ -0,0 +1,131 @@
package com.alya.ecommerce_serang.ui.profile.mystore.sells
import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.fragment.app.viewModels
import androidx.recyclerview.widget.LinearLayoutManager
import com.alya.ecommerce_serang.data.api.response.store.orders.OrdersItem
import com.alya.ecommerce_serang.data.api.retrofit.ApiConfig
import com.alya.ecommerce_serang.data.repository.SellsRepository
import com.alya.ecommerce_serang.databinding.FragmentSellsListBinding
import com.alya.ecommerce_serang.ui.order.address.ViewState
import com.alya.ecommerce_serang.utils.BaseViewModelFactory
import com.alya.ecommerce_serang.utils.SessionManager
import com.alya.ecommerce_serang.utils.viewmodel.SellsViewModel
class SellsListFragment : Fragment() {
private var _binding: FragmentSellsListBinding? = null
private val binding get() = _binding!!
private lateinit var sessionManager: SessionManager
private val viewModel: SellsViewModel by viewModels {
BaseViewModelFactory {
val apiService = ApiConfig.getApiService(sessionManager)
val sellsRepository = SellsRepository(apiService)
SellsViewModel(sellsRepository)
}
}
private lateinit var sellsAdapter: SellsAdapter
private var status: String = "all"
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
sessionManager = SessionManager(requireContext())
arguments?.let {
status = it.getString(ARG_STATUS) ?: "all"
}
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
_binding = FragmentSellsListBinding.inflate(inflater, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
setupRecyclerView()
observeSellsList()
loadSells()
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
companion object {
private const val ARG_STATUS = "status"
fun newInstance(status: String): SellsListFragment {
return SellsListFragment().apply {
arguments = Bundle().apply {
putString(ARG_STATUS, status)
}
}
}
}
private fun setupRecyclerView() {
sellsAdapter = SellsAdapter(
onOrderClickListener = { sells ->
// Handle order click
navigateToSellsDetail(sells)
},
viewModel = viewModel
)
sellsAdapter.setFragmentStatus(status)
binding.rvSells.apply {
layoutManager = LinearLayoutManager(requireContext())
adapter = sellsAdapter
}
}
private fun observeSellsList() {
viewModel.sells.observe(viewLifecycleOwner) { result ->
when (result) {
is ViewState.Success -> {
binding.progressBar.visibility = View.GONE
if (result.data.isNullOrEmpty()) {
binding.tvEmptyState.visibility = View.VISIBLE
binding.rvSells.visibility = View.GONE
} else {
binding.tvEmptyState.visibility = View.GONE
binding.rvSells.visibility = View.VISIBLE
//sellsAdapter.submitList(result.data)
}
}
is ViewState.Error -> {
binding.progressBar.visibility = View.GONE
binding.tvEmptyState.visibility = View.VISIBLE
Toast.makeText(requireContext(), result.message, Toast.LENGTH_SHORT).show()
}
is ViewState.Loading -> {
null
}
}
}
}
private fun loadSells() {
viewModel.getSellList(status)
}
private fun navigateToSellsDetail(sells: OrdersItem) {
// In a real app, you would navigate to sells detail screen
// For example: findNavController().navigate(SellsListFragmentDirections.actionToSellsDetail(sells.orderId))
Toast.makeText(requireContext(), "Order ID: ${sells.orderId}", Toast.LENGTH_SHORT).show()
}
}

View File

@ -1,34 +0,0 @@
package com.alya.ecommerce_serang.ui.profile.mystore.sells
import androidx.fragment.app.Fragment
import androidx.viewpager2.adapter.FragmentStateAdapter
import com.alya.ecommerce_serang.ui.profile.mystore.sells.all_sells.AllSellsFragment
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.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
import com.alya.ecommerce_serang.ui.profile.mystore.sells.shipped.ShippedFragment
class SellsPagerAdapter(fragment: Fragment, private val itemCount: Int) :
FragmentStateAdapter(fragment) {
override fun getItemCount(): Int = itemCount
override fun createFragment(position: Int): Fragment {
return when (position) {
0 -> AllSellsFragment()
1 -> OrderFragment()
2 -> PaymentFragment()
3 -> ShipmentFragment()
4 -> ShippedFragment()
5 -> CompletedFragment()
6 -> CancellationFragment()
7 -> FailedPaymentFragment()
8 -> FailedShipmentFragment()
else -> Fragment()
}
}
}

View File

@ -0,0 +1,27 @@
package com.alya.ecommerce_serang.ui.profile.mystore.sells
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity
import androidx.viewpager2.adapter.FragmentStateAdapter
class SellsViewPagerAdapter(fragmentActivity: FragmentActivity)
: FragmentStateAdapter(fragmentActivity) {
private val sellsStatuses = listOf(
"all", // Semua Pesanan
"pending", // Perlu Tagihan
"processed", // Konfirmasi Pembayaran
"paid", // Perlu Dikirim
"shipped", // Dikirim
"delivered", // Dikirim
"completed", // Selesai
"canceled", // Dibatalkan
TODO("Klaim Pembayaran dan Pengajuan Komplain belum ada statusnya")
)
override fun getItemCount(): Int = sellsStatuses.size
override fun createFragment(position: Int): Fragment {
return SellsListFragment.newInstance(sellsStatuses[position])
}
}

View File

@ -1,41 +0,0 @@
package com.alya.ecommerce_serang.ui.profile.mystore.sells.all_sells
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.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? {
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

@ -1,41 +0,0 @@
package com.alya.ecommerce_serang.ui.profile.mystore.sells.cancellation
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.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? {
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

@ -1,41 +0,0 @@
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

@ -1,42 +0,0 @@
package com.alya.ecommerce_serang.ui.profile.mystore.sells.failed_payment
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.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? {
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

@ -1,41 +0,0 @@
package com.alya.ecommerce_serang.ui.profile.mystore.sells.failed_shipment
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.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? {
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

@ -0,0 +1,21 @@
package com.alya.ecommerce_serang.ui.profile.mystore.sells.order
import android.os.Bundle
import androidx.activity.enableEdgeToEdge
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import com.alya.ecommerce_serang.R
class DetailOrderActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
setContentView(R.layout.activity_detail_order)
ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main)) { v, insets ->
val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom)
insets
}
}
}

View File

@ -1,60 +0,0 @@
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?.userId.toString()
tvOrderDue.text = order?.createdAt + 7
tvOrderQty.text = "${order?.orderItems?.size} produk"
tvOrderPrice.text = "Rp${order?.totalAmount}"
}
}
}

View File

@ -1,40 +0,0 @@
package com.alya.ecommerce_serang.ui.profile.mystore.sells.order
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.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? {
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

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

@ -1,61 +0,0 @@
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?.userId.toString()
tvPaymentLocation.text = order?.addressId.toString()
}
}
}

View File

@ -1,40 +0,0 @@
package com.alya.ecommerce_serang.ui.profile.mystore.sells.payment
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.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? {
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

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

@ -1,56 +0,0 @@
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.userId.toString()
tvShipmentLocation.text = order.addressId.toString()
}
}
}

View File

@ -1,41 +0,0 @@
package com.alya.ecommerce_serang.ui.profile.mystore.sells.shipment
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.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? {
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

@ -1,41 +0,0 @@
package com.alya.ecommerce_serang.ui.profile.mystore.sells.shipped
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.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? {
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

@ -1,26 +1,61 @@
package com.alya.ecommerce_serang.utils.viewmodel
import android.util.Log
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 com.alya.ecommerce_serang.data.api.response.store.orders.OrdersItem
import com.alya.ecommerce_serang.data.repository.Result
import com.alya.ecommerce_serang.data.repository.SellsRepository
import com.alya.ecommerce_serang.ui.order.address.ViewState
import kotlinx.coroutines.launch
class SellsViewModel(private val repository: OrderRepository) : ViewModel() {
private val _sellsList = MutableLiveData<List<OrdersItem?>>()
val sellsList: LiveData<List<OrdersItem?>> get() = _sellsList
class SellsViewModel(private val repository: SellsRepository) : ViewModel() {
companion object {
private const val TAG = "SellsViewModel"
}
private val _sells = MutableLiveData<ViewState<List<OrdersItem?>?>>()
val sells: LiveData<ViewState<List<OrdersItem?>?>> = _sells
fun getSellList(status: String) {
_sells.value = ViewState.Loading
fun loadOrdersByStatus(status: String) {
viewModelScope.launch {
val result = if (status == "all") {
repository.fetchSells()
} else {
repository.fetchOrdersByStatus(status)
_sells.value = ViewState.Loading
try {
when (val result = repository.getSellList(status)) {
is Result.Success -> {
_sells.value = ViewState.Success(result.data.orders)
Log.d("SellsViewModel", "Sells loaded successfully: ${result.data.orders?.size} items")
}
is Result.Error -> {
_sells.value = ViewState.Error(result.exception.message ?: "Unknown error occurred")
Log.e("SellsViewModel", "Error loading sells", result.exception)
}
is Result.Loading -> {
null
}
}
} catch (e: Exception) {
_sells.value = ViewState.Error("An unexpected error occurred: ${e.message}")
Log.e("SellsViewModel", "Exception in getOrderList", e)
}
}
}
fun updateOrderStatus(orderId: Int?, status: String) {
Log.d(TAG, "Updating order status: orderId=$orderId, status=$status")
viewModelScope.launch {
try {
repository.updateOrderStatus(orderId, status)
Log.d(TAG, "Order status updated successfully: orderId=$orderId, status=$status")
} catch (e: Exception) {
Log.e(TAG, "Error updating order status", e)
}
_sellsList.value = result
}
}
}

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.profile.mystore.sells.order.DetailOrderActivity">
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.profile.mystore.sells.payment.DetailPaymentActivity">
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.profile.mystore.sells.shipment.DetailShipmentActivity">
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -1,14 +1,55 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout
<LinearLayout
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"
android:orientation="vertical"
tools:context=".ui.profile.mystore.sells.SellsActivity">
<FrameLayout
android:id="@+id/sells_fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<include
android:id="@+id/header"
layout="@layout/header" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
<!-- Search Bar -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="16dp"
android:background="@color/white">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:orientation="horizontal"
android:background="@drawable/bg_text_field"
android:paddingHorizontal="6dp"
android:paddingVertical="10dp">
<ImageView
android:layout_width="14dp"
android:layout_height="14dp"
android:src="@drawable/ic_search"
android:contentDescription="Search Icon" />
<EditText
android:id="@+id/edt_search"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@null"
android:hint="Cari No. Pesanan, Nama Pemesan, Nama Produk, atau Lokasi di sini..."
android:inputType="text"
style="@style/body_small"
android:layout_marginStart="6dp"/>
</LinearLayout>
</LinearLayout>
<androidx.fragment.app.FragmentContainerView
android:id="@+id/fragment_container_sells"
android:layout_width="match_parent"
android:layout_height="0dp" />
</LinearLayout>

View File

@ -1,6 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<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"/>

View File

@ -1,7 +0,0 @@
<?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_cancellation"
android:layout_width="match_parent"
android:layout_height="match_parent"/>

View File

@ -1,7 +0,0 @@
<?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,7 +0,0 @@
<?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_failed_payment"
android:layout_width="match_parent"
android:layout_height="match_parent"/>

View File

@ -1,7 +0,0 @@
<?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_failed_shipment"
android:layout_width="match_parent"
android:layout_height="match_parent"/>

View File

@ -1,7 +0,0 @@
<?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_order"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:listitem="@layout/item_sells_order" />

View File

@ -11,10 +11,12 @@
android:background="@android:color/white"
app:layout_constraintTop_toTopOf="parent"
app:tabGravity="fill"
app:tabIndicatorColor="@color/blue_200"
app:tabMode="scrollable"
app:tabSelectedTextColor="@color/blue_200"
app:tabTextColor="@android:color/darker_gray" />
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" />
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/viewPager"

View File

@ -1,8 +0,0 @@
<?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_payment"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:listitem="@layout/item_sells_payment"/>

View File

@ -0,0 +1,38 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.profile.mystore.sells.SellsListFragment">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv_sells"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
tools:listitem="@layout/item_sells_order" />
<TextView
android:id="@+id/tv_empty_state"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TIdak ada penjualan"
android:textSize="16sp"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ProgressBar
android:id="@+id/progress_bar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</FrameLayout>

View File

@ -1,7 +0,0 @@
<?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_shipment"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:listitem="@layout/item_sells_shipment" />

View File

@ -1,7 +0,0 @@
<?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_shipped"
android:layout_width="match_parent"
android:layout_height="match_parent"/>

View File

@ -16,7 +16,7 @@
app:layout_constraintTop_toTopOf="parent"/>
<LinearLayout
android:id="@+id/layout_order_header"
android:id="@+id/layout_sells_header"
android:layout_width="220dp"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
@ -25,7 +25,7 @@
android:orientation="vertical">
<TextView
android:id="@+id/tv_order_title"
android:id="@+id/tv_sells_title"
style="@style/label_medium_prominent"
android:layout_width="match_parent"
android:layout_height="wrap_content"
@ -33,7 +33,7 @@
android:text="Pesanan Perlu Dibuat Tagihan"/>
<TextView
android:id="@+id/tv_order_number"
android:id="@+id/tv_sells_number"
style="@style/label_small"
android:layout_width="match_parent"
android:layout_height="wrap_content"
@ -52,7 +52,7 @@
android:src="@drawable/ic_person"/>
<TextView
android:id="@+id/tv_order_customer"
android:id="@+id/tv_sells_customer"
style="@style/label_small"
android:layout_width="match_parent"
android:layout_height="wrap_content"
@ -84,7 +84,7 @@
android:textColor="@color/black_300" />
<TextView
android:id="@+id/tv_order_due"
android:id="@+id/tv_sells_due"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="25 Okt; 23.59"
@ -97,11 +97,11 @@
<!-- Order Detail -->
<LinearLayout
android:id="@+id/layout_order_detail"
android:id="@+id/layout_sells_detail"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/layout_order_header"
app:layout_constraintTop_toBottomOf="@id/layout_sells_header"
android:paddingHorizontal="16dp"
android:layout_marginTop="8dp"
android:orientation="vertical">
@ -113,13 +113,13 @@
<!-- Product Detail -->
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/layout_order_product_detail"
android:id="@+id/layout_sells_product_detail"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingVertical="12dp">
<com.google.android.material.imageview.ShapeableImageView
android:id="@+id/iv_order_product"
android:id="@+id/iv_sells_product"
android:layout_width="95dp"
android:layout_height="64dp"
android:src="@drawable/placeholder_image"
@ -134,26 +134,26 @@
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_marginStart="13dp"
app:layout_constraintStart_toEndOf="@id/iv_order_product"
app:layout_constraintStart_toEndOf="@id/iv_sells_product"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent">
<TextView
android:id="@+id/tv_order_product_name"
android:id="@+id/tv_sells_product_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:maxLines="1"
android:text="Jaket Pink Fuschia"
style="@style/label_medium_prominent"/>
<TextView
android:id="@+id/tv_order_product_variant"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:maxLines="1"
android:text="S"
style="@style/label_medium"
android:textColor="@color/black_300"/>
<!-- <TextView-->
<!-- android:id="@+id/tv_sells_product_variant"-->
<!-- android:layout_width="match_parent"-->
<!-- android:layout_height="wrap_content"-->
<!-- android:maxLines="1"-->
<!-- android:text="S"-->
<!-- style="@style/label_medium"-->
<!-- android:textColor="@color/black_300"/>-->
</LinearLayout>
@ -163,12 +163,12 @@
android:orientation="vertical"
android:layout_marginStart="13dp"
android:gravity="end"
app:layout_constraintStart_toEndOf="@id/iv_order_product"
app:layout_constraintStart_toEndOf="@id/iv_sells_product"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="@id/iv_order_product">
app:layout_constraintBottom_toBottomOf="@id/iv_sells_product">
<TextView
android:id="@+id/tv_order_product_qty"
android:id="@+id/tv_sells_product_qty"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:maxLines="1"
@ -178,7 +178,7 @@
android:textAlignment="textEnd"/>
<TextView
android:id="@+id/tv_order_product_price"
android:id="@+id/tv_sells_product_price"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:maxLines="1"
@ -198,7 +198,7 @@
style="@style/label_small"
android:fontFamily="@font/dmsans_italic"
android:textColor="@color/black_300"
app:layout_constraintTop_toBottomOf="@id/iv_order_product"
app:layout_constraintTop_toBottomOf="@id/iv_sells_product"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:layout_marginVertical="8dp"
@ -219,7 +219,7 @@
android:paddingVertical="8dp">
<TextView
android:id="@+id/tv_order_qty"
android:id="@+id/tv_sells_qty"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="2 produk"
@ -240,7 +240,7 @@
android:textAlignment="textEnd"/>
<TextView
android:id="@+id/tv_order_price"
android:id="@+id/tv_sells_price"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Rp300.000"
@ -287,6 +287,6 @@
android:background="@color/black_50"
android:layout_marginTop="16dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/layout_order_detail"/>
app:layout_constraintTop_toBottomOf="@id/layout_sells_detail"/>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -16,7 +16,7 @@
app:layout_constraintTop_toTopOf="parent"/>
<LinearLayout
android:id="@+id/layout_payment_header"
android:id="@+id/layout_sells_header"
android:layout_width="220dp"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
@ -25,7 +25,7 @@
android:orientation="vertical">
<TextView
android:id="@+id/tv_payment_title"
android:id="@+id/tv_sells_title"
style="@style/label_medium_prominent"
android:layout_width="match_parent"
android:layout_height="wrap_content"
@ -33,7 +33,7 @@
android:text="Pesanan Telah Dibayar"/>
<TextView
android:id="@+id/tv_payment_number"
android:id="@+id/tv_sells_number"
style="@style/label_small"
android:layout_width="match_parent"
android:layout_height="wrap_content"
@ -53,6 +53,7 @@
android:gravity="end">
<TextView
android:id="@+id/tv_sells_due_desc"
android:layout_width="150dp"
android:layout_height="wrap_content"
android:maxLines="1"
@ -62,7 +63,7 @@
android:textColor="@color/black_300" />
<TextView
android:id="@+id/tv_payment_due"
android:id="@+id/tv_sells_due"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="25 Okt; 23.59"
@ -75,11 +76,11 @@
<!-- Order Detail -->
<LinearLayout
android:id="@+id/layout_payment_detail"
android:id="@+id/layout_sells_detail"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/layout_payment_header"
app:layout_constraintTop_toBottomOf="@id/layout_sells_header"
android:paddingHorizontal="16dp"
android:layout_marginTop="8dp"
android:orientation="vertical">
@ -91,13 +92,13 @@
<!-- Product Detail -->
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/layout_payment_product_detail"
android:id="@+id/layout_sells_product_detail"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingVertical="12dp">
<com.google.android.material.imageview.ShapeableImageView
android:id="@+id/iv_payment_product"
android:id="@+id/iv_sells_product"
android:layout_width="95dp"
android:layout_height="64dp"
android:src="@drawable/placeholder_image"
@ -112,26 +113,26 @@
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_marginStart="13dp"
app:layout_constraintStart_toEndOf="@id/iv_payment_product"
app:layout_constraintStart_toEndOf="@id/iv_sells_product"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent">
<TextView
android:id="@+id/tv_payment_product_name"
android:id="@+id/tv_sells_product_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:maxLines="1"
android:text="Jaket Pink Fuschia"
style="@style/label_medium_prominent"/>
<TextView
android:id="@+id/tv_payment_product_variant"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:maxLines="1"
android:text="S"
style="@style/label_medium"
android:textColor="@color/black_300"/>
<!-- <TextView-->
<!-- android:id="@+id/tv_sells_product_variant"-->
<!-- android:layout_width="match_parent"-->
<!-- android:layout_height="wrap_content"-->
<!-- android:maxLines="1"-->
<!-- android:text="S"-->
<!-- style="@style/label_medium"-->
<!-- android:textColor="@color/black_300"/>-->
</LinearLayout>
@ -141,12 +142,12 @@
android:orientation="vertical"
android:layout_marginStart="13dp"
android:gravity="end"
app:layout_constraintStart_toEndOf="@id/iv_payment_product"
app:layout_constraintStart_toEndOf="@id/iv_sells_product"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="@id/iv_payment_product">
app:layout_constraintBottom_toBottomOf="@id/iv_sells_product">
<TextView
android:id="@+id/tv_payment_product_qty"
android:id="@+id/tv_sells_product_qty"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:maxLines="1"
@ -156,7 +157,7 @@
android:textAlignment="textEnd"/>
<TextView
android:id="@+id/tv_payment_product_price"
android:id="@+id/tv_sells_product_price"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:maxLines="1"
@ -176,7 +177,7 @@
style="@style/label_small"
android:fontFamily="@font/dmsans_italic"
android:textColor="@color/black_300"
app:layout_constraintTop_toBottomOf="@id/iv_payment_product"
app:layout_constraintTop_toBottomOf="@id/iv_sells_product"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:layout_marginVertical="8dp"
@ -197,7 +198,7 @@
android:paddingVertical="8dp">
<TextView
android:id="@+id/tv_payment_qty"
android:id="@+id/tv_sells_qty"
style="@style/label_large"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
@ -218,7 +219,7 @@
android:textAlignment="textEnd"/>
<TextView
android:id="@+id/tv_payment_price"
android:id="@+id/tv_sells_price"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Rp300.000"
@ -262,7 +263,7 @@
app:tint="@color/black_500" />
<TextView
android:id="@+id/tv_payment_customer"
android:id="@+id/tv_sells_customer"
style="@style/label_small"
android:layout_width="match_parent"
android:layout_height="wrap_content"
@ -284,7 +285,7 @@
android:src="@drawable/ic_location" />
<TextView
android:id="@+id/tv_payment_location"
android:id="@+id/tv_sells_location"
style="@style/label_small"
android:layout_width="match_parent"
android:layout_height="wrap_content"
@ -313,6 +314,6 @@
android:background="@color/black_50"
android:layout_marginTop="16dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/layout_payment_detail"/>
app:layout_constraintTop_toBottomOf="@id/layout_sells_detail"/>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -16,7 +16,7 @@
app:layout_constraintTop_toTopOf="parent"/>
<LinearLayout
android:id="@+id/layout_shipment_header"
android:id="@+id/layout_sells_header"
android:layout_width="220dp"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
@ -25,7 +25,7 @@
android:orientation="vertical">
<TextView
android:id="@+id/tv_shipment_title"
android:id="@+id/tv_sells_title"
style="@style/label_medium_prominent"
android:layout_width="match_parent"
android:layout_height="wrap_content"
@ -33,7 +33,7 @@
android:text="Pesanan Perlu Dikirim"/>
<TextView
android:id="@+id/tv_shipment_number"
android:id="@+id/tv_sells_number"
style="@style/label_small"
android:layout_width="match_parent"
android:layout_height="wrap_content"
@ -62,7 +62,7 @@
android:textColor="@color/black_300" />
<TextView
android:id="@+id/tv_shipment_due"
android:id="@+id/tv_sells_due"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="25 Okt; 23.59"
@ -75,11 +75,11 @@
<!-- Order Detail -->
<LinearLayout
android:id="@+id/layout_shipment_detail"
android:id="@+id/layout_sells_detail"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/layout_shipment_header"
app:layout_constraintTop_toBottomOf="@id/layout_sells_header"
android:paddingHorizontal="16dp"
android:layout_marginTop="8dp"
android:orientation="vertical">
@ -91,13 +91,13 @@
<!-- Product Detail -->
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/layout_shipment_product_detail"
android:id="@+id/layout_sells_product_detail"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingVertical="12dp">
<com.google.android.material.imageview.ShapeableImageView
android:id="@+id/iv_shipment_product"
android:id="@+id/iv_sells_product"
android:layout_width="95dp"
android:layout_height="48dp"
android:src="@drawable/placeholder_image"
@ -112,31 +112,31 @@
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_marginStart="13dp"
app:layout_constraintStart_toEndOf="@id/iv_shipment_product"
app:layout_constraintStart_toEndOf="@id/iv_sells_product"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent">
<TextView
android:id="@+id/tv_shipment_product_name"
android:id="@+id/tv_sells_product_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:maxLines="1"
android:text="Jaket Pink Fuschia"
style="@style/label_medium_prominent"/>
<TextView
android:id="@+id/tv_shipment_product_variant"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:maxLines="1"
android:text="S"
style="@style/label_medium"
android:textColor="@color/black_300"/>
<!-- <TextView-->
<!-- android:id="@+id/tv_sells_product_variant"-->
<!-- android:layout_width="match_parent"-->
<!-- android:layout_height="wrap_content"-->
<!-- android:maxLines="1"-->
<!-- android:text="S"-->
<!-- style="@style/label_medium"-->
<!-- android:textColor="@color/black_300"/>-->
</LinearLayout>
<TextView
android:id="@+id/tv_shipment_product_qty"
android:id="@+id/tv_sells_product_qty"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:maxLines="1"
@ -145,9 +145,9 @@
android:layout_marginStart="13dp"
android:gravity="end"
android:textAlignment="textEnd"
app:layout_constraintStart_toEndOf="@id/iv_shipment_product"
app:layout_constraintStart_toEndOf="@id/iv_sells_product"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="@id/iv_shipment_product"/>
app:layout_constraintBottom_toBottomOf="@id/iv_sells_product"/>
<TextView
android:id="@+id/tv_see_more"
@ -159,7 +159,7 @@
style="@style/label_small"
android:fontFamily="@font/dmsans_italic"
android:textColor="@color/black_300"
app:layout_constraintTop_toBottomOf="@id/iv_shipment_product"
app:layout_constraintTop_toBottomOf="@id/iv_sells_product"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:layout_marginVertical="8dp"
@ -199,7 +199,7 @@
app:tint="@color/black_500" />
<TextView
android:id="@+id/tv_shipment_customer"
android:id="@+id/tv_sells_customer"
style="@style/label_small"
android:layout_width="match_parent"
android:layout_height="wrap_content"
@ -221,7 +221,7 @@
android:src="@drawable/ic_location" />
<TextView
android:id="@+id/tv_shipment_location"
android:id="@+id/tv_sells_location"
style="@style/label_small"
android:layout_width="match_parent"
android:layout_height="wrap_content"
@ -250,6 +250,6 @@
android:background="@color/black_50"
android:layout_marginTop="16dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/layout_shipment_detail"/>
app:layout_constraintTop_toBottomOf="@id/layout_sells_detail"/>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -10,7 +10,7 @@
<string name="item_price_txt">Rp%.1f</string>
<string name="retry">Coba lagi\n</string>
<string name="error_loading">Terdapat error...</string>
<string name="error_loading">Terdapat error</string>
<string name="new_products_text">Produk Terbaru</string>
<string name="rating">4.5</string>
<string name="open_store">Buka Toko</string>