Skip to content

Commit ca5bb59

Browse files
feat: set new password ui and viewModel (#2857)
1 parent 5b16aa3 commit ca5bb59

File tree

10 files changed

+685
-14
lines changed

10 files changed

+685
-14
lines changed

feature/auth/src/commonMain/composeResources/values/strings.xml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,22 @@
147147
<string name="feature_otp_required_error">OTP is required</string>
148148
<string name="feature_otp_invalid_error">Enter valid OTP</string>
149149

150+
151+
<!--Set New Password-->
152+
153+
<string name="feature_set_new_password_title">Set Password</string>
154+
<string name="feature_set_new_password_message">Set your new high security password now!</string>
155+
<string name="feature_set_new_password_new_password_label">New Password</string>
156+
<string name="feature_set_new_password_confirm_password_label">Confirm New Password</string>
157+
<string name="feature_set_new_password_submit">Submit</string>
158+
<string name="feature_set_new_password_tip">Remember your password?</string>
159+
<string name="feature_set_new_password_action_tip">Log in</string>
160+
161+
<string name="feature_common_error_password_required_error">Password is Required</string>
162+
<string name="feature_common_error_password_short">Password must be at least 6 characters</string>
163+
<string name="feature_common_error_password_mismatch">Passwords do not match</string>
164+
165+
150166
<!--Recover Password-->
151167
<string name="feature_recover_now_title">Recover Now</string>
152168
<string name="feature_recover_now_message">Forgot your password, don’t worry!, we got you covered. Reset your password now!</string>

feature/auth/src/commonMain/kotlin/org/mifos/mobile/feature/auth/di/AuthModule.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,14 @@ import org.mifos.mobile.feature.auth.login.LoginViewModel
1515
import org.mifos.mobile.feature.auth.otpAuthentication.OtpAuthenticationViewModel
1616
import org.mifos.mobile.feature.auth.recoverPassword.RecoverPasswordViewModel
1717
import org.mifos.mobile.feature.auth.registration.RegistrationViewModel
18+
import org.mifos.mobile.feature.auth.setNewPassword.SetPasswordViewModel
1819
import org.mifos.mobile.feature.auth.uploadId.UploadIdViewModel
1920

2021
val AuthModule = module {
2122
viewModelOf(::LoginViewModel)
2223
viewModelOf(::RegistrationViewModel)
2324
viewModelOf(::UploadIdViewModel)
2425
viewModelOf(::OtpAuthenticationViewModel)
26+
viewModelOf(::SetPasswordViewModel)
2527
viewModelOf(::RecoverPasswordViewModel)
2628
}

feature/auth/src/commonMain/kotlin/org/mifos/mobile/feature/auth/navigation/AuthenticationNavGraph.kt

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ import org.mifos.mobile.feature.auth.recoverPassword.navigateToRecoverPasswordSc
2727
import org.mifos.mobile.feature.auth.recoverPassword.recoverPasswordDestination
2828
import org.mifos.mobile.feature.auth.registration.navigateToRegisterScreen
2929
import org.mifos.mobile.feature.auth.registration.registrationDestination
30+
import org.mifos.mobile.feature.auth.setNewPassword.navigateToSetPasswordScreen
31+
import org.mifos.mobile.feature.auth.setNewPassword.setPasswordDestination
3032
import org.mifos.mobile.feature.auth.status.navigateToStatusScreen
3133
import org.mifos.mobile.feature.auth.status.statusDestination
3234
import org.mifos.mobile.feature.auth.uploadId.navigateToUploadIdScreen
@@ -48,8 +50,7 @@ fun NavGraphBuilder.authenticationNavGraph(
4850
startDestination = LoginRoute,
4951
) {
5052
loginDestination(
51-
// navigateToRegisterScreen = navController::navigateToRegisterScreen,
52-
navigateToRegisterScreen = navController::navigateToOtpAuthScreen,
53+
navigateToRegisterScreen = navController::navigateToRegisterScreen,
5354
navigateToPasscodeScreen = navigateToPasscodeScreen,
5455
navigateToForgotPasswordScreen = navController::navigateToRecoverPasswordScreen,
5556
)
@@ -66,6 +67,7 @@ fun NavGraphBuilder.authenticationNavGraph(
6667

6768
otpAuthenticationDestination(
6869
navigateToStatusScreen = navController::navigateToStatusScreen,
70+
navigateToSetPasswordScreen = navController::navigateToSetPasswordScreen,
6971
)
7072

7173
statusDestination(
@@ -78,5 +80,10 @@ fun NavGraphBuilder.authenticationNavGraph(
7880
navigateToLoginScreen = navController::navigateToLoginScreen,
7981
navigateToOtpAuthenticationScreen = navController::navigateToOtpAuthScreen,
8082
)
83+
84+
setPasswordDestination(
85+
navigateToStatusScreen = navController::navigateToStatusScreen,
86+
navigateToLoginScreen = navController::navigateToLoginScreen,
87+
)
8188
}
8289
}

feature/auth/src/commonMain/kotlin/org/mifos/mobile/feature/auth/otpAuthentication/OtpAuthenticationNavigation.kt

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,22 +14,33 @@ package org.mifos.mobile.feature.auth.otpAuthentication
1414
import androidx.navigation.NavController
1515
import androidx.navigation.NavGraphBuilder
1616
import androidx.navigation.NavOptions
17+
import kotlinx.serialization.ExperimentalSerializationApi
1718
import kotlinx.serialization.Serializable
1819
import org.mifos.mobile.core.ui.composableWithStayTransitions
20+
import org.mifos.mobile.feature.auth.status.StatusNavigationRoute
1921

22+
@OptIn(ExperimentalSerializationApi::class)
2023
@Serializable
21-
data object OtpAuthenticationRoute
24+
data class OtpAuthenticationRoute(
25+
val nextRoute: String = StatusNavigationRoute.serializer().descriptor.serialName,
26+
)
2227

23-
fun NavController.navigateToOtpAuthScreen(navOptions: NavOptions? = null) {
24-
this.navigate(route = OtpAuthenticationRoute, navOptions = navOptions)
28+
@OptIn(ExperimentalSerializationApi::class)
29+
fun NavController.navigateToOtpAuthScreen(
30+
nextRoute: String = StatusNavigationRoute.serializer().descriptor.serialName,
31+
navOptions: NavOptions? = null,
32+
) {
33+
this.navigate(OtpAuthenticationRoute(nextRoute), navOptions)
2534
}
2635

2736
fun NavGraphBuilder.otpAuthenticationDestination(
2837
navigateToStatusScreen: (EventType, String) -> Unit,
38+
navigateToSetPasswordScreen: () -> Unit,
2939
) {
3040
composableWithStayTransitions<OtpAuthenticationRoute> {
3141
OtpAuthenticationScreen(
3242
navigateToStatusScreen = navigateToStatusScreen,
43+
navigateToSetPasswordScreen = navigateToSetPasswordScreen,
3344
)
3445
}
3546
}

feature/auth/src/commonMain/kotlin/org/mifos/mobile/feature/auth/otpAuthentication/OtpAuthenticationScreen.kt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ import org.mifos.mobile.core.ui.utils.EventsEffect
6767
@Composable
6868
internal fun OtpAuthenticationScreen(
6969
navigateToStatusScreen: (EventType, String) -> Unit,
70+
navigateToSetPasswordScreen: () -> Unit,
7071
modifier: Modifier = Modifier,
7172
viewModel: OtpAuthenticationViewModel = koinViewModel(),
7273
) {
@@ -80,6 +81,12 @@ internal fun OtpAuthenticationScreen(
8081
event.eventDestination,
8182
)
8283
}
84+
85+
is OtpAuthEvent.NavigateNext -> {
86+
if (uiState.nextRoute == "set_password") {
87+
navigateToSetPasswordScreen.invoke()
88+
}
89+
}
8390
}
8491
}
8592

feature/auth/src/commonMain/kotlin/org/mifos/mobile/feature/auth/otpAuthentication/OtpAuthenticationViewModel.kt

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@
99
*/
1010
package org.mifos.mobile.feature.auth.otpAuthentication
1111

12+
import androidx.lifecycle.SavedStateHandle
1213
import androidx.lifecycle.viewModelScope
14+
import androidx.navigation.toRoute
1315
import kotlinx.coroutines.Job
1416
import kotlinx.coroutines.delay
1517
import kotlinx.coroutines.flow.update
@@ -24,9 +26,22 @@ import org.jetbrains.compose.resources.StringResource
2426
import org.mifos.mobile.core.ui.utils.BaseViewModel
2527
import org.mifos.mobile.feature.auth.login.LoginRoute
2628

27-
internal class OtpAuthenticationViewModel : BaseViewModel<OtpAuthState, OtpAuthEvent, OtpAuthAction>(
29+
internal class OtpAuthenticationViewModel(
30+
savedStateHandle: SavedStateHandle,
31+
) : BaseViewModel<
32+
OtpAuthState,
33+
OtpAuthEvent,
34+
OtpAuthAction,
35+
>(
2836
initialState = OtpAuthState(dialogState = null),
2937
) {
38+
init {
39+
val nextRoute = savedStateHandle.toRoute<OtpAuthenticationRoute>()
40+
41+
mutableStateFlow.update {
42+
it.copy(nextRoute = nextRoute.nextRoute)
43+
}
44+
}
3045

3146
private var validationJob: Job? = null
3247

@@ -79,7 +94,24 @@ internal class OtpAuthenticationViewModel : BaseViewModel<OtpAuthState, OtpAuthE
7994
}
8095

8196
if (otpError == null) {
82-
registerUser()
97+
when {
98+
state.nextRoute == "set_password" -> handleRecoverPassword()
99+
else -> registerUser()
100+
}
101+
}
102+
}
103+
104+
@OptIn(InternalSerializationApi::class, ExperimentalSerializationApi::class)
105+
private fun handleRecoverPassword() {
106+
viewModelScope.launch {
107+
mutableStateFlow.update {
108+
it.copy(
109+
dialogState = OtpAuthState.DialogState.Loading,
110+
)
111+
}
112+
delay(3000)
113+
dismissDialog()
114+
sendEvent(OtpAuthEvent.NavigateNext)
83115
}
84116
}
85117

@@ -124,6 +156,9 @@ internal class OtpAuthenticationViewModel : BaseViewModel<OtpAuthState, OtpAuthE
124156
}
125157

