Merge de la barre de navigation à master

pull/24/head
Kentin BRONGNIART 2 months ago
commit a5269b4ec1

@ -1,2 +1,42 @@
# WF-Android # Projet Android What the Fantasy
# Description
L'application mobile **What the Fantasy** est une application pour android permettant aux utilisateurs de découvrir des citations célèbres du monde de la fantasy. En plus de pouvoir lire et apprécier les citations, les utilisateurs peuvent créer un compte pour interagir avec elles en les likant, en les commentant, et en participant à des quiz à thème ou aléatoires.
### Fonctionnalités principales
- **Découverte de citations** : Parcourez une large sélection de citations tirées de l'univers de la fantasy.
- **Interaction avec les citations** : Les utilisateurs connectés peuvent **liker** et **commenter** les citations.
- **Création de compte utilisateur** : Inscription et connexion des utilisateurs pour accéder à des fonctionnalités supplémentaires.
- **Quiz interactifs** : Les utilisateurs peuvent participer à des quiz à thème (par exemple, quiz sur les personnages de la fantasy) ou un quiz aléatoire pour deviner qui a dit une citation parmi une liste d'auteurs célèbres.
## Prérequis
Avant d'exécuter l'application sur votre android, vous devez avoir installé les éléments suivants sur votre machine :
- **Android Studio** : L'IDE officiel des applications Android
- [Installation d'Android Studio](https://developer.android.com/studio?hl=fr)
## Installation
### 1. Cloner le dépôt
Clonez le dépôt Git sur votre machine locale avec la commande suivante :
```bash
git clone https://codefirst.iut.uca.fr/git/WhatTheFantasy/WF-Android.git
```
### 2. Lancer l'application à travers Android Studio
Une fois le projet ouvert dans Android Studio, lancer le build du projet, soit sur votre smartphone android physique, soit par un émulateur intégré à Android Studio
## Auteurs
BRONGNIART Kentin<br/>
BEAULATON Léni<br/>
ROCHER Maxime<br/>
MONDEJAR Kevin<br/>
GUICHARD-MONTGUERS Louis<br/>
NGUYEN Tommy<br/>

@ -4,19 +4,8 @@ import android.os.Bundle
import androidx.activity.ComponentActivity import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge import androidx.activity.enableEdgeToEdge
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.navigation.NavController
import com.example.what_the_fantasy.ui.navigations.AppNavigator import com.example.what_the_fantasy.ui.navigations.AppNavigator
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.screens.LoginPage
import com.example.what_the_fantasy.ui.screens.ProfilPage
import com.example.what_the_fantasy.ui.screens.QuizPage
class MainActivity : ComponentActivity() { class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
@ -24,9 +13,7 @@ class MainActivity : ComponentActivity() {
enableEdgeToEdge() enableEdgeToEdge()
setContent { setContent {
What_The_FantasyTheme { What_The_FantasyTheme {
AppNavigator() AppNavigator()
//QuizPage()
} }
} }
} }

@ -1,5 +1,6 @@
package com.example.what_the_fantasy.ui.components package com.example.what_the_fantasy.ui.components
import androidx.compose.foundation.Image
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Box
@ -64,7 +65,10 @@ fun NavBar(onProfile : Boolean = false ,
Button(onClick = {}, Button(onClick = {},
colors = ButtonDefaults.buttonColors(containerColor = Color.Transparent) colors = ButtonDefaults.buttonColors(containerColor = Color.Transparent)
) { ) {
Text("Theme", fontSize = 25.sp, color = Color.White) Image(
painter = painterResource(id = R.drawable.toggle),
contentDescription = "Theme"
)
} }
} }

@ -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) }
}

@ -104,7 +104,7 @@ fun AppNavigator() {
} }
composable(Destination.Quote.route) { QuotePage() } composable(Destination.Quote.route) { QuotePage() }
composable(Destination.Search.route) { SearchPage() } composable(Destination.Search.route) { SearchPage() }
composable(Destination.SignUp.route) { SignUpPage(navController) } composable(Destination.SignUp.route) { SignUpPage(navController, services) }
composable(Destination.SubmitQuote.route) { SubmitQuotePage() } composable(Destination.SubmitQuote.route) { SubmitQuotePage() }
composable(Destination.QuizMenu.route) { composable(Destination.QuizMenu.route) {
@ -138,4 +138,3 @@ fun AppNavigator() {
} }
} }
} }

