diff --git a/app/src/main/java/com/paw/key/presentation/ui/dbti/StartScreen.kt b/app/src/main/java/com/paw/key/presentation/ui/dbti/StartScreen.kt new file mode 100644 index 00000000..b2e42957 --- /dev/null +++ b/app/src/main/java/com/paw/key/presentation/ui/dbti/StartScreen.kt @@ -0,0 +1,158 @@ +package com.paw.key.presentation.ui.dbti + +import androidx.compose.foundation.Image +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.* +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material3.Button +import androidx.compose.material3.ButtonDefaults +import androidx.compose.material3.Text +import androidx.compose.material3.TextButton +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.layout.ContentScale +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import com.paw.key.R +import com.paw.key.core.designsystem.component.TopBar +import com.paw.key.core.designsystem.theme.PawKeyTheme + +@Composable +fun StartScreen( + navigateUp: () -> Unit, + navigateToTest: () -> Unit, + showSkipButton: Boolean = false, + onSkip: (() -> Unit)? = null, + modifier: Modifier = Modifier, +) { + Box(modifier = modifier.fillMaxSize()) { + // 이미지를 배경으로 + Image( + painter = painterResource(id = R.drawable.doki_welcome), + contentDescription = null, + modifier = Modifier.fillMaxSize(), + contentScale = ContentScale.Crop + ) + + Column( + modifier = modifier + .fillMaxSize() + ) { + TopBar( + title = "DBTI 검사", + onBackClick = navigateUp, + isBackVisible = true + ) + + Column( + modifier = Modifier + .fillMaxSize() + .padding(horizontal = 24.dp), + horizontalAlignment = Alignment.Start + ) { + Spacer(modifier = Modifier.height(40.dp)) + + Text( + text = "반려견 성향을 알아보는\nDBTI 성격 유형 검사", + fontSize = 24.sp, + fontWeight = FontWeight.Bold, + color = PawKeyTheme.colors.contents, + textAlign = TextAlign.Start, + lineHeight = 32.sp, + style = PawKeyTheme.typography.header1 + ) + + Spacer(modifier = Modifier.height(4.dp)) + + Text( + text = "본 조사는 사랑하는 반려견 위한 비정식 테스트입니다.", + fontSize = 14.sp, + color = PawKeyTheme.colors.defaultDark, + textAlign = TextAlign.Center, + style = PawKeyTheme.typography.body14R + ) + + Spacer(modifier = Modifier.weight(1f)) + +// Image( +// painter = painterResource(id = R.drawable.doki_welcome), +// contentDescription = "DOKI 캐릭터", +// modifier = Modifier +// .fillMaxSize(), // 전체 화면 차지 +// contentScale = ContentScale.Crop +// ) + + Spacer(modifier = Modifier.weight(1f)) + + // 조건부 건너뛰기 + if (showSkipButton && onSkip != null) { + TextButton( + onClick = onSkip, + modifier = Modifier.fillMaxWidth() + ) { + Text( + text = "건너뛰기", + color = PawKeyTheme.colors.defaultMiddle, + style = PawKeyTheme.typography.subTitle + ) + } + + Spacer(modifier = Modifier.height(8.dp)) + } + + Button( + onClick = navigateToTest, + modifier = Modifier + .fillMaxWidth() + .height(56.dp), + colors = ButtonDefaults.buttonColors( + containerColor = PawKeyTheme.colors.primary + ), + shape = RoundedCornerShape(12.dp) + ) { + Text( + text = "시작하기", + fontWeight = FontWeight.SemiBold, + color = PawKeyTheme.colors.background, + style = PawKeyTheme.typography.mainButtonActive + ) + } + + Spacer(modifier = Modifier.height(24.dp)) + } + } + } +} + +@Preview(showBackground = true) +@Composable +private fun StartScreenWithSkipPreview() { + PawKeyTheme { + // 회원가입에서 진입 (건너뛰기 있음) + StartScreen( + navigateUp = {}, + navigateToTest = {}, + showSkipButton = true, + onSkip = {} + ) + } +} + +@Preview(showBackground = true) +@Composable +private fun StartScreenNoSkipPreview() { + PawKeyTheme { + // 마이페이지에서 진입 (건너뛰기 없음) + StartScreen( + navigateUp = {}, + navigateToTest = {}, + showSkipButton = false, + onSkip = null + ) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/paw/key/presentation/ui/dbti/result/ResultScreen.kt b/app/src/main/java/com/paw/key/presentation/ui/dbti/result/ResultScreen.kt new file mode 100644 index 00000000..1f60c314 --- /dev/null +++ b/app/src/main/java/com/paw/key/presentation/ui/dbti/result/ResultScreen.kt @@ -0,0 +1,119 @@ +package com.paw.key.presentation.ui.dbti.result + +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.* +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import com.paw.key.core.designsystem.component.DokiButton +import com.paw.key.core.designsystem.component.TopBar +import com.paw.key.core.designsystem.theme.PawKeyTheme +import com.paw.key.presentation.ui.dbti.result.component.ResultBox +import com.paw.key.presentation.ui.dbti.result.component.TraitAnalysis + +@Composable +fun ResultScreen( + type: String, + name: String, + imageUrl: String?, + keywords: List, + description: String, + analysis: List, + onRetakeTest: () -> Unit, + onGoHome: () -> Unit, + navigateUp: () -> Unit, + modifier: Modifier = Modifier, +) { + Column( + modifier = modifier + .fillMaxSize() + .background(PawKeyTheme.colors.defaultButton) + ) { + TopBar( + title = "DBTI 결과", + onBackClick = navigateUp, + isBackVisible = true + ) + + Column( + modifier = Modifier + .fillMaxSize() + .padding(horizontal = 16.dp), + horizontalAlignment = Alignment.CenterHorizontally + ) { + Spacer(modifier = Modifier.weight(20f)) + + ResultBox( + type = type, + name = name, + imageUrl = imageUrl, + keywords = keywords, + description = description, + analysis = analysis + ) + + Spacer(modifier = Modifier.weight(20f)) + + Row( + modifier = Modifier.fillMaxWidth(), + horizontalArrangement = Arrangement.spacedBy(12.dp) + ) { + DokiButton( + text = "다시 테스트하기", + onClick = onRetakeTest, + modifier = Modifier.weight(1f), + enabled = true + // TODO: 버튼 바꾸기 + ) + + DokiButton( + text = "홈으로 가기", + onClick = onGoHome, + modifier = Modifier.weight(1f), + enabled = true + ) + } + + Spacer(modifier = Modifier.height(24.dp)) + } + } +} + +@Preview(showBackground = true) +@Composable +private fun ResultScreenPreview() { + PawKeyTheme { + ResultScreen( + type = "EPR", + name = "탐험대장 멍멍이", + imageUrl = null, + keywords = listOf("모험", "활발", "사교성"), + description = "활발하고 친구들과 어울리며 모험을 좋아해요.\n집사에게 언제나 애너지를 주는 타입!", + analysis = listOf( + TraitAnalysis( + leftLabel = "휴식가", + rightLabel = "탐험가", + dominantSide = "right", + score = 2 + ), + TraitAnalysis( + leftLabel = "부끄멍", + rightLabel = "적극멍", + dominantSide = "right", + score = 2 + ), + TraitAnalysis( + leftLabel = "루틴러", + rightLabel = "자유러", + dominantSide = "left", + score = 2 + ) + ), + onRetakeTest = {}, + onGoHome = {}, + navigateUp = {} + ) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/paw/key/presentation/ui/dbti/result/component/CharacterChip.kt b/app/src/main/java/com/paw/key/presentation/ui/dbti/result/component/CharacterChip.kt new file mode 100644 index 00000000..d75634de --- /dev/null +++ b/app/src/main/java/com/paw/key/presentation/ui/dbti/result/component/CharacterChip.kt @@ -0,0 +1,42 @@ +package com.paw.key.presentation.ui.dbti.result.component + +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material3.Surface +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import com.paw.key.core.designsystem.theme.PawKeyTheme + +@Composable +fun CharacterChip( + text: String, + modifier: Modifier = Modifier, +) { + Surface( + modifier = modifier, + color = PawKeyTheme.colors.primaryGra1, + shape = RoundedCornerShape(8.dp) + ) { + Text( + text = text, + fontSize = 12.sp, + fontWeight = FontWeight.Medium, + color = PawKeyTheme.colors.primary, + style = PawKeyTheme.typography.subButtonActive, + modifier = Modifier.padding(8.dp) + ) + } +} + +@Preview(showBackground = true) +@Composable +private fun CharacterChipPreview() { + PawKeyTheme { + CharacterChip(text = "# Character") + } +} \ No newline at end of file diff --git a/app/src/main/java/com/paw/key/presentation/ui/dbti/result/component/ResultBox.kt b/app/src/main/java/com/paw/key/presentation/ui/dbti/result/component/ResultBox.kt new file mode 100644 index 00000000..d36ad828 --- /dev/null +++ b/app/src/main/java/com/paw/key/presentation/ui/dbti/result/component/ResultBox.kt @@ -0,0 +1,185 @@ +package com.paw.key.presentation.ui.dbti.result.component + +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.* +import androidx.compose.foundation.shape.RoundedCornerShape +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.layout.ContentScale +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import coil.compose.AsyncImage +import coil.request.ImageRequest +import com.paw.key.core.designsystem.theme.PawKeyTheme + +// TraitAnalysis 데이터 클래스 정의 +data class TraitAnalysis( + val leftLabel: String, + val rightLabel: String, + val dominantSide: String, + val score: Int +) + +@Composable +fun ResultBox( + type: String, + name: String, + imageUrl: String?, + keywords: List, + description: String, + analysis: List, + modifier: Modifier = Modifier, +) { + Surface( + modifier = modifier.fillMaxWidth(), + color = PawKeyTheme.colors.background, + shape = RoundedCornerShape(8.dp) + ) { + Column( + modifier = Modifier + .fillMaxWidth() + .padding(vertical = 32.dp), + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.spacedBy(20.dp) + ) { + Column( + modifier = Modifier.width(210.dp), + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.spacedBy(16.dp) + ) { + Text( + text = "내 강아지의 성향은", + fontSize = 14.sp, + fontWeight = FontWeight.Medium, + color = PawKeyTheme.colors.defaultDark, + textAlign = TextAlign.Center, + style = PawKeyTheme.typography.body14M, + modifier = Modifier.fillMaxWidth() + ) + + Column( + modifier = Modifier.fillMaxWidth(), + horizontalAlignment = Alignment.CenterHorizontally + ) { + Text( + text = name, + fontSize = 24.sp, + fontWeight = FontWeight.Bold, + color = PawKeyTheme.colors.contents, + letterSpacing = (-0.48).sp, + textAlign = TextAlign.Center, + style = PawKeyTheme.typography.header1 + ) + Text( + text = type, + fontSize = 28.sp, + fontWeight = FontWeight.Bold, + color = PawKeyTheme.colors.primary, + letterSpacing = (-0.56).sp, + textAlign = TextAlign.Center, + style = PawKeyTheme.typography.header1 + ) + } + } + Column( + modifier = Modifier.fillMaxWidth(), + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.spacedBy(24.dp) + ) { + if (imageUrl != null) { + AsyncImage( + model = ImageRequest.Builder(LocalContext.current) + .data(imageUrl) + .crossfade(true) + .build(), + contentDescription = null, + modifier = Modifier.size(150.dp), + contentScale = ContentScale.Crop + ) + } else { + Box( + modifier = Modifier + .size(150.dp) + .background(PawKeyTheme.colors.defaultButton) + ) + } + + Row( + horizontalArrangement = Arrangement.spacedBy(8.dp, Alignment.CenterHorizontally), + modifier = Modifier.fillMaxWidth() + ) { + keywords.forEach { keyword -> + CharacterChip(text = "# $keyword") + } + } + + Text( + text = description, + fontSize = 14.sp, + fontWeight = FontWeight.Medium, + color = PawKeyTheme.colors.contents, + textAlign = TextAlign.Center, + style = PawKeyTheme.typography.body14M, + modifier = Modifier + .fillMaxWidth() + .padding(horizontal = 28.dp) + ) + } + + Column( + modifier = Modifier.fillMaxWidth(), + verticalArrangement = Arrangement.spacedBy(16.dp) + ) { + analysis.forEach { trait -> + TraitBar( + leftLabel = trait.leftLabel, + rightLabel = trait.rightLabel, + dominantSide = trait.dominantSide, + score = trait.score + ) + } + } + } + } +} + +@Preview(showBackground = true) +@Composable +private fun ResultBoxPreview() { + PawKeyTheme { + ResultBox( + type = "ISF", + name = "온순한 방구석멍", + imageUrl = null, + keywords = listOf("차분", "다소 활발", "탐험"), + description = "내향적이고 온순하며 자유로운 흐름 속에서 소소한 행복을 찾습니다.", + analysis = listOf( + TraitAnalysis( + leftLabel = "탐험가", + rightLabel = "휴식가", + dominantSide = "right", + score = 2 + ), + TraitAnalysis( + leftLabel = "인싸싸", + rightLabel = "독고다", + dominantSide = "left", + score = 3 + ), + TraitAnalysis( + leftLabel = "루틴러", + rightLabel = "자유러", + dominantSide = "right", + score = 2 + ) + ) + ) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/paw/key/presentation/ui/dbti/result/component/TraitBar.kt b/app/src/main/java/com/paw/key/presentation/ui/dbti/result/component/TraitBar.kt new file mode 100644 index 00000000..2d5d9f83 --- /dev/null +++ b/app/src/main/java/com/paw/key/presentation/ui/dbti/result/component/TraitBar.kt @@ -0,0 +1,130 @@ +package com.paw.key.presentation.ui.dbti.result.component + +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.* +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import com.paw.key.core.designsystem.theme.PawKeyTheme + +@Composable +fun TraitBar( + leftLabel: String, + rightLabel: String, + dominantSide: String, // "left" 또는 "right" + score: Int, // 1, 2, 3 + modifier: Modifier = Modifier, +) { + Row( + modifier = modifier.fillMaxWidth(), + horizontalArrangement = Arrangement.spacedBy(16.dp, Alignment.CenterHorizontally), + verticalAlignment = Alignment.CenterVertically + ) { + Text( + text = leftLabel, + fontSize = 14.sp, + fontWeight = FontWeight.SemiBold, + color = PawKeyTheme.colors.contents, + textAlign = TextAlign.Center, + style = PawKeyTheme.typography.body14Sb, + modifier = Modifier.width(40.dp) + ) + + TraitBlocks( + dominantSide = dominantSide, + score = score + ) + + Text( + text = rightLabel, + fontSize = 14.sp, + fontWeight = FontWeight.Normal, + color = PawKeyTheme.colors.defaultMiddle, + textAlign = TextAlign.Center, + style = PawKeyTheme.typography.body14R, + modifier = Modifier.width(40.dp) + ) + } +} + +@Composable +private fun TraitBlocks( + dominantSide: String, + score: Int, + modifier: Modifier = Modifier, +) { + val activeColor = PawKeyTheme.colors.primaryGra5 + val inactiveColor = PawKeyTheme.colors.defaultButton + + // dominantSide와 score에 따라 블록 색상 결정 + val (first, second, third) = when { + dominantSide == "left" && score == 3 -> Triple(activeColor, activeColor, activeColor) + dominantSide == "left" && score == 2 -> Triple(activeColor, activeColor, inactiveColor) + dominantSide == "left" && score == 1 -> Triple(activeColor, inactiveColor, inactiveColor) + dominantSide == "right" && score == 3 -> Triple(activeColor, activeColor, activeColor) + dominantSide == "right" && score == 2 -> Triple(inactiveColor, activeColor, activeColor) + dominantSide == "right" && score == 1 -> Triple(inactiveColor, inactiveColor, activeColor) + else -> Triple(inactiveColor, inactiveColor, inactiveColor) // 기본값 + } + + Row( + modifier = modifier.width(175.dp), + horizontalArrangement = Arrangement.spacedBy(2.dp) + ) { + Box( + modifier = Modifier + .weight(1f) + .height(10.dp) + .background(first, RoundedCornerShape(4.dp)) + ) + Box( + modifier = Modifier + .weight(1f) + .height(10.dp) + .background(second, RoundedCornerShape(4.dp)) + ) + Box( + modifier = Modifier + .weight(1f) + .height(10.dp) + .background(third, RoundedCornerShape(4.dp)) + ) + } +} + +@Preview(showBackground = true) +@Composable +private fun TraitBarPreview() { + PawKeyTheme { + Column( + modifier = Modifier.padding(16.dp), + verticalArrangement = Arrangement.spacedBy(16.dp) + ) { + TraitBar( + leftLabel = "탐험가", + rightLabel = "휴식가", + dominantSide = "right", + score = 2 + ) + TraitBar( + leftLabel = "인싸싸", + rightLabel = "독고다", + dominantSide = "left", + score = 3 + ) + TraitBar( + leftLabel = "루틴러", + rightLabel = "자유러", + dominantSide = "right", + score = 2 + ) + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/paw/key/presentation/ui/dbti/test/TestScreen.kt b/app/src/main/java/com/paw/key/presentation/ui/dbti/test/TestScreen.kt new file mode 100644 index 00000000..851ec501 --- /dev/null +++ b/app/src/main/java/com/paw/key/presentation/ui/dbti/test/TestScreen.kt @@ -0,0 +1,137 @@ +package com.paw.key.presentation.ui.dbti.test + +import androidx.compose.foundation.layout.* +import androidx.compose.runtime.* +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import androidx.compose.material3.Text +import com.paw.key.core.designsystem.component.DogkyButton +import com.paw.key.core.designsystem.component.TopBar +import com.paw.key.core.designsystem.theme.PawKeyTheme +import com.paw.key.presentation.ui.dbti.component.SelectCard + + +data class TestOption( + val id: Int, + val topText: String, + val bottomText: String, + val imageUrl: String? = null +) + +@Composable +fun TestScreen( + categoryName: String, + questionText: String, + options: List, + onBackClick: () -> Unit, + onNextClick: () -> Unit, + modifier: Modifier = Modifier, +) { + var selectedOptionId by remember { mutableStateOf(null) } + + Box(modifier = modifier.fillMaxSize()) { + Column(modifier = Modifier.fillMaxSize()) { + TopBar( + title = "프로필 설정", + onBackClick = onBackClick, + isBackVisible = true + ) + + Column( + modifier = Modifier + .fillMaxSize() + .padding(horizontal = 24.dp) + ) { + Spacer(modifier = Modifier.weight(67f)) // TopBar ↔ 텍스트 + + Column( + horizontalAlignment = Alignment.CenterHorizontally + ) { + Text( + text = categoryName, + fontWeight = FontWeight.SemiBold, + color = PawKeyTheme.colors.primary, + style = PawKeyTheme.typography.bodyActive + ) + + Spacer(modifier = Modifier.height(16.dp)) + + Text( + text = questionText, + color = PawKeyTheme.colors.contents, + textAlign = TextAlign.Center, + lineHeight = 28.sp, + style = PawKeyTheme.typography.header3, + modifier = Modifier.fillMaxWidth() + ) + } + + Spacer(modifier = Modifier.weight(30f)) + + Spacer(modifier = Modifier.weight(219.31f)) + + Spacer(modifier = Modifier.weight(1f)) + + DogkyButton( + text = "다음으로", + onClick = onNextClick, + enabled = selectedOptionId != null, + modifier = Modifier.fillMaxWidth() + ) + + Spacer(modifier = Modifier.height(34.dp)) + } + } + + Row( + modifier = Modifier + .fillMaxWidth() + .align(Alignment.CenterStart) + .padding(horizontal = 24.dp), + horizontalArrangement = Arrangement.spacedBy(12.dp) + ) { + options.forEach { option -> + SelectCard( + imageUrl = option.imageUrl, + topText = option.topText, + bottomText = option.bottomText, + isSelected = selectedOptionId == option.id, + onClick = { selectedOptionId = option.id }, + modifier = Modifier.weight(1f) + ) + } + } + } +} + +@Preview(showBackground = true) +@Composable +private fun TestScreenPreview() { + PawKeyTheme { + TestScreen( + categoryName = "부끄멍 vs 적극멍", + questionText = "산책 중 다른 강아지를 만나면\n우리 강아지는...", + options = listOf( + TestOption( + id = 1, + topText = "잠깐 눈치만 보고", + bottomText = "거리를 유지해요", + imageUrl = null + ), + TestOption( + id = 2, + topText = "먼저 다가가서", + bottomText = "인사하고 놀자고 해요", + imageUrl = null + ) + ), + onBackClick = {}, + onNextClick = {} + ) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/paw/key/presentation/ui/dbti/test/component/SelectCard.kt b/app/src/main/java/com/paw/key/presentation/ui/dbti/test/component/SelectCard.kt new file mode 100644 index 00000000..f4413225 --- /dev/null +++ b/app/src/main/java/com/paw/key/presentation/ui/dbti/test/component/SelectCard.kt @@ -0,0 +1,137 @@ +package com.paw.key.presentation.ui.dbti.component + +import androidx.compose.foundation.background +import androidx.compose.foundation.border +import androidx.compose.foundation.layout.* +import androidx.compose.foundation.shape.RoundedCornerShape +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.graphics.Color +import androidx.compose.ui.layout.ContentScale +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import coil.compose.AsyncImage +import coil.request.ImageRequest +import com.paw.key.core.designsystem.theme.PawKeyTheme +import com.paw.key.core.extension.noRippleClickable + +@Composable +fun SelectCard( + imageUrl: String?, + topText: String, + bottomText: String, + isSelected: Boolean = false, + onClick: () -> Unit, + modifier: Modifier = Modifier, +) { + val backgroundColor = if (isSelected) { + PawKeyTheme.colors.opacity5Primary + } else { + Color.Transparent + } + + val borderColor = if (isSelected) { + PawKeyTheme.colors.primary + } else { + PawKeyTheme.colors.defaultMiddle + } + + val textColor = if (isSelected) { + PawKeyTheme.colors.primary + } else { + PawKeyTheme.colors.contents + } + + val textStyle = if (isSelected) { + PawKeyTheme.typography.bodyActive + } else { + PawKeyTheme.typography.bodyDefault + } + + Column( + modifier = modifier + .aspectRatio(159.5f / 219.31f) // 비율로 크기 조정 + .clip(RoundedCornerShape(8.dp)) + .background(backgroundColor) + .border( + width = 1.dp, + color = borderColor, + shape = RoundedCornerShape(8.dp) + ) + .noRippleClickable(onClick = onClick) + .padding(horizontal = 16.dp, vertical = 20.dp), + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.spacedBy(12.dp, Alignment.CenterVertically) + ) { + AsyncImage( + model = ImageRequest.Builder(LocalContext.current) + .data(imageUrl) + .crossfade(true) + .build(), + contentDescription = null, + modifier = Modifier + .size(90.dp) + .clip(RoundedCornerShape(8.dp)), + contentScale = ContentScale.Crop + ) + + Column( + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.Center + ) { + Text( + text = topText, + color = textColor, + style = textStyle, + textAlign = TextAlign.Center, + maxLines = 1, + modifier = Modifier.fillMaxWidth() + ) + + Spacer(modifier = Modifier.height(2.dp)) + + Text( + text = bottomText, + color = textColor, + style = textStyle, + textAlign = TextAlign.Center, + maxLines = 1, + modifier = Modifier.fillMaxWidth() + ) + } + } +} + +@Preview(showBackground = true, backgroundColor = 0xFFF5F5F5) +@Composable +private fun SelectionCardPreview() { + PawKeyTheme { + Row( + modifier = Modifier.padding(16.dp), + horizontalArrangement = Arrangement.spacedBy(16.dp) + ) { + SelectCard( + imageUrl = null, + topText = "잠깐 눈치만 보고", + bottomText = "거리를 유지해요", + isSelected = false, + onClick = {}, + modifier = Modifier.weight(1f) + ) + + SelectCard( + imageUrl = null, + topText = "먼저 다가가서", + bottomText = "인사하고 놀자고 해요", + isSelected = true, + onClick = {}, + modifier = Modifier.weight(1f) + ) + } + } +} \ No newline at end of file diff --git a/app/src/main/res/drawable/doki_welcome.png b/app/src/main/res/drawable/doki_welcome.png new file mode 100644 index 00000000..e58c6ba0 Binary files /dev/null and b/app/src/main/res/drawable/doki_welcome.png differ diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 6fc3e5fb..7d4f6a4b 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -8,7 +8,7 @@ versionCode = "1" versionName = "1.0.0" # Kotlin -agp = "8.9.1" +agp = "8.13.2" kotlin = "2.0.0" kotlinxImmutable = "0.3.7" kotlinxSerializationJson = "1.6.3" diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 63fab2f7..7d306342 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ #Fri Jun 20 02:14:50 KST 2025 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.11.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.13-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists