diff --git a/app/build.gradle.kts b/app/build.gradle.kts
index 5be48a8..724cb49 100644
--- a/app/build.gradle.kts
+++ b/app/build.gradle.kts
@@ -23,7 +23,7 @@ android {
buildTypes {
release {
- buildConfigField("String", "BASE_URL", "\"http://192.168.1.13:3000/\"")
+ buildConfigField("String", "BASE_URL", "\"http://192.168.1.6:3000/\"")
isMinifyEnabled = false
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
@@ -31,7 +31,7 @@ android {
)
}
debug {
- buildConfigField("String", "BASE_URL", "\"http://192.168.1.13:3000/\"")
+ buildConfigField("String", "BASE_URL", "\"http://192.168.1.6:3000/\"")
}
}
compileOptions {
@@ -72,6 +72,8 @@ dependencies {
implementation("com.github.bumptech.glide:glide:4.16.0")
implementation("androidx.paging:paging-runtime:3.2.1")
implementation("androidx.swiperefreshlayout:swiperefreshlayout:1.1.0")
+ implementation("de.hdodenhof:circleimageview:3.1.0")
+
// implementation(libs.hilt.android)
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index e00fc08..8986548 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -2,7 +2,7 @@
-
+
+ tools:targetApi="31">
-
@@ -28,6 +25,20 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/java/com/alya/ecommerce_serang/data/api/dto/LoginRequest.kt b/app/src/main/java/com/alya/ecommerce_serang/data/api/dto/LoginRequest.kt
new file mode 100644
index 0000000..bcf9afb
--- /dev/null
+++ b/app/src/main/java/com/alya/ecommerce_serang/data/api/dto/LoginRequest.kt
@@ -0,0 +1,6 @@
+package com.alya.ecommerce_serang.data.api.dto
+
+data class LoginRequest (
+ val email: String,
+ val password: String,
+)
\ No newline at end of file
diff --git a/app/src/main/java/com/alya/ecommerce_serang/data/api/dto/OtpRequest.kt b/app/src/main/java/com/alya/ecommerce_serang/data/api/dto/OtpRequest.kt
new file mode 100644
index 0000000..00f383b
--- /dev/null
+++ b/app/src/main/java/com/alya/ecommerce_serang/data/api/dto/OtpRequest.kt
@@ -0,0 +1,7 @@
+package com.alya.ecommerce_serang.data.api.dto
+
+import com.google.gson.annotations.SerializedName
+
+data class OtpRequest(
+ @SerializedName("email") val email: String
+)
\ No newline at end of file
diff --git a/app/src/main/java/com/alya/ecommerce_serang/data/api/dto/RegisterRequest.kt b/app/src/main/java/com/alya/ecommerce_serang/data/api/dto/RegisterRequest.kt
new file mode 100644
index 0000000..0e38c12
--- /dev/null
+++ b/app/src/main/java/com/alya/ecommerce_serang/data/api/dto/RegisterRequest.kt
@@ -0,0 +1,12 @@
+package com.alya.ecommerce_serang.data.api.dto
+
+data class RegisterRequest (
+ val name: String?,
+ val email: String?,
+ val password: String?,
+ val username: String?,
+ val phone: String?,
+ val birthDate: String?,
+ val image: String?,
+ val otp: String? = null
+)
\ No newline at end of file
diff --git a/app/src/main/java/com/alya/ecommerce_serang/data/api/response/LoginResponse.kt b/app/src/main/java/com/alya/ecommerce_serang/data/api/response/LoginResponse.kt
new file mode 100644
index 0000000..58c9206
--- /dev/null
+++ b/app/src/main/java/com/alya/ecommerce_serang/data/api/response/LoginResponse.kt
@@ -0,0 +1,15 @@
+package com.alya.ecommerce_serang.data.api.response
+
+import com.google.gson.annotations.SerializedName
+
+data class LoginResponse(
+
+ @field:SerializedName("role")
+ val role: String,
+
+ @field:SerializedName("message")
+ val message: String,
+
+ @field:SerializedName("accessToken")
+ val accessToken: String
+)
diff --git a/app/src/main/java/com/alya/ecommerce_serang/data/api/response/OtpResponse.kt b/app/src/main/java/com/alya/ecommerce_serang/data/api/response/OtpResponse.kt
new file mode 100644
index 0000000..60a87f5
--- /dev/null
+++ b/app/src/main/java/com/alya/ecommerce_serang/data/api/response/OtpResponse.kt
@@ -0,0 +1,9 @@
+package com.alya.ecommerce_serang.data.api.response
+
+import com.google.gson.annotations.SerializedName
+
+data class OtpResponse(
+
+ @field:SerializedName("message")
+ val message: String
+)
diff --git a/app/src/main/java/com/alya/ecommerce_serang/data/api/response/RegisterResponse.kt b/app/src/main/java/com/alya/ecommerce_serang/data/api/response/RegisterResponse.kt
new file mode 100644
index 0000000..1136015
--- /dev/null
+++ b/app/src/main/java/com/alya/ecommerce_serang/data/api/response/RegisterResponse.kt
@@ -0,0 +1,42 @@
+package com.alya.ecommerce_serang.data.api.response
+
+import com.google.gson.annotations.SerializedName
+
+data class RegisterResponse(
+
+ @field:SerializedName("message")
+ val message: String,
+
+ @field:SerializedName("user")
+ val user: User
+)
+
+data class User(
+
+ @field:SerializedName("image")
+ val image: String,
+
+ @field:SerializedName("password")
+ val password: String,
+
+ @field:SerializedName("role")
+ val role: String,
+
+ @field:SerializedName("phone")
+ val phone: String,
+
+ @field:SerializedName("birth_date")
+ val birthDate: String,
+
+ @field:SerializedName("name")
+ val name: String,
+
+ @field:SerializedName("id")
+ val id: Int,
+
+ @field:SerializedName("email")
+ val email: String,
+
+ @field:SerializedName("username")
+ val username: String
+)
diff --git a/app/src/main/java/com/alya/ecommerce_serang/data/api/response/StoreResponse.kt b/app/src/main/java/com/alya/ecommerce_serang/data/api/response/StoreResponse.kt
new file mode 100644
index 0000000..386de42
--- /dev/null
+++ b/app/src/main/java/com/alya/ecommerce_serang/data/api/response/StoreResponse.kt
@@ -0,0 +1,138 @@
+package com.alya.ecommerce_serang.data.api.response
+
+import com.google.gson.annotations.SerializedName
+
+data class StoreResponse(
+
+ @field:SerializedName("shipping")
+ val shipping: List,
+
+ @field:SerializedName("payment")
+ val payment: List,
+
+ @field:SerializedName("store")
+ val store: Store,
+
+ @field:SerializedName("message")
+ val message: String
+)
+
+data class Store(
+
+ @field:SerializedName("approval_reason")
+ val approvalReason: String,
+
+ @field:SerializedName("store_status")
+ val storeStatus: String,
+
+ @field:SerializedName("sppirt")
+ val sppirt: String,
+
+ @field:SerializedName("user_name")
+ val userName: String,
+
+ @field:SerializedName("nib")
+ val nib: String,
+
+ @field:SerializedName("latitude")
+ val latitude: String,
+
+ @field:SerializedName("store_type_id")
+ val storeTypeId: Int,
+
+ @field:SerializedName("balance")
+ val balance: String,
+
+ @field:SerializedName("street")
+ val street: String,
+
+ @field:SerializedName("store_name")
+ val storeName: String,
+
+ @field:SerializedName("user_phone")
+ val userPhone: String,
+
+ @field:SerializedName("halal")
+ val halal: String,
+
+ @field:SerializedName("id")
+ val id: Int,
+
+ @field:SerializedName("email")
+ val email: String,
+
+ @field:SerializedName("store_image")
+ val storeImage: Any,
+
+ @field:SerializedName("longitude")
+ val longitude: String,
+
+ @field:SerializedName("store_id")
+ val storeId: Int,
+
+ @field:SerializedName("is_store_location")
+ val isStoreLocation: Boolean,
+
+ @field:SerializedName("ktp")
+ val ktp: String,
+
+ @field:SerializedName("approval_status")
+ val approvalStatus: String,
+
+ @field:SerializedName("npwp")
+ val npwp: String,
+
+ @field:SerializedName("store_type")
+ val storeType: String,
+
+ @field:SerializedName("is_on_leave")
+ val isOnLeave: Boolean,
+
+ @field:SerializedName("user_id")
+ val userId: Int,
+
+ @field:SerializedName("province_id")
+ val provinceId: Int,
+
+ @field:SerializedName("phone")
+ val phone: String,
+
+ @field:SerializedName("subdistrict")
+ val subdistrict: String,
+
+ @field:SerializedName("recipient")
+ val recipient: String,
+
+ @field:SerializedName("detail")
+ val detail: String,
+
+ @field:SerializedName("postal_code")
+ val postalCode: String,
+
+ @field:SerializedName("store_description")
+ val storeDescription: String,
+
+ @field:SerializedName("city_id")
+ val cityId: Int
+)
+
+data class ShippingItem(
+
+ @field:SerializedName("courier")
+ val courier: String
+)
+
+data class PaymentItem(
+
+ @field:SerializedName("qris_image")
+ val qrisImage: String,
+
+ @field:SerializedName("bank_num")
+ val bankNum: String,
+
+ @field:SerializedName("bank_name")
+ val bankName: String,
+
+ @field:SerializedName("id")
+ val id: Int
+)
diff --git a/app/src/main/java/com/alya/ecommerce_serang/data/api/retrofit/ApiConfig.kt b/app/src/main/java/com/alya/ecommerce_serang/data/api/retrofit/ApiConfig.kt
index 3a2e8f4..43720e3 100644
--- a/app/src/main/java/com/alya/ecommerce_serang/data/api/retrofit/ApiConfig.kt
+++ b/app/src/main/java/com/alya/ecommerce_serang/data/api/retrofit/ApiConfig.kt
@@ -1,24 +1,51 @@
package com.alya.ecommerce_serang.data.api.retrofit
import com.alya.ecommerce_serang.BuildConfig
+import com.alya.ecommerce_serang.utils.AuthInterceptor
+import com.alya.ecommerce_serang.utils.SessionManager
import okhttp3.OkHttpClient
import okhttp3.logging.HttpLoggingInterceptor
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
class ApiConfig {
- companion object{
- fun getApiService(): ApiService {
- val loggingInterceptor =
- HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY)
+ companion object {
+ fun getApiService(tokenManager: SessionManager): ApiService {
+ val loggingInterceptor = HttpLoggingInterceptor().apply {
+ level = HttpLoggingInterceptor.Level.BODY
+ }
+
+ val authInterceptor = AuthInterceptor(tokenManager)
+
val client = OkHttpClient.Builder()
.addInterceptor(loggingInterceptor)
+ .addInterceptor(authInterceptor)
.build()
+
val retrofit = Retrofit.Builder()
.baseUrl(BuildConfig.BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.client(client)
.build()
+
+ return retrofit.create(ApiService::class.java)
+ }
+
+ fun getUnauthenticatedApiService(): ApiService {
+ val loggingInterceptor = HttpLoggingInterceptor().apply {
+ level = HttpLoggingInterceptor.Level.BODY
+ }
+
+ val client = OkHttpClient.Builder()
+ .addInterceptor(loggingInterceptor)
+ .build()
+
+ val retrofit = Retrofit.Builder()
+ .baseUrl(BuildConfig.BASE_URL)
+ .addConverterFactory(GsonConverterFactory.create())
+ .client(client)
+ .build()
+
return retrofit.create(ApiService::class.java)
}
}
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 02e6bd2..ca78eab 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
@@ -1,28 +1,45 @@
package com.alya.ecommerce_serang.data.api.retrofit
+import com.alya.ecommerce_serang.data.api.dto.LoginRequest
+import com.alya.ecommerce_serang.data.api.dto.OtpRequest
+import com.alya.ecommerce_serang.data.api.dto.RegisterRequest
import com.alya.ecommerce_serang.data.api.response.AllProductResponse
+import com.alya.ecommerce_serang.data.api.response.LoginResponse
+import com.alya.ecommerce_serang.data.api.response.OtpResponse
import com.alya.ecommerce_serang.data.api.response.ProductResponse
+import com.alya.ecommerce_serang.data.api.response.RegisterResponse
import com.alya.ecommerce_serang.data.api.response.StoreResponse
import retrofit2.Call
+import retrofit2.Response
+import retrofit2.http.Body
import retrofit2.http.GET
-import retrofit2.http.Header
+import retrofit2.http.POST
import retrofit2.http.Path
interface ApiService {
- @GET("product")
- fun getAllProduct(
- @Header("Authorization") token: String = "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6NzEsIm5hbWUiOiJhbHlhIiwiZW1haWwiOiJha3VuYmVsYWphci5hbHlhQGdtYWlsLmNvbSIsInJvbGUiOiJ1c2VyIiwiaWF0IjoxNzM4NDg0OTc0LCJleHAiOjE3NDEwNzY5NzR9.0JyXJQ_6CKiZEi0gvk1gcn-0ILu3a9lOr3HqjhJXbBE"
- ): Call
+ @POST("registeruser")
+ suspend fun register (
+ @Body registerRequest: RegisterRequest
+ ): Response
+ @POST("otp")
+ suspend fun getOTP(
+ @Body otpRequest: OtpRequest
+ ):OtpResponse
+
+ @POST("login")
+ fun login(
+ @Body loginRequest: LoginRequest
+ ): Call
+
+ @GET("product")
+ fun getAllProduct(): Call
@GET("product/detail/{id}")
fun getDetailProduct (
- @Header("Authorization") token: String,
@Path("id") productId: Int
): Call
@GET("mystore")
- fun getStore (
- @Header("Authorization") token: String = "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6NzEsIm5hbWUiOiJhbHlhIiwiZW1haWwiOiJha3VuYmVsYWphci5hbHlhQGdtYWlsLmNvbSIsInJvbGUiOiJ1c2VyIiwiaWF0IjoxNzM4NDg0OTc0LCJleHAiOjE3NDEwNzY5NzR9.0JyXJQ_6CKiZEi0gvk1gcn-0ILu3a9lOr3HqjhJXbBE"
- ): Call
+ fun getStore (): Call
}
\ No newline at end of file
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 1f73cbd..47f561c 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
@@ -17,19 +17,15 @@ class ProductRepository(private val apiService: ApiService) {
Log.d("ProductRepository", "Response message: ${response.message()}")
if (response.isSuccessful) {
- Result.success(response.body()?.products ?: emptyList())
+ // Return a Result.Success with the list of products
+ Result.Success(response.body()?.products ?: emptyList())
} else {
- Result.failure(Exception("Failed to fetch products"))
+ // Return a Result.Error with a custom Exception
+ Result.Error(Exception("Failed to fetch products. Code: ${response.code()}"))
}
} catch (e: Exception) {
- Result.failure(e)
+ // Return a Result.Error with the exception caught
+ Result.Error(e)
}
}
-// suspend fun getCategories():List
-//
-// fun getProducts(query: ProductQuery) : Flow>
-// fun getRecentSearchs(): Flow>
-// suspend fun clearRecents()
-// suspend fun addRecents(search:String)
-// suspend fun getProduct(id:String):DetailProduct
}
\ No newline at end of file
diff --git a/app/src/main/java/com/alya/ecommerce_serang/data/repository/UserRepository.kt b/app/src/main/java/com/alya/ecommerce_serang/data/repository/UserRepository.kt
new file mode 100644
index 0000000..e7e57ac
--- /dev/null
+++ b/app/src/main/java/com/alya/ecommerce_serang/data/repository/UserRepository.kt
@@ -0,0 +1,34 @@
+package com.alya.ecommerce_serang.data.repository
+
+import com.alya.ecommerce_serang.data.api.dto.OtpRequest
+import com.alya.ecommerce_serang.data.api.dto.RegisterRequest
+import com.alya.ecommerce_serang.data.api.response.OtpResponse
+import com.alya.ecommerce_serang.data.api.retrofit.ApiService
+
+class UserRepository(private val apiService: ApiService) {
+
+ suspend fun requestOtpRep(email: String): OtpResponse {
+
+// fun requestOtpRep(email: String): Result {
+
+ return apiService.getOTP(OtpRequest(email))
+
+ }
+
+ suspend fun registerUser(request: RegisterRequest): String {
+ val response = apiService.register(request) // API call
+
+ if (response.isSuccessful) {
+ val responseBody = response.body() ?: throw Exception("Empty response body")
+ return responseBody.message // Get the message from RegisterResponse
+ } else {
+ throw Exception("Registration failed: ${response.errorBody()?.string()}")
+ }
+ }
+}
+
+sealed class Result {
+ data class Success(val data: T) : Result()
+ data class Error(val exception: Throwable) : Result()
+ object Loading : Result()
+}
\ No newline at end of file
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
new file mode 100644
index 0000000..673762e
--- /dev/null
+++ b/app/src/main/java/com/alya/ecommerce_serang/ui/auth/LoginActivity.kt
@@ -0,0 +1,21 @@
+package com.alya.ecommerce_serang.ui.auth
+
+import android.os.Bundle
+import androidx.activity.enableEdgeToEdge
+import androidx.appcompat.app.AppCompatActivity
+import androidx.core.view.ViewCompat
+import androidx.core.view.WindowInsetsCompat
+import com.alya.ecommerce_serang.R
+
+class LoginActivity : AppCompatActivity() {
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ enableEdgeToEdge()
+ setContentView(R.layout.activity_login)
+ ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main)) { v, insets ->
+ val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
+ v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom)
+ insets
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/alya/ecommerce_serang/ui/auth/OtpBottomsheetDialog.kt b/app/src/main/java/com/alya/ecommerce_serang/ui/auth/OtpBottomsheetDialog.kt
new file mode 100644
index 0000000..c20b7f9
--- /dev/null
+++ b/app/src/main/java/com/alya/ecommerce_serang/ui/auth/OtpBottomsheetDialog.kt
@@ -0,0 +1,41 @@
+package com.alya.ecommerce_serang.ui.auth
+
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.Button
+import android.widget.EditText
+import android.widget.Toast
+import com.alya.ecommerce_serang.R
+import com.alya.ecommerce_serang.data.api.dto.RegisterRequest
+import com.google.android.material.bottomsheet.BottomSheetDialogFragment
+
+class OtpBottomSheetDialog(
+ private val userData: RegisterRequest, // Store user data
+ private val onRegister: (RegisterRequest) -> Unit)
+ : BottomSheetDialogFragment() {
+
+ override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
+ val view = inflater.inflate(R.layout.dialog_otp, container, false)
+
+ val etOtp = view.findViewById(R.id.etOtp)
+ val btnSubmit = view.findViewById