diff --git a/composeApp/src/commonMain/kotlin/ch/parano/myice/ui/components/EventCard.kt b/composeApp/src/commonMain/kotlin/ch/parano/myice/ui/components/EventCard.kt new file mode 100644 index 0000000..b60157d --- /dev/null +++ b/composeApp/src/commonMain/kotlin/ch/parano/myice/ui/components/EventCard.kt @@ -0,0 +1,81 @@ +package ch.parano.myice.ui.components + +import androidx.compose.foundation.background +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.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.width +import androidx.compose.material3.Card +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.myice.models.Event + +@Composable +fun EventCard( + event: Event, + onClick: () -> Unit, + modifier: Modifier = Modifier, +) { + val stripeColor = event.color?.let { parseHexColor(it) } + ?: MaterialTheme.colorScheme.primary + + Card( + onClick = onClick, + modifier = modifier + .fillMaxWidth() + .padding(horizontal = 16.dp, vertical = 8.dp), + ) { + Row( + modifier = Modifier.height(120.dp), + ) { + Box( + modifier = Modifier + .width(4.dp) + .fillMaxHeight() + .background(stripeColor), + ) + Column( + modifier = Modifier + .padding(16.dp) + .fillMaxHeight(), + verticalArrangement = androidx.compose.foundation.layout.Arrangement.spacedBy(4.dp), + ) { + Text( + text = "${event.agegroup} - ${event.name}", + style = MaterialTheme.typography.titleMedium, + ) + Text( + text = event.title, + style = MaterialTheme.typography.bodyMedium, + ) + Text( + text = "Adversaire: ${event.opponent}", + style = MaterialTheme.typography.bodySmall, + ) + Text( + text = "Lieu: ${event.place}", + style = MaterialTheme.typography.bodySmall, + ) + Text( + text = "${event.start} - ${event.end}", + style = MaterialTheme.typography.bodySmall, + ) + } + } + } +} + +private fun parseHexColor(hex: String): Color { + val cleanHex = hex.removePrefix("#") + val value = cleanHex.toLong(16) + return Color(0xFF000000 or value) +} diff --git a/composeApp/src/commonMain/kotlin/ch/parano/myice/ui/components/FilterDropdown.kt b/composeApp/src/commonMain/kotlin/ch/parano/myice/ui/components/FilterDropdown.kt new file mode 100644 index 0000000..61ca6ad --- /dev/null +++ b/composeApp/src/commonMain/kotlin/ch/parano/myice/ui/components/FilterDropdown.kt @@ -0,0 +1,56 @@ +package ch.parano.myice.ui.components + +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.material3.DropdownMenuItem +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.ExposedDropdownMenuBox +import androidx.compose.material3.ExposedDropdownMenuDefaults +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.Modifier + +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun FilterDropdown( + label: String, + selectedValue: String?, + options: List, + onSelect: (String?) -> Unit, + modifier: Modifier = Modifier, +) { + var expanded by remember { mutableStateOf(false) } + + ExposedDropdownMenuBox( + expanded = expanded, + onExpandedChange = { expanded = it }, + modifier = modifier.fillMaxWidth(), + ) { + OutlinedTextField( + value = selectedValue ?: "", + onValueChange = {}, + readOnly = true, + label = { Text(label) }, + trailingIcon = { ExposedDropdownMenuDefaults.TrailingIcon(expanded) }, + modifier = Modifier.menuAnchor().fillMaxWidth(), + ) + ExposedDropdownMenu( + expanded = expanded, + onDismissRequest = { expanded = false }, + ) { + options.forEach { option -> + DropdownMenuItem( + text = { Text(option) }, + onClick = { + onSelect(option) + expanded = false + }, + ) + } + } + } +} diff --git a/composeApp/src/commonMain/kotlin/ch/parano/myice/ui/components/LoadingIndicator.kt b/composeApp/src/commonMain/kotlin/ch/parano/myice/ui/components/LoadingIndicator.kt new file mode 100644 index 0000000..506d000 --- /dev/null +++ b/composeApp/src/commonMain/kotlin/ch/parano/myice/ui/components/LoadingIndicator.kt @@ -0,0 +1,18 @@ +package ch.parano.myice.ui.components + +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.material3.CircularProgressIndicator +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier + +@Composable +fun LoadingIndicator(modifier: Modifier = Modifier) { + Box( + modifier = modifier.fillMaxSize(), + contentAlignment = Alignment.Center, + ) { + CircularProgressIndicator() + } +} diff --git a/composeApp/src/commonMain/kotlin/ch/parano/myice/ui/theme/Theme.kt b/composeApp/src/commonMain/kotlin/ch/parano/myice/ui/theme/Theme.kt new file mode 100644 index 0000000..070bdb1 --- /dev/null +++ b/composeApp/src/commonMain/kotlin/ch/parano/myice/ui/theme/Theme.kt @@ -0,0 +1,37 @@ +package ch.parano.myice.ui.theme + +import androidx.compose.foundation.isSystemInDarkTheme +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.darkColorScheme +import androidx.compose.material3.lightColorScheme +import androidx.compose.runtime.Composable +import androidx.compose.ui.graphics.Color + +private val Indigo = Color(0xFF3F51B5) +private val IndigoLight = Color(0xFF7986CB) +private val IndigoDark = Color(0xFF303F9F) + +private val LightColors = lightColorScheme( + primary = Indigo, + onPrimary = Color.White, + primaryContainer = IndigoDark, + secondary = IndigoLight, +) + +private val DarkColors = darkColorScheme( + primary = IndigoLight, + onPrimary = Color.Black, + primaryContainer = Indigo, + secondary = Indigo, +) + +@Composable +fun MyIceTheme( + darkTheme: Boolean = isSystemInDarkTheme(), + content: @Composable () -> Unit, +) { + MaterialTheme( + colorScheme = if (darkTheme) DarkColors else LightColors, + content = content, + ) +}