diff --git a/app/src/main/java/com/iqball/app/MainActivity.kt b/app/src/main/java/com/iqball/app/MainActivity.kt index 596da9f..79c9e33 100644 --- a/app/src/main/java/com/iqball/app/MainActivity.kt +++ b/app/src/main/java/com/iqball/app/MainActivity.kt @@ -43,25 +43,15 @@ class MainActivity : ComponentActivity() { val service = retrofit.create() setContent { - IQBallTheme { + IQBallTheme(darkTheme = false, dynamicColor = false) { // A surface container using the 'background' color from the theme - Surface(modifier = Modifier.fillMaxSize(), color = MaterialTheme.colorScheme.background) { - //App(service) + Surface( + modifier = Modifier.fillMaxSize(), + color = MaterialTheme.colorScheme.background + ) { HomePage(service) } } } } -} - -@Composable -fun App(service: IQBallService) { - runBlocking { - val result = service.login(AuthService.LoginRequest("yanis@mail.com", "123456")) - - val auth = result.getOrNull()!! - Log.d("test", "test") - service.getUserData(auth.token) - } - RegisterPage(service) } \ No newline at end of file diff --git a/app/src/main/java/com/iqball/app/model/Team.kt b/app/src/main/java/com/iqball/app/model/Team.kt index 2a7b99e..8a91a8e 100644 --- a/app/src/main/java/com/iqball/app/model/Team.kt +++ b/app/src/main/java/com/iqball/app/model/Team.kt @@ -1,29 +1,9 @@ package com.iqball.app.model; -class Team public constructor( - private val id: Int, - private val name: String, - private val picture: String, - private val mainColor: String, - private val secondColor: String -) { - public fun getId() : Int { - return id - } - - public fun getName() : String { - return name - } - - public fun getPicture() : String { - return picture - } - - public fun getMainColor() : String { - return mainColor - } - - public fun getSecondColor() : String { - return secondColor - } -} +data class Team ( + val id: Int, + val name: String, + val picture: String, + val mainColor: String, + val secondColor: String +) \ No newline at end of file diff --git a/app/src/main/java/com/iqball/app/page/HomePage.kt b/app/src/main/java/com/iqball/app/page/HomePage.kt index 9d58a99..8d404e2 100644 --- a/app/src/main/java/com/iqball/app/page/HomePage.kt +++ b/app/src/main/java/com/iqball/app/page/HomePage.kt @@ -24,13 +24,13 @@ import androidx.core.graphics.toColorInt import androidx.compose.material3.CenterAlignedTopAppBar import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.OutlinedButton import androidx.compose.material3.Scaffold import androidx.compose.material3.Text import androidx.compose.material3.TopAppBarDefaults import androidx.compose.material3.TopAppBarDefaults.pinnedScrollBehavior import androidx.compose.material3.rememberTopAppBarState -import androidx.compose.runtime.getValue +import androidx.compose.runtime.MutableState +import androidx.compose.runtime.mutableIntStateOf import androidx.compose.runtime.mutableStateOf import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color @@ -40,7 +40,6 @@ import androidx.compose.ui.unit.sp import com.iqball.app.model.Tactic import com.iqball.app.model.Team import androidx.compose.runtime.remember -import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.draw.shadow import androidx.compose.ui.graphics.RectangleShape @@ -85,7 +84,7 @@ fun HomePage(service: IQBallService) { colors = TopAppBarDefaults.topAppBarColors( containerColor = MaterialTheme.colorScheme.primary, titleContentColor = MaterialTheme.colorScheme.secondary, - ), + ), title = { Text( "IQBall", @@ -103,101 +102,107 @@ fun HomePage(service: IQBallService) { } @Composable -fun Body(padding: PaddingValues, tactics: List, teams: List, invalid: Boolean) { +private fun Body(padding: PaddingValues, tactics: List, teams: List, invalid: Boolean) { Column( modifier = Modifier .padding(padding) ) { - var isTactics by remember { mutableStateOf(true) } - TabButtons(isTactics) { newIsTactic -> - isTactics = newIsTactic - } - if (isTactics) { - ListTacticCard(tactics) - } else { - ListTeamCard(teams) - } - if (invalid) { - TextCentered(text = "Erreur : Aucune connexion internet. Veillez activer votre connexion internet puis relancer l'application", fontSize = 20.sp ) + val selectedTab = remember { mutableIntStateOf(0) } + val tabs = listOf Unit>>( + Pair("Espace personnel") { + ListComponentCard(tactics) { tactic -> + TacticCard(tactic = tactic) + } + }, + Pair("Mes Equipes") { + ListComponentCard(teams) { team -> + TeamCard(team = team) + } + } + ) + TabsSelector(tabsTitles = tabs.map { it.first }, selectedIndex = selectedTab) + if (!invalid) { + tabs[selectedTab.intValue].second() + return } } + + TextCentered( + text = "Erreur : Aucune connexion internet. Veillez activer votre connexion internet puis relancer l'application", + fontSize = 20.sp + ) } @Composable -fun TabButtons(isTactics: Boolean, onToggle: (Boolean) -> Unit) { +private fun TabsSelector(tabsTitles: List, selectedIndex: MutableState) { Row( horizontalArrangement = Arrangement.Center, modifier = Modifier - .padding(top = 10.dp, start = 2.dp, end = 2.dp) + .padding(top = 20.dp, start = 2.dp, end = 2.dp, bottom = 10.dp) .fillMaxWidth() - .padding(top = 10.dp, bottom = 10.dp) - ) { - val tacticTitle = "Espace personnel" - val teamTitle = "Mes équipes" - val spaceButton = 5.dp - if (isTactics) { - FilledButton(tacticTitle) {} - Spacer( - modifier = Modifier - .padding(spaceButton) + + for ((idx, tab) in tabsTitles.withIndex()) { + TabButton( + tab, + fill = idx == selectedIndex.value, + onClick = { selectedIndex.value = idx } ) - OutlinedButton(teamTitle) { - onToggle(false) - } - } else { - OutlinedButton(tacticTitle) { - onToggle(true) + if (idx != tabsTitles.size - 1) { + Spacer( + modifier = Modifier + .padding(5.dp) + ) } - Spacer( - modifier = Modifier - .padding(spaceButton) - ) - FilledButton(teamTitle) {} } + } } @Composable -fun ListTacticCard(tactics: List) { - LazyVerticalStaggeredGrid( - columns = StaggeredGridCells.Fixed(2), - modifier = Modifier - .padding(5.dp), - content = { - items(tactics) { tactic -> - TacticCard(tactic) - } - } - ) +private fun TabButton(title: String, fill: Boolean, onClick: () -> Unit) { + val scheme = MaterialTheme.colorScheme + Button( + border = BorderStroke( + 1.dp, + color = scheme.tertiary + ), + colors = ButtonDefaults.buttonColors( + containerColor = if (fill) scheme.tertiary else scheme.background, + contentColor = if (fill) scheme.background else scheme.tertiary, + ), + onClick = onClick + ) { + Text(title) + } } @Composable -fun ListTeamCard(teams: List) { +private fun ListComponentCard(items: List, componentCard: @Composable (C) -> Unit) { LazyVerticalStaggeredGrid( columns = StaggeredGridCells.Fixed(2), modifier = Modifier .padding(5.dp), content = { - items(teams) { team -> - TeamCard(team) + items(items) { tactic -> + componentCard(tactic) } } ) } @Composable -fun TacticCard(tactic: Tactic) { +private fun TacticCard(tactic: Tactic) { Column( modifier = Modifier .padding(5.dp) .border( - border = BorderStroke(1.dp, Color(0xFFDADCE0)), + border = BorderStroke(1.dp, MaterialTheme.colorScheme.outline), shape = RoundedCornerShape(8.dp) ) .shadow(1.dp, shape = RoundedCornerShape(8.dp)) .background( - color = Color(0xFFFFFFFF) + color = Color.White ) .padding(15.dp) ) { @@ -205,27 +210,35 @@ fun TacticCard(tactic: Tactic) { TextCentered(text = tactic.name, fontSize = 16.sp) } Row { - val date =LocalDateTime.ofInstant(Instant.ofEpochMilli(tactic.creationDate), ZoneId.systemDefault()) + val date = LocalDateTime.ofInstant( + Instant.ofEpochMilli(tactic.creationDate), + ZoneId.systemDefault() + ) val dateFormatted = date.format(DateTimeFormatter.ofPattern("dd/MM/yyyy kk:mm")) - TextCentered(text = dateFormatted , fontSize = 10.sp, fontWeight = FontWeight.Bold, modifier = Modifier.padding(2.dp)) + TextCentered( + text = dateFormatted, + fontSize = 10.sp, + fontWeight = FontWeight.Bold, + modifier = Modifier.padding(2.dp) + ) } } } @Composable -fun TeamCard(team: Team) { +private fun TeamCard(team: Team) { var mainColor = Color.White var secondColor = Color.White var validMain = true var validSecond = true try { - mainColor = Color(team.getMainColor().toColorInt()) - } catch (e : Exception) { + mainColor = Color(team.mainColor.toColorInt()) + } catch (e: Exception) { validMain = false } try { - secondColor = Color(team.getSecondColor().toColorInt()) - } catch (e : Exception) { + secondColor = Color(team.secondColor.toColorInt()) + } catch (e: Exception) { validSecond = false } @@ -233,39 +246,39 @@ fun TeamCard(team: Team) { modifier = Modifier .padding(5.dp) .border( - border = BorderStroke(1.dp, Color(0xFFDADCE0)), + border = BorderStroke(1.dp, MaterialTheme.colorScheme.outline), shape = RoundedCornerShape(8.dp) ) .shadow(1.dp, shape = RoundedCornerShape(8.dp)) .background( - color = Color(0xFFFFFFFF) + color = Color.White ) .padding(15.dp) ) { AsyncImage( - model = team.getPicture(), + model = team.picture, contentDescription = null, modifier = Modifier .fillMaxWidth() .border( - border = BorderStroke(1.dp, Color(0xFFDADCE0)), + border = BorderStroke(1.dp, MaterialTheme.colorScheme.outline), shape = RectangleShape ) ) - TextCentered(text = team.getName()) + TextCentered(text = team.name) Row { - TeamColorCard("Couleur principale", mainColor, 0.5f) - TeamColorCard("Couleur secondaire", secondColor) + TeamColorCard("Couleur principale", mainColor, 0.5f) + TeamColorCard("Couleur secondaire", secondColor) } - if(!validMain || !validSecond) { + if (!validMain || !validSecond) { TextCentered(text = "Erreur : Format des couleurs invalides", fontSize = 16.sp) } } } @Composable -fun TeamColorCard(text: String, color: Color, fraction : Float = 1f) { +private fun TeamColorCard(text: String, color: Color, fraction: Float = 1f) { Column( modifier = Modifier .fillMaxWidth(fraction) @@ -289,35 +302,14 @@ fun TeamColorCard(text: String, color: Color, fraction : Float = 1f) { } @Composable -fun FilledButton(text: String, onClick: () -> Unit) { - Button( - colors = ButtonDefaults.buttonColors( - containerColor = MaterialTheme.colorScheme.tertiary, - ), - onClick = { onClick() } - ) { - Text(text) - } -} - -@Composable -fun OutlinedButton(text: String, onClick: () -> Unit) { - OutlinedButton( - border = BorderStroke( - 1.dp, - color = MaterialTheme.colorScheme.tertiary - ), - colors = ButtonDefaults.outlinedButtonColors( - contentColor = MaterialTheme.colorScheme.tertiary - ), - onClick = { onClick() }) { - Text(text) - } -} - -@Composable -fun TextCentered( modifier: Modifier = Modifier, text: String, fontSize: TextUnit = 18.sp, fontWeight: FontWeight? = null) { - Text(text = text, +private fun TextCentered( + modifier: Modifier = Modifier, + text: String, + fontSize: TextUnit = 18.sp, + fontWeight: FontWeight? = null +) { + Text( + text = text, modifier = modifier .fillMaxWidth(), textAlign = TextAlign.Center, @@ -326,8 +318,8 @@ fun TextCentered( modifier: Modifier = Modifier, text: String, fontSize: TextUni ) } - fun getDataFromApi(service: IQBallService) : UserService.UserDataResponse?{ - var res : UserService.UserDataResponse? = null +private fun getDataFromApi(service: IQBallService): UserService.UserDataResponse? { + var res: UserService.UserDataResponse? = null try { runBlocking { val result = service.login(AuthService.LoginRequest("yanis@mail.com", "123456")) @@ -345,25 +337,49 @@ fun TextCentered( modifier: Modifier = Modifier, text: String, fontSize: TextUni } } return res - } catch (error : Exception) { + } catch (error: Exception) { return res } } -fun getStubTeam() : ArrayList { +private fun getStubTeam(): ArrayList { val teams = ArrayList() teams.addAll( listOf( - Team(1, "equipe1", "https://www.shutterstock.com/image-vector/batman-logo-icon-vector-template-600nw-1998917738.jpg", "#4500FF", "#456789"), - Team(2, "equipe2", "https://images-wixmp-ed30a86b8c4ca887773594c2.wixmp.com/f/2f899b52-daf8-4098-83fe-5c5e27b69915/d4s4nzj-5f915488-7462-4908-b3c5-1605b0e4dc32.jpg?token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ1cm46YXBwOjdlMGQxODg5ODIyNjQzNzNhNWYwZDQxNWVhMGQyNmUwIiwiaXNzIjoidXJuOmFwcDo3ZTBkMTg4OTgyMjY0MzczYTVmMGQ0MTVlYTBkMjZlMCIsIm9iaiI6W1t7InBhdGgiOiJcL2ZcLzJmODk5YjUyLWRhZjgtNDA5OC04M2ZlLTVjNWUyN2I2OTkxNVwvZDRzNG56ai01ZjkxNTQ4OC03NDYyLTQ5MDgtYjNjNS0xNjA1YjBlNGRjMzIuanBnIn1dXSwiYXVkIjpbInVybjpzZXJ2aWNlOmZpbGUuZG93bmxvYWQiXX0.KqdQgobH9kzyMIeYIneNdyWgKTpGbztwSKqK5pO3YYs", "121212", "#564738"), - Team(3, "equipe3", "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQ1jiizrhhGsr48WrxxBbDpkFrRKeAYlGgcNQ&usqp=CAU", "#987654", "121212"), - Team(4, "equipe4", "https://www.shutterstock.com/image-vector/batman-logo-icon-vector-template-600nw-1998917738.jpg", "121212", "121212") + Team( + 1, + "equipe1", + "https://www.shutterstock.com/image-vector/batman-logo-icon-vector-template-600nw-1998917738.jpg", + "#4500FF", + "#456789" + ), + Team( + 2, + "equipe2", + "https://images-wixmp-ed30a86b8c4ca887773594c2.wixmp.com/f/2f899b52-daf8-4098-83fe-5c5e27b69915/d4s4nzj-5f915488-7462-4908-b3c5-1605b0e4dc32.jpg?token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ1cm46YXBwOjdlMGQxODg5ODIyNjQzNzNhNWYwZDQxNWVhMGQyNmUwIiwiaXNzIjoidXJuOmFwcDo3ZTBkMTg4OTgyMjY0MzczYTVmMGQ0MTVlYTBkMjZlMCIsIm9iaiI6W1t7InBhdGgiOiJcL2ZcLzJmODk5YjUyLWRhZjgtNDA5OC04M2ZlLTVjNWUyN2I2OTkxNVwvZDRzNG56ai01ZjkxNTQ4OC03NDYyLTQ5MDgtYjNjNS0xNjA1YjBlNGRjMzIuanBnIn1dXSwiYXVkIjpbInVybjpzZXJ2aWNlOmZpbGUuZG93bmxvYWQiXX0.KqdQgobH9kzyMIeYIneNdyWgKTpGbztwSKqK5pO3YYs", + "121212", + "#564738" + ), + Team( + 3, + "equipe3", + "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQ1jiizrhhGsr48WrxxBbDpkFrRKeAYlGgcNQ&usqp=CAU", + "#987654", + "121212" + ), + Team( + 4, + "equipe4", + "https://www.shutterstock.com/image-vector/batman-logo-icon-vector-template-600nw-1998917738.jpg", + "121212", + "121212" + ) ) ) return teams } -fun getStubTactic() : ArrayList { +private fun getStubTactic(): ArrayList { val tactics = ArrayList() tactics.addAll( listOf( @@ -391,4 +407,66 @@ fun getStubTactic() : ArrayList { ) return tactics -} \ No newline at end of file +} + +/* +======================================================= + Commentaire +======================================================= + + Gérer les listes à afficher avec des paires n'est pas forcément la meilleure chose à faire dans le contexte de composable. + Nous avons fait le choix de rester sur ce modèle par manque de temps. + +Nous aurions aussi pu faire quelque chose comme ça : + +@Composable +fun Body(padding: PaddingValues, tactics: List, teams: List, invalid: Boolean) { + Column(...) { + val selectedTab by remember { mutableIntStateOf(0) } + val tabs = remember(selectedTab) { + mutableStateOf(TabsGroup.entries.getOrNull(selectedTab)) + } + TabsSelector(tabsTitles = TabsGroup.entries.map { it.title }, selectedIndex = selectedTab, ) + if (!invalid) { + ListComponentCard { + when(selectedTab) { + TabsGroup.TEAM -> { + items(tactics) { + TacticCard(tactic = it) + } + } + TabsGroup.TACTIC -> ... + } + } + tabs[selectedTab.intValue].second() + return + } + + TextCentered(...) + } +} + +enum class TabsGroup { + TEAM, + TACTIC +} + +val TabsGroup.title: String + @Composable + get() = when(this) { + TabsGroup.TACTIC -> "Espace personnel" + TabsGroup.TEAM -> "Mes équipes" + } + +@Composable +fun ListComponentCard(componentCard: LazyStaggeredGridScope.() -> Unit) { + LazyVerticalStaggeredGrid( + columns = StaggeredGridCells.Fixed(2), + modifier = ..., + content = { + componentCard() + } + ) +} + + */ \ No newline at end of file diff --git a/app/src/main/java/com/iqball/app/ui/theme/Color.kt b/app/src/main/java/com/iqball/app/ui/theme/Color.kt index e8374f6..66341eb 100644 --- a/app/src/main/java/com/iqball/app/ui/theme/Color.kt +++ b/app/src/main/java/com/iqball/app/ui/theme/Color.kt @@ -15,4 +15,6 @@ val orange = Color(0xFFFFA239) val blue = Color(0xFF0D6EFD) val grey = Color(0xFF282A36) val back = Color(0xFFf8f8f8) +val borderCard = Color(0xFFDADCE0) + diff --git a/app/src/main/java/com/iqball/app/ui/theme/Theme.kt b/app/src/main/java/com/iqball/app/ui/theme/Theme.kt index 7f0d92c..ae5f228 100644 --- a/app/src/main/java/com/iqball/app/ui/theme/Theme.kt +++ b/app/src/main/java/com/iqball/app/ui/theme/Theme.kt @@ -28,7 +28,8 @@ private val LightColorScheme = lightColorScheme( tertiary = blue, primaryContainer = black, surface = grey, - background = back + background = back, + outline = borderCard /* Other default colors to override diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index f8c6127..9255bbb 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -7,4 +7,5 @@ #FF018786 #FF000000 #FFFFFFFF + #FFDADCE0 \ No newline at end of file