From bf100a01b2087b3326961b16bc4af53c73ac9b05 Mon Sep 17 00:00:00 2001 From: kevin Mondejar Date: Thu, 13 Feb 2025 13:38:36 +0100 Subject: [PATCH 01/21] Repare building error --- .../app/src/main/res/img/Group 89.svg | 21 ------------------ .../app/src/main/res/img/Vector.png | Bin 4222 -> 0 bytes 2 files changed, 21 deletions(-) delete mode 100644 What_The_Fantasy/app/src/main/res/img/Group 89.svg delete mode 100644 What_The_Fantasy/app/src/main/res/img/Vector.png diff --git a/What_The_Fantasy/app/src/main/res/img/Group 89.svg b/What_The_Fantasy/app/src/main/res/img/Group 89.svg deleted file mode 100644 index 503a1bf..0000000 --- a/What_The_Fantasy/app/src/main/res/img/Group 89.svg +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - diff --git a/What_The_Fantasy/app/src/main/res/img/Vector.png b/What_The_Fantasy/app/src/main/res/img/Vector.png deleted file mode 100644 index 7dd83e6579dfa38699da22031e04bb0adac906a2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4222 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 Ugb89kKmY&$07*qoM6N<$g4Qh(JOBUy From 7424c5487ee482889d173d3cd83d03f7457bb238 Mon Sep 17 00:00:00 2001 From: "leni.beaulaton" Date: Thu, 13 Feb 2025 21:59:46 +0100 Subject: [PATCH 02/21] Page Login + SignUp + Profil (pour le moment, c'est juste visuel) --- .../example/what_the_fantasy/MainActivity.kt | 5 +- .../what_the_fantasy/ui/screens/LoginPage.kt | 172 ++++++++- .../what_the_fantasy/ui/screens/ProfilPage.kt | 363 +++++++++++++++++- .../what_the_fantasy/ui/screens/SignUpPage.kt | 197 +++++++++- 4 files changed, 733 insertions(+), 4 deletions(-) diff --git a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/MainActivity.kt b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/MainActivity.kt index 9194e38..ea5af26 100644 --- a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/MainActivity.kt +++ b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/MainActivity.kt @@ -11,8 +11,10 @@ import androidx.compose.material3.Scaffold import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier +import com.example.what_the_fantasy.ui.screens.AppNavigator 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 class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { @@ -28,7 +30,8 @@ class MainActivity : ComponentActivity() { ) } } - LoginPage() + AppNavigator() // Accès à la page login et SingUp (pour le moment) + //ProfilPage() //Accès à la page profil } } } diff --git a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/LoginPage.kt b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/LoginPage.kt index 40b2f04..7c5358b 100644 --- a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/LoginPage.kt +++ b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/LoginPage.kt @@ -1,7 +1,177 @@ package com.example.what_the_fantasy.ui.screens +import android.os.Bundle +import android.text.style.BackgroundColorSpan +import androidx.activity.ComponentActivity +import androidx.activity.compose.setContent +import androidx.activity.enableEdgeToEdge +import androidx.compose.foundation.background +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.foundation.text.KeyboardOptions +import androidx.compose.material.icons.Icons +import androidx.compose.material3.Button +import androidx.compose.material3.ButtonDefaults +import androidx.compose.material3.Icon +import androidx.compose.material3.IconButton +import androidx.compose.material3.OutlinedTextField +import androidx.compose.material3.Text +import androidx.compose.material3.TextField import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.geometry.Offset +import androidx.compose.ui.graphics.Brush +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.input.KeyboardType +import androidx.compose.ui.text.input.PasswordVisualTransformation +import androidx.compose.ui.text.input.VisualTransformation +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import com.example.what_the_fantasy.ui.theme.What_The_FantasyTheme +import androidx.navigation.NavController +import androidx.navigation.compose.rememberNavController +import androidx.navigation.compose.NavHost +import androidx.navigation.compose.composable +@Composable +fun LoginPage(navController : NavController) { + + val gradient = Brush.linearGradient( + colors = listOf(Color(0xFF7B1FA2), Color(0xFF311B92)), // Violet clair → Violet foncé + start = Offset(0f, 1000f), // Départ en bas à gauche + end = Offset(1000f, 0f) // Fin en haut à droite + ) + + Box( + modifier = Modifier + .fillMaxSize() + .background(Color(0xFF100C1B)), + contentAlignment = Alignment.Center + ){ + Column( + modifier = Modifier + .fillMaxWidth(0.9f) // Ajuste la largeur + .padding(20.dp) // Marge extérieure + .clip(RoundedCornerShape(16.dp)) // Arrondi les angles + .background(gradient) // Ajoute un fond blanc + .padding(20.dp), // Padding interne + horizontalAlignment = Alignment.CenterHorizontally + ) { + + TitleLogin("Connexion au compte", 20,Color.White) + IdentifiantTextField("Identifiant*") + PassWdTextField("Mot de passe*") + Space(16) + ConnexionButtonLogin("Connexion",18, Color.White, Color.Black) + Space(16) + CreateAccountButton("Créer un compte",12, Color.White, navController) + + } + } +} + +@Composable +fun Space(height : Int){ + Spacer( + modifier = Modifier + .height(height.dp)) // Ajoute un espacement +} + + +@Composable +fun IdentifiantTextField(textIdentifiant : String){ + var identifiant by remember { mutableStateOf("") } // Stocke la valeur du champ + Column(modifier = Modifier.padding(top = 16.dp)) { + OutlinedTextField( + value = identifiant, + onValueChange = { identifiant = it }, + label = { Text(textIdentifiant) }, + modifier = Modifier + .fillMaxWidth() + .padding(top = 8.dp), + keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Text), + shape = RoundedCornerShape(16.dp) // 🔹 Bords arrondis + ) + } +} @Composable -fun LoginPage() { +fun PassWdTextField(textpasswd : String){ + 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)) { + OutlinedTextField( + value = passwd, + onValueChange = { passwd = it }, + label = { Text(textpasswd) }, + modifier = Modifier + .fillMaxWidth() + .padding(top = 8.dp), + keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Password), + visualTransformation = if (passwordVisible) VisualTransformation.None else PasswordVisualTransformation(), + trailingIcon = { + IconButton(onClick = { passwordVisible = !passwordVisible }) { + } + }, + shape = RoundedCornerShape(16.dp) // 🔹 Bords arrondis + ) + } +} + +@Composable +fun TitleLogin(title : String, size : Int, color : Color){ + Text( + text = title, + fontSize = size.sp, + fontWeight = FontWeight.Bold, + color = color + ) +} + +@Composable +fun ConnexionButtonLogin(title : String, size : Int, colorButton : Color, colorText : Color){ + Button( + onClick = { /* Action */ }, + colors = ButtonDefaults.buttonColors(containerColor = colorButton), + modifier = Modifier + .fillMaxWidth(), + ) { + Text(title, fontSize = size.sp, color = colorText) + } +} + +@Composable +fun CreateAccountButton(title : String, size : Int, color : Color, navController: NavController){ + Text( + text = title, + fontSize = size.sp, + color = color, + modifier = Modifier.clickable { + navController.navigate("signup")// rediriger vers la page de création de compte + } + ) +} + +@Composable +fun AppNavigator() { + val navController = rememberNavController() + + NavHost(navController, startDestination = "login") { + composable("login") { LoginPage(navController) } + composable("signup") { SignUpPage(navController) } + } + } \ No newline at end of file diff --git a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/ProfilPage.kt b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/ProfilPage.kt index a80fed3..6d8d60e 100644 --- a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/ProfilPage.kt +++ b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/ProfilPage.kt @@ -1,6 +1,367 @@ package com.example.what_the_fantasy.ui.screens +import android.os.Bundle +import androidx.activity.ComponentActivity +import androidx.activity.compose.setContent +import androidx.activity.enableEdgeToEdge +import androidx.compose.foundation.Image +import androidx.compose.foundation.background +import androidx.compose.foundation.border +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.shape.CircleShape +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.foundation.text.KeyboardActions +import androidx.compose.foundation.text.KeyboardOptions +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.Check +import androidx.compose.material.icons.filled.Edit +import androidx.compose.material3.Button +import androidx.compose.material3.ButtonDefaults +import androidx.compose.material3.Icon +import androidx.compose.material3.IconButton +import androidx.compose.material3.OutlinedTextField +import androidx.compose.material3.Scaffold +import androidx.compose.material3.Text import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.geometry.Offset +import androidx.compose.ui.graphics.Brush +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.input.ImeAction +import androidx.compose.ui.text.input.KeyboardType +import androidx.compose.ui.text.input.PasswordVisualTransformation +import androidx.compose.ui.text.input.VisualTransformation +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import androidx.navigation.NavController +import com.example.what_the_fantasy.R +import com.example.what_the_fantasy.ui.theme.What_The_FantasyTheme @Composable -fun ProfilPage() {} \ No newline at end of file +fun ProfilPage() { + val gradient = Brush.linearGradient( + colors = listOf(Color(0xFF7B1FA2), Color(0xFF311B92)), // Violet clair → Violet foncé + start = Offset(0f, 1000f), // Départ en bas à gauche + end = Offset(1000f, 0f) // Fin en haut à droite + ) + + Box( + modifier = Modifier + .fillMaxSize() + .background(Color(0xFF100C1B)), + contentAlignment = Alignment.Center + ) { + Column( + modifier = Modifier + .fillMaxWidth(0.9f) + .padding(20.dp) + .clip(RoundedCornerShape(16.dp)) + .background(gradient) + .padding(20.dp), + horizontalAlignment = Alignment.CenterHorizontally + ) { + + // Titre + TitleProfil("Profil", 20, Color.White) + SpaceProfil(16) + + // Image de profil + val id = R.drawable.ic_launcher_foreground + ImageProfil(id, 120, 2, Color.White) + + + SpaceProfil(16) + + EditUsername()// Édition du Username + SpaceProfil(16) + + EditEmail()// Édition du Email + Spacer(modifier = Modifier.height(8.dp)) + + EditPasswd() + SpaceProfil(16) + + // Bouton + ButtonProfile("Ajouter une citation",18, Color.Black, Color.White) + SpaceProfil(16) + ButtonProfile("Langue",18, Color.Black, Color.White) + SpaceProfil(16) + ButtonProfile("Déconnexion", 18, Color.Black, Color.White) + + } + } +} + + +@Composable +fun SpaceProfil(height : Int){ + Spacer( + modifier = Modifier + .height(height.dp)) // Ajoute un espacement +} + + +@Composable +fun TitleProfil(title : String, size : Int, color : Color){ + Text( + text = title, + fontSize = size.sp, + fontWeight = FontWeight.Bold, + color = color + ) +} + +@Composable +fun ImageProfil(imgProfil : Int, size :Int, sizeBorber : Int, colorBorder : Color){ + Image( + painter = painterResource(imgProfil), + contentDescription = "Photo de profil", + modifier = Modifier + .size(size.dp) + .clip(CircleShape) + .border(sizeBorber.dp, colorBorder, CircleShape) + ) +} + + +@Composable +fun EditEmail(){ + var email by remember { mutableStateOf("user@example.com") } + var isEditingEmail by remember { mutableStateOf(false) } // État d'édition + var emailError by remember { mutableStateOf(false) } + + if (isEditingEmail) { + OutlinedTextField( + value = email, + onValueChange = { + email = it + emailError = !android.util.Patterns.EMAIL_ADDRESS.matcher(it).matches() + }, + modifier = Modifier.fillMaxWidth(), + textStyle = TextStyle(color = Color.White, fontSize = 18.sp), + singleLine = true, + keyboardOptions = KeyboardOptions.Default.copy( + keyboardType = KeyboardType.Email, // ✅ Clavier spécialisé pour email + imeAction = ImeAction.Done + ), + keyboardActions = KeyboardActions( + onDone = { if (!emailError) isEditingEmail = false } // ✅ Fermer si l'email est valide + ), + trailingIcon = { + IconButton(onClick = { if (!emailError) isEditingEmail = false }) { + Icon(imageVector = Icons.Default.Check, contentDescription = "Valider") + } + }, + isError = emailError // ✅ Afficher l'erreur si l'email est invalide + ) + if (emailError) { + Text( + text = "Adresse e-mail invalide", + color = Color.Red, + fontSize = 12.sp, + modifier = Modifier.padding(top = 4.dp) + ) + } + } else { + Row( + verticalAlignment = Alignment.CenterVertically, + modifier = Modifier.clickable { isEditingEmail = true } + ) { + Text( + text = email, + fontSize = 18.sp, + fontWeight = FontWeight.Bold, + color = Color.White + ) + Icon( + imageVector = Icons.Default.Edit, + contentDescription = "Modifier", + tint = Color.White, + modifier = Modifier.size(16.dp).padding(start = 8.dp) + ) + } + } +} + + +@Composable +fun EditUsername(){ + var username by remember { mutableStateOf("Username") } + var isEditingUsername by remember { mutableStateOf(false) } // État d'édition + + if (isEditingUsername) { + OutlinedTextField( + value = username, + onValueChange = { username = it }, + modifier = Modifier.fillMaxWidth(), + textStyle = TextStyle(color = Color.White, fontSize = 18.sp), + singleLine = true, + keyboardOptions = KeyboardOptions.Default.copy( + imeAction = ImeAction.Done + ), + keyboardActions = KeyboardActions( + onDone = { isEditingUsername = false } // Quand on appuie sur "Done" + ), + trailingIcon = { + IconButton(onClick = { isEditingUsername = false }) { + Icon(imageVector = Icons.Default.Check, contentDescription = "Valider") + } + } + ) + } else { + Row( + verticalAlignment = Alignment.CenterVertically, + modifier = Modifier.clickable { isEditingUsername = true } + ) { + Text( + text = username, + fontSize = 18.sp, + fontWeight = FontWeight.Bold, + color = Color.White + ) + Icon( + imageVector = Icons.Default.Edit, + contentDescription = "Modifier", + tint = Color.White, + modifier = Modifier.size(16.dp).padding(start = 8.dp) + ) + } + } +} + + +@Composable +fun EditPasswd(){ + var password by remember { mutableStateOf("*******") } + var isEditingPassword by remember { mutableStateOf(false) } + var newPassword by remember { mutableStateOf("") } + var confirmPassword by remember { mutableStateOf("") } + var passwordVisible by remember { mutableStateOf(false) } + var passwordError by remember { mutableStateOf(false) } + if (isEditingPassword) { + Column { + OutlinedTextField( + value = newPassword, + onValueChange = { newPassword = it }, + label = { Text("Nouveau mot de passe") }, + modifier = Modifier.fillMaxWidth(), + textStyle = TextStyle(color = Color.White, fontSize = 18.sp), + singleLine = true, + keyboardOptions = KeyboardOptions.Default.copy( + keyboardType = KeyboardType.Password, + imeAction = ImeAction.Next + ), + visualTransformation = if (passwordVisible) VisualTransformation.None else PasswordVisualTransformation(), + trailingIcon = { + IconButton(onClick = { passwordVisible = !passwordVisible }) { + + } + } + ) + + Spacer(modifier = Modifier.height(8.dp)) + + OutlinedTextField( + value = confirmPassword, + onValueChange = { + confirmPassword = it + passwordError = newPassword != it + }, + label = { Text("Confirmer le mot de passe") }, + modifier = Modifier.fillMaxWidth(), + textStyle = TextStyle(color = Color.White, fontSize = 18.sp), + singleLine = true, + keyboardOptions = KeyboardOptions.Default.copy( + keyboardType = KeyboardType.Password, + imeAction = ImeAction.Done + ), + keyboardActions = KeyboardActions( + onDone = { if (!passwordError && newPassword.isNotEmpty()) { + password = newPassword + isEditingPassword = false + }} + ), + visualTransformation = if (passwordVisible) VisualTransformation.None else PasswordVisualTransformation(), + trailingIcon = { + IconButton(onClick = { passwordVisible = !passwordVisible }) { + + } + }, + isError = passwordError + ) + + if (passwordError) { + Text( + text = "Les mots de passe ne correspondent pas", + color = Color.Red, + fontSize = 12.sp, + modifier = Modifier.padding(top = 4.dp) + ) + } + + Spacer(modifier = Modifier.height(8.dp)) + + Button( + onClick = { + if (!passwordError && newPassword.isNotEmpty()) { + password = newPassword + isEditingPassword = false + } + }, + colors = ButtonDefaults.buttonColors(containerColor = Color.White), + modifier = Modifier.fillMaxWidth() + ) { + Text("Valider", fontSize = 18.sp, color = Color.Black) + } + } + } else { + Row( + verticalAlignment = Alignment.CenterVertically, + modifier = Modifier.clickable { isEditingPassword = true } + ) { + Text( + text = password, + fontSize = 18.sp, + fontWeight = FontWeight.Bold, + color = Color.White + ) + Icon( + imageVector = Icons.Default.Edit, + contentDescription = "Modifier", + tint = Color.White, + modifier = Modifier.size(16.dp).padding(start = 8.dp) + ) + } + } +} + + +@Composable +fun ButtonProfile(text : String, size :Int, colorTexte : Color, colorButton : Color){ + Button( + onClick = { /* Action */ }, + colors = ButtonDefaults.buttonColors(containerColor = colorButton), + modifier = Modifier.fillMaxWidth(), + ) { + Text(text, fontSize = size.sp, color = colorTexte) + } +} \ No newline at end of file diff --git a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/SignUpPage.kt b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/SignUpPage.kt index ce60fcf..cc4f679 100644 --- a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/SignUpPage.kt +++ b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/SignUpPage.kt @@ -1,6 +1,201 @@ package com.example.what_the_fantasy.ui.screens +import android.os.Bundle +import androidx.activity.ComponentActivity +import androidx.activity.compose.setContent +import androidx.activity.enableEdgeToEdge +import androidx.compose.foundation.background +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.foundation.text.KeyboardOptions +import androidx.compose.material3.Button +import androidx.compose.material3.ButtonDefaults +import androidx.compose.material3.IconButton +import androidx.compose.material3.OutlinedTextField +import androidx.compose.material3.Text import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.geometry.Offset +import androidx.compose.ui.graphics.Brush +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.input.KeyboardType +import androidx.compose.ui.text.input.PasswordVisualTransformation +import androidx.compose.ui.text.input.VisualTransformation +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import androidx.navigation.NavController +import com.example.what_the_fantasy.ui.theme.What_The_FantasyTheme @Composable -fun SignUpPage() {} \ No newline at end of file +fun SignUpPage(navController: NavController) { + val gradient = Brush.linearGradient( + colors = listOf(Color(0xFF7B1FA2), Color(0xFF311B92)), // Violet clair → Violet foncé + start = Offset(0f, 1000f), // Départ en bas à gauche + end = Offset(1000f, 0f) // Fin en haut à droite + ) + + Box( + modifier = Modifier + .fillMaxSize() + .background(Color(0xFF100C1B)), + contentAlignment = Alignment.Center + ){ + Column( + modifier = Modifier + .fillMaxWidth(0.9f) // Ajuste la largeur + .padding(20.dp) // Marge extérieure + .clip(RoundedCornerShape(16.dp)) // Arrondi les angles + .background(gradient) // Ajoute un fond blanc + .padding(20.dp), // Padding interne + horizontalAlignment = Alignment.CenterHorizontally + ) { + + TitleSign("Inscription", 20,Color.White) + IdentifiantTextFieldSign("Identifiant*") + EmailTextFieldSign("Email*") + PassWdTextFieldSign("Mot de passe*") + PassWdConfirmTextFieldSign("Confirmer mot de passe*") + SpaceSign(16) + ConnexionButtonSign("S'incrire",18, Color.White, Color.Black) + SpaceSign(16) + CreateAccountButtonSign("Se connecter",12, Color.White, navController = navController) + + } + } +} + +@Composable +fun SpaceSign(height : Int){ + Spacer( + modifier = Modifier + .height(height.dp)) // Ajoute un espacement +} + + +@Composable +fun IdentifiantTextFieldSign(textIdentifiant : String){ + var identifiant by remember { mutableStateOf("") } // Stocke la valeur du champ + Column(modifier = Modifier.padding(top = 16.dp)) { + OutlinedTextField( + value = identifiant, + onValueChange = { identifiant = it }, + label = { Text(textIdentifiant) }, + modifier = Modifier + .fillMaxWidth() + .padding(top = 8.dp), + keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Text), + shape = RoundedCornerShape(16.dp) // 🔹 Bords arrondis + ) + } +} + +@Composable +fun EmailTextFieldSign(textIdentifiant : String){ + var identifiant by remember { mutableStateOf("") } // Stocke la valeur du champ + Column(modifier = Modifier.padding(top = 16.dp)) { + OutlinedTextField( + value = identifiant, + onValueChange = { identifiant = it }, + label = { Text(textIdentifiant) }, + modifier = Modifier + .fillMaxWidth() + .padding(top = 8.dp), + keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Email), + shape = RoundedCornerShape(16.dp) // 🔹 Bords arrondis + ) + } +} + +@Composable +fun PassWdTextFieldSign(textpasswd : String){ + 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)) { + OutlinedTextField( + value = passwd, + onValueChange = { passwd = it }, + label = { Text(textpasswd) }, + modifier = Modifier + .fillMaxWidth() + .padding(top = 8.dp), + keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Password), + visualTransformation = if (passwordVisible) VisualTransformation.None else PasswordVisualTransformation(), + trailingIcon = { + IconButton(onClick = { passwordVisible = !passwordVisible }) { + } + }, + shape = RoundedCornerShape(16.dp) // 🔹 Bords arrondis + ) + } +} + +@Composable +fun PassWdConfirmTextFieldSign(textpasswd : String){ + 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)) { + OutlinedTextField( + value = passwd, + onValueChange = { passwd = it }, + label = { Text(textpasswd) }, + modifier = Modifier + .fillMaxWidth() + .padding(top = 8.dp), + keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Password), + visualTransformation = if (passwordVisible) VisualTransformation.None else PasswordVisualTransformation(), + trailingIcon = { + IconButton(onClick = { passwordVisible = !passwordVisible }) { + } + }, + shape = RoundedCornerShape(16.dp) // 🔹 Bords arrondis + ) + } +} + +@Composable +fun TitleSign(title : String, size : Int, color : Color){ + Text( + text = title, + fontSize = size.sp, + fontWeight = FontWeight.Bold, + color = color + ) +} + +@Composable +fun ConnexionButtonSign(title : String, size : Int, colorButton : Color, colorText : Color){ + Button( + onClick = { /* Action */ }, + colors = ButtonDefaults.buttonColors(containerColor = colorButton), + modifier = Modifier + .fillMaxWidth(), + ) { + Text(title, fontSize = size.sp, color = colorText) + } +} + +@Composable +fun CreateAccountButtonSign(title: String, size: Int, color: Color, navController: NavController) { + Text( + text = title, + fontSize = size.sp, + color = color, + modifier = Modifier.clickable { + navController.popBackStack() // Revenir à la page précédente + } + ) +} From 1de145c96ce16da5a18277e66af25f24cc5459f6 Mon Sep 17 00:00:00 2001 From: "leni.beaulaton" Date: Thu, 13 Feb 2025 23:12:36 +0100 Subject: [PATCH 03/21] Traduction fr-en --- .../example/what_the_fantasy/MainActivity.kt | 4 +- .../what_the_fantasy/ui/screens/LoginPage.kt | 28 +++++++---- .../what_the_fantasy/ui/screens/ProfilPage.kt | 32 ++++++++----- .../what_the_fantasy/ui/screens/SignUpPage.kt | 48 +++++++++++-------- .../app/src/main/res/values-fr/strings.xml | 23 +++++++++ .../app/src/main/res/values/strings.xml | 24 ++++++++++ 6 files changed, 115 insertions(+), 44 deletions(-) diff --git a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/MainActivity.kt b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/MainActivity.kt index ea5af26..0dba709 100644 --- a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/MainActivity.kt +++ b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/MainActivity.kt @@ -30,8 +30,8 @@ class MainActivity : ComponentActivity() { ) } } - AppNavigator() // Accès à la page login et SingUp (pour le moment) - //ProfilPage() //Accès à la page profil + //AppNavigator() // Accès à la page login et SingUp (pour le moment) + ProfilPage() //Accès à la page profil } } } diff --git a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/LoginPage.kt b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/LoginPage.kt index 7c5358b..2596711 100644 --- a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/LoginPage.kt +++ b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/LoginPage.kt @@ -35,6 +35,7 @@ import androidx.compose.ui.draw.clip import androidx.compose.ui.geometry.Offset import androidx.compose.ui.graphics.Brush import androidx.compose.ui.graphics.Color +import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.input.KeyboardType import androidx.compose.ui.text.input.PasswordVisualTransformation @@ -46,6 +47,8 @@ import androidx.navigation.NavController import androidx.navigation.compose.rememberNavController import androidx.navigation.compose.NavHost import androidx.navigation.compose.composable +import com.example.what_the_fantasy.R + @Composable fun LoginPage(navController : NavController) { @@ -71,13 +74,13 @@ fun LoginPage(navController : NavController) { horizontalAlignment = Alignment.CenterHorizontally ) { - TitleLogin("Connexion au compte", 20,Color.White) - IdentifiantTextField("Identifiant*") - PassWdTextField("Mot de passe*") + TitlePage(R.string.titleLogin, 20,Color.White) + IdentifiantTextField(R.string.IdentifiantLogin) + PassWdTextField(R.string.PasswdLogin) Space(16) - ConnexionButtonLogin("Connexion",18, Color.White, Color.Black) + ConnexionButtonLogin(R.string.ButtonLogin,18, Color.White, Color.Black) Space(16) - CreateAccountButton("Créer un compte",12, Color.White, navController) + CreateAccountButton(R.string.ButtonCreateLogin,12, Color.White, navController) } } @@ -92,7 +95,8 @@ fun Space(height : Int){ @Composable -fun IdentifiantTextField(textIdentifiant : String){ +fun IdentifiantTextField(textIdentifiantResId : Int){ + val textIdentifiant = stringResource(id = textIdentifiantResId) var identifiant by remember { mutableStateOf("") } // Stocke la valeur du champ Column(modifier = Modifier.padding(top = 16.dp)) { OutlinedTextField( @@ -109,7 +113,8 @@ fun IdentifiantTextField(textIdentifiant : String){ } @Composable -fun PassWdTextField(textpasswd : String){ +fun PassWdTextField(textpasswdResId : Int){ + 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)) { @@ -132,7 +137,8 @@ fun PassWdTextField(textpasswd : String){ } @Composable -fun TitleLogin(title : String, size : Int, color : Color){ +fun TitlePage(titleResId : Int, size : Int, color : Color){ + val title = stringResource(id = titleResId) Text( text = title, fontSize = size.sp, @@ -142,7 +148,8 @@ fun TitleLogin(title : String, size : Int, color : Color){ } @Composable -fun ConnexionButtonLogin(title : String, size : Int, colorButton : Color, colorText : Color){ +fun ConnexionButtonLogin(titleResId : Int, size : Int, colorButton : Color, colorText : Color){ + val title = stringResource(id = titleResId) Button( onClick = { /* Action */ }, colors = ButtonDefaults.buttonColors(containerColor = colorButton), @@ -154,7 +161,8 @@ fun ConnexionButtonLogin(title : String, size : Int, colorButton : Color, colorT } @Composable -fun CreateAccountButton(title : String, size : Int, color : Color, navController: NavController){ +fun CreateAccountButton(titleResId : Int, size : Int, color : Color, navController: NavController){ + val title = stringResource(id = titleResId) Text( text = title, fontSize = size.sp, diff --git a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/ProfilPage.kt b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/ProfilPage.kt index 6d8d60e..ea753fd 100644 --- a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/ProfilPage.kt +++ b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/ProfilPage.kt @@ -43,6 +43,7 @@ import androidx.compose.ui.geometry.Offset import androidx.compose.ui.graphics.Brush import androidx.compose.ui.graphics.Color import androidx.compose.ui.res.painterResource +import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.input.ImeAction @@ -81,7 +82,7 @@ fun ProfilPage() { ) { // Titre - TitleProfil("Profil", 20, Color.White) + TitleProfil(R.string.titleProfile, 20, Color.White) SpaceProfil(16) // Image de profil @@ -101,11 +102,11 @@ fun ProfilPage() { SpaceProfil(16) // Bouton - ButtonProfile("Ajouter une citation",18, Color.Black, Color.White) + ButtonProfile(R.string.ButtonAddQuoteprofile,18, Color.Black, Color.White) SpaceProfil(16) - ButtonProfile("Langue",18, Color.Black, Color.White) + ButtonProfile(R.string.ButtonLanguageprofile,18, Color.Black, Color.White) SpaceProfil(16) - ButtonProfile("Déconnexion", 18, Color.Black, Color.White) + ButtonProfile(R.string.ButtonUnlogprofile, 18, Color.Black, Color.White) } } @@ -121,7 +122,8 @@ fun SpaceProfil(height : Int){ @Composable -fun TitleProfil(title : String, size : Int, color : Color){ +fun TitleProfil(titleResId : Int, size : Int, color : Color){ + val title = stringResource(id = titleResId) Text( text = title, fontSize = size.sp, @@ -174,8 +176,9 @@ fun EditEmail(){ isError = emailError // ✅ Afficher l'erreur si l'email est invalide ) if (emailError) { + val text = stringResource(id = R.string.ErrorEmailprofile) Text( - text = "Adresse e-mail invalide", + text = text, color = Color.Red, fontSize = 12.sp, modifier = Modifier.padding(top = 4.dp) @@ -259,10 +262,11 @@ fun EditPasswd(){ var passwordError by remember { mutableStateOf(false) } if (isEditingPassword) { Column { + val text = stringResource(id = R.string.NewPasswdprofile) OutlinedTextField( value = newPassword, onValueChange = { newPassword = it }, - label = { Text("Nouveau mot de passe") }, + label = { Text(text) }, modifier = Modifier.fillMaxWidth(), textStyle = TextStyle(color = Color.White, fontSize = 18.sp), singleLine = true, @@ -279,14 +283,15 @@ fun EditPasswd(){ ) Spacer(modifier = Modifier.height(8.dp)) - + val textConfirm = stringResource(id = R.string.ConfirmNewPasswdprofile) OutlinedTextField( value = confirmPassword, onValueChange = { confirmPassword = it passwordError = newPassword != it }, - label = { Text("Confirmer le mot de passe") }, + + label = { Text(textConfirm) }, modifier = Modifier.fillMaxWidth(), textStyle = TextStyle(color = Color.White, fontSize = 18.sp), singleLine = true, @@ -310,8 +315,9 @@ fun EditPasswd(){ ) if (passwordError) { + val text = stringResource(id = R.string.Errorpasswdprofile) Text( - text = "Les mots de passe ne correspondent pas", + text = text, color = Color.Red, fontSize = 12.sp, modifier = Modifier.padding(top = 4.dp) @@ -330,7 +336,8 @@ fun EditPasswd(){ colors = ButtonDefaults.buttonColors(containerColor = Color.White), modifier = Modifier.fillMaxWidth() ) { - Text("Valider", fontSize = 18.sp, color = Color.Black) + val text = stringResource(id = R.string.ButtonSaveprofile) + Text(text, fontSize = 18.sp, color = Color.Black) } } } else { @@ -356,7 +363,8 @@ fun EditPasswd(){ @Composable -fun ButtonProfile(text : String, size :Int, colorTexte : Color, colorButton : Color){ +fun ButtonProfile(textResId : Int, size :Int, colorTexte : Color, colorButton : Color){ + val text = stringResource(id = textResId) Button( onClick = { /* Action */ }, colors = ButtonDefaults.buttonColors(containerColor = colorButton), diff --git a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/SignUpPage.kt b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/SignUpPage.kt index cc4f679..7ed5121 100644 --- a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/SignUpPage.kt +++ b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/SignUpPage.kt @@ -31,6 +31,7 @@ import androidx.compose.ui.draw.clip import androidx.compose.ui.geometry.Offset import androidx.compose.ui.graphics.Brush import androidx.compose.ui.graphics.Color +import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.input.KeyboardType import androidx.compose.ui.text.input.PasswordVisualTransformation @@ -38,6 +39,7 @@ import androidx.compose.ui.text.input.VisualTransformation import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import androidx.navigation.NavController +import com.example.what_the_fantasy.R import com.example.what_the_fantasy.ui.theme.What_The_FantasyTheme @Composable @@ -64,15 +66,15 @@ fun SignUpPage(navController: NavController) { horizontalAlignment = Alignment.CenterHorizontally ) { - TitleSign("Inscription", 20,Color.White) - IdentifiantTextFieldSign("Identifiant*") + TitlePage(R.string.titleSignUp, 20,Color.White) + IdentifiantTextFieldSign(R.string.IdentifiantLogin) EmailTextFieldSign("Email*") - PassWdTextFieldSign("Mot de passe*") - PassWdConfirmTextFieldSign("Confirmer mot de passe*") + PassWdTextFieldSign(R.string.PasswdLogin) + PassWdConfirmTextFieldSign(R.string.ConfirmPassWdSignUp) SpaceSign(16) - ConnexionButtonSign("S'incrire",18, Color.White, Color.Black) + ConnexionButtonSign(R.string.ButtonSignUp,18, Color.White, Color.Black) SpaceSign(16) - CreateAccountButtonSign("Se connecter",12, Color.White, navController = navController) + CreateAccountButtonSign(R.string.ButtonLogin,12, Color.White, navController = navController) } } @@ -87,8 +89,10 @@ fun SpaceSign(height : Int){ @Composable -fun IdentifiantTextFieldSign(textIdentifiant : String){ +fun IdentifiantTextFieldSign(textIdentifiantResId : Int){ + val textIdentifiant = stringResource(id = textIdentifiantResId) var identifiant by remember { mutableStateOf("") } // Stocke la valeur du champ + Column(modifier = Modifier.padding(top = 16.dp)) { OutlinedTextField( value = identifiant, @@ -121,7 +125,8 @@ fun EmailTextFieldSign(textIdentifiant : String){ } @Composable -fun PassWdTextFieldSign(textpasswd : String){ +fun PassWdTextFieldSign(textpasswdResId : Int){ + 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)) { @@ -144,7 +149,8 @@ fun PassWdTextFieldSign(textpasswd : String){ } @Composable -fun PassWdConfirmTextFieldSign(textpasswd : String){ +fun PassWdConfirmTextFieldSign(textpasswdResId : Int){ + 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)) { @@ -166,18 +172,19 @@ fun PassWdConfirmTextFieldSign(textpasswd : String){ } } -@Composable -fun TitleSign(title : String, size : Int, color : Color){ - Text( - text = title, - fontSize = size.sp, - fontWeight = FontWeight.Bold, - color = color - ) -} +//@Composable +//fun TitleSign(title : String, size : Int, color : Color){ +// Text( +// text = title, +// fontSize = size.sp, +// fontWeight = FontWeight.Bold, +// color = color +// ) +//} @Composable -fun ConnexionButtonSign(title : String, size : Int, colorButton : Color, colorText : Color){ +fun ConnexionButtonSign(titleResId : Int, size : Int, colorButton : Color, colorText : Color){ + val title = stringResource(id = titleResId) Button( onClick = { /* Action */ }, colors = ButtonDefaults.buttonColors(containerColor = colorButton), @@ -189,7 +196,8 @@ fun ConnexionButtonSign(title : String, size : Int, colorButton : Color, colorTe } @Composable -fun CreateAccountButtonSign(title: String, size: Int, color: Color, navController: NavController) { +fun CreateAccountButtonSign(titleResId: Int, size: Int, color: Color, navController: NavController) { + val title = stringResource(id = titleResId) Text( text = title, fontSize = size.sp, diff --git a/What_The_Fantasy/app/src/main/res/values-fr/strings.xml b/What_The_Fantasy/app/src/main/res/values-fr/strings.xml index cfb65f0..9d55b61 100644 --- a/What_The_Fantasy/app/src/main/res/values-fr/strings.xml +++ b/What_The_Fantasy/app/src/main/res/values-fr/strings.xml @@ -4,4 +4,27 @@ Film Jeu Vidéo Série + + //Page Login + Connexion au compte + Votre identifiant* + Votre mot de passe* + Se connecter + Créer son compte + + //Page Sign Up + Inscription + Confirmer mot de passe* + S\'inscrire + + //Page Profil + Profil + Suggérer une citation + Changer la langue + Se Déconnecter + Nouveau mot de passe + Confirmer le nouveau mot de passe + Sauvegarder + L\'adress email est invalide + Les mots de passe ne correspondent pas \ No newline at end of file diff --git a/What_The_Fantasy/app/src/main/res/values/strings.xml b/What_The_Fantasy/app/src/main/res/values/strings.xml index 75ba845..c9ab3e1 100644 --- a/What_The_Fantasy/app/src/main/res/values/strings.xml +++ b/What_The_Fantasy/app/src/main/res/values/strings.xml @@ -3,4 +3,28 @@ Movie Video Game Series + + //Page Login + Account login + Your username* + Your password* + Login + Create your account + + //Page Sign Up + Account creation + Confirm your password* + Create + + //Page Profil + Profile + Suggest a quote + Change Language + Disconnect + New password + Confirm password + Save + Invalid email address + Passwords do not match + \ No newline at end of file From 773c40bfa64f246f56575b10a9821e503501fe07 Mon Sep 17 00:00:00 2001 From: "louis.guichard-montguers" Date: Fri, 14 Feb 2025 12:00:28 +0100 Subject: [PATCH 04/21] page Quizz --- .../example/what_the_fantasy/MainActivity.kt | 4 +- .../what_the_fantasy/ui/screens/QuizPage.kt | 103 +++++++++++++++++- 2 files changed, 105 insertions(+), 2 deletions(-) diff --git a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/MainActivity.kt b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/MainActivity.kt index 0dba709..45b0771 100644 --- a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/MainActivity.kt +++ b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/MainActivity.kt @@ -15,6 +15,7 @@ import com.example.what_the_fantasy.ui.screens.AppNavigator 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() { override fun onCreate(savedInstanceState: Bundle?) { @@ -31,7 +32,8 @@ class MainActivity : ComponentActivity() { } } //AppNavigator() // Accès à la page login et SingUp (pour le moment) - ProfilPage() //Accès à la page profil + //ProfilPage() //Accès à la page profil + QuizPage() } } } diff --git a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/QuizPage.kt b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/QuizPage.kt index bc7854f..a342a02 100644 --- a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/QuizPage.kt +++ b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/QuizPage.kt @@ -1,6 +1,107 @@ package com.example.what_the_fantasy.ui.screens +import androidx.compose.foundation.background +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.width +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material3.Button +import androidx.compose.material3.ButtonColors +import androidx.compose.material3.ButtonDefaults +import androidx.compose.material3.Text import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.geometry.Offset +import androidx.compose.ui.graphics.Brush +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import com.example.what_the_fantasy.data.local.QuestionStub +import com.example.what_the_fantasy.data.model.Question @Composable -fun QuizPage() {} \ No newline at end of file +fun QuizPage() { + val gradient = Brush.linearGradient( + colors = listOf(Color(0xFF7B1FA2), Color(0xFF311B92)), // Violet clair → Violet foncé + start = Offset(0f, 1000f), // Départ en bas à gauche + end = Offset(1000f, 0f) // Fin en haut à droite + ) + + val questions = QuestionStub.allQuestions + + Box( + modifier = Modifier + .fillMaxSize() + .background(Color(0xFF100C1B)) // Fond global de l'écran + .padding(16.dp) // Marges autour de tout le contenu + ) { + // Numéro de la question en haut + Text( + text = "Question numéro : " + questions.first().id.toString(), + color = Color.White, + fontSize = 18.sp, // Taille réduite pour tenir sur un écran portrait + modifier = Modifier + .align(Alignment.TopCenter) // Position en haut au centre + .padding(top = 16.dp) // Un peu d'espace en haut + ) + + // Contenu centré, mais avec une gestion plus équilibrée du placement + Column( + modifier = Modifier + .fillMaxSize() + .padding(top = 48.dp), // Réduit l'espace entre le numéro de la question et la question elle-même + verticalArrangement = Arrangement.Center, // Centre verticalement + horizontalAlignment = Alignment.CenterHorizontally // Centre horizontalement + ) { + // Question principale + Text( + text = questions.first().question, + color = Color.White, + fontSize = 22.sp, // Taille plus petite pour tenir sur un écran portrait + modifier = Modifier.padding(bottom = 16.dp) // Réduit l'espacement entre la question et les réponses + ) + + // Liste des réponses + val answers = listOf( + questions.first().ansA, + questions.first().ansB, + questions.first().ansC, + questions.first().ansD + ) + + // Pour chaque réponse, on applique une Box avec un espacement uniforme + answers.forEach { answer -> + Box( + modifier = Modifier + .width(220.dp) // Largeur plus petite pour que ça tienne mieux + .height(50.dp) // Hauteur ajustée + .background( + brush = gradient, + shape = RoundedCornerShape(16.dp) // Coins arrondis + ) + .clickable { /* Action pour la réponse */ } + .padding(horizontal = 8.dp), // Padding interne + contentAlignment = Alignment.Center + ) { + Text( + text = answer, + color = Color.White, + fontSize = 18.sp // Taille du texte ajustée pour un écran portrait + ) + } + Spacer(modifier = Modifier.height(16.dp)) // Espacement réduit entre les réponses + } + } + } +} + + From d102a7f3d8517ab34602aa17b50e41eb6d7e9733 Mon Sep 17 00:00:00 2001 From: beaulaton Date: Fri, 14 Feb 2025 15:24:44 +0100 Subject: [PATCH 05/21] Stub en cours pour la page profil, pb pour l'image url --- .../app/src/main/AndroidManifest.xml | 3 ++ .../example/what_the_fantasy/MainActivity.kt | 4 +-- .../what_the_fantasy/ui/screens/ProfilPage.kt | 30 ++++++++++++------- 3 files changed, 24 insertions(+), 13 deletions(-) diff --git a/What_The_Fantasy/app/src/main/AndroidManifest.xml b/What_The_Fantasy/app/src/main/AndroidManifest.xml index 1aef3bb..5dbf082 100644 --- a/What_The_Fantasy/app/src/main/AndroidManifest.xml +++ b/What_The_Fantasy/app/src/main/AndroidManifest.xml @@ -1,6 +1,9 @@ + + + Date: Fri, 14 Feb 2025 16:12:17 +0100 Subject: [PATCH 06/21] changement de la page afficher --- .../com/example/what_the_fantasy/MainActivity.kt | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/MainActivity.kt b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/MainActivity.kt index 45b0771..2f05acd 100644 --- a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/MainActivity.kt +++ b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/MainActivity.kt @@ -23,17 +23,9 @@ class MainActivity : ComponentActivity() { enableEdgeToEdge() setContent { What_The_FantasyTheme { - Column { - Scaffold(modifier = Modifier.fillMaxSize()) { innerPadding -> - Title( - title = "What The Fantasy", - modifier = Modifier.padding(innerPadding) - ) - } - } //AppNavigator() // Accès à la page login et SingUp (pour le moment) - //ProfilPage() //Accès à la page profil - QuizPage() + ProfilPage() //Accès à la page profil + //QuizPage() } } } From 50aa963de2799a523e303e2fc930c6ae2d3607ac Mon Sep 17 00:00:00 2001 From: "leni.beaulaton" Date: Fri, 14 Feb 2025 19:03:35 +0100 Subject: [PATCH 07/21] Ajout de l'url de l'image (AsyncImage) --- What_The_Fantasy/app/build.gradle.kts | 2 ++ .../example/what_the_fantasy/ui/screens/ProfilPage.kt | 10 +++++----- What_The_Fantasy/gradle/libs.versions.toml | 2 ++ 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/What_The_Fantasy/app/build.gradle.kts b/What_The_Fantasy/app/build.gradle.kts index 994366b..e884189 100644 --- a/What_The_Fantasy/app/build.gradle.kts +++ b/What_The_Fantasy/app/build.gradle.kts @@ -68,4 +68,6 @@ dependencies { androidTestImplementation(libs.androidx.ui.test.junit4) debugImplementation(libs.androidx.ui.tooling) debugImplementation(libs.androidx.ui.test.manifest) + implementation(libs.coil.compose) + } \ No newline at end of file diff --git a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/ProfilPage.kt b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/ProfilPage.kt index de8c577..7d287df 100644 --- a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/ProfilPage.kt +++ b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/ProfilPage.kt @@ -56,6 +56,7 @@ import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import androidx.navigation.NavController +import coil.compose.AsyncImage import com.example.what_the_fantasy.R import com.example.what_the_fantasy.data.local.QuestionStub import com.example.what_the_fantasy.data.local.UserStub @@ -69,7 +70,7 @@ fun ProfilPage() { end = Offset(1000f, 0f) // Fin en haut à droite ) val user = UserStub.allUsers - val index = 5 // Pour changer l'utilisateur pour le moment + val index = 2 // Pour changer l'utilisateur pour le moment Box( modifier = Modifier @@ -139,15 +140,14 @@ fun TitleProfil(titleResId : Int, size : Int, color : Color){ @Composable fun ImageProfil(imgProfil : String, size :Int, sizeBorber : Int, colorBorder : Color){ - - Image( - painter = painterResource(imgProfil), + AsyncImage( + model = imgProfil, contentDescription = "Photo de profil", modifier = Modifier .size(size.dp) .clip(CircleShape) - .border(sizeBorber.dp, colorBorder, CircleShape) ) + } diff --git a/What_The_Fantasy/gradle/libs.versions.toml b/What_The_Fantasy/gradle/libs.versions.toml index 302bb60..251a75f 100644 --- a/What_The_Fantasy/gradle/libs.versions.toml +++ b/What_The_Fantasy/gradle/libs.versions.toml @@ -1,5 +1,6 @@ [versions] agp = "8.6.0" +coilCompose = "2.2.1" kotlin = "1.9.0" coreKtx = "1.10.1" junit = "4.13.2" @@ -13,6 +14,7 @@ navigationCommonAndroid = "2.9.0-alpha05" [libraries] androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" } +coil-compose = { module = "io.coil-kt:coil-compose", version.ref = "coilCompose" } junit = { group = "junit", name = "junit", version.ref = "junit" } androidx-junit = { group = "androidx.test.ext", name = "junit", version.ref = "junitVersion" } androidx-espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espressoCore" } From bb712a0e86de233ea8ab508c3be2ac12764221a3 Mon Sep 17 00:00:00 2001 From: "leni.beaulaton" Date: Sat, 15 Feb 2025 00:19:30 +0100 Subject: [PATCH 08/21] Commencement du lien login --- .../example/what_the_fantasy/MainActivity.kt | 4 +- .../what_the_fantasy/data/local/UserStub.kt | 39 ++++++++++--------- .../what_the_fantasy/data/model/User.kt | 3 +- .../what_the_fantasy/ui/screens/LoginPage.kt | 29 ++++++++++---- .../what_the_fantasy/ui/screens/ProfilPage.kt | 2 +- 5 files changed, 47 insertions(+), 30 deletions(-) diff --git a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/MainActivity.kt b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/MainActivity.kt index 5dd132b..f3676f0 100644 --- a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/MainActivity.kt +++ b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/MainActivity.kt @@ -31,8 +31,8 @@ class MainActivity : ComponentActivity() { ) } } - //AppNavigator() // Accès à la page login et SingUp (pour le moment) - ProfilPage() //Accès à la page profil + AppNavigator() // Accès à la page login et SingUp (pour le moment) + //ProfilPage() //Accès à la page profil //QuizPage() } } diff --git a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/data/local/UserStub.kt b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/data/local/UserStub.kt index b05fbb3..48a3f0e 100644 --- a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/data/local/UserStub.kt +++ b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/data/local/UserStub.kt @@ -8,71 +8,72 @@ object UserStub { username = "Aragorn123", email = "aragorn@example.com", date = "2022-01-15", - imgUrl = "https://img.freepik.com/vecteurs-libre/personnage-guerrier-fantaisie_1045-185.jpg?size=338&ext=jpg" + imgUrl = "https://img.freepik.com/vecteurs-libre/personnage-guerrier-fantaisie_1045-185.jpg?size=338&ext=jpg", + password = "password123" ) val user2 = User( id = 2, username = "Legolas456", email = "legolas@example.com", date = "2021-05-23", - imgUrl = "https://img.freepik.com/vecteurs-libre/personnage-elfe-fantaisie_1045-186.jpg?size=338&ext=jpg" - ) + imgUrl = "https://img.freepik.com/vecteurs-libre/personnage-elfe-fantaisie_1045-186.jpg?size=338&ext=jpg", + password = "password123") val user3 = User( id = 3, username = "Gandalf789", email = "gandalf@example.com", date = "2020-09-10", - imgUrl = "https://img.freepik.com/vecteurs-libre/personnage-magicien-fantaisie_1045-187.jpg?size=338&ext=jpg" - ) + imgUrl = "https://img.freepik.com/vecteurs-libre/personnage-magicien-fantaisie_1045-187.jpg?size=338&ext=jpg", + password = "password123") val user4 = User( id = 4, username = "FrodoBaggins", email = "frodo@example.com", date = "2023-03-18", - imgUrl = "https://img.freepik.com/vecteurs-libre/personnage-hobbit-fantaisie_1045-188.jpg?size=338&ext=jpg" - ) + imgUrl = "https://img.freepik.com/vecteurs-libre/personnage-hobbit-fantaisie_1045-188.jpg?size=338&ext=jpg", + password = "password123") val user5 = User( id = 5, username = "Gimli999", email = "gimli@example.com", date = "2022-07-04", - imgUrl = "https://img.freepik.com/vecteurs-libre/personnage-nain-fantaisie_1045-189.jpg?size=338&ext=jpg" - ) + imgUrl = "https://img.freepik.com/vecteurs-libre/personnage-nain-fantaisie_1045-189.jpg?size=338&ext=jpg", + password = "password123") val user6 = User( id = 6, username = "Galadriel321", email = "galadriel@example.com", date = "2021-11-30", - imgUrl = "https://img.freepik.com/vecteurs-libre/personnage-elfe-femme-fantaisie_1045-190.jpg?size=338&ext=jpg" - ) + imgUrl = "https://img.freepik.com/vecteurs-libre/personnage-elfe-femme-fantaisie_1045-190.jpg?size=338&ext=jpg", + password = "password123") val user7 = User( id = 7, username = "Boromir654", email = "boromir@example.com", date = "2023-06-22", - imgUrl = "https://img.freepik.com/vecteurs-libre/personnage-guerrier-homme-fantaisie_1045-191.jpg?size=338&ext=jpg" - ) + imgUrl = "https://img.freepik.com/vecteurs-libre/personnage-guerrier-homme-fantaisie_1045-191.jpg?size=338&ext=jpg", + password = "password123") val user8 = User( id = 8, username = "Eowyn777", email = "eowyn@example.com", date = "2022-04-11", - imgUrl = "https://img.freepik.com/vecteurs-libre/personnage-guerriere-femme-fantaisie_1045-192.jpg?size=338&ext=jpg" - ) + imgUrl = "https://img.freepik.com/vecteurs-libre/personnage-guerriere-femme-fantaisie_1045-192.jpg?size=338&ext=jpg", + password = "password123") val user9 = User( id = 9, username = "Saruman888", email = "saruman@example.com", date = "2021-08-15", - imgUrl = "https://img.freepik.com/vecteurs-libre/personnage-magicien-malefique-fantaisie_1045-193.jpg?size=338&ext=jpg" - ) + imgUrl = "https://img.freepik.com/vecteurs-libre/personnage-magicien-malefique-fantaisie_1045-193.jpg?size=338&ext=jpg", + password = "password123") val user10 = User( id = 10, username = "Faramir222", email = "faramir@example.com", date = "2023-02-08", - imgUrl = "https://img.freepik.com/vecteurs-libre/personnage-guerrier-homme-fantaisie_1045-194.jpg?size=338&ext=jpg" - ) + imgUrl = "https://img.freepik.com/vecteurs-libre/personnage-guerrier-homme-fantaisie_1045-194.jpg?size=338&ext=jpg", + password = "password123") val allUsers: List = listOf( user1, user2, user3, user4, user5, user6, user7, user8, user9, user10 diff --git a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/data/model/User.kt b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/data/model/User.kt index 10af186..ce4cb2f 100644 --- a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/data/model/User.kt +++ b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/data/model/User.kt @@ -5,5 +5,6 @@ class User( var username:String, var email:String, var date:String, - val imgUrl: String + val imgUrl: String, + val password: String ) diff --git a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/LoginPage.kt b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/LoginPage.kt index 2596711..cf17cd1 100644 --- a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/LoginPage.kt +++ b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/LoginPage.kt @@ -44,14 +44,18 @@ import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import com.example.what_the_fantasy.ui.theme.What_The_FantasyTheme import androidx.navigation.NavController +import androidx.navigation.Navigation import androidx.navigation.compose.rememberNavController import androidx.navigation.compose.NavHost import androidx.navigation.compose.composable import com.example.what_the_fantasy.R +import com.example.what_the_fantasy.data.local.UserStub +import com.example.what_the_fantasy.data.model.User @Composable fun LoginPage(navController : NavController) { + val users = UserStub.allUsers; val gradient = Brush.linearGradient( colors = listOf(Color(0xFF7B1FA2), Color(0xFF311B92)), // Violet clair → Violet foncé start = Offset(0f, 1000f), // Départ en bas à gauche @@ -75,10 +79,10 @@ fun LoginPage(navController : NavController) { ) { TitlePage(R.string.titleLogin, 20,Color.White) - IdentifiantTextField(R.string.IdentifiantLogin) - PassWdTextField(R.string.PasswdLogin) + val identifiant =IdentifiantTextField(R.string.IdentifiantLogin) + val passwd = PassWdTextField(R.string.PasswdLogin) Space(16) - ConnexionButtonLogin(R.string.ButtonLogin,18, Color.White, Color.Black) + ConnexionButtonLogin(users,identifiant, passwd, R.string.ButtonLogin,18, Color.White, Color.Black,navController) Space(16) CreateAccountButton(R.string.ButtonCreateLogin,12, Color.White, navController) @@ -95,7 +99,7 @@ fun Space(height : Int){ @Composable -fun IdentifiantTextField(textIdentifiantResId : Int){ +fun IdentifiantTextField(textIdentifiantResId : Int) : String{ val textIdentifiant = stringResource(id = textIdentifiantResId) var identifiant by remember { mutableStateOf("") } // Stocke la valeur du champ Column(modifier = Modifier.padding(top = 16.dp)) { @@ -110,10 +114,11 @@ fun IdentifiantTextField(textIdentifiantResId : Int){ shape = RoundedCornerShape(16.dp) // 🔹 Bords arrondis ) } + return identifiant; } @Composable -fun PassWdTextField(textpasswdResId : Int){ +fun PassWdTextField(textpasswdResId : Int) : String{ 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 @@ -134,6 +139,7 @@ fun PassWdTextField(textpasswdResId : Int){ shape = RoundedCornerShape(16.dp) // 🔹 Bords arrondis ) } + return passwd; } @Composable @@ -148,10 +154,10 @@ fun TitlePage(titleResId : Int, size : Int, color : Color){ } @Composable -fun ConnexionButtonLogin(titleResId : Int, size : Int, colorButton : Color, colorText : Color){ +fun ConnexionButtonLogin(userStub : List, id : String, passwd : String, titleResId : Int, size : Int, colorButton : Color, colorText : Color, navController: NavController){ val title = stringResource(id = titleResId) Button( - onClick = { /* Action */ }, + onClick = { ValidLogin(id, passwd, userStub, navController) }, colors = ButtonDefaults.buttonColors(containerColor = colorButton), modifier = Modifier .fillMaxWidth(), @@ -160,6 +166,14 @@ fun ConnexionButtonLogin(titleResId : Int, size : Int, colorButton : Color, colo } } +fun ValidLogin(identifiant : String, passwd : String, users : List, navController: NavController){ + users.forEach { user -> + if (user.username == identifiant && user.password == passwd){ + navController.navigate("profile") + } + } +} + @Composable fun CreateAccountButton(titleResId : Int, size : Int, color : Color, navController: NavController){ val title = stringResource(id = titleResId) @@ -180,6 +194,7 @@ fun AppNavigator() { NavHost(navController, startDestination = "login") { composable("login") { LoginPage(navController) } composable("signup") { SignUpPage(navController) } + composable("profile") { ProfilPage(navController) } } } \ No newline at end of file diff --git a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/ProfilPage.kt b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/ProfilPage.kt index 7d287df..be9ef85 100644 --- a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/ProfilPage.kt +++ b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/ProfilPage.kt @@ -63,7 +63,7 @@ import com.example.what_the_fantasy.data.local.UserStub import com.example.what_the_fantasy.ui.theme.What_The_FantasyTheme @Composable -fun ProfilPage() { +fun ProfilPage(navController: NavController) { val gradient = Brush.linearGradient( colors = listOf(Color(0xFF7B1FA2), Color(0xFF311B92)), // Violet clair → Violet foncé start = Offset(0f, 1000f), // Départ en bas à gauche From 657da2d024ba746718efde963285aa293f41977e Mon Sep 17 00:00:00 2001 From: beaulaton Date: Mon, 17 Feb 2025 14:24:26 +0100 Subject: [PATCH 09/21] En cours de hachage --- What_The_Fantasy/app/build.gradle.kts | 4 ++-- .../com/example/what_the_fantasy/ui/screens/LoginPage.kt | 7 +++++-- .../com/example/what_the_fantasy/ui/screens/ProfilPage.kt | 5 ++--- What_The_Fantasy/gradle/libs.versions.toml | 5 +++++ 4 files changed, 14 insertions(+), 7 deletions(-) diff --git a/What_The_Fantasy/app/build.gradle.kts b/What_The_Fantasy/app/build.gradle.kts index e884189..5c11806 100644 --- a/What_The_Fantasy/app/build.gradle.kts +++ b/What_The_Fantasy/app/build.gradle.kts @@ -50,7 +50,7 @@ android { } dependencies { - + implementation(libs.bcrypt) // pour hacher les mdp implementation(libs.androidx.core.ktx) implementation(libs.androidx.lifecycle.runtime.ktx) implementation(libs.androidx.activity.compose) @@ -68,6 +68,6 @@ dependencies { androidTestImplementation(libs.androidx.ui.test.junit4) debugImplementation(libs.androidx.ui.tooling) debugImplementation(libs.androidx.ui.test.manifest) - implementation(libs.coil.compose) + implementation(libs.coil.compose) //gére les url des image } \ No newline at end of file diff --git a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/LoginPage.kt b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/LoginPage.kt index cf17cd1..9f94e86 100644 --- a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/LoginPage.kt +++ b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/LoginPage.kt @@ -157,7 +157,7 @@ fun TitlePage(titleResId : Int, size : Int, color : Color){ fun ConnexionButtonLogin(userStub : List, id : String, passwd : String, titleResId : Int, size : Int, colorButton : Color, colorText : Color, navController: NavController){ val title = stringResource(id = titleResId) Button( - onClick = { ValidLogin(id, passwd, userStub, navController) }, + onClick = { validLogin(id, passwd, userStub, navController) }, colors = ButtonDefaults.buttonColors(containerColor = colorButton), modifier = Modifier .fillMaxWidth(), @@ -166,14 +166,17 @@ fun ConnexionButtonLogin(userStub : List, id : String, passwd : String, ti } } -fun ValidLogin(identifiant : String, passwd : String, users : List, navController: NavController){ + +fun validLogin(identifiant : String, passwd : String, users : List, navController: NavController){ users.forEach { user -> if (user.username == identifiant && user.password == passwd){ navController.navigate("profile") + //navController.navigate(ProfilPage(navController)) } } } + @Composable fun CreateAccountButton(titleResId : Int, size : Int, color : Color, navController: NavController){ val title = stringResource(id = titleResId) diff --git a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/ProfilPage.kt b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/ProfilPage.kt index be9ef85..7d07b7e 100644 --- a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/ProfilPage.kt +++ b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/ProfilPage.kt @@ -2,6 +2,7 @@ package com.example.what_the_fantasy.ui.screens import android.content.Context import android.os.Bundle +import android.util.Patterns import android.widget.ImageView import androidx.activity.ComponentActivity import androidx.activity.compose.setContent @@ -151,8 +152,6 @@ fun ImageProfil(imgProfil : String, size :Int, sizeBorber : Int, colorBorder : C } - - @Composable fun EditEmail(userEmail : String){ var email by remember { mutableStateOf(userEmail) } @@ -164,7 +163,7 @@ fun EditEmail(userEmail : String){ value = email, onValueChange = { email = it - emailError = !android.util.Patterns.EMAIL_ADDRESS.matcher(it).matches() + emailError = !Patterns.EMAIL_ADDRESS.matcher(it).matches() }, modifier = Modifier.fillMaxWidth(), textStyle = TextStyle(color = Color.White, fontSize = 18.sp), diff --git a/What_The_Fantasy/gradle/libs.versions.toml b/What_The_Fantasy/gradle/libs.versions.toml index 251a75f..ae80aff 100644 --- a/What_The_Fantasy/gradle/libs.versions.toml +++ b/What_The_Fantasy/gradle/libs.versions.toml @@ -1,6 +1,8 @@ [versions] agp = "8.6.0" +bcrypt = "2.2.0" coilCompose = "2.2.1" +coilComposeVersion = "3.1.0" kotlin = "1.9.0" coreKtx = "1.10.1" junit = "4.13.2" @@ -14,7 +16,10 @@ navigationCommonAndroid = "2.9.0-alpha05" [libraries] androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" } +bcrypt = { module = "de.nycode:bcrypt", version.ref = "bcrypt" } coil-compose = { module = "io.coil-kt:coil-compose", version.ref = "coilCompose" } +coil-network-okhttp = { module = "io.coil-kt.coil3:coil-network-okhttp", version.ref = "coilComposeVersion" } +coil3-coil-compose = { module = "io.coil-kt.coil3:coil-compose", version.ref = "coilComposeVersion" } junit = { group = "junit", name = "junit", version.ref = "junit" } androidx-junit = { group = "androidx.test.ext", name = "junit", version.ref = "junitVersion" } androidx-espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espressoCore" } From 1cdf28bcdd93d951acf3f975c5b502ef0652a01d Mon Sep 17 00:00:00 2001 From: tomivt Date: Mon, 17 Feb 2025 15:19:48 +0100 Subject: [PATCH 10/21] Answers clickable now --- .../what_the_fantasy/ui/screens/QuizPage.kt | 52 +++++++++++++++---- 1 file changed, 43 insertions(+), 9 deletions(-) diff --git a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/QuizPage.kt b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/QuizPage.kt index a342a02..2970bd2 100644 --- a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/QuizPage.kt +++ b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/QuizPage.kt @@ -1,5 +1,6 @@ package com.example.what_the_fantasy.ui.screens +import android.util.Log import androidx.compose.foundation.background import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Arrangement @@ -18,6 +19,11 @@ import androidx.compose.material3.ButtonColors import androidx.compose.material3.ButtonDefaults import androidx.compose.material3.Text import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableIntStateOf +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.geometry.Offset @@ -28,16 +34,34 @@ import androidx.compose.ui.unit.sp import com.example.what_the_fantasy.data.local.QuestionStub import com.example.what_the_fantasy.data.model.Question + +val questions = QuestionStub.allQuestions +var pts = 0 + @Composable fun QuizPage() { + var idCurrentQuestion by remember { mutableIntStateOf(0) } + fun goNext(correctAns: String, ans: String) { + if (correctAns == "A") { + if (questions[idCurrentQuestion].ansA == ans) pts += 1 + } + if (correctAns == "B") { + if (questions[idCurrentQuestion].ansB == ans) pts += 1 + } + if (correctAns == "C") { + if (questions[idCurrentQuestion].ansC == ans) pts += 1 + } + if (correctAns == "D") { + if (questions[idCurrentQuestion].ansD == ans) pts += 1 + } + if (idCurrentQuestion < questions.size) idCurrentQuestion += 1 + } val gradient = Brush.linearGradient( colors = listOf(Color(0xFF7B1FA2), Color(0xFF311B92)), // Violet clair → Violet foncé start = Offset(0f, 1000f), // Départ en bas à gauche end = Offset(1000f, 0f) // Fin en haut à droite ) - val questions = QuestionStub.allQuestions - Box( modifier = Modifier .fillMaxSize() @@ -46,13 +70,21 @@ fun QuizPage() { ) { // Numéro de la question en haut Text( - text = "Question numéro : " + questions.first().id.toString(), + text = "Question numéro : " + questions[idCurrentQuestion].id.toString(), color = Color.White, fontSize = 18.sp, // Taille réduite pour tenir sur un écran portrait modifier = Modifier .align(Alignment.TopCenter) // Position en haut au centre .padding(top = 16.dp) // Un peu d'espace en haut ) + Text( + text = "Nombre de points : " + pts.toString(), + color = Color.White, + fontSize = 18.sp, // Taille réduite pour tenir sur un écran portrait + modifier = Modifier + .align(Alignment.TopCenter) // Position en haut au centre + .padding(top = 50.dp) // Un peu d'espace en haut + ) // Contenu centré, mais avec une gestion plus équilibrée du placement Column( @@ -64,7 +96,7 @@ fun QuizPage() { ) { // Question principale Text( - text = questions.first().question, + text = questions[idCurrentQuestion].question, color = Color.White, fontSize = 22.sp, // Taille plus petite pour tenir sur un écran portrait modifier = Modifier.padding(bottom = 16.dp) // Réduit l'espacement entre la question et les réponses @@ -72,13 +104,15 @@ fun QuizPage() { // Liste des réponses val answers = listOf( - questions.first().ansA, - questions.first().ansB, - questions.first().ansC, - questions.first().ansD + questions[idCurrentQuestion].ansA, + questions[idCurrentQuestion].ansB, + questions[idCurrentQuestion].ansC, + questions[idCurrentQuestion].ansD, + ) // Pour chaque réponse, on applique une Box avec un espacement uniforme + answers.forEach { answer -> Box( modifier = Modifier @@ -88,7 +122,7 @@ fun QuizPage() { brush = gradient, shape = RoundedCornerShape(16.dp) // Coins arrondis ) - .clickable { /* Action pour la réponse */ } + .clickable { goNext(questions[idCurrentQuestion].correctAns, answer) } .padding(horizontal = 8.dp), // Padding interne contentAlignment = Alignment.Center ) { From 5a1949aca1718e85ce51cf4592b44bd188f365cd Mon Sep 17 00:00:00 2001 From: beaulaton Date: Mon, 17 Feb 2025 16:44:06 +0100 Subject: [PATCH 11/21] Hashage mdp --- .../what_the_fantasy/data/local/UserStub.kt | 40 +++++++++++++------ .../what_the_fantasy/ui/screens/LoginPage.kt | 21 ++++++++-- .../what_the_fantasy/ui/screens/SignUpPage.kt | 11 +---- What_The_Fantasy/gradle/libs.versions.toml | 9 ++--- 4 files changed, 52 insertions(+), 29 deletions(-) diff --git a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/data/local/UserStub.kt b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/data/local/UserStub.kt index 48a3f0e..5bc2351 100644 --- a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/data/local/UserStub.kt +++ b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/data/local/UserStub.kt @@ -9,73 +9,89 @@ object UserStub { email = "aragorn@example.com", date = "2022-01-15", imgUrl = "https://img.freepik.com/vecteurs-libre/personnage-guerrier-fantaisie_1045-185.jpg?size=338&ext=jpg", - password = "password123" - ) + password = "03ac674216f3e15c761ee1a5e255f067953623c8b388b4459e13f978d7c846f4") // 1234 + val user2 = User( id = 2, username = "Legolas456", email = "legolas@example.com", date = "2021-05-23", imgUrl = "https://img.freepik.com/vecteurs-libre/personnage-elfe-fantaisie_1045-186.jpg?size=338&ext=jpg", - password = "password123") + password = "03ac674216f3e15c761ee1a5e255f067953623c8b388b4459e13f978d7c846f4") // 1234 + val user3 = User( id = 3, username = "Gandalf789", email = "gandalf@example.com", date = "2020-09-10", imgUrl = "https://img.freepik.com/vecteurs-libre/personnage-magicien-fantaisie_1045-187.jpg?size=338&ext=jpg", - password = "password123") + password = "03ac674216f3e15c761ee1a5e255f067953623c8b388b4459e13f978d7c846f4") // 1234 + val user4 = User( id = 4, username = "FrodoBaggins", email = "frodo@example.com", date = "2023-03-18", imgUrl = "https://img.freepik.com/vecteurs-libre/personnage-hobbit-fantaisie_1045-188.jpg?size=338&ext=jpg", - password = "password123") + password = "03ac674216f3e15c761ee1a5e255f067953623c8b388b4459e13f978d7c846f4") // 1234 + val user5 = User( id = 5, username = "Gimli999", email = "gimli@example.com", date = "2022-07-04", imgUrl = "https://img.freepik.com/vecteurs-libre/personnage-nain-fantaisie_1045-189.jpg?size=338&ext=jpg", - password = "password123") + password = "03ac674216f3e15c761ee1a5e255f067953623c8b388b4459e13f978d7c846f4") // 1234 + val user6 = User( id = 6, username = "Galadriel321", email = "galadriel@example.com", date = "2021-11-30", imgUrl = "https://img.freepik.com/vecteurs-libre/personnage-elfe-femme-fantaisie_1045-190.jpg?size=338&ext=jpg", - password = "password123") + password = "03ac674216f3e15c761ee1a5e255f067953623c8b388b4459e13f978d7c846f4") // 1234 + val user7 = User( id = 7, username = "Boromir654", email = "boromir@example.com", date = "2023-06-22", imgUrl = "https://img.freepik.com/vecteurs-libre/personnage-guerrier-homme-fantaisie_1045-191.jpg?size=338&ext=jpg", - password = "password123") + password = "03ac674216f3e15c761ee1a5e255f067953623c8b388b4459e13f978d7c846f4") // 1234 + val user8 = User( id = 8, username = "Eowyn777", email = "eowyn@example.com", date = "2022-04-11", imgUrl = "https://img.freepik.com/vecteurs-libre/personnage-guerriere-femme-fantaisie_1045-192.jpg?size=338&ext=jpg", - password = "password123") + password = "03ac674216f3e15c761ee1a5e255f067953623c8b388b4459e13f978d7c846f4") // 1234 + val user9 = User( id = 9, username = "Saruman888", email = "saruman@example.com", date = "2021-08-15", imgUrl = "https://img.freepik.com/vecteurs-libre/personnage-magicien-malefique-fantaisie_1045-193.jpg?size=338&ext=jpg", - password = "password123") + password = "03ac674216f3e15c761ee1a5e255f067953623c8b388b4459e13f978d7c846f4") // 1234 + val user10 = User( id = 10, username = "Faramir222", email = "faramir@example.com", date = "2023-02-08", imgUrl = "https://img.freepik.com/vecteurs-libre/personnage-guerrier-homme-fantaisie_1045-194.jpg?size=338&ext=jpg", - password = "password123") + password = "03ac674216f3e15c761ee1a5e255f067953623c8b388b4459e13f978d7c846f4") // 1234 + + val user11 = User( + id = 10, + username = "testeur", + email = "testeur@example.com", + date = "2023-02-08", + imgUrl = "https://img.freepik.com/vecteurs-libre/personnage-guerrier-homme-fantaisie_1045-194.jpg?size=338&ext=jpg", + password = "03ac674216f3e15c761ee1a5e255f067953623c8b388b4459e13f978d7c846f4") // 1234 val allUsers: List = listOf( - user1, user2, user3, user4, user5, user6, user7, user8, user9, user10 + user1, user2, user3, user4, user5, user6, user7, user8, user9, user10, user11 ) } \ No newline at end of file diff --git a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/LoginPage.kt b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/LoginPage.kt index 9f94e86..fc883f4 100644 --- a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/LoginPage.kt +++ b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/LoginPage.kt @@ -2,6 +2,7 @@ package com.example.what_the_fantasy.ui.screens import android.os.Bundle import android.text.style.BackgroundColorSpan +import android.util.Log import androidx.activity.ComponentActivity import androidx.activity.compose.setContent import androidx.activity.enableEdgeToEdge @@ -51,6 +52,8 @@ import androidx.navigation.compose.composable import com.example.what_the_fantasy.R import com.example.what_the_fantasy.data.local.UserStub import com.example.what_the_fantasy.data.model.User +import org.mindrot.jbcrypt.BCrypt +import java.security.MessageDigest @Composable fun LoginPage(navController : NavController) { @@ -85,7 +88,6 @@ fun LoginPage(navController : NavController) { ConnexionButtonLogin(users,identifiant, passwd, R.string.ButtonLogin,18, Color.White, Color.Black,navController) Space(16) CreateAccountButton(R.string.ButtonCreateLogin,12, Color.White, navController) - } } } @@ -136,7 +138,7 @@ fun PassWdTextField(textpasswdResId : Int) : String{ IconButton(onClick = { passwordVisible = !passwordVisible }) { } }, - shape = RoundedCornerShape(16.dp) // 🔹 Bords arrondis + shape = RoundedCornerShape(16.dp) // Bords arrondis ) } return passwd; @@ -169,13 +171,26 @@ fun ConnexionButtonLogin(userStub : List, id : String, passwd : String, ti fun validLogin(identifiant : String, passwd : String, users : List, navController: NavController){ users.forEach { user -> - if (user.username == identifiant && user.password == passwd){ + val hashPassWd = hashPassword(passwd) + + if (user.username == identifiant && user.password == hashPassWd){ navController.navigate("profile") //navController.navigate(ProfilPage(navController)) } } } +fun hashPassword(password: String): String { + // Créer un objet MessageDigest pour SHA-256 + val digest = MessageDigest.getInstance("SHA-256") + + // Convertir le mot de passe 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 fun CreateAccountButton(titleResId : Int, size : Int, color : Color, navController: NavController){ diff --git a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/SignUpPage.kt b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/SignUpPage.kt index 7ed5121..5f87056 100644 --- a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/SignUpPage.kt +++ b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/SignUpPage.kt @@ -41,6 +41,7 @@ import androidx.compose.ui.unit.sp import androidx.navigation.NavController import com.example.what_the_fantasy.R import com.example.what_the_fantasy.ui.theme.What_The_FantasyTheme +import org.mindrot.jbcrypt.BCrypt @Composable fun SignUpPage(navController: NavController) { @@ -172,15 +173,7 @@ fun PassWdConfirmTextFieldSign(textpasswdResId : Int){ } } -//@Composable -//fun TitleSign(title : String, size : Int, color : Color){ -// Text( -// text = title, -// fontSize = size.sp, -// fontWeight = FontWeight.Bold, -// color = color -// ) -//} + @Composable fun ConnexionButtonSign(titleResId : Int, size : Int, colorButton : Color, colorText : Color){ diff --git a/What_The_Fantasy/gradle/libs.versions.toml b/What_The_Fantasy/gradle/libs.versions.toml index ae80aff..258393f 100644 --- a/What_The_Fantasy/gradle/libs.versions.toml +++ b/What_The_Fantasy/gradle/libs.versions.toml @@ -1,8 +1,8 @@ [versions] agp = "8.6.0" -bcrypt = "2.2.0" +bcrypt = "0.4" coilCompose = "2.2.1" -coilComposeVersion = "3.1.0" + kotlin = "1.9.0" coreKtx = "1.10.1" junit = "4.13.2" @@ -16,10 +16,9 @@ navigationCommonAndroid = "2.9.0-alpha05" [libraries] androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" } -bcrypt = { module = "de.nycode:bcrypt", version.ref = "bcrypt" } +bcrypt = { module = "org.mindrot:jbcrypt", version.ref = "bcrypt" } coil-compose = { module = "io.coil-kt:coil-compose", version.ref = "coilCompose" } -coil-network-okhttp = { module = "io.coil-kt.coil3:coil-network-okhttp", version.ref = "coilComposeVersion" } -coil3-coil-compose = { module = "io.coil-kt.coil3:coil-compose", version.ref = "coilComposeVersion" } + junit = { group = "junit", name = "junit", version.ref = "junit" } androidx-junit = { group = "androidx.test.ext", name = "junit", version.ref = "junitVersion" } androidx-espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espressoCore" } From f6ceb44e29b1b797c22d22343132e5ae938a8ce5 Mon Sep 17 00:00:00 2001 From: beaulaton Date: Mon, 17 Feb 2025 17:37:23 +0100 Subject: [PATCH 12/21] =?UTF-8?q?Mdp=20hach=C3=A9=20+=20cr=C3=A9ation=20co?= =?UTF-8?q?mponents?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../example/what_the_fantasy/MainActivity.kt | 17 +- .../ui/components/ErrorMessageComponent.kt | 22 + .../ui/components/SpaceComponent.kt | 15 + .../ui/components/TitleComponents.kt | 21 + .../what_the_fantasy/ui/screens/LoginPage.kt | 39 +- .../what_the_fantasy/ui/screens/ProfilPage.kt | 471 ++++++++++-------- .../what_the_fantasy/ui/screens/SignUpPage.kt | 17 +- 7 files changed, 355 insertions(+), 247 deletions(-) create mode 100644 What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/components/ErrorMessageComponent.kt create mode 100644 What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/components/SpaceComponent.kt create mode 100644 What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/components/TitleComponents.kt diff --git a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/MainActivity.kt b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/MainActivity.kt index f3676f0..1c0f0a5 100644 --- a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/MainActivity.kt +++ b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/MainActivity.kt @@ -11,6 +11,7 @@ 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.screens.AppNavigator import com.example.what_the_fantasy.ui.theme.What_The_FantasyTheme import com.example.what_the_fantasy.ui.screens.LoginPage @@ -23,14 +24,7 @@ class MainActivity : ComponentActivity() { enableEdgeToEdge() setContent { What_The_FantasyTheme { - Column { - Scaffold(modifier = Modifier.fillMaxSize()) { innerPadding -> - Title( - title = "What The Fantasy", - modifier = Modifier.padding(innerPadding) - ) - } - } + AppNavigator() // Accès à la page login et SingUp (pour le moment) //ProfilPage() //Accès à la page profil //QuizPage() @@ -39,11 +33,4 @@ class MainActivity : ComponentActivity() { } } -@Composable -fun Title(title: String, modifier: Modifier = Modifier) { - Text( - text = "Welcome to $title!", - modifier = modifier - ) -} diff --git a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/components/ErrorMessageComponent.kt b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/components/ErrorMessageComponent.kt new file mode 100644 index 0000000..6498a73 --- /dev/null +++ b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/components/ErrorMessageComponent.kt @@ -0,0 +1,22 @@ +package com.example.what_the_fantasy.ui.components + +import androidx.compose.foundation.layout.padding +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp + + +@Composable +fun ErrorMessageProfileComponent(titleResId : Int) { + val textError = stringResource(id = titleResId) + Text( + text = textError, + color = Color.Red, + fontSize = 12.sp, + modifier = Modifier.padding(top = 4.dp) + ) +} \ No newline at end of file diff --git a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/components/SpaceComponent.kt b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/components/SpaceComponent.kt new file mode 100644 index 0000000..d9a69d7 --- /dev/null +++ b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/components/SpaceComponent.kt @@ -0,0 +1,15 @@ +package com.example.what_the_fantasy.ui.components + +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.width +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.dp + +@Composable +fun SpaceHeightComponent(height : Int){ + Spacer( + modifier = Modifier + .height(height.dp)) // Ajoute un espacement +} \ No newline at end of file diff --git a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/components/TitleComponents.kt b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/components/TitleComponents.kt new file mode 100644 index 0000000..86aad8f --- /dev/null +++ b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/components/TitleComponents.kt @@ -0,0 +1,21 @@ +package com.example.what_the_fantasy.ui.components + +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.unit.sp + + + +@Composable +fun TitlePageComponent(titleResId : Int, size : Int, color : Color) { + val title = stringResource(id = titleResId) + Text( + text = title, + fontSize = size.sp, + fontWeight = FontWeight.Bold, + color = color + ) +} diff --git a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/LoginPage.kt b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/LoginPage.kt index fc883f4..78343ea 100644 --- a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/LoginPage.kt +++ b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/LoginPage.kt @@ -52,6 +52,8 @@ import androidx.navigation.compose.composable import com.example.what_the_fantasy.R 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.SpaceHeightComponent +import com.example.what_the_fantasy.ui.components.TitlePageComponent import org.mindrot.jbcrypt.BCrypt import java.security.MessageDigest @@ -81,23 +83,18 @@ fun LoginPage(navController : NavController) { horizontalAlignment = Alignment.CenterHorizontally ) { - TitlePage(R.string.titleLogin, 20,Color.White) + TitlePageComponent(R.string.titleLogin, 20,Color.White) val identifiant =IdentifiantTextField(R.string.IdentifiantLogin) val passwd = PassWdTextField(R.string.PasswdLogin) - Space(16) + SpaceHeightComponent(16) ConnexionButtonLogin(users,identifiant, passwd, R.string.ButtonLogin,18, Color.White, Color.Black,navController) - Space(16) + SpaceHeightComponent(16) CreateAccountButton(R.string.ButtonCreateLogin,12, Color.White, navController) } } } -@Composable -fun Space(height : Int){ - Spacer( - modifier = Modifier - .height(height.dp)) // Ajoute un espacement -} + @Composable @@ -144,16 +141,16 @@ fun PassWdTextField(textpasswdResId : Int) : String{ return passwd; } -@Composable -fun TitlePage(titleResId : Int, size : Int, color : Color){ - val title = stringResource(id = titleResId) - Text( - text = title, - fontSize = size.sp, - fontWeight = FontWeight.Bold, - color = color - ) -} +//@Composable +//fun TitlePage(titleResId : Int, size : Int, color : Color){ +// val title = stringResource(id = titleResId) +// Text( +// text = title, +// fontSize = size.sp, +// fontWeight = FontWeight.Bold, +// color = color +// ) +//} @Composable fun ConnexionButtonLogin(userStub : List, id : String, passwd : String, titleResId : Int, size : Int, colorButton : Color, colorText : Color, navController: NavController){ @@ -181,10 +178,10 @@ fun validLogin(identifiant : String, passwd : String, users : List, navCon } fun hashPassword(password: String): String { - // Créer un objet MessageDigest pour SHA-256 + // SHA-256 val digest = MessageDigest.getInstance("SHA-256") - // Convertir le mot de passe en bytes et appliquer le hash + // 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 diff --git a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/ProfilPage.kt b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/ProfilPage.kt index 7d07b7e..cdfbec9 100644 --- a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/ProfilPage.kt +++ b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/ProfilPage.kt @@ -61,6 +61,9 @@ import coil.compose.AsyncImage import com.example.what_the_fantasy.R import com.example.what_the_fantasy.data.local.QuestionStub import com.example.what_the_fantasy.data.local.UserStub +import com.example.what_the_fantasy.ui.components.ErrorMessageProfileComponent +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.theme.What_The_FantasyTheme @Composable @@ -90,28 +93,27 @@ fun ProfilPage(navController: NavController) { ) { // Titre - TitleProfil(R.string.titleProfile, 20, Color.White) - SpaceProfil(16) + TitlePageComponent(R.string.titleProfile, 20, Color.White) + SpaceHeightComponent(16) // Image de profil - //val id = R.drawable.ic_launcher_foreground ImageProfil(user[index].imgUrl, 120, 2, Color.White) - SpaceProfil(16) + SpaceHeightComponent(16) EditUsername(user[index].username)// Édition du Username - SpaceProfil(16) + SpaceHeightComponent(16) EditEmail(user[index].email)// Édition du Email Spacer(modifier = Modifier.height(8.dp)) EditPasswd() - SpaceProfil(16) + SpaceHeightComponent(16) // Bouton ButtonProfile(R.string.ButtonAddQuoteprofile,18, Color.Black, Color.White) - SpaceProfil(16) + SpaceHeightComponent(16) ButtonProfile(R.string.ButtonLanguageprofile,18, Color.Black, Color.White) - SpaceProfil(16) + SpaceHeightComponent(16) ButtonProfile(R.string.ButtonUnlogprofile, 18, Color.Black, Color.White) } @@ -119,24 +121,8 @@ fun ProfilPage(navController: NavController) { } -@Composable -fun SpaceProfil(height : Int){ - Spacer( - modifier = Modifier - .height(height.dp)) // Ajoute un espacement -} -@Composable -fun TitleProfil(titleResId : Int, size : Int, color : Color){ - val title = stringResource(id = titleResId) - Text( - text = title, - fontSize = size.sp, - fontWeight = FontWeight.Bold, - color = color - ) -} @Composable fun ImageProfil(imgProfil : String, size :Int, sizeBorber : Int, colorBorder : Color){ @@ -148,226 +134,309 @@ fun ImageProfil(imgProfil : String, size :Int, sizeBorber : Int, colorBorder : C .size(size.dp) .clip(CircleShape) ) - } @Composable -fun EditEmail(userEmail : String){ +fun EditEmail(userEmail: String) { var email by remember { mutableStateOf(userEmail) } - var isEditingEmail by remember { mutableStateOf(false) } // État d'édition + var isEditingEmail by remember { mutableStateOf(false) } var emailError by remember { mutableStateOf(false) } if (isEditingEmail) { - OutlinedTextField( - value = email, - onValueChange = { - email = it - emailError = !Patterns.EMAIL_ADDRESS.matcher(it).matches() + EmailEditingField( + email = email, + onEmailChange = { newEmail -> + email = newEmail + emailError = !Patterns.EMAIL_ADDRESS.matcher(newEmail).matches() }, - modifier = Modifier.fillMaxWidth(), - textStyle = TextStyle(color = Color.White, fontSize = 18.sp), - singleLine = true, - keyboardOptions = KeyboardOptions.Default.copy( - keyboardType = KeyboardType.Email, // ✅ Clavier spécialisé pour email - imeAction = ImeAction.Done - ), - keyboardActions = KeyboardActions( - onDone = { if (!emailError) isEditingEmail = false } // ✅ Fermer si l'email est valide - ), - trailingIcon = { - IconButton(onClick = { if (!emailError) isEditingEmail = false }) { - Icon(imageVector = Icons.Default.Check, contentDescription = "Valider") - } + onDone = { + if (!emailError) isEditingEmail = false }, - isError = emailError // ✅ Afficher l'erreur si l'email est invalide + emailError = emailError ) - if (emailError) { - val text = stringResource(id = R.string.ErrorEmailprofile) - Text( - text = text, - color = Color.Red, - fontSize = 12.sp, - modifier = Modifier.padding(top = 4.dp) - ) - } } else { - Row( - verticalAlignment = Alignment.CenterVertically, - modifier = Modifier.clickable { isEditingEmail = true } - ) { - Text( - text = email, - fontSize = 18.sp, - fontWeight = FontWeight.Bold, - color = Color.White - ) - Icon( - imageVector = Icons.Default.Edit, - contentDescription = "Modifier", - tint = Color.White, - modifier = Modifier.size(16.dp).padding(start = 8.dp) - ) - } + DisplayEmail(email = email, onEdit = { isEditingEmail = true }) + } +} + +@Composable +fun EmailEditingField( + email: String, + onEmailChange: (String) -> Unit, + onDone: () -> Unit, + emailError: Boolean +) { + OutlinedTextField( + value = email, + onValueChange = onEmailChange, + modifier = Modifier.fillMaxWidth(), + textStyle = TextStyle(color = Color.White, fontSize = 18.sp), + singleLine = true, + keyboardOptions = KeyboardOptions.Default.copy( + keyboardType = KeyboardType.Email, + imeAction = ImeAction.Done + ), + keyboardActions = KeyboardActions( + onDone = { onDone() } + ), + trailingIcon = { + IconButton(onClick = { if (!emailError) onDone() }) { + Icon(imageVector = Icons.Default.Check, contentDescription = "Valider") + } + }, + isError = emailError + ) + + if (emailError) { + ErrorMessageProfileComponent(R.string.ErrorEmailprofile) + } +} + + +@Composable +fun DisplayEmail(email: String, onEdit: () -> Unit) { + Row( + verticalAlignment = Alignment.CenterVertically, + modifier = Modifier.clickable { onEdit() } + ) { + Text( + text = email, + fontSize = 18.sp, + fontWeight = FontWeight.Bold, + color = Color.White + ) + Icon( + imageVector = Icons.Default.Edit, + contentDescription = "Modifier", + tint = Color.White, + modifier = Modifier.size(16.dp).padding(start = 8.dp) + ) } } + + + @Composable -fun EditUsername(userName : String){ +fun EditUsername(userName: String) { var username by remember { mutableStateOf(userName) } - var isEditingUsername by remember { mutableStateOf(false) } // État d'édition + var isEditingUsername by remember { mutableStateOf(false) } if (isEditingUsername) { - OutlinedTextField( - value = username, - onValueChange = { username = it }, - modifier = Modifier.fillMaxWidth(), - textStyle = TextStyle(color = Color.White, fontSize = 18.sp), - singleLine = true, - keyboardOptions = KeyboardOptions.Default.copy( - imeAction = ImeAction.Done - ), - keyboardActions = KeyboardActions( - onDone = { isEditingUsername = false } // Quand on appuie sur "Done" - ), - trailingIcon = { - IconButton(onClick = { isEditingUsername = false }) { - Icon(imageVector = Icons.Default.Check, contentDescription = "Valider") - } - } + UsernameEditingField( + username = username, + onUsernameChange = { username = it }, + onDone = { isEditingUsername = false } ) } else { - Row( - verticalAlignment = Alignment.CenterVertically, - modifier = Modifier.clickable { isEditingUsername = true } - ) { - Text( - text = username, - fontSize = 18.sp, - fontWeight = FontWeight.Bold, - color = Color.White - ) - Icon( - imageVector = Icons.Default.Edit, - contentDescription = "Modifier", - tint = Color.White, - modifier = Modifier.size(16.dp).padding(start = 8.dp) - ) + DisplayUsername(username = username, onEdit = { isEditingUsername = true }) + } +} + +@Composable +fun UsernameEditingField( + username: String, + onUsernameChange: (String) -> Unit, + onDone: () -> Unit +) { + OutlinedTextField( + value = username, + onValueChange = onUsernameChange, + modifier = Modifier.fillMaxWidth(), + textStyle = TextStyle(color = Color.White, fontSize = 18.sp), + singleLine = true, + keyboardOptions = KeyboardOptions.Default.copy( + imeAction = ImeAction.Done + ), + keyboardActions = KeyboardActions( + onDone = { onDone() } // Quand on appuie sur "Done", on met fin à l'édition + ), + trailingIcon = { + IconButton(onClick = { onDone() }) { + Icon(imageVector = Icons.Default.Check, contentDescription = "Valider") + } } + ) +} + +@Composable +fun DisplayUsername(username: String, onEdit: () -> Unit) { + Row( + verticalAlignment = Alignment.CenterVertically, + modifier = Modifier.clickable { onEdit() } + ) { + Text( + text = username, + fontSize = 18.sp, + fontWeight = FontWeight.Bold, + color = Color.White + ) + Icon( + imageVector = Icons.Default.Edit, + contentDescription = "Modifier", + tint = Color.White, + modifier = Modifier.size(16.dp).padding(start = 8.dp) + ) } } + + + + @Composable -fun EditPasswd(){ +fun EditPasswd() { var password by remember { mutableStateOf("*******") } var isEditingPassword by remember { mutableStateOf(false) } var newPassword by remember { mutableStateOf("") } var confirmPassword by remember { mutableStateOf("") } var passwordVisible by remember { mutableStateOf(false) } var passwordError by remember { mutableStateOf(false) } + if (isEditingPassword) { - Column { - val text = stringResource(id = R.string.NewPasswdprofile) - OutlinedTextField( - value = newPassword, - onValueChange = { newPassword = it }, - label = { Text(text) }, - modifier = Modifier.fillMaxWidth(), - textStyle = TextStyle(color = Color.White, fontSize = 18.sp), - singleLine = true, - keyboardOptions = KeyboardOptions.Default.copy( - keyboardType = KeyboardType.Password, - imeAction = ImeAction.Next - ), - visualTransformation = if (passwordVisible) VisualTransformation.None else PasswordVisualTransformation(), - trailingIcon = { - IconButton(onClick = { passwordVisible = !passwordVisible }) { - - } + PasswordEditingFields( + newPassword = newPassword, + confirmPassword = confirmPassword, + onNewPasswordChange = { newPassword = it }, + onConfirmPasswordChange = { + confirmPassword = it + passwordError = newPassword != it + }, + passwordVisible = passwordVisible, + onPasswordVisibilityChange = { passwordVisible = it }, + passwordError = passwordError, + onDone = { + if (!passwordError && newPassword.isNotEmpty()) { + password = newPassword + isEditingPassword = false } - ) - - Spacer(modifier = Modifier.height(8.dp)) - val textConfirm = stringResource(id = R.string.ConfirmNewPasswdprofile) - OutlinedTextField( - value = confirmPassword, - onValueChange = { - confirmPassword = it - passwordError = newPassword != it - }, - - label = { Text(textConfirm) }, - modifier = Modifier.fillMaxWidth(), - textStyle = TextStyle(color = Color.White, fontSize = 18.sp), - singleLine = true, - keyboardOptions = KeyboardOptions.Default.copy( - keyboardType = KeyboardType.Password, - imeAction = ImeAction.Done - ), - keyboardActions = KeyboardActions( - onDone = { if (!passwordError && newPassword.isNotEmpty()) { - password = newPassword - isEditingPassword = false - }} - ), - visualTransformation = if (passwordVisible) VisualTransformation.None else PasswordVisualTransformation(), - trailingIcon = { - IconButton(onClick = { passwordVisible = !passwordVisible }) { - - } - }, - isError = passwordError - ) - - if (passwordError) { - val text = stringResource(id = R.string.Errorpasswdprofile) - Text( - text = text, - color = Color.Red, - fontSize = 12.sp, - modifier = Modifier.padding(top = 4.dp) - ) } + ) + } else { + DisplayPassword(onEdit = { isEditingPassword = true }) + } +} - Spacer(modifier = Modifier.height(8.dp)) +@Composable +fun PasswordEditingFields( + newPassword: String, + confirmPassword: String, + onNewPasswordChange: (String) -> Unit, + onConfirmPasswordChange: (String) -> Unit, + passwordVisible: Boolean, + onPasswordVisibilityChange: (Boolean) -> Unit, + passwordError: Boolean, + onDone: () -> Unit +) { + Column { + val text = stringResource(id = R.string.NewPasswdprofile) + PasswordTextField( + value = newPassword, + onValueChange = onNewPasswordChange, + label = text, + passwordVisible = passwordVisible, + onPasswordVisibilityChange = onPasswordVisibilityChange + ) - Button( - onClick = { - if (!passwordError && newPassword.isNotEmpty()) { - password = newPassword - isEditingPassword = false - } - }, - colors = ButtonDefaults.buttonColors(containerColor = Color.White), - modifier = Modifier.fillMaxWidth() - ) { - val text = stringResource(id = R.string.ButtonSaveprofile) - Text(text, fontSize = 18.sp, color = Color.Black) - } - } - } else { - Row( - verticalAlignment = Alignment.CenterVertically, - modifier = Modifier.clickable { isEditingPassword = true } - ) { - Text( - text = password, - fontSize = 18.sp, - fontWeight = FontWeight.Bold, - color = Color.White - ) - Icon( - imageVector = Icons.Default.Edit, - contentDescription = "Modifier", - tint = Color.White, - modifier = Modifier.size(16.dp).padding(start = 8.dp) - ) + Spacer(modifier = Modifier.height(8.dp)) + + val textConfirm = stringResource(id = R.string.ConfirmNewPasswdprofile) + PasswordTextField( + value = confirmPassword, + onValueChange = onConfirmPasswordChange, + label = textConfirm, + passwordVisible = passwordVisible, + onPasswordVisibilityChange = onPasswordVisibilityChange, + isError = passwordError, + onDone = onDone + ) + + if (passwordError) { + ErrorMessageProfileComponent(R.string.Errorpasswdprofile) } + + Spacer(modifier = Modifier.height(8.dp)) + + SaveButton(onClick = onDone) } } +@Composable +fun PasswordTextField( + value: String, + onValueChange: (String) -> Unit, + label: String, + passwordVisible: Boolean, + onPasswordVisibilityChange: (Boolean) -> Unit, + isError: Boolean = false, + onDone: (() -> Unit)? = null +) { + OutlinedTextField( + value = value, + onValueChange = onValueChange, + label = { Text(label) }, + modifier = Modifier.fillMaxWidth(), + textStyle = TextStyle(color = Color.White, fontSize = 18.sp), + singleLine = true, + keyboardOptions = KeyboardOptions.Default.copy( + keyboardType = KeyboardType.Password, + imeAction = if (onDone != null) ImeAction.Done else ImeAction.Next + ), + keyboardActions = onDone?.let { + KeyboardActions(onDone = { it() }) + } ?: KeyboardActions.Default, + visualTransformation = if (passwordVisible) VisualTransformation.None else PasswordVisualTransformation(), + trailingIcon = { + IconButton(onClick = { onPasswordVisibilityChange(!passwordVisible) }) { + // Ajout d'une icône pour montrer/masquer le mot de passe + } + }, + isError = isError + ) +} + +@Composable +fun SaveButton(onClick: () -> Unit) { + Button( + onClick = onClick, + colors = ButtonDefaults.buttonColors(containerColor = Color.White), + modifier = Modifier.fillMaxWidth() + ) { + val text = stringResource(id = R.string.ButtonSaveprofile) + Text(text, + fontSize = 18.sp, + color = Color.Black) + } +} + +@Composable +fun DisplayPassword(onEdit: () -> Unit) { + Row( + verticalAlignment = Alignment.CenterVertically, + modifier = Modifier.clickable { onEdit() } + ) { + Text( + text = "*****", + fontSize = 18.sp, + fontWeight = FontWeight.Bold, + color = Color.White + ) + Icon( + imageVector = Icons.Default.Edit, + contentDescription = "Modifier", + tint = Color.White, + modifier = Modifier.size(16.dp).padding(start = 8.dp) + ) + } +} + + + + + @Composable fun ButtonProfile(textResId : Int, size :Int, colorTexte : Color, colorButton : Color){ diff --git a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/SignUpPage.kt b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/SignUpPage.kt index 5f87056..ef18e31 100644 --- a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/SignUpPage.kt +++ b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/SignUpPage.kt @@ -40,6 +40,8 @@ import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import androidx.navigation.NavController import com.example.what_the_fantasy.R +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.theme.What_The_FantasyTheme import org.mindrot.jbcrypt.BCrypt @@ -67,26 +69,21 @@ fun SignUpPage(navController: NavController) { horizontalAlignment = Alignment.CenterHorizontally ) { - TitlePage(R.string.titleSignUp, 20,Color.White) + TitlePageComponent(R.string.titleSignUp, 20,Color.White) IdentifiantTextFieldSign(R.string.IdentifiantLogin) EmailTextFieldSign("Email*") PassWdTextFieldSign(R.string.PasswdLogin) PassWdConfirmTextFieldSign(R.string.ConfirmPassWdSignUp) - SpaceSign(16) + SpaceHeightComponent(16) ConnexionButtonSign(R.string.ButtonSignUp,18, Color.White, Color.Black) - SpaceSign(16) + SpaceHeightComponent(16) CreateAccountButtonSign(R.string.ButtonLogin,12, Color.White, navController = navController) } } } -@Composable -fun SpaceSign(height : Int){ - Spacer( - modifier = Modifier - .height(height.dp)) // Ajoute un espacement -} + @Composable @@ -120,7 +117,7 @@ fun EmailTextFieldSign(textIdentifiant : String){ .fillMaxWidth() .padding(top = 8.dp), keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Email), - shape = RoundedCornerShape(16.dp) // 🔹 Bords arrondis + shape = RoundedCornerShape(16.dp) // Bords arrondis ) } } From 3a01eaa1b7aaeadc43a90eaa283502f0c863496c Mon Sep 17 00:00:00 2001 From: "louis.guichard-montguers" Date: Mon, 17 Feb 2025 20:03:40 +0100 Subject: [PATCH 13/21] ajoout QuizAccueil --- .../example/what_the_fantasy/MainActivity.kt | 6 +- .../ui/screens/QuizAccueil.kt | 136 ++++++++++++++++++ .../what_the_fantasy/ui/screens/QuizPage.kt | 21 ++- .../app/src/main/res/drawable/quiz.jpg | Bin 0 -> 13644 bytes 4 files changed, 161 insertions(+), 2 deletions(-) create mode 100644 What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/QuizAccueil.kt create mode 100644 What_The_Fantasy/app/src/main/res/drawable/quiz.jpg diff --git a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/MainActivity.kt b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/MainActivity.kt index 45b0771..cc76997 100644 --- a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/MainActivity.kt +++ b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/MainActivity.kt @@ -11,10 +11,13 @@ import androidx.compose.material3.Scaffold import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier +import androidx.navigation.compose.rememberNavController import com.example.what_the_fantasy.ui.screens.AppNavigator 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.QuizAccueil +import com.example.what_the_fantasy.ui.screens.QuizApp import com.example.what_the_fantasy.ui.screens.QuizPage class MainActivity : ComponentActivity() { @@ -31,9 +34,10 @@ class MainActivity : ComponentActivity() { ) } } + //AppNavigator() // Accès à la page login et SingUp (pour le moment) //ProfilPage() //Accès à la page profil - QuizPage() + QuizApp() } } } diff --git a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/QuizAccueil.kt b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/QuizAccueil.kt new file mode 100644 index 0000000..f9f7e9c --- /dev/null +++ b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/QuizAccueil.kt @@ -0,0 +1,136 @@ +package com.example.what_the_fantasy.ui.screens + +import androidx.compose.foundation.Image +import androidx.compose.foundation.background +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxHeight +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.width +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.layout.ContentScale +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.unit.dp +import androidx.navigation.NavController +import androidx.navigation.compose.NavHost +import androidx.navigation.compose.composable +import androidx.navigation.compose.rememberNavController +import com.example.what_the_fantasy.R + + +@Composable +fun QuizAccueil(navController: NavController) { + Row( + modifier = Modifier + .fillMaxSize() + .background(Color(0xFF100C1B)) + .padding(top = 100.dp) + ) { + Spacer(modifier = Modifier.weight(0.1f)) + + Column( + modifier = Modifier + .weight(0.9f) + .fillMaxHeight(), + horizontalAlignment = Alignment.CenterHorizontally + ) { + Box( + modifier = Modifier + .size(width = 150.dp, height = 100.dp) + .padding(8.dp) + .clickable { + navController.navigate("quizPage") + } + ) { + Image( + painter = painterResource(id = R.drawable.quiz), + contentDescription = "Quiz 1", + modifier = Modifier.fillMaxSize(), + contentScale = ContentScale.Crop + ) + } + + Box( + modifier = Modifier + .size(width = 150.dp, height = 100.dp) + .padding(8.dp) + .clickable { + + navController.navigate("quizPage") + } + ) { + Image( + painter = painterResource(id = R.drawable.quiz), + contentDescription = "Quiz 2", + modifier = Modifier.fillMaxSize(), + contentScale = ContentScale.Crop + ) + } + } + + Spacer(modifier = Modifier.width(10.dp)) + + Column( + modifier = Modifier + .weight(0.9f) + .fillMaxHeight(), + horizontalAlignment = Alignment.CenterHorizontally + ) { + Box( + modifier = Modifier + .size(width = 150.dp, height = 100.dp) + .padding(8.dp) + .clickable { + navController.navigate("quizPage") + } + ) { + Image( + painter = painterResource(id = R.drawable.quiz), + contentDescription = "Quiz 3", + modifier = Modifier.fillMaxSize(), + contentScale = ContentScale.Crop + ) + } + + Box( + modifier = Modifier + .size(width = 150.dp, height = 100.dp) + .padding(8.dp) + .clickable { + navController.navigate("quizPage") + } + ) { + Image( + painter = painterResource(id = R.drawable.quiz), + contentDescription = "Quiz 4", + modifier = Modifier.fillMaxSize(), + contentScale = ContentScale.Crop + ) + } + } + + Spacer(modifier = Modifier.weight(0.1f)) + } +} + +@Composable +fun QuizApp() { + val navController = rememberNavController() + + NavHost(navController = navController, startDestination = "quizAccueil") { + composable("quizAccueil") { + QuizAccueil(navController = navController) + } + composable("quizPage") { + QuizPage(navController = navController) + } + } +} \ No newline at end of file diff --git a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/QuizPage.kt b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/QuizPage.kt index 2970bd2..8eee9c3 100644 --- a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/QuizPage.kt +++ b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/QuizPage.kt @@ -14,9 +14,13 @@ import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.width import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.ArrowBack import androidx.compose.material3.Button import androidx.compose.material3.ButtonColors import androidx.compose.material3.ButtonDefaults +import androidx.compose.material3.Icon +import androidx.compose.material3.IconButton import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue @@ -31,6 +35,7 @@ import androidx.compose.ui.graphics.Brush import androidx.compose.ui.graphics.Color import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp +import androidx.navigation.NavController import com.example.what_the_fantasy.data.local.QuestionStub import com.example.what_the_fantasy.data.model.Question @@ -39,7 +44,7 @@ val questions = QuestionStub.allQuestions var pts = 0 @Composable -fun QuizPage() { +fun QuizPage(navController: NavController) { var idCurrentQuestion by remember { mutableIntStateOf(0) } fun goNext(correctAns: String, ans: String) { if (correctAns == "A") { @@ -68,6 +73,20 @@ fun QuizPage() { .background(Color(0xFF100C1B)) // Fond global de l'écran .padding(16.dp) // Marges autour de tout le contenu ) { + IconButton( + onClick = { + navController.popBackStack() // Revenir à la page précédente (QuizAccueil) + }, + modifier = Modifier + .align(Alignment.TopStart) + ) { + Icon( + imageVector = Icons.Default.ArrowBack, // Flèche de retour + contentDescription = "Retour", + tint = Color.White + ) + } + // Numéro de la question en haut Text( text = "Question numéro : " + questions[idCurrentQuestion].id.toString(), diff --git a/What_The_Fantasy/app/src/main/res/drawable/quiz.jpg b/What_The_Fantasy/app/src/main/res/drawable/quiz.jpg new file mode 100644 index 0000000000000000000000000000000000000000..d0bcef9fef19346165fa1fc927c32b73f58f5e7c GIT binary patch literal 13644 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 Date: Tue, 18 Feb 2025 11:09:21 +0100 Subject: [PATCH 14/21] Update QuizPage code --- .../example/what_the_fantasy/MainActivity.kt | 6 - .../what_the_fantasy/ui/screens/QuizPage.kt | 182 ++++++------------ 2 files changed, 62 insertions(+), 126 deletions(-) diff --git a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/MainActivity.kt b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/MainActivity.kt index cc76997..691ac43 100644 --- a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/MainActivity.kt +++ b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/MainActivity.kt @@ -11,14 +11,8 @@ import androidx.compose.material3.Scaffold import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier -import androidx.navigation.compose.rememberNavController -import com.example.what_the_fantasy.ui.screens.AppNavigator 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.QuizAccueil import com.example.what_the_fantasy.ui.screens.QuizApp -import com.example.what_the_fantasy.ui.screens.QuizPage class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { diff --git a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/QuizPage.kt b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/QuizPage.kt index 8eee9c3..4317669 100644 --- a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/QuizPage.kt +++ b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/QuizPage.kt @@ -1,33 +1,16 @@ package com.example.what_the_fantasy.ui.screens -import android.util.Log import androidx.compose.foundation.background import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.Spacer -import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.height -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.width +import androidx.compose.foundation.layout.* import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.automirrored.filled.ArrowBack import androidx.compose.material.icons.filled.ArrowBack -import androidx.compose.material3.Button -import androidx.compose.material3.ButtonColors -import androidx.compose.material3.ButtonDefaults import androidx.compose.material3.Icon import androidx.compose.material3.IconButton import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableIntStateOf -import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.remember -import androidx.compose.runtime.setValue +import androidx.compose.runtime.* import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.geometry.Offset @@ -37,124 +20,83 @@ import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import androidx.navigation.NavController import com.example.what_the_fantasy.data.local.QuestionStub -import com.example.what_the_fantasy.data.model.Question - - -val questions = QuestionStub.allQuestions -var pts = 0 @Composable fun QuizPage(navController: NavController) { + val questions = QuestionStub.allQuestions var idCurrentQuestion by remember { mutableIntStateOf(0) } - fun goNext(correctAns: String, ans: String) { - if (correctAns == "A") { - if (questions[idCurrentQuestion].ansA == ans) pts += 1 - } - if (correctAns == "B") { - if (questions[idCurrentQuestion].ansB == ans) pts += 1 - } - if (correctAns == "C") { - if (questions[idCurrentQuestion].ansC == ans) pts += 1 - } - if (correctAns == "D") { - if (questions[idCurrentQuestion].ansD == ans) pts += 1 - } - if (idCurrentQuestion < questions.size) idCurrentQuestion += 1 - } + var pts by remember { mutableIntStateOf(0) } + val gradient = Brush.linearGradient( - colors = listOf(Color(0xFF7B1FA2), Color(0xFF311B92)), // Violet clair → Violet foncé - start = Offset(0f, 1000f), // Départ en bas à gauche - end = Offset(1000f, 0f) // Fin en haut à droite + colors = listOf(Color(0xFF7B1FA2), Color(0xFF311B92)), + start = Offset(0f, 1000f), + end = Offset(1000f, 0f) ) + fun onAnswerSelected(answer: String) { + val currentQuestion = questions[idCurrentQuestion] + val correctAnswer = mapOf( + "A" to currentQuestion.ansA, + "B" to currentQuestion.ansB, + "C" to currentQuestion.ansC, + "D" to currentQuestion.ansD + )[currentQuestion.correctAns] + + if (answer == correctAnswer) pts++ + if (idCurrentQuestion < questions.size - 1) idCurrentQuestion++ + else navController.popBackStack() // Retour menu + } + Box( modifier = Modifier .fillMaxSize() - .background(Color(0xFF100C1B)) // Fond global de l'écran - .padding(16.dp) // Marges autour de tout le contenu + .background(Color(0xFF100C1B)) + .padding(16.dp) ) { - IconButton( - onClick = { - navController.popBackStack() // Revenir à la page précédente (QuizAccueil) - }, - modifier = Modifier - .align(Alignment.TopStart) - ) { - Icon( - imageVector = Icons.Default.ArrowBack, // Flèche de retour - contentDescription = "Retour", - tint = Color.White - ) - } - - // Numéro de la question en haut - Text( - text = "Question numéro : " + questions[idCurrentQuestion].id.toString(), - color = Color.White, - fontSize = 18.sp, // Taille réduite pour tenir sur un écran portrait - modifier = Modifier - .align(Alignment.TopCenter) // Position en haut au centre - .padding(top = 16.dp) // Un peu d'espace en haut - ) - Text( - text = "Nombre de points : " + pts.toString(), - color = Color.White, - fontSize = 18.sp, // Taille réduite pour tenir sur un écran portrait - modifier = Modifier - .align(Alignment.TopCenter) // Position en haut au centre - .padding(top = 50.dp) // Un peu d'espace en haut - ) - - // Contenu centré, mais avec une gestion plus équilibrée du placement Column( modifier = Modifier - .fillMaxSize() - .padding(top = 48.dp), // Réduit l'espace entre le numéro de la question et la question elle-même - verticalArrangement = Arrangement.Center, // Centre verticalement - horizontalAlignment = Alignment.CenterHorizontally // Centre horizontalement + .fillMaxSize(), + horizontalAlignment = Alignment.CenterHorizontally ) { - // Question principale - Text( - text = questions[idCurrentQuestion].question, - color = Color.White, - fontSize = 22.sp, // Taille plus petite pour tenir sur un écran portrait - modifier = Modifier.padding(bottom = 16.dp) // Réduit l'espacement entre la question et les réponses - ) - - // Liste des réponses - val answers = listOf( - questions[idCurrentQuestion].ansA, - questions[idCurrentQuestion].ansB, - questions[idCurrentQuestion].ansC, - questions[idCurrentQuestion].ansD, - - ) + val question = questions[idCurrentQuestion] - // Pour chaque réponse, on applique une Box avec un espacement uniforme - - answers.forEach { answer -> + Column ( + horizontalAlignment = Alignment.CenterHorizontally, + ) { Box( - modifier = Modifier - .width(220.dp) // Largeur plus petite pour que ça tienne mieux - .height(50.dp) // Hauteur ajustée - .background( - brush = gradient, - shape = RoundedCornerShape(16.dp) // Coins arrondis - ) - .clickable { goNext(questions[idCurrentQuestion].correctAns, answer) } - .padding(horizontal = 8.dp), // Padding interne - contentAlignment = Alignment.Center + modifier = Modifier.fillMaxWidth() ) { - Text( - text = answer, - color = Color.White, - fontSize = 18.sp // Taille du texte ajustée pour un écran portrait - ) + IconButton( + onClick = { navController.popBackStack() }, + modifier = Modifier.align(Alignment.TopStart) + ) { + Icon(Icons.AutoMirrored.Filled.ArrowBack, contentDescription = "Retour", tint = Color.White) + } + } + Text("Question ${question.id}", color = Color.White, fontSize = 18.sp, modifier = Modifier.padding(top = 20.dp)) + Text("Points : $pts", color = Color.White, fontSize = 18.sp, modifier = Modifier.padding(top = 40.dp)) + Text(question.question, color = Color.White, fontSize = 22.sp, modifier = Modifier.padding(40.dp)) + } + Column ( + modifier = Modifier + .padding(top = 30.dp) + ) { + listOf(question.ansA, question.ansB, question.ansC, question.ansD).forEach { answer -> + Box( + modifier = Modifier + .width(220.dp) + .height(50.dp) + .background(brush = gradient, shape = RoundedCornerShape(16.dp)) + .clickable { onAnswerSelected(answer) } + .padding(horizontal = 8.dp), + contentAlignment = Alignment.Center + ) { + Text(answer, color = Color.White, fontSize = 18.sp) + } + Spacer(modifier = Modifier.height(60.dp)) } - Spacer(modifier = Modifier.height(16.dp)) // Espacement réduit entre les réponses } + } } -} - - +} \ No newline at end of file From 2c4f97175d801b92a490d6be3bbe6582db1d1efe Mon Sep 17 00:00:00 2001 From: "leni.beaulaton" Date: Tue, 18 Feb 2025 17:53:50 +0100 Subject: [PATCH 15/21] Navigation pour l'application --- What_The_Fantasy/app/build.gradle.kts | 1 + .../example/what_the_fantasy/MainActivity.kt | 2 +- .../ui/navigations/AppNavigator.kt | 37 ++++++++++++ .../what_the_fantasy/ui/screens/LoginPage.kt | 56 +++---------------- .../what_the_fantasy/ui/screens/SignUpPage.kt | 1 - What_The_Fantasy/build.gradle.kts | 2 +- 6 files changed, 49 insertions(+), 50 deletions(-) create mode 100644 What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/navigations/AppNavigator.kt diff --git a/What_The_Fantasy/app/build.gradle.kts b/What_The_Fantasy/app/build.gradle.kts index 5c11806..4b7e70e 100644 --- a/What_The_Fantasy/app/build.gradle.kts +++ b/What_The_Fantasy/app/build.gradle.kts @@ -69,5 +69,6 @@ dependencies { debugImplementation(libs.androidx.ui.tooling) debugImplementation(libs.androidx.ui.test.manifest) implementation(libs.coil.compose) //gére les url des image + implementation(kotlin("script-runtime")) } \ No newline at end of file diff --git a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/MainActivity.kt b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/MainActivity.kt index 1c0f0a5..07f86de 100644 --- a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/MainActivity.kt +++ b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/MainActivity.kt @@ -12,7 +12,7 @@ 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.screens.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.screens.LoginPage import com.example.what_the_fantasy.ui.screens.ProfilPage diff --git a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/navigations/AppNavigator.kt b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/navigations/AppNavigator.kt new file mode 100644 index 0000000..fbdac89 --- /dev/null +++ b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/navigations/AppNavigator.kt @@ -0,0 +1,37 @@ +package com.example.what_the_fantasy.ui.navigations + +import androidx.compose.runtime.Composable +import androidx.navigation.compose.NavHost +import androidx.navigation.compose.composable +import androidx.navigation.compose.rememberNavController +import com.example.what_the_fantasy.ui.screens.AccueilPage +import com.example.what_the_fantasy.ui.screens.FavoritePage +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 +import com.example.what_the_fantasy.ui.screens.QuotePage +import com.example.what_the_fantasy.ui.screens.SearchPage +import com.example.what_the_fantasy.ui.screens.SignUpPage +import com.example.what_the_fantasy.ui.screens.SubmitQuotePage + + + +@Composable +fun AppNavigator() { + val navController = rememberNavController() + NavHost(navController, startDestination = "Login") { + composable("Login") { LoginPage( + navControllerSignUp = { navController.navigate("SignUp") }, + navControllerProfil = { navController.navigate("Profil") } // A changer pour mettre l'Accueil quand elle sera faite + )} + composable("Accueil") { AccueilPage() } + composable("Favorite") { FavoritePage() } + composable("Profil") { ProfilPage(navController) } + composable("Quiz") { QuizPage() } + composable("Quote") { QuotePage() } + composable("Search") { SearchPage() } + composable("SignUp") { SignUpPage(navController)} + composable("SubmitQuote") { SubmitQuotePage() } + } + +} \ No newline at end of file diff --git a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/LoginPage.kt b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/LoginPage.kt index 78343ea..6cbc262 100644 --- a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/LoginPage.kt +++ b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/LoginPage.kt @@ -1,30 +1,19 @@ package com.example.what_the_fantasy.ui.screens -import android.os.Bundle -import android.text.style.BackgroundColorSpan -import android.util.Log -import androidx.activity.ComponentActivity -import androidx.activity.compose.setContent -import androidx.activity.enableEdgeToEdge import androidx.compose.foundation.background import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.text.KeyboardOptions -import androidx.compose.material.icons.Icons import androidx.compose.material3.Button import androidx.compose.material3.ButtonDefaults -import androidx.compose.material3.Icon import androidx.compose.material3.IconButton import androidx.compose.material3.OutlinedTextField import androidx.compose.material3.Text -import androidx.compose.material3.TextField import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf @@ -37,15 +26,12 @@ import androidx.compose.ui.geometry.Offset import androidx.compose.ui.graphics.Brush import androidx.compose.ui.graphics.Color import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.input.KeyboardType import androidx.compose.ui.text.input.PasswordVisualTransformation import androidx.compose.ui.text.input.VisualTransformation import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp -import com.example.what_the_fantasy.ui.theme.What_The_FantasyTheme import androidx.navigation.NavController -import androidx.navigation.Navigation import androidx.navigation.compose.rememberNavController import androidx.navigation.compose.NavHost import androidx.navigation.compose.composable @@ -54,11 +40,10 @@ 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.SpaceHeightComponent import com.example.what_the_fantasy.ui.components.TitlePageComponent -import org.mindrot.jbcrypt.BCrypt import java.security.MessageDigest @Composable -fun LoginPage(navController : NavController) { +fun LoginPage(navControllerSignUp: () -> Unit, navControllerProfil: () -> Unit) { val users = UserStub.allUsers; val gradient = Brush.linearGradient( @@ -87,9 +72,9 @@ fun LoginPage(navController : NavController) { val identifiant =IdentifiantTextField(R.string.IdentifiantLogin) val passwd = PassWdTextField(R.string.PasswdLogin) SpaceHeightComponent(16) - ConnexionButtonLogin(users,identifiant, passwd, R.string.ButtonLogin,18, Color.White, Color.Black,navController) + ConnexionButtonLogin(users,identifiant, passwd, R.string.ButtonLogin,18, Color.White, Color.Black,navControllerProfil) SpaceHeightComponent(16) - CreateAccountButton(R.string.ButtonCreateLogin,12, Color.White, navController) + CreateAccountButton(R.string.ButtonCreateLogin,12, Color.White, navControllerSignUp) } } } @@ -141,19 +126,9 @@ fun PassWdTextField(textpasswdResId : Int) : String{ return passwd; } -//@Composable -//fun TitlePage(titleResId : Int, size : Int, color : Color){ -// val title = stringResource(id = titleResId) -// Text( -// text = title, -// fontSize = size.sp, -// fontWeight = FontWeight.Bold, -// color = color -// ) -//} @Composable -fun ConnexionButtonLogin(userStub : List, id : String, passwd : String, titleResId : Int, size : Int, colorButton : Color, colorText : Color, navController: NavController){ +fun ConnexionButtonLogin(userStub : List, id : String, passwd : String, titleResId : Int, size : Int, colorButton : Color, colorText : Color, navController: () -> Unit){ val title = stringResource(id = titleResId) Button( onClick = { validLogin(id, passwd, userStub, navController) }, @@ -166,13 +141,12 @@ fun ConnexionButtonLogin(userStub : List, id : String, passwd : String, ti } -fun validLogin(identifiant : String, passwd : String, users : List, navController: NavController){ +fun validLogin(identifiant : String, passwd : String, users : List, navController: () -> Unit){ users.forEach { user -> val hashPassWd = hashPassword(passwd) - if (user.username == identifiant && user.password == hashPassWd){ - navController.navigate("profile") - //navController.navigate(ProfilPage(navController)) + if (user.username == identifiant && user.password == hashPassWd) run { + navController() } } } @@ -190,26 +164,14 @@ fun hashPassword(password: String): String { @Composable -fun CreateAccountButton(titleResId : Int, size : Int, color : Color, navController: NavController){ +fun CreateAccountButton(titleResId : Int, size : Int, color : Color, navController: () -> Unit){ val title = stringResource(id = titleResId) Text( text = title, fontSize = size.sp, color = color, modifier = Modifier.clickable { - navController.navigate("signup")// rediriger vers la page de création de compte + navController()// rediriger vers la page de création de compte } ) } - -@Composable -fun AppNavigator() { - val navController = rememberNavController() - - NavHost(navController, startDestination = "login") { - composable("login") { LoginPage(navController) } - composable("signup") { SignUpPage(navController) } - composable("profile") { ProfilPage(navController) } - } - -} \ No newline at end of file diff --git a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/SignUpPage.kt b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/SignUpPage.kt index ef18e31..3394b60 100644 --- a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/SignUpPage.kt +++ b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/SignUpPage.kt @@ -43,7 +43,6 @@ import com.example.what_the_fantasy.R 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.theme.What_The_FantasyTheme -import org.mindrot.jbcrypt.BCrypt @Composable fun SignUpPage(navController: NavController) { diff --git a/What_The_Fantasy/build.gradle.kts b/What_The_Fantasy/build.gradle.kts index 922f551..7f09f7c 100644 --- a/What_The_Fantasy/build.gradle.kts +++ b/What_The_Fantasy/build.gradle.kts @@ -2,4 +2,4 @@ plugins { alias(libs.plugins.android.application) apply false alias(libs.plugins.kotlin.android) apply false -} \ No newline at end of file +} From 46958143494edca018fcbac89e84abba317b34a9 Mon Sep 17 00:00:00 2001 From: "leni.beaulaton" Date: Tue, 18 Feb 2025 18:03:41 +0100 Subject: [PATCH 16/21] Color --- .../example/what_the_fantasy/MainActivity.kt | 3 +-- .../what_the_fantasy/ui/screens/LoginPage.kt | 20 +++++++++---------- .../what_the_fantasy/ui/screens/SignUpPage.kt | 20 +++++++++---------- .../what_the_fantasy/ui/theme/Color.kt | 10 +++++++++- 4 files changed, 28 insertions(+), 25 deletions(-) diff --git a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/MainActivity.kt b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/MainActivity.kt index 07f86de..2d893b5 100644 --- a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/MainActivity.kt +++ b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/MainActivity.kt @@ -25,8 +25,7 @@ class MainActivity : ComponentActivity() { setContent { What_The_FantasyTheme { - AppNavigator() // Accès à la page login et SingUp (pour le moment) - //ProfilPage() //Accès à la page profil + AppNavigator() //QuizPage() } } diff --git a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/LoginPage.kt b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/LoginPage.kt index 6cbc262..f6e1023 100644 --- a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/LoginPage.kt +++ b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/LoginPage.kt @@ -40,31 +40,29 @@ 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.SpaceHeightComponent import com.example.what_the_fantasy.ui.components.TitlePageComponent +import com.example.what_the_fantasy.ui.theme.colorBackground +import com.example.what_the_fantasy.ui.theme.gradienBox import java.security.MessageDigest @Composable fun LoginPage(navControllerSignUp: () -> Unit, navControllerProfil: () -> Unit) { val users = UserStub.allUsers; - val gradient = Brush.linearGradient( - colors = listOf(Color(0xFF7B1FA2), Color(0xFF311B92)), // Violet clair → Violet foncé - start = Offset(0f, 1000f), // Départ en bas à gauche - end = Offset(1000f, 0f) // Fin en haut à droite - ) + Box( modifier = Modifier .fillMaxSize() - .background(Color(0xFF100C1B)), + .background(colorBackground), contentAlignment = Alignment.Center ){ Column( modifier = Modifier - .fillMaxWidth(0.9f) // Ajuste la largeur - .padding(20.dp) // Marge extérieure - .clip(RoundedCornerShape(16.dp)) // Arrondi les angles - .background(gradient) // Ajoute un fond blanc - .padding(20.dp), // Padding interne + .fillMaxWidth(0.9f) + .padding(20.dp) + .clip(RoundedCornerShape(16.dp)) + .background(gradienBox) + .padding(20.dp), horizontalAlignment = Alignment.CenterHorizontally ) { diff --git a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/SignUpPage.kt b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/SignUpPage.kt index 3394b60..3e77782 100644 --- a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/SignUpPage.kt +++ b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/SignUpPage.kt @@ -43,28 +43,26 @@ import com.example.what_the_fantasy.R 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.theme.What_The_FantasyTheme +import com.example.what_the_fantasy.ui.theme.colorBackground +import com.example.what_the_fantasy.ui.theme.gradienBox @Composable fun SignUpPage(navController: NavController) { - val gradient = Brush.linearGradient( - colors = listOf(Color(0xFF7B1FA2), Color(0xFF311B92)), // Violet clair → Violet foncé - start = Offset(0f, 1000f), // Départ en bas à gauche - end = Offset(1000f, 0f) // Fin en haut à droite - ) + Box( modifier = Modifier .fillMaxSize() - .background(Color(0xFF100C1B)), + .background(colorBackground), contentAlignment = Alignment.Center ){ Column( modifier = Modifier - .fillMaxWidth(0.9f) // Ajuste la largeur - .padding(20.dp) // Marge extérieure - .clip(RoundedCornerShape(16.dp)) // Arrondi les angles - .background(gradient) // Ajoute un fond blanc - .padding(20.dp), // Padding interne + .fillMaxWidth(0.9f) + .padding(20.dp) + .clip(RoundedCornerShape(16.dp)) + .background(gradienBox) + .padding(20.dp), horizontalAlignment = Alignment.CenterHorizontally ) { diff --git a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/theme/Color.kt b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/theme/Color.kt index 02f6d8b..41c8deb 100644 --- a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/theme/Color.kt +++ b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/theme/Color.kt @@ -1,5 +1,7 @@ package com.example.what_the_fantasy.ui.theme +import androidx.compose.ui.geometry.Offset +import androidx.compose.ui.graphics.Brush import androidx.compose.ui.graphics.Color val Purple80 = Color(0xFFD0BCFF) @@ -8,4 +10,10 @@ val Pink80 = Color(0xFFEFB8C8) val Purple40 = Color(0xFF6650a4) val PurpleGrey40 = Color(0xFF625b71) -val Pink40 = Color(0xFF7D5260) \ No newline at end of file +val Pink40 = Color(0xFF7D5260) +val gradienBox = Brush.linearGradient( + colors = listOf(Color(0xFF7B1FA2), Color(0xFF311B92)), // Violet clair → Violet foncé + start = Offset(0f, 1000f), // Départ en bas à gauche + end = Offset(1000f, 0f) // Fin en haut à droite +) +val colorBackground = Color(0xFF100C1B) \ No newline at end of file From bfe8bf5b9df2cd424ee1b20b3bfed4547d052b4f Mon Sep 17 00:00:00 2001 From: tomivt Date: Wed, 19 Feb 2025 09:13:54 +0100 Subject: [PATCH 17/21] WIP : Create QuizEnd View --- .../example/what_the_fantasy/MainActivity.kt | 6 +- .../ui/screens/QuizAccueil.kt | 5 +- .../ui/screens/QuizEndPage.kt | 218 ++++++++++++++++++ 3 files changed, 225 insertions(+), 4 deletions(-) create mode 100644 What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/QuizEndPage.kt diff --git a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/MainActivity.kt b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/MainActivity.kt index 691ac43..3ba2662 100644 --- a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/MainActivity.kt +++ b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/MainActivity.kt @@ -20,17 +20,17 @@ class MainActivity : ComponentActivity() { enableEdgeToEdge() setContent { What_The_FantasyTheme { - Column { + /*Column { Scaffold(modifier = Modifier.fillMaxSize()) { innerPadding -> Title( title = "What The Fantasy", modifier = Modifier.padding(innerPadding) ) } - } + }*/ //AppNavigator() // Accès à la page login et SingUp (pour le moment) - //ProfilPage() //Accès à la page profil + //ProfilPage() //Accès à la page profil QuizApp() } } diff --git a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/QuizAccueil.kt b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/QuizAccueil.kt index f9f7e9c..b237afd 100644 --- a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/QuizAccueil.kt +++ b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/QuizAccueil.kt @@ -125,12 +125,15 @@ fun QuizAccueil(navController: NavController) { fun QuizApp() { val navController = rememberNavController() - NavHost(navController = navController, startDestination = "quizAccueil") { + NavHost(navController = navController, startDestination = "quizEndPage") { composable("quizAccueil") { QuizAccueil(navController = navController) } composable("quizPage") { QuizPage(navController = navController) } + composable("quizEndPage") { + QuizEndPage(5, 1) + } } } \ No newline at end of file diff --git a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/QuizEndPage.kt b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/QuizEndPage.kt new file mode 100644 index 0000000..9fdf003 --- /dev/null +++ b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/QuizEndPage.kt @@ -0,0 +1,218 @@ +package com.example.what_the_fantasy.ui.screens + +import android.widget.ImageButton +import androidx.compose.foundation.Image +import androidx.compose.foundation.background +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxHeight +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.shape.CircleShape +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.automirrored.filled.ArrowBack +import androidx.compose.material3.Icon +import androidx.compose.material3.IconButton +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.mutableDoubleStateOf +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.geometry.Offset +import androidx.compose.ui.graphics.Brush +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import com.example.what_the_fantasy.R + +val gradient = Brush.linearGradient( + colors = listOf(Color(0xFF7B1FA2), Color(0xFF311B92)), + start = Offset(0f, 1000f), + end = Offset(1000f, 0f) +) + +@Composable +fun QuizEndPage(points : Int, idQuiz : Int) { + Column ( + modifier = Modifier + .fillMaxSize() + .background(Color(0xFF100C1B)) + ) { + // Bandeau ( Bouton Retour / Bouton Profil / Dark-Light Mode ) + Row ( + modifier = Modifier + .background(Color(0xFF300052)) + .height(100.dp) + .fillMaxWidth() + .padding(20.dp) + ) { + Row ( + modifier = Modifier + .fillMaxSize() + ) { + Row ( + modifier = Modifier + .fillMaxWidth() + .clickable { }, + horizontalArrangement = Arrangement.SpaceBetween + ) { + Box { + IconButton( + onClick = { }, + modifier = Modifier + .align(Alignment.TopStart) + .fillMaxHeight() + ) { + Icon( + Icons.AutoMirrored.Filled.ArrowBack, + contentDescription = "Retour", + tint = Color.White) + } + } + Box ( + modifier = Modifier + .background(Color.Yellow, shape = CircleShape), + contentAlignment = Alignment.Center + ) { + Image ( + // Image transparente + painter = painterResource(id = R.drawable.quiz), + contentDescription = "Back Button" + ) + } + Box ( + modifier = Modifier + .background(Color.Yellow, shape = CircleShape), + contentAlignment = Alignment.Center + ) { + Image ( + // Image transparente + painter = painterResource(id = R.drawable.quiz), + contentDescription = "Back Button" + ) + } + } + } + } + + // Titre de la page + Box( + modifier = Modifier + .fillMaxWidth() + .height(100.dp) + .background(Color.Red), + contentAlignment = Alignment.Center + ) { + Text ( + text = "▶ Résultats ◀", + color = Color.White, + style = TextStyle( + fontSize = 25.sp, + fontWeight = FontWeight.Bold, + textAlign = TextAlign.Center + ), + modifier = Modifier.fillMaxWidth() + ) + } + + // Résultat du quiz + Column ( + modifier = Modifier + .padding(50.dp) + ) { + Column ( + modifier = Modifier + .background(brush = gradient, shape = RoundedCornerShape(20.dp)) + .fillMaxHeight() + .padding(30.dp) + ) { + Box ( + modifier = Modifier + .fillMaxWidth() + .height(50.dp), + contentAlignment = Alignment.Center + ) { + Text ( + text = "Quiz N°${idQuiz.toString()}", + color = Color.White, + style = TextStyle( + fontSize = 25.sp, + fontWeight = FontWeight.Bold, + textAlign = TextAlign.Center + ), + modifier = Modifier.fillMaxWidth() + ) + } + } + } + + // Bandeau ( Bouton Likes / Bouton Menu / Bouton Quiz ) + Row ( + modifier = Modifier + .background(Color(0xFF300052)) + .height(100.dp) + .fillMaxWidth() + .padding(20.dp) + ) { + Row ( + modifier = Modifier + .fillMaxSize() + ) { + Row ( + modifier = Modifier + .fillMaxWidth() + .clickable { }, + horizontalArrangement = Arrangement.SpaceBetween + ) { + Box ( + modifier = Modifier + .background(Color.Yellow, shape = CircleShape), + contentAlignment = Alignment.Center + ) { + Image ( + // Image transparente + painter = painterResource(id = R.drawable.quiz), + contentDescription = "Back Button" + ) + } + Box ( + modifier = Modifier + .background(Color.Yellow, shape = CircleShape), + contentAlignment = Alignment.Center + ) { + Image ( + // Image transparente + painter = painterResource(id = R.drawable.quiz), + contentDescription = "Back Button" + ) + } + Box ( + modifier = Modifier + .background(Color.Yellow, shape = CircleShape), + contentAlignment = Alignment.Center + ) { + Image ( + // Image transparente + painter = painterResource(id = R.drawable.quiz), + contentDescription = "Back Button" + ) + } + } + } + } + } +} + From 140be5e8f4cdd7e74e20941c10f6251dbf2dca54 Mon Sep 17 00:00:00 2001 From: tomivt Date: Wed, 19 Feb 2025 17:02:06 +0100 Subject: [PATCH 18/21] Finish QuizEnd View --- .../ui/screens/QuizEndPage.kt | 257 +++++++----------- 1 file changed, 101 insertions(+), 156 deletions(-) diff --git a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/QuizEndPage.kt b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/QuizEndPage.kt index 9fdf003..359e7f7 100644 --- a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/QuizEndPage.kt +++ b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/QuizEndPage.kt @@ -1,30 +1,16 @@ package com.example.what_the_fantasy.ui.screens -import android.widget.ImageButton import androidx.compose.foundation.Image import androidx.compose.foundation.background -import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.fillMaxHeight -import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.height -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.size -import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.layout.* import androidx.compose.foundation.shape.CircleShape import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.icons.Icons import androidx.compose.material.icons.automirrored.filled.ArrowBack import androidx.compose.material3.Icon import androidx.compose.material3.IconButton -import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable -import androidx.compose.runtime.mutableDoubleStateOf import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.geometry.Offset @@ -37,6 +23,7 @@ import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import com.example.what_the_fantasy.R +import com.example.what_the_fantasy.data.local.QuestionStub val gradient = Brush.linearGradient( colors = listOf(Color(0xFF7B1FA2), Color(0xFF311B92)), @@ -44,175 +31,133 @@ val gradient = Brush.linearGradient( end = Offset(1000f, 0f) ) + + @Composable -fun QuizEndPage(points : Int, idQuiz : Int) { - Column ( - modifier = Modifier - .fillMaxSize() - .background(Color(0xFF100C1B)) +fun QuizEndPage(points: Int, idQuiz: Int) { + Column( + modifier = Modifier.fillMaxSize().background(Color(0xFF100C1B)) ) { - // Bandeau ( Bouton Retour / Bouton Profil / Dark-Light Mode ) - Row ( + // Bandeau supérieur + Row( modifier = Modifier - .background(Color(0xFF300052)) - .height(100.dp) .fillMaxWidth() - .padding(20.dp) + .weight(0.1f) + .background(Color(0xFF300052)) + .padding(20.dp), + horizontalArrangement = Arrangement.SpaceBetween, + verticalAlignment = Alignment.CenterVertically ) { - Row ( - modifier = Modifier - .fillMaxSize() - ) { - Row ( - modifier = Modifier - .fillMaxWidth() - .clickable { }, - horizontalArrangement = Arrangement.SpaceBetween - ) { - Box { - IconButton( - onClick = { }, - modifier = Modifier - .align(Alignment.TopStart) - .fillMaxHeight() - ) { - Icon( - Icons.AutoMirrored.Filled.ArrowBack, - contentDescription = "Retour", - tint = Color.White) - } - } - Box ( - modifier = Modifier - .background(Color.Yellow, shape = CircleShape), - contentAlignment = Alignment.Center - ) { - Image ( - // Image transparente - painter = painterResource(id = R.drawable.quiz), - contentDescription = "Back Button" - ) - } - Box ( - modifier = Modifier - .background(Color.Yellow, shape = CircleShape), - contentAlignment = Alignment.Center - ) { - Image ( - // Image transparente - painter = painterResource(id = R.drawable.quiz), - contentDescription = "Back Button" - ) - } - } + IconButton(onClick = { }) { + Icon(Icons.AutoMirrored.Filled.ArrowBack, contentDescription = "Retour", tint = Color.White) } + Image( + painter = painterResource(id = R.drawable.quiz), + contentDescription = "Profil", + modifier = Modifier.size(50.dp).background(Color.Yellow, CircleShape) + ) + Image( + painter = painterResource(id = R.drawable.quiz), + contentDescription = "Profil", + modifier = Modifier.size(50.dp).background(Color.Yellow, CircleShape) + ) } - // Titre de la page - Box( + // Contenu principal + Column( modifier = Modifier - .fillMaxWidth() - .height(100.dp) - .background(Color.Red), - contentAlignment = Alignment.Center + .weight(0.8f) + .padding(horizontal = 50.dp, vertical = 20.dp) + .fillMaxWidth(), + horizontalAlignment = Alignment.CenterHorizontally ) { - Text ( + Text( text = "▶ Résultats ◀", color = Color.White, - style = TextStyle( - fontSize = 25.sp, - fontWeight = FontWeight.Bold, - textAlign = TextAlign.Center - ), - modifier = Modifier.fillMaxWidth() + style = TextStyle(fontSize = 25.sp, fontWeight = FontWeight.Bold, textAlign = TextAlign.Center) ) - } - - // Résultat du quiz - Column ( - modifier = Modifier - .padding(50.dp) - ) { + Spacer(modifier = Modifier.height(16.dp)) Column ( modifier = Modifier .background(brush = gradient, shape = RoundedCornerShape(20.dp)) - .fillMaxHeight() .padding(30.dp) + .fillMaxSize(), + horizontalAlignment = Alignment.CenterHorizontally ) { - Box ( + Text ( + text = "Quiz N°$idQuiz", + color = Color.White, + style = TextStyle(fontSize = 25.sp, fontWeight = FontWeight.Bold, textAlign = TextAlign.Center) + ) + + val nbQuestions = QuestionStub.allQuestions.size + + Text ( + text = "Nombres de Questions : $nbQuestions", + color = Color.White, + style = TextStyle(fontSize = 15.sp, fontWeight = FontWeight.Bold, textAlign = TextAlign.Center) + ) + Text ( + text = "Nombres de bonnes réponses : $points", + color = Color.White, + style = TextStyle(fontSize = 15.sp, fontWeight = FontWeight.Bold, textAlign = TextAlign.Center) + ) + Row ( modifier = Modifier - .fillMaxWidth() - .height(50.dp), - contentAlignment = Alignment.Center + .fillMaxWidth(), + horizontalArrangement = Arrangement.SpaceAround ) { - Text ( - text = "Quiz N°${idQuiz.toString()}", - color = Color.White, - style = TextStyle( - fontSize = 25.sp, - fontWeight = FontWeight.Bold, - textAlign = TextAlign.Center - ), - modifier = Modifier.fillMaxWidth() + // Bouton Quiz Précédent + Image( + painter = painterResource(id = R.drawable.quiz), + contentDescription = "Profil", + modifier = Modifier.size(50.dp).background(Color.Yellow, CircleShape) + ) + // Bouton Retour Menu Quiz + Image( + painter = painterResource(id = R.drawable.quiz), + contentDescription = "Profil", + modifier = Modifier.size(50.dp).background(Color.Yellow, CircleShape) + ) + // Bouton Quiz Suivant + Image( + painter = painterResource(id = R.drawable.quiz), + contentDescription = "Profil", + modifier = Modifier.size(50.dp).background(Color.Yellow, CircleShape) ) } + } } - // Bandeau ( Bouton Likes / Bouton Menu / Bouton Quiz ) - Row ( + // Bandeau inférieur + Row( modifier = Modifier - .background(Color(0xFF300052)) - .height(100.dp) .fillMaxWidth() - .padding(20.dp) + .weight(0.1f) + .background(Color(0xFF300052)) + .padding(20.dp), + horizontalArrangement = Arrangement.SpaceAround, + verticalAlignment = Alignment.CenterVertically ) { - Row ( - modifier = Modifier - .fillMaxSize() - ) { - Row ( - modifier = Modifier - .fillMaxWidth() - .clickable { }, - horizontalArrangement = Arrangement.SpaceBetween - ) { - Box ( - modifier = Modifier - .background(Color.Yellow, shape = CircleShape), - contentAlignment = Alignment.Center - ) { - Image ( - // Image transparente - painter = painterResource(id = R.drawable.quiz), - contentDescription = "Back Button" - ) - } - Box ( - modifier = Modifier - .background(Color.Yellow, shape = CircleShape), - contentAlignment = Alignment.Center - ) { - Image ( - // Image transparente - painter = painterResource(id = R.drawable.quiz), - contentDescription = "Back Button" - ) - } - Box ( - modifier = Modifier - .background(Color.Yellow, shape = CircleShape), - contentAlignment = Alignment.Center - ) { - Image ( - // Image transparente - painter = painterResource(id = R.drawable.quiz), - contentDescription = "Back Button" - ) - } - } - } + // Bouton Likes + Image( + painter = painterResource(id = R.drawable.quiz), + contentDescription = "Bouton", + modifier = Modifier.size(50.dp).background(Color.Yellow, CircleShape) + ) + // Bouton WhatTheFantasy + Image( + painter = painterResource(id = R.drawable.quiz), + contentDescription = "Bouton", + modifier = Modifier.size(50.dp).background(Color.Yellow, CircleShape) + ) + // Bouton Quiz + Image( + painter = painterResource(id = R.drawable.quiz), + contentDescription = "Bouton", + modifier = Modifier.size(50.dp).background(Color.Yellow, CircleShape) + ) } } } - From 39f3ccdcc255af931fb391380ac29faae34d2e47 Mon Sep 17 00:00:00 2001 From: beaulaton Date: Thu, 20 Feb 2025 14:19:52 +0100 Subject: [PATCH 19/21] Navigation refaite --- .../what_the_fantasy/data/local/UserStub.kt | 2 +- .../ui/navigations/AppNavigator.kt | 44 ++++++++++++------- 2 files changed, 30 insertions(+), 16 deletions(-) diff --git a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/data/local/UserStub.kt b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/data/local/UserStub.kt index 5bc2351..552ad3e 100644 --- a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/data/local/UserStub.kt +++ b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/data/local/UserStub.kt @@ -85,7 +85,7 @@ object UserStub { val user11 = User( id = 10, - username = "testeur", + username = "dev", email = "testeur@example.com", date = "2023-02-08", imgUrl = "https://img.freepik.com/vecteurs-libre/personnage-guerrier-homme-fantaisie_1045-194.jpg?size=338&ext=jpg", diff --git a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/navigations/AppNavigator.kt b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/navigations/AppNavigator.kt index fbdac89..fc05703 100644 --- a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/navigations/AppNavigator.kt +++ b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/navigations/AppNavigator.kt @@ -16,22 +16,36 @@ import com.example.what_the_fantasy.ui.screens.SubmitQuotePage +sealed class Destination(val route: String) { + data object Login : Destination("Login") + data object Accueil : Destination("Accueil") + data object Favorite : Destination("Favorite") + data object Profil : Destination("Profil") + data object Quiz : Destination("Quiz") + data object Quote : Destination("Quote") + data object Search : Destination("Search") + data object SignUp : Destination("SignUp") + data object SubmitQuote : Destination("SubmitQuote") +} + @Composable fun AppNavigator() { val navController = rememberNavController() - NavHost(navController, startDestination = "Login") { - composable("Login") { LoginPage( - navControllerSignUp = { navController.navigate("SignUp") }, - navControllerProfil = { navController.navigate("Profil") } // A changer pour mettre l'Accueil quand elle sera faite - )} - composable("Accueil") { AccueilPage() } - composable("Favorite") { FavoritePage() } - composable("Profil") { ProfilPage(navController) } - composable("Quiz") { QuizPage() } - composable("Quote") { QuotePage() } - composable("Search") { SearchPage() } - composable("SignUp") { SignUpPage(navController)} - composable("SubmitQuote") { SubmitQuotePage() } - } -} \ No newline at end of file + NavHost(navController, startDestination = Destination.Login.route) { + composable(Destination.Login.route) { + LoginPage( + navControllerSignUp = { navController.navigate(Destination.SignUp.route) }, + navControllerProfil = { navController.navigate(Destination.Profil.route) } + ) + } + composable(Destination.Accueil.route) { AccueilPage() } + composable(Destination.Favorite.route) { FavoritePage() } + composable(Destination.Profil.route) { ProfilPage(navController) } + composable(Destination.Quiz.route) { QuizPage() } + composable(Destination.Quote.route) { QuotePage() } + composable(Destination.Search.route) { SearchPage() } + composable(Destination.SignUp.route) { SignUpPage(navController) } + composable(Destination.SubmitQuote.route) { SubmitQuotePage() } + } +} From 829d85e9b22d0597824fe86b84cf84446397d116 Mon Sep 17 00:00:00 2001 From: beaulaton Date: Thu, 20 Feb 2025 15:20:45 +0100 Subject: [PATCH 20/21] Lien entre Login et Profil --- .../ui/navigations/AppNavigator.kt | 15 ++++++++++++--- .../what_the_fantasy/ui/screens/LoginPage.kt | 15 ++++++++------- .../what_the_fantasy/ui/screens/ProfilPage.kt | 8 ++------ 3 files changed, 22 insertions(+), 16 deletions(-) diff --git a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/navigations/AppNavigator.kt b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/navigations/AppNavigator.kt index fc05703..d155f2a 100644 --- a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/navigations/AppNavigator.kt +++ b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/navigations/AppNavigator.kt @@ -20,7 +20,9 @@ sealed class Destination(val route: String) { data object Login : Destination("Login") data object Accueil : Destination("Accueil") data object Favorite : Destination("Favorite") - data object Profil : Destination("Profil") + data object Profil : Destination("Profil/{userIndex}") { // Ajout du paramètre userIndex + fun createRoute(userIndex: Int) = "Profil/$userIndex" // Fonction pour créer la route avec l'index + } data object Quiz : Destination("Quiz") data object Quote : Destination("Quote") data object Search : Destination("Search") @@ -36,12 +38,18 @@ fun AppNavigator() { composable(Destination.Login.route) { LoginPage( navControllerSignUp = { navController.navigate(Destination.SignUp.route) }, - navControllerProfil = { navController.navigate(Destination.Profil.route) } + navControllerProfil = { userIndex -> + navController.navigate(Destination.Profil.createRoute(userIndex)) // Passe l'index à Profil + } ) } composable(Destination.Accueil.route) { AccueilPage() } composable(Destination.Favorite.route) { FavoritePage() } - composable(Destination.Profil.route) { ProfilPage(navController) } + composable(Destination.Profil.route) { backStackEntry -> + // Récupère l'index passé dans la route + val userIndex = backStackEntry.arguments?.getString("userIndex")?.toInt() ?: -1 + ProfilPage(index = userIndex, navController = navController) + } composable(Destination.Quiz.route) { QuizPage() } composable(Destination.Quote.route) { QuotePage() } composable(Destination.Search.route) { SearchPage() } @@ -49,3 +57,4 @@ fun AppNavigator() { composable(Destination.SubmitQuote.route) { SubmitQuotePage() } } } + diff --git a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/LoginPage.kt b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/LoginPage.kt index f6e1023..d5d3fd7 100644 --- a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/LoginPage.kt +++ b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/LoginPage.kt @@ -1,5 +1,6 @@ package com.example.what_the_fantasy.ui.screens +import android.util.Log import androidx.compose.foundation.background import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Box @@ -45,7 +46,7 @@ import com.example.what_the_fantasy.ui.theme.gradienBox import java.security.MessageDigest @Composable -fun LoginPage(navControllerSignUp: () -> Unit, navControllerProfil: () -> Unit) { +fun LoginPage(navControllerSignUp: () -> Unit, navControllerProfil: (Int) -> Unit) { val users = UserStub.allUsers; @@ -126,7 +127,7 @@ fun PassWdTextField(textpasswdResId : Int) : String{ @Composable -fun ConnexionButtonLogin(userStub : List, id : String, passwd : String, titleResId : Int, size : Int, colorButton : Color, colorText : Color, navController: () -> Unit){ +fun ConnexionButtonLogin(userStub : List, id : String, passwd : String, titleResId : Int, size : Int, colorButton : Color, colorText : Color, navController: (Int) -> Unit){ val title = stringResource(id = titleResId) Button( onClick = { validLogin(id, passwd, userStub, navController) }, @@ -139,12 +140,12 @@ fun ConnexionButtonLogin(userStub : List, id : String, passwd : String, ti } -fun validLogin(identifiant : String, passwd : String, users : List, navController: () -> Unit){ - users.forEach { user -> +fun validLogin(identifiant : String, passwd : String, users : List, navController: (Int) -> Unit){ + users.forEachIndexed { index, user -> val hashPassWd = hashPassword(passwd) - - if (user.username == identifiant && user.password == hashPassWd) run { - navController() + if (user.username == identifiant && user.password == hashPassWd) { + // Utilise l'index pour naviguer à la position correspondante + navController(index) // Passer l'index à la fonction navController } } } diff --git a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/ProfilPage.kt b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/ProfilPage.kt index cdfbec9..c2c0702 100644 --- a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/ProfilPage.kt +++ b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/ProfilPage.kt @@ -67,14 +67,14 @@ import com.example.what_the_fantasy.ui.components.TitlePageComponent import com.example.what_the_fantasy.ui.theme.What_The_FantasyTheme @Composable -fun ProfilPage(navController: NavController) { +fun ProfilPage(index: Int, navController: NavController) { val gradient = Brush.linearGradient( colors = listOf(Color(0xFF7B1FA2), Color(0xFF311B92)), // Violet clair → Violet foncé start = Offset(0f, 1000f), // Départ en bas à gauche end = Offset(1000f, 0f) // Fin en haut à droite ) val user = UserStub.allUsers - val index = 2 // Pour changer l'utilisateur pour le moment + //val index = 2 // Pour changer l'utilisateur pour le moment Box( modifier = Modifier @@ -121,9 +121,6 @@ fun ProfilPage(navController: NavController) { } - - - @Composable fun ImageProfil(imgProfil : String, size :Int, sizeBorber : Int, colorBorder : Color){ @@ -136,7 +133,6 @@ fun ImageProfil(imgProfil : String, size :Int, sizeBorber : Int, colorBorder : C ) } - @Composable fun EditEmail(userEmail: String) { var email by remember { mutableStateOf(userEmail) } From 4fb791519e8a7e9f521e117faa7ae556a38e1352 Mon Sep 17 00:00:00 2001 From: beaulaton Date: Thu, 20 Feb 2025 15:24:02 +0100 Subject: [PATCH 21/21] =?UTF-8?q?pb=20r=C3=A9gl=C3=A9=20sur=20la=20QuizPag?= =?UTF-8?q?e?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/example/what_the_fantasy/ui/navigations/AppNavigator.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/navigations/AppNavigator.kt b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/navigations/AppNavigator.kt index d155f2a..d7c38e5 100644 --- a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/navigations/AppNavigator.kt +++ b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/navigations/AppNavigator.kt @@ -50,7 +50,7 @@ fun AppNavigator() { val userIndex = backStackEntry.arguments?.getString("userIndex")?.toInt() ?: -1 ProfilPage(index = userIndex, navController = navController) } - composable(Destination.Quiz.route) { QuizPage() } + composable(Destination.Quiz.route) { QuizPage(navController) } composable(Destination.Quote.route) { QuotePage() } composable(Destination.Search.route) { SearchPage() } composable(Destination.SignUp.route) { SignUpPage(navController) }