126158
internal data class OtpAuthState(
159+
160+
val nextRoute: String = "",
161+
127162
val otp: String = "",
128163
val otpError: StringResource? = null,
129164

@@ -151,6 +186,8 @@ internal sealed interface OtpAuthAction {
151186
}
152187

153188
internal sealed interface OtpAuthEvent {
189+
data object NavigateNext : OtpAuthEvent
190+
154191
data class NavigateToStatus(
155192
val eventType: EventType,
156193
val eventDestination: String,
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/*
2+
* Copyright 2025 Mifos Initiative
3+
*
4+
* This Source Code Form is subject to the terms of the Mozilla Public
5+
* License, v. 2.0. If a copy of the MPL was not distributed with this
6+
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
7+
*
8+
* See https://github.com/openMF/mobile-mobile/blob/master/LICENSE.md
9+
*/
10+
@file:Suppress("MatchingDeclarationName")
11+
12+
package org.mifos.mobile.feature.auth.setNewPassword
13+
14+
import androidx.navigation.NavController
15+
import androidx.navigation.NavGraphBuilder
16+
import androidx.navigation.NavOptions
17+
import kotlinx.serialization.SerialName
18+
import kotlinx.serialization.Serializable
19+
import org.mifos.mobile.core.ui.composableWithSlideTransitions
20+
import org.mifos.mobile.feature.auth.otpAuthentication.EventType
21+
22+
@Serializable
23+
@SerialName("set_password")
24+
data object SetPasswordRoute
25+
26+
fun NavController.navigateToSetPasswordScreen(navOptions: NavOptions? = null) {
27+
this.navigate(SetPasswordRoute, navOptions)
28+
}
29+
30+
fun NavGraphBuilder.setPasswordDestination(
31+
navigateToStatusScreen: (EventType, String) -> Unit,
32+
navigateToLoginScreen: () -> Unit,
33+
) {
34+
composableWithSlideTransitions<SetPasswordRoute> {
35+
SetPasswordScreen(
36+
navigateToStatusScreen = navigateToStatusScreen,
37+
navigateToLoginScreen = navigateToLoginScreen,
38+
)
39+
}
40+
}

0 commit comments

Comments
 (0)