Skip to content

Commit 1f05c64

Browse files
committed
feat(android_sidebar): adding the profil page and password edit
1 parent 6da09af commit 1f05c64

File tree

11 files changed

+118
-57
lines changed

11 files changed

+118
-57
lines changed
Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
package com.xpeho.xpeapp.data.entity.user
22

3+
import com.google.gson.annotations.SerializedName
4+
35
data class UserEditPassword(
4-
val initialPassword: String,
5-
val password: String,
6-
val passwordRepeat: String,
6+
@SerializedName("initial_password") val initialPassword: String,
7+
@SerializedName("password") val password: String,
8+
@SerializedName("password_repeat") val passwordRepeat: String,
9+
10+
711
)
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package com.xpeho.xpeapp.data.model.user
2+
3+
sealed interface UpdatePasswordResult{
4+
object IncorrectInitialPassword : UpdatePasswordResult
5+
object PasswordMismatch : UpdatePasswordResult
6+
object Success : UpdatePasswordResult
7+
object NetworkError : UpdatePasswordResult
8+
}

xpeapp_android/app/src/main/java/com/xpeho/xpeapp/data/service/WordpressRepository.kt

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import com.xpeho.xpeapp.data.model.WordpressToken
1212
import com.xpeho.xpeapp.data.model.qvst.QvstCampaign
1313
import com.xpeho.xpeapp.data.model.qvst.QvstProgress
1414
import com.xpeho.xpeapp.data.model.qvst.QvstQuestion
15+
import com.xpeho.xpeapp.data.model.user.UpdatePasswordResult
1516
import retrofit2.HttpException
1617
import java.net.ConnectException
1718
import java.net.SocketTimeoutException
@@ -27,6 +28,8 @@ class WordpressRepository(
2728

2829
companion object {
2930
private const val HTTPFORBIDDEN = 403
31+
private const val INTERNAL_SERVER_ERROR = 500
32+
private const val NO_CONTENT = 204
3033

3134
private const val DATETIME_FORMATTER_PATTERN = "yyyy-MM-dd"
3235
}
@@ -200,19 +203,34 @@ class WordpressRepository(
200203
)
201204
}
202205

203-
/*suspend fun updatePassword(
206+
suspend fun updatePassword(
204207
editPassword: UserEditPassword
205-
): Boolean {
208+
): UpdatePasswordResult {
206209
handleServiceExceptions(
207210
tryBody = {
208-
return api.updatePassword(editPassword)
211+
val result = api.updatePassword(editPassword)
212+
when (result.code()) {
213+
NO_CONTENT -> return UpdatePasswordResult.Success
214+
INTERNAL_SERVER_ERROR -> result.errorBody()?.string()?.let {
215+
if (it.contains("incorrect_password")) {
216+
Log.d("WordpressRepository: updatePassword", "Incorrect initial password")
217+
return UpdatePasswordResult.IncorrectInitialPassword
218+
}
219+
if (it.contains("password_mismatch")) {
220+
Log.d("WordpressRepository: updatePassword", "Password mismatch")
221+
return UpdatePasswordResult.PasswordMismatch
222+
}
223+
}
224+
}
225+
Log.e("WordpressRepository: updatePassword", "Unknown error: ${result.code()}")
226+
return UpdatePasswordResult.NetworkError
209227
},
210-
catchBody = { e ->
211-
Log.e("WordpressRepository: updatePassword", "Network error: ${e.message}")
212-
return false
228+
catchBody = {
229+
Log.e("WordpressRepository: fetchUserInfos", "Network error: ${it.message}")
230+
return UpdatePasswordResult.NetworkError
213231
}
214232
)
215-
}*/
233+
}
216234

217235
// Exceptions handling
218236

xpeapp_android/app/src/main/java/com/xpeho/xpeapp/data/service/WordpressService.kt

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,13 @@ import com.xpeho.xpeapp.data.model.WordpressToken
88
import com.xpeho.xpeapp.data.model.qvst.QvstCampaign
99
import com.xpeho.xpeapp.data.model.qvst.QvstProgress
1010
import com.xpeho.xpeapp.data.model.qvst.QvstQuestion
11+
import retrofit2.Response
1112
import retrofit2.http.Body
1213
import retrofit2.http.GET
1314
import retrofit2.http.Header
1415
import retrofit2.http.Headers
1516
import retrofit2.http.POST
17+
import retrofit2.http.PUT
1618
import retrofit2.http.Path
1719
import retrofit2.http.Query
1820

