From b8e6d93b2419fc3191c7cd5afc81903bfd1c5199 Mon Sep 17 00:00:00 2001 From: shaulascr Date: Thu, 27 Mar 2025 00:11:27 +0700 Subject: [PATCH 01/16] add chcekout and fix other products --- app/src/main/AndroidManifest.xml | 5 +- .../ui/home/HorizontalProductAdapter.kt | 1 + .../ui/order/CheckoutActivity.kt | 21 ++ .../ui/order/ProductOrderAdapter.kt | 4 + .../ui/order/SellerOrderAdapter.kt | 4 + .../ui/product/DetailProductActivity.kt | 24 +- .../ui/product/ProductViewModel.kt | 22 ++ .../ui/profile/DetailProfileActivity.kt | 26 +- app/src/main/res/layout/activity_checkout.xml | 268 ++++++++++++++++++ .../main/res/layout/item_order_product.xml | 61 ++++ app/src/main/res/layout/item_order_seller.xml | 43 +++ 11 files changed, 459 insertions(+), 20 deletions(-) create mode 100644 app/src/main/java/com/alya/ecommerce_serang/ui/order/CheckoutActivity.kt create mode 100644 app/src/main/java/com/alya/ecommerce_serang/ui/order/ProductOrderAdapter.kt create mode 100644 app/src/main/java/com/alya/ecommerce_serang/ui/order/SellerOrderAdapter.kt create mode 100644 app/src/main/res/layout/activity_checkout.xml create mode 100644 app/src/main/res/layout/item_order_product.xml create mode 100644 app/src/main/res/layout/item_order_seller.xml diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 6693f7e..7b8f128 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -17,6 +17,9 @@ android:theme="@style/Theme.Ecommerce_serang" android:usesCleartextTraffic="true" tools:targetApi="31"> + @@ -61,7 +64,7 @@ android:exported="false" /> + android:exported="false" /> \ No newline at end of file diff --git a/app/src/main/java/com/alya/ecommerce_serang/ui/home/HorizontalProductAdapter.kt b/app/src/main/java/com/alya/ecommerce_serang/ui/home/HorizontalProductAdapter.kt index 8af4b5f..a23f60a 100644 --- a/app/src/main/java/com/alya/ecommerce_serang/ui/home/HorizontalProductAdapter.kt +++ b/app/src/main/java/com/alya/ecommerce_serang/ui/home/HorizontalProductAdapter.kt @@ -61,6 +61,7 @@ class HorizontalProductAdapter( val diffResult = DiffUtil.calculateDiff(diffCallback) products = newProducts diffResult.dispatchUpdatesTo(this) + notifyDataSetChanged() } fun updateLimitedProducts(newProducts: List) { diff --git a/app/src/main/java/com/alya/ecommerce_serang/ui/order/CheckoutActivity.kt b/app/src/main/java/com/alya/ecommerce_serang/ui/order/CheckoutActivity.kt new file mode 100644 index 0000000..329be6e --- /dev/null +++ b/app/src/main/java/com/alya/ecommerce_serang/ui/order/CheckoutActivity.kt @@ -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 + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/alya/ecommerce_serang/ui/order/ProductOrderAdapter.kt b/app/src/main/java/com/alya/ecommerce_serang/ui/order/ProductOrderAdapter.kt new file mode 100644 index 0000000..ace46d1 --- /dev/null +++ b/app/src/main/java/com/alya/ecommerce_serang/ui/order/ProductOrderAdapter.kt @@ -0,0 +1,4 @@ +package com.alya.ecommerce_serang.ui.order + +class ProductOrderAdapter { +} \ No newline at end of file diff --git a/app/src/main/java/com/alya/ecommerce_serang/ui/order/SellerOrderAdapter.kt b/app/src/main/java/com/alya/ecommerce_serang/ui/order/SellerOrderAdapter.kt new file mode 100644 index 0000000..7118b6a --- /dev/null +++ b/app/src/main/java/com/alya/ecommerce_serang/ui/order/SellerOrderAdapter.kt @@ -0,0 +1,4 @@ +package com.alya.ecommerce_serang.ui.order + +class SellerOrderAdapter { +} \ No newline at end of file diff --git a/app/src/main/java/com/alya/ecommerce_serang/ui/product/DetailProductActivity.kt b/app/src/main/java/com/alya/ecommerce_serang/ui/product/DetailProductActivity.kt index e8de51a..518714a 100644 --- a/app/src/main/java/com/alya/ecommerce_serang/ui/product/DetailProductActivity.kt +++ b/app/src/main/java/com/alya/ecommerce_serang/ui/product/DetailProductActivity.kt @@ -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) { + 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 diff --git a/app/src/main/java/com/alya/ecommerce_serang/ui/product/ProductViewModel.kt b/app/src/main/java/com/alya/ecommerce_serang/ui/product/ProductViewModel.kt index 87bb380..bd928b4 100644 --- a/app/src/main/java/com/alya/ecommerce_serang/ui/product/ProductViewModel.kt +++ b/app/src/main/java/com/alya/ecommerce_serang/ui/product/ProductViewModel.kt @@ -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>() val reviewProduct: LiveData> get() = _reviewProduct + private val _otherProducts = MutableLiveData>() + val otherProducts: LiveData> 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){ diff --git a/app/src/main/java/com/alya/ecommerce_serang/ui/profile/DetailProfileActivity.kt b/app/src/main/java/com/alya/ecommerce_serang/ui/profile/DetailProfileActivity.kt index af33617..f29c2c9 100644 --- a/app/src/main/java/com/alya/ecommerce_serang/ui/profile/DetailProfileActivity.kt +++ b/app/src/main/java/com/alya/ecommerce_serang/ui/profile/DetailProfileActivity.kt @@ -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" } } + } \ No newline at end of file diff --git a/app/src/main/res/layout/activity_checkout.xml b/app/src/main/res/layout/activity_checkout.xml new file mode 100644 index 0000000..2a992f2 --- /dev/null +++ b/app/src/main/res/layout/activity_checkout.xml @@ -0,0 +1,268 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_order_product.xml b/app/src/main/res/layout/item_order_product.xml new file mode 100644 index 0000000..1fc7eb5 --- /dev/null +++ b/app/src/main/res/layout/item_order_product.xml @@ -0,0 +1,61 @@ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_order_seller.xml b/app/src/main/res/layout/item_order_seller.xml new file mode 100644 index 0000000..3a6bfbd --- /dev/null +++ b/app/src/main/res/layout/item_order_seller.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + \ No newline at end of file From 65cd210e3fb187303b6ff41254a1e50367f027f7 Mon Sep 17 00:00:00 2001 From: shaulascr Date: Tue, 8 Apr 2025 02:55:02 +0700 Subject: [PATCH 02/16] add order --- .idea/misc.xml | 1 - app/build.gradle.kts | 4 +- .../data/api/dto/CheckoutData.kt | 12 + .../data/api/dto/CreateAddressRequest.kt | 41 ++ .../data/api/dto/OrderRequest.kt | 32 ++ .../data/api/retrofit/ApiService.kt | 13 + .../data/repository/OrderRepository.kt | 42 ++ .../ui/order/CheckoutActivity.kt | 391 +++++++++++++++++- .../ui/order/CheckoutProductAdapter.kt | 47 +++ .../ui/order/CheckoutSellerAdapter.kt | 47 +++ .../ui/order/CheckoutViewModel.kt | 62 +++ .../ui/order/ProductOrderAdapter.kt | 4 - .../ui/order/SellerOrderAdapter.kt | 4 - .../ui/product/DetailProductActivity.kt | 53 +++ app/src/main/res/drawable/bg_popup_count.xml | 8 + app/src/main/res/layout/dialog_count_buy.xml | 71 ++++ 16 files changed, 811 insertions(+), 21 deletions(-) create mode 100644 app/src/main/java/com/alya/ecommerce_serang/data/api/dto/CheckoutData.kt create mode 100644 app/src/main/java/com/alya/ecommerce_serang/data/api/dto/CreateAddressRequest.kt create mode 100644 app/src/main/java/com/alya/ecommerce_serang/data/api/dto/OrderRequest.kt create mode 100644 app/src/main/java/com/alya/ecommerce_serang/data/repository/OrderRepository.kt create mode 100644 app/src/main/java/com/alya/ecommerce_serang/ui/order/CheckoutProductAdapter.kt create mode 100644 app/src/main/java/com/alya/ecommerce_serang/ui/order/CheckoutSellerAdapter.kt create mode 100644 app/src/main/java/com/alya/ecommerce_serang/ui/order/CheckoutViewModel.kt delete mode 100644 app/src/main/java/com/alya/ecommerce_serang/ui/order/ProductOrderAdapter.kt delete mode 100644 app/src/main/java/com/alya/ecommerce_serang/ui/order/SellerOrderAdapter.kt create mode 100644 app/src/main/res/drawable/bg_popup_count.xml create mode 100644 app/src/main/res/layout/dialog_count_buy.xml diff --git a/.idea/misc.xml b/.idea/misc.xml index 6d8fb78..fee46db 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,4 +1,3 @@ -