Page Login + SignUp + Profil (pour le moment, c'est juste visuel)

pull/6/head
Leni BEAULATON 2 months ago
parent bf100a01b2
commit 7424c5487e

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

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

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

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

Loading…
Cancel
Save