La page d'inscription fonctionne

pull/21/head
Leni BEAULATON 2 months ago
parent 5d5af2b1d8
commit bba419bff0

@ -6,7 +6,7 @@ interface IServices {
fun EditPasswd(passwd : String, passwdValid : String) fun EditPasswd(passwd : String, passwdValid : String)
fun EditImage(imageURL : String) fun EditImage(imageURL : String)
fun CreateUser(username : String, email : String, passwd : String, imageURL: String) fun CreateUser(username : String, email : String, passwd : String, imageURL: String) : Boolean
fun getFavorite(username: String) fun getFavorite(username: String)
fun SearchQuote(quote : String) fun SearchQuote(quote : String)

@ -17,7 +17,7 @@ class ServicesAPI : IServices {
TODO("Not yet implemented") TODO("Not yet implemented")
} }
override fun CreateUser(username: String, email: String, passwd: String, imageURL: String) { override fun CreateUser(username: String, email: String, passwd: String, imageURL: String) : Boolean {
TODO("Not yet implemented") TODO("Not yet implemented")
} }

@ -1,5 +1,12 @@
package com.example.what_the_fantasy.data.services package com.example.what_the_fantasy.data.services
import android.annotation.SuppressLint
import android.util.Log
import com.example.what_the_fantasy.data.local.UserStub
import com.example.what_the_fantasy.data.model.User
import com.example.what_the_fantasy.ui.components.hashPassword
import java.time.LocalDate
class ServicesStub : IServices { class ServicesStub : IServices {
override fun EditUsername(username: String) { override fun EditUsername(username: String) {
TODO("Not yet implemented") TODO("Not yet implemented")
@ -17,10 +24,29 @@ class ServicesStub : IServices {
TODO("Not yet implemented") TODO("Not yet implemented")
} }
override fun CreateUser(username: String, email: String, passwd: String, imageURL: String) { override fun CreateUser(username: String, email: String, passwd: String, imageURL: String) : Boolean {
TODO("Not yet implemented") val date =dateDuJour()
val passwordhash = hashPassword(passwd)
//Check si user existe déjà
val users = UserStub.allUsers
for (user in users) {
if (user.username == username) {
return false
}
} }
val user = User(100,username, email, imageURL, date, passwordhash)
//A ajouter au stub
Log.e("CreateUser", "User created: ${user.username} => ${user.password}")
return true
}
@SuppressLint("NewApi")
fun dateDuJour(): String {
val date = LocalDate.now()
return date.toString()
}
override fun SearchQuote(quote: String) { override fun SearchQuote(quote: String) {
TODO("Not yet implemented") TODO("Not yet implemented")
} }

@ -0,0 +1,14 @@
package com.example.what_the_fantasy.ui.components
import java.security.MessageDigest
fun hashPassword(password: String): String {
// SHA-256
val digest = MessageDigest.getInstance("SHA-256")
// Convertir mdp en bytes et appliquer le hash
val hashedBytes = digest.digest(password.toByteArray())
// Convertir le tableau de bytes en une chaîne hexadécimale
return hashedBytes.joinToString("") { "%02x".format(it) }
}

@ -41,6 +41,7 @@ import com.example.what_the_fantasy.data.local.UserStub
import com.example.what_the_fantasy.data.model.User import com.example.what_the_fantasy.data.model.User
import com.example.what_the_fantasy.ui.components.SpaceHeightComponent import com.example.what_the_fantasy.ui.components.SpaceHeightComponent
import com.example.what_the_fantasy.ui.components.TitlePageComponent import com.example.what_the_fantasy.ui.components.TitlePageComponent
import com.example.what_the_fantasy.ui.components.hashPassword
import com.example.what_the_fantasy.ui.theme.colorBackground import com.example.what_the_fantasy.ui.theme.colorBackground
import com.example.what_the_fantasy.ui.theme.gradienBox import com.example.what_the_fantasy.ui.theme.gradienBox
import java.security.MessageDigest import java.security.MessageDigest
@ -148,18 +149,6 @@ fun validLogin(identifiant : String, passwd : String, users : List<User>, navCon
} }
} }
fun hashPassword(password: String): String {
// SHA-256
val digest = MessageDigest.getInstance("SHA-256")
// Convertir mdp en bytes et appliquer le hash
val hashedBytes = digest.digest(password.toByteArray())
// Convertir le tableau de bytes en une chaîne hexadécimale
return hashedBytes.joinToString("") { "%02x".format(it) }
}
@Composable @Composable
fun CreateAccountButton(titleResId : Int, size : Int, color : Color, navController: () -> Unit){ fun CreateAccountButton(titleResId : Int, size : Int, color : Color, navController: () -> Unit){
val title = stringResource(id = titleResId) val title = stringResource(id = titleResId)

@ -15,8 +15,11 @@ import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.text.KeyboardOptions import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Check
import androidx.compose.material3.Button import androidx.compose.material3.Button
import androidx.compose.material3.ButtonDefaults import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton import androidx.compose.material3.IconButton
import androidx.compose.material3.OutlinedTextField import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.Text import androidx.compose.material3.Text
@ -45,10 +48,17 @@ import com.example.what_the_fantasy.ui.components.TitlePageComponent
import com.example.what_the_fantasy.ui.theme.What_The_FantasyTheme import com.example.what_the_fantasy.ui.theme.What_The_FantasyTheme
import com.example.what_the_fantasy.ui.theme.colorBackground import com.example.what_the_fantasy.ui.theme.colorBackground
import com.example.what_the_fantasy.ui.theme.gradienBox import com.example.what_the_fantasy.ui.theme.gradienBox
import com.example.what_the_fantasy.data.services.ServicesStub
import com.example.what_the_fantasy.ui.components.ErrorMessageProfileComponent
@Composable @Composable
fun SignUpPage(navController: NavController) { fun SignUpPage(navController: NavController) {
var username by remember { mutableStateOf("") }
var email by remember { mutableStateOf("") }
var password by remember { mutableStateOf("") }
var confirmPassword by remember { mutableStateOf("") }
var passwordVisible by remember { mutableStateOf(false) }
val servicesStub = ServicesStub()
Box( Box(
modifier = Modifier modifier = Modifier
@ -67,14 +77,14 @@ fun SignUpPage(navController: NavController) {
) { ) {
TitlePageComponent(R.string.titleSignUp, 20,Color.White) TitlePageComponent(R.string.titleSignUp, 20,Color.White)
IdentifiantTextFieldSign(R.string.IdentifiantLogin) IdentifiantTextFieldSign(R.string.IdentifiantLogin,identifiant = username,onValueChange = { username = it })
EmailTextFieldSign("Email*") EmailTextFieldSign(R.string.EmailSignUp, email, onValueChange = { email = it })
PassWdTextFieldSign(R.string.PasswdLogin) PassWdTextFieldSign(R.string.PasswdLogin,password, onValueChange = { password = it },passwordVisible,onPasswordVisibilityChange = { passwordVisible = !passwordVisible })
PassWdConfirmTextFieldSign(R.string.ConfirmPassWdSignUp) PassWdConfirmTextFieldSign(R.string.ConfirmPassWdSignUp,confirmPassword,onValueChange = { confirmPassword = it },passwordVisible,onPasswordVisibilityChange = { passwordVisible = !passwordVisible })
SpaceHeightComponent(16) SpaceHeightComponent(16)
ConnexionButtonSign(R.string.ButtonSignUp,18, Color.White, Color.Black) ConnexionButtonSign(R.string.ButtonSignUp,18, Color.White, Color.Black, username, email, password, confirmPassword, servicesStub, navController = navController)
SpaceHeightComponent(16) SpaceHeightComponent(16)
CreateAccountButtonSign(R.string.ButtonLogin,12, Color.White, navController = navController) ReturnLogin(R.string.ButtonLogin,12, Color.White, navController = navController)
} }
} }
@ -84,50 +94,47 @@ fun SignUpPage(navController: NavController) {
@Composable @Composable
fun IdentifiantTextFieldSign(textIdentifiantResId : Int){ fun IdentifiantTextFieldSign(textIdentifiantResId : Int, identifiant: String, onValueChange: (String) -> Unit){
val textIdentifiant = stringResource(id = textIdentifiantResId) val textIdentifiant = stringResource(id = textIdentifiantResId)
var identifiant by remember { mutableStateOf("") } // Stocke la valeur du champ
Column(modifier = Modifier.padding(top = 16.dp)) { Column(modifier = Modifier.padding(top = 16.dp)) {
OutlinedTextField( OutlinedTextField(
value = identifiant, value = identifiant,
onValueChange = { identifiant = it }, onValueChange = onValueChange,
label = { Text(textIdentifiant) }, label = { Text(textIdentifiant) },
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.padding(top = 8.dp), .padding(top = 8.dp),
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Text), keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Text),
shape = RoundedCornerShape(16.dp) // 🔹 Bords arrondis shape = RoundedCornerShape(16.dp)
) )
} }
} }
@Composable @Composable
fun EmailTextFieldSign(textIdentifiant : String){ fun EmailTextFieldSign(textIdentifiantResId: Int, email: String, onValueChange: (String) -> Unit){
var identifiant by remember { mutableStateOf("") } // Stocke la valeur du champ val textIdentifiant = stringResource(id = textIdentifiantResId)
Column(modifier = Modifier.padding(top = 16.dp)) { Column(modifier = Modifier.padding(top = 16.dp)) {
OutlinedTextField( OutlinedTextField(
value = identifiant, value = email,
onValueChange = { identifiant = it }, onValueChange = onValueChange,
label = { Text(textIdentifiant) }, label = { Text(textIdentifiant) },
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.padding(top = 8.dp), .padding(top = 8.dp),
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Email), keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Email),
shape = RoundedCornerShape(16.dp) // Bords arrondis shape = RoundedCornerShape(16.dp)
) )
} }
} }
@Composable @Composable
fun PassWdTextFieldSign(textpasswdResId : Int){ fun PassWdTextFieldSign(textpasswdResId : Int, passwd: String, onValueChange: (String) -> Unit, passwordVisible: Boolean, onPasswordVisibilityChange: () -> Unit){
val textpasswd = stringResource(id = textpasswdResId) val textpasswd = stringResource(id = textpasswdResId)
var passwd by remember { mutableStateOf("") } // Stocke la valeur du champ
var passwordVisible by remember { mutableStateOf(false) } // État pour afficher/masquer
Column(modifier = Modifier.padding(top = 10.dp)) { Column(modifier = Modifier.padding(top = 10.dp)) {
OutlinedTextField( OutlinedTextField(
value = passwd, value = passwd,
onValueChange = { passwd = it }, onValueChange = onValueChange,
label = { Text(textpasswd) }, label = { Text(textpasswd) },
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
@ -135,23 +142,22 @@ fun PassWdTextFieldSign(textpasswdResId : Int){
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Password), keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Password),
visualTransformation = if (passwordVisible) VisualTransformation.None else PasswordVisualTransformation(), visualTransformation = if (passwordVisible) VisualTransformation.None else PasswordVisualTransformation(),
trailingIcon = { trailingIcon = {
IconButton(onClick = { passwordVisible = !passwordVisible }) { IconButton(onClick = onPasswordVisibilityChange) {
Icon(imageVector = Icons.Default.Check, contentDescription = "Valider")
} }
}, },
shape = RoundedCornerShape(16.dp) // 🔹 Bords arrondis shape = RoundedCornerShape(16.dp)
) )
} }
} }
@Composable @Composable
fun PassWdConfirmTextFieldSign(textpasswdResId : Int){ fun PassWdConfirmTextFieldSign(textpasswdResId : Int,confirmPassword: String, onValueChange: (String) -> Unit, passwordVisible: Boolean, onPasswordVisibilityChange: () -> Unit){
val textpasswd = stringResource(id = textpasswdResId) val textpasswd = stringResource(id = textpasswdResId)
var passwd by remember { mutableStateOf("") } // Stocke la valeur du champ
var passwordVisible by remember { mutableStateOf(false) } // État pour afficher/masquer
Column(modifier = Modifier.padding(top = 10.dp)) { Column(modifier = Modifier.padding(top = 10.dp)) {
OutlinedTextField( OutlinedTextField(
value = passwd, value = confirmPassword,
onValueChange = { passwd = it }, onValueChange = onValueChange,
label = { Text(textpasswd) }, label = { Text(textpasswd) },
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
@ -159,31 +165,88 @@ fun PassWdConfirmTextFieldSign(textpasswdResId : Int){
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Password), keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Password),
visualTransformation = if (passwordVisible) VisualTransformation.None else PasswordVisualTransformation(), visualTransformation = if (passwordVisible) VisualTransformation.None else PasswordVisualTransformation(),
trailingIcon = { trailingIcon = {
IconButton(onClick = { passwordVisible = !passwordVisible }) { IconButton(onClick = onPasswordVisibilityChange) {
Icon(imageVector = Icons.Default.Check, contentDescription = "Valider")
} }
}, },
shape = RoundedCornerShape(16.dp) // 🔹 Bords arrondis shape = RoundedCornerShape(16.dp)
) )
} }
} }
// Validation de email
fun isValidEmail(email: String): Boolean {
val emailRegex = "[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,6}"
return email.matches(emailRegex.toRegex())
}
// Vérification mots de passe
fun arePasswordsMatching(password: String, confirmPassword: String): Boolean {
return password == confirmPassword
}
@Composable @Composable
fun ConnexionButtonSign(titleResId : Int, size : Int, colorButton : Color, colorText : Color){ fun ConnexionButtonSign(
titleResId: Int,
size: Int,
colorButton: Color,
colorText: Color,
username: String,
email: String,
password: String,
confirmPassword: String,
service: ServicesStub,
navController: NavController
) {
val title = stringResource(id = titleResId) val title = stringResource(id = titleResId)
var emailError by remember { mutableStateOf(false) }
var passwordError by remember { mutableStateOf(false) }
var usernameErrorEmpty by remember { mutableStateOf(false) }
var usernameErrorExist by remember { mutableStateOf(false) }
Button( Button(
onClick = { /* Action */ }, onClick = {
emailError = !isValidEmail(email)
passwordError = !arePasswordsMatching(password, confirmPassword)
usernameErrorEmpty = username.isBlank()
if (!emailError && !passwordError && !usernameErrorEmpty) {
usernameErrorExist = !service.CreateUser(username, email, password, "https://img.freepik.com/vecteurs-libre/personnage-magicien-malefique-fantaisie_1045-193.jpg?size=338&ext=jpg")
}
},
colors = ButtonDefaults.buttonColors(containerColor = colorButton), colors = ButtonDefaults.buttonColors(containerColor = colorButton),
modifier = Modifier modifier = Modifier.fillMaxWidth(),
.fillMaxWidth(),
) { ) {
Text(title, fontSize = size.sp, color = colorText) Text(title, fontSize = size.sp, color = colorText)
} }
// Afficher erreurs
if (usernameErrorEmpty) {
ErrorMessageProfileComponent(R.string.ErrorUserEmptySignUp)
} }
if (usernameErrorExist) {
ErrorMessageProfileComponent(R.string.ErrorUserExistSignUp)
}
if (emailError) {
ErrorMessageProfileComponent(R.string.ErrorEmailSignUp)
}
if (passwordError) {
ErrorMessageProfileComponent(R.string.ErrorPasswordSignUp)
}
}
@Composable @Composable
fun CreateAccountButtonSign(titleResId: Int, size: Int, color: Color, navController: NavController) { fun ReturnLogin(titleResId: Int, size: Int, color: Color, navController: NavController) {
val title = stringResource(id = titleResId) val title = stringResource(id = titleResId)
Text( Text(
text = title, text = title,

@ -16,6 +16,11 @@
<string name="titleSignUp">Inscription</string> <string name="titleSignUp">Inscription</string>
<string name="ConfirmPassWdSignUp">Confirmer mot de passe*</string> <string name="ConfirmPassWdSignUp">Confirmer mot de passe*</string>
<string name="ButtonSignUp">S\'inscrire</string> <string name="ButtonSignUp">S\'inscrire</string>
<string name="EmailSignUp">Email*</string>
<string name="ErrorEmailSignUp">Email invalide</string>
<string name="ErrorPasswordSignUp">Les mots de passe ne correspondent pas</string>
<string name="ErrorUserEmptySignUp">Le nom d\'utilisateur ne peut pas être vide</string>
<string name="ErrorUserExistSignUp">Le nom d\'utilisateur n\'est pas disponible</string>
//Page Profil //Page Profil
<string name="titleProfile">Profil</string> <string name="titleProfile">Profil</string>

@ -15,6 +15,11 @@
<string name="titleSignUp">Account creation</string> <string name="titleSignUp">Account creation</string>
<string name="ConfirmPassWdSignUp">Confirm your password*</string> <string name="ConfirmPassWdSignUp">Confirm your password*</string>
<string name="ButtonSignUp">Create</string> <string name="ButtonSignUp">Create</string>
<string name="EmailSignUp">Your email*</string>
<string name="ErrorEmailSignUp">Invalid email</string>
<string name="ErrorPasswordSignUp">Passwords do not match</string>
<string name="ErrorUserEmptySignUp">Username cannot be empty</string>
<string name="ErrorUserExistSignUp">Username is not available</string>
//Page Profil //Page Profil
<string name="titleProfile">Profile</string> <string name="titleProfile">Profile</string>

Loading…
Cancel
Save