mirror of
https://github.com/shaulascr/ecommerce_serang.git
synced 2025-12-15 15:41:02 +00:00
Merge remote-tracking branch 'origin/master'
This commit is contained in:
@ -173,7 +173,8 @@
|
||||
<activity
|
||||
android:name=".ui.auth.RegisterActivity"
|
||||
android:exported="true"
|
||||
android:windowSoftInputMode="adjustResize">
|
||||
android:windowSoftInputMode="adjustResize"
|
||||
android:theme="@style/Theme.App.SplashScreen">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
||||
|
||||
@ -43,27 +43,10 @@ class LoginActivity : AppCompatActivity() {
|
||||
WindowCompat.setDecorFitsSystemWindows(window, false)
|
||||
enableEdgeToEdge()
|
||||
|
||||
// ViewCompat.setOnApplyWindowInsetsListener(binding.root) { view, windowInsets ->
|
||||
// val systemBars = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars())
|
||||
// view.setPadding(
|
||||
// systemBars.left,
|
||||
// systemBars.top,
|
||||
// systemBars.right,
|
||||
// systemBars.bottom
|
||||
// )
|
||||
// windowInsets
|
||||
// }
|
||||
|
||||
// onBackPressedDispatcher.addCallback(this) {
|
||||
// // Handle the back button event
|
||||
// }
|
||||
|
||||
setupListeners()
|
||||
observeLoginState()
|
||||
|
||||
FirebaseApp.initializeApp(this)
|
||||
|
||||
// Request FCM token at app startup
|
||||
}
|
||||
|
||||
private fun setupListeners() {
|
||||
|
||||
@ -6,6 +6,7 @@ import android.util.Log
|
||||
import androidx.activity.enableEdgeToEdge
|
||||
import androidx.activity.viewModels
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
|
||||
import androidx.core.view.ViewCompat
|
||||
import androidx.core.view.WindowCompat
|
||||
import androidx.core.view.WindowInsetsCompat
|
||||
@ -39,6 +40,8 @@ class RegisterActivity : AppCompatActivity() {
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
Thread.sleep(3000)
|
||||
installSplashScreen()
|
||||
binding = ActivityRegisterBinding.inflate(layoutInflater)
|
||||
setContentView(binding.root)
|
||||
sessionManager = SessionManager(this)
|
||||
|
||||
@ -381,36 +381,4 @@ class RegisterStep2Fragment : Fragment() {
|
||||
Log.d(TAG, "onDetach - final cleanup")
|
||||
stopTimer()
|
||||
}
|
||||
}
|
||||
|
||||
// override fun onDestroyView() {
|
||||
// super.onDestroyView()
|
||||
// countDownTimer?.cancel()
|
||||
// _binding = null
|
||||
// }
|
||||
|
||||
// private fun startResendCooldown() {
|
||||
// Log.d(TAG, "startResendCooldown called")
|
||||
// timeRemaining = 30
|
||||
// binding.tvResendOtp.isEnabled = false
|
||||
// binding.tvResendOtp.setTextColor(ContextCompat.getColor(requireContext(), R.color.soft_gray))
|
||||
//
|
||||
// countDownTimer?.cancel()
|
||||
// countDownTimer = object : CountDownTimer(30000, 1000) {
|
||||
// override fun onTick(millisUntilFinished: Long) {
|
||||
// timeRemaining = (millisUntilFinished / 1000).toInt()
|
||||
// binding.tvTimer.text = "Kirim ulang OTP dalam waktu 00:${String.format("%02d", timeRemaining)}"
|
||||
// if (timeRemaining % 5 == 0) {
|
||||
// Log.d(TAG, "Cooldown remaining: $timeRemaining seconds")
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// override fun onFinish() {
|
||||
// Log.d(TAG, "Cooldown finished, enabling resend button")
|
||||
// binding.tvTimer.text = "Dapat mengirim ulang kode OTP"
|
||||
// binding.tvResendOtp.isEnabled = true
|
||||
// binding.tvResendOtp.setTextColor(ContextCompat.getColor(requireContext(), R.color.blue1))
|
||||
// timeRemaining = 0
|
||||
// }
|
||||
// }.start()
|
||||
// }
|
||||
}
|
||||
@ -96,19 +96,11 @@ class RegisterStep3Fragment : Fragment() {
|
||||
Log.d(TAG, "Auto-filled name: ${it.name}, phone: ${it.phone}")
|
||||
}
|
||||
|
||||
// Set up province and city dropdowns
|
||||
setupAutoComplete()
|
||||
|
||||
setupEdgeToEdge()
|
||||
|
||||
// Set up button listeners
|
||||
binding.btnPrevious.setOnClickListener {
|
||||
// Go back to the previous step
|
||||
// parentFragmentManager.popBackStack()
|
||||
// (activity as? RegisterActivity)?.navigateToStep(2, null)
|
||||
// (activity as? RegisterActivity)?.goBackToPreviousStep()
|
||||
|
||||
// Option 2: Direct navigation to step 1
|
||||
val step2Fragment = RegisterStep2Fragment()
|
||||
parentFragmentManager.beginTransaction()
|
||||
.replace(R.id.fragment_container, step2Fragment)
|
||||
@ -117,14 +109,8 @@ class RegisterStep3Fragment : Fragment() {
|
||||
|
||||
binding.btnRegister.setOnClickListener {
|
||||
submitAddress()
|
||||
sessionManager.clearAll()
|
||||
}
|
||||
|
||||
// If user skips address entry
|
||||
// binding.btnSkip.setOnClickListener {
|
||||
// showRegistrationSuccess()
|
||||
// }
|
||||
|
||||
// Observe address submission state
|
||||
observeAddressSubmissionState()
|
||||
|
||||
@ -513,6 +499,7 @@ class RegisterStep3Fragment : Fragment() {
|
||||
private fun showRegistrationSuccess() {
|
||||
// Now we can show the success message for the overall registration process
|
||||
Toast.makeText(requireContext(), "Berhasil mendaftarkan akun", Toast.LENGTH_LONG).show()
|
||||
sessionManager.clearAll()
|
||||
|
||||
// Navigate to login screen
|
||||
startActivity(Intent(requireContext(), LoginActivity::class.java))
|
||||
|
||||
@ -69,12 +69,10 @@ class HomeFragment : Fragment() {
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
|
||||
initUi()
|
||||
setupRecyclerView()
|
||||
observeData()
|
||||
setupSearchView()
|
||||
|
||||
}
|
||||
|
||||
private fun setupRecyclerView() {
|
||||
@ -145,15 +143,14 @@ class HomeFragment : Fragment() {
|
||||
binding.loadingAll.root.visibility = View.VISIBLE
|
||||
binding.error.root.isVisible = false
|
||||
binding.home.isVisible = false
|
||||
delay(5000)
|
||||
}
|
||||
is HomeUiState.Success -> {
|
||||
val products = state.products
|
||||
viewModel.loadStoresForProducts(products)
|
||||
delay(2000)
|
||||
binding.loadingAll.root.visibility = View.GONE
|
||||
binding.error.root.isVisible = false
|
||||
binding.home.isVisible = true
|
||||
val products = state.products
|
||||
viewModel.loadStoresForProducts(products) // << add this here
|
||||
|
||||
productAdapter?.updateLimitedProducts(products)
|
||||
}
|
||||
is HomeUiState.Error -> {
|
||||
@ -171,7 +168,6 @@ class HomeFragment : Fragment() {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
viewLifecycleOwner.lifecycleScope.launch {
|
||||
|
||||
@ -145,6 +145,8 @@ class CheckoutViewModel(private val repository: OrderRepository) : ViewModel() {
|
||||
isReseller = isWholesaleMap.any { it.value }
|
||||
)
|
||||
|
||||
Log.d(TAG, "Cek is reseller: ${orderRequest.isReseller}")
|
||||
|
||||
_checkoutData.value = CheckoutData(
|
||||
orderRequest = orderRequest,
|
||||
productName = matchingItems.first().productName,
|
||||
@ -378,6 +380,7 @@ class CheckoutViewModel(private val repository: OrderRepository) : ViewModel() {
|
||||
} else {
|
||||
// For Cart checkout, use the standard order endpoint
|
||||
val cartRequest = data.orderRequest as OrderRequest
|
||||
Log.d(TAG, "data: ${cartRequest.cartItemId}")
|
||||
repository.createOrder(cartRequest)
|
||||
}
|
||||
|
||||
|
||||
@ -4,6 +4,7 @@ import android.content.Context
|
||||
import android.util.Log
|
||||
import android.widget.ArrayAdapter
|
||||
import android.widget.Spinner
|
||||
import com.alya.ecommerce_serang.R
|
||||
import com.alya.ecommerce_serang.data.api.response.customer.order.CitiesItem
|
||||
import com.alya.ecommerce_serang.data.api.response.customer.order.ProvincesItem
|
||||
import com.alya.ecommerce_serang.data.api.response.customer.order.SubdistrictsItem
|
||||
@ -134,23 +135,8 @@ class BankAdapter(
|
||||
}
|
||||
|
||||
private fun loadHardcodedData() {
|
||||
val defaultBanks = listOf(
|
||||
BankItem("Bank Mandiri", "008", "PT Bank Mandiri (Persero) Tbk"),
|
||||
BankItem("Bank BRI", "002", "PT Bank Rakyat Indonesia (Persero) Tbk"),
|
||||
BankItem("Bank BCA", "014", "PT Bank Central Asia Tbk"),
|
||||
BankItem("Bank BNI", "009", "PT Bank Negara Indonesia (Persero) Tbk"),
|
||||
BankItem("Bank BTN", "200", "PT Bank Tabungan Negara (Persero) Tbk"),
|
||||
BankItem("Bank CIMB Niaga", "022", "PT Bank CIMB Niaga Tbk"),
|
||||
BankItem("Bank Danamon", "011", "PT Bank Danamon Indonesia Tbk"),
|
||||
BankItem("Bank Permata", "013", "PT Bank Permata Tbk"),
|
||||
BankItem("Bank OCBC NISP", "028", "PT Bank OCBC NISP Tbk"),
|
||||
BankItem("Bank Maybank", "016", "PT Bank Maybank Indonesia Tbk"),
|
||||
BankItem("Bank Panin", "019", "PT Bank Panin Dubai Syariah Tbk"),
|
||||
BankItem("Bank UOB", "023", "PT Bank UOB Indonesia"),
|
||||
BankItem("Bank Mega", "426", "PT Bank Mega Tbk"),
|
||||
BankItem("Bank Bukopin", "441", "PT Bank Bukopin Tbk"),
|
||||
BankItem("Bank BJB", "110", "PT Bank Pembangunan Daerah Jawa Barat dan Banten Tbk")
|
||||
)
|
||||
val bankNames = context.resources.getStringArray(R.array.bank_names)
|
||||
val defaultBanks = bankNames.map { BankItem(bankName = it) }
|
||||
updateData(defaultBanks)
|
||||
}
|
||||
|
||||
|
||||
@ -27,7 +27,6 @@ class HistoryActivity : AppCompatActivity() {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
binding = ActivityHistoryBinding.inflate(layoutInflater)
|
||||
|
||||
@ -37,9 +37,6 @@ class HistoryViewModel(private val repository: OrderRepository) : ViewModel() {
|
||||
private const val TAG = "HistoryViewModel"
|
||||
}
|
||||
|
||||
// private val _orders = MutableLiveData<ViewState<List<OrdersItem>>>()
|
||||
// val orders: LiveData<ViewState<List<OrdersItem>>> = _orders
|
||||
|
||||
private val _orderCompletionStatus = MutableLiveData<Result<CompletedOrderResponse>>()
|
||||
val orderCompletionStatus: LiveData<Result<CompletedOrderResponse>> = _orderCompletionStatus
|
||||
|
||||
@ -113,83 +110,6 @@ class HistoryViewModel(private val repository: OrderRepository) : ViewModel() {
|
||||
ViewState.Loading // ② initial value, still fine
|
||||
)
|
||||
|
||||
|
||||
// fun getOrderList(status: String) {
|
||||
// _orders.value = ViewState.Loading
|
||||
// viewModelScope.launch {
|
||||
// try {
|
||||
// if (status == "all") {
|
||||
// // Get all orders by combining all statuses
|
||||
// getAllOrdersCombined()
|
||||
// } else {
|
||||
// // Get orders for specific status
|
||||
// when (val result = repository.getOrderList(status)) {
|
||||
// is Result.Success -> {
|
||||
// _orders.value = ViewState.Success(result.data.orders)
|
||||
// Log.d(TAG, "Orders loaded successfully: ${result.data.orders.size} items")
|
||||
// }
|
||||
// is Result.Error -> {
|
||||
// _orders.value = ViewState.Error(result.exception.message ?: "Unknown error occurred")
|
||||
// Log.e(TAG, "Error loading orders", result.exception)
|
||||
// }
|
||||
// is Result.Loading -> {
|
||||
// // Keep loading state
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// } catch (e: Exception) {
|
||||
// _orders.value = ViewState.Error("An unexpected error occurred: ${e.message}")
|
||||
// Log.e(TAG, "Exception in getOrderList", e)
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// private suspend fun getAllOrdersCombined() {
|
||||
// try {
|
||||
// val allStatuses = listOf("unpaid", "paid", "processed", "shipped", "completed", "canceled")
|
||||
// val allOrders = mutableListOf<OrdersItem>()
|
||||
//
|
||||
// // Use coroutineScope to allow launching async blocks
|
||||
// coroutineScope {
|
||||
// val deferreds = allStatuses.map { status ->
|
||||
// async {
|
||||
// when (val result = repository.getOrderList(status)) {
|
||||
// is Result.Success -> {
|
||||
// // Tag each order with the status it was fetched from
|
||||
// result.data.orders.onEach { it.displayStatus = status }
|
||||
// }
|
||||
// is Result.Error -> {
|
||||
// Log.e(TAG, "Error loading orders for status $status", result.exception)
|
||||
// emptyList<OrdersItem>()
|
||||
// }
|
||||
// is Result.Loading -> emptyList<OrdersItem>()
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// // Await all results and combine
|
||||
// deferreds.awaitAll().forEach { orders ->
|
||||
// allOrders.addAll(orders)
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// // Sort orders
|
||||
// val sortedOrders = allOrders.sortedByDescending { order ->
|
||||
// try {
|
||||
// SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.getDefault()).parse(order.createdAt)
|
||||
// } catch (e: Exception) {
|
||||
// null
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// _orders.value = ViewState.Success(sortedOrders)
|
||||
// Log.d(TAG, "All orders loaded successfully: ${sortedOrders.size} items")
|
||||
//
|
||||
// } catch (e: Exception) {
|
||||
// _orders.value = ViewState.Error("An unexpected error occurred: ${e.message}")
|
||||
// Log.e(TAG, "Exception in getAllOrdersCombined", e)
|
||||
// }
|
||||
// }
|
||||
private suspend fun getAllOrdersCombined(): ViewState<List<OrdersItem>> = try {
|
||||
val statuses = listOf("unpaid", "paid", "processed", "shipped", "completed", "canceled")
|
||||
|
||||
@ -292,11 +212,6 @@ class HistoryViewModel(private val repository: OrderRepository) : ViewModel() {
|
||||
}
|
||||
}
|
||||
|
||||
// fun refreshOrders(status: String = "all") {
|
||||
// Log.d(TAG, "Refreshing orders with status: $status")
|
||||
// // Don't set Loading here if you want to show current data while refreshing
|
||||
// getOrderList(status)
|
||||
// }
|
||||
|
||||
fun updateStatus(status: String, forceRefresh: Boolean = false) {
|
||||
Log.d(TAG, "↪️ updateStatus(status = $status, forceRefresh = $forceRefresh)")
|
||||
|
||||
@ -200,10 +200,6 @@ class OrderHistoryAdapter(
|
||||
// viewModel.refreshOrders()
|
||||
}
|
||||
}
|
||||
// deadlineDate.apply {
|
||||
// visibility = View.VISIBLE
|
||||
// text = formatDatePay(order.updatedAt)
|
||||
// }
|
||||
}
|
||||
"processed" -> {
|
||||
// Untuk status processed, tampilkan "Hubungi Penjual"
|
||||
@ -215,15 +211,6 @@ class OrderHistoryAdapter(
|
||||
visibility = View.VISIBLE
|
||||
text = itemView.context.getString(R.string.dl_processed)
|
||||
}
|
||||
// gabisa complaint
|
||||
// btnLeft.apply {
|
||||
// visibility = View.VISIBLE
|
||||
// text = itemView.context.getString(R.string.canceled_order_btn)
|
||||
// setOnClickListener {
|
||||
// showCancelOrderDialog(order.orderId.toString())
|
||||
// viewModel.refreshOrders()
|
||||
// }
|
||||
// }
|
||||
}
|
||||
"shipped" -> {
|
||||
// Untuk status shipped, tampilkan "Lacak Pengiriman" dan "Terima Barang"
|
||||
@ -517,14 +504,14 @@ class OrderHistoryAdapter(
|
||||
} 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, "Terjadi kendala", Toast.LENGTH_SHORT).show()
|
||||
Toast.makeText(context, "Terjadi kendala di batalkan pesanan", 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, "Terjadi kendala", Toast.LENGTH_SHORT).show()
|
||||
Toast.makeText(context, "Terjadi kendala di batalkan pesanan", Toast.LENGTH_SHORT).show()
|
||||
return
|
||||
}
|
||||
}
|
||||
@ -549,7 +536,8 @@ class OrderHistoryAdapter(
|
||||
|
||||
viewModel.error.observe(itemView.findViewTreeLifecycleOwner()!!) { errorMsg ->
|
||||
if (!errorMsg.isNullOrEmpty()) {
|
||||
Toast.makeText(itemView.context, errorMsg, Toast.LENGTH_SHORT).show()
|
||||
Log.e("OrderHistoryAdapter", "Error $errorMsg")
|
||||
Toast.makeText(itemView.context, "Terdapat kendala di tambah ulasan", Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
}
|
||||
|
||||
@ -585,7 +573,7 @@ class OrderHistoryAdapter(
|
||||
} else {
|
||||
Toast.makeText(
|
||||
itemView.context,
|
||||
"No items to review",
|
||||
"Tidak ada produk untuk direview",
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
}
|
||||
|
||||
@ -44,8 +44,6 @@ class OrderHistoryFragment : Fragment() {
|
||||
sessionManager = SessionManager(requireContext())
|
||||
|
||||
setupViewPager()
|
||||
|
||||
|
||||
}
|
||||
|
||||
private fun setupViewPager() {
|
||||
@ -67,17 +65,25 @@ class OrderHistoryFragment : Fragment() {
|
||||
}
|
||||
}.attach()
|
||||
|
||||
statusPage()
|
||||
}
|
||||
|
||||
private fun statusPage(){
|
||||
binding.viewPager.registerOnPageChangeCallback(
|
||||
object : ViewPager2.OnPageChangeCallback() {
|
||||
override fun onPageSelected(position: Int) {
|
||||
val status = viewPagerAdapter.orderStatuses[position]
|
||||
/* setStatus() is the API we added earlier; TRUE → always re‑query */
|
||||
historyVm.updateStatus(status, forceRefresh = true)
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
statusPage()
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
_binding = null
|
||||
|
||||
@ -3,6 +3,7 @@ package com.alya.ecommerce_serang.ui.order.history
|
||||
import android.app.Activity
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.util.Log
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
@ -84,8 +85,6 @@ class OrderListFragment : Fragment(), OrderHistoryAdapter.OrderActionCallbacks {
|
||||
setupRecyclerView()
|
||||
observeOrderList()
|
||||
observeViewModel()
|
||||
// observeOrderCompletionStatus()
|
||||
// loadOrders()
|
||||
}
|
||||
|
||||
private fun setupRecyclerView() {
|
||||
@ -106,31 +105,6 @@ class OrderListFragment : Fragment(), OrderHistoryAdapter.OrderActionCallbacks {
|
||||
}
|
||||
|
||||
private fun observeOrderList() {
|
||||
// Now we only need to observe one LiveData for all cases
|
||||
// viewModel.orders.observe(viewLifecycleOwner) { result ->
|
||||
// when (result) {
|
||||
// is ViewState.Success -> {
|
||||
// binding.progressBar.visibility = View.GONE
|
||||
//
|
||||
// if (result.data.isNullOrEmpty()) {
|
||||
// binding.tvEmptyState.visibility = View.VISIBLE
|
||||
// binding.rvOrders.visibility = View.GONE
|
||||
// } else {
|
||||
// binding.tvEmptyState.visibility = View.GONE
|
||||
// binding.rvOrders.visibility = View.VISIBLE
|
||||
// orderAdapter.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 -> {
|
||||
// binding.progressBar.visibility = View.VISIBLE
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
viewLifecycleOwner.lifecycleScope.launchWhenStarted {
|
||||
viewModel.orders.collect { state ->
|
||||
when (state) {
|
||||
@ -141,7 +115,7 @@ class OrderListFragment : Fragment(), OrderHistoryAdapter.OrderActionCallbacks {
|
||||
binding.progressBar.isVisible = false
|
||||
binding.tvEmptyState.isVisible = true
|
||||
binding.rvOrders.isVisible = false
|
||||
Toast.makeText(requireContext(), state.message, Toast.LENGTH_SHORT).show()
|
||||
Log.e("OrderListFragment", "Error in order list: ${state.message}")
|
||||
}
|
||||
is ViewState.Success -> {
|
||||
binding.progressBar.isVisible = false
|
||||
@ -157,47 +131,19 @@ class OrderListFragment : Fragment(), OrderHistoryAdapter.OrderActionCallbacks {
|
||||
}
|
||||
|
||||
private fun observeViewModel() {
|
||||
// Observe order completion
|
||||
// viewModel.orderCompletionStatus.observe(viewLifecycleOwner) { result ->
|
||||
// when (result) {
|
||||
// is Result.Success -> {
|
||||
// Toast.makeText(requireContext(), "Order completed successfully!", Toast.LENGTH_SHORT).show()
|
||||
//// loadOrders() // Refresh here
|
||||
// }
|
||||
// is Result.Error -> {
|
||||
// Toast.makeText(requireContext(), "Failed: ${result.exception.message}", Toast.LENGTH_SHORT).show()
|
||||
// }
|
||||
// is Result.Loading -> {
|
||||
// // Show loading if needed
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// // Observe cancel order status
|
||||
// viewModel.cancelOrderStatus.observe(viewLifecycleOwner) { result ->
|
||||
// when (result) {
|
||||
// is Result.Success -> {
|
||||
// Toast.makeText(requireContext(), "Order cancelled successfully!", Toast.LENGTH_SHORT).show()
|
||||
// loadOrders() // Refresh here
|
||||
// }
|
||||
// is Result.Error -> {
|
||||
// Toast.makeText(requireContext(), "Failed to cancel: ${result.exception.message}", Toast.LENGTH_SHORT).show()
|
||||
// }
|
||||
// is Result.Loading -> {
|
||||
// // Show loading if needed
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
viewModel.orderCompletionStatus.observe(viewLifecycleOwner) { result ->
|
||||
when (result) {
|
||||
is Result.Success -> {
|
||||
Toast.makeText(requireContext(),
|
||||
"Order completed!", Toast.LENGTH_SHORT).show()
|
||||
"Pesanan Selesai", Toast.LENGTH_SHORT).show()
|
||||
Log.d("OrderListFragment", "Order selesai")
|
||||
viewModel.updateStatus(status, forceRefresh = true)
|
||||
}
|
||||
is Result.Error ->
|
||||
Toast.makeText(requireContext(),
|
||||
"Failed: ${result.exception.message}", Toast.LENGTH_SHORT).show()
|
||||
// Toast.makeText(requireContext(),
|
||||
// "Failed: ${result.exception.message}", Toast.LENGTH_SHORT).show()
|
||||
Log.e("OrderListFragment", "Failed: ${result.exception.message}")
|
||||
|
||||
else -> { /* Loading → no UI change */ }
|
||||
}
|
||||
}
|
||||
@ -206,31 +152,19 @@ class OrderListFragment : Fragment(), OrderHistoryAdapter.OrderActionCallbacks {
|
||||
when (result) {
|
||||
is Result.Success -> {
|
||||
Toast.makeText(requireContext(),
|
||||
"Order cancelled!", Toast.LENGTH_SHORT).show()
|
||||
"Pesanan Dibatalkan", Toast.LENGTH_SHORT).show()
|
||||
Log.d("OrderListFragment", "Order dibatalkan")
|
||||
viewModel.updateStatus(status, forceRefresh = true)
|
||||
}
|
||||
is Result.Error ->
|
||||
Toast.makeText(requireContext(),
|
||||
"Failed: ${result.exception.message}", Toast.LENGTH_SHORT).show()
|
||||
Log.e("OrderListFragment", "Failed: ${result.exception.message}")
|
||||
// Toast.makeText(requireContext(),
|
||||
// "Failed: ${result.exception.message}", Toast.LENGTH_SHORT).show()
|
||||
else -> { /* Loading */ }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// private fun loadOrders() {
|
||||
// // Simple - just call getOrderList for any status including "all"
|
||||
// viewModel.getOrderList(status)
|
||||
// }
|
||||
|
||||
// private val detailOrderLauncher = registerForActivityResult(
|
||||
// ActivityResultContracts.StartActivityForResult()
|
||||
// ) { result ->
|
||||
// if (result.resultCode == Activity.RESULT_OK) {
|
||||
// // Refresh order list when returning with OK result
|
||||
//// loadOrders()
|
||||
// }
|
||||
// }
|
||||
|
||||
private fun navigateToOrderDetail(order: OrdersItem) {
|
||||
val intent = Intent(requireContext(), DetailOrderStatusActivity::class.java).apply {
|
||||
putExtra("ORDER_ID", order.orderId)
|
||||
@ -239,11 +173,10 @@ class OrderListFragment : Fragment(), OrderHistoryAdapter.OrderActionCallbacks {
|
||||
detailOrderLauncher.launch(intent)
|
||||
}
|
||||
|
||||
|
||||
|
||||
override fun onOrderCancelled(orderId: String, success: Boolean, message: String) {
|
||||
if (success) {
|
||||
Toast.makeText(requireContext(), message, Toast.LENGTH_SHORT).show()
|
||||
Toast.makeText(requireContext(), "Berhasil batalkan pesanan", Toast.LENGTH_SHORT).show()
|
||||
Log.d("OrderListFragment", "Order cancel success: $message")
|
||||
// loadOrders() // Refresh the list
|
||||
if (success) viewModel.updateStatus(status, forceRefresh = true)
|
||||
|
||||
@ -254,11 +187,13 @@ class OrderListFragment : Fragment(), OrderHistoryAdapter.OrderActionCallbacks {
|
||||
|
||||
override fun onOrderCompleted(orderId: Int, success: Boolean, message: String) {
|
||||
if (success) {
|
||||
Toast.makeText(requireContext(), message, Toast.LENGTH_SHORT).show()
|
||||
Toast.makeText(requireContext(), "Pesanan selesai", Toast.LENGTH_SHORT).show()
|
||||
Log.d("OrderListFragment", "Pesanan selesai: $message")
|
||||
// loadOrders() // Refresh the list
|
||||
if (success) viewModel.updateStatus(status, forceRefresh = true)
|
||||
} else {
|
||||
Toast.makeText(requireContext(), message, Toast.LENGTH_SHORT).show()
|
||||
Log.e("OrderListFragment", "Error Order Complete: $message")
|
||||
Toast.makeText(requireContext(), "Terdapat kendala di pesanan selesai", Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
}
|
||||
|
||||
@ -271,20 +206,8 @@ class OrderListFragment : Fragment(), OrderHistoryAdapter.OrderActionCallbacks {
|
||||
_binding = null
|
||||
}
|
||||
|
||||
// private fun observeOrderCompletionStatus() {
|
||||
// viewModel.orderCompletionStatus.observe(viewLifecycleOwner) { result ->
|
||||
// when (result) {
|
||||
// is Result.Loading -> {
|
||||
// // Handle loading state if needed
|
||||
// }
|
||||
// is Result.Success -> {
|
||||
// Toast.makeText(requireContext(), "Order completed successfully!", Toast.LENGTH_SHORT).show()
|
||||
//// loadOrders()
|
||||
// }
|
||||
// is Result.Error -> {
|
||||
// Toast.makeText(requireContext(), "Failed to complete order: ${result.exception.message}", Toast.LENGTH_SHORT).show()
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
observeOrderList()
|
||||
}
|
||||
}
|
||||
@ -151,7 +151,7 @@ class StoreDetailActivity : AppCompatActivity() {
|
||||
.into(binding.ivStoreImage)
|
||||
|
||||
val ratingStr = it.storeRating
|
||||
val ratingValue = ratingStr.toFloatOrNull()
|
||||
val ratingValue = ratingStr?.toFloatOrNull() ?: 0f
|
||||
|
||||
if (ratingValue != null && ratingValue > 0f) {
|
||||
binding.tvStoreRating.text = String.format("%.1f", ratingValue)
|
||||
|
||||
@ -45,11 +45,11 @@ class StoreDetailViewModel (private val repository: ProductRepository
|
||||
} // Filter by storeId and exclude current product
|
||||
_otherProducts.value = filteredProducts // Update LiveData
|
||||
} else if (result is Result.Error) {
|
||||
Log.e("ProductViewModel", "Error loading other products: ${result.exception.message}")
|
||||
Log.e("StoreDetailViewModel", "Error loading other products: ${result.exception.message}")
|
||||
_otherProducts.value = emptyList() // Set empty list on failure
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Log.e("ProductViewModel", "Exception loading other products: ${e.message}")
|
||||
Log.e("StoreDetailViewModel", "Exception loading other products: ${e.message}")
|
||||
_otherProducts.value = emptyList()
|
||||
}
|
||||
}
|
||||
@ -67,7 +67,7 @@ class StoreDetailViewModel (private val repository: ProductRepository
|
||||
loadStoreDetail(storeId)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Log.e("ProductViewModel", "Error loading product details: ${e.message}")
|
||||
Log.e("StoreDetailViewModel", "Error loading product details: ${e.message}")
|
||||
_error.value = "Failed to load product details: ${e.message}"
|
||||
} finally {
|
||||
_isLoading.value = false
|
||||
@ -82,7 +82,7 @@ class StoreDetailViewModel (private val repository: ProductRepository
|
||||
val result = repository.fetchStoreDetail(storeId)
|
||||
_storeDetail.value = result
|
||||
} catch (e: Exception) {
|
||||
Log.e("ProductViewModel", "Error loading store details: ${e.message}")
|
||||
Log.e("StoreDetailViewModel", "Error loading store details: ${e.message}")
|
||||
_storeDetail.value = Result.Error(e)
|
||||
}
|
||||
}
|
||||
@ -99,10 +99,10 @@ class StoreDetailViewModel (private val repository: ProductRepository
|
||||
if (result is Result.Success) {
|
||||
map[storeId] = result.data
|
||||
} else if (result is Result.Error) {
|
||||
Log.e("ProductViewModel", "Failed to load storeId $storeId", result.exception)
|
||||
Log.e("StoreDetailViewModel", "Failed to load storeId $storeId", result.exception)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Log.e("ProductViewModel", "Exception fetching storeId $storeId", e)
|
||||
Log.e("StoreDetailViewModel", "Exception fetching storeId $storeId", e)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -208,6 +208,9 @@ class MyStoreActivity : AppCompatActivity() {
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
lifecycleScope.launch {
|
||||
viewModel.getAllStatusCounts()
|
||||
}
|
||||
viewModel.loadMyStore()
|
||||
viewModel.loadMyStoreProducts()
|
||||
viewModel.fetchBalance()
|
||||
|
||||
@ -322,19 +322,6 @@ class DetailStoreAddressActivity : AppCompatActivity() {
|
||||
villageId = oldAddress.villageId
|
||||
)
|
||||
viewModel.saveStoreAddress(oldAddress, newAddress)
|
||||
// Save address
|
||||
// viewModel.saveStoreAddress(
|
||||
// provinceId = selectedProvinceId!!,
|
||||
// provinceName = province?.provinceName ?: "",
|
||||
// cityId = city.cityId,
|
||||
// cityName = city.cityName,
|
||||
// street = street,
|
||||
// subdistrict = subdistrict,
|
||||
// detail = detail,
|
||||
// postalCode = postalCode,
|
||||
// latitude = latitude,
|
||||
// longitude = longitude
|
||||
// )
|
||||
}
|
||||
}
|
||||
|
||||
@ -360,11 +347,13 @@ class DetailStoreAddressActivity : AppCompatActivity() {
|
||||
it.isEnabled = true
|
||||
it.setBackgroundResource(R.drawable.bg_button_active)
|
||||
it.setTextColor(getColor(R.color.white))
|
||||
binding.btnSaveAddress.text = "Simpan Perubahan"
|
||||
|
||||
} else {
|
||||
it.isEnabled = false
|
||||
it.setBackgroundResource(R.drawable.bg_button_disabled)
|
||||
it.setTextColor(getColor(R.color.black_300))
|
||||
Toast.makeText(this, "Periksa dan lenkapi alamat anda", Toast.LENGTH_SHORT).show()
|
||||
binding.btnSaveAddress.text = "Lengkapi alamat anda"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -5,9 +5,15 @@ import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.activityViewModels
|
||||
import androidx.viewpager2.widget.ViewPager2
|
||||
import com.alya.ecommerce_serang.R
|
||||
import com.alya.ecommerce_serang.data.api.retrofit.ApiConfig
|
||||
import com.alya.ecommerce_serang.data.repository.SellsRepository
|
||||
import com.alya.ecommerce_serang.databinding.FragmentSellsBinding
|
||||
import com.alya.ecommerce_serang.utils.BaseViewModelFactory
|
||||
import com.alya.ecommerce_serang.utils.SessionManager
|
||||
import com.alya.ecommerce_serang.utils.viewmodel.SellsViewModel
|
||||
import com.google.android.material.tabs.TabLayoutMediator
|
||||
|
||||
class SellsFragment : Fragment() {
|
||||
@ -18,6 +24,13 @@ class SellsFragment : Fragment() {
|
||||
|
||||
private lateinit var viewPagerAdapter: SellsViewPagerAdapter
|
||||
|
||||
private val sellsVm: SellsViewModel by activityViewModels {
|
||||
BaseViewModelFactory {
|
||||
val api = ApiConfig.getApiService(SessionManager(requireContext()))
|
||||
SellsViewModel(SellsRepository(api))
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup?,
|
||||
@ -53,8 +66,25 @@ class SellsFragment : Fragment() {
|
||||
else -> "Tab $position"
|
||||
}
|
||||
}.attach()
|
||||
|
||||
statusPage()
|
||||
}
|
||||
|
||||
private fun statusPage(){
|
||||
binding.viewPagerSells.registerOnPageChangeCallback(
|
||||
object : ViewPager2.OnPageChangeCallback() {
|
||||
override fun onPageSelected(position: Int) {
|
||||
val status = viewPagerAdapter.sellsStatuses[position]
|
||||
sellsVm.updateStatus(status, forceRefresh = true)
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
statusPage()
|
||||
}
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
_binding = null
|
||||
|
||||
@ -87,7 +87,6 @@ class SellsListFragment : Fragment() {
|
||||
setupRecyclerView()
|
||||
observeSellsList()
|
||||
observePaymentConfirmation()
|
||||
// getAllOrderCountsAndNavigate()
|
||||
}
|
||||
|
||||
private fun setupRecyclerView() {
|
||||
@ -121,8 +120,8 @@ class SellsListFragment : Fragment() {
|
||||
Log.d(TAG, "Data received: ${result.data?.size ?: 0} items")
|
||||
|
||||
if (result.data.isNullOrEmpty()) {
|
||||
binding.tvEmptyState.visibility = View.VISIBLE
|
||||
binding.rvSells.visibility = View.GONE
|
||||
binding.tvEmptyState.visibility = View.VISIBLE
|
||||
Log.d(TAG, "Showing empty state")
|
||||
|
||||
} else {
|
||||
|
||||
@ -9,7 +9,7 @@ class SellsViewPagerAdapter(
|
||||
) : FragmentStateAdapter(fragmentActivity) {
|
||||
|
||||
// Define all possible sells statuses - keeping your original list
|
||||
private val sellsStatuses = listOf(
|
||||
val sellsStatuses = listOf(
|
||||
"all",
|
||||
"unpaid",
|
||||
"paid",
|
||||
|
||||
@ -2,7 +2,6 @@ package com.alya.ecommerce_serang.ui.profile.mystore.sells.payment
|
||||
|
||||
import android.app.Dialog
|
||||
import android.graphics.Color
|
||||
import android.graphics.drawable.ColorDrawable
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.os.Bundle
|
||||
import android.util.Log
|
||||
@ -16,6 +15,8 @@ import android.widget.TextView
|
||||
import android.widget.Toast
|
||||
import androidx.activity.viewModels
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.graphics.drawable.toDrawable
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import com.alya.ecommerce_serang.BuildConfig.BASE_URL
|
||||
import com.alya.ecommerce_serang.R
|
||||
import com.alya.ecommerce_serang.data.api.response.store.sells.Orders
|
||||
@ -38,9 +39,6 @@ import java.text.SimpleDateFormat
|
||||
import java.util.Calendar
|
||||
import java.util.Locale
|
||||
import java.util.TimeZone
|
||||
import androidx.core.graphics.drawable.toDrawable
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import com.alya.ecommerce_serang.ui.profile.mystore.sells.DetailSellsActivity
|
||||
|
||||
class DetailPaymentActivity : AppCompatActivity() {
|
||||
|
||||
@ -139,6 +137,7 @@ class DetailPaymentActivity : AppCompatActivity() {
|
||||
tvOrderSubtotal.text = formatPrice(sell.totalAmount.toString())
|
||||
tvOrderShipPrice.text = formatPrice(sell.shipmentPrice.toString())
|
||||
tvOrderPrice.text = formatPrice(sell.totalAmount.toString())
|
||||
tvOrderDue.text = formatDueDate(sell.updatedAt.toString(), 2)
|
||||
tvOrderRecipient.text = sell.recipient ?: "-"
|
||||
tvOrderRecipientNum.text = sell.receiptNum?.toString() ?: "-"
|
||||
|
||||
@ -201,6 +200,28 @@ class DetailPaymentActivity : AppCompatActivity() {
|
||||
}
|
||||
}
|
||||
|
||||
private fun formatDueDate(dateString: 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")
|
||||
|
||||
val outputFormat = SimpleDateFormat("dd MMM; HH.mm", Locale("id", "ID"))
|
||||
|
||||
val date = inputFormat.parse(dateString)
|
||||
|
||||
date?.let {
|
||||
val calendar = Calendar.getInstance()
|
||||
calendar.time = it
|
||||
calendar.add(Calendar.DATE, dueDay)
|
||||
|
||||
outputFormat.format(calendar.time)
|
||||
} ?: dateString
|
||||
} catch (e: Exception) {
|
||||
Log.e("DateFormatting", "Error formatting date: ${e.message}")
|
||||
dateString
|
||||
}
|
||||
}
|
||||
|
||||
private fun formatPrice(price: String): String {
|
||||
val priceDouble = price.toDoubleOrNull() ?: 0.0
|
||||
return String.format(Locale("id", "ID"), "Rp%,.0f", priceDouble)
|
||||
|
||||
@ -14,7 +14,6 @@ import com.alya.ecommerce_serang.data.repository.AddressRepository
|
||||
import com.alya.ecommerce_serang.data.repository.SellsRepository
|
||||
import com.alya.ecommerce_serang.databinding.ActivityDetailShipmentBinding
|
||||
import com.alya.ecommerce_serang.ui.profile.mystore.sells.SellsProductAdapter
|
||||
import com.alya.ecommerce_serang.ui.profile.mystore.sells.payment.DetailPaymentActivity
|
||||
import com.alya.ecommerce_serang.utils.BaseViewModelFactory
|
||||
import com.alya.ecommerce_serang.utils.SessionManager
|
||||
import com.alya.ecommerce_serang.utils.viewmodel.AddressViewModel
|
||||
@ -24,7 +23,6 @@ import java.text.SimpleDateFormat
|
||||
import java.util.Calendar
|
||||
import java.util.Locale
|
||||
import java.util.TimeZone
|
||||
import kotlin.getValue
|
||||
|
||||
class DetailShipmentActivity : AppCompatActivity() {
|
||||
|
||||
@ -106,6 +104,7 @@ class DetailShipmentActivity : AppCompatActivity() {
|
||||
tvOrderSubtotal.text = formatPrice(sell.totalAmount.toString())
|
||||
tvOrderShipPrice.text = formatPrice(sell.shipmentPrice.toString())
|
||||
tvOrderPrice.text = formatPrice(sell.totalAmount.toString())
|
||||
tvOrderDue.text = formatDueDate(sell.updatedAt.toString(), 2)
|
||||
tvOrderRecipient.text = sell.recipient ?: "-"
|
||||
tvOrderRecipientNum.text = sell.receiptNum?.toString() ?: "-"
|
||||
|
||||
@ -168,6 +167,28 @@ class DetailShipmentActivity : AppCompatActivity() {
|
||||
}
|
||||
}
|
||||
|
||||
private fun formatDueDate(dateString: 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")
|
||||
|
||||
val outputFormat = SimpleDateFormat("dd MMM; HH.mm", Locale("id", "ID"))
|
||||
|
||||
val date = inputFormat.parse(dateString)
|
||||
|
||||
date?.let {
|
||||
val calendar = Calendar.getInstance()
|
||||
calendar.time = it
|
||||
calendar.add(Calendar.DATE, dueDay)
|
||||
|
||||
outputFormat.format(calendar.time)
|
||||
} ?: dateString
|
||||
} catch (e: Exception) {
|
||||
Log.e("DateFormatting", "Error formatting date: ${e.message}")
|
||||
dateString
|
||||
}
|
||||
}
|
||||
|
||||
private fun formatPrice(price: String): String {
|
||||
val priceDouble = price.toDoubleOrNull() ?: 0.0
|
||||
return String.format(Locale("id", "ID"), "Rp%,.0f", priceDouble)
|
||||
|
||||
@ -17,6 +17,9 @@ import com.alya.ecommerce_serang.ui.order.address.ViewState
|
||||
import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.awaitAll
|
||||
import kotlinx.coroutines.coroutineScope
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.asStateFlow
|
||||
import kotlinx.coroutines.launch
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.Locale
|
||||
@ -52,6 +55,9 @@ class SellsViewModel(private val repository: SellsRepository) : ViewModel() {
|
||||
private val _error = MutableLiveData<String>()
|
||||
val error: LiveData<String> get() = _error
|
||||
|
||||
private val _selectedStatus = MutableStateFlow("all")
|
||||
val selectedStatus: StateFlow<String> = _selectedStatus.asStateFlow()
|
||||
|
||||
fun getSellList(status: String) {
|
||||
Log.d(TAG, "========== Starting getSellList ==========")
|
||||
Log.d(TAG, "Requested status: '$status'")
|
||||
@ -320,4 +326,40 @@ class SellsViewModel(private val repository: SellsRepository) : ViewModel() {
|
||||
|
||||
Log.d(TAG, "========== refreshOrders method completed ==========")
|
||||
}
|
||||
|
||||
fun updateStatus(status: String, forceRefresh: Boolean = false) {
|
||||
Log.d(TAG, "↪️ updateStatus(status = $status, forceRefresh = $forceRefresh)")
|
||||
|
||||
// No‑op guard (optional): skip if user re‑selects same tab and no refresh asked
|
||||
if (_selectedStatus.value == status && !forceRefresh) {
|
||||
Log.d(TAG, "🔸 Status unchanged & forceRefresh = false → skip update")
|
||||
return
|
||||
}
|
||||
|
||||
_selectedStatus.value = status
|
||||
Log.d(TAG, "✅ _selectedStatus set to \"$status\"")
|
||||
|
||||
if (forceRefresh) {
|
||||
Log.d(TAG, "🔄 forceRefresh = true → launching refresh()")
|
||||
viewModelScope.launch { refresh(status) }
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun refresh(status: String) {
|
||||
Log.d(TAG, "⏳ refresh(\"$status\") started")
|
||||
|
||||
try {
|
||||
if (status == "all") {
|
||||
Log.d(TAG, "🌐 Calling getAllOrdersCombined()")
|
||||
getAllStatusCounts() // network → cache
|
||||
} else {
|
||||
Log.d(TAG, "🌐 repository.getOrderList(\"$status\")")
|
||||
repository.getSellList(status) // network → cache
|
||||
}
|
||||
Log.d(TAG, "✅ refresh(\"$status\") completed (repository updated)")
|
||||
// Flow that watches DB/cache will emit automatically
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "❌ refresh(\"$status\") failed: ${e.message}", e)
|
||||
}
|
||||
}
|
||||
}
|
||||
29
app/src/main/res/drawable/logo_bisa_umkm.xml
Normal file
29
app/src/main/res/drawable/logo_bisa_umkm.xml
Normal file
@ -0,0 +1,29 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="64dp"
|
||||
android:height="64dp"
|
||||
android:viewportWidth="108"
|
||||
android:viewportHeight="108">
|
||||
|
||||
<!-- Background circle for better splash screen appearance -->
|
||||
<path
|
||||
android:pathData="M54,54m-50,0a50,50 0,1 1,100 0a50,50 0,1 1,-100 0"
|
||||
android:fillColor="#ffff"/>
|
||||
|
||||
<!-- Main logo content scaled and centered -->
|
||||
<group android:translateX="32" android:translateY="32" android:scaleX="0.7" android:scaleY="0.7">
|
||||
<!-- Background rectangle -->
|
||||
<path
|
||||
android:pathData="M0,0h64v64h-64z"
|
||||
android:fillColor="#489EC6"/>
|
||||
|
||||
<!-- Main logo shape -->
|
||||
<path
|
||||
android:pathData="M11.868,58C10.523,58 9.399,57.538 8.497,56.614C7.594,55.69 7.144,54.537 7.146,53.155V29.074C5.912,28.14 5.009,26.915 4.438,25.399C3.867,23.883 3.854,22.266 4.4,20.548L7.245,10.924C7.635,9.7 8.264,8.74 9.131,8.044C10.001,7.348 11.075,7 12.354,7H51.536C52.813,7 53.883,7.326 54.747,7.978C55.608,8.63 56.24,9.573 56.641,10.807L59.598,20.545C60.146,22.265 60.134,23.896 59.563,25.438C58.992,26.98 58.089,28.23 56.855,29.188V53.152C56.855,54.534 56.404,55.687 55.501,56.611C54.599,57.535 53.476,57.998 52.133,58H11.868ZM38.433,28C40.311,28 41.712,27.46 42.638,26.38C43.564,25.302 43.954,24.188 43.808,23.038L41.866,10H33.465V22.6C33.465,24.074 33.957,25.342 34.939,26.404C35.922,27.468 37.084,28 38.433,28ZM25.278,28C26.849,28 28.119,27.468 29.088,26.404C30.057,25.34 30.541,24.072 30.541,22.6V10H22.138L20.19,23.269C20.071,24.201 20.468,25.222 21.38,26.332C22.292,27.442 23.594,27.998 25.278,28ZM12.263,28C13.551,28 14.647,27.55 15.55,26.65C16.452,25.75 17.014,24.627 17.234,23.281L19.067,10H12.354C11.716,10 11.209,10.144 10.833,10.432C10.457,10.72 10.176,11.153 9.991,11.731L7.292,21.205C6.812,22.781 7.017,24.308 7.906,25.786C8.795,27.264 10.247,28.002 12.263,28ZM51.738,28C53.488,28 54.886,27.3 55.931,25.9C56.978,24.5 57.237,22.935 56.709,21.205L53.864,11.617C53.676,11.039 53.395,10.625 53.019,10.375C52.642,10.125 52.137,10 51.501,10H44.933L46.767,23.281C46.987,24.627 47.549,25.75 48.451,26.65C49.354,27.55 50.449,28 51.738,28Z"
|
||||
android:fillColor="#ffffff"/>
|
||||
|
||||
<!-- Text elements -->
|
||||
<path
|
||||
android:pathData="M20.382,39V30.6H23.97C24.554,30.6 25.046,30.692 25.446,30.876C25.846,31.052 26.15,31.304 26.358,31.632C26.574,31.952 26.682,32.332 26.682,32.772C26.682,33.196 26.59,33.552 26.406,33.84C26.222,34.128 25.978,34.348 25.674,34.5C25.378,34.652 25.05,34.744 24.69,34.776L24.882,34.632C25.274,34.648 25.618,34.752 25.914,34.944C26.21,35.136 26.442,35.388 26.61,35.7C26.786,36.004 26.874,36.34 26.874,36.708C26.874,37.164 26.766,37.564 26.55,37.908C26.334,38.252 26.018,38.52 25.602,38.712C25.186,38.904 24.682,39 24.09,39H20.382ZM22.182,37.536H23.79C24.19,37.536 24.498,37.448 24.714,37.272C24.938,37.088 25.05,36.824 25.05,36.48C25.05,36.136 24.934,35.868 24.702,35.676C24.478,35.484 24.166,35.388 23.766,35.388H22.182V37.536ZM22.182,34.056H23.658C24.042,34.056 24.334,33.968 24.534,33.792C24.742,33.616 24.846,33.368 24.846,33.048C24.846,32.728 24.742,32.48 24.534,32.304C24.334,32.12 24.038,32.028 23.646,32.028H22.182V34.056ZM28.163,39V32.952H29.963V39H28.163ZM29.063,32.256C28.743,32.256 28.483,32.164 28.283,31.98C28.083,31.796 27.983,31.564 27.983,31.284C27.983,30.996 28.083,30.76 28.283,30.576C28.483,30.392 28.743,30.3 29.063,30.3C29.391,30.3 29.655,30.392 29.855,30.576C30.063,30.76 30.167,30.996 30.167,31.284C30.167,31.564 30.063,31.796 29.855,31.98C29.655,32.164 29.391,32.256 29.063,32.256ZM34.069,39.144C33.501,39.144 33.009,39.056 32.593,38.88C32.186,38.696 31.861,38.448 31.622,38.136C31.389,37.824 31.257,37.472 31.226,37.08H33.014C33.046,37.216 33.102,37.34 33.181,37.452C33.27,37.556 33.386,37.64 33.529,37.704C33.681,37.76 33.849,37.788 34.034,37.788C34.234,37.788 34.394,37.764 34.514,37.716C34.641,37.66 34.737,37.588 34.801,37.5C34.866,37.412 34.897,37.32 34.897,37.224C34.897,37.072 34.849,36.956 34.754,36.876C34.666,36.796 34.534,36.732 34.357,36.684C34.181,36.628 33.97,36.576 33.722,36.528C33.433,36.464 33.146,36.392 32.857,36.312C32.577,36.224 32.326,36.116 32.102,35.988C31.885,35.86 31.709,35.696 31.573,35.496C31.445,35.288 31.382,35.036 31.382,34.74C31.382,34.38 31.482,34.056 31.681,33.768C31.882,33.472 32.169,33.24 32.546,33.072C32.922,32.896 33.377,32.808 33.914,32.808C34.674,32.808 35.27,32.976 35.701,33.312C36.133,33.648 36.389,34.1 36.47,34.668H34.79C34.742,34.508 34.641,34.388 34.489,34.308C34.338,34.22 34.146,34.176 33.914,34.176C33.65,34.176 33.45,34.22 33.313,34.308C33.178,34.396 33.11,34.512 33.11,34.656C33.11,34.752 33.153,34.84 33.242,34.92C33.338,34.992 33.473,35.056 33.65,35.112C33.826,35.168 34.042,35.224 34.298,35.28C34.785,35.384 35.206,35.496 35.557,35.616C35.917,35.736 36.197,35.912 36.397,36.144C36.597,36.368 36.694,36.696 36.686,37.128C36.694,37.52 36.59,37.868 36.374,38.172C36.166,38.476 35.866,38.716 35.473,38.892C35.082,39.06 34.613,39.144 34.069,39.144ZM40.094,39.144C39.59,39.144 39.17,39.064 38.834,38.904C38.506,38.744 38.262,38.528 38.102,38.256C37.95,37.976 37.874,37.668 37.874,37.332C37.874,36.972 37.962,36.656 38.138,36.384C38.322,36.104 38.606,35.884 38.99,35.724C39.374,35.556 39.858,35.472 40.442,35.472H41.906C41.906,35.2 41.87,34.976 41.798,34.8C41.734,34.624 41.626,34.492 41.474,34.404C41.322,34.316 41.114,34.272 40.85,34.272C40.57,34.272 40.334,34.328 40.142,34.44C39.95,34.552 39.83,34.728 39.782,34.968H38.054C38.094,34.536 38.234,34.16 38.474,33.84C38.722,33.52 39.05,33.268 39.458,33.084C39.866,32.9 40.334,32.808 40.862,32.808C41.438,32.808 41.938,32.904 42.362,33.096C42.786,33.28 43.114,33.552 43.346,33.912C43.586,34.272 43.706,34.72 43.706,35.256V39H42.206L41.99,38.124C41.902,38.276 41.798,38.416 41.678,38.544C41.558,38.664 41.418,38.772 41.258,38.868C41.098,38.956 40.922,39.024 40.73,39.072C40.538,39.12 40.326,39.144 40.094,39.144ZM40.538,37.776C40.73,37.776 40.898,37.744 41.042,37.68C41.186,37.616 41.31,37.528 41.414,37.416C41.518,37.304 41.602,37.176 41.666,37.032C41.738,36.88 41.79,36.716 41.822,36.54V36.528H40.658C40.458,36.528 40.29,36.556 40.154,36.612C40.026,36.66 39.93,36.732 39.866,36.828C39.802,36.924 39.77,37.036 39.77,37.164C39.77,37.3 39.802,37.416 39.866,37.512C39.938,37.6 40.03,37.668 40.142,37.716C40.262,37.756 40.394,37.776 40.538,37.776ZM17.132,53.144C16.5,53.144 15.924,53.02 15.404,52.772C14.892,52.516 14.484,52.136 14.18,51.632C13.884,51.128 13.736,50.492 13.736,49.724V44.6H15.536V49.736C15.536,50.112 15.596,50.432 15.716,50.696C15.844,50.96 16.028,51.16 16.268,51.296C16.516,51.424 16.812,51.488 17.156,51.488C17.508,51.488 17.804,51.424 18.044,51.296C18.292,51.16 18.48,50.96 18.608,50.696C18.736,50.432 18.8,50.112 18.8,49.736V44.6H20.6V49.724C20.6,50.492 20.44,51.128 20.12,51.632C19.808,52.136 19.388,52.516 18.86,52.772C18.34,53.02 17.764,53.144 17.132,53.144ZM22.128,53V44.6H24.288L26.736,49.652L29.16,44.6H31.308V53H29.508V47.636L27.444,51.824H26.004L23.928,47.636V53H22.128ZM32.921,53V44.6H34.721V47.78L37.625,44.6H39.833L36.749,47.924L39.941,53H37.733L35.465,49.316L34.721,50.12V53H32.921ZM41.007,53V44.6H43.167L45.615,49.652L48.039,44.6H50.187V53H48.387V47.636L46.323,51.824H44.883L42.807,47.636V53H41.007Z"
|
||||
android:fillColor="#489EC6"/>
|
||||
</group>
|
||||
</vector>
|
||||
@ -14,7 +14,6 @@
|
||||
android:layout_height="match_parent"
|
||||
app:layout_behavior="@string/appbar_scrolling_view_behavior">
|
||||
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
@ -167,7 +166,7 @@
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="@color/soft_gray"
|
||||
android:textSize="14sp"
|
||||
android:textSize="12sp"
|
||||
tools:text="@string/item_sold" />
|
||||
|
||||
<View
|
||||
@ -186,7 +185,7 @@
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="4dp"
|
||||
android:textSize="14sp"
|
||||
android:textSize="12sp"
|
||||
tools:text="4.5" />
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
@ -219,7 +218,7 @@
|
||||
android:layout_weight="1"
|
||||
android:text="@string/ulasan_pembeli"
|
||||
android:textColor="@color/black"
|
||||
android:textSize="16sp"
|
||||
android:textSize="14sp"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<TextView
|
||||
@ -236,7 +235,7 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Belum ada ulasan"
|
||||
android:textSize="16sp"
|
||||
android:textSize="12sp"
|
||||
android:textColor="@color/black_200"
|
||||
android:gravity="center"
|
||||
android:visibility="gone"
|
||||
@ -277,7 +276,7 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/detail_produk"
|
||||
android:textColor="@color/black"
|
||||
android:textSize="16sp"
|
||||
android:textSize="14sp"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<TableLayout
|
||||
@ -296,7 +295,7 @@
|
||||
android:layout_weight="1"
|
||||
android:text="@string/berat_produk"
|
||||
android:fontFamily="@font/dmsans_semibold"
|
||||
android:textSize="14sp" />
|
||||
android:textSize="12sp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvWeight"
|
||||
@ -304,7 +303,7 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:textColor="@color/blue_500"
|
||||
android:textSize="14sp"
|
||||
android:textSize="12sp"
|
||||
tools:text="200 gram" />
|
||||
</TableRow>
|
||||
|
||||
@ -319,7 +318,7 @@
|
||||
android:layout_weight="1"
|
||||
android:text="@string/stock_product"
|
||||
android:fontFamily="@font/dmsans_semibold"
|
||||
android:textSize="14sp" />
|
||||
android:textSize="12sp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvStock"
|
||||
@ -327,7 +326,7 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:textColor="@color/blue_500"
|
||||
android:textSize="14sp"
|
||||
android:textSize="12sp"
|
||||
tools:text="100 buah" />
|
||||
</TableRow>
|
||||
|
||||
@ -358,8 +357,8 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/deskripsi_produk"
|
||||
android:textColor="@color/black"
|
||||
android:textSize="16sp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:textSize="14sp"
|
||||
android:layout_marginTop="16dp"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<TextView
|
||||
@ -368,7 +367,7 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:textColor="@color/black"
|
||||
android:textSize="14sp"
|
||||
android:textSize="12sp"
|
||||
tools:text="Terbuat dari tepung dan ikan tenggiri asli Serang Banten. Tahan selama 25 hari." />
|
||||
</LinearLayout>
|
||||
</androidx.cardview.widget.CardView>
|
||||
@ -422,7 +421,7 @@
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="@color/black"
|
||||
android:textSize="16sp"
|
||||
android:textSize="14sp"
|
||||
android:textStyle="bold"
|
||||
tools:text="SnackEnak" />
|
||||
|
||||
@ -430,8 +429,9 @@
|
||||
android:id="@+id/tvSellerLocation"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:fontFamily="@font/dmsans_semibold"
|
||||
android:textSize="14sp"
|
||||
android:fontFamily="@font/dmsans_regular"
|
||||
android:textColor="@color/black_300"
|
||||
android:textSize="12sp"
|
||||
tools:text="Jakarta Selatan" />
|
||||
|
||||
<RatingBar
|
||||
@ -450,7 +450,7 @@
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="2dp"
|
||||
android:textSize="14sp"
|
||||
android:textSize="12sp"
|
||||
android:textStyle="bold"
|
||||
tools:text="5.0" />
|
||||
</LinearLayout>
|
||||
@ -484,7 +484,7 @@
|
||||
android:layout_weight="1"
|
||||
android:text="@string/produk_lainnya"
|
||||
android:textColor="@color/black"
|
||||
android:textSize="16sp"
|
||||
android:textSize="14sp"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<TextView
|
||||
@ -501,7 +501,7 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Belum ada produk lainnya"
|
||||
android:textSize="16sp"
|
||||
android:textSize="12sp"
|
||||
android:textColor="@color/black_200"
|
||||
android:gravity="center"
|
||||
android:visibility="gone"
|
||||
@ -574,6 +574,7 @@
|
||||
android:insetBottom="0dp"
|
||||
android:text="@string/add_to_cart"
|
||||
android:textColor="@color/blue_500"
|
||||
android:textSize="14sp"
|
||||
app:cornerRadius="4dp"
|
||||
app:icon="@drawable/baseline_add_24"
|
||||
app:iconGravity="textStart"
|
||||
@ -591,6 +592,7 @@
|
||||
android:insetTop="0dp"
|
||||
android:insetBottom="0dp"
|
||||
android:text="@string/beli_sekarang"
|
||||
android:textSize="14sp"
|
||||
android:textColor="@color/white"
|
||||
app:cornerRadius="4dp" />
|
||||
</LinearLayout>
|
||||
|
||||
@ -6,6 +6,8 @@
|
||||
android:layout_height="match_parent"
|
||||
android:paddingHorizontal="32dp"
|
||||
android:paddingVertical="16dp"
|
||||
android:layout_marginTop="32dp"
|
||||
android:theme="@style/Theme.Ecommerce_serang"
|
||||
tools:context=".ui.auth.LoginActivity">
|
||||
|
||||
<!-- Title -->
|
||||
|
||||
@ -261,7 +261,7 @@
|
||||
android:id="@+id/btn_register"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="56dp"
|
||||
android:layout_margin="16dp"
|
||||
android:layout_marginHorizontal="16dp"
|
||||
android:background="@drawable/button_address_background"
|
||||
android:text="@string/signup"
|
||||
android:textAllCaps="false"
|
||||
|
||||
@ -147,29 +147,112 @@
|
||||
<string name="buka_toko_desc">Mohon untuk melengkapi formulir pendaftaran ini agar dapat mengakses fitur penjual pada aplikasi.</string>
|
||||
|
||||
<!-- List Bank -->
|
||||
<string-array name="bank_name_array">
|
||||
<string-array name="bank_names">
|
||||
<item>Bank of America</item>
|
||||
<item>Bank of China (Hong Kong)</item>
|
||||
<item>Citibank</item>
|
||||
<item>Deutsche Bank Ag</item>
|
||||
<item>JP Morgan Chase Bank</item>
|
||||
<item>MUFG Bank</item>
|
||||
<item>Allo Bank Indonesia</item>
|
||||
<item>Bank Digital BCA</item>
|
||||
<item>Bank Central Asia (BCA)</item>
|
||||
<item>Bank Aceh Syariah</item>
|
||||
<item>Bank Aladin Syariah</item>
|
||||
<item>Bank Amar Indonesia</item>
|
||||
<item>Bank ANZ Indonesia</item>
|
||||
<item>Bank Artha Graha Internasional</item>
|
||||
<item>Bank BCA Syariah</item>
|
||||
<item>Bank Jago</item>
|
||||
<item>Bank Mandiri </item>
|
||||
<item>Bank Kb Bukopi</item>
|
||||
<item>Bank BNP Paribas Indonesia</item>
|
||||
<item>Bank BTPN Syariah</item>
|
||||
<item>Bank Bumi Arta</item>
|
||||
<item>Bank Capital Indonesia</item>
|
||||
<item>Bank Central Asia (BCA)</item>
|
||||
<item>Bank China Construction Bank Indonesia</item>
|
||||
<item>Bank CIMB Niaga</item>
|
||||
<item>Bank CTBC Indonesia</item>
|
||||
<item>Bank Danamon Indonesia</item>
|
||||
<item>Bank DBS Indonesia</item>
|
||||
<item>Bank Digital BCA</item>
|
||||
<item>Bank Ganesha</item>
|
||||
<item>Bank Hibank Indonesia</item>
|
||||
<item>Bank HSBC Indonesia</item>
|
||||
<item>Bank IBK Indonesia</item>
|
||||
<item>Bank ICBC Indonesia</item>
|
||||
<item>Bank Ina Perdana</item>
|
||||
<item>Bank Index Selindo</item>
|
||||
<item>Bank Jabar Banten Syariah</item>
|
||||
<item> Bank Mandiri Taspen</item>
|
||||
<item>Bank Maybank Indonesia </item>
|
||||
<item>Bank Jago</item>
|
||||
<item>Bank JTrust Indonesia</item>
|
||||
<item>Bank Kb Bukopin Syariah</item>
|
||||
<item>Bank Kb Bukopin</item>
|
||||
<item>Bank Keb Hana Indonesia</item>
|
||||
<item>Bank Mandiri</item>
|
||||
<item>Bank Mandiri Taspen</item>
|
||||
<item>Bank Maspion Indonesia</item>
|
||||
<item>Bank Mayapada International</item>
|
||||
<item>Bank Maybank Indonesia</item>
|
||||
<item>Bank Mega Syariah</item>
|
||||
<item>Bank Mega</item>
|
||||
<item>Bank Mestika Dharma</item>
|
||||
<item>Bank Mizuho Indonesia</item>
|
||||
<item>Bank MNC Internasional</item>
|
||||
<item>Bank Muamalat Indonesia</item>
|
||||
<item>Bank Multiarta Sentosa</item>
|
||||
<item>Bank Nagari</item>
|
||||
<item>Bank Nano Syariah</item>
|
||||
<item>Bank Nationalnobu</item>
|
||||
<item>Bank Negara Indonesia (BNI)</item>
|
||||
<item>Bank Neo Commerce</item>
|
||||
<item>Bank NTB Syariah</item>
|
||||
<item>Bank OCBC NISP</item>
|
||||
<item>Bank of India Indonesia</item>
|
||||
<item>Bank Oke Indonesia</item>
|
||||
<item>Bank PAN Indonesia</item>
|
||||
<item>Bank Panin Dubai Syariah</item>
|
||||
<item>Bank Pembangunan Daerah (BPD) Bali</item>
|
||||
<item>Bank Permata</item>
|
||||
<item>Bank QNB Indonesia</item>
|
||||
<item>Bank Rakyat Indonesia (BRI)</item>
|
||||
<item>Bank Raya Indonesia</item>
|
||||
<item>Bank Resona Perdania</item>
|
||||
<item>Bank Sahabat Sampoerna</item>
|
||||
<item>Bank Saqu Indonesia</item>
|
||||
<item>Bank SBI Indonesia</item>
|
||||
<item>Bank Seabank Indonesia</item>
|
||||
<item>Bank Sinarmas </item>
|
||||
<item>Bank Shinhan Indonesia</item>
|
||||
<item>Bank Sinarmas</item>
|
||||
<item>Bank SMBC Indonesia</item>
|
||||
<item>Bank Syariah Indonesia (BSI)</item>
|
||||
<item>Bank Tabungan Negara (BTN)</item>
|
||||
<item>Bank UOB Indonesia</item>
|
||||
<item>Bank Victoria International</item>
|
||||
<item>Bank Victoria Syariah</item>
|
||||
<item>Bank Woori Saudara Indonesia 1906</item>
|
||||
<item>BPD Banten</item>
|
||||
<item>BPD Bengkulu</item>
|
||||
<item>BPD Daerah Istimewa Yogyakarta</item>
|
||||
<item>BPD DKI</item>
|
||||
<item>BPD Jambi</item>
|
||||
<item>BPD Jawa Barat dan Banten</item>
|
||||
<item>BPD Jawa Tengah</item>
|
||||
<item>BPD Jawa Timur</item>
|
||||
<item>BPD Kalimantan Barat</item>
|
||||
<item>BPD Kalimantan Selatan</item>
|
||||
<item>BPD Kalimantan Tengah</item>
|
||||
<item>BPD Kalimantan Timur dan Kalimantan Utara</item>
|
||||
<item>BPD Lampung</item>
|
||||
<item>BPD Maluku dan Maluku Utara</item>
|
||||
<item>BPD Nusa Tenggara Timur</item>
|
||||
<item>BPD Papua</item>
|
||||
<item>BPD Riau Kepri Syariah</item>
|
||||
<item>BPD Sulawesi Selatan dan Sulawesi Barat</item>
|
||||
<item>BPD Sulawesi Tengah</item>
|
||||
<item>BPD Sulawesi Tenggara</item>
|
||||
<item>BPD Sulawesi Utara dan Gorontalo</item>
|
||||
<item>BPD Sumatera Selatan dan Bangka Belitung</item>
|
||||
<item>BPD Sumatera Utara</item>
|
||||
<item>Krom Bank Indonesia</item>
|
||||
<item>Super Bank Indonesia</item>
|
||||
|
||||
<item>Standard Chartered Bank</item>
|
||||
</string-array>
|
||||
|
||||
</resources>
|
||||
@ -1,4 +1,4 @@
|
||||
<resources>
|
||||
<resources xmlns:tools="http://schemas.android.com/tools">
|
||||
<!-- Base application theme. -->
|
||||
<style name="Theme.Ecommerce_serang" parent="Theme.Material3.Light.NoActionBar">
|
||||
<!-- Primary Color Customization -->
|
||||
@ -330,4 +330,12 @@
|
||||
<item name="cornerSize">5dp</item>
|
||||
</style>
|
||||
|
||||
</resources>
|
||||
|
||||
<style name="Theme.App.SplashScreen" parent="Theme.SplashScreen">
|
||||
<item name="windowSplashScreenBackground">@color/white</item>
|
||||
<item name="windowSplashScreenAnimatedIcon">@drawable/logo_bisa_umkm</item>
|
||||
<item name="windowSplashScreenAnimationDuration">1000</item>
|
||||
<item name="android:windowSplashScreenBehavior" tools:targetApi="33">icon_preferred</item>
|
||||
<item name="postSplashScreenTheme">@style/Theme.Ecommerce_serang</item>
|
||||
</style>
|
||||
</resources>
|
||||
Reference in New Issue
Block a user