Correction finale

This commit is contained in:
Chocolaterie
2025-01-30 16:21:04 +01:00
parent 7052a52779
commit 70b7ea7ff8
5 changed files with 142 additions and 37 deletions

View File

@@ -26,13 +26,15 @@ fun ArticleActivityPage() {
val navController = rememberNavController(); val navController = rememberNavController();
var viewModel = ListArticleViewModel(); var viewModel = ListArticleViewModel();
var detailViewModel = DetailArticleViewModel();
NavHost( NavHost(
navController = navController, navController = navController,
startDestination = "list_article" startDestination = "list_article"
) { ) {
composable("list_article") { ListArticleFragmentPage(viewModel, navController) } composable("list_article") { ListArticleFragmentPage(viewModel, detailViewModel, navController) }
composable("article_form") { ArticleFormFragmentPage(viewModel, navController) } composable("article_form") { ArticleFormFragmentPage(viewModel, navController) }
composable("article_detail") { DetailArticleFragmentPage(detailViewModel) }
} }
} }

View File

@@ -0,0 +1,72 @@
package com.example.tpfilrouge.article
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.style.TextAlign
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.tpfilrouge.R
import com.example.tpfilrouge.ui.theme.EniPage
@Composable
fun DetailArticleFragmentPage(
viewModel: DetailArticleViewModel
) {
// Ecouter les changements de la liste d'article dans le ViewModel
val articleState by viewModel.article.collectAsState();
EniPage {
Column(
horizontalAlignment = Alignment.CenterHorizontally,
modifier = Modifier.padding(40.dp)
) {
Text(
text = articleState.title,
modifier = Modifier.fillMaxWidth(),
textAlign = TextAlign.Center,
style = TextStyle(color = Color.White, fontSize = 28.sp)
)
Row(modifier = Modifier
.padding(10.dp)
.fillMaxWidth()
.padding(vertical = 14.dp)) {
AsyncImage(
model = articleState.imgPath,
contentDescription = "",
modifier = Modifier
.width(82.dp)
.padding(horizontal = 5.dp),
placeholder = painterResource(R.drawable.reset_password_ic),
)
Column(modifier = Modifier.padding(start = 5.dp)) {
Text(articleState.desc, style = TextStyle(color = Color.White, fontSize = 20.sp))
}
}
}
}
}
@Preview(
showBackground = true,
)
@Composable
fun DetailArticleFragmentPreview() {
var viewModel = DetailArticleViewModel();
DetailArticleFragmentPage(viewModel)
}

View File

@@ -0,0 +1,9 @@
package com.example.tpfilrouge.article
import kotlinx.coroutines.flow.MutableStateFlow
class DetailArticleViewModel {
var article = MutableStateFlow<Article>(Article("", "", ""));
}

View File

