package com.taskttl.presentation.countdown import androidx.compose.foundation.background 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.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.width import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.verticalScroll import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.CalendarToday import androidx.compose.material.icons.filled.Edit import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Icon import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.graphics.Color import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import com.taskttl.core.ui.Chip import com.taskttl.core.ui.LoadingOverlay import com.taskttl.core.utils.DateUtils import com.taskttl.data.state.CountdownEffect import com.taskttl.data.viewmodel.CountdownViewModel import com.taskttl.ui.components.AppHeader import org.jetbrains.compose.resources.stringResource import org.koin.compose.viewmodel.koinViewModel import taskttl.composeapp.generated.resources.Res import taskttl.composeapp.generated.resources.countdown_not_found import taskttl.composeapp.generated.resources.detail_information import taskttl.composeapp.generated.resources.event_description import taskttl.composeapp.generated.resources.label_created_at import taskttl.composeapp.generated.resources.label_days import taskttl.composeapp.generated.resources.reminder import taskttl.composeapp.generated.resources.title_countdown_info @OptIn(ExperimentalMaterial3Api::class) @Composable fun CountdownDetailScreen( countdownId: String, onNavigateBack: () -> Unit, onNavigateToEdit: () -> Unit, viewModel: CountdownViewModel = koinViewModel() ) { val state by viewModel.state.collectAsState() val countdown = state.countdowns.find { it.id == countdownId } LaunchedEffect(Unit) { viewModel.effects.collect { effect -> when (effect) { is CountdownEffect.NavigateBack -> { onNavigateBack() } else -> {} } } } if (countdown == null) { Box( modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center ) { Text(stringResource(Res.string.countdown_not_found)) } return } // 剩余天数 val daysRemaining = DateUtils.daysRemaining(countdown.targetDate) Box( modifier = Modifier .fillMaxSize() .background(Color.White) ) { Column( modifier = Modifier.fillMaxSize() ) { AppHeader( title = Res.string.title_countdown_info, showBack = true, onBackClick = { onNavigateBack.invoke() }, trailingIcon = Icons.Default.Edit, onTrailingClick = { onNavigateToEdit.invoke() } ) Column( modifier = Modifier .fillMaxSize() .background(MaterialTheme.colorScheme.background) .padding(16.dp) .verticalScroll(rememberScrollState()), horizontalAlignment = Alignment.CenterHorizontally ) { Box( modifier = Modifier .fillMaxWidth() .clip(RoundedCornerShape(20.dp)) .background( brush = androidx.compose.ui.graphics.Brush.linearGradient( colors = listOf( countdown.category.color.backgroundColor, Color.Transparent ) ) ) .padding(20.dp) ) { Column(modifier = Modifier.align(Alignment.CenterStart)) { Row(verticalAlignment = Alignment.CenterVertically) { Text( text = countdown.title, fontSize = 18.sp, fontWeight = FontWeight.ExtraBold, color = Color(0xFF111111) ) Spacer(modifier = Modifier.width(6.dp)) Chip(text = countdown.category.name) } Spacer(modifier = Modifier.height(6.dp)) Row(verticalAlignment = Alignment.CenterVertically) { Icon( imageVector = Icons.Default.CalendarToday, contentDescription = null ) Spacer(modifier = Modifier.width(8.dp)) Text( text = countdown.targetDate.toString(), fontSize = 14.sp, color = Color(0xFF444444) ) } } Column( modifier = Modifier.align(Alignment.TopEnd), horizontalAlignment = Alignment.End ) { Text( text = daysRemaining.toString(), fontSize = 44.sp, fontWeight = FontWeight.ExtraBold, color = Color(0xFF111111) ) Text( text = stringResource(Res.string.label_days), fontSize = 12.sp, fontWeight = FontWeight.SemiBold, color = Color(0xFF666666) ) } } countdown.description.let { Spacer(modifier = Modifier.height(16.dp)) Column(modifier = Modifier.fillMaxWidth()) { Text( text = stringResource(Res.string.event_description), fontWeight = FontWeight.SemiBold, fontSize = 14.sp, color = Color(0xFF333333) ) Spacer(modifier = Modifier.height(10.dp)) Box( modifier = Modifier .fillMaxWidth() .clip(RoundedCornerShape(12.dp)) .background(Color.White) .padding(12.dp) ) { Column { Text( text = countdown.description, color = countdown.category.color.textColor, lineHeight = 20.sp ) } } } } Spacer(modifier = Modifier.height(12.dp)) Column(modifier = Modifier.fillMaxWidth()) { Text( text = stringResource(Res.string.detail_information), fontWeight = FontWeight.SemiBold, fontSize = 14.sp, color = Color(0xFF333333) ) Spacer(modifier = Modifier.height(10.dp)) Column { Row( modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.spacedBy(10.dp) ) { InfoItem( iconTint = Color(0xFF667EEA), text = "${stringResource(Res.string.reminder)}:${ stringResource(countdown.notificationEnabled.displayNameRes) }", modifier = Modifier.weight(1f) ) } Spacer(modifier = Modifier.height(10.dp)) Row(modifier = Modifier.fillMaxWidth()) { InfoItem( iconTint = Color(0xFF999999), text = "${stringResource(Res.string.label_created_at)}${countdown.createdAt}", modifier = Modifier.fillMaxWidth() ) } } } } } LoadingOverlay(state.isLoading) } } @Composable private fun InfoItem(iconTint: Color, text: String, modifier: Modifier = Modifier) { Row( modifier = modifier .clip(RoundedCornerShape(10.dp)) .background(Color.White) .padding(12.dp), verticalAlignment = Alignment.CenterVertically ) { Box( modifier = Modifier .size(18.dp) .clip(RoundedCornerShape(6.dp)) .background(iconTint) ) {} Spacer(modifier = Modifier.width(10.dp)) Text(text = text, fontSize = 13.sp, color = Color(0xFF555555)) } }