package com.craigvg.lichun_android.ui.screens.onboarding import androidx.compose.animation.* import androidx.compose.animation.core.* import androidx.compose.foundation.background import androidx.compose.foundation.layout.* import androidx.compose.foundation.shape.CircleShape import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.* import androidx.compose.material3.* import androidx.compose.runtime.* 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.graphics.vector.ImageVector import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp import com.craigvg.lichun_android.R import com.craigvg.lichun_android.ui.theme.AppColors import com.craigvg.lichun_android.ui.theme.AppSpacing import com.craigvg.lichun_android.ui.theme.AppTypography import kotlinx.coroutines.delay /** * Main container for the onboarding flow * Ported from iOS OnboardingContainerView.swift */ @Composable fun OnboardingContainerScreen( onComplete: () -> Unit = {} ) { var currentStep by remember { mutableIntStateOf(0) } var showCharacterConfirmation by remember { mutableStateOf(false) } var characterName by remember { mutableStateOf("") } var characterAge by remember { mutableIntStateOf(18) } var characterSex by remember { mutableStateOf("Male") } fun advanceToStep(newStep: Int) { currentStep = newStep } Box(modifier = Modifier.fillMaxSize()) { AnimatedContent( targetState = currentStep, transitionSpec = { fadeIn( animationSpec = tween(300) ) + scaleIn( initialScale = 0.95f, animationSpec = tween(300) ) togetherWith fadeOut( animationSpec = tween(300) ) + scaleOut( targetScale = 1.05f, animationSpec = tween(300) ) }, label = "onboarding_step" ) { step -> when (step) { 0 -> { // Step 1: Welcome screen WelcomeScreen( onBeginJourney = { advanceToStep(1) } ) } 1 -> { // Step 2: Character creation if (!showCharacterConfirmation) { CharacterSetupScreen( onContinue = { name, age, sex -> characterName = name characterAge = age characterSex = sex showCharacterConfirmation = true } ) } else { ConfirmationScreen( name = characterName, age = characterAge, sex = characterSex, onStartJourney = { advanceToStep(2) } ) } } 2 -> { // Step 3: UI Tour OnboardingUITourScreen( onContinue = { advanceToStep(3) } ) } 3 -> { // Step 4: Guided actions OnboardingGuidedActionsScreen( onContinue = { advanceToStep(4) } ) } 4 -> { // Step 5: Completion OnboardingCompletionScreen( onComplete = onComplete ) } } } } } /** * UI Tour step of onboarding */ @Composable fun OnboardingUITourScreen( onContinue: () -> Unit ) { Column( modifier = Modifier .fillMaxSize() .background(AppColors.background) .padding(AppSpacing.lg), horizontalAlignment = Alignment.CenterHorizontally, verticalArrangement = Arrangement.SpaceBetween ) { Spacer(modifier = Modifier.height(AppSpacing.xl)) Column( horizontalAlignment = Alignment.CenterHorizontally, verticalArrangement = Arrangement.spacedBy(AppSpacing.md) ) { Box( modifier = Modifier .size(100.dp) .clip(CircleShape) .background(AppColors.secondary.copy(alpha = 0.2f)), contentAlignment = Alignment.Center ) { Icon( imageVector = Icons.Default.Explore, contentDescription = null, tint = AppColors.secondary, modifier = Modifier.size(50.dp) ) } Text( text = stringResource(R.string.explore_your_world), style = AppTypography.title, color = AppColors.primaryText ) Text( text = stringResource(R.string.explore_description), style = AppTypography.body, color = AppColors.secondaryText, textAlign = TextAlign.Center ) } // Feature highlights Column( verticalArrangement = Arrangement.spacedBy(AppSpacing.md) ) { TourHighlight( icon = Icons.Default.Home, title = stringResource(R.string.home), description = stringResource(R.string.home_description) ) TourHighlight( icon = Icons.Default.Favorite, title = stringResource(R.string.dating), description = stringResource(R.string.dating_description) ) TourHighlight( icon = Icons.Default.DirectionsRun, title = stringResource(R.string.activities), description = stringResource(R.string.activities_description) ) TourHighlight( icon = Icons.Default.Person, title = stringResource(R.string.character), description = stringResource(R.string.character_description) ) } Button( onClick = onContinue, modifier = Modifier .fillMaxWidth() .height(AppSpacing.buttonHeight), shape = RoundedCornerShape(AppSpacing.cornerRadius), colors = ButtonDefaults.buttonColors(containerColor = AppColors.primary) ) { Text( text = stringResource(R.string.got_it), style = AppTypography.headline, color = Color.White ) } Spacer(modifier = Modifier.height(AppSpacing.lg)) } } @Composable private fun TourHighlight( icon: ImageVector, title: String, description: String ) { Row( modifier = Modifier .fillMaxWidth() .clip(RoundedCornerShape(AppSpacing.cornerRadius)) .background(AppColors.surfaceElevated) .padding(AppSpacing.md), verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.spacedBy(AppSpacing.md) ) { Icon( imageVector = icon, contentDescription = null, tint = AppColors.primary, modifier = Modifier.size(24.dp) ) Column { Text( text = title, style = AppTypography.bodyBold, color = AppColors.primaryText ) Text( text = description, style = AppTypography.caption, color = AppColors.secondaryText ) } } } /** * Guided actions step of onboarding */ @Composable fun OnboardingGuidedActionsScreen( onContinue: () -> Unit ) { Column( modifier = Modifier .fillMaxSize() .background(AppColors.background) .padding(AppSpacing.lg), horizontalAlignment = Alignment.CenterHorizontally, verticalArrangement = Arrangement.SpaceBetween ) { Spacer(modifier = Modifier.height(AppSpacing.xl)) Column( horizontalAlignment = Alignment.CenterHorizontally, verticalArrangement = Arrangement.spacedBy(AppSpacing.md) ) { Box( modifier = Modifier .size(100.dp) .clip(CircleShape) .background(AppColors.accent.copy(alpha = 0.2f)), contentAlignment = Alignment.Center ) { Icon( imageVector = Icons.Default.TouchApp, contentDescription = null, tint = AppColors.accent, modifier = Modifier.size(50.dp) ) } Text( text = stringResource(R.string.take_action), style = AppTypography.title, color = AppColors.primaryText ) Text( text = stringResource(R.string.take_action_description), style = AppTypography.body, color = AppColors.secondaryText, textAlign = TextAlign.Center ) } Column( verticalArrangement = Arrangement.spacedBy(AppSpacing.md) ) { ActionTip( emoji = "\uD83D\uDC46", text = stringResource(R.string.tip_claim_rewards) ) ActionTip( emoji = "\uD83D\uDCAC", text = stringResource(R.string.tip_answer_questions) ) ActionTip( emoji = "\u23E9", text = stringResource(R.string.tip_game_speed) ) } Button( onClick = onContinue, modifier = Modifier .fillMaxWidth() .height(AppSpacing.buttonHeight), shape = RoundedCornerShape(AppSpacing.cornerRadius), colors = ButtonDefaults.buttonColors(containerColor = AppColors.primary) ) { Text( text = stringResource(R.string.lets_start), style = AppTypography.headline, color = Color.White ) } Spacer(modifier = Modifier.height(AppSpacing.lg)) } } @Composable private fun ActionTip( emoji: String, text: String ) { Row( modifier = Modifier .fillMaxWidth() .clip(RoundedCornerShape(AppSpacing.cornerRadius)) .background(AppColors.surfaceElevated) .padding(AppSpacing.md), verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.spacedBy(AppSpacing.md) ) { Text( text = emoji, style = AppTypography.title ) Text( text = text, style = AppTypography.body, color = AppColors.primaryText ) } } /** * Completion step of onboarding */ @Composable fun OnboardingCompletionScreen( onComplete: () -> Unit ) { @Suppress("UNUSED_VARIABLE") var showConfetti by remember { mutableStateOf(true) } LaunchedEffect(Unit) { delay(3000) showConfetti = false } Column( modifier = Modifier .fillMaxSize() .background(AppColors.background) .padding(AppSpacing.lg), horizontalAlignment = Alignment.CenterHorizontally, verticalArrangement = Arrangement.Center ) { Box( modifier = Modifier .size(120.dp) .clip(CircleShape) .background(AppColors.success.copy(alpha = 0.2f)), contentAlignment = Alignment.Center ) { Icon( imageVector = Icons.Default.Celebration, contentDescription = null, tint = AppColors.success, modifier = Modifier.size(60.dp) ) } Spacer(modifier = Modifier.height(AppSpacing.lg)) Text( text = stringResource(R.string.youre_ready), style = AppTypography.title, color = AppColors.primaryText ) Spacer(modifier = Modifier.height(AppSpacing.sm)) Text( text = stringResource(R.string.ready_description), style = AppTypography.body, color = AppColors.secondaryText, textAlign = TextAlign.Center ) Spacer(modifier = Modifier.height(AppSpacing.xxl)) Button( onClick = onComplete, modifier = Modifier .fillMaxWidth() .height(AppSpacing.buttonHeight), shape = RoundedCornerShape(AppSpacing.cornerRadius), colors = ButtonDefaults.buttonColors(containerColor = AppColors.primary) ) { Text( text = stringResource(R.string.begin_my_life), style = AppTypography.headline, color = Color.White ) } } }