@@ -67,11 +69,11 @@ interface WordpressService {
6769
@GET("xpeho/v1/user-infos")
6870
suspend fun fetchUserInfos(): UserInfos
6971

70-
/*// Update the user infos
72+
// Update the user infos
7173
@Headers("Content-Type: application/json")
72-
@POST("xpeho/v1/update-password")
74+
@PUT("xpeho/v1/update-password")
7375
suspend fun updatePassword(
74-
@Body editPassword: UserEditPassword,
75-
): Boolean*/
76+
@Body editPassword: UserEditPassword
77+
): Response<String>
7678
}
7779

xpeapp_android/app/src/main/java/com/xpeho/xpeapp/di/AppModule.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ class MainAppModule(
3535

3636
private val gson = GsonBuilder().setLenient().create()
3737

38-
private val logging = HttpLoggingInterceptor().apply { level = HttpLoggingInterceptor.Level.BODY }
38+
private val logging = HttpLoggingInterceptor().apply { level = HttpLoggingInterceptor.Level.BASIC }
3939
private val authorization by lazy {
4040
AuthorizationHeaderInterceptor(
4141
tokenProvider = tokenProvider

xpeapp_android/app/src/main/java/com/xpeho/xpeapp/ui/page/user/ProfileEditPasswordView.kt

Lines changed: 31 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,23 @@
11
package com.xpeho.xpeapp.ui.page.user
22

3+
import android.widget.Toast
34
import androidx.compose.foundation.layout.*
45
import androidx.compose.runtime.*
56
import androidx.compose.ui.Modifier
67
import androidx.compose.ui.focus.FocusRequester
78
import androidx.compose.ui.text.input.ImeAction
89
import androidx.compose.ui.unit.dp
910
import androidx.compose.ui.graphics.Color
11+
import androidx.compose.ui.platform.LocalContext
1012
import androidx.compose.ui.res.stringResource
1113
import androidx.compose.ui.unit.sp
1214
import androidx.lifecycle.viewmodel.compose.viewModel
1315
import com.xpeho.xpeapp.R
1416
import com.xpeho.xpeapp.XpeApp
1517
import com.xpeho.xpeapp.data.entity.user.UserEditPassword
18+
import com.xpeho.xpeapp.ui.components.CustomDialog
1619
import com.xpeho.xpeapp.ui.components.layout.Title
20+
import com.xpeho.xpeapp.ui.uiState.PasswordUpdateUiState
1721
import com.xpeho.xpeapp.ui.viewModel.user.UserInfosViewModel
1822
import com.xpeho.xpeapp.ui.viewModel.viewModelFactory
1923
import com.xpeho.xpeho_ui_android.ClickyButton
@@ -30,13 +34,35 @@ fun ProfileEditPasswordView(
3034
)
3135
}
3236
),
33-
onChangePassword: () -> Unit
37+
onComplete: () -> Unit
3438
) {
3539
val passwordFocusRequester = remember { FocusRequester() }
3640
var initialPassword by remember { mutableStateOf("") }
3741
var newPassword by remember { mutableStateOf("") }
3842
var confirmPassword by remember { mutableStateOf("") }
3943

44+
val context = LocalContext.current
45+
46+
when (userInfosViewModel.passwordUpdateState) {
47+
is PasswordUpdateUiState.ERROR -> {
48+
CustomDialog(
49+
title = stringResource(id = R.string.profil_page_modify_password_error),
50+
message = (userInfosViewModel.passwordUpdateState as PasswordUpdateUiState.ERROR).errorMessage,
51+
closeDialog = { userInfosViewModel.passwordUpdateState = PasswordUpdateUiState.EMPTY }
52+
)
53+
}
54+
is PasswordUpdateUiState.SUCCESS -> {
55+
Toast.makeText(
56+
context,
57+
stringResource(id = R.string.profil_page_modify_password_success),
58+
Toast.LENGTH_SHORT
59+
).show()
60+
onComplete()
61+
}
62+
else -> {}
63+
}
64+
65+
4066
Column(
4167
modifier = Modifier
4268
.fillMaxWidth()
@@ -87,7 +113,7 @@ fun ProfileEditPasswordView(
87113
ClickyButton(
88114
label = stringResource(id = R.string.profil_page_modify_password_cancel),
89115
onPress = {
90-
onChangePassword()
116+
onComplete()
91117
},
92118
backgroundColor = Color.White,
93119
labelColor = Colors.CONTENT_COLOR
@@ -97,15 +123,11 @@ fun ProfileEditPasswordView(
97123
ClickyButton(
98124
label = stringResource(id = R.string.profil_page_modify_password_save),
99125
onPress = {
100-
// if (newPassword == confirmPassword) {
101-
// userInfosViewModel.updatePassword(UserEditPassword(
102-
// initialPassword, newPassword, confirmPassword))
103-
// onChangePassword()
104-
// } else {
105-
// // Handle password mismatch error
106-
// }
126+
userInfosViewModel.updatePassword(UserEditPassword(initialPassword, newPassword, confirmPassword))
107127
}
108128
)
109129
}
130+
131+
110132
}
111133
}

xpeapp_android/app/src/main/java/com/xpeho/xpeapp/ui/page/user/ProfilePage.kt

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,18 @@
11
package com.xpeho.xpeapp.ui.page.user
22

3-
43
import androidx.compose.foundation.layout.*
54
import androidx.compose.runtime.*
65
import androidx.compose.ui.Modifier
76
import androidx.compose.ui.semantics.semantics
87
import androidx.compose.ui.semantics.contentDescription
98
import androidx.compose.ui.unit.dp
109
import androidx.compose.runtime.Composable
11-
import androidx.lifecycle.viewmodel.compose.viewModel
1210
import androidx.navigation.NavController
13-
import com.xpeho.xpeapp.XpeApp
14-
import com.xpeho.xpeapp.ui.viewModel.user.UserInfosViewModel
15-
import com.xpeho.xpeapp.ui.viewModel.viewModelFactory
1611

1712
@Composable
1813
fun ProfilePage(
1914
navigationController: NavController
20-
) {
15+
) {
2116
var isChangingPassword by remember { mutableStateOf(false) }
2217

2318
Column(
@@ -29,10 +24,11 @@ fun ProfilePage(
2924
verticalArrangement = Arrangement.spacedBy(16.dp)
3025
) {
3126
if (isChangingPassword) {
32-
ProfileEditPasswordView( onChangePassword = { isChangingPassword = false }
27+
ProfileEditPasswordView(
28+
onComplete = { isChangingPassword = false }
3329
)
3430
} else {
35-
ProfileUserInfosView(onChangePassword = { isChangingPassword = true }, navigationController = navigationController)
31+
ProfileUserInfosView(onClickToAccessPasswordEdition = { isChangingPassword = true }, navigationController = navigationController)
3632
}
3733
}
3834
}

xpeapp_android/app/src/main/java/com/xpeho/xpeapp/ui/page/user/ProfileUserInfosView.kt

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ fun ProfileUserInfosView(
4141
)
4242
}
4343
),
44-
onChangePassword: () -> Unit,
44+
onClickToAccessPasswordEdition: () -> Unit,
4545
navigationController: NavController
4646
) {
4747
val userInfosState = userInfosViewModel.state
@@ -104,7 +104,10 @@ fun ProfileUserInfosView(
104104
) {
105105
ClickyButton(
106106
label = stringResource(id = R.string.profil_page_modify_password),
107-
onPress = onChangePassword,
107+
onPress = {
108+
userInfosViewModel.resetPasswordUpdateState()
109+
onClickToAccessPasswordEdition()
110+
},
108111
)
109112
}
110113
Spacer(modifier = Modifier.weight(1f))
Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
1-
/*
21
package com.xpeho.xpeapp.ui.uiState
32

43
interface PasswordUpdateUiState {
54
object EMPTY : PasswordUpdateUiState
65
object LOADING : PasswordUpdateUiState
7-
data class SUCCESS(val isSuccessful: Boolean) : PasswordUpdateUiState
6+
object SUCCESS : PasswordUpdateUiState
87
data class ERROR(val errorMessage: String) : PasswordUpdateUiState
98
}
10-
*/
9+

xpeapp_android/app/src/main/java/com/xpeho/xpeapp/ui/viewModel/user/UserInfosViewModel.kt

Lines changed: 27 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,17 @@
11
package com.xpeho.xpeapp.ui.viewModel.user
22

3+
import android.util.Log
34
import androidx.compose.runtime.getValue
45
import androidx.compose.runtime.mutableStateOf
56
import androidx.compose.runtime.setValue
67
import androidx.lifecycle.ViewModel
78
import androidx.lifecycle.viewModelScope
89
import com.xpeho.xpeapp.data.entity.user.UserEditPassword
10+
import com.xpeho.xpeapp.data.model.user.UpdatePasswordResult
911
import com.xpeho.xpeapp.data.service.WordpressRepository
1012
import com.xpeho.xpeapp.domain.AuthState
1113
import com.xpeho.xpeapp.domain.AuthenticationManager
12-
// import com.xpeho.xpeapp.ui.uiState.PasswordUpdateUiState
14+
import com.xpeho.xpeapp.ui.uiState.PasswordUpdateUiState
1315
import com.xpeho.xpeapp.ui.uiState.UserInfosUiState
1416
import kotlinx.coroutines.launch
1517

@@ -19,7 +21,7 @@ class UserInfosViewModel (
1921
) : ViewModel() {
2022

2123
var state: UserInfosUiState by mutableStateOf(UserInfosUiState.EMPTY)
22-
// var passwordUpdateState: PasswordUpdateUiState by mutableStateOf(PasswordUpdateUiState.EMPTY)
24+
var passwordUpdateState: PasswordUpdateUiState by mutableStateOf(PasswordUpdateUiState.EMPTY)
2325

2426
init {
2527
fetchUserInfos()
@@ -43,30 +45,35 @@ class UserInfosViewModel (
4345
}
4446
}
4547

46-
// fun updatePassword(editPassword: UserEditPassword) {
47-
// passwordUpdateState = PasswordUpdateUiState.LOADING
48-
// viewModelScope.launch {
49-
// try {
50-
// val result = wordpressRepo.updatePassword(editPassword)
51-
// passwordUpdateState = if (result) {
52-
// PasswordUpdateUiState.SUCCESS(true)
53-
// } else {
54-
// PasswordUpdateUiState.ERROR("La mise à jour du mot de passe a échoué.")
55-
// }
56-
// } catch (e: Exception) {
57-
// passwordUpdateState = PasswordUpdateUiState.ERROR("Erreur : ${e.message}")
58-
// }
59-
// }
60-
// }
48+
fun updatePassword(editPassword: UserEditPassword) {
49+
passwordUpdateState = PasswordUpdateUiState.LOADING
50+
viewModelScope.launch {
51+
try {
52+
val result = wordpressRepo.updatePassword(editPassword)
53+
passwordUpdateState = when (result) {
54+
is UpdatePasswordResult.Success -> PasswordUpdateUiState.SUCCESS
55+
is UpdatePasswordResult.IncorrectInitialPassword -> PasswordUpdateUiState.ERROR("Le mot de passe initial est incorrect.")
56+
is UpdatePasswordResult.PasswordMismatch -> PasswordUpdateUiState.ERROR("Les mots de passe ne correspondent pas.")
57+
else -> PasswordUpdateUiState.ERROR("La mise à jour du mot de passe a échoué.")
58+
}
59+
Log.d("UserInfosVIewmodle", "updatePassword: $passwordUpdateState")
60+
} catch (e: Exception) {
61+
passwordUpdateState = PasswordUpdateUiState.ERROR("Oups, il y a eu un problème dans la mise à jour du mot de passe")
62+
}
63+
}
64+
}
6165

6266

63-
fun resetState() {
67+
fun resetPasswordUpdateState() {
68+
passwordUpdateState = PasswordUpdateUiState.EMPTY
69+
}
70+
71+
fun resetUserInfosState() {
6472
state = UserInfosUiState.EMPTY
65-
//passwordUpdateState = PasswordUpdateUiState.EMPTY
6673
}
6774

6875
fun updateState() {
69-
resetState()
76+
resetUserInfosState()
7077
fetchUserInfos()
7178
}
7279

0 commit comments

Comments
 (0)