diff --git a/app/src/main/java/app/closer/ui/components/PlaceholderScreen.kt b/app/src/main/java/app/closer/ui/components/PlaceholderScreen.kt deleted file mode 100644 index efee0150..00000000 --- a/app/src/main/java/app/closer/ui/components/PlaceholderScreen.kt +++ /dev/null @@ -1,358 +0,0 @@ -package app.closer.ui.components - -import app.closer.ui.theme.closerBackgroundBrush -import app.closer.ui.theme.closerSoftSurfaceColor -import androidx.compose.foundation.Canvas -import androidx.compose.foundation.background -import androidx.compose.foundation.border -import androidx.compose.foundation.horizontalScroll -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.Spacer -import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.height -import androidx.compose.foundation.layout.navigationBarsPadding -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.safeDrawingPadding -import androidx.compose.foundation.layout.size -import androidx.compose.foundation.layout.statusBarsPadding -import androidx.compose.foundation.layout.width -import androidx.compose.foundation.rememberScrollState -import androidx.compose.foundation.shape.CircleShape -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.foundation.verticalScroll -import androidx.compose.material3.Button -import androidx.compose.material3.ButtonDefaults -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.OutlinedButton -import androidx.compose.material3.Surface -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -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.geometry.Size -import androidx.compose.ui.graphics.Brush -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.graphics.drawscope.rotate -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.text.style.TextOverflow -import androidx.compose.ui.unit.dp - -data class PlaceholderAction( - val label: String, - val route: String -) - -@Composable -fun PlaceholderScreen( - title: String, - section: String, - description: String, - route: String, - onNavigate: (String) -> Unit, - modifier: Modifier = Modifier, - accent: Color = Color(0xFFB98AF4), - primaryAction: PlaceholderAction? = null, - secondaryAction: PlaceholderAction? = null, - chips: List = emptyList(), - details: List = emptyList() -) { - val background = closerBackgroundBrush() - - Box( - modifier = modifier - .fillMaxSize() - .background(background) - ) { - DepthBackdrop(accent = accent) - - Column( - modifier = Modifier - .fillMaxSize() - .safeDrawingPadding() - .verticalScroll(rememberScrollState()) - .padding(horizontal = 22.dp, vertical = 18.dp) - .navigationBarsPadding(), - verticalArrangement = Arrangement.spacedBy(20.dp) - ) { - PlaceholderHeader( - section = section, - title = title, - description = description, - accent = accent - ) - - if (chips.isNotEmpty()) { - Row( - modifier = Modifier - .fillMaxWidth() - .horizontalScroll(rememberScrollState()), - horizontalArrangement = Arrangement.spacedBy(10.dp) - ) { - chips.forEach { chip -> - SignalChip(label = chip, accent = accent) - } - } - } - - PreviewPanel( - title = "What belongs here", - accent = accent, - details = details.ifEmpty { - listOf( - "The main moment is easy to find", - "Important choices have room to breathe", - "The path forward stays clear" - ) - } - ) - - Row( - modifier = Modifier.fillMaxWidth(), - horizontalArrangement = Arrangement.spacedBy(12.dp) - ) { - primaryAction?.let { action -> - Button( - onClick = { onNavigate(action.route) }, - modifier = Modifier.weight(1f), - colors = ButtonDefaults.buttonColors( - containerColor = accent, - contentColor = MaterialTheme.colorScheme.onPrimary - ), - shape = RoundedCornerShape(16.dp) - ) { - Text( - text = action.label, - maxLines = 1, - overflow = TextOverflow.Ellipsis - ) - } - } - - secondaryAction?.let { action -> - OutlinedButton( - onClick = { onNavigate(action.route) }, - modifier = Modifier.weight(1f), - colors = ButtonDefaults.outlinedButtonColors( - contentColor = MaterialTheme.colorScheme.onSurface - ), - shape = RoundedCornerShape(16.dp) - ) { - Text( - text = action.label, - maxLines = 1, - overflow = TextOverflow.Ellipsis - ) - } - } - } - - Spacer(modifier = Modifier.height(10.dp)) - } - } -} - -@Composable -private fun PlaceholderHeader( - section: String, - title: String, - description: String, - accent: Color -) { - Column( - modifier = Modifier - .fillMaxWidth() - .statusBarsPadding(), - verticalArrangement = Arrangement.spacedBy(16.dp) - ) { - Row( - modifier = Modifier.fillMaxWidth(), - horizontalArrangement = Arrangement.SpaceBetween, - verticalAlignment = Alignment.CenterVertically - ) { - SignalChip(label = section, accent = accent) - Text( - text = "Guided", - style = MaterialTheme.typography.labelSmall, - color = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.54f), - maxLines = 1, - overflow = TextOverflow.Ellipsis - ) - } - - Text( - text = title, - style = MaterialTheme.typography.displaySmall.copy( - fontWeight = FontWeight.SemiBold - ), - color = MaterialTheme.colorScheme.onSurface, - maxLines = 3, - overflow = TextOverflow.Ellipsis - ) - - Text( - text = description, - style = MaterialTheme.typography.bodyLarge, - color = MaterialTheme.colorScheme.onSurfaceVariant, - maxLines = 6, - overflow = TextOverflow.Ellipsis - ) - } -} - -@Composable -private fun SignalChip( - label: String, - accent: Color -) { - Surface( - shape = RoundedCornerShape(999.dp), - color = Color.White.copy(alpha = 0.72f), - tonalElevation = 0.dp, - shadowElevation = 0.dp, - modifier = Modifier.border( - width = 1.dp, - brush = Brush.horizontalGradient( - listOf(accent.copy(alpha = 0.42f), Color.White.copy(alpha = 0.2f)) - ), - shape = RoundedCornerShape(999.dp) - ) - ) { - Text( - text = label, - modifier = Modifier.padding(horizontal = 13.dp, vertical = 8.dp), - style = MaterialTheme.typography.labelMedium, - color = MaterialTheme.colorScheme.onSurface, - maxLines = 1, - overflow = TextOverflow.Ellipsis - ) - } -} - -@Composable -private fun PreviewPanel( - title: String, - accent: Color, - details: List -) { - Surface( - modifier = Modifier.fillMaxWidth(), - shape = RoundedCornerShape(28.dp), - color = Color.White.copy(alpha = 0.78f), - tonalElevation = 0.dp, - shadowElevation = 18.dp - ) { - Column( - modifier = Modifier.padding(18.dp), - verticalArrangement = Arrangement.spacedBy(14.dp) - ) { - Row( - modifier = Modifier.fillMaxWidth(), - horizontalArrangement = Arrangement.SpaceBetween, - verticalAlignment = Alignment.CenterVertically - ) { - Text( - text = title, - style = MaterialTheme.typography.titleMedium, - color = MaterialTheme.colorScheme.onSurface, - fontWeight = FontWeight.SemiBold, - maxLines = 1, - overflow = TextOverflow.Ellipsis - ) - Box( - modifier = Modifier - .clip(CircleShape) - .background(accent.copy(alpha = 0.16f)) - .padding(horizontal = 10.dp, vertical = 6.dp) - ) { - Text( - text = "Ready", - style = MaterialTheme.typography.labelSmall, - color = Color(0xFF56306F), - maxLines = 1, - overflow = TextOverflow.Ellipsis - ) - } - } - - details.take(4).forEachIndexed { index, detail -> - DetailRow( - detail = detail, - accent = accent, - index = index - ) - } - } - } -} - -@Composable -private fun DetailRow( - detail: String, - accent: Color, - index: Int -) { - Row( - modifier = Modifier - .fillMaxWidth() - .clip(RoundedCornerShape(18.dp)) - .background(closerSoftSurfaceColor()) - .padding(14.dp), - verticalAlignment = Alignment.CenterVertically - ) { - Box( - modifier = Modifier - .size(34.dp) - .clip(RoundedCornerShape(12.dp)) - .background(accent.copy(alpha = 0.16f)), - contentAlignment = Alignment.Center - ) { - Text( - text = (index + 1).toString().padStart(2, '0'), - style = MaterialTheme.typography.labelMedium, - color = Color(0xFF56306F), - fontWeight = FontWeight.SemiBold - ) - } - Spacer(modifier = Modifier.width(12.dp)) - Text( - text = detail, - style = MaterialTheme.typography.bodyMedium, - color = MaterialTheme.colorScheme.onSurfaceVariant, - modifier = Modifier.weight(1f), - maxLines = 2, - overflow = TextOverflow.Ellipsis - ) - } -} - -@Composable -private fun DepthBackdrop(accent: Color) { - Canvas(modifier = Modifier.fillMaxSize()) { - rotate(degrees = -12f, pivot = Offset(size.width * 0.76f, size.height * 0.12f)) { - drawRoundRect( - brush = Brush.linearGradient( - listOf(accent.copy(alpha = 0.26f), Color(0xFFE7A2D1).copy(alpha = 0.14f)) - ), - topLeft = Offset(size.width * 0.44f, -size.height * 0.05f), - size = Size(size.width * 0.78f, size.height * 0.24f), - cornerRadius = androidx.compose.ui.geometry.CornerRadius(72.dp.toPx()) - ) - } - rotate(degrees = 9f, pivot = Offset(size.width * 0.18f, size.height * 0.78f)) { - drawRoundRect( - brush = Brush.linearGradient( - listOf(Color(0xFFF4E8FF).copy(alpha = 0.32f), Color.White.copy(alpha = 0.08f)) - ), - topLeft = Offset(-size.width * 0.22f, size.height * 0.64f), - size = Size(size.width * 0.74f, size.height * 0.22f), - cornerRadius = androidx.compose.ui.geometry.CornerRadius(56.dp.toPx()) - ) - } - } -} diff --git a/app/src/main/java/app/closer/ui/dates/BucketListScreen.kt b/app/src/main/java/app/closer/ui/dates/BucketListScreen.kt index 62004002..30e8e015 100644 --- a/app/src/main/java/app/closer/ui/dates/BucketListScreen.kt +++ b/app/src/main/java/app/closer/ui/dates/BucketListScreen.kt @@ -248,7 +248,7 @@ private fun FilterChip( ) { Surface( shape = RoundedCornerShape(999.dp), - color = if (selected) Color(0xFFB98AF4) else Color(0xFFFFF8FC), + color = if (selected) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.surfaceVariant, tonalElevation = if (selected) 0.dp else 2.dp, shadowElevation = if (selected) 0.dp else 2.dp, modifier = Modifier @@ -378,13 +378,13 @@ private fun CategoryBadge( ) { Surface( shape = RoundedCornerShape(999.dp), - color = Color(0xFFF3E8FF) + color = MaterialTheme.colorScheme.primaryContainer ) { Text( text = category.replaceFirstChar { it.uppercase() }, modifier = Modifier.padding(horizontal = 11.dp, vertical = 6.dp), style = MaterialTheme.typography.labelSmall, - color = Color(0xFF56306F), + color = MaterialTheme.colorScheme.onPrimaryContainer, fontWeight = FontWeight.SemiBold ) } @@ -406,7 +406,7 @@ private fun AddItemDialog( Surface( modifier = Modifier.padding(20.dp), shape = RoundedCornerShape(28.dp), - color = Color.White + color = MaterialTheme.colorScheme.surface ) { Column( modifier = Modifier @@ -459,10 +459,10 @@ private fun AddItemDialog( modifier = Modifier.weight(1f), shape = RoundedCornerShape(16.dp), colors = ButtonDefaults.buttonColors( - containerColor = Color(0xFFE3D4EB) + containerColor = MaterialTheme.colorScheme.secondaryContainer ) ) { - Text("Cancel", color = MaterialTheme.colorScheme.onSurfaceVariant) + Text("Cancel", color = MaterialTheme.colorScheme.onSecondaryContainer) } Button( @@ -470,7 +470,7 @@ private fun AddItemDialog( modifier = Modifier.weight(1f), shape = RoundedCornerShape(16.dp), colors = ButtonDefaults.buttonColors( - containerColor = Color(0xFFB98AF4), + containerColor = MaterialTheme.colorScheme.primary, contentColor = MaterialTheme.colorScheme.onPrimary ) ) { @@ -489,7 +489,7 @@ private fun CategoryChip( ) { Surface( shape = RoundedCornerShape(999.dp), - color = if (selected) Color(0xFFB98AF4) else Color(0xFFFFF8FC), + color = if (selected) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.surfaceVariant, tonalElevation = if (selected) 0.dp else 2.dp, shadowElevation = if (selected) 0.dp else 2.dp, modifier = Modifier diff --git a/app/src/main/java/app/closer/ui/dates/DateMatchScreen.kt b/app/src/main/java/app/closer/ui/dates/DateMatchScreen.kt index 0ccf3ebf..0c455d28 100644 --- a/app/src/main/java/app/closer/ui/dates/DateMatchScreen.kt +++ b/app/src/main/java/app/closer/ui/dates/DateMatchScreen.kt @@ -239,18 +239,18 @@ private fun DateMatchHeader( IconButton(onClick = onViewMatches) { Surface( shape = CircleShape, - color = Color(0xFFF3E8FF) + color = MaterialTheme.colorScheme.primaryContainer ) { Box(modifier = Modifier.padding(8.dp)) { Icon( imageVector = Icons.Filled.Favorite, contentDescription = "View matches", - tint = Color(0xFF56306F) + tint = MaterialTheme.colorScheme.onPrimaryContainer ) if (matchCount > 0) { Surface( shape = CircleShape, - color = Color(0xFF8D2D35), + color = MaterialTheme.colorScheme.error, modifier = Modifier .size(16.dp) .align(Alignment.TopEnd) @@ -258,7 +258,7 @@ private fun DateMatchHeader( Text( text = matchCount.toString(), style = MaterialTheme.typography.labelSmall, - color = Color.White, + color = MaterialTheme.colorScheme.onError, modifier = Modifier.align(Alignment.Center) ) } diff --git a/app/src/main/java/app/closer/ui/questions/QuestionThreadScreen.kt b/app/src/main/java/app/closer/ui/questions/QuestionThreadScreen.kt index ffd17c2d..4f9456bb 100644 --- a/app/src/main/java/app/closer/ui/questions/QuestionThreadScreen.kt +++ b/app/src/main/java/app/closer/ui/questions/QuestionThreadScreen.kt @@ -168,7 +168,7 @@ private fun WaitingPhase( Surface( modifier = Modifier.fillMaxWidth(), shape = RoundedCornerShape(20.dp), - color = Color.White.copy(alpha = 0.78f) + color = MaterialTheme.colorScheme.surfaceVariant.copy(alpha = 0.78f) ) { Column( modifier = Modifier.padding(18.dp), diff --git a/app/src/main/java/app/closer/ui/wheel/WheelHistoryScreen.kt b/app/src/main/java/app/closer/ui/wheel/WheelHistoryScreen.kt index 3afbcfcd..4fca2cb1 100644 --- a/app/src/main/java/app/closer/ui/wheel/WheelHistoryScreen.kt +++ b/app/src/main/java/app/closer/ui/wheel/WheelHistoryScreen.kt @@ -355,13 +355,13 @@ private fun GameHistoryLockedCard(onUnlock: () -> Unit) { ) { Surface( shape = RoundedCornerShape(50.dp), - color = Color(0xFFF8F1FF) + color = MaterialTheme.colorScheme.surfaceVariant ) { Icon( Icons.Filled.Lock, contentDescription = null, modifier = Modifier.padding(16.dp).size(28.dp), - tint = Color(0xFFB98AF4) + tint = MaterialTheme.colorScheme.primary ) } Text(