merging master in Quote

pull/38/head
kevin.modejar 2 months ago
commit ec4b03649d

@ -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,4 +68,7 @@ dependencies {
androidTestImplementation(libs.androidx.ui.test.junit4)
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"))
}

@ -2,6 +2,9 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<application
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"

@ -13,8 +13,9 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import com.example.what_the_fantasy.data.local.QuoteStub
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.QuotePage
import androidx.navigation.NavController
import com.example.what_the_fantasy.ui.navigations.AppNavigator
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
@ -22,14 +23,9 @@ class MainActivity : ComponentActivity() {
enableEdgeToEdge()
setContent {
What_The_FantasyTheme {
Column {
Scaffold(modifier = Modifier.fillMaxSize()) { innerPadding ->
QuotePage(
quote = QuoteStub.quote1,
modifier = Modifier.padding(innerPadding)
)
}
}
//AppNavigator()
//QuizPage()
QuotePage(QuoteStub.quote15)
}
}
}

@ -8,73 +8,90 @@ 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 = "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"
)
imgUrl = "https://img.freepik.com/vecteurs-libre/personnage-elfe-fantaisie_1045-186.jpg?size=338&ext=jpg",
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"
)
imgUrl = "https://img.freepik.com/vecteurs-libre/personnage-magicien-fantaisie_1045-187.jpg?size=338&ext=jpg",
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"
)
imgUrl = "https://img.freepik.com/vecteurs-libre/personnage-hobbit-fantaisie_1045-188.jpg?size=338&ext=jpg",
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"
)
imgUrl = "https://img.freepik.com/vecteurs-libre/personnage-nain-fantaisie_1045-189.jpg?size=338&ext=jpg",
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"
)
imgUrl = "https://img.freepik.com/vecteurs-libre/personnage-elfe-femme-fantaisie_1045-190.jpg?size=338&ext=jpg",
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"
)
imgUrl = "https://img.freepik.com/vecteurs-libre/personnage-guerrier-homme-fantaisie_1045-191.jpg?size=338&ext=jpg",
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"
)
imgUrl = "https://img.freepik.com/vecteurs-libre/personnage-guerriere-femme-fantaisie_1045-192.jpg?size=338&ext=jpg",
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"
)
imgUrl = "https://img.freepik.com/vecteurs-libre/personnage-magicien-malefique-fantaisie_1045-193.jpg?size=338&ext=jpg",
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"
)
imgUrl = "https://img.freepik.com/vecteurs-libre/personnage-guerrier-homme-fantaisie_1045-194.jpg?size=338&ext=jpg",
password = "03ac674216f3e15c761ee1a5e255f067953623c8b388b4459e13f978d7c846f4") // 1234
val user11 = User(
id = 10,
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",
password = "03ac674216f3e15c761ee1a5e255f067953623c8b388b4459e13f978d7c846f4") // 1234
val allUsers: List<User> = listOf(
user1, user2, user3, user4, user5, user6, user7, user8, user9, user10
user1, user2, user3, user4, user5, user6, user7, user8, user9, user10, user11
)
}

@ -5,5 +5,6 @@ class User(
var username:String,
var email:String,
var date:String,
val imgUrl: String
val imgUrl: String,
val password: String
)

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

