From e7fbace5323b7665ef4d98832086c3691d3417af Mon Sep 17 00:00:00 2001 From: shaulascr Date: Thu, 22 May 2025 04:17:55 +0700 Subject: [PATCH] update ui and detail store --- app/src/main/AndroidManifest.xml | 4 + .../store/orders/OrderListResponse.kt | 2 +- .../data/api/retrofit/ApiService.kt | 2 +- .../data/repository/ProductRepository.kt | 7 +- .../ecommerce_serang/ui/auth/LoginActivity.kt | 29 ++- .../ui/auth/RegisterActivity.kt | 17 ++ .../ui/auth/RegisterStoreActivity.kt | 5 - .../auth/fragments/RegisterStep1Fragment.kt | 4 +- .../auth/fragments/RegisterStep2Fragment.kt | 4 +- .../auth/fragments/RegisterStep3Fragment.kt | 6 +- .../ecommerce_serang/ui/cart/CartActivity.kt | 8 + .../ecommerce_serang/ui/chat/ChatActivity.kt | 5 - .../ui/notif/NotificationActivity.kt | 20 ++ .../ui/order/ShippingActivity.kt | 20 ++ .../ui/order/address/AddAddressActivity.kt | 20 ++ .../ui/order/address/AddressActivity.kt | 32 +++- .../detail/AddEvidencePaymentActivity.kt | 26 ++- .../ui/order/detail/PaymentActivity.kt | 30 ++- .../ui/order/history/HistoryActivity.kt | 21 +++ .../detailorder/DetailOrderStatusActivity.kt | 9 + .../ui/product/DetailProductActivity.kt | 22 ++- .../storeDetail/StoreDetailActivity.kt | 178 ++++++++++++++++++ .../storeDetail/StoreDetailViewModel.kt | 87 +++++++++ .../ui/profile/ProfileFragment.kt | 5 +- .../mystore/sells/SellsListFragment.kt | 4 +- .../utils/viewmodel/ProfileViewModel.kt | 2 +- .../utils/viewmodel/SellsViewModel.kt | 4 +- .../layout/activity_detail_order_status.xml | 13 +- .../res/layout/activity_detail_product.xml | 6 +- app/src/main/res/layout/activity_login.xml | 3 +- app/src/main/res/layout/activity_payment.xml | 9 - app/src/main/res/layout/activity_register.xml | 11 ++ .../main/res/layout/activity_store_detail.xml | 171 +++++++++++++++++ app/src/main/res/layout/fragment_profile.xml | 80 ++++---- .../res/layout/item_order_detail_product.xml | 15 +- app/src/main/res/layout/view_search_back.xml | 54 ++++++ 36 files changed, 819 insertions(+), 116 deletions(-) create mode 100644 app/src/main/java/com/alya/ecommerce_serang/ui/product/storeDetail/StoreDetailActivity.kt create mode 100644 app/src/main/java/com/alya/ecommerce_serang/ui/product/storeDetail/StoreDetailViewModel.kt create mode 100644 app/src/main/res/layout/activity_store_detail.xml create mode 100644 app/src/main/res/layout/view_search_back.xml diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index cecfcb1..c7690ea 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -29,6 +29,9 @@ android:theme="@style/Theme.Ecommerce_serang" android:usesCleartextTraffic="true" tools:targetApi="31"> + @@ -67,6 +70,7 @@ android:enabled="true" android:exported="false" android:foregroundServiceType="dataSync" /> + diff --git a/app/src/main/java/com/alya/ecommerce_serang/data/api/response/store/orders/OrderListResponse.kt b/app/src/main/java/com/alya/ecommerce_serang/data/api/response/store/orders/OrderListResponse.kt index e9b00c3..49ddc36 100644 --- a/app/src/main/java/com/alya/ecommerce_serang/data/api/response/store/orders/OrderListResponse.kt +++ b/app/src/main/java/com/alya/ecommerce_serang/data/api/response/store/orders/OrderListResponse.kt @@ -5,7 +5,7 @@ import com.google.gson.annotations.SerializedName data class OrderListResponse( @field:SerializedName("orders") - val orders: List? = null, + val orders: List, @field:SerializedName("message") val message: String? = null 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 ce83b01..2e1e579 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 @@ -314,7 +314,7 @@ interface ApiService { suspend fun getListProv( ): Response - @GET("order/{status}") + @GET("mystore/orders/{status}") suspend fun getSellList( @Path("status") status: String ): Response diff --git a/app/src/main/java/com/alya/ecommerce_serang/data/repository/ProductRepository.kt b/app/src/main/java/com/alya/ecommerce_serang/data/repository/ProductRepository.kt index cee8bc0..85aae9e 100644 --- a/app/src/main/java/com/alya/ecommerce_serang/data/repository/ProductRepository.kt +++ b/app/src/main/java/com/alya/ecommerce_serang/data/repository/ProductRepository.kt @@ -6,15 +6,14 @@ import com.alya.ecommerce_serang.data.api.dto.CategoryItem import com.alya.ecommerce_serang.data.api.dto.Preorder import com.alya.ecommerce_serang.data.api.dto.ProductsItem import com.alya.ecommerce_serang.data.api.dto.SearchRequest -import com.alya.ecommerce_serang.data.api.response.store.product.CreateProductResponse import com.alya.ecommerce_serang.data.api.response.customer.cart.AddCartResponse import com.alya.ecommerce_serang.data.api.response.customer.product.ProductResponse import com.alya.ecommerce_serang.data.api.response.customer.product.ReviewsItem import com.alya.ecommerce_serang.data.api.response.customer.product.StoreProduct -import com.alya.ecommerce_serang.data.api.response.store.product.UpdateProductResponse import com.alya.ecommerce_serang.data.api.response.product.Search +import com.alya.ecommerce_serang.data.api.response.store.product.CreateProductResponse +import com.alya.ecommerce_serang.data.api.response.store.product.UpdateProductResponse import com.alya.ecommerce_serang.data.api.retrofit.ApiService -import com.alya.ecommerce_serang.utils.SessionManager import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext import okhttp3.MediaType.Companion.toMediaTypeOrNull @@ -119,7 +118,7 @@ class ProductRepository(private val apiService: ApiService) { } } - suspend fun fetchStoreDetail(storeId: Int): Result { + suspend fun fetchStoreDetail(storeId: Int): Result { return try { val response = apiService.getDetailStore(storeId) if (response.isSuccessful) { 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 56e6213..531b526 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,6 +8,9 @@ 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 @@ -35,11 +38,30 @@ class LoginActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - enableEdgeToEdge() binding = ActivityLoginBinding.inflate(layoutInflater) 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 + } + +// onBackPressedDispatcher.addCallback(this) { +// // Handle the back button event +// } + setupListeners() observeLoginState() @@ -59,6 +81,11 @@ class LoginActivity : AppCompatActivity() { loginViewModel.login(email, password) } } + + binding.tvRegistrasi.setOnClickListener{ + startActivity(Intent(this, RegisterActivity::class.java)) + finish() + } } private fun observeLoginState() { 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 e399590..c8f6585 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 @@ -42,6 +42,23 @@ class RegisterActivity : AppCompatActivity() { binding = ActivityRegisterBinding.inflate(layoutInflater) 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()}'") 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 b7954af..32e36b5 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 @@ -63,22 +63,17 @@ class RegisterStoreActivity : AppCompatActivity() { } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - Log.d(TAG, "onCreate: Starting RegisterStoreActivity") binding = ActivityRegisterStoreBinding.inflate(layoutInflater) setContentView(binding.root) sessionManager = SessionManager(this) - Log.d(TAG, "onCreate: SessionManager initialized") WindowCompat.setDecorFitsSystemWindows(window, false) - Log.d(TAG, "onCreate: Window decoration set") enableEdgeToEdge() - Log.d(TAG, "onCreate: Edge-to-edge enabled") // Apply insets to your root layout ViewCompat.setOnApplyWindowInsetsListener(binding.root) { view, windowInsets -> - Log.d(TAG, "onCreate: Applying window insets") val systemBars = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars()) view.setPadding( systemBars.left, 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 911d2e5..7e1eb62 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 @@ -64,9 +64,9 @@ class RegisterStep1Fragment : Fragment() { // Set step progress and description (activity as? RegisterActivity)?.let { it.findViewById(R.id.registration_progress)?.progress = 33 - it.findViewById(R.id.tv_step_title)?.text = "Step 1: Account & Personal Info" + it.findViewById(R.id.tv_step_title)?.text = "Step 1: Informasi Akun" it.findViewById(R.id.tv_step_description)?.text = - "Fill in your account and personal details to create your profile." + "Masukkan data pengguna dengan data yang valid." } setupFieldValidations() 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 e464524..e7e5bb6 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 @@ -70,9 +70,9 @@ class RegisterStep2Fragment : Fragment() { // Set step progress and description (activity as? RegisterActivity)?.let { it.findViewById(R.id.registration_progress)?.progress = 66 - it.findViewById(R.id.tv_step_title)?.text = "Step 2: Verify Your Email" + it.findViewById(R.id.tv_step_title)?.text = "Step 2: Masukkan Kode OTP" it.findViewById(R.id.tv_step_description)?.text = - "Enter the verification code sent to your email to continue." + "Cek email untuk melihat kode OTP. Pastikan email yang digunakan aktif." Log.d(TAG, "Step indicators updated to Step 2") } diff --git a/app/src/main/java/com/alya/ecommerce_serang/ui/auth/fragments/RegisterStep3Fragment.kt b/app/src/main/java/com/alya/ecommerce_serang/ui/auth/fragments/RegisterStep3Fragment.kt index e44392f..ec34458 100644 --- a/app/src/main/java/com/alya/ecommerce_serang/ui/auth/fragments/RegisterStep3Fragment.kt +++ b/app/src/main/java/com/alya/ecommerce_serang/ui/auth/fragments/RegisterStep3Fragment.kt @@ -70,10 +70,10 @@ class RegisterStep3Fragment : Fragment() { // Set step progress and description (activity as? RegisterActivity)?.let { - it.findViewById(R.id.registration_progress)?.progress = 33 - it.findViewById(R.id.tv_step_title)?.text = "Step 1: Account & Personal Info" + it.findViewById(R.id.registration_progress)?.progress = 100 + it.findViewById(R.id.tv_step_title)?.text = "Step 3: Tambahkan Alamat" it.findViewById(R.id.tv_step_description)?.text = - "Fill in your account and personal details to create your profile." + "Masukkan alamat untuk menerima pesanan." Log.d(TAG, "Step indicators updated to Step 1") } 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 fdf0597..09b10cc 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 @@ -60,12 +60,20 @@ class CartActivity : AppCompatActivity() { windowInsets } + setupToolbar() setupRecyclerView() setupListeners() observeViewModel() viewModel.getCart() } + private fun setupToolbar(){ + binding.header.headerLeftIcon.setOnClickListener{ + finish() + } + binding.header.headerTitle.text = "Keranjang" + } + private fun setupRecyclerView() { storeAdapter = StoreAdapter( onStoreCheckChanged = { storeId, isChecked -> 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 0d61401..453c9b2 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 @@ -59,11 +59,6 @@ class ChatActivity : AppCompatActivity() { // For image attachment private var tempImageUri: Uri? = null -// // Chat parameters from intent -// private var chatRoomId: Int = 0 -// private var storeId: Int = 0 -// private var productId: Int = 0 - // Typing indicator handler private val typingHandler = android.os.Handler(android.os.Looper.getMainLooper()) private val stopTypingRunnable = Runnable { diff --git a/app/src/main/java/com/alya/ecommerce_serang/ui/notif/NotificationActivity.kt b/app/src/main/java/com/alya/ecommerce_serang/ui/notif/NotificationActivity.kt index cef7ec9..060d3be 100644 --- a/app/src/main/java/com/alya/ecommerce_serang/ui/notif/NotificationActivity.kt +++ b/app/src/main/java/com/alya/ecommerce_serang/ui/notif/NotificationActivity.kt @@ -3,8 +3,12 @@ package com.alya.ecommerce_serang.ui.notif import android.os.Bundle import android.util.Log import android.view.View +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 androidx.recyclerview.widget.LinearLayoutManager import com.alya.ecommerce_serang.data.repository.Result import com.alya.ecommerce_serang.databinding.ActivityNotificationBinding @@ -30,6 +34,22 @@ class NotificationActivity : AppCompatActivity() { binding = ActivityNotificationBinding.inflate(layoutInflater) 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 + } + setupToolbar() setupAdapters() setupTabLayout() diff --git a/app/src/main/java/com/alya/ecommerce_serang/ui/order/ShippingActivity.kt b/app/src/main/java/com/alya/ecommerce_serang/ui/order/ShippingActivity.kt index 1d08e8f..82bcde9 100644 --- a/app/src/main/java/com/alya/ecommerce_serang/ui/order/ShippingActivity.kt +++ b/app/src/main/java/com/alya/ecommerce_serang/ui/order/ShippingActivity.kt @@ -5,8 +5,12 @@ import android.os.Bundle import android.util.Log import android.view.View 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 androidx.recyclerview.widget.LinearLayoutManager import com.alya.ecommerce_serang.data.api.retrofit.ApiConfig import com.alya.ecommerce_serang.data.repository.OrderRepository @@ -37,6 +41,22 @@ class ShippingActivity : AppCompatActivity() { // Initialize SessionManager 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 + } + // Get data from intent val addressId = intent.getIntExtra(EXTRA_ADDRESS_ID, 0) val productId = intent.getIntExtra(EXTRA_PRODUCT_ID, 0) 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 4de34df..9d9c4a3 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 @@ -13,10 +13,14 @@ import android.provider.Settings import android.util.Log import android.view.View import android.widget.Toast +import androidx.activity.enableEdgeToEdge import androidx.activity.result.contract.ActivityResultContracts import androidx.activity.viewModels import androidx.appcompat.app.AlertDialog 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.CreateAddressRequest import com.alya.ecommerce_serang.data.api.dto.UserProfile import com.alya.ecommerce_serang.data.api.response.customer.order.CitiesItem @@ -61,6 +65,22 @@ class AddAddressActivity : AppCompatActivity() { apiService = ApiConfig.getApiService(sessionManager) locationManager = getSystemService(LOCATION_SERVICE) as LocationManager + 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 + } + // Get user profile from session manager // profileUser =UserProfile. viewModel.userProfile.observe(this){ user -> diff --git a/app/src/main/java/com/alya/ecommerce_serang/ui/order/address/AddressActivity.kt b/app/src/main/java/com/alya/ecommerce_serang/ui/order/address/AddressActivity.kt index 7b5a585..edd0a5a 100644 --- a/app/src/main/java/com/alya/ecommerce_serang/ui/order/address/AddressActivity.kt +++ b/app/src/main/java/com/alya/ecommerce_serang/ui/order/address/AddressActivity.kt @@ -2,8 +2,12 @@ package com.alya.ecommerce_serang.ui.order.address import android.content.Intent import android.os.Bundle +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 androidx.core.view.isVisible import androidx.recyclerview.widget.LinearLayoutManager import com.alya.ecommerce_serang.data.api.retrofit.ApiConfig @@ -32,6 +36,22 @@ class AddressActivity : AppCompatActivity() { 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 + } + setupToolbar() setupRecyclerView() @@ -40,19 +60,17 @@ class AddressActivity : AppCompatActivity() { viewModel.fetchAddresses() } - private fun addAddressClicked(){ - binding.addAddressClick.setOnClickListener{ - val intent = Intent(this, AddAddressActivity::class.java) - startActivity(intent) - } - } private fun setupToolbar() { // Remove duplicate toolbar setup - addAddressClicked() binding.toolbar.setNavigationOnClickListener { onBackPressedWithResult() } + + binding.addAddressClick.setOnClickListener{ + val intent = Intent(this, AddAddressActivity::class.java) + startActivity(intent) + } } private fun setupRecyclerView() { diff --git a/app/src/main/java/com/alya/ecommerce_serang/ui/order/detail/AddEvidencePaymentActivity.kt b/app/src/main/java/com/alya/ecommerce_serang/ui/order/detail/AddEvidencePaymentActivity.kt index 62dea9d..77d4e91 100644 --- a/app/src/main/java/com/alya/ecommerce_serang/ui/order/detail/AddEvidencePaymentActivity.kt +++ b/app/src/main/java/com/alya/ecommerce_serang/ui/order/detail/AddEvidencePaymentActivity.kt @@ -13,11 +13,15 @@ import android.webkit.MimeTypeMap import android.widget.AdapterView import android.widget.ArrayAdapter import android.widget.Toast +import androidx.activity.enableEdgeToEdge import androidx.activity.result.contract.ActivityResultContracts import androidx.activity.viewModels import androidx.appcompat.app.AppCompatActivity import androidx.core.app.ActivityCompat import androidx.core.content.ContextCompat +import androidx.core.view.ViewCompat +import androidx.core.view.WindowCompat +import androidx.core.view.WindowInsetsCompat import com.alya.ecommerce_serang.data.api.dto.AddEvidenceMultipartRequest import com.alya.ecommerce_serang.data.api.retrofit.ApiConfig import com.alya.ecommerce_serang.data.repository.OrderRepository @@ -81,14 +85,32 @@ class AddEvidencePaymentActivity : AppCompatActivity() { } + 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 + } + + binding.toolbar.navigationIcon.apply { + onBackPressed() + } + setupUI() viewModel.getOrderDetails(orderId) setupListeners() setupObservers() - - } private fun setupUI() { diff --git a/app/src/main/java/com/alya/ecommerce_serang/ui/order/detail/PaymentActivity.kt b/app/src/main/java/com/alya/ecommerce_serang/ui/order/detail/PaymentActivity.kt index fbe1010..72f824e 100644 --- a/app/src/main/java/com/alya/ecommerce_serang/ui/order/detail/PaymentActivity.kt +++ b/app/src/main/java/com/alya/ecommerce_serang/ui/order/detail/PaymentActivity.kt @@ -4,9 +4,13 @@ import android.content.Intent import android.os.Bundle import android.util.Log import android.widget.Toast +import androidx.activity.enableEdgeToEdge import androidx.activity.viewModels import androidx.appcompat.app.AlertDialog 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.retrofit.ApiConfig import com.alya.ecommerce_serang.data.repository.OrderRepository import com.alya.ecommerce_serang.databinding.ActivityPaymentBinding @@ -39,6 +43,22 @@ class PaymentActivity : AppCompatActivity() { 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 + } + // Mengambil data dari intent val orderId = intent.getIntExtra("ORDER_ID", 0) val paymentInfoId = intent.getIntExtra("ORDER_PAYMENT_ID", 0) @@ -50,6 +70,7 @@ class PaymentActivity : AppCompatActivity() { // Setup toolbar binding.toolbar.setNavigationOnClickListener { + onBackPressedDispatcher finish() } @@ -75,15 +96,6 @@ class PaymentActivity : AppCompatActivity() { startActivity(intent) } - - // Setup button negosiasi harga - binding.btnNegotiatePrice.setOnClickListener { - // Intent ke activity negosiasi harga -// val intent = Intent(this, NegotiatePriceActivity::class.java) -// intent.putExtra("ORDER_ID", orderId) -// startActivity(intent) - } - // Observe data observeData() diff --git a/app/src/main/java/com/alya/ecommerce_serang/ui/order/history/HistoryActivity.kt b/app/src/main/java/com/alya/ecommerce_serang/ui/order/history/HistoryActivity.kt index fdc7f1d..139f894 100644 --- a/app/src/main/java/com/alya/ecommerce_serang/ui/order/history/HistoryActivity.kt +++ b/app/src/main/java/com/alya/ecommerce_serang/ui/order/history/HistoryActivity.kt @@ -1,8 +1,12 @@ package com.alya.ecommerce_serang.ui.order.history import android.os.Bundle +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 androidx.fragment.app.commit import com.alya.ecommerce_serang.R import com.alya.ecommerce_serang.data.api.retrofit.ApiConfig @@ -31,6 +35,22 @@ class HistoryActivity : AppCompatActivity() { 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 + } + setupToolbar() if (savedInstanceState == null) { @@ -44,6 +64,7 @@ class HistoryActivity : AppCompatActivity() { binding.btnBack.setOnClickListener { onBackPressed() + finish() } } 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 7eb7341..4e5d6b4 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 @@ -106,12 +106,21 @@ class DetailOrderStatusActivity : AppCompatActivity() { return } + setupToolbar() setupObservers() loadOrderDetails() Log.d(TAG, "onCreate: Activity initialization completed") } + private fun setupToolbar(){ + binding.header.headerLeftIcon.setOnClickListener{ + finish() + } + + binding.header.headerTitle.text = "Detail Pesanan" + } + private fun setupObservers() { Log.d(TAG, "setupObservers: Setting up LiveData observers") diff --git a/app/src/main/java/com/alya/ecommerce_serang/ui/product/DetailProductActivity.kt b/app/src/main/java/com/alya/ecommerce_serang/ui/product/DetailProductActivity.kt index 23d27da..83d156c 100644 --- a/app/src/main/java/com/alya/ecommerce_serang/ui/product/DetailProductActivity.kt +++ b/app/src/main/java/com/alya/ecommerce_serang/ui/product/DetailProductActivity.kt @@ -33,6 +33,7 @@ import com.alya.ecommerce_serang.ui.cart.CartActivity import com.alya.ecommerce_serang.ui.chat.ChatActivity import com.alya.ecommerce_serang.ui.home.HorizontalProductAdapter import com.alya.ecommerce_serang.ui.order.CheckoutActivity +import com.alya.ecommerce_serang.ui.product.storeDetail.StoreDetailActivity import com.alya.ecommerce_serang.utils.BaseViewModelFactory import com.alya.ecommerce_serang.utils.SessionManager import com.bumptech.glide.Glide @@ -185,12 +186,13 @@ class DetailProductActivity : AppCompatActivity() { binding.recyclerViewOtherProducts.visibility = View.VISIBLE binding.tvViewAllProducts.visibility = View.VISIBLE productAdapter?.updateProducts(products) - } } + } + } private fun setupUI() { -// binding.btnBack.setOnClickListener { -// finish() -// } + binding.searchContainer.btnBack.setOnClickListener { + finish() + } binding.tvViewAllReviews.setOnClickListener { viewModel.productDetail.value?.productId?.let { productId -> @@ -198,8 +200,6 @@ class DetailProductActivity : AppCompatActivity() { } } - - val searchContainerView = binding.searchContainer searchContainerView.btnCart.setOnClickListener{ navigateToCart() @@ -244,6 +244,10 @@ class DetailProductActivity : AppCompatActivity() { } } + binding.containerStoreDetail.setOnClickListener{ + handleStoreClick(product) + } + binding.btnAddToCart.setOnClickListener { viewModel.productDetail.value?.productId?.let { id -> showAddToCartPopup(id) @@ -317,6 +321,12 @@ class DetailProductActivity : AppCompatActivity() { startActivity(intent) } + private fun handleStoreClick(product: Product) { + val intent = Intent(this, StoreDetailActivity::class.java) + intent.putExtra("STORE_ID", product.storeId) // Pass product ID + startActivity(intent) + } + private fun showBuyNowPopup(productId: Int) { showQuantityDialog(productId, true) } diff --git a/app/src/main/java/com/alya/ecommerce_serang/ui/product/storeDetail/StoreDetailActivity.kt b/app/src/main/java/com/alya/ecommerce_serang/ui/product/storeDetail/StoreDetailActivity.kt new file mode 100644 index 0000000..c51e925 --- /dev/null +++ b/app/src/main/java/com/alya/ecommerce_serang/ui/product/storeDetail/StoreDetailActivity.kt @@ -0,0 +1,178 @@ +package com.alya.ecommerce_serang.ui.product.storeDetail + +import android.content.Intent +import android.os.Bundle +import android.util.Log +import android.view.View +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 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.dto.ProductsItem +import com.alya.ecommerce_serang.data.api.response.customer.product.StoreProduct +import com.alya.ecommerce_serang.data.api.retrofit.ApiConfig +import com.alya.ecommerce_serang.data.api.retrofit.ApiService +import com.alya.ecommerce_serang.data.repository.ProductRepository +import com.alya.ecommerce_serang.data.repository.Result +import com.alya.ecommerce_serang.databinding.ActivityStoreDetailBinding +import com.alya.ecommerce_serang.ui.cart.CartActivity +import com.alya.ecommerce_serang.ui.home.HorizontalProductAdapter +import com.alya.ecommerce_serang.ui.product.DetailProductActivity +import com.alya.ecommerce_serang.utils.BaseViewModelFactory +import com.alya.ecommerce_serang.utils.SessionManager +import com.bumptech.glide.Glide + +class StoreDetailActivity : AppCompatActivity() { + private lateinit var binding: ActivityStoreDetailBinding + private lateinit var apiService: ApiService + private lateinit var sessionManager: SessionManager + private var productAdapter: HorizontalProductAdapter? = null + + private val viewModel: StoreDetailViewModel by viewModels { + BaseViewModelFactory { + val apiService = ApiConfig.getApiService(sessionManager) + val productRepository = ProductRepository(apiService) + StoreDetailViewModel(productRepository) + } + } + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + binding = ActivityStoreDetailBinding.inflate(layoutInflater) + setContentView(binding.root) + + sessionManager = SessionManager(this) + apiService = ApiConfig.getApiService(sessionManager) + + 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 + } + + setupUI() + setupObservers() + loadData() + } + + private fun setupUI() { + binding.searchContainer.btnBack.setOnClickListener { + finish() + } + + val searchContainerView = binding.searchContainer + searchContainerView.btnCart.setOnClickListener{ + navigateToCart() + } + + setupRecyclerViewOtherProducts() + } + + private fun setupObservers(){ + + viewModel.storeDetail.observe(this) { result -> + when (result) { + is Result.Success -> { + updateStoreInfo(result.data) + viewModel.loadOtherProducts(result.data.storeId) + } + is Result.Error -> { + // Show error message, maybe a Toast or Snackbar + Toast.makeText(this, "Failed to load store: ${result.exception.message}", Toast.LENGTH_SHORT).show() + } + is Result.Loading -> { + // Show loading indicator if needed + } + } + } + viewModel.otherProducts.observe(this) { products -> + updateOtherProducts(products) + } + } + + private fun loadData() { + val storeId = intent.getIntExtra("STORE_ID", -1) + if (storeId == -1) { + Log.e("StoreDetailActivity", "Invalid store ID") + Toast.makeText(this, "Invalid store ID", Toast.LENGTH_SHORT).show() + finish() // Close activity if no valid ID + return + } + + viewModel.loadStoreDetail(storeId) + } + + private fun updateStoreInfo(store: StoreProduct?) { + store?.let { + binding.tvStoreName.text = it.storeName + binding.tvStoreRating.text = it.storeRating + binding.tvStoreLocation.text = it.storeLocation + binding.tvStoreType.text = it.storeType + binding.tvActiveStatus.text = it.status + + // Load store image using Glide + val fullImageUrl = when (val img = it.storeImage) { + is String -> { + if (img.startsWith("/")) BASE_URL + img.substring(1) else img + } + else -> R.drawable.placeholder_image + } + + Glide.with(this) + .load(fullImageUrl) + .placeholder(R.drawable.placeholder_image) + .into(binding.ivStoreImage) + } + } + + private fun updateOtherProducts(products: List) { + if (products.isEmpty()) { + binding.rvProducts.visibility = View.GONE + } else { + binding.rvProducts.visibility = View.VISIBLE + productAdapter?.updateProducts(products) + } + } + + private fun setupRecyclerViewOtherProducts(){ + productAdapter = HorizontalProductAdapter( + products = emptyList(), + onClick = { productsItem -> handleProductClick(productsItem) } + ) + + binding.rvProducts.apply { + adapter = productAdapter + layoutManager = LinearLayoutManager( + context, + LinearLayoutManager.HORIZONTAL, + false + ) + } + } + + private fun handleProductClick(product: ProductsItem) { + val intent = Intent(this, DetailProductActivity::class.java) + intent.putExtra("PRODUCT_ID", product.id) // Pass product ID + startActivity(intent) + } + + private fun navigateToCart() { + val intent = Intent(this, CartActivity::class.java) + startActivity(intent) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/alya/ecommerce_serang/ui/product/storeDetail/StoreDetailViewModel.kt b/app/src/main/java/com/alya/ecommerce_serang/ui/product/storeDetail/StoreDetailViewModel.kt new file mode 100644 index 0000000..78baf3e --- /dev/null +++ b/app/src/main/java/com/alya/ecommerce_serang/ui/product/storeDetail/StoreDetailViewModel.kt @@ -0,0 +1,87 @@ +package com.alya.ecommerce_serang.ui.product.storeDetail + +import android.util.Log +import androidx.lifecycle.LiveData +import androidx.lifecycle.MutableLiveData +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import com.alya.ecommerce_serang.data.api.dto.ProductsItem +import com.alya.ecommerce_serang.data.api.response.customer.product.Product +import com.alya.ecommerce_serang.data.api.response.customer.product.StoreProduct +import com.alya.ecommerce_serang.data.repository.ProductRepository +import com.alya.ecommerce_serang.data.repository.Result +import kotlinx.coroutines.launch + +class StoreDetailViewModel (private val repository: ProductRepository +): ViewModel() { + + private val _productDetail = MutableLiveData() + val productDetail: LiveData get() = _productDetail + + private val _otherProducts = MutableLiveData>() + val otherProducts: LiveData> get() = _otherProducts + + private val _isLoading = MutableLiveData() + val isLoading: LiveData get() = _isLoading + + private val _error = MutableLiveData() + val error: LiveData get() = _error + + private val _storeDetail = MutableLiveData>() + val storeDetail : LiveData> get() = _storeDetail + + fun loadOtherProducts(storeId: Int) { + viewModelScope.launch { + try { + val result = repository.getAllProducts() // Fetch products + + if (result is Result.Success) { + val allProducts = result.data // Extract the list + val filteredProducts = allProducts.filter { + it.storeId == storeId && it.id != _productDetail.value?.productId + } // 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}") + _otherProducts.value = emptyList() // Set empty list on failure + } + } catch (e: Exception) { + Log.e("ProductViewModel", "Exception loading other products: ${e.message}") + _otherProducts.value = emptyList() + } + } + } + + fun loadProductDetail(productId: Int) { + _isLoading.value = true + viewModelScope.launch { + try { + val result = repository.fetchProductDetail(productId) + _productDetail.value = result?.product + + //Load store details if product has a store ID + result?.product?.storeId?.let { storeId -> + loadStoreDetail(storeId) + } + } catch (e: Exception) { + Log.e("ProductViewModel", "Error loading product details: ${e.message}") + _error.value = "Failed to load product details: ${e.message}" + } finally { + _isLoading.value = false + } + } + } + + fun loadStoreDetail(storeId: Int) { + viewModelScope.launch { + try { + _storeDetail.value = Result.Loading + val result = repository.fetchStoreDetail(storeId) + _storeDetail.value = result + } catch (e: Exception) { + Log.e("ProductViewModel", "Error loading store details: ${e.message}") + _storeDetail.value = Result.Error(e) + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/alya/ecommerce_serang/ui/profile/ProfileFragment.kt b/app/src/main/java/com/alya/ecommerce_serang/ui/profile/ProfileFragment.kt index b6ffcad..7f73254 100644 --- a/app/src/main/java/com/alya/ecommerce_serang/ui/profile/ProfileFragment.kt +++ b/app/src/main/java/com/alya/ecommerce_serang/ui/profile/ProfileFragment.kt @@ -63,16 +63,19 @@ class ProfileFragment : Fragment() { viewModel.loadUserProfile() viewModel.checkStoreUser() + + binding.cardBukaToko.setOnClickListener{ val hasStore = viewModel.checkStore.value -// val hasStore = false Log.d("Profile Fragment", "Check store $hasStore") if (hasStore == true){ + binding.tvBukaToko.text = "Buka Toko Saya" val intentBuka = Intent(requireContext(), MyStoreActivity::class.java) startActivity(intentBuka) } else { + binding.tvBukaToko.text = "Daftar Toko Saya" val intentBuka = Intent(requireContext(), RegisterStoreActivity::class.java) startActivity(intentBuka) } diff --git a/app/src/main/java/com/alya/ecommerce_serang/ui/profile/mystore/sells/SellsListFragment.kt b/app/src/main/java/com/alya/ecommerce_serang/ui/profile/mystore/sells/SellsListFragment.kt index 0e25cc6..6341c8d 100644 --- a/app/src/main/java/com/alya/ecommerce_serang/ui/profile/mystore/sells/SellsListFragment.kt +++ b/app/src/main/java/com/alya/ecommerce_serang/ui/profile/mystore/sells/SellsListFragment.kt @@ -1,11 +1,11 @@ package com.alya.ecommerce_serang.ui.profile.mystore.sells import android.os.Bundle -import androidx.fragment.app.Fragment import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.widget.Toast +import androidx.fragment.app.Fragment import androidx.fragment.app.viewModels import androidx.recyclerview.widget.LinearLayoutManager import com.alya.ecommerce_serang.data.api.response.store.orders.OrdersItem @@ -104,7 +104,7 @@ class SellsListFragment : Fragment() { } else { binding.tvEmptyState.visibility = View.GONE binding.rvSells.visibility = View.VISIBLE - //sellsAdapter.submitList(result.data) + sellsAdapter.submitList(result.data) } } is ViewState.Error -> { diff --git a/app/src/main/java/com/alya/ecommerce_serang/utils/viewmodel/ProfileViewModel.kt b/app/src/main/java/com/alya/ecommerce_serang/utils/viewmodel/ProfileViewModel.kt index da4552f..e655986 100644 --- a/app/src/main/java/com/alya/ecommerce_serang/utils/viewmodel/ProfileViewModel.kt +++ b/app/src/main/java/com/alya/ecommerce_serang/utils/viewmodel/ProfileViewModel.kt @@ -28,7 +28,7 @@ class ProfileViewModel(private val userRepository: UserRepository) : ViewModel() val checkStore: LiveData = _checkStore private val _logout = MutableLiveData() - val logout : LiveData = _checkStore + val logout : LiveData = _logout fun loadUserProfile(){ viewModelScope.launch { diff --git a/app/src/main/java/com/alya/ecommerce_serang/utils/viewmodel/SellsViewModel.kt b/app/src/main/java/com/alya/ecommerce_serang/utils/viewmodel/SellsViewModel.kt index ee3aa28..67a47c7 100644 --- a/app/src/main/java/com/alya/ecommerce_serang/utils/viewmodel/SellsViewModel.kt +++ b/app/src/main/java/com/alya/ecommerce_serang/utils/viewmodel/SellsViewModel.kt @@ -17,8 +17,8 @@ class SellsViewModel(private val repository: SellsRepository) : ViewModel() { private const val TAG = "SellsViewModel" } - private val _sells = MutableLiveData?>>() - val sells: LiveData?>> = _sells + private val _sells = MutableLiveData>>() + val sells: LiveData>> = _sells fun getSellList(status: String) { _sells.value = ViewState.Loading diff --git a/app/src/main/res/layout/activity_detail_order_status.xml b/app/src/main/res/layout/activity_detail_order_status.xml index c650212..1d05c02 100644 --- a/app/src/main/res/layout/activity_detail_order_status.xml +++ b/app/src/main/res/layout/activity_detail_order_status.xml @@ -225,16 +225,6 @@ android:orientation="vertical" android:padding="16dp"> - - diff --git a/app/src/main/res/layout/activity_detail_product.xml b/app/src/main/res/layout/activity_detail_product.xml index 9fbb296..1bb20ff 100644 --- a/app/src/main/res/layout/activity_detail_product.xml +++ b/app/src/main/res/layout/activity_detail_product.xml @@ -22,7 +22,7 @@ - - - diff --git a/app/src/main/res/layout/activity_login.xml b/app/src/main/res/layout/activity_login.xml index 7510d73..e73b979 100644 --- a/app/src/main/res/layout/activity_login.xml +++ b/app/src/main/res/layout/activity_login.xml @@ -6,7 +6,7 @@ android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" - android:padding="16dp" + android:layout_margin="16dp" android:layout_marginHorizontal="16dp" android:layout_marginVertical="16dp" tools:context=".ui.auth.LoginActivity"> @@ -94,6 +94,7 @@ android:text="@string/no_account"/> - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_profile.xml b/app/src/main/res/layout/fragment_profile.xml index c99ee71..dfcf34b 100644 --- a/app/src/main/res/layout/fragment_profile.xml +++ b/app/src/main/res/layout/fragment_profile.xml @@ -53,51 +53,59 @@ app:layout_constraintTop_toTopOf="@id/profileImage" /> - - + android:layout_height="wrap_content" + android:layout_marginTop="16dp" + android:clickable="true" + android:focusable="true" + android:paddingHorizontal="16dp" + app:cardElevation="4dp" + tools:layout_editor_absoluteX="0dp"> - + android:layout_gravity="center" + android:layout_marginHorizontal="14dp"> - + - + - + + + + + app:layout_constraintTop_toBottomOf="@id/container_buka_toko"> + + + + + + + + + + + + \ No newline at end of file