update gradle

This commit is contained in:
shaulascr
2025-04-11 16:46:26 +07:00
parent 4c7526e980
commit 59b44c932e
15 changed files with 96 additions and 42 deletions

View File

@ -1,3 +1,4 @@
import java.util.Properties
plugins { plugins {
alias(libs.plugins.android.application) alias(libs.plugins.android.application)
alias(libs.plugins.jetbrains.kotlin.android) alias(libs.plugins.jetbrains.kotlin.android)
@ -7,6 +8,14 @@ plugins {
// id("com.google.dagger.hilt.android") // id("com.google.dagger.hilt.android")
} }
val localProperties = Properties().apply {
val localPropertiesFile = rootProject.file("local.properties")
if (localPropertiesFile.exists()) {
load(localPropertiesFile.inputStream())
}
}
android { android {
namespace = "com.alya.ecommerce_serang" namespace = "com.alya.ecommerce_serang"
compileSdk = 34 compileSdk = 34
@ -23,7 +32,7 @@ android {
buildTypes { buildTypes {
release { release {
buildConfigField("String", "BASE_URL", "\"http://192.168.1.5:3000/\"") buildConfigField("String", "BASE_URL", "\"http://192.168.1.6:3000/\"")
isMinifyEnabled = false isMinifyEnabled = false
proguardFiles( proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"), getDefaultProguardFile("proguard-android-optimize.txt"),
@ -31,7 +40,7 @@ android {
) )
} }
debug { debug {
buildConfigField("String", "BASE_URL", "\"http://192.168.1.5:3000/\"") buildConfigField("String", "BASE_URL", "\"http://192.168.1.6:3000/\"")
} }
} }
compileOptions { compileOptions {

View File

@ -19,6 +19,9 @@
android:theme="@style/Theme.Ecommerce_serang" android:theme="@style/Theme.Ecommerce_serang"
android:usesCleartextTraffic="true" android:usesCleartextTraffic="true"
tools:targetApi="31"> tools:targetApi="31">
<activity
android:name=".data.api.response.cart.CartActivity"
android:exported="false" />
<activity <activity
android:name=".ui.order.address.EditAddressActivity" android:name=".ui.order.address.EditAddressActivity"
android:exported="false" /> android:exported="false" />

View File

@ -1,5 +1,6 @@
package com.alya.ecommerce_serang.data.api.response package com.alya.ecommerce_serang.data.api.response
import com.alya.ecommerce_serang.data.api.response.product.Product
import com.google.gson.annotations.SerializedName import com.google.gson.annotations.SerializedName
data class CreateProductResponse( data class CreateProductResponse(

View File

@ -0,0 +1,21 @@
package com.alya.ecommerce_serang.data.api.response.cart
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 CartActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
setContentView(R.layout.activity_cart)
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,4 +1,4 @@
package com.alya.ecommerce_serang.data.api.response package com.alya.ecommerce_serang.data.api.response.product
import com.alya.ecommerce_serang.data.api.dto.Store import com.alya.ecommerce_serang.data.api.dto.Store
import com.google.gson.annotations.SerializedName import com.google.gson.annotations.SerializedName

View File

@ -9,6 +9,7 @@ import com.alya.ecommerce_serang.data.api.dto.OrderRequestBuy
import com.alya.ecommerce_serang.data.api.dto.OtpRequest import com.alya.ecommerce_serang.data.api.dto.OtpRequest
import com.alya.ecommerce_serang.data.api.dto.RegisterRequest import com.alya.ecommerce_serang.data.api.dto.RegisterRequest
import com.alya.ecommerce_serang.data.api.dto.UpdateCart import com.alya.ecommerce_serang.data.api.dto.UpdateCart
import com.alya.ecommerce_serang.data.api.response.ViewStoreProductsResponse
import com.alya.ecommerce_serang.data.api.response.auth.LoginResponse import com.alya.ecommerce_serang.data.api.response.auth.LoginResponse
import com.alya.ecommerce_serang.data.api.response.auth.OtpResponse import com.alya.ecommerce_serang.data.api.response.auth.OtpResponse
import com.alya.ecommerce_serang.data.api.response.auth.RegisterResponse import com.alya.ecommerce_serang.data.api.response.auth.RegisterResponse
@ -28,7 +29,6 @@ import com.alya.ecommerce_serang.data.api.response.product.StoreResponse
import com.alya.ecommerce_serang.data.api.response.profile.AddressResponse import com.alya.ecommerce_serang.data.api.response.profile.AddressResponse
import com.alya.ecommerce_serang.data.api.response.profile.CreateAddressResponse import com.alya.ecommerce_serang.data.api.response.profile.CreateAddressResponse
import com.alya.ecommerce_serang.data.api.response.profile.ProfileResponse import com.alya.ecommerce_serang.data.api.response.profile.ProfileResponse
import com.alya.ecommerce_serang.data.api.response.ViewStoreProductsResponse
import retrofit2.Call import retrofit2.Call
import retrofit2.Response import retrofit2.Response
import retrofit2.http.Body import retrofit2.http.Body

View File

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

View File

@ -11,7 +11,7 @@ import androidx.recyclerview.widget.LinearLayoutManager
import com.alya.ecommerce_serang.data.api.dto.CheckoutData import com.alya.ecommerce_serang.data.api.dto.CheckoutData
import com.alya.ecommerce_serang.data.api.dto.OrderRequest 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.OrderRequestBuy
import com.alya.ecommerce_serang.data.api.response.product.PaymentItem import com.alya.ecommerce_serang.data.api.response.product.PaymentInfoItem
import com.alya.ecommerce_serang.data.api.retrofit.ApiConfig import com.alya.ecommerce_serang.data.api.retrofit.ApiConfig
import com.alya.ecommerce_serang.data.repository.OrderRepository import com.alya.ecommerce_serang.data.repository.OrderRepository
import com.alya.ecommerce_serang.databinding.ActivityCheckoutBinding import com.alya.ecommerce_serang.databinding.ActivityCheckoutBinding
@ -104,8 +104,10 @@ class CheckoutActivity : AppCompatActivity() {
// Observe payment details // Observe payment details
viewModel.paymentDetails.observe(this) { payment -> viewModel.paymentDetails.observe(this) { payment ->
// Update selected payment in adapter if (payment != null) {
payment?.id?.let { paymentAdapter?.setSelectedPaymentId(it) } // Update selected payment in adapter by name instead of ID
paymentAdapter?.setSelectedPaymentName(payment.name)
}
} }
// Observe loading state // Observe loading state
@ -145,10 +147,13 @@ class CheckoutActivity : AppCompatActivity() {
} }
} }
private fun setupPaymentMethodsRecyclerView(paymentMethods: List<PaymentItem>) { private fun setupPaymentMethodsRecyclerView(paymentMethods: List<PaymentInfoItem>) {
paymentAdapter = PaymentMethodAdapter(paymentMethods) { payment -> paymentAdapter = PaymentMethodAdapter(paymentMethods) { payment ->
// When a payment method is selected // When a payment method is selected
viewModel.setPaymentMethod(payment.id) // Since PaymentInfoItem doesn't have an id field, we'll use the name as identifier
// You might need to convert the name to an ID if your backend expects an integer
val paymentId = payment.name.toIntOrNull() ?: 0
viewModel.setPaymentMethod(paymentId)
} }
binding.rvPaymentMethods.apply { binding.rvPaymentMethods.apply {

View File

@ -10,7 +10,7 @@ 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.OrderRequestBuy
import com.alya.ecommerce_serang.data.api.response.cart.CartItemsItem import com.alya.ecommerce_serang.data.api.response.cart.CartItemsItem
import com.alya.ecommerce_serang.data.api.response.cart.DataItem import com.alya.ecommerce_serang.data.api.response.cart.DataItem
import com.alya.ecommerce_serang.data.api.response.product.PaymentItem import com.alya.ecommerce_serang.data.api.response.product.PaymentInfoItem
import com.alya.ecommerce_serang.data.api.response.profile.AddressesItem import com.alya.ecommerce_serang.data.api.response.profile.AddressesItem
import com.alya.ecommerce_serang.data.repository.OrderRepository import com.alya.ecommerce_serang.data.repository.OrderRepository
import com.alya.ecommerce_serang.data.repository.Result import com.alya.ecommerce_serang.data.repository.Result
@ -24,8 +24,8 @@ class CheckoutViewModel(private val repository: OrderRepository) : ViewModel() {
private val _addressDetails = MutableLiveData<AddressesItem?>() private val _addressDetails = MutableLiveData<AddressesItem?>()
val addressDetails: LiveData<AddressesItem?> = _addressDetails val addressDetails: LiveData<AddressesItem?> = _addressDetails
private val _paymentDetails = MutableLiveData<PaymentItem?>() private val _paymentDetails = MutableLiveData<PaymentInfoItem?>()
val paymentDetails: LiveData<PaymentItem?> = _paymentDetails val paymentDetails: LiveData<PaymentInfoItem?> = _paymentDetails
private val _isLoading = MutableLiveData<Boolean>() private val _isLoading = MutableLiveData<Boolean>()
val isLoading: LiveData<Boolean> = _isLoading val isLoading: LiveData<Boolean> = _isLoading
@ -145,12 +145,16 @@ class CheckoutViewModel(private val repository: OrderRepository) : ViewModel() {
} }
// Get payment methods from API // Get payment methods from API
fun getPaymentMethods(callback: (List<PaymentItem>) -> Unit) { fun getPaymentMethods(callback: (List<PaymentInfoItem>) -> Unit) {
viewModelScope.launch { viewModelScope.launch {
try { try {
val storeResponse = repository.getStore() val storeId = _checkoutData.value?.sellerId ?: return@launch
if (storeResponse != null && storeResponse.payment.isNotEmpty()) {
callback(storeResponse.payment) // Use fetchStoreDetail instead of getStore
val storeResult = repository.fetchStoreDetail(storeId)
if (storeResult is Result.Success && storeResult.data != null) {
callback(storeResult.data.paymentInfo)
} else { } else {
callback(emptyList()) callback(emptyList())
} }
@ -227,12 +231,16 @@ class CheckoutViewModel(private val repository: OrderRepository) : ViewModel() {
fun setPaymentMethod(paymentId: Int) { fun setPaymentMethod(paymentId: Int) {
viewModelScope.launch { viewModelScope.launch {
try { try {
val storeResponse = repository.getStore() val storeId = _checkoutData.value?.sellerId ?: return@launch
if (storeResponse != null) {
val payment = storeResponse.payment.find { it.id == paymentId } // Use fetchStoreDetail instead of getStore
val storeResult = repository.fetchStoreDetail(storeId)
if (storeResult is Result.Success && storeResult.data != null) {
// Find the selected payment in the payment info list
val payment = storeResult.data.paymentInfo.find { it.name == paymentId.toString() }
_paymentDetails.value = payment _paymentDetails.value = payment
// Update order request only if payment isn't null // Update order request if payment isn't null
if (payment != null) { if (payment != null) {
val currentData = _checkoutData.value ?: return@launch val currentData = _checkoutData.value ?: return@launch
if (currentData.isBuyNow) { if (currentData.isBuyNow) {

View File

@ -4,14 +4,14 @@ import android.view.LayoutInflater
import android.view.ViewGroup import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import com.alya.ecommerce_serang.R import com.alya.ecommerce_serang.R
import com.alya.ecommerce_serang.data.api.response.product.PaymentItem import com.alya.ecommerce_serang.data.api.response.product.PaymentInfoItem
import com.alya.ecommerce_serang.databinding.ItemPaymentMethodBinding import com.alya.ecommerce_serang.databinding.ItemPaymentMethodBinding
import com.bumptech.glide.Glide import com.bumptech.glide.Glide
import com.bumptech.glide.request.RequestOptions import com.bumptech.glide.request.RequestOptions
class PaymentMethodAdapter( class PaymentMethodAdapter(
private val paymentMethods: List<PaymentItem>, private val paymentMethods: List<PaymentInfoItem>,
private val onPaymentSelected: (PaymentItem) -> Unit private val onPaymentSelected: (PaymentInfoItem) -> Unit
) : RecyclerView.Adapter<PaymentMethodAdapter.PaymentMethodViewHolder>() { ) : RecyclerView.Adapter<PaymentMethodAdapter.PaymentMethodViewHolder>() {
// Track the selected position // Track the selected position
@ -36,7 +36,7 @@ class PaymentMethodAdapter(
with(holder.binding) { with(holder.binding) {
// Set payment method name // Set payment method name
tvPaymentMethodName.text = payment.bankName tvPaymentMethodName.text = payment.name
// Set radio button state // Set radio button state
rbPaymentMethod.isChecked = selectedPosition == position rbPaymentMethod.isChecked = selectedPosition == position
@ -45,8 +45,7 @@ class PaymentMethodAdapter(
if (payment.qrisImage.isNotEmpty()) { if (payment.qrisImage.isNotEmpty()) {
Glide.with(ivPaymentMethod.context) Glide.with(ivPaymentMethod.context)
.load(payment.qrisImage) .load(payment.qrisImage)
.apply( .apply(RequestOptions()
RequestOptions()
.placeholder(R.drawable.outline_store_24) .placeholder(R.drawable.outline_store_24)
.error(R.drawable.outline_store_24)) .error(R.drawable.outline_store_24))
.into(ivPaymentMethod) .into(ivPaymentMethod)
@ -81,9 +80,9 @@ class PaymentMethodAdapter(
} }
} }
// Select a payment method programmatically //selected by name
fun setSelectedPaymentId(paymentId: Int) { fun setSelectedPaymentName(paymentName: String) {
val position = paymentMethods.indexOfFirst { it.id == paymentId } val position = paymentMethods.indexOfFirst { it.name == paymentName }
if (position != -1 && position != selectedPosition) { if (position != -1 && position != selectedPosition) {
selectPayment(position) selectPayment(position)
} }

View File

@ -28,7 +28,6 @@ import com.alya.ecommerce_serang.ui.home.HorizontalProductAdapter
import com.alya.ecommerce_serang.ui.order.CheckoutActivity import com.alya.ecommerce_serang.ui.order.CheckoutActivity
import com.alya.ecommerce_serang.utils.BaseViewModelFactory import com.alya.ecommerce_serang.utils.BaseViewModelFactory
import com.alya.ecommerce_serang.utils.SessionManager import com.alya.ecommerce_serang.utils.SessionManager
import com.alya.ecommerce_serang.utils.viewmodel.ProductViewModel
import com.bumptech.glide.Glide import com.bumptech.glide.Glide
import com.google.android.material.bottomsheet.BottomSheetDialog import com.google.android.material.bottomsheet.BottomSheetDialog
import java.text.NumberFormat import java.text.NumberFormat
@ -43,11 +42,11 @@ class DetailProductActivity : AppCompatActivity() {
private var currentQuantity = 1 private var currentQuantity = 1
private val viewModel: ProductViewModel by viewModels { private val viewModel: ProductUserViewModel by viewModels {
BaseViewModelFactory { BaseViewModelFactory {
val apiService = ApiConfig.getApiService(sessionManager) val apiService = ApiConfig.getApiService(sessionManager)
val productRepository = ProductRepository(apiService) val productRepository = ProductRepository(apiService)
ProductViewModel(productRepository) ProductUserViewModel(productRepository)
} }
} }
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {

View File

@ -15,7 +15,7 @@ import com.alya.ecommerce_serang.data.repository.ProductRepository
import com.alya.ecommerce_serang.data.repository.Result import com.alya.ecommerce_serang.data.repository.Result
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
class ProductViewModel(private val repository: ProductRepository) : ViewModel() { class ProductUserViewModel(private val repository: ProductRepository) : ViewModel() {
private val _productDetail = MutableLiveData<Product?>() private val _productDetail = MutableLiveData<Product?>()
val productDetail: LiveData<Product?> get() = _productDetail val productDetail: LiveData<Product?> get() = _productDetail

View File

@ -13,18 +13,17 @@ import com.alya.ecommerce_serang.data.repository.ProductRepository
import com.alya.ecommerce_serang.databinding.ActivityReviewProductBinding import com.alya.ecommerce_serang.databinding.ActivityReviewProductBinding
import com.alya.ecommerce_serang.utils.BaseViewModelFactory import com.alya.ecommerce_serang.utils.BaseViewModelFactory
import com.alya.ecommerce_serang.utils.SessionManager import com.alya.ecommerce_serang.utils.SessionManager
import com.alya.ecommerce_serang.utils.viewmodel.ProductViewModel
class ReviewProductActivity : AppCompatActivity() { class ReviewProductActivity : AppCompatActivity() {
private lateinit var binding: ActivityReviewProductBinding private lateinit var binding: ActivityReviewProductBinding
private lateinit var apiService: ApiService private lateinit var apiService: ApiService
private var reviewsAdapter: ReviewsAdapter? = null private var reviewsAdapter: ReviewsAdapter? = null
private lateinit var sessionManager: SessionManager private lateinit var sessionManager: SessionManager
private val viewModel: ProductViewModel by viewModels { private val viewModel: ProductUserViewModel by viewModels {
BaseViewModelFactory { BaseViewModelFactory {
val apiService = ApiConfig.getApiService(sessionManager) val apiService = ApiConfig.getApiService(sessionManager)
val productRepository = ProductRepository(apiService) val productRepository = ProductRepository(apiService)
ProductViewModel(productRepository) ProductUserViewModel(productRepository)
} }
} }

View File

@ -7,9 +7,9 @@ import androidx.lifecycle.liveData
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import com.alya.ecommerce_serang.data.api.dto.CategoryItem import com.alya.ecommerce_serang.data.api.dto.CategoryItem
import com.alya.ecommerce_serang.data.api.dto.ProductsItem import com.alya.ecommerce_serang.data.api.dto.ProductsItem
import com.alya.ecommerce_serang.data.api.dto.Store import com.alya.ecommerce_serang.data.api.response.product.Product
import com.alya.ecommerce_serang.data.api.response.Product import com.alya.ecommerce_serang.data.api.response.product.ReviewsItem
import com.alya.ecommerce_serang.data.api.response.ReviewsItem import com.alya.ecommerce_serang.data.api.response.product.StoreProduct
import com.alya.ecommerce_serang.data.repository.ProductRepository import com.alya.ecommerce_serang.data.repository.ProductRepository
import com.alya.ecommerce_serang.data.repository.Result import com.alya.ecommerce_serang.data.repository.Result
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
@ -19,8 +19,8 @@ class ProductViewModel(private val repository: ProductRepository) : ViewModel()
private val _productDetail = MutableLiveData<Product?>() private val _productDetail = MutableLiveData<Product?>()
val productDetail: LiveData<Product?> get() = _productDetail val productDetail: LiveData<Product?> get() = _productDetail
private val _storeDetail = MutableLiveData<Store?>() private val _storeDetail = MutableLiveData<StoreProduct?>()
val storeDetail : LiveData<Store?> get() = _storeDetail val storeDetail : LiveData<StoreProduct?> get() = _storeDetail
private val _reviewProduct = MutableLiveData<List<ReviewsItem>>() private val _reviewProduct = MutableLiveData<List<ReviewsItem>>()
val reviewProduct: LiveData<List<ReviewsItem>> get() = _reviewProduct val reviewProduct: LiveData<List<ReviewsItem>> get() = _reviewProduct

View File

@ -0,0 +1,10 @@
<?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"
tools:context=".data.api.response.cart.CartActivity">
</androidx.constraintlayout.widget.ConstraintLayout>