From e5c0a1183dc08f21b0138bebfde97bce5500829d Mon Sep 17 00:00:00 2001 From: Rene Luria Date: Thu, 6 Aug 2026 17:07:11 +0200 Subject: [PATCH] feat: redesign EventCard with color border, type badge, leading icons MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 4dp colored border from event.color (fallback primary) - AssistChip badge: Match (teal) vs Entraînement (slate) - Opponent line only for games, 'Entraînement' for practices - Place and Schedule icons leading info lines - Condensed time range via formatEventTimeRange --- .../parano/myicek/ui/components/EventCard.kt | 121 +++++++++++++----- 1 file changed, 90 insertions(+), 31 deletions(-) diff --git a/composeApp/src/commonMain/kotlin/ch/parano/myicek/ui/components/EventCard.kt b/composeApp/src/commonMain/kotlin/ch/parano/myicek/ui/components/EventCard.kt index 4dc26ce..6354701 100644 --- a/composeApp/src/commonMain/kotlin/ch/parano/myicek/ui/components/EventCard.kt +++ b/composeApp/src/commonMain/kotlin/ch/parano/myicek/ui/components/EventCard.kt @@ -17,24 +17,33 @@ package ch.parano.myicek.ui.components -import androidx.compose.foundation.background +import androidx.compose.foundation.border import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.fillMaxHeight +import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.width +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.Place +import androidx.compose.material.icons.filled.Schedule +import androidx.compose.material3.AssistChip +import androidx.compose.material3.AssistChipDefaults import androidx.compose.material3.Card +import androidx.compose.material3.CardDefaults +import androidx.compose.material3.Icon import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text 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.unit.dp import ch.parano.myicek.models.Event -import ch.parano.myicek.util.formatEventDateTime +import ch.parano.myicek.ui.theme.Dimens +import ch.parano.myicek.util.formatEventTimeRange @Composable fun EventCard( @@ -42,6 +51,7 @@ fun EventCard( onClick: () -> Unit, modifier: Modifier = Modifier, ) { + val isGame = event.eventType == "Jeu" val stripeColor = event.color?.let { parseHexColor(it) } ?: MaterialTheme.colorScheme.primary @@ -49,40 +59,89 @@ fun EventCard( onClick = onClick, modifier = modifier .fillMaxWidth() - .padding(horizontal = 16.dp, vertical = 8.dp), + .padding(horizontal = Dimens.lg, vertical = Dimens.sm), + elevation = CardDefaults.cardElevation(defaultElevation = 1.dp), ) { - Row { - Box( - modifier = Modifier - .width(4.dp) - .fillMaxHeight() - .background(stripeColor), - ) + Row( + modifier = Modifier + .fillMaxWidth() + .border(width = 4.dp, color = stripeColor), + ) { Column( modifier = Modifier - .padding(16.dp), - verticalArrangement = Arrangement.spacedBy(4.dp), + .fillMaxWidth() + .padding(Dimens.lg), + verticalArrangement = Arrangement.spacedBy(Dimens.xs), ) { + Row( + modifier = Modifier.fillMaxWidth(), + horizontalArrangement = Arrangement.SpaceBetween, + verticalAlignment = Alignment.CenterVertically, + ) { + Text( + text = "${event.agegroup} - ${event.name}", + style = MaterialTheme.typography.titleMedium, + modifier = Modifier.weight(1f), + ) + AssistChip( + onClick = {}, + label = { + Text( + if (isGame) "Match" else "Entraînement", + style = MaterialTheme.typography.labelMedium, + ) + }, + colors = if (isGame) { + AssistChipDefaults.assistChipColors( + containerColor = MaterialTheme.colorScheme.primaryContainer, + labelColor = MaterialTheme.colorScheme.onPrimaryContainer, + ) + } else { + AssistChipDefaults.assistChipColors( + containerColor = MaterialTheme.colorScheme.secondaryContainer, + labelColor = MaterialTheme.colorScheme.onSecondaryContainer, + ) + }, + ) + } Text( - text = "${event.agegroup} - ${event.name}", - style = MaterialTheme.typography.titleMedium, - ) - Text( - text = event.title, + text = if (isGame) "Match vs ${event.opponent}" else "Entraînement", style = MaterialTheme.typography.bodyMedium, + color = MaterialTheme.colorScheme.onSurfaceVariant, ) - Text( - text = "Adversaire: ${event.opponent}", - style = MaterialTheme.typography.bodySmall, - ) - Text( - text = "Lieu: ${event.place}", - style = MaterialTheme.typography.bodySmall, - ) - Text( - text = "Date: ${formatEventDateTime(event.start, event.end)}", - style = MaterialTheme.typography.bodySmall, - ) + Spacer(Modifier.height(Dimens.xs)) + Row( + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.spacedBy(Dimens.xs), + ) { + Icon( + imageVector = Icons.Filled.Place, + contentDescription = null, + modifier = Modifier.width(18.dp).height(18.dp), + tint = MaterialTheme.colorScheme.onSurfaceVariant, + ) + Text( + text = event.place, + style = MaterialTheme.typography.bodyMedium, + color = MaterialTheme.colorScheme.onSurfaceVariant, + ) + } + Row( + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.spacedBy(Dimens.xs), + ) { + Icon( + imageVector = Icons.Filled.Schedule, + contentDescription = null, + modifier = Modifier.width(18.dp).height(18.dp), + tint = MaterialTheme.colorScheme.onSurfaceVariant, + ) + Text( + text = formatEventTimeRange(event.start, event.end), + style = MaterialTheme.typography.bodySmall, + color = MaterialTheme.colorScheme.onSurfaceVariant, + ) + } } } }