add chcekout and fix other products

This commit is contained in:
shaulascr
2025-03-27 00:11:27 +07:00
parent 055f88977b
commit b8e6d93b24
11 changed files with 459 additions and 20 deletions

View File

@ -17,6 +17,9 @@
android:theme="@style/Theme.Ecommerce_serang"
android:usesCleartextTraffic="true"
tools:targetApi="31">
<activity
android:name=".ui.order.CheckoutActivity"
android:exported="false" />
<activity
android:name=".ui.product.ReviewProductActivity"
android:exported="false" />
@ -61,7 +64,7 @@
android:exported="false" />
<activity
android:name=".ui.MainActivity"
android:exported="false"></activity>
android:exported="false" />
</application>
</manifest>

View File

@ -61,6 +61,7 @@ class HorizontalProductAdapter(
val diffResult = DiffUtil.calculateDiff(diffCallback)
products = newProducts
diffResult.dispatchUpdatesTo(this)
notifyDataSetChanged()
}
fun updateLimitedProducts(newProducts: List<ProductsItem>) {

View File

@ -0,0 +1,21 @@
package com.alya.ecommerce_serang.ui.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 CheckoutActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
setContentView(R.layout.activity_checkout)
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

@ -0,0 +1,4 @@
package com.alya.ecommerce_serang.ui.order
class ProductOrderAdapter {
}

View File

@ -0,0 +1,4 @@
package com.alya.ecommerce_serang.ui.order
class SellerOrderAdapter {
}

View File

@ -53,22 +53,19 @@ class DetailProductActivity : AppCompatActivity() {
viewModel.loadProductDetail(productId)
viewModel.loadReviews(productId)
viewModel.productDetail.observe(this) { product ->
if (product != null) {
Log.d("ProductDetail", "Name: ${product.productName}, Price: ${product.price}")
// Update UI here, e.g., show in a TextView or ImageView
viewModel.loadProductDetail(productId)
} else {
Log.e("ProductDetail", "Failed to fetch product details")
}
}
observeProductDetail()
observeProductReviews()
}
private fun observeProductDetail() {
viewModel.productDetail.observe(this) { product ->
product?.let { updateUI(it) }
product?.let {
updateUI(it)
viewModel.loadOtherProducts(it.storeId)
}
}
viewModel.otherProducts.observe(this) { products ->
updateOtherProducts(products)
}
}
@ -78,6 +75,11 @@ class DetailProductActivity : AppCompatActivity() {
}
}
private fun updateOtherProducts(products: List<ProductsItem>) {
productAdapter?.updateProducts(products) // Make sure your adapter has a method to update data
}
private fun updateUI(product: Product){
binding.tvProductName.text = product.productName
binding.tvPrice.text = product.price

View File

@ -1,13 +1,16 @@
package com.alya.ecommerce_serang.ui.product
import android.util.Log
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.alya.ecommerce_serang.data.api.dto.ProductsItem
import com.alya.ecommerce_serang.data.api.response.Product
import com.alya.ecommerce_serang.data.api.response.ReviewsItem
import com.alya.ecommerce_serang.data.api.response.Store
import com.alya.ecommerce_serang.data.repository.ProductRepository
import com.alya.ecommerce_serang.data.repository.Result
import kotlinx.coroutines.launch
class ProductViewModel(private val repository: ProductRepository) : ViewModel() {
@ -21,6 +24,9 @@ class ProductViewModel(private val repository: ProductRepository) : ViewModel()
private val _reviewProduct = MutableLiveData<List<ReviewsItem>>()
val reviewProduct: LiveData<List<ReviewsItem>> get() = _reviewProduct
private val _otherProducts = MutableLiveData<List<ProductsItem>>()
val otherProducts: LiveData<List<ProductsItem>> get() = _otherProducts
fun loadProductDetail(productId: Int) {
viewModelScope.launch {
val result = repository.fetchProductDetail(productId)
@ -34,6 +40,22 @@ class ProductViewModel(private val repository: ProductRepository) : ViewModel()
_reviewProduct.value = reviews ?: emptyList()
}
}
fun loadOtherProducts(storeId: Int) {
viewModelScope.launch {
val result = repository.getAllProducts() // Fetch products
if (result is Result.Success) {
val allProducts = result.data // Extract the list
val filteredProducts = allProducts.filter { it.storeId == storeId } // Filter by storeId
_otherProducts.value = filteredProducts // Update LiveData
} else if (result is Result.Error) {
Log.e("ProductViewModel", "Error loading other products: ${result.exception.message}")
_otherProducts.value = emptyList() // Set empty list on failure
}
}
}
}
// fun loadStoreDetail(storeId: Int){

View File

@ -1,10 +1,12 @@
package com.alya.ecommerce_serang.ui.profile
import android.os.Bundle
import android.util.Log
import android.widget.Toast
import androidx.activity.enableEdgeToEdge
import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity
import com.alya.ecommerce_serang.R
import com.alya.ecommerce_serang.data.api.dto.UserProfile
import com.alya.ecommerce_serang.data.api.retrofit.ApiConfig
import com.alya.ecommerce_serang.data.api.retrofit.ApiService
@ -61,25 +63,33 @@ class DetailProfileActivity : AppCompatActivity() {
binding.tvNameUser.setText(user.name.toString())
binding.tvUsername.setText(user.username)
binding.tvEmailUser.setText(user.email)
binding.tvDateBirth.setText(formatDate(user.birthDate))
Log.d("ProfileActivity", "Raw Birth Date: ${user.birthDate}")
binding.tvDateBirth.setText(user.birthDate?.let { formatDate(it) } ?: "N/A")
Log.d("ProfileActivity", "Formatted Birth Date: ${formatDate(user.birthDate)}")
binding.tvNumberPhoneUser.setText(user.phone)
if (user.image != null && user.image is String) {
Glide.with(this)
.load(user.image)
.placeholder(R.drawable.baseline_account_circle_24)
.into(binding.profileImage)
}
}
private fun formatDate(dateString: String): String {
private fun formatDate(dateString: String?): String {
if (dateString.isNullOrEmpty()) return "N/A" // Return default if null
return try {
val inputFormat = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.getDefault()) //from json
inputFormat.timeZone = TimeZone.getTimeZone("UTC") //get timezone
val outputFormat = SimpleDateFormat("dd MMMM yyyy", Locale.getDefault()) // new format
val date = inputFormat.parse(dateString) // Parse from json format
outputFormat.format(date!!) // convert to new format
val inputFormat = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.getDefault())
inputFormat.timeZone = TimeZone.getTimeZone("UTC") // Ensure parsing in UTC
val outputFormat = SimpleDateFormat("dd-MM-yy", Locale.getDefault()) // Convert to "dd-MM-yy" format
val date = inputFormat.parse(dateString)
outputFormat.format(date ?: return "Invalid Date") // Ensure valid date
} catch (e: Exception) {
dateString // Return original if error occurs
Log.e("ERROR", "Date parsing error: ${e.message}") // Log errors for debugging
"Invalid Date"
}
}
}