@@ -1,13 +1,18 @@
package com.example.tpfilrouge.article package com.example.tpfilrouge.article
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width import androidx.compose.foundation.layout.width
import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Delete import androidx.compose.material.icons.filled.Delete
import androidx.compose.material.icons.filled.Edit import androidx.compose.material.icons.filled.Edit
@@ -22,7 +27,9 @@ import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.TextStyle
@@ -39,52 +46,63 @@ import com.example.tpfilrouge.ui.theme.EniPage
import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.MutableStateFlow
@Composable @Composable
fun ArticleCard(article: Article, viewModel: ListArticleViewModel, navController: NavController?=null){ fun ArticleCard(article: Article, viewModel: ListArticleViewModel, detailViewModel: DetailArticleViewModel, navController: NavController?=null){
ElevatedCard( ElevatedCard(
elevation = CardDefaults.cardElevation(defaultElevation = 6.dp), elevation = CardDefaults.cardElevation(defaultElevation = 6.dp),
shape = RoundedCornerShape(0.dp),
modifier = Modifier.fillMaxWidth().padding(vertical = 14.dp) modifier = Modifier.fillMaxWidth().padding(vertical = 14.dp)
) { ) {
Row(modifier = Modifier.padding(10.dp)) { Box(Modifier.background(brush = Brush.linearGradient(listOf(
AsyncImage( Color(0xFF3a3b5d),
model = article.imgPath, Color(0xFF535479),
contentDescription = "", ))).fillMaxSize()) {
modifier = Modifier.width(82.dp).padding(horizontal = 5.dp), Row(modifier = Modifier.padding(10.dp)) {
placeholder = painterResource(R.drawable.reset_password_ic), AsyncImage(
) model = article.imgPath,
Column(modifier = Modifier.padding(start = 5.dp)) { contentDescription = "",
Text(article.title, modifier = Modifier.width(82.dp).padding(horizontal = 5.dp),
style = TextStyle(fontWeight = FontWeight.Bold, fontSize = 15.sp)) placeholder = painterResource(R.drawable.reset_password_ic),
Text(article.desc) )
Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.End) { Column(modifier = Modifier.padding(start = 5.dp)) {
IconButton(onClick = { Text(article.title,
}) { style = TextStyle(fontWeight = FontWeight.Bold, fontSize = 15.sp, color = Color.White))
Icon(imageVector = Icons.Filled.Info, contentDescription = "Voir") Text(article.desc, style = TextStyle(color = Color.White))
} Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.End) {
IconButton(onClick = { IconButton(onClick = {
// Dire au viewmodel qu'on va être en mode édition
viewModel.isEdit.value = true; detailViewModel.article.value = article;
// Dire au viewmodel quel article on va modifier navController!!.navigate("article_detail");
viewModel.editedArticle = article;
// Dire au viewmodel quel Id d'article en cours de proccessus }) {
viewModel.editedArticleId = article.id; Icon(imageVector = Icons.Filled.Info, tint = Color.White, contentDescription = "Voir")
// naviguer dans le formulaire }
navController!!.navigate("article_form") IconButton(onClick = {
}) { // Dire au viewmodel qu'on va être en mode édition
Icon(imageVector = Icons.Filled.Edit, contentDescription = "Edit") viewModel.isEdit.value = true;
} // Dire au viewmodel quel article on va modifier
IconButton(onClick = { viewModel.editedArticle = article;
viewModel.callDeleteArticleApi(article.id); // Dire au viewmodel quel Id d'article en cours de proccessus
}) { viewModel.editedArticleId = article.id;
Icon(imageVector = Icons.Filled.Delete, contentDescription = "Delete") // naviguer dans le formulaire
navController!!.navigate("article_form")
}) {
Icon(imageVector = Icons.Filled.Edit, tint = Color.White, contentDescription = "Edit")
}
IconButton(onClick = {
viewModel.callDeleteArticleApi(article.id);
}) {
Icon(imageVector = Icons.Filled.Delete, tint = Color.White, contentDescription = "Delete")
}
} }
} }
} }
} }
} }
} }
@Composable @Composable
fun ListArticleFragmentPage(viewModel: ListArticleViewModel, navController: NavController? = null) { fun ListArticleFragmentPage(viewModel: ListArticleViewModel, detailViewModel: DetailArticleViewModel, navController: NavController? = null) {
// Ecouter les changements de la liste d'article dans le ViewModel // Ecouter les changements de la liste d'article dans le ViewModel
val articlesState by viewModel.articles.collectAsState(); val articlesState by viewModel.articles.collectAsState();
@@ -98,6 +116,9 @@ fun ListArticleFragmentPage(viewModel: ListArticleViewModel, navController: NavC
textAlign = TextAlign.Center, textAlign = TextAlign.Center,
style = TextStyle(color = Color.White, fontSize = 28.sp)) style = TextStyle(color = Color.White, fontSize = 28.sp))
EniButton("Ajouter un Article") { EniButton("Ajouter un Article") {
// Passer le edit à false pour revenir en mode ajout dans le form
viewModel.isEdit.value = false;
navController!!.navigate("article_form") navController!!.navigate("article_form")
} }
EniButton("Rafraichir") { EniButton("Rafraichir") {
@@ -106,7 +127,7 @@ fun ListArticleFragmentPage(viewModel: ListArticleViewModel, navController: NavC
} }
LazyColumn { LazyColumn {
items(articlesState) { article -> items(articlesState) { article ->
ArticleCard(article, viewModel, navController) ArticleCard(article, viewModel, detailViewModel, navController)
} }
} }
} }
@@ -119,10 +140,11 @@ fun ListArticleFragmentPage(viewModel: ListArticleViewModel, navController: NavC
@Composable @Composable
fun ListArticleActivityPreview() { fun ListArticleActivityPreview() {
var viewModel = ListArticleViewModel(); var viewModel = ListArticleViewModel();
var detailViewModel = DetailArticleViewModel();
viewModel.articles = MutableStateFlow(listOf( viewModel.articles = MutableStateFlow(listOf(
Article("Teletubies", "Meilleur série du monde", "https://avatar.iran.liara.run/public"), Article("Teletubies", "Meilleur série du monde", "https://avatar.iran.liara.run/public"),
Article("Velocipastor", "Meilleur film du monde, gros budget", "https://avatar.iran.liara.run/public"), Article("Velocipastor", "Meilleur film du monde, gros budget", "https://avatar.iran.liara.run/public"),
Article("Photo mouton béret paille ?", "Pourquoi", "https://avatar.iran.liara.run/public") Article("Photo mouton béret paille ?", "Pourquoi", "https://avatar.iran.liara.run/public")
)); ));
ListArticleFragmentPage(viewModel) ListArticleFragmentPage(viewModel, detailViewModel)
} }

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB