瀏覽代碼

Integrated forgot password API, created structure for forgot password screen

Khubaib 3 周之前
父節點
當前提交
19ff94bb47

+ 13 - 0
app/src/main/java/com/fastest/pass/forgotpassword/data/remote/ForgotPasswordApiService.kt

@@ -0,0 +1,13 @@
+package com.fastest.pass.forgotpassword.data.remote
+
+import com.fastest.pass.app.WebResponse
+import retrofit2.http.Body
+import retrofit2.http.Headers
+import retrofit2.http.POST
+import java.util.Objects
+
+interface ForgotPasswordApiService {
+
+    @POST("forgot-password")
+    suspend fun forgotPassword(@Body email: String) : WebResponse<Objects>
+}

+ 16 - 0
app/src/main/java/com/fastest/pass/forgotpassword/data/repository/ForgotPasswordRepositoryImpl.kt

@@ -0,0 +1,16 @@
+package com.fastest.pass.forgotpassword.data.repository
+
+import com.fastest.pass.app.WebResponse
+import com.fastest.pass.forgotpassword.data.remote.ForgotPasswordApiService
+import com.fastest.pass.forgotpassword.domain.repository.ForgotPasswordRepository
+import java.util.Objects
+import javax.inject.Inject
+
+class ForgotPasswordRepositoryImpl @Inject constructor(
+    private val forgotPasswordApiService: ForgotPasswordApiService
+) : ForgotPasswordRepository{
+    override suspend fun forgotPasswordRepository(email: String): WebResponse<Objects> {
+        return forgotPasswordApiService.forgotPassword(email)
+    }
+
+}

+ 16 - 0
app/src/main/java/com/fastest/pass/forgotpassword/di/ForgotPasswordModule.kt

@@ -1,10 +1,14 @@
 package com.fastest.pass.forgotpassword.di
 
+import com.fastest.pass.forgotpassword.data.remote.ForgotPasswordApiService
+import com.fastest.pass.forgotpassword.data.repository.ForgotPasswordRepositoryImpl
+import com.fastest.pass.forgotpassword.domain.repository.ForgotPasswordRepository
 import com.fastest.pass.forgotpassword.utils.ForgotPasswordNavigation
 import dagger.Module
 import dagger.Provides
 import dagger.hilt.InstallIn
 import dagger.hilt.components.SingletonComponent
+import retrofit2.Retrofit
 import javax.inject.Singleton
 
 @Module
@@ -16,4 +20,16 @@ object ForgotPasswordModule {
     fun provideNavigation(): ForgotPasswordNavigation {
         return ForgotPasswordNavigation()
     }
+
+    @Provides
+    @Singleton
+    fun provideForgotPasswordApiService(retrofit: Retrofit) : ForgotPasswordApiService {
+        return retrofit.create(ForgotPasswordApiService::class.java)
+    }
+
+    @Provides
+    @Singleton
+    fun provideForgotPasswordRepository(forgotPasswordApiService: ForgotPasswordApiService) : ForgotPasswordRepository {
+        return ForgotPasswordRepositoryImpl(forgotPasswordApiService)
+    }
 }

+ 8 - 0
app/src/main/java/com/fastest/pass/forgotpassword/domain/repository/ForgotPasswordRepository.kt

@@ -0,0 +1,8 @@
+package com.fastest.pass.forgotpassword.domain.repository
+
+import com.fastest.pass.app.WebResponse
+import java.util.Objects
+
+interface ForgotPasswordRepository {
+    suspend fun forgotPasswordRepository(email: String) : WebResponse<Objects>
+}

+ 16 - 0
app/src/main/java/com/fastest/pass/forgotpassword/domain/usecase/ForgotPasswordUseCase.kt

@@ -0,0 +1,16 @@
+package com.fastest.pass.forgotpassword.domain.usecase
+
+import com.fastest.pass.app.BaseUseCase
+import com.fastest.pass.app.WebResponse
+import com.fastest.pass.forgotpassword.domain.repository.ForgotPasswordRepository
+import java.util.Objects
+import javax.inject.Inject
+
+class ForgotPasswordUseCase @Inject constructor(
+    private val forgotPasswordRepository: ForgotPasswordRepository
+) : BaseUseCase<String, WebResponse<Objects>>(){
+
+    override suspend fun execute(params: String): WebResponse<Objects> {
+        return forgotPasswordRepository.forgotPasswordRepository(params)
+    }
+}

+ 21 - 8
app/src/main/java/com/fastest/pass/forgotpassword/presentation/ui/ForgotPasswordFragment.kt

@@ -1,12 +1,14 @@
 package com.fastest.pass.forgotpassword.presentation.ui
 
 import android.os.Bundle
+import android.util.Log
 import android.view.LayoutInflater
 import android.view.View
 import android.view.ViewGroup
 import androidx.compose.ui.platform.ComposeView
 import androidx.fragment.app.viewModels
 import com.fastest.pass.app.BaseFragment
+import com.fastest.pass.app.GenericLoader
 import com.fastest.pass.forgotpassword.presentation.ui.components.ClickType
 import com.fastest.pass.forgotpassword.presentation.ui.components.ForgotPasswordScreen
 import com.fastest.pass.forgotpassword.presentation.viewmodels.ForgotPasswordViewmodel
@@ -37,17 +39,28 @@ class ForgotPasswordFragment : BaseFragment() {
         return ComposeView(requireActivity()).apply {
             setContent {
                 FastestPassTheme {
-                    ForgotPasswordScreen { clickType ->
-                        when (clickType) {
-                            ClickType.GO_BACK -> {
-                                viewmodel.navigateTo(ForgotPasswordRoute.GoBackToLogin)
-                            }
+                    val forgotPasswordResponse = viewmodel.forgotPasswordResponse.value
+                    Log.d("forgotPasswordResponse", "forgotPasswordResponse = ${forgotPasswordResponse.response?.message}")
 
-                            ClickType.OPEN_FORGOT_VERIFY -> {
-                                viewmodel.navigateTo(ForgotPasswordRoute.OpenForgotVerifyScreen)
+                    ForgotPasswordScreen(
+                        clickType = { clickType ->
+                            when (clickType) {
+                                ClickType.GO_BACK -> {
+                                    viewmodel.navigateTo(ForgotPasswordRoute.GoBackToLogin)
+                                }
+                                ClickType.OPEN_FORGOT_VERIFY -> {
+                                    viewmodel.navigateTo(ForgotPasswordRoute.OpenForgotVerifyScreen)
+                                }
+                                ClickType.FORGOT_API -> {}
                             }
+                        },
+                        onSendButtonClicked = { email ->
+                            Log.d("forgotPasswordResponse", "onSendButtonClicked: email = $email")
+                            viewmodel.forgotPassword(email)
                         }
-                    }
+                    )
+
+                    GenericLoader(loader = forgotPasswordResponse.isLoading)
                 }
             }
         }

+ 28 - 9
app/src/main/java/com/fastest/pass/forgotpassword/presentation/ui/components/ForgotPasswordScreen.kt

@@ -53,13 +53,18 @@ import com.fastest.pass.R
 
 enum class ClickType {
     GO_BACK,
-    OPEN_FORGOT_VERIFY
+    OPEN_FORGOT_VERIFY,
+    FORGOT_API
 }
 
 @Composable
-fun ForgotPasswordScreen(clickType: (ClickType) -> Unit) {
+fun ForgotPasswordScreen(
+    clickType: (ClickType) -> Unit,
+    onSendButtonClicked: (String) -> Unit
+    ) {
     val keyboardController = LocalSoftwareKeyboardController.current
     val focusManager = LocalFocusManager.current
+    var email by remember { mutableStateOf("") }
 
     Box(
         modifier = Modifier
@@ -92,11 +97,19 @@ fun ForgotPasswordScreen(clickType: (ClickType) -> Unit) {
                     )
             ) {
                 ForgotPasswordText(R.string.email_associated_account)
-                LoginTextFieldFP(keyboardController = keyboardController, focusManager = focusManager)
+                LoginTextFieldFP(
+                    keyboardController = keyboardController,
+                    focusManager = focusManager,
+                    onEmailText = { email = it }
+                )
                 Spacer(modifier = Modifier.height(25.dp))
-                SendCodeButton(buttonText = R.string.send_email) { clickType ->
-                    clickType(clickType)
-                }
+                SendCodeButton(
+                    buttonText = R.string.send_email,
+                    clickType = { clickType -> clickType(clickType) },
+                    onSendButtonClicked = {
+                        if (email.isNotEmpty()) { onSendButtonClicked.invoke(email) }
+                    }
+                )
             }
 
         }
@@ -174,7 +187,8 @@ fun ColumnScope.ForgotPasswordText(
 @Composable
 fun ColumnScope.LoginTextFieldFP(
     keyboardController: SoftwareKeyboardController?,
-    focusManager: FocusManager
+    focusManager: FocusManager,
+    onEmailText: (String) -> Unit
 ) {
     var emailText by remember { mutableStateOf("") }
 
@@ -182,6 +196,7 @@ fun ColumnScope.LoginTextFieldFP(
         value = emailText,
         onValueChange = {
             emailText = it
+            onEmailText.invoke(emailText)
         },
         textStyle = MaterialTheme.typography.displayMedium,
         modifier = Modifier
@@ -241,7 +256,11 @@ fun ColumnScope.LoginTextFieldFP(
 }
 
 @Composable
-fun ColumnScope.SendCodeButton(buttonText: Int, clickType: (ClickType) -> Unit) {
+fun ColumnScope.SendCodeButton(
+    buttonText: Int,
+    clickType: (ClickType) -> Unit,
+    onSendButtonClicked: () -> Unit
+) {
     Button(
         modifier = Modifier
             .padding(start = 30.dp, end = 30.dp,)
@@ -250,7 +269,7 @@ fun ColumnScope.SendCodeButton(buttonText: Int, clickType: (ClickType) -> Unit)
             .height(60.dp)
             .clickable() {},
         onClick = {
-//            clickType.invoke(ClickType.OPEN_FORGOT_VERIFY)
+            onSendButtonClicked.invoke()
         },
         shape = RoundedCornerShape(15.dp),
 //            border = BorderStroke(25.dp, colorResource(id = R.color.black)),

+ 38 - 1
app/src/main/java/com/fastest/pass/forgotpassword/presentation/viewmodels/ForgotPasswordViewmodel.kt

@@ -1,15 +1,52 @@
 package com.fastest.pass.forgotpassword.presentation.viewmodels
 
+import android.util.Log
+import androidx.compose.runtime.State
+import androidx.compose.runtime.mutableStateOf
 import androidx.lifecycle.ViewModel
+import androidx.lifecycle.viewModelScope
+import com.fastest.pass.app.Result
+import com.fastest.pass.app.UIState
+import com.fastest.pass.app.WebResponse
+import com.fastest.pass.forgotpassword.domain.usecase.ForgotPasswordUseCase
 import com.fastest.pass.forgotpassword.utils.ForgotPasswordRoute
 import com.fastest.pass.login.utils.LoginRoute
+import dagger.hilt.android.lifecycle.HiltViewModel
 import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.launch
+import java.util.Objects
+import javax.inject.Inject
 
-class ForgotPasswordViewmodel : ViewModel() {
+@HiltViewModel
+class ForgotPasswordViewmodel @Inject constructor(
+    private val forgotPasswordUseCase: ForgotPasswordUseCase
+): ViewModel() {
 
     private val _router = MutableStateFlow<ForgotPasswordRoute>(ForgotPasswordRoute.OpenNoneScreen)
     val router: MutableStateFlow<ForgotPasswordRoute> = _router
 
+    private var _forgotPasswordResponse = mutableStateOf(UIState<WebResponse<Objects>>())
+    val forgotPasswordResponse: State<UIState<WebResponse<Objects>>> = _forgotPasswordResponse
+
+    fun forgotPassword(email: String) {
+        viewModelScope.launch {
+            forgotPasswordUseCase(email) { result ->
+                Log.d("forgotPasswordResponse", "result = $result")
+                when (result) {
+                    is Result.Loading -> {
+                        _forgotPasswordResponse.value = UIState(true)
+                    }
+                    is Result.Success -> {
+                        _forgotPasswordResponse.value = UIState(false, result.data)
+                    }
+                    is Result.Failure -> {
+                        _forgotPasswordResponse.value = UIState(false)
+                    }
+                }
+            }
+        }
+    }
+
     fun navigateTo(forgotPasswordRoute: ForgotPasswordRoute) {
         _router.value = forgotPasswordRoute
     }