View File

@ -0,0 +1,268 @@
<?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:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/cardview_light_background"
tools:context=".ui.order.CheckoutActivity">
<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:navigationIcon="@drawable/ic_back_24"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:title="Pemesanan" />
<ScrollView
android:id="@+id/scrollView"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginBottom="16dp"
app:layout_constraintTop_toBottomOf="@id/toolbar"
app:layout_constraintBottom_toTopOf="@id/btn_pay">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<!-- Delivery Address Section -->
<androidx.cardview.widget.CardView
android:id="@+id/card_delivery_address"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="16dp"
app:cardCornerRadius="8dp"
app:cardElevation="2dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="start"
android:padding="8dp">
<LinearLayout
android:id="@+id/linear_address"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="16dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@id/tv_change_address">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Alamat Pengiriman"
android:fontFamily="@font/dmsans_semibold"/>
<TextView
android:id="@+id/tv_places_address"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="Rumah"
android:fontFamily="@font/dmsans_medium"/>
<TextView
android:id="@+id/tv_address"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="Jl. Pegangasan Timur"
android:fontFamily="@font/dmsans_medium"/>
</LinearLayout>
<TextView
android:id="@+id/tv_change_address"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
android:text="Pilih Alamat"
android:textColor="@color/blue_500"
android:fontFamily="@font/dmsans_medium"
android:clickable="true"
android:focusable="true"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="@id/linear_address"/>
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>
<!-- Product Item Section -->
<androidx.cardview.widget.CardView
android:id="@+id/card_product"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="16dp"
app:cardCornerRadius="8dp"
app:cardElevation="2dp"
app:layout_constraintTop_toBottomOf="@id/card_delivery_address"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv_seller_order"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:listitem="@layout/item_order_seller"/>
</androidx.cardview.widget.CardView>
<!-- Voucher Section -->
<LinearLayout
android:id="@+id/layout_voucher"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:background="?attr/selectableItemBackground"
android:padding="16dp"
app:layout_constraintTop_toBottomOf="@id/card_product"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent">
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Gunakan Voucher"
android:fontFamily="@font/dmsans_semibold"/>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_arrow_right"/>
</LinearLayout>
<!-- Shipping Method Section -->
<LinearLayout
android:id="@+id/layout_shipping_method"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:orientation="vertical"
android:background="?attr/selectableItemBackground"
android:padding="16dp"
app:layout_constraintTop_toBottomOf="@id/layout_voucher"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Metode Pengiriman"
android:fontFamily="@font/dmsans_medium"/>
<TextView
android:id="@+id/tv_shipping_method"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Pilih Pengiriman"
android:fontFamily="@font/dmsans_medium"
android:layout_marginTop="4dp"/>
</LinearLayout>
<!-- Payment Method Section -->
<LinearLayout
android:id="@+id/layout_payment_method"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:orientation="vertical"
android:background="?attr/selectableItemBackground"
android:padding="16dp"
app:layout_constraintTop_toBottomOf="@id/layout_shipping_method"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Metode Pembayaran"
android:fontFamily="@font/dmsans_medium"/>
<TextView
android:id="@+id/tv_payment_method"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Bank Transfer"
android:fontFamily="@font/dmsans_medium"
android:layout_marginTop="4dp"/>
</LinearLayout>
<!-- Price Summary Section -->
<LinearLayout
android:id="@+id/layout_price_summary"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="16dp"
app:layout_constraintTop_toBottomOf="@id/layout_payment_method"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Subtotal"
android:fontFamily="@font/dmsans_medium"/>
<TextView
android:id="@+id/tv_subtotal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Rp65,000"
android:fontFamily="@font/dmsans_medium"/>
</LinearLayout>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="@color/soft_gray"
android:layout_marginVertical="8dp"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Total"
android:fontFamily="@font/dmsans_bold"/>
<TextView
android:id="@+id/tv_total"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Rp65,000"
android:fontFamily="@font/dmsans_bold"/>
</LinearLayout>
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
</ScrollView>
<!-- Pay Button -->
<com.google.android.material.button.MaterialButton
android:id="@+id/btn_pay"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="Bayar"
android:layout_margin="16dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -0,0 +1,61 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
xmlns:app="http://schemas.android.com/apk/res-auto">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="8dp"
android:gravity="center_vertical">
<ImageView
android:id="@+id/iv_product"
android:layout_width="64dp"
android:layout_height="64dp"
android:src="@drawable/placeholder_image"
android:scaleType="centerCrop"/>
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="vertical"
android:layout_marginStart="16dp">
<TextView
android:id="@+id/tv_product_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Keripik Balado"
android:fontFamily="@font/dmsans_bold"/>
<TextView
android:id="@+id/tv_product_quantity"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="1 buah"
android:fontFamily="@font/dmsans_medium" />
<TextView
android:id="@+id/tv_product_price"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Rp65,000"
android:fontFamily="@font/dmsans_medium"/>
</LinearLayout>
</LinearLayout>
<com.google.android.material.divider.MaterialDivider
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:dividerInsetStart="16dp"
app:dividerInsetEnd="16dp"/>
</LinearLayout>

View File

@ -0,0 +1,43 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<LinearLayout
android:id="@+id/linear_seller_order"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_margin="4dp"
android:gravity="center_vertical">
<ImageView
android:id="@+id/iv_seller_order"
android:layout_width="32dp"
android:layout_height="32dp"
android:src="@drawable/placeholder_image"/>
<TextView
android:id="@+id/tv_list_product_order"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Toko Buka"/>
</LinearLayout>
<com.google.android.material.divider.MaterialDivider
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:dividerInsetStart="16dp"
app:dividerInsetEnd="16dp"/>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv_seller_order_product"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:listitem="@layout/item_order_product"/>
</LinearLayout>