From adf324e15de865ef2f7ae002f4bfbbc497355b7b Mon Sep 17 00:00:00 2001 From: shaulascr Date: Thu, 10 Jul 2025 11:58:14 +0700 Subject: [PATCH] fix bug --- app/.gitignore | 3 +- .../data/api/retrofit/ApiConfig.kt | 8 ++ .../ecommerce_serang/ui/auth/LoginActivity.kt | 24 ++-- .../ui/auth/RegisterActivity.kt | 20 +--- .../auth/fragments/RegisterStep1Fragment.kt | 7 ++ .../auth/fragments/RegisterStep2Fragment.kt | 11 +- .../ecommerce_serang/ui/cart/CartActivity.kt | 4 +- .../ecommerce_serang/ui/chat/ChatActivity.kt | 5 +- .../ui/chat/ChatListFragment.kt | 46 +++++--- .../ecommerce_serang/ui/chat/ChatViewModel.kt | 13 ++- .../ecommerce_serang/ui/home/HomeFragment.kt | 23 ---- .../ui/order/CheckoutActivity.kt | 12 +- .../detailorder/DetailOrderStatusActivity.kt | 45 ++++---- .../utils/viewmodel/RegisterViewModel.kt | 16 +++ app/src/main/res/layout/activity_cart.xml | 12 ++ app/src/main/res/layout/activity_checkout.xml | 8 +- .../main/res/layout/activity_list_product.xml | 62 ++++++----- app/src/main/res/layout/activity_login.xml | 105 ++++++++++++------ app/src/main/res/layout/activity_shipping.xml | 1 + .../main/res/layout/fragment_chat_list.xml | 19 ++++ .../res/layout/fragment_register_step2.xml | 2 +- app/src/main/res/layout/view_loading.xml | 13 ++- 22 files changed, 279 insertions(+), 180 deletions(-) diff --git a/app/.gitignore b/app/.gitignore index 42afabf..65d12b9 100644 --- a/app/.gitignore +++ b/app/.gitignore @@ -1 +1,2 @@ -/build \ No newline at end of file +/build +google-services.json \ No newline at end of file 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 b277cea..f53ae8a 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 @@ -15,10 +15,14 @@ class ApiConfig { val loggingInterceptor = HttpLoggingInterceptor().apply { level = HttpLoggingInterceptor.Level.BODY + //httplogginginterceptor ntuk debug dan monitoring request/response } val authInterceptor = AuthInterceptor(tokenManager) + // utk tambak token auth otomatis pada header + // Konfigurasi OkHttpClient + //Low-level HTTP client yang melakukan actual network request val client = OkHttpClient.Builder() .addInterceptor(loggingInterceptor) .addInterceptor(authInterceptor) @@ -27,13 +31,17 @@ class ApiConfig { .writeTimeout(300, TimeUnit.SECONDS) // 5 minutes .build() + // Konfigurasi Retrofit val retrofit = Retrofit.Builder() + //almat domain backend .baseUrl(BuildConfig.BASE_URL) .addConverterFactory(GsonConverterFactory.create()) + //gson convertes: mengkonversi JSON ke object Kotlin dan sebaliknya .client(client) .build() return retrofit.create(ApiService::class.java) + // retrofit : menyederhanakan HTTP Request dgn mengubah interface Kotlin di ApiService menjadi HTTP calls secara otomatis } fun getUnauthenticatedApiService(): ApiService { diff --git a/app/src/main/java/com/alya/ecommerce_serang/ui/auth/LoginActivity.kt b/app/src/main/java/com/alya/ecommerce_serang/ui/auth/LoginActivity.kt index 3d0ce11..01e7307 100644 --- a/app/src/main/java/com/alya/ecommerce_serang/ui/auth/LoginActivity.kt +++ b/app/src/main/java/com/alya/ecommerce_serang/ui/auth/LoginActivity.kt @@ -8,9 +8,7 @@ import android.widget.Toast import androidx.activity.enableEdgeToEdge import androidx.activity.viewModels import androidx.appcompat.app.AppCompatActivity -import androidx.core.view.ViewCompat import androidx.core.view.WindowCompat -import androidx.core.view.WindowInsetsCompat import com.alya.ecommerce_serang.data.api.dto.FcmReq import com.alya.ecommerce_serang.data.api.retrofit.ApiConfig import com.alya.ecommerce_serang.data.repository.Result @@ -43,20 +41,18 @@ class LoginActivity : AppCompatActivity() { setContentView(binding.root) WindowCompat.setDecorFitsSystemWindows(window, false) - enableEdgeToEdge() - // Apply insets to your root layout - ViewCompat.setOnApplyWindowInsetsListener(binding.root) { view, windowInsets -> - val systemBars = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars()) - view.setPadding( - systemBars.left, - systemBars.top, - systemBars.right, - systemBars.bottom - ) - windowInsets - } +// 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 diff --git a/app/src/main/java/com/alya/ecommerce_serang/ui/auth/RegisterActivity.kt b/app/src/main/java/com/alya/ecommerce_serang/ui/auth/RegisterActivity.kt index 04b5780..8a2c0a8 100644 --- a/app/src/main/java/com/alya/ecommerce_serang/ui/auth/RegisterActivity.kt +++ b/app/src/main/java/com/alya/ecommerce_serang/ui/auth/RegisterActivity.kt @@ -43,24 +43,6 @@ class RegisterActivity : AppCompatActivity() { setContentView(binding.root) sessionManager = SessionManager(this) - WindowCompat.setDecorFitsSystemWindows(window, false) - - enableEdgeToEdge() - - // Apply insets to your root layout - ViewCompat.setOnApplyWindowInsetsListener(binding.root) { view, windowInsets -> - val systemBars = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars()) - view.setPadding( - systemBars.left, - systemBars.top, - systemBars.right, - systemBars.bottom - ) - windowInsets - } - - - Log.d("RegisterActivity", "Token in storage: '${sessionManager.getToken()}'") Log.d("RegisterActivity", "User ID in storage: '${sessionManager.getUserId()}'") @@ -104,7 +86,7 @@ class RegisterActivity : AppCompatActivity() { } } - // Function to navigate to the next fragment + // navigate step register in fragment fun navigateToStep(step: Int, userData: RegisterRequest?) { val fragment = when (step) { 1 -> RegisterStep1Fragment.newInstance() diff --git a/app/src/main/java/com/alya/ecommerce_serang/ui/auth/fragments/RegisterStep1Fragment.kt b/app/src/main/java/com/alya/ecommerce_serang/ui/auth/fragments/RegisterStep1Fragment.kt index 7e1eb62..814a366 100644 --- a/app/src/main/java/com/alya/ecommerce_serang/ui/auth/fragments/RegisterStep1Fragment.kt +++ b/app/src/main/java/com/alya/ecommerce_serang/ui/auth/fragments/RegisterStep1Fragment.kt @@ -204,6 +204,13 @@ class RegisterStep1Fragment : Fragment() { } } } + + registerViewModel.toastMessage.observe(viewLifecycleOwner){ event -> + //memanggil toast check value email dan phone + event.getContentIfNotHandled()?.let { msg -> + Toast.makeText(requireContext(), msg, Toast.LENGTH_SHORT).show() + } + } } private fun validateAndProceed() { diff --git a/app/src/main/java/com/alya/ecommerce_serang/ui/auth/fragments/RegisterStep2Fragment.kt b/app/src/main/java/com/alya/ecommerce_serang/ui/auth/fragments/RegisterStep2Fragment.kt index ecf2a66..15e3c22 100644 --- a/app/src/main/java/com/alya/ecommerce_serang/ui/auth/fragments/RegisterStep2Fragment.kt +++ b/app/src/main/java/com/alya/ecommerce_serang/ui/auth/fragments/RegisterStep2Fragment.kt @@ -252,15 +252,10 @@ class RegisterStep2Fragment : Fragment() { sessionManager.saveToken(accessToken) Log.d(TAG, "Token saved to SessionManager: $accessToken") - // Also save user ID if available in the login response -// result.data.?.let { userId -> -// sessionManager.saveUserId(userId) -// } - - Log.d(TAG, "Login successful, token saved: $accessToken") - // Proceed to Step 3 Log.d(TAG, "Proceeding to Step 3 after successful login") + + // call navigate register step from activity (activity as? RegisterActivity)?.navigateToStep(3, null ) } is Result.Error -> { @@ -270,7 +265,7 @@ class RegisterStep2Fragment : Fragment() { // Show error message but continue to Step 3 anyway Log.e(TAG, "Login failed but proceeding to Step 3", result.exception) - Toast.makeText(requireContext(), "Gagal login, namun berhasil membuat akun", Toast.LENGTH_SHORT).show() + Toast.makeText(requireContext(), "Berhasil membuat akun, namun belum login", Toast.LENGTH_SHORT).show() // Proceed to Step 3 (activity as? RegisterActivity)?.navigateToStep(3, null) diff --git a/app/src/main/java/com/alya/ecommerce_serang/ui/cart/CartActivity.kt b/app/src/main/java/com/alya/ecommerce_serang/ui/cart/CartActivity.kt index 09b10cc..fe0d9b3 100644 --- a/app/src/main/java/com/alya/ecommerce_serang/ui/cart/CartActivity.kt +++ b/app/src/main/java/com/alya/ecommerce_serang/ui/cart/CartActivity.kt @@ -1,6 +1,7 @@ package com.alya.ecommerce_serang.ui.cart import android.os.Bundle +import android.util.Log import android.view.View import android.widget.Toast import androidx.activity.enableEdgeToEdge @@ -153,7 +154,8 @@ class CartActivity : AppCompatActivity() { } viewModel.isLoading.observe(this) { isLoading -> - // Show/hide loading indicator if needed + binding.progressBarCart?.visibility = if (isLoading) View.VISIBLE else View.GONE + Log.d("CartActivity", "Loading state: $isLoading") } viewModel.errorMessage.observe(this) { errorMessage -> diff --git a/app/src/main/java/com/alya/ecommerce_serang/ui/chat/ChatActivity.kt b/app/src/main/java/com/alya/ecommerce_serang/ui/chat/ChatActivity.kt index 92c3322..e677422 100644 --- a/app/src/main/java/com/alya/ecommerce_serang/ui/chat/ChatActivity.kt +++ b/app/src/main/java/com/alya/ecommerce_serang/ui/chat/ChatActivity.kt @@ -129,6 +129,7 @@ class ChatActivity : AppCompatActivity() { return } + // set up data toko binding.tvStoreName.text = storeName val fullImageUrl = when (val img = storeImg) { is String -> { @@ -142,7 +143,7 @@ class ChatActivity : AppCompatActivity() { .placeholder(R.drawable.placeholder_image) .into(binding.imgProfile) - // Set chat parameters to ViewModel + // Set chat parameter to send to ViewModel with product viewModel.setChatParameters( storeId = storeId, productId = productId, @@ -159,10 +160,12 @@ class ChatActivity : AppCompatActivity() { } // Setup UI components + // rv isi chat setupRecyclerView() setupWindowInsets() setupListeners() setupTypingIndicator() + // observe listener from viewmodel observeViewModel() // If opened from ChatListFragment with a valid chatRoomId diff --git a/app/src/main/java/com/alya/ecommerce_serang/ui/chat/ChatListFragment.kt b/app/src/main/java/com/alya/ecommerce_serang/ui/chat/ChatListFragment.kt index ed2aa87..923ad50 100644 --- a/app/src/main/java/com/alya/ecommerce_serang/ui/chat/ChatListFragment.kt +++ b/app/src/main/java/com/alya/ecommerce_serang/ui/chat/ChatListFragment.kt @@ -1,6 +1,7 @@ package com.alya.ecommerce_serang.ui.chat import android.os.Bundle +import android.util.Log import android.view.LayoutInflater import android.view.View import android.view.ViewGroup @@ -55,31 +56,44 @@ class ChatListFragment : Fragment() { viewModel.chatList.observe(viewLifecycleOwner) { result -> when (result) { is Result.Success -> { - val adapter = ChatListAdapter(result.data) { chatItem -> - // Use the ChatActivity.createIntent factory method for proper navigation - ChatActivity.createIntent( - context = requireActivity(), - storeId = chatItem.storeId, - productId = 0, // Default value since we don't have it in ChatListItem - productName = null, // Null is acceptable as per ChatActivity - productPrice = "", - productImage = null, - productRating = null, - storeName = chatItem.storeName, - chatRoomId = chatItem.chatRoomId, - storeImage = chatItem.storeImage - ) + val data = result.data + + binding.tvEmptyChat.visibility = View.GONE + if (data.isNotEmpty()) { + val adapter = ChatListAdapter(data) { chatItem -> + ChatActivity.createIntent( + context = requireActivity(), + storeId = chatItem.storeId, + productId = 0, + productName = null, + productPrice = "", + productImage = null, + productRating = null, + storeName = chatItem.storeName, + chatRoomId = chatItem.chatRoomId, + storeImage = chatItem.storeImage + ) + } + binding.chatListRecyclerView.adapter = adapter + } else { + binding.tvEmptyChat.visibility = View.VISIBLE } - binding.chatListRecyclerView.adapter = adapter } is Result.Error -> { + binding.tvEmptyChat.visibility = View.VISIBLE Toast.makeText(requireContext(), "Failed to load chats", Toast.LENGTH_SHORT).show() } Result.Loading -> { + binding.progressBarChat.visibility = View.VISIBLE // Optional: show progress bar } } } + //loading chat list + viewModel.isLoading.observe(viewLifecycleOwner) { isLoading -> + binding.progressBarChat?.visibility = if (isLoading) View.VISIBLE else View.GONE + Log.d(TAG, "Loading state: $isLoading") + } } @@ -89,6 +103,6 @@ class ChatListFragment : Fragment() { } companion object{ - + private var TAG = "ChatListFragment" } } \ No newline at end of file diff --git a/app/src/main/java/com/alya/ecommerce_serang/ui/chat/ChatViewModel.kt b/app/src/main/java/com/alya/ecommerce_serang/ui/chat/ChatViewModel.kt index 108993f..8a496cb 100644 --- a/app/src/main/java/com/alya/ecommerce_serang/ui/chat/ChatViewModel.kt +++ b/app/src/main/java/com/alya/ecommerce_serang/ui/chat/ChatViewModel.kt @@ -60,6 +60,9 @@ class ChatViewModel @Inject constructor( private val _state = MutableLiveData(ChatUiState()) val state: LiveData = _state + private val _isLoading = MutableLiveData() + val isLoading: LiveData = _isLoading + val _chatRoomId = MutableLiveData(0) val chatRoomId: LiveData = _chatRoomId @@ -94,12 +97,15 @@ class ChatViewModel @Inject constructor( } private fun initializeUser() { + _isLoading.value = true viewModelScope.launch { Log.d(TAG, "Initializing user session...") when (val result = chatRepository.fetchUserProfile()) { is Result.Success -> { currentUserId = result.data?.userId + _isLoading.value = false + Log.d(TAG, "User session initialized - User ID: $currentUserId") if (currentUserId == null || currentUserId == 0) { @@ -111,10 +117,12 @@ class ChatViewModel @Inject constructor( } } is Result.Error -> { + _isLoading.value = false Log.e(TAG, "Failed to fetch user profile: ${result.exception.message}") updateState { it.copy(error = "User authentication error. Please login again.") } } is Result.Loading -> { + _isLoading.value = true Log.d(TAG, "Loading user profile...") } } @@ -335,10 +343,13 @@ class ChatViewModel @Inject constructor( } fun getChatList() { + _isLoading.value = true Log.d(TAG, "Getting chat list...") viewModelScope.launch { - _chatList.value = Result.Loading +// _chatList.value = Result.Loading _chatList.value = chatRepository.getListChat() + _isLoading.value = false + } } diff --git a/app/src/main/java/com/alya/ecommerce_serang/ui/home/HomeFragment.kt b/app/src/main/java/com/alya/ecommerce_serang/ui/home/HomeFragment.kt index dba398a..8bbfbf4 100644 --- a/app/src/main/java/com/alya/ecommerce_serang/ui/home/HomeFragment.kt +++ b/app/src/main/java/com/alya/ecommerce_serang/ui/home/HomeFragment.kt @@ -208,25 +208,6 @@ class HomeFragment : Fragment() { private fun initUi() { // For LightStatusBar setLightStatusBar() -// val banners = binding.banners -// banners.offscreenPageLimit = 1 -// -// val nextItemVisiblePx = resources.getDimension(R.dimen.viewpager_next_item_visible) -// val currentItemHorizontalMarginPx = -// resources.getDimension(R.dimen.viewpager_current_item_horizontal_margin) -// val pageTranslationX = nextItemVisiblePx + currentItemHorizontalMarginPx -// -// banners.setPageTransformer { page, position -> -// page.translationX = -pageTranslationX * position -// page.scaleY = 1 - (0.25f * kotlin.math.abs(position)) -// } -// -// banners.addItemDecoration( -// HorizontalMarginItemDecoration( -// requireContext(), -// R.dimen.viewpager_current_item_horizontal_margin -// ) -// ) } private fun handleProductClick(product: ProductsItem) { @@ -248,8 +229,4 @@ class HomeFragment : Fragment() { categoryAdapter = null _binding = null } - -// private fun showLoading(isLoading: Boolean) { -// binding.progressBar.isVisible = isLoading -// } } \ No newline at end of file diff --git a/app/src/main/java/com/alya/ecommerce_serang/ui/order/CheckoutActivity.kt b/app/src/main/java/com/alya/ecommerce_serang/ui/order/CheckoutActivity.kt index 9f4e7e4..79608f9 100644 --- a/app/src/main/java/com/alya/ecommerce_serang/ui/order/CheckoutActivity.kt +++ b/app/src/main/java/com/alya/ecommerce_serang/ui/order/CheckoutActivity.kt @@ -4,6 +4,7 @@ import android.content.Context import android.content.Intent import android.os.Bundle import android.util.Log +import android.view.View import android.view.ViewGroup import android.widget.TextView import android.widget.Toast @@ -110,11 +111,6 @@ class CheckoutActivity : AppCompatActivity() { finish() } } - -// viewModel.getPaymentMethods { paymentMethods -> -// // Logging is just for debugging -// Log.d("CheckoutActivity", "Loaded ${paymentMethods.size} payment methods") -// } } private fun setupToolbar() { @@ -165,7 +161,7 @@ class CheckoutActivity : AppCompatActivity() { // Observe loading state viewModel.isLoading.observe(this) { isLoading -> binding.btnPay.isEnabled = !isLoading - // Show/hide loading indicator if you have one + } // Observe error messages @@ -273,10 +269,14 @@ class CheckoutActivity : AppCompatActivity() { private fun updateShippingUI(shipName: String, shipService: String, shipEtd: String, shipPrice: Int) { if (shipName.isNotEmpty() && shipService.isNotEmpty()) { // Display shipping name and service in one line + binding.cardShipment.visibility = View.VISIBLE + binding.tvCourierName.text = "$shipName $shipService" binding.tvDeliveryEstimate.text = "$shipEtd hari kerja" binding.tvShippingPrice.text = formatCurrency(shipPrice.toDouble()) binding.rbJne.isChecked = true + } else { + binding.cardShipment.visibility = View.GONE } } diff --git a/app/src/main/java/com/alya/ecommerce_serang/ui/order/history/detailorder/DetailOrderStatusActivity.kt b/app/src/main/java/com/alya/ecommerce_serang/ui/order/history/detailorder/DetailOrderStatusActivity.kt index 00d3441..0b3f940 100644 --- a/app/src/main/java/com/alya/ecommerce_serang/ui/order/history/detailorder/DetailOrderStatusActivity.kt +++ b/app/src/main/java/com/alya/ecommerce_serang/ui/order/history/detailorder/DetailOrderStatusActivity.kt @@ -44,6 +44,9 @@ import com.google.gson.Gson import java.io.File import java.text.NumberFormat import java.text.SimpleDateFormat +import java.time.Instant +import java.time.ZoneId +import java.time.format.DateTimeFormatter import java.util.Calendar import java.util.Locale import java.util.TimeZone @@ -197,12 +200,12 @@ class DetailOrderStatusActivity : AppCompatActivity() { Log.d(TAG, "populateOrderDetails: Payment method=${orders.payInfoName ?: "Tidak tersedia"}") // Set subtotal, shipping cost, and total - val subtotal = orders.totalAmount?.minus(orders.shipmentPrice.toIntOrNull() ?: 0) ?: 0 - binding.tvSubtotal.text = formatCurrency(subtotal.toDouble()) +// val subtotal = orders.totalAmount?.minus(orders.shipmentPrice.toDouble() ?: 0) ?: 0 +// binding.tvSubtotal.text = formatCurrency(subtotal.toDouble()) binding.tvShippingCost.text = formatCurrency(orders.shipmentPrice.toDouble()) binding.tvTotal.text = formatCurrency(orders.totalAmount?.toDouble() ?: 0.00) - Log.d(TAG, "populateOrderDetails: Subtotal=$subtotal, Shipping=${orders.shipmentPrice}, Total=${orders.totalAmount}") + Log.d(TAG, "populateOrderDetails: Subtotal=, Shipping=${orders.shipmentPrice}, Total=${orders.totalAmount}") // Adjust buttons based on order status Log.d(TAG, "populateOrderDetails: Adjusting buttons for status=$orderStatus") @@ -223,6 +226,11 @@ class DetailOrderStatusActivity : AppCompatActivity() { this.adapter = adapter } adapter.submitList(orderItems) + + // get data from ordetlistitemsitem untuk ambil subtotal nya dan dijumlahkan + val subtotalSum = orderItems.sumOf { it.subtotal } + binding.tvSubtotal.text = formatCurrency(subtotalSum.toDouble()) + } private fun adjustButtonsBasedOnStatus(orders: Orders, status: String) { @@ -287,7 +295,7 @@ class DetailOrderStatusActivity : AppCompatActivity() { // Show status note binding.tvStatusHeader.text = "Sudah Dibayar" binding.tvStatusNote.visibility = View.VISIBLE - binding.tvStatusNote.text = "Menunggu pesanan dikonfirmasi penjual ${formatDatePay(orders.updatedAt)}" + binding.tvStatusNote.text = "Menunggu pesanan dikonfirmasi penjual ${formatDatePaid(orders.updatedAt)}" binding.tvPaymentDeadlineLabel.text = "Batas konfirmasi penjual:" binding.tvPaymentDeadline.text = formatDatePaid(orders.updatedAt) @@ -606,32 +614,17 @@ class DetailOrderStatusActivity : AppCompatActivity() { } private fun formatDate(dateString: String): String { - Log.d(TAG, "formatDate: Formatting date: $dateString") - return try { - val inputFormat = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.getDefault()) - inputFormat.timeZone = TimeZone.getTimeZone("UTC") + val jakarta = ZoneId.of("Asia/Jakarta") + val instant = Instant.parse(dateString) // parses ISO‑8601 with ‘Z’ + val zoned = instant.atZone(jakarta) - val timeFormat = SimpleDateFormat("HH:mm", Locale("id", "ID")) - val dateFormat = SimpleDateFormat("dd MMMM yyyy", Locale("id", "ID")) + val time = DateTimeFormatter.ofPattern("HH:mm", Locale("id", "ID")).format(zoned) + val date = DateTimeFormatter.ofPattern("dd MMMM yyyy",Locale("id", "ID")).format(zoned) - val date = inputFormat.parse(dateString) - - date?.let { - val calendar = Calendar.getInstance() - calendar.time = it - calendar.set(Calendar.HOUR_OF_DAY, 23) - calendar.set(Calendar.MINUTE, 59) - - val timePart = timeFormat.format(calendar.time) - val datePart = dateFormat.format(calendar.time) - - val formatted = "$timePart\n$datePart" - Log.d(TAG, "formatDate: Formatted date: $formatted") - formatted - } ?: dateString + "$time\n$date" } catch (e: Exception) { - Log.e(TAG, "formatDate: Error formatting date: ${e.message}", e) + Log.e(TAG, "formatDate: $e") dateString } } diff --git a/app/src/main/java/com/alya/ecommerce_serang/utils/viewmodel/RegisterViewModel.kt b/app/src/main/java/com/alya/ecommerce_serang/utils/viewmodel/RegisterViewModel.kt index daaed9d..7cddac2 100644 --- a/app/src/main/java/com/alya/ecommerce_serang/utils/viewmodel/RegisterViewModel.kt +++ b/app/src/main/java/com/alya/ecommerce_serang/utils/viewmodel/RegisterViewModel.kt @@ -64,6 +64,9 @@ class RegisterViewModel(private val repository: UserRepository, private val orde private val _registeredUser = MutableLiveData() val registeredUser: LiveData = _registeredUser + private val _toastMessage = MutableLiveData>() + val toastMessage: LiveData> = _toastMessage + // For address data var selectedProvinceId: Int? = null var selectedCityId: String? = null @@ -224,9 +227,16 @@ class RegisterViewModel(private val repository: UserRepository, private val orde Log.d("RegisterViewModel", "OTP Response: ${response.available}") _checkValue.value = Result.Success(response.available)// Store the message for UI feedback + val msg = if (response.available) + "${request.fieldRegis.capitalize()} dapat digunakan" + else + "${request.fieldRegis.capitalize()} sudah terdaftar" + _toastMessage.value = Event(msg) + } catch (exception: Exception) { // Handle any errors and update state _checkValue.value = Result.Error(exception) + _toastMessage.value = Event("Gagal memeriksa ${request.fieldRegis}") // Log the error for debugging Log.e("RegisterViewModel", "Error:", exception) @@ -375,4 +385,10 @@ class RegisterViewModel(private val repository: UserRepository, private val orde companion object { private const val TAG = "RegisterViewModel" } + +} + +class Event(private val data: T) { + private var handled = false + fun getContentIfNotHandled(): T? = if (handled) null else { handled = true; data } } \ No newline at end of file diff --git a/app/src/main/res/layout/activity_cart.xml b/app/src/main/res/layout/activity_cart.xml index 973c8a1..57d1ece 100644 --- a/app/src/main/res/layout/activity_cart.xml +++ b/app/src/main/res/layout/activity_cart.xml @@ -21,6 +21,18 @@ app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/header"/> + + @@ -75,7 +75,7 @@ android:id="@+id/tv_places_address" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:text="Rumah" + android:text="-" android:textColor="#5A5A5A" android:paddingHorizontal="8dp" android:paddingVertical="2dp" @@ -94,7 +94,7 @@ android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" - android:text="Jl. Pegangasan Timur" + android:text="-" android:textSize="14sp" android:layout_marginStart="32dp" /> @@ -179,9 +179,11 @@ diff --git a/app/src/main/res/layout/activity_list_product.xml b/app/src/main/res/layout/activity_list_product.xml index cb0fbff..bb6a49a 100644 --- a/app/src/main/res/layout/activity_list_product.xml +++ b/app/src/main/res/layout/activity_list_product.xml @@ -3,38 +3,48 @@ xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" - android:layout_height="wrap_content" + android:layout_height="match_parent" + android:theme="@style/Theme.Ecommerce_serang" tools:context=".ui.product.listproduct.ListProductActivity"> - + app:layout_constraintTop_toTopOf="parent"> + + + + + + + + + + + + - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/layout/activity_login.xml b/app/src/main/res/layout/activity_login.xml index e73b979..925d062 100644 --- a/app/src/main/res/layout/activity_login.xml +++ b/app/src/main/res/layout/activity_login.xml @@ -1,97 +1,136 @@ - + + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent" + app:layout_constraintBottom_toTopOf="@+id/tv_email_label" + android:layout_marginBottom="48dp" + android:paddingBottom="24dp"/> + + android:layout_marginVertical="8dp" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@id/tv_login_title" + app:layout_constraintEnd_toEndOf="parent" /> + + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@id/tv_email_label" + app:layout_constraintEnd_toEndOf="parent"> + android:inputType="textEmailAddress" /> + + android:layout_marginVertical="8dp" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@id/til_login_email" + app:layout_constraintEnd_toEndOf="parent" /> + + app:passwordToggleEnabled="true" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@id/tv_password_label" + app:layout_constraintEnd_toEndOf="parent"> + android:inputType="textPassword" /> + + android:textColor="@android:color/holo_red_light" + android:layout_marginBottom="16dp" + android:visibility="gone" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintTop_toBottomOf="@id/til_login_password" /> + + app:cornerRadius="8dp" + android:layout_marginVertical="16dp" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintTop_toBottomOf="@id/tv_forgetPassword" /> + + android:orientation="horizontal" + android:layout_marginTop="16dp" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintTop_toBottomOf="@id/btn_login"> + android:text="@string/no_account" /> + android:textStyle="bold" /> - \ No newline at end of file + diff --git a/app/src/main/res/layout/activity_shipping.xml b/app/src/main/res/layout/activity_shipping.xml index fd1c245..7179bea 100644 --- a/app/src/main/res/layout/activity_shipping.xml +++ b/app/src/main/res/layout/activity_shipping.xml @@ -38,5 +38,6 @@ android:layout_marginBottom="8dp" android:visibility="gone" app:layout_constraintTop_toBottomOf="@id/linear_shipment" + app:layout_constraintStart_toStartOf="parent" app:layout_constraintEnd_toEndOf="parent"/> \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_chat_list.xml b/app/src/main/res/layout/fragment_chat_list.xml index 48707ce..69d919e 100644 --- a/app/src/main/res/layout/fragment_chat_list.xml +++ b/app/src/main/res/layout/fragment_chat_list.xml @@ -33,4 +33,23 @@ tools:listitem="@layout/item_chat" app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"/> + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_register_step2.xml b/app/src/main/res/layout/fragment_register_step2.xml index ca89814..2d8ea37 100644 --- a/app/src/main/res/layout/fragment_register_step2.xml +++ b/app/src/main/res/layout/fragment_register_step2.xml @@ -75,7 +75,7 @@ + android:text="Belum menerima kode? " /> + android:layout_height="match_parent" + xmlns:app="http://schemas.android.com/apk/res-auto"> + + \ No newline at end of file