commit
ec4b03649d
@ -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)
|
||||
)
|
||||
}
|
@ -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
|
||||
}
|
@ -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
|
||||
)
|
||||
}
|
@ -0,0 +1,60 @@
|
||||
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
|
||||
|
||||
|
||||
|
||||
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/{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")
|
||||
data object SignUp : Destination("SignUp")
|
||||
data object SubmitQuote : Destination("SubmitQuote")
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun AppNavigator() {
|
||||
val navController = rememberNavController()
|
||||
|
||||
NavHost(navController, startDestination = Destination.Login.route) {
|
||||
composable(Destination.Login.route) {
|
||||
LoginPage(
|
||||
navControllerSignUp = { navController.navigate(Destination.SignUp.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) { 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(navController) }
|
||||
composable(Destination.Quote.route) { QuotePage() }
|
||||
composable(Destination.Search.route) { SearchPage() }
|
||||
composable(Destination.SignUp.route) { SignUpPage(navController) }
|
||||
composable(Destination.SubmitQuote.route) { SubmitQuotePage() }
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,176 @@
|
||||
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
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
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.res.stringResource
|
||||
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 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
|
||||
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() {
|
||||
}
|
||||
fun LoginPage(navControllerSignUp: () -> Unit, navControllerProfil: (Int) -> Unit) {
|
||||
|
||||
val users = UserStub.allUsers;
|
||||
|
||||
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.background(colorBackground),
|
||||
contentAlignment = Alignment.Center
|
||||
){
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth(0.9f)
|
||||
.padding(20.dp)
|
||||
.clip(RoundedCornerShape(16.dp))
|
||||
.background(gradienBox)
|
||||
.padding(20.dp),
|
||||
horizontalAlignment = Alignment.CenterHorizontally
|
||||
) {
|
||||
|
||||
TitlePageComponent(R.string.titleLogin, 20,Color.White)
|
||||
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,navControllerProfil)
|
||||
SpaceHeightComponent(16)
|
||||
CreateAccountButton(R.string.ButtonCreateLogin,12, Color.White, navControllerSignUp)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@Composable
|
||||
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)) {
|
||||
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
|
||||
)
|
||||
}
|
||||
return identifiant;
|
||||
}
|
||||
|
||||
@Composable
|
||||
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
|
||||
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
|
||||
)
|
||||
}
|
||||
return passwd;
|
||||
}
|
||||
|
||||
|
||||
@Composable
|
||||
fun ConnexionButtonLogin(userStub : List<User>, 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) },
|
||||
colors = ButtonDefaults.buttonColors(containerColor = colorButton),
|
||||
modifier = Modifier
|
||||
.fillMaxWidth(),
|
||||
) {
|
||||
Text(title, fontSize = size.sp, color = colorText)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fun validLogin(identifiant : String, passwd : String, users : List<User>, navController: (Int) -> Unit){
|
||||
users.forEachIndexed { index, user ->
|
||||
val hashPassWd = hashPassword(passwd)
|
||||
if (user.username == identifiant && user.password == hashPassWd) {
|
||||
// Utilise l'index pour naviguer à la position correspondante
|
||||
navController(index) // Passer l'index à la fonction navController
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun hashPassword(password: String): String {
|
||||
// SHA-256
|
||||
val digest = MessageDigest.getInstance("SHA-256")
|
||||
|
||||
// Convertir mdp en bytes et appliquer le hash
|
||||
val hashedBytes = digest.digest(password.toByteArray())
|
||||
|
||||
// Convertir le tableau de bytes en une chaîne hexadécimale
|
||||
return hashedBytes.joinToString("") { "%02x".format(it) }
|
||||
}
|
||||
|
||||
|
||||
@Composable
|
||||
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()// rediriger vers la page de création de compte
|
||||
}
|
||||
)
|
||||
}
|
||||
|
@ -1,6 +1,447 @@
|
||||
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
|
||||
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.res.stringResource
|
||||
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 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
|
||||
fun ProfilPage() {}
|
||||
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
|
||||
|
||||
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
|
||||
TitlePageComponent(R.string.titleProfile, 20, Color.White)
|
||||
SpaceHeightComponent(16)
|
||||
|
||||
// Image de profil
|
||||
ImageProfil(user[index].imgUrl, 120, 2, Color.White)
|
||||
SpaceHeightComponent(16)
|
||||
|
||||
EditUsername(user[index].username)// Édition du Username
|
||||
SpaceHeightComponent(16)
|
||||
|
||||
EditEmail(user[index].email)// Édition du Email
|
||||
Spacer(modifier = Modifier.height(8.dp))
|
||||
|
||||
EditPasswd()
|
||||
SpaceHeightComponent(16)
|
||||
|
||||
// Bouton
|
||||
ButtonProfile(R.string.ButtonAddQuoteprofile,18, Color.Black, Color.White)
|
||||
SpaceHeightComponent(16)
|
||||
ButtonProfile(R.string.ButtonLanguageprofile,18, Color.Black, Color.White)
|
||||
SpaceHeightComponent(16)
|
||||
ButtonProfile(R.string.ButtonUnlogprofile, 18, Color.Black, Color.White)
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Composable
|
||||
fun ImageProfil(imgProfil : String, size :Int, sizeBorber : Int, colorBorder : Color){
|
||||
|
||||
AsyncImage(
|
||||
model = imgProfil,
|
||||
contentDescription = "Photo de profil",
|
||||
modifier = Modifier
|
||||
.size(size.dp)
|
||||
.clip(CircleShape)
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun EditEmail(userEmail: String) {
|
||||
var email by remember { mutableStateOf(userEmail) }
|
||||
var isEditingEmail by remember { mutableStateOf(false) }
|
||||
var emailError by remember { mutableStateOf(false) }
|
||||
|
||||
if (isEditingEmail) {
|
||||
EmailEditingField(
|
||||
email = email,
|
||||
onEmailChange = { newEmail ->
|
||||
email = newEmail
|
||||
emailError = !Patterns.EMAIL_ADDRESS.matcher(newEmail).matches()
|
||||
},
|
||||
onDone = {
|
||||
if (!emailError) isEditingEmail = false
|
||||
},
|
||||
emailError = emailError
|
||||
)
|
||||
} else {
|
||||
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) {
|
||||
var username by remember { mutableStateOf(userName) }
|
||||
var isEditingUsername by remember { mutableStateOf(false) }
|
||||
|
||||
if (isEditingUsername) {
|
||||
UsernameEditingField(
|
||||
username = username,
|
||||
onUsernameChange = { username = it },
|
||||
onDone = { isEditingUsername = false }
|
||||
)
|
||||
} else {
|
||||
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() {
|
||||
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) {
|
||||
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
|
||||
}
|
||||
}
|
||||
)
|
||||
} else {
|
||||
DisplayPassword(onEdit = { isEditingPassword = true })
|
||||
}
|
||||
}
|
||||
|
||||
@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
|
||||
)
|
||||
|
||||
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){
|
||||
val text = stringResource(id = textResId)
|
||||
Button(
|
||||
onClick = { /* Action */ },
|
||||
colors = ButtonDefaults.buttonColors(containerColor = colorButton),
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
) {
|
||||
Text(text, fontSize = size.sp, color = colorTexte)
|
||||
}
|
||||
}
|
@ -0,0 +1,139 @@
|
||||
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 = "quizEndPage") {
|
||||
composable("quizAccueil") {
|
||||
QuizAccueil(navController = navController)
|
||||
}
|
||||
composable("quizPage") {
|
||||
QuizPage(navController = navController)
|
||||
}
|
||||
composable("quizEndPage") {
|
||||
QuizEndPage(5, 1)
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,163 @@
|
||||
package com.example.what_the_fantasy.ui.screens
|
||||
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.background
|
||||
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.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.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
|
||||
import com.example.what_the_fantasy.data.local.QuestionStub
|
||||
|
||||
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 supérieur
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.weight(0.1f)
|
||||
.background(Color(0xFF300052))
|
||||
.padding(20.dp),
|
||||
horizontalArrangement = Arrangement.SpaceBetween,
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
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)
|
||||
)
|
||||
}
|
||||
|
||||
// Contenu principal
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.weight(0.8f)
|
||||
.padding(horizontal = 50.dp, vertical = 20.dp)
|
||||
.fillMaxWidth(),
|
||||
horizontalAlignment = Alignment.CenterHorizontally
|
||||
) {
|
||||
Text(
|
||||
text = "▶ Résultats ◀",
|
||||
color = Color.White,
|
||||
style = TextStyle(fontSize = 25.sp, fontWeight = FontWeight.Bold, textAlign = TextAlign.Center)
|
||||
)
|
||||
Spacer(modifier = Modifier.height(16.dp))
|
||||
Column (
|
||||
modifier = Modifier
|
||||
.background(brush = gradient, shape = RoundedCornerShape(20.dp))
|
||||
.padding(30.dp)
|
||||
.fillMaxSize(),
|
||||
horizontalAlignment = Alignment.CenterHorizontally
|
||||
) {
|
||||
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(),
|
||||
horizontalArrangement = Arrangement.SpaceAround
|
||||
) {
|
||||
// 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 inférieur
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.weight(0.1f)
|
||||
.background(Color(0xFF300052))
|
||||
.padding(20.dp),
|
||||
horizontalArrangement = Arrangement.SpaceAround,
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
// Bouton Likes
|
||||
Image(
|
||||
painter = painterResource(id = R.drawable.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)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
@ -1,6 +1,102 @@
|
||||
package com.example.what_the_fantasy.ui.screens
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.clickable
|
||||
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.Icon
|
||||
import androidx.compose.material3.IconButton
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.*
|
||||
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 androidx.navigation.NavController
|
||||
import com.example.what_the_fantasy.data.local.QuestionStub
|
||||
|
||||
@Composable
|
||||
fun QuizPage() {}
|
||||
fun QuizPage(navController: NavController) {
|
||||
val questions = QuestionStub.allQuestions
|
||||
var idCurrentQuestion by remember { mutableIntStateOf(0) }
|
||||
var pts by remember { mutableIntStateOf(0) }
|
||||
|
||||
val gradient = Brush.linearGradient(
|
||||
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))
|
||||
.padding(16.dp)
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxSize(),
|
||||
horizontalAlignment = Alignment.CenterHorizontally
|
||||
) {
|
||||
val question = questions[idCurrentQuestion]
|
||||
|
||||
Column (
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
) {
|
||||
Box(
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
) {
|
||||
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))
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
@ -1,6 +1,196 @@
|
||||
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.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 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 com.example.what_the_fantasy.ui.theme.colorBackground
|
||||
import com.example.what_the_fantasy.ui.theme.gradienBox
|
||||
|
||||
@Composable
|
||||
fun SignUpPage() {}
|
||||
fun SignUpPage(navController: NavController) {
|
||||
|
||||
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.background(colorBackground),
|
||||
contentAlignment = Alignment.Center
|
||||
){
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth(0.9f)
|
||||
.padding(20.dp)
|
||||
.clip(RoundedCornerShape(16.dp))
|
||||
.background(gradienBox)
|
||||
.padding(20.dp),
|
||||
horizontalAlignment = Alignment.CenterHorizontally
|
||||
) {
|
||||
|
||||
TitlePageComponent(R.string.titleSignUp, 20,Color.White)
|
||||
IdentifiantTextFieldSign(R.string.IdentifiantLogin)
|
||||
EmailTextFieldSign("Email*")
|
||||
PassWdTextFieldSign(R.string.PasswdLogin)
|
||||
PassWdConfirmTextFieldSign(R.string.ConfirmPassWdSignUp)
|
||||
SpaceHeightComponent(16)
|
||||
ConnexionButtonSign(R.string.ButtonSignUp,18, Color.White, Color.Black)
|
||||
SpaceHeightComponent(16)
|
||||
CreateAccountButtonSign(R.string.ButtonLogin,12, Color.White, navController = navController)
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@Composable
|
||||
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,
|
||||
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(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)) {
|
||||
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(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)) {
|
||||
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 ConnexionButtonSign(titleResId : Int, size : Int, colorButton : Color, colorText : Color){
|
||||
val title = stringResource(id = titleResId)
|
||||
Button(
|
||||
onClick = { /* Action */ },
|
||||
colors = ButtonDefaults.buttonColors(containerColor = colorButton),
|
||||
modifier = Modifier
|
||||
.fillMaxWidth(),
|
||||
) {
|
||||
Text(title, fontSize = size.sp, color = colorText)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun CreateAccountButtonSign(titleResId: Int, size: Int, color: Color, navController: NavController) {
|
||||
val title = stringResource(id = titleResId)
|
||||
Text(
|
||||
text = title,
|
||||
fontSize = size.sp,
|
||||
color = color,
|
||||
modifier = Modifier.clickable {
|
||||
navController.popBackStack() // Revenir à la page précédente
|
||||
}
|
||||
)
|
||||
}
|
||||
|
After Width: | Height: | Size: 13 KiB |
Loading…
Reference in new issue