diff --git a/app/src/main/java/com/alya/ecommerce_serang/app/App.kt b/app/src/main/java/com/alya/ecommerce_serang/app/App.kt index 55e0321..fa3dd4f 100644 --- a/app/src/main/java/com/alya/ecommerce_serang/app/App.kt +++ b/app/src/main/java/com/alya/ecommerce_serang/app/App.kt @@ -1,50 +1,17 @@ package com.alya.ecommerce_serang.app import android.app.Application -import android.content.Context -import android.util.Log -import com.google.firebase.FirebaseApp -import com.google.firebase.messaging.FirebaseMessaging import dagger.hilt.android.HiltAndroidApp @HiltAndroidApp class App : Application(){ - private val TAG = "AppSerang" +// private val TAG = "AppSerang" +// +//// var tokenTes: String? = null +// +// override fun onCreate() { +// +// } -// var tokenTes: String? = null - override fun onCreate() { - super.onCreate() - - // Initialize Firebase - FirebaseApp.initializeApp(this) - - // Request FCM token at app startup - retrieveFCMToken() - } - - private fun retrieveFCMToken() { - FirebaseMessaging.getInstance().token - .addOnCompleteListener { task -> - if (!task.isSuccessful) { - Log.e(TAG, "Failed to get FCM token", task.exception) - return@addOnCompleteListener - } - - val token = task.result -// tokenTes = token - Log.d(TAG, "FCM token retrieved: $token") - - // Save token locally - val sharedPreferences = getSharedPreferences("FCM_PREFS", Context.MODE_PRIVATE) - sharedPreferences.edit().putString("FCM_TOKEN", token).apply() - - // Send to your server - sendTokenToServer(token) - } - } - - private fun sendTokenToServer(token: String) { - Log.d(TAG, "Would send token to server: $token") - } } \ No newline at end of file diff --git a/app/src/main/java/com/alya/ecommerce_serang/data/api/dto/CancelOrderReq.kt b/app/src/main/java/com/alya/ecommerce_serang/data/api/dto/CancelOrderReq.kt new file mode 100644 index 0000000..1009818 --- /dev/null +++ b/app/src/main/java/com/alya/ecommerce_serang/data/api/dto/CancelOrderReq.kt @@ -0,0 +1,11 @@ +package com.alya.ecommerce_serang.data.api.dto + +import com.google.gson.annotations.SerializedName + +data class CancelOrderReq ( + @SerializedName("order_id") + val orderId: Int, + + @SerializedName("reason") + val reason: String +) \ No newline at end of file diff --git a/app/src/main/java/com/alya/ecommerce_serang/data/api/response/customer/order/CancelOrderResponse.kt b/app/src/main/java/com/alya/ecommerce_serang/data/api/response/customer/order/CancelOrderResponse.kt new file mode 100644 index 0000000..24adeed --- /dev/null +++ b/app/src/main/java/com/alya/ecommerce_serang/data/api/response/customer/order/CancelOrderResponse.kt @@ -0,0 +1,14 @@ +package com.alya.ecommerce_serang.data.api.response.customer.order + +data class CancelOrderResponse( + val data: DataCancel, + val message: String +) + +data class DataCancel( + val reason: String, + val createdAt: String, + val id: Int, + val orderId: Int +) + diff --git a/app/src/main/java/com/alya/ecommerce_serang/data/api/retrofit/ApiConfig.kt b/app/src/main/java/com/alya/ecommerce_serang/data/api/retrofit/ApiConfig.kt index 026c995..78e0394 100644 --- a/app/src/main/java/com/alya/ecommerce_serang/data/api/retrofit/ApiConfig.kt +++ b/app/src/main/java/com/alya/ecommerce_serang/data/api/retrofit/ApiConfig.kt @@ -22,6 +22,9 @@ class ApiConfig { val client = OkHttpClient.Builder() .addInterceptor(loggingInterceptor) .addInterceptor(authInterceptor) + .connectTimeout(60, TimeUnit.SECONDS) // Increase to 60 seconds + .readTimeout(60, TimeUnit.SECONDS) // Increase to 60 seconds + .writeTimeout(60, TimeUnit.SECONDS) .build() val retrofit = Retrofit.Builder() diff --git a/app/src/main/java/com/alya/ecommerce_serang/data/api/retrofit/ApiService.kt b/app/src/main/java/com/alya/ecommerce_serang/data/api/retrofit/ApiService.kt index 3c67690..51ec55e 100644 --- a/app/src/main/java/com/alya/ecommerce_serang/data/api/retrofit/ApiService.kt +++ b/app/src/main/java/com/alya/ecommerce_serang/data/api/retrofit/ApiService.kt @@ -3,6 +3,7 @@ package com.alya.ecommerce_serang.data.api.retrofit import com.alya.ecommerce_serang.data.api.dto.AddEvidenceRequest import com.alya.ecommerce_serang.data.api.dto.AddPaymentInfoResponse +import com.alya.ecommerce_serang.data.api.dto.CancelOrderReq import com.alya.ecommerce_serang.data.api.dto.CartItem import com.alya.ecommerce_serang.data.api.dto.CityResponse import com.alya.ecommerce_serang.data.api.dto.CompletedOrderRequest @@ -35,6 +36,7 @@ import com.alya.ecommerce_serang.data.api.response.customer.cart.AddCartResponse import com.alya.ecommerce_serang.data.api.response.customer.cart.DeleteCartResponse import com.alya.ecommerce_serang.data.api.response.customer.cart.ListCartResponse import com.alya.ecommerce_serang.data.api.response.customer.cart.UpdateCartResponse +import com.alya.ecommerce_serang.data.api.response.customer.order.CancelOrderResponse import com.alya.ecommerce_serang.data.api.response.customer.order.CourierCostResponse import com.alya.ecommerce_serang.data.api.response.customer.order.CreateOrderResponse import com.alya.ecommerce_serang.data.api.response.customer.order.CreateReviewResponse @@ -163,6 +165,11 @@ interface ApiService { @Body request: OrderRequest ): Response + @POST("order/cancel") + suspend fun cancelOrder( + @Body cancelReq: CancelOrderReq + ): Response + @GET("order/detail/{id}") suspend fun getDetailOrder( @Path("id") orderId: Int diff --git a/app/src/main/java/com/alya/ecommerce_serang/data/repository/OrderRepository.kt b/app/src/main/java/com/alya/ecommerce_serang/data/repository/OrderRepository.kt index 080c3cb..e162141 100644 --- a/app/src/main/java/com/alya/ecommerce_serang/data/repository/OrderRepository.kt +++ b/app/src/main/java/com/alya/ecommerce_serang/data/repository/OrderRepository.kt @@ -2,16 +2,17 @@ package com.alya.ecommerce_serang.data.repository import android.util.Log import com.alya.ecommerce_serang.data.api.dto.AddEvidenceMultipartRequest +import com.alya.ecommerce_serang.data.api.dto.CancelOrderReq import com.alya.ecommerce_serang.data.api.dto.CompletedOrderRequest 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.ReviewProductItem import com.alya.ecommerce_serang.data.api.dto.UpdateCart import com.alya.ecommerce_serang.data.api.dto.UserProfile import com.alya.ecommerce_serang.data.api.response.customer.cart.DataItemCart +import com.alya.ecommerce_serang.data.api.response.customer.order.CancelOrderResponse import com.alya.ecommerce_serang.data.api.response.customer.order.CourierCostResponse import com.alya.ecommerce_serang.data.api.response.customer.order.CreateOrderResponse import com.alya.ecommerce_serang.data.api.response.customer.order.CreateReviewResponse @@ -491,4 +492,23 @@ class OrderRepository(private val apiService: ApiService) { } + suspend fun cancelOrder(cancelReq: CancelOrderReq): Result{ + return try{ + val response= apiService.cancelOrder(cancelReq) + + if (response.isSuccessful){ + response.body()?.let { cancelOrderResponse -> + Result.Success(cancelOrderResponse) + } ?: run { + Result.Error(Exception("Failed to cancel order")) + } + } else { + val errorMsg = response.errorBody()?.string() ?: "Unknown Error" + Result.Error(Exception(errorMsg)) + } + }catch (e: Exception){ + Result.Error(e) + } + } + } \ No newline at end of file diff --git a/app/src/main/java/com/alya/ecommerce_serang/ui/MainActivity.kt b/app/src/main/java/com/alya/ecommerce_serang/ui/MainActivity.kt index 35a85a4..12d3b44 100644 --- a/app/src/main/java/com/alya/ecommerce_serang/ui/MainActivity.kt +++ b/app/src/main/java/com/alya/ecommerce_serang/ui/MainActivity.kt @@ -1,8 +1,10 @@ package com.alya.ecommerce_serang.ui +import android.content.Context import android.content.pm.PackageManager import android.os.Build import android.os.Bundle +import android.util.Log import android.widget.Toast import androidx.activity.enableEdgeToEdge import androidx.appcompat.app.AppCompatActivity @@ -20,11 +22,15 @@ import com.alya.ecommerce_serang.data.api.retrofit.ApiService import com.alya.ecommerce_serang.databinding.ActivityMainBinding import com.alya.ecommerce_serang.ui.notif.WebSocketManager import com.alya.ecommerce_serang.utils.SessionManager +import com.google.firebase.FirebaseApp +import com.google.firebase.messaging.FirebaseMessaging import dagger.hilt.android.AndroidEntryPoint import javax.inject.Inject @AndroidEntryPoint class MainActivity : AppCompatActivity() { + private val TAG = "MainActivity" + private lateinit var binding: ActivityMainBinding private lateinit var apiService: ApiService private lateinit var sessionManager: SessionManager @@ -65,6 +71,11 @@ class MainActivity : AppCompatActivity() { ) windowInsets } + // Initialize Firebase + FirebaseApp.initializeApp(this) + + // Request FCM token at app startup + retrieveFCMToken() requestNotificationPermissionIfNeeded() @@ -151,4 +162,31 @@ class MainActivity : AppCompatActivity() { } } } + + private fun retrieveFCMToken() { + FirebaseMessaging.getInstance().token + .addOnCompleteListener { task -> + if (!task.isSuccessful) { + Log.e(TAG, "Failed to get FCM token", task.exception) + return@addOnCompleteListener + } + + val token = task.result +// tokenTes = token + Log.d(TAG, "FCM token retrieved: $token") + + // Save token locally + val sharedPreferences = getSharedPreferences("FCM_PREFS", Context.MODE_PRIVATE) + sharedPreferences.edit().putString("FCM_TOKEN", token).apply() + + // Send to your server + sendTokenToServer(token) + } + } + + private fun sendTokenToServer(token: String) { + Log.d(TAG, "Would send token to server: $token") + } + + } \ No newline at end of file diff --git a/app/src/main/java/com/alya/ecommerce_serang/ui/auth/RegisterStoreActivity.kt b/app/src/main/java/com/alya/ecommerce_serang/ui/auth/RegisterStoreActivity.kt index 4cdfb77..c3c83bf 100644 --- a/app/src/main/java/com/alya/ecommerce_serang/ui/auth/RegisterStoreActivity.kt +++ b/app/src/main/java/com/alya/ecommerce_serang/ui/auth/RegisterStoreActivity.kt @@ -508,6 +508,14 @@ class RegisterStoreActivity : AppCompatActivity() { viewModel.subdistrict.value = s.toString() } }) + + binding.etBankName.addTextChangedListener(object: TextWatcher { + override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {} + override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {} + override fun afterTextChanged(s: Editable?) { + viewModel.subdistrict.value = s.toString() + } + }) } override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { diff --git a/app/src/main/java/com/alya/ecommerce_serang/ui/order/ShippingViewModel.kt b/app/src/main/java/com/alya/ecommerce_serang/ui/order/ShippingViewModel.kt index 1252f3d..9793977 100644 --- a/app/src/main/java/com/alya/ecommerce_serang/ui/order/ShippingViewModel.kt +++ b/app/src/main/java/com/alya/ecommerce_serang/ui/order/ShippingViewModel.kt @@ -1,5 +1,6 @@ package com.alya.ecommerce_serang.ui.order +import android.util.Log import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel @@ -9,6 +10,7 @@ import com.alya.ecommerce_serang.data.api.dto.CourierCostRequest import com.alya.ecommerce_serang.data.api.response.customer.order.CourierCostsItem import com.alya.ecommerce_serang.data.repository.OrderRepository import com.alya.ecommerce_serang.data.repository.Result +import kotlinx.coroutines.delay import kotlinx.coroutines.launch class ShippingViewModel( @@ -30,12 +32,71 @@ class ShippingViewModel( /** * Load shipping options based on address, product, and quantity */ +// fun loadShippingOptions(addressId: Int, productId: Int, quantity: Int) { +// _isLoading.value = true +// _errorMessage.value = "" +// +// val costProduct = CostProduct( +// productId = productId, +// quantity = quantity +// ) +// +// viewModelScope.launch { +// // Define the courier services to try +// val courierServices = listOf("pos", "jne", "tiki") +// +// // Create a mutable list to collect successful courier options +// val availableCourierOptions = mutableListOf() +// +// // Try each courier service +// for (courier in courierServices) { +// try { +// // Create a request for this specific courier +// val courierRequest = CourierCostRequest( +// addressId = addressId, +// itemCost = listOf(costProduct), +// courier = courier // Add the courier to the request +// ) +// +// // Make a separate API call for each courier +// val result = repository.getCountCourierCost(courierRequest) +// +// when (result) { +// is Result.Success -> { +// // Add this courier's options to our collection +// result.data.courierCosts?.let { costs -> +// availableCourierOptions.addAll(costs) +// } +// // Update UI with what we have so far +// _shippingOptions.value = availableCourierOptions +// } +// is Result.Error -> { +// // Log the error but continue with next courier +// Log.e("ShippingViewModel", "Error fetching cost for courier $courier: ${result.exception.message}") +// } +// is Result.Loading -> { +// // Handle loading state +// } +// } +// } catch (e: Exception) { +// // Log the exception but continue with next courier +// Log.e("ShippingViewModel", "Exception for courier $courier: ${e.message}") +// } +// } +// +// // Show error only if we couldn't get any shipping options +// if (availableCourierOptions.isEmpty()) { +// _errorMessage.value = "No shipping options available. Please try again later." +// } +// +// _isLoading.value = false +// } +// } + fun loadShippingOptions(addressId: Int, productId: Int, quantity: Int) { - // Reset previous state _isLoading.value = true _errorMessage.value = "" - // Prepare the request val costProduct = CostProduct( productId = productId, quantity = quantity @@ -43,34 +104,47 @@ class ShippingViewModel( val request = CourierCostRequest( addressId = addressId, - itemCost = listOf(costProduct) // Wrap in a list + itemCost = listOf(costProduct) ) viewModelScope.launch { - try { - // Fetch courier costs - val result = repository.getCountCourierCost(request) + var success = false + var attempt = 0 + val maxAttempts = 3 - when (result) { - is Result.Success -> { - // Update shipping options directly with courier costs - _shippingOptions.value = result.data.courierCosts - } - is Result.Error -> { - // Handle error case - _errorMessage.value = result.exception.message ?: "Unknown error occurred" - } - is Result.Loading -> { - // Typically handled by the loading state + while (!success && attempt < maxAttempts) { + attempt++ + + try { + val result = repository.getCountCourierCost(request) + + when (result) { + is Result.Success -> { + _shippingOptions.value = result.data.courierCosts + success = true + } + is com.alya.ecommerce_serang.data.repository.Result.Error -> { + Log.e("ShippingViewModel", "Attempt $attempt failed: ${result.exception.message}") + // Wait before retrying + delay(120000) + } + is com.alya.ecommerce_serang.data.repository.Result.Loading -> { + // Handle loading state + } } + } catch (e: Exception) { + Log.e("ShippingViewModel", "Attempt $attempt exception: ${e.message}") + // Wait before retrying + delay(1000) } - } catch (e: Exception) { - // Catch any unexpected exceptions - _errorMessage.value = e.localizedMessage ?: "An unexpected error occurred" - } finally { - // Always set loading to false - _isLoading.value = false } + + // After all attempts, check if we have any shipping options + if (!success || _shippingOptions.value.isNullOrEmpty()) { + _errorMessage.value = "No shipping options available. Please try again later." + } + + _isLoading.value = false } } } \ No newline at end of file diff --git a/app/src/main/java/com/alya/ecommerce_serang/ui/order/address/AddAddressActivity.kt b/app/src/main/java/com/alya/ecommerce_serang/ui/order/address/AddAddressActivity.kt index c955672..4de34df 100644 --- a/app/src/main/java/com/alya/ecommerce_serang/ui/order/address/AddAddressActivity.kt +++ b/app/src/main/java/com/alya/ecommerce_serang/ui/order/address/AddAddressActivity.kt @@ -398,7 +398,7 @@ class AddAddressActivity : AppCompatActivity() { isRequestingLocation = false Toast.makeText(this, "Timeout lokasi, menggunakan lokasi default", Toast.LENGTH_SHORT).show() } - }, 15000) // 15 seconds timeout + }, 60000) // 15 seconds timeout // Try getting last known location first try { diff --git a/app/src/main/java/com/alya/ecommerce_serang/ui/order/history/HistoryViewModel.kt b/app/src/main/java/com/alya/ecommerce_serang/ui/order/history/HistoryViewModel.kt index 4f02163..9c36c28 100644 --- a/app/src/main/java/com/alya/ecommerce_serang/ui/order/history/HistoryViewModel.kt +++ b/app/src/main/java/com/alya/ecommerce_serang/ui/order/history/HistoryViewModel.kt @@ -5,8 +5,10 @@ import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope +import com.alya.ecommerce_serang.data.api.dto.CancelOrderReq import com.alya.ecommerce_serang.data.api.dto.CompletedOrderRequest import com.alya.ecommerce_serang.data.api.dto.OrdersItem +import com.alya.ecommerce_serang.data.api.response.customer.order.CancelOrderResponse import com.alya.ecommerce_serang.data.api.response.customer.order.OrderListItemsItem import com.alya.ecommerce_serang.data.api.response.customer.order.Orders import com.alya.ecommerce_serang.data.api.response.order.CompletedOrderResponse @@ -31,6 +33,11 @@ class HistoryViewModel(private val repository: OrderRepository) : ViewModel() { private val _orderDetails = MutableLiveData() val orderDetails: LiveData get() = _orderDetails + private val _cancelOrderStatus = MutableLiveData>() + val cancelOrderStatus: LiveData> = _cancelOrderStatus + private val _isCancellingOrder = MutableLiveData() + val isCancellingOrder: LiveData = _isCancellingOrder + // LiveData untuk OrderItems private val _orderItems = MutableLiveData>() val orderItems: LiveData> get() = _orderItems @@ -131,4 +138,26 @@ class HistoryViewModel(private val repository: OrderRepository) : ViewModel() { } } } + + fun cancelOrder(cancelReq: CancelOrderReq) { + viewModelScope.launch { + try { + _cancelOrderStatus.value = Result.Loading + val result = repository.cancelOrder(cancelReq) + _cancelOrderStatus.value = result + } catch (e: Exception) { + Log.e("HistoryViewModel", "Error cancelling order: ${e.message}") + _cancelOrderStatus.value = Result.Error(e) + } + } + } + + fun refreshOrders(status: String = "all") { + Log.d(TAG, "Refreshing orders with status: $status") + // Clear current orders before fetching new ones + _orders.value = ViewState.Loading + + // Re-fetch the orders with the current status + getOrderList(status) + } } \ No newline at end of file diff --git a/app/src/main/java/com/alya/ecommerce_serang/ui/order/history/OrderHistoryAdapter.kt b/app/src/main/java/com/alya/ecommerce_serang/ui/order/history/OrderHistoryAdapter.kt index c420ae8..9857af3 100644 --- a/app/src/main/java/com/alya/ecommerce_serang/ui/order/history/OrderHistoryAdapter.kt +++ b/app/src/main/java/com/alya/ecommerce_serang/ui/order/history/OrderHistoryAdapter.kt @@ -2,6 +2,7 @@ package com.alya.ecommerce_serang.ui.order.history import android.app.Activity import android.app.Dialog +import android.content.ContextWrapper import android.content.Intent import android.graphics.Color import android.net.Uri @@ -17,6 +18,7 @@ import android.widget.ImageView import android.widget.ProgressBar import android.widget.TextView import android.widget.Toast +import androidx.fragment.app.FragmentActivity import androidx.lifecycle.findViewTreeLifecycleOwner import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView @@ -24,6 +26,7 @@ import com.alya.ecommerce_serang.R import com.alya.ecommerce_serang.data.api.dto.OrdersItem import com.alya.ecommerce_serang.data.api.dto.ReviewUIItem import com.alya.ecommerce_serang.ui.order.detail.PaymentActivity +import com.alya.ecommerce_serang.ui.order.history.cancelorder.CancelOrderBottomSheet import com.alya.ecommerce_serang.ui.order.review.CreateReviewActivity import com.alya.ecommerce_serang.ui.product.ReviewProductActivity import com.google.android.material.button.MaterialButton @@ -150,7 +153,7 @@ class OrderHistoryAdapter( visibility = View.VISIBLE text = itemView.context.getString(R.string.canceled_order_btn) setOnClickListener { - showCancelOrderDialog(order.orderId.toString()) + showCancelOrderBottomSheet(order.orderId) } } deadlineDate.apply { @@ -171,7 +174,7 @@ class OrderHistoryAdapter( visibility = View.VISIBLE text = itemView.context.getString(R.string.canceled_order_btn) setOnClickListener { - showCancelOrderDialog(order.orderId.toString()) + showCancelOrderBottomSheet(order.orderId) } } @@ -226,7 +229,6 @@ class OrderHistoryAdapter( text = itemView.context.getString(R.string.claim_complaint) setOnClickListener { showCancelOrderDialog(order.orderId.toString()) - // Handle click event } } btnRight.apply { @@ -492,6 +494,48 @@ class OrderHistoryAdapter( dialog.show() } + private fun showCancelOrderBottomSheet(orderId : Int) { + val context = itemView.context + + // We need a FragmentManager to show the bottom sheet + // Try to get it from the context + val fragmentActivity = when (context) { + is FragmentActivity -> context + is ContextWrapper -> { + val baseContext = context.baseContext + if (baseContext is FragmentActivity) { + baseContext + } else { + // Log error and show a Toast instead if we can't get a FragmentManager + Log.e("OrderHistoryAdapter", "Cannot show bottom sheet: Context is not a FragmentActivity") + Toast.makeText(context, "Cannot show cancel order dialog", Toast.LENGTH_SHORT).show() + return + } + } + else -> { + // Log error and show a Toast instead if we can't get a FragmentManager + Log.e("OrderHistoryAdapter", "Cannot show bottom sheet: Context is not a FragmentActivity") + Toast.makeText(context, "Cannot show cancel order dialog", Toast.LENGTH_SHORT).show() + return + } + } + + // Create and show the bottom sheet using the obtained FragmentManager + val bottomSheet = CancelOrderBottomSheet( + orderId = orderId, + onOrderCancelled = { + // Handle the successful cancellation + // Refresh the data + viewModel.refreshOrders() // Assuming there's a method to refresh orders + + // Show a success message + Toast.makeText(context, "Order cancelled successfully", Toast.LENGTH_SHORT).show() + } + ) + + bottomSheet.show(fragmentActivity.supportFragmentManager, CancelOrderBottomSheet.TAG) + } + private fun addReviewProduct(order: OrdersItem) { // Use ViewModel to fetch order details viewModel.getOrderDetails(order.orderId) diff --git a/app/src/main/java/com/alya/ecommerce_serang/ui/order/history/cancelorder/CancelOrderBottomSheet.kt b/app/src/main/java/com/alya/ecommerce_serang/ui/order/history/cancelorder/CancelOrderBottomSheet.kt new file mode 100644 index 0000000..99f25de --- /dev/null +++ b/app/src/main/java/com/alya/ecommerce_serang/ui/order/history/cancelorder/CancelOrderBottomSheet.kt @@ -0,0 +1,173 @@ +package com.alya.ecommerce_serang.ui.order.history.cancelorder + +import android.os.Bundle +import android.util.Log +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.AdapterView +import android.widget.Button +import android.widget.Spinner +import android.widget.TextView +import android.widget.Toast +import androidx.fragment.app.viewModels +import com.alya.ecommerce_serang.R +import com.alya.ecommerce_serang.data.api.dto.CancelOrderReq +import com.alya.ecommerce_serang.data.api.retrofit.ApiConfig +import com.alya.ecommerce_serang.data.repository.OrderRepository +import com.alya.ecommerce_serang.data.repository.Result +import com.alya.ecommerce_serang.ui.order.history.HistoryViewModel +import com.alya.ecommerce_serang.utils.BaseViewModelFactory +import com.alya.ecommerce_serang.utils.SessionManager +import com.google.android.material.bottomsheet.BottomSheetDialogFragment + +class CancelOrderBottomSheet( + private val orderId: Int, + private val onOrderCancelled: () -> Unit +) : BottomSheetDialogFragment() { + private lateinit var sessionManager: SessionManager + + private val viewModel: HistoryViewModel by viewModels { + BaseViewModelFactory { + val apiService = ApiConfig.getApiService(sessionManager) + val orderRepository = OrderRepository(apiService) + HistoryViewModel(orderRepository) + } + } + private var selectedReason: CancelOrderReq? = null + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + return inflater.inflate(R.layout.layout_cancel_order_bottom, container, false) + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + + sessionManager = SessionManager(requireContext()) + + val tvTitle = view.findViewById(R.id.tv_title) + val spinnerReason = view.findViewById(R.id.spinner_reason) + val btnCancel = view.findViewById