update ui and detail store

This commit is contained in:
shaulascr
2025-05-22 04:17:55 +07:00
parent 419eddee90
commit e7fbace532
36 changed files with 819 additions and 116 deletions

View File

@ -29,6 +29,9 @@
android:theme="@style/Theme.Ecommerce_serang" android:theme="@style/Theme.Ecommerce_serang"
android:usesCleartextTraffic="true" android:usesCleartextTraffic="true"
tools:targetApi="31"> tools:targetApi="31">
<activity
android:name=".ui.product.storeDetail.StoreDetailActivity"
android:exported="false" />
<activity <activity
android:name=".ui.auth.RegisterStoreActivity" android:name=".ui.auth.RegisterStoreActivity"
android:exported="false" /> android:exported="false" />
@ -67,6 +70,7 @@
android:enabled="true" android:enabled="true"
android:exported="false" android:exported="false"
android:foregroundServiceType="dataSync" /> android:foregroundServiceType="dataSync" />
<activity <activity
android:name=".ui.profile.mystore.profile.shipping_service.ShippingServiceActivity" android:name=".ui.profile.mystore.profile.shipping_service.ShippingServiceActivity"
android:exported="false" /> android:exported="false" />

View File

@ -5,7 +5,7 @@ import com.google.gson.annotations.SerializedName
data class OrderListResponse( data class OrderListResponse(
@field:SerializedName("orders") @field:SerializedName("orders")
val orders: List<OrdersItem?>? = null, val orders: List<OrdersItem>,
@field:SerializedName("message") @field:SerializedName("message")
val message: String? = null val message: String? = null

View File

@ -314,7 +314,7 @@ interface ApiService {
suspend fun getListProv( suspend fun getListProv(
): Response<ListProvinceResponse> ): Response<ListProvinceResponse>
@GET("order/{status}") @GET("mystore/orders/{status}")
suspend fun getSellList( suspend fun getSellList(
@Path("status") status: String @Path("status") status: String
): Response<com.alya.ecommerce_serang.data.api.response.store.orders.OrderListResponse> ): Response<com.alya.ecommerce_serang.data.api.response.store.orders.OrderListResponse>

View File

@ -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.Preorder
import com.alya.ecommerce_serang.data.api.dto.ProductsItem import com.alya.ecommerce_serang.data.api.dto.ProductsItem
import com.alya.ecommerce_serang.data.api.dto.SearchRequest 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.cart.AddCartResponse
import com.alya.ecommerce_serang.data.api.response.customer.product.ProductResponse 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.ReviewsItem
import com.alya.ecommerce_serang.data.api.response.customer.product.StoreProduct 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.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.data.api.retrofit.ApiService
import com.alya.ecommerce_serang.utils.SessionManager
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import okhttp3.MediaType.Companion.toMediaTypeOrNull import okhttp3.MediaType.Companion.toMediaTypeOrNull
@ -119,7 +118,7 @@ class ProductRepository(private val apiService: ApiService) {
} }
} }
suspend fun fetchStoreDetail(storeId: Int): Result<StoreProduct?> { suspend fun fetchStoreDetail(storeId: Int): Result<StoreProduct> {
return try { return try {
val response = apiService.getDetailStore(storeId) val response = apiService.getDetailStore(storeId)
if (response.isSuccessful) { if (response.isSuccessful) {

View File

@ -8,6 +8,9 @@ import android.widget.Toast
import androidx.activity.enableEdgeToEdge import androidx.activity.enableEdgeToEdge
import androidx.activity.viewModels import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity 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.dto.FcmReq
import com.alya.ecommerce_serang.data.api.retrofit.ApiConfig import com.alya.ecommerce_serang.data.api.retrofit.ApiConfig
import com.alya.ecommerce_serang.data.repository.Result import com.alya.ecommerce_serang.data.repository.Result
@ -35,11 +38,30 @@ class LoginActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
enableEdgeToEdge()
binding = ActivityLoginBinding.inflate(layoutInflater) binding = ActivityLoginBinding.inflate(layoutInflater)
setContentView(binding.root) 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() setupListeners()
observeLoginState() observeLoginState()
@ -59,6 +81,11 @@ class LoginActivity : AppCompatActivity() {
loginViewModel.login(email, password) loginViewModel.login(email, password)
} }
} }
binding.tvRegistrasi.setOnClickListener{
startActivity(Intent(this, RegisterActivity::class.java))
finish()
}
} }
private fun observeLoginState() { private fun observeLoginState() {

View File

@ -42,6 +42,23 @@ class RegisterActivity : AppCompatActivity() {
binding = ActivityRegisterBinding.inflate(layoutInflater) binding = ActivityRegisterBinding.inflate(layoutInflater)
setContentView(binding.root) setContentView(binding.root)
sessionManager = SessionManager(this) 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", "Token in storage: '${sessionManager.getToken()}'")
Log.d("RegisterActivity", "User ID in storage: '${sessionManager.getUserId()}'") Log.d("RegisterActivity", "User ID in storage: '${sessionManager.getUserId()}'")

View File

@ -63,22 +63,17 @@ class RegisterStoreActivity : AppCompatActivity() {
} }
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
Log.d(TAG, "onCreate: Starting RegisterStoreActivity")
binding = ActivityRegisterStoreBinding.inflate(layoutInflater) binding = ActivityRegisterStoreBinding.inflate(layoutInflater)
setContentView(binding.root) setContentView(binding.root)
sessionManager = SessionManager(this) sessionManager = SessionManager(this)
Log.d(TAG, "onCreate: SessionManager initialized")
WindowCompat.setDecorFitsSystemWindows(window, false) WindowCompat.setDecorFitsSystemWindows(window, false)
Log.d(TAG, "onCreate: Window decoration set")
enableEdgeToEdge() enableEdgeToEdge()
Log.d(TAG, "onCreate: Edge-to-edge enabled")
// Apply insets to your root layout // Apply insets to your root layout
ViewCompat.setOnApplyWindowInsetsListener(binding.root) { view, windowInsets -> ViewCompat.setOnApplyWindowInsetsListener(binding.root) { view, windowInsets ->
Log.d(TAG, "onCreate: Applying window insets")
val systemBars = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars()) val systemBars = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars())
view.setPadding( view.setPadding(
systemBars.left, systemBars.left,

View File

@ -64,9 +64,9 @@ class RegisterStep1Fragment : Fragment() {
// Set step progress and description // Set step progress and description
(activity as? RegisterActivity)?.let { (activity as? RegisterActivity)?.let {
it.findViewById<LinearProgressIndicator>(R.id.registration_progress)?.progress = 33 it.findViewById<LinearProgressIndicator>(R.id.registration_progress)?.progress = 33
it.findViewById<TextView>(R.id.tv_step_title)?.text = "Step 1: Account & Personal Info" it.findViewById<TextView>(R.id.tv_step_title)?.text = "Step 1: Informasi Akun"
it.findViewById<TextView>(R.id.tv_step_description)?.text = it.findViewById<TextView>(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() setupFieldValidations()

View File

@ -70,9 +70,9 @@ class RegisterStep2Fragment : Fragment() {
// Set step progress and description // Set step progress and description
(activity as? RegisterActivity)?.let { (activity as? RegisterActivity)?.let {
it.findViewById<LinearProgressIndicator>(R.id.registration_progress)?.progress = 66 it.findViewById<LinearProgressIndicator>(R.id.registration_progress)?.progress = 66
it.findViewById<TextView>(R.id.tv_step_title)?.text = "Step 2: Verify Your Email" it.findViewById<TextView>(R.id.tv_step_title)?.text = "Step 2: Masukkan Kode OTP"
it.findViewById<TextView>(R.id.tv_step_description)?.text = it.findViewById<TextView>(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") Log.d(TAG, "Step indicators updated to Step 2")
} }

View File

@ -70,10 +70,10 @@ class RegisterStep3Fragment : Fragment() {
// Set step progress and description // Set step progress and description
(activity as? RegisterActivity)?.let { (activity as? RegisterActivity)?.let {
it.findViewById<LinearProgressIndicator>(R.id.registration_progress)?.progress = 33 it.findViewById<LinearProgressIndicator>(R.id.registration_progress)?.progress = 100
it.findViewById<TextView>(R.id.tv_step_title)?.text = "Step 1: Account & Personal Info" it.findViewById<TextView>(R.id.tv_step_title)?.text = "Step 3: Tambahkan Alamat"
it.findViewById<TextView>(R.id.tv_step_description)?.text = it.findViewById<TextView>(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") Log.d(TAG, "Step indicators updated to Step 1")
} }

View File

@ -60,12 +60,20 @@ class CartActivity : AppCompatActivity() {
windowInsets windowInsets
} }
setupToolbar()
setupRecyclerView() setupRecyclerView()
setupListeners() setupListeners()
observeViewModel() observeViewModel()
viewModel.getCart() viewModel.getCart()
} }
private fun setupToolbar(){
binding.header.headerLeftIcon.setOnClickListener{
finish()
}
binding.header.headerTitle.text = "Keranjang"
}
private fun setupRecyclerView() { private fun setupRecyclerView() {
storeAdapter = StoreAdapter( storeAdapter = StoreAdapter(
onStoreCheckChanged = { storeId, isChecked -> onStoreCheckChanged = { storeId, isChecked ->

View File

@ -59,11 +59,6 @@ class ChatActivity : AppCompatActivity() {
// For image attachment // For image attachment
private var tempImageUri: Uri? = null 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 // Typing indicator handler
private val typingHandler = android.os.Handler(android.os.Looper.getMainLooper()) private val typingHandler = android.os.Handler(android.os.Looper.getMainLooper())
private val stopTypingRunnable = Runnable { private val stopTypingRunnable = Runnable {

View File

@ -3,8 +3,12 @@ package com.alya.ecommerce_serang.ui.notif
import android.os.Bundle import android.os.Bundle
import android.util.Log import android.util.Log
import android.view.View import android.view.View
import androidx.activity.enableEdgeToEdge
import androidx.activity.viewModels import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity 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 androidx.recyclerview.widget.LinearLayoutManager
import com.alya.ecommerce_serang.data.repository.Result import com.alya.ecommerce_serang.data.repository.Result
import com.alya.ecommerce_serang.databinding.ActivityNotificationBinding import com.alya.ecommerce_serang.databinding.ActivityNotificationBinding
@ -30,6 +34,22 @@ class NotificationActivity : AppCompatActivity() {
binding = ActivityNotificationBinding.inflate(layoutInflater) binding = ActivityNotificationBinding.inflate(layoutInflater)
setContentView(binding.root) 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() setupToolbar()
setupAdapters() setupAdapters()
setupTabLayout() setupTabLayout()

View File

@ -5,8 +5,12 @@ import android.os.Bundle
import android.util.Log import android.util.Log
import android.view.View import android.view.View
import android.widget.Toast import android.widget.Toast
import androidx.activity.enableEdgeToEdge
import androidx.activity.viewModels import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity 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 androidx.recyclerview.widget.LinearLayoutManager
import com.alya.ecommerce_serang.data.api.retrofit.ApiConfig import com.alya.ecommerce_serang.data.api.retrofit.ApiConfig
import com.alya.ecommerce_serang.data.repository.OrderRepository import com.alya.ecommerce_serang.data.repository.OrderRepository
@ -37,6 +41,22 @@ class ShippingActivity : AppCompatActivity() {
// Initialize SessionManager // Initialize SessionManager
sessionManager = SessionManager(this) 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 // Get data from intent
val addressId = intent.getIntExtra(EXTRA_ADDRESS_ID, 0) val addressId = intent.getIntExtra(EXTRA_ADDRESS_ID, 0)
val productId = intent.getIntExtra(EXTRA_PRODUCT_ID, 0) val productId = intent.getIntExtra(EXTRA_PRODUCT_ID, 0)

View File

@ -13,10 +13,14 @@ import android.provider.Settings
import android.util.Log import android.util.Log
import android.view.View import android.view.View
import android.widget.Toast import android.widget.Toast
import androidx.activity.enableEdgeToEdge
import androidx.activity.result.contract.ActivityResultContracts import androidx.activity.result.contract.ActivityResultContracts
import androidx.activity.viewModels import androidx.activity.viewModels
import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity 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.CreateAddressRequest
import com.alya.ecommerce_serang.data.api.dto.UserProfile import com.alya.ecommerce_serang.data.api.dto.UserProfile
import com.alya.ecommerce_serang.data.api.response.customer.order.CitiesItem import com.alya.ecommerce_serang.data.api.response.customer.order.CitiesItem
@ -61,6 +65,22 @@ class AddAddressActivity : AppCompatActivity() {
apiService = ApiConfig.getApiService(sessionManager) apiService = ApiConfig.getApiService(sessionManager)
locationManager = getSystemService(LOCATION_SERVICE) as LocationManager 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 // Get user profile from session manager
// profileUser =UserProfile. // profileUser =UserProfile.
viewModel.userProfile.observe(this){ user -> viewModel.userProfile.observe(this){ user ->

View File

@ -2,8 +2,12 @@ package com.alya.ecommerce_serang.ui.order.address
import android.content.Intent import android.content.Intent
import android.os.Bundle import android.os.Bundle
import androidx.activity.enableEdgeToEdge
import androidx.activity.viewModels import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity 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.core.view.isVisible
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import com.alya.ecommerce_serang.data.api.retrofit.ApiConfig import com.alya.ecommerce_serang.data.api.retrofit.ApiConfig
@ -32,6 +36,22 @@ class AddressActivity : AppCompatActivity() {
sessionManager = SessionManager(this) 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() setupToolbar()
setupRecyclerView() setupRecyclerView()
@ -40,19 +60,17 @@ class AddressActivity : AppCompatActivity() {
viewModel.fetchAddresses() viewModel.fetchAddresses()
} }
private fun addAddressClicked(){
binding.addAddressClick.setOnClickListener{
val intent = Intent(this, AddAddressActivity::class.java)
startActivity(intent)
}
}
private fun setupToolbar() { private fun setupToolbar() {
// Remove duplicate toolbar setup // Remove duplicate toolbar setup
addAddressClicked()
binding.toolbar.setNavigationOnClickListener { binding.toolbar.setNavigationOnClickListener {
onBackPressedWithResult() onBackPressedWithResult()
} }
binding.addAddressClick.setOnClickListener{
val intent = Intent(this, AddAddressActivity::class.java)
startActivity(intent)
}
} }
private fun setupRecyclerView() { private fun setupRecyclerView() {

View File

@ -13,11 +13,15 @@ import android.webkit.MimeTypeMap
import android.widget.AdapterView import android.widget.AdapterView
import android.widget.ArrayAdapter import android.widget.ArrayAdapter
import android.widget.Toast import android.widget.Toast
import androidx.activity.enableEdgeToEdge
import androidx.activity.result.contract.ActivityResultContracts import androidx.activity.result.contract.ActivityResultContracts
import androidx.activity.viewModels import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.ActivityCompat import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat 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.dto.AddEvidenceMultipartRequest
import com.alya.ecommerce_serang.data.api.retrofit.ApiConfig import com.alya.ecommerce_serang.data.api.retrofit.ApiConfig
import com.alya.ecommerce_serang.data.repository.OrderRepository import com.alya.ecommerce_serang.data.repository.OrderRepository
@ -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() setupUI()
viewModel.getOrderDetails(orderId) viewModel.getOrderDetails(orderId)
setupListeners() setupListeners()
setupObservers() setupObservers()
} }
private fun setupUI() { private fun setupUI() {

View File

@ -4,9 +4,13 @@ import android.content.Intent
import android.os.Bundle import android.os.Bundle
import android.util.Log import android.util.Log
import android.widget.Toast import android.widget.Toast
import androidx.activity.enableEdgeToEdge
import androidx.activity.viewModels import androidx.activity.viewModels
import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity 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.api.retrofit.ApiConfig
import com.alya.ecommerce_serang.data.repository.OrderRepository import com.alya.ecommerce_serang.data.repository.OrderRepository
import com.alya.ecommerce_serang.databinding.ActivityPaymentBinding import com.alya.ecommerce_serang.databinding.ActivityPaymentBinding
@ -39,6 +43,22 @@ class PaymentActivity : AppCompatActivity() {
sessionManager = SessionManager(this) 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 // Mengambil data dari intent
val orderId = intent.getIntExtra("ORDER_ID", 0) val orderId = intent.getIntExtra("ORDER_ID", 0)
val paymentInfoId = intent.getIntExtra("ORDER_PAYMENT_ID", 0) val paymentInfoId = intent.getIntExtra("ORDER_PAYMENT_ID", 0)
@ -50,6 +70,7 @@ class PaymentActivity : AppCompatActivity() {
// Setup toolbar // Setup toolbar
binding.toolbar.setNavigationOnClickListener { binding.toolbar.setNavigationOnClickListener {
onBackPressedDispatcher
finish() finish()
} }
@ -75,15 +96,6 @@ class PaymentActivity : AppCompatActivity() {
startActivity(intent) 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 // Observe data
observeData() observeData()

View File

@ -1,8 +1,12 @@
package com.alya.ecommerce_serang.ui.order.history package com.alya.ecommerce_serang.ui.order.history
import android.os.Bundle import android.os.Bundle
import androidx.activity.enableEdgeToEdge
import androidx.activity.viewModels import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity 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 androidx.fragment.app.commit
import com.alya.ecommerce_serang.R import com.alya.ecommerce_serang.R
import com.alya.ecommerce_serang.data.api.retrofit.ApiConfig import com.alya.ecommerce_serang.data.api.retrofit.ApiConfig
@ -31,6 +35,22 @@ class HistoryActivity : AppCompatActivity() {
sessionManager = SessionManager(this) 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() setupToolbar()
if (savedInstanceState == null) { if (savedInstanceState == null) {
@ -44,6 +64,7 @@ class HistoryActivity : AppCompatActivity() {
binding.btnBack.setOnClickListener { binding.btnBack.setOnClickListener {
onBackPressed() onBackPressed()
finish()
} }
} }

View File

@ -106,12 +106,21 @@ class DetailOrderStatusActivity : AppCompatActivity() {
return return
} }
setupToolbar()
setupObservers() setupObservers()
loadOrderDetails() loadOrderDetails()
Log.d(TAG, "onCreate: Activity initialization completed") Log.d(TAG, "onCreate: Activity initialization completed")
} }
private fun setupToolbar(){
binding.header.headerLeftIcon.setOnClickListener{
finish()
}
binding.header.headerTitle.text = "Detail Pesanan"
}
private fun setupObservers() { private fun setupObservers() {
Log.d(TAG, "setupObservers: Setting up LiveData observers") Log.d(TAG, "setupObservers: Setting up LiveData observers")

View File

@ -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.chat.ChatActivity
import com.alya.ecommerce_serang.ui.home.HorizontalProductAdapter import com.alya.ecommerce_serang.ui.home.HorizontalProductAdapter
import com.alya.ecommerce_serang.ui.order.CheckoutActivity import com.alya.ecommerce_serang.ui.order.CheckoutActivity
import com.alya.ecommerce_serang.ui.product.storeDetail.StoreDetailActivity
import com.alya.ecommerce_serang.utils.BaseViewModelFactory import com.alya.ecommerce_serang.utils.BaseViewModelFactory
import com.alya.ecommerce_serang.utils.SessionManager import com.alya.ecommerce_serang.utils.SessionManager
import com.bumptech.glide.Glide import com.bumptech.glide.Glide
@ -185,12 +186,13 @@ class DetailProductActivity : AppCompatActivity() {
binding.recyclerViewOtherProducts.visibility = View.VISIBLE binding.recyclerViewOtherProducts.visibility = View.VISIBLE
binding.tvViewAllProducts.visibility = View.VISIBLE binding.tvViewAllProducts.visibility = View.VISIBLE
productAdapter?.updateProducts(products) productAdapter?.updateProducts(products)
} } }
}
private fun setupUI() { private fun setupUI() {
// binding.btnBack.setOnClickListener { binding.searchContainer.btnBack.setOnClickListener {
// finish() finish()
// } }
binding.tvViewAllReviews.setOnClickListener { binding.tvViewAllReviews.setOnClickListener {
viewModel.productDetail.value?.productId?.let { productId -> viewModel.productDetail.value?.productId?.let { productId ->
@ -198,8 +200,6 @@ class DetailProductActivity : AppCompatActivity() {
} }
} }
val searchContainerView = binding.searchContainer val searchContainerView = binding.searchContainer
searchContainerView.btnCart.setOnClickListener{ searchContainerView.btnCart.setOnClickListener{
navigateToCart() navigateToCart()
@ -244,6 +244,10 @@ class DetailProductActivity : AppCompatActivity() {
} }
} }
binding.containerStoreDetail.setOnClickListener{
handleStoreClick(product)
}
binding.btnAddToCart.setOnClickListener { binding.btnAddToCart.setOnClickListener {
viewModel.productDetail.value?.productId?.let { id -> viewModel.productDetail.value?.productId?.let { id ->
showAddToCartPopup(id) showAddToCartPopup(id)
@ -317,6 +321,12 @@ class DetailProductActivity : AppCompatActivity() {
startActivity(intent) 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) { private fun showBuyNowPopup(productId: Int) {
showQuantityDialog(productId, true) showQuantityDialog(productId, true)
} }

View File

@ -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<ProductsItem>) {
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)
}
}

View File

@ -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<Product?>()
val productDetail: LiveData<Product?> get() = _productDetail
private val _otherProducts = MutableLiveData<List<ProductsItem>>()
val otherProducts: LiveData<List<ProductsItem>> get() = _otherProducts
private val _isLoading = MutableLiveData<Boolean>()
val isLoading: LiveData<Boolean> get() = _isLoading
private val _error = MutableLiveData<String>()
val error: LiveData<String> get() = _error
private val _storeDetail = MutableLiveData<Result<StoreProduct>>()
val storeDetail : LiveData<Result<StoreProduct>> 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)
}
}
}
}

View File

@ -63,16 +63,19 @@ class ProfileFragment : Fragment() {
viewModel.loadUserProfile() viewModel.loadUserProfile()
viewModel.checkStoreUser() viewModel.checkStoreUser()
binding.cardBukaToko.setOnClickListener{ binding.cardBukaToko.setOnClickListener{
val hasStore = viewModel.checkStore.value val hasStore = viewModel.checkStore.value
// val hasStore = false
Log.d("Profile Fragment", "Check store $hasStore") Log.d("Profile Fragment", "Check store $hasStore")
if (hasStore == true){ if (hasStore == true){
binding.tvBukaToko.text = "Buka Toko Saya"
val intentBuka = Intent(requireContext(), MyStoreActivity::class.java) val intentBuka = Intent(requireContext(), MyStoreActivity::class.java)
startActivity(intentBuka) startActivity(intentBuka)
} else { } else {
binding.tvBukaToko.text = "Daftar Toko Saya"
val intentBuka = Intent(requireContext(), RegisterStoreActivity::class.java) val intentBuka = Intent(requireContext(), RegisterStoreActivity::class.java)
startActivity(intentBuka) startActivity(intentBuka)
} }

View File

@ -1,11 +1,11 @@
package com.alya.ecommerce_serang.ui.profile.mystore.sells package com.alya.ecommerce_serang.ui.profile.mystore.sells
import android.os.Bundle import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.Toast import android.widget.Toast
import androidx.fragment.app.Fragment
import androidx.fragment.app.viewModels import androidx.fragment.app.viewModels
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import com.alya.ecommerce_serang.data.api.response.store.orders.OrdersItem import com.alya.ecommerce_serang.data.api.response.store.orders.OrdersItem
@ -104,7 +104,7 @@ class SellsListFragment : Fragment() {
} else { } else {
binding.tvEmptyState.visibility = View.GONE binding.tvEmptyState.visibility = View.GONE
binding.rvSells.visibility = View.VISIBLE binding.rvSells.visibility = View.VISIBLE
//sellsAdapter.submitList(result.data) sellsAdapter.submitList(result.data)
} }
} }
is ViewState.Error -> { is ViewState.Error -> {

View File

@ -28,7 +28,7 @@ class ProfileViewModel(private val userRepository: UserRepository) : ViewModel()
val checkStore: LiveData<Boolean> = _checkStore val checkStore: LiveData<Boolean> = _checkStore
private val _logout = MutableLiveData<Boolean>() private val _logout = MutableLiveData<Boolean>()
val logout : LiveData<Boolean> = _checkStore val logout : LiveData<Boolean> = _logout
fun loadUserProfile(){ fun loadUserProfile(){
viewModelScope.launch { viewModelScope.launch {

View File

@ -17,8 +17,8 @@ class SellsViewModel(private val repository: SellsRepository) : ViewModel() {
private const val TAG = "SellsViewModel" private const val TAG = "SellsViewModel"
} }
private val _sells = MutableLiveData<ViewState<List<OrdersItem?>?>>() private val _sells = MutableLiveData<ViewState<List<OrdersItem>>>()
val sells: LiveData<ViewState<List<OrdersItem?>?>> = _sells val sells: LiveData<ViewState<List<OrdersItem>>> = _sells
fun getSellList(status: String) { fun getSellList(status: String) {
_sells.value = ViewState.Loading _sells.value = ViewState.Loading

View File

@ -225,16 +225,6 @@
android:orientation="vertical" android:orientation="vertical"
android:padding="16dp"> android:padding="16dp">
<TextView
android:id="@+id/tvStoreName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="SnackEnak"
android:fontFamily="@font/dmsans_semibold"
android:textColor="@color/black"
android:textSize="16sp"
android:textStyle="bold" />
<androidx.recyclerview.widget.RecyclerView <androidx.recyclerview.widget.RecyclerView
android:id="@+id/rvOrderItems" android:id="@+id/rvOrderItems"
android:layout_width="match_parent" android:layout_width="match_parent"
@ -310,10 +300,11 @@
android:orientation="horizontal"> android:orientation="horizontal">
<TextView <TextView
android:id="@+id/tv_item_count"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_weight="1" android:layout_weight="1"
android:text="1 item" android:text="Harga Total Produk"
android:textColor="@color/black_400" android:textColor="@color/black_400"
android:textSize="14sp" /> android:textSize="14sp" />

View File

@ -22,7 +22,7 @@
<include <include
android:id="@+id/searchContainer" android:id="@+id/searchContainer"
layout="@layout/view_search" layout="@layout/view_search_back"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="16dp" android:layout_marginTop="16dp"
@ -196,9 +196,6 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content"/> android:layout_height="wrap_content"/>
<!-- Buyer Reviews Section --> <!-- Buyer Reviews Section -->
<androidx.cardview.widget.CardView <androidx.cardview.widget.CardView
android:layout_width="match_parent" android:layout_width="match_parent"
@ -377,6 +374,7 @@
<!-- Seller Info Section --> <!-- Seller Info Section -->
<androidx.cardview.widget.CardView <androidx.cardview.widget.CardView
android:id="@+id/container_store_detail"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
app:cardElevation="0dp"> app:cardElevation="0dp">

View File

@ -6,7 +6,7 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:orientation="vertical" android:orientation="vertical"
android:padding="16dp" android:layout_margin="16dp"
android:layout_marginHorizontal="16dp" android:layout_marginHorizontal="16dp"
android:layout_marginVertical="16dp" android:layout_marginVertical="16dp"
tools:context=".ui.auth.LoginActivity"> tools:context=".ui.auth.LoginActivity">
@ -94,6 +94,7 @@
android:text="@string/no_account"/> android:text="@string/no_account"/>
<TextView <TextView
android:id="@+id/tv_registrasi"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/signup" android:text="@string/signup"

View File

@ -221,15 +221,6 @@
android:padding="16dp" android:padding="16dp"
app:layout_constraintBottom_toBottomOf="parent"> app:layout_constraintBottom_toBottomOf="parent">
<com.google.android.material.button.MaterialButton
android:id="@+id/btnNegotiatePrice"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:background="@drawable/bg_button_outline"
android:text="Negosiasi Harga"
android:textAllCaps="false"
android:textColor="@color/blue_500" />
<com.google.android.material.button.MaterialButton <com.google.android.material.button.MaterialButton
android:id="@+id/btnUploadPaymentProof" android:id="@+id/btnUploadPaymentProof"

View File

@ -9,6 +9,17 @@
android:theme="@style/Theme.Ecommerce_serang" android:theme="@style/Theme.Ecommerce_serang"
tools:context=".ui.auth.RegisterActivity"> tools:context=".ui.auth.RegisterActivity">
<TextView
android:id="@+id/tv_title_register"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="16dp"
android:layout_marginTop="16dp"
android:text="Daftar Akun"
android:textAlignment="center"
android:textSize="20sp"
android:textStyle="bold" />
<com.google.android.material.progressindicator.LinearProgressIndicator <com.google.android.material.progressindicator.LinearProgressIndicator
android:id="@+id/registration_progress" android:id="@+id/registration_progress"
android:layout_width="match_parent" android:layout_width="match_parent"

View File

@ -0,0 +1,171 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.product.storeDetail.StoreDetailActivity">
<include
android:id="@+id/searchContainer"
layout="@layout/view_search_back"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
app:layout_constraintTop_toTopOf="parent" />
<!-- Store Information -->
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/storeInfoContainer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/blue_50"
android:layout_marginTop="16dp"
android:padding="24dp"
app:layout_constraintTop_toBottomOf="@id/searchContainer">
<ImageView
android:id="@+id/ivStoreImage"
android:layout_width="64dp"
android:layout_height="64dp"
android:background="@drawable/circle_background"
android:scaleType="centerCrop"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:src="@drawable/placeholder_image" />
<TextView
android:id="@+id/tvStoreName"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:textColor="@android:color/black"
android:textSize="18sp"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/ivStoreImage"
app:layout_constraintTop_toTopOf="@id/ivStoreImage"
tools:text="SnackEnak" />
<TextView
android:id="@+id/tvStoreType"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:textSize="14sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/ivStoreImage"
app:layout_constraintTop_toBottomOf="@id/tvStoreName"
tools:text="Makanan Ringan" />
<LinearLayout
android:id="@+id/storeRatingContainer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="4dp"
android:gravity="center_vertical"
android:orientation="horizontal"
app:layout_constraintStart_toEndOf="@id/ivStoreImage"
app:layout_constraintTop_toBottomOf="@id/tvStoreType">
<ImageView
android:id="@+id/ivStoreRatingStar"
android:layout_width="16dp"
android:layout_height="16dp"
android:src="@drawable/ic_star"
app:tint="@color/yellow" />
<TextView
android:id="@+id/tvStoreRating"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="4dp"
android:textSize="12sp"
android:textStyle="bold"
tools:text="5.0" />
</LinearLayout>
<TextView
android:id="@+id/tvStoreLocation"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="4dp"
android:layout_marginEnd="16dp"
android:textSize="12sp"
app:layout_constraintEnd_toStartOf="@id/tvActiveStatus"
app:layout_constraintStart_toEndOf="@id/ivStoreImage"
app:layout_constraintTop_toBottomOf="@id/storeRatingContainer"
tools:text="Kabupaten Serang" />
<TextView
android:id="@+id/tvActiveStatus"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingStart="4dp"
android:paddingEnd="4dp"
android:text="Aktif"
android:textColor="@android:color/black"
android:textSize="12sp"
app:layout_constraintBottom_toBottomOf="@id/tvStoreLocation"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@id/tvStoreLocation" />
<!-- <ImageButton-->
<!-- android:id="@+id/btnChevron"-->
<!-- android:layout_width="wrap_content"-->
<!-- android:layout_height="wrap_content"-->
<!-- android:background="?attr/selectableItemBackgroundBorderless"-->
<!-- android:contentDescription="More"-->
<!-- android:src="@drawable/ic_chevron_right"-->
<!-- app:layout_constraintBottom_toBottomOf="parent"-->
<!-- app:layout_constraintEnd_toEndOf="parent"-->
<!-- app:layout_constraintTop_toTopOf="parent" />-->
</androidx.constraintlayout.widget.ConstraintLayout>
<com.google.android.material.divider.MaterialDivider
android:id="@+id/divider_product"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="@id/storeInfoContainer"/>
<!-- Tab Layout: TO DO implement after review -->
<!-- <com.google.android.material.tabs.TabLayout-->
<!-- android:id="@+id/tabLayout"-->
<!-- android:layout_width="match_parent"-->
<!-- android:layout_height="wrap_content"-->
<!-- app:layout_constraintTop_toBottomOf="@id/storeInfoContainer"-->
<!-- app:tabIndicatorColor="@color/colorPrimary"-->
<!-- app:tabSelectedTextColor="@color/colorPrimary"-->
<!-- app:tabTextColor="@android:color/darker_gray">-->
<!-- <com.google.android.material.tabs.TabItem-->
<!-- android:layout_width="wrap_content"-->
<!-- android:layout_height="wrap_content"-->
<!-- android:text="Produk" />-->
<!-- <com.google.android.material.tabs.TabItem-->
<!-- android:layout_width="wrap_content"-->
<!-- android:layout_height="wrap_content"-->
<!-- android:text="Kategori" />-->
<!-- </com.google.android.material.tabs.TabLayout>-->
<!-- Products RecyclerView -->
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv_products"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:layout_marginBottom="16dp"
android:orientation="vertical"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
app:layout_constraintTop_toBottomOf="@id/divider_product"
tools:itemCount="5"
tools:listitem="@layout/item_section_horizontal" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -53,51 +53,59 @@
app:layout_constraintTop_toTopOf="@id/profileImage" /> app:layout_constraintTop_toTopOf="@id/profileImage" />
<!-- Store Button --> <!-- Store Button -->
<androidx.cardview.widget.CardView <LinearLayout
android:id="@+id/cardBukaToko" android:id="@+id/container_buka_toko"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:paddingHorizontal="16dp" android:orientation="vertical"
android:layout_marginTop="16dp"
android:clickable="true"
android:focusable="true"
app:cardElevation="4dp"
app:layout_constraintTop_toBottomOf="@id/profileImage"> app:layout_constraintTop_toBottomOf="@id/profileImage">
<androidx.constraintlayout.widget.ConstraintLayout <androidx.cardview.widget.CardView
android:layout_marginHorizontal="14dp" android:id="@+id/cardBukaToko"
android:layout_gravity="center"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content"> 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">
<TextView <androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/tvBukaToko" android:layout_width="match_parent"
android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:drawableStart="@drawable/outline_store_24" android:layout_gravity="center"
android:drawablePadding="16dp" android:layout_marginHorizontal="14dp">
android:padding="16dp"
android:fontFamily="@font/dmsans_semibold"
android:textSize="14sp"
android:text="@string/open_store"
app:layout_constraintEnd_toStartOf="@id/ivStoreArrow"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ImageButton <TextView
android:id="@+id/ivStoreArrow" android:id="@+id/tvBukaToko"
android:layout_width="wrap_content" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginEnd="16dp" android:drawableStart="@drawable/outline_store_24"
android:background="?attr/selectableItemBackgroundBorderless" android:drawablePadding="16dp"
android:src="@drawable/ic_arrow_right" android:fontFamily="@font/dmsans_semibold"
app:layout_constraintBottom_toBottomOf="@id/tvBukaToko" android:padding="16dp"
app:layout_constraintEnd_toEndOf="parent" android:text="@string/open_store"
app:layout_constraintTop_toTopOf="@id/tvBukaToko" /> android:textSize="14sp"
app:layout_constraintEnd_toStartOf="@id/ivStoreArrow"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout> <ImageView
android:id="@+id/ivStoreArrow"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="16dp"
android:background="?attr/selectableItemBackgroundBorderless"
android:src="@drawable/ic_arrow_right"
app:layout_constraintBottom_toBottomOf="@id/tvBukaToko"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@id/tvBukaToko" />
</androidx.cardview.widget.CardView> </androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>
</LinearLayout>
<androidx.cardview.widget.CardView <androidx.cardview.widget.CardView
android:id="@+id/cardPesanan" android:id="@+id/cardPesanan"
@ -105,7 +113,7 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginBottom="8dp" android:layout_marginBottom="8dp"
android:layout_marginTop="8dp" android:layout_marginTop="8dp"
app:layout_constraintTop_toBottomOf="@id/cardBukaToko"> app:layout_constraintTop_toBottomOf="@id/container_buka_toko">
<androidx.constraintlayout.widget.ConstraintLayout <androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent" android:layout_width="match_parent"

View File

@ -6,6 +6,19 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:padding="8dp"> android:padding="8dp">
<TextView
android:id="@+id/tvStoreName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="SnackEnak"
android:fontFamily="@font/dmsans_semibold"
android:textColor="@color/black"
android:paddingBottom="8dp"
android:textSize="16sp"
android:textStyle="bold"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
<ImageView <ImageView
android:id="@+id/ivProduct" android:id="@+id/ivProduct"
android:layout_width="64dp" android:layout_width="64dp"
@ -13,7 +26,7 @@
android:scaleType="centerCrop" android:scaleType="centerCrop"
android:elevation="4dp" android:elevation="4dp"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" app:layout_constraintTop_toBottomOf="@id/tvStoreName"
tools:src="@drawable/placeholder_image" /> tools:src="@drawable/placeholder_image" />
<TextView <TextView

View File

@ -0,0 +1,54 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">
<ImageButton
android:id="@+id/btn_back"
android:layout_width="48dp"
android:layout_height="0dp"
android:layout_marginEnd="0dp"
android:padding="8dp"
android:backgroundTint="@color/white"
android:src="@drawable/baseline_arrow_back_24"
app:layout_constraintDimensionRatio="1:1"
app:layout_constraintEnd_toStartOf="@id/search"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
/>
<EditText
android:id="@+id/search"
android:layout_width="0dp"
android:layout_height="48dp"
android:background="@drawable/search_background"
android:hint="@string/fragment_home_search"
android:textColor="@color/soft_gray"
android:textSize="16sp"
android:fontFamily="@font/dmsans_regular"
android:layout_marginStart="8dp"
android:drawablePadding="8dp"
android:paddingHorizontal="25dp"
android:imeOptions="actionSearch"
android:inputType="text"
app:layout_constraintEnd_toStartOf="@id/btn_cart"
app:layout_constraintTop_toTopOf="parent"
android:drawableStart="@drawable/baseline_search_24"
app:layout_constraintStart_toEndOf="@id/btn_back"/>
<ImageButton
android:id="@+id/btn_cart"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginEnd="8dp"
android:padding="8dp"
android:backgroundTint="@color/white"
android:src="@drawable/outline_shopping_cart_24"
app:layout_constraintDimensionRatio="1:1"
app:layout_constraintBottom_toBottomOf="@id/search"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@id/search"/>
</androidx.constraintlayout.widget.ConstraintLayout>