@ -9,12 +9,14 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.drawBehind
import androidx.compose.ui.geometry.CornerRadius
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import com.example.what_the_fantasy.R
import com.example.what_the_fantasy.data.model.Quote
@Composable
fun QuotePage(quote : Quote, modifier: Modifier) {
Column(modifier = modifier.padding(10.dp).drawBehind {
fun QuotePage(quote : Quote) {
Column(modifier = Modifier.padding(10.dp).drawBehind {
drawRoundRect(
Color(70,190,115),
cornerRadius = CornerRadius(10.dp.toPx())
@ -26,11 +28,11 @@ fun QuotePage(quote : Quote, modifier: Modifier) {
)
InfoQuoteText(
name = "@string/source",
nameId = R.string.source,
text = quote.source
)
InfoQuoteText(
name = "@string/charac",
nameId = R.string.charac,
text = quote.character
)
Text(
@ -41,10 +43,10 @@ fun QuotePage(quote : Quote, modifier: Modifier) {
}
@Composable
fun InfoQuoteText(name : String, text : String){
fun InfoQuoteText(nameId : Int, text : String){
Column{
Text(
text = name
text = stringResource(id = nameId)
)
Text(

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

@ -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)
@ -9,3 +11,9 @@ val Pink80 = Color(0xFFEFB8C8)
val Purple40 = Color(0xFF6650a4)
val PurpleGrey40 = Color(0xFF625b71)
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)

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

@ -4,6 +4,31 @@
<string name="movie">Film</string>
<string name="videoGame">Jeu Vidéo</string>
<string name="series">Série</string>
//Page Quote
<string name="charac">Personnage</string>
<string name="source">Source</string>
//Page Login
<string name="titleLogin">Connexion au compte</string>
<string name="IdentifiantLogin">Votre identifiant*</string>
<string name="PasswdLogin">Votre mot de passe*</string>
<string name="ButtonLogin">Se connecter</string>
<string name="ButtonCreateLogin">Créer son compte</string>
//Page Sign Up
<string name="titleSignUp">Inscription</string>
<string name="ConfirmPassWdSignUp">Confirmer mot de passe*</string>
<string name="ButtonSignUp">S\'inscrire</string>
//Page Profil
<string name="titleProfile">Profil</string>
<string name="ButtonAddQuoteprofile">Suggérer une citation</string>
<string name="ButtonLanguageprofile">Changer la langue</string>
<string name="ButtonUnlogprofile">Se Déconnecter</string>
<string name="NewPasswdprofile">Nouveau mot de passe</string>
<string name="ConfirmNewPasswdprofile">Confirmer le nouveau mot de passe</string>
<string name="ButtonSaveprofile">Sauvegarder</string>
<string name="ErrorEmailprofile">L\'adress email est invalide</string>
<string name="Errorpasswdprofile">Les mots de passe ne correspondent pas</string>
</resources>

@ -3,6 +3,31 @@
<string name="movie">Movie</string>
<string name="videoGame">Video Game</string>
<string name="series">Series</string>
//Page Quote
<string name="charac">Character</string>
<string name="source">Source</string>
//Page Login
<string name="titleLogin">Account login</string>
<string name="IdentifiantLogin">Your username*</string>
<string name="PasswdLogin">Your password*</string>
<string name="ButtonLogin">Login</string>
<string name="ButtonCreateLogin">Create your account</string>
//Page Sign Up
<string name="titleSignUp">Account creation</string>
<string name="ConfirmPassWdSignUp">Confirm your password*</string>
<string name="ButtonSignUp">Create</string>
//Page Profil
<string name="titleProfile">Profile</string>
<string name="ButtonAddQuoteprofile">Suggest a quote</string>
<string name="ButtonLanguageprofile">Change Language</string>
<string name="ButtonUnlogprofile">Disconnect</string>
<string name="NewPasswdprofile">New password</string>
<string name="ConfirmNewPasswdprofile">Confirm password</string>
<string name="ButtonSaveprofile">Save</string>
<string name="ErrorEmailprofile">Invalid email address</string>
<string name="Errorpasswdprofile">Passwords do not match</string>
</resources>

@ -1,5 +1,8 @@
[versions]
agp = "8.6.0"
bcrypt = "0.4"
coilCompose = "2.2.1"
kotlin = "1.9.0"
coreKtx = "1.10.1"
junit = "4.13.2"
@ -13,6 +16,9 @@ navigationCommonAndroid = "2.9.0-alpha05"
[libraries]
androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
bcrypt = { module = "org.mindrot:jbcrypt", version.ref = "bcrypt" }
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" }

Loading…
Cancel
Save