@ -62,6 +62,8 @@ import com.example.what_the_fantasy.R
import com.example.what_the_fantasy.data.local.QuestionStub import com.example.what_the_fantasy.data.local.QuestionStub
import com.example.what_the_fantasy.data.local.UserStub import com.example.what_the_fantasy.data.local.UserStub
import com.example.what_the_fantasy.data.services.IServices import com.example.what_the_fantasy.data.services.IServices
//import com.example.what_the_fantasy.data.local.UserStub.users
import com.example.what_the_fantasy.data.services.ServicesStub
import com.example.what_the_fantasy.ui.components.ErrorMessageProfileComponent import com.example.what_the_fantasy.ui.components.ErrorMessageProfileComponent
import com.example.what_the_fantasy.ui.components.NavBar import com.example.what_the_fantasy.ui.components.NavBar
import com.example.what_the_fantasy.ui.components.SpaceHeightComponent import com.example.what_the_fantasy.ui.components.SpaceHeightComponent
@ -110,13 +112,13 @@ fun ProfilPage(index: Int,
ImageProfil(user.imgUrl, 120) ImageProfil(user.imgUrl, 120)
SpaceHeightComponent(16) SpaceHeightComponent(16)
EditUsername(user.username)// Édition du Username EditUsername(user.username, index, services)// Édition du Username
SpaceHeightComponent(16) SpaceHeightComponent(16)
EditEmail(user.email)// Édition du Email EditEmail(user.email,index, services)// Édition du Email
Spacer(modifier = Modifier.height(8.dp)) Spacer(modifier = Modifier.height(8.dp))
EditPasswd() EditPasswd(index, services)
SpaceHeightComponent(16) SpaceHeightComponent(16)
// Bouton // Bouton
@ -145,20 +147,27 @@ fun ImageProfil(imgProfil : String, size :Int){
} }
@Composable @Composable
fun EditEmail(userEmail: String) { fun EditEmail(userEmail: String, index: Int, service: IServices) {
var email by remember { mutableStateOf(userEmail) } var email by remember { mutableStateOf(userEmail) }
var isEditingEmail by remember { mutableStateOf(false) } var isEditingEmail by remember { mutableStateOf(false) }
var emailError by remember { mutableStateOf(false) } var emailError by remember { mutableStateOf(false) }
fun onDoneEditing() {
service.EditEmail(email, index)
isEditingEmail = false
}
if (isEditingEmail) { if (isEditingEmail) {
EmailEditingField( EmailEditingField(
email = email, email = email,
onEmailChange = { newEmail -> onEmailChange = { newEmail ->
email = newEmail email = newEmail
emailError = !Patterns.EMAIL_ADDRESS.matcher(newEmail).matches() emailError = !Patterns.EMAIL_ADDRESS.matcher(newEmail).matches() // Validation email
}, },
onDone = { onDone = {
if (!emailError) isEditingEmail = false if (!emailError) {
onDoneEditing()
}
}, },
emailError = emailError emailError = emailError
) )
@ -224,18 +233,21 @@ fun DisplayEmail(email: String, onEdit: () -> Unit) {
@Composable @Composable
fun EditUsername(userName: String) { fun EditUsername(userName: String, index: Int, service : IServices) {
var username by remember { mutableStateOf(userName) } var username by remember { mutableStateOf(userName) }
var isEditingUsername by remember { mutableStateOf(false) } var isEditingUsername by remember { mutableStateOf(false) }
fun onDoneEditing() {
service.EditUsername(username, index)
isEditingUsername = false
}
if (isEditingUsername) { if (isEditingUsername) {
UsernameEditingField( UsernameEditingField(
username = username, username = username,
onUsernameChange = { username = it }, onUsernameChange = { username = it },
onDone = { isEditingUsername = false } onDone = { onDoneEditing() }
) )
} else { } else {
DisplayUsername(username = username, onEdit = { isEditingUsername = true }) DisplayUsername(username = username, onEdit = { isEditingUsername = true })
@ -258,7 +270,7 @@ fun UsernameEditingField(
imeAction = ImeAction.Done imeAction = ImeAction.Done
), ),
keyboardActions = KeyboardActions( keyboardActions = KeyboardActions(
onDone = { onDone() } // Quand on appuie sur "Done", on met fin à l'édition onDone = { onDone() }
), ),
trailingIcon = { trailingIcon = {
IconButton(onClick = { onDone() }) { IconButton(onClick = { onDone() }) {
@ -291,18 +303,22 @@ fun DisplayUsername(username: String, onEdit: () -> Unit) {
@Composable @Composable
fun EditPasswd() { fun EditPasswd(index: Int, service: IServices) {
var password by remember { mutableStateOf("*******") } var password by remember { mutableStateOf("*******") } // Mot de passe actuel (affiché comme un masque)
var isEditingPassword by remember { mutableStateOf(false) } var isEditingPassword by remember { mutableStateOf(false) }
var newPassword by remember { mutableStateOf("") } var newPassword by remember { mutableStateOf("") }
var confirmPassword by remember { mutableStateOf("") } var confirmPassword by remember { mutableStateOf("") }
var passwordVisible by remember { mutableStateOf(false) } var passwordVisible by remember { mutableStateOf(false) }
var passwordError by remember { mutableStateOf(false) } var passwordError by remember { mutableStateOf(false) }
// Fonction pour finaliser l'édition du mot de passe et appeler la méthode EditPasswd2
fun onDoneEditing() {
// Appeler EditPasswd2 pour mettre à jour le mot de passe de l'utilisateur
service.EditPasswd(newPassword, index)
isEditingPassword = false
}
if (isEditingPassword) { if (isEditingPassword) {
PasswordEditingFields( PasswordEditingFields(
newPassword = newPassword, newPassword = newPassword,
@ -310,20 +326,19 @@ fun EditPasswd() {
onNewPasswordChange = { newPassword = it }, onNewPasswordChange = { newPassword = it },
onConfirmPasswordChange = { onConfirmPasswordChange = {
confirmPassword = it confirmPassword = it
passwordError = newPassword != it passwordError = newPassword != it // Vérifier si les mots de passe correspondent
}, },
passwordVisible = passwordVisible, passwordVisible = passwordVisible,
onPasswordVisibilityChange = { passwordVisible = it }, onPasswordVisibilityChange = { passwordVisible = it },
passwordError = passwordError, passwordError = passwordError,
onDone = { onDone = {
if (!passwordError && newPassword.isNotEmpty()) { if (!passwordError && newPassword.isNotEmpty()) {
password = newPassword onDoneEditing() // Appeler la fonction onDoneEditing() pour mettre à jour le mot de passe
isEditingPassword = false
} }
} }
) )
} else { } else {
DisplayPassword(onEdit = { isEditingPassword = true }) DisplayPassword(onEdit = { isEditingPassword = true }) // Afficher l'option pour modifier le mot de passe
} }
} }

@ -37,6 +37,25 @@ fun QuizEndPage(idQuiz: Int, points: Int, navControllerQuizMenu: () -> Unit) {
Column( Column(
modifier = Modifier.fillMaxSize().background(Color(0xFF100C1B)) modifier = Modifier.fillMaxSize().background(Color(0xFF100C1B))
) { ) {
// // Bandeau supérieur
// Row(
// modifier = Modifier
// .fillMaxWidth()
// .weight(0.1f)
// .padding(20.dp),
// horizontalArrangement = Arrangement.SpaceBetween,
// verticalAlignment = Alignment.CenterVertically
// ) {
// Image(
// painter = painterResource(id = R.drawable.profile_icon),
// contentDescription = "Profil",
// modifier = Modifier.size(50.dp)
// )
// Image(
// painter = painterResource(id = R.drawable.toggle),
// contentDescription = "Profil"
// )
// }
// Contenu principal // Contenu principal
Column( Column(
@ -80,5 +99,34 @@ fun QuizEndPage(idQuiz: Int, points: Int, navControllerQuizMenu: () -> Unit) {
} }
} }
// // Bandeau inférieur
// Row(
// modifier = Modifier
// .fillMaxWidth()
// .weight(0.1f)
// .background(Color(0xFF300052))
// .padding(20.dp),
// horizontalArrangement = Arrangement.SpaceAround,
// verticalAlignment = Alignment.CenterVertically
// ) {
// // Bouton Likes
// Image(
// painter = painterResource(id = R.drawable.like_icon),
// contentDescription = "Bouton",
// modifier = Modifier.size(50.dp)
// )
// // Bouton WhatTheFantasy
// Image(
// painter = painterResource(R.drawable.wf_logo),
// contentDescription = "Menu Button",
// Modifier.clickable { navControllerQuizMenu() }
// )
// // Bouton Quiz
// Image(
// painter = painterResource(id = R.drawable.quiz_icon),
// contentDescription = "Bouton",
// modifier = Modifier.size(50.dp)
// )
// }
} }
} }

@ -54,7 +54,25 @@ fun QuizPage(
Column ( Column (
modifier = Modifier.fillMaxSize().background(Color(0xFF100C1B)) modifier = Modifier.fillMaxSize().background(Color(0xFF100C1B))
) { ) {
// // Bandeau supérieur
// Row(
// modifier = Modifier
// .fillMaxWidth()
// .weight(0.1f)
// //.background(Color(0xFF300052))
// .padding(20.dp),
// horizontalArrangement = Arrangement.SpaceBetween,
// verticalAlignment = Alignment.CenterVertically
// ) {
// Image(
// painter = painterResource(id = R.drawable.profile_icon),
// contentDescription = "Profil"
// )
// Image(
// painter = painterResource(id = R.drawable.toggle),
// contentDescription = "Profil"
// )
// }
// Contenu princiapl // Contenu princiapl
Column( Column(
@ -124,5 +142,33 @@ fun QuizPage(
} }
} }
// // Bandeau inférieur
// Row(
// modifier = Modifier
// .fillMaxWidth()
// .weight(0.1f)
// .background(Color(0xFF300052))
// .padding(20.dp),
// horizontalArrangement = Arrangement.SpaceAround,
// verticalAlignment = Alignment.CenterVertically
// ) {
// // Bouton Likes
// Image(
// painter = painterResource(id = R.drawable.like_icon),
// contentDescription = "Bouton"
// )
// // Bouton WhatTheFantasy
// Image(
// painter = painterResource(R.drawable.wf_logo),
// contentDescription = "Menu Button",
// Modifier.clickable { navControllerQuizMenu() }
// )
// // Bouton Quiz
// Image(
// painter = painterResource(id = R.drawable.quiz_icon),
// contentDescription = "Bouton"
// )
// }
} }
} }

@ -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
@ -40,15 +43,23 @@ import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp import androidx.compose.ui.unit.sp
import androidx.navigation.NavController import androidx.navigation.NavController
import com.example.what_the_fantasy.R import com.example.what_the_fantasy.R
import com.example.what_the_fantasy.data.services.IServices
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.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, services : IServices) {
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 +78,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, services, 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 +95,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 +143,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 +166,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: IServices,
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", service)
}
},
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,

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.1 KiB

@ -11,11 +11,17 @@
<string name="PasswdLogin">Votre mot de passe*</string> <string name="PasswdLogin">Votre mot de passe*</string>
<string name="ButtonLogin">Se connecter</string> <string name="ButtonLogin">Se connecter</string>
<string name="ButtonCreateLogin">Créer son compte</string> <string name="ButtonCreateLogin">Créer son compte</string>
<string name="ErrorLogin">Identifiant ou mot de passe incorrect</string>
//Page Sign Up //Page Sign Up
<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>

@ -10,11 +10,17 @@
<string name="PasswdLogin">Your password*</string> <string name="PasswdLogin">Your password*</string>
<string name="ButtonLogin">Login</string> <string name="ButtonLogin">Login</string>
<string name="ButtonCreateLogin">Create your account</string> <string name="ButtonCreateLogin">Create your account</string>
<string name="ErrorLogin">Incorrect username or password</string>
//Page Sign Up //Page Sign Up
<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