diff --git a/challenge/data/src/main/kotlin/com/ruleup/challenge/data/dto/ChallengeCommonResponse.kt b/challenge/data/src/main/kotlin/com/ruleup/challenge/data/dto/ChallengeCommonResponse.kt index 8019bf9d..c12cc9ac 100644 --- a/challenge/data/src/main/kotlin/com/ruleup/challenge/data/dto/ChallengeCommonResponse.kt +++ b/challenge/data/src/main/kotlin/com/ruleup/challenge/data/dto/ChallengeCommonResponse.kt @@ -55,7 +55,7 @@ internal fun PenaltiesResponse?.toDomain(): ChallengePenalties = watcher = this?.watcher ?: false, ) -/** 인증 `{ type, method, detail, requiredPermissions }`. */ +/** 인증 `{ type, method, detail, requiredPermissions, guide }`. */ @Serializable data class VerificationResponse( @SerialName("type") @@ -67,6 +67,8 @@ data class VerificationResponse( val detail: String? = null, @SerialName("requiredPermissions") val requiredPermissions: List? = null, + @SerialName("guide") + val guide: String? = null, ) /** 미지의 method 는 [VerificationMethod.SELF_CHECK] 로 떨어뜨린다 */ @@ -79,6 +81,7 @@ internal fun VerificationResponse?.toDomain(): VerificationConfig { method = method, detail = this?.detail, requiredPermissions = this?.requiredPermissions.orEmpty(), + guide = this?.guide, ) } diff --git a/challenge/data/src/test/kotlin/com/ruleup/challenge/data/dto/ChallengeDetailMappingTest.kt b/challenge/data/src/test/kotlin/com/ruleup/challenge/data/dto/ChallengeDetailMappingTest.kt index eeb9e350..84e6c0cd 100644 --- a/challenge/data/src/test/kotlin/com/ruleup/challenge/data/dto/ChallengeDetailMappingTest.kt +++ b/challenge/data/src/test/kotlin/com/ruleup/challenge/data/dto/ChallengeDetailMappingTest.kt @@ -22,4 +22,17 @@ class ChallengeDetailMappingTest { assertNull(ChallengeDetailResponse(challengeId = "c1", weeklyCount = 0).toDomain().weeklyCount) assertNull(ChallengeDetailResponse(challengeId = "c1", weeklyCount = 8).toDomain().weeklyCount) } + + @Test + fun `인증 방법 안내를 그대로 옮긴다`() { + val response = + ChallengeDetailResponse(challengeId = "c1", verification = VerificationResponse(guide = "매일 10,000걸음 이상 걸으면 자동 인증됩니다.")) + assertEquals("매일 10,000걸음 이상 걸으면 자동 인증됩니다.", response.toDomain().verification.guide) + } + + @Test + fun `인증 방법 안내가 아직 없으면 비워 둔다`() { + // 서버가 채우는 중이다. 화면이 「아직 입력중입니다.」로 가른다. + assertNull(ChallengeDetailResponse(challengeId = "c1", verification = VerificationResponse()).toDomain().verification.guide) + } } diff --git a/challenge/domain/src/main/kotlin/com/ruleup/challenge/domain/entity/RoutineVerification.kt b/challenge/domain/src/main/kotlin/com/ruleup/challenge/domain/entity/RoutineVerification.kt index a8a837ea..43205f80 100644 --- a/challenge/domain/src/main/kotlin/com/ruleup/challenge/domain/entity/RoutineVerification.kt +++ b/challenge/domain/src/main/kotlin/com/ruleup/challenge/domain/entity/RoutineVerification.kt @@ -58,6 +58,8 @@ data class VerificationConfig( // 표시 문구(예: "기상 06:00 ±10분 내 10걸음"). val detail: String? = null, val requiredPermissions: List = emptyList(), + // 인증 방법 안내. 생성 직후·빈도·목표값·인증 방식 변경 직후에는 서버가 채우는 중이라 null 이다. + val guide: String? = null, ) /** 목표값 입력 종류 */ diff --git a/challenge/presentation/src/main/kotlin/com/ruleup/challenge/presentation/common/VerificationGuideText.kt b/challenge/presentation/src/main/kotlin/com/ruleup/challenge/presentation/common/VerificationGuideText.kt new file mode 100644 index 00000000..20f87b60 --- /dev/null +++ b/challenge/presentation/src/main/kotlin/com/ruleup/challenge/presentation/common/VerificationGuideText.kt @@ -0,0 +1,20 @@ +package com.ruleup.challenge.presentation.common + +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import com.ruleup.designsystem.theme.RuleUpTheme + +/** 인증 방법 안내(서버가 준 verification.guide). 서버가 아직 채우는 중이면 그렇다고 알린다. */ +@Composable +internal fun VerificationGuideText( + guide: String?, + modifier: Modifier = Modifier, +) { + Text( + text = guide ?: "아직 입력중입니다.", + color = if (guide != null) RuleUpTheme.colors.textSlate else RuleUpTheme.colors.textMuted, + style = RuleUpTheme.typography.body, + modifier = modifier, + ) +} diff --git a/challenge/presentation/src/main/kotlin/com/ruleup/challenge/presentation/detail/component/DetailInfoPage.kt b/challenge/presentation/src/main/kotlin/com/ruleup/challenge/presentation/detail/component/DetailInfoPage.kt index a0941ad6..18752afb 100644 --- a/challenge/presentation/src/main/kotlin/com/ruleup/challenge/presentation/detail/component/DetailInfoPage.kt +++ b/challenge/presentation/src/main/kotlin/com/ruleup/challenge/presentation/detail/component/DetailInfoPage.kt @@ -28,6 +28,7 @@ import com.ruleup.challenge.domain.entity.ChallengeDetail import com.ruleup.challenge.domain.entity.ChallengeLimits import com.ruleup.challenge.domain.entity.JoinNote import com.ruleup.challenge.presentation.common.RequiredPermissionList +import com.ruleup.challenge.presentation.common.VerificationGuideText import com.ruleup.challenge.presentation.common.capacityLabel import com.ruleup.challenge.presentation.create.label import com.ruleup.designsystem.component.RuleUpCard @@ -108,6 +109,7 @@ internal fun DetailInfoPage( detail.verification.detail?.let { Text(text = it, color = RuleUpTheme.colors.textSlate, style = RuleUpTheme.typography.body) } + VerificationGuideText(guide = detail.verification.guide) // 가입 전에 어떤 권한을 내줘야 하는지 알게 한다 RequiredPermissionList(tokens = requiredPermissions, snapshot = permissions) } diff --git a/challenge/presentation/src/main/kotlin/com/ruleup/challenge/presentation/detail/component/RoomInfoTab.kt b/challenge/presentation/src/main/kotlin/com/ruleup/challenge/presentation/detail/component/RoomInfoTab.kt index a9e003fd..7a9e247f 100644 --- a/challenge/presentation/src/main/kotlin/com/ruleup/challenge/presentation/detail/component/RoomInfoTab.kt +++ b/challenge/presentation/src/main/kotlin/com/ruleup/challenge/presentation/detail/component/RoomInfoTab.kt @@ -33,6 +33,7 @@ import com.ruleup.challenge.domain.entity.ChallengeRoom import com.ruleup.challenge.domain.entity.OwnerType import com.ruleup.challenge.domain.entity.TodayVerificationStatus import com.ruleup.challenge.presentation.common.RequiredPermissionList +import com.ruleup.challenge.presentation.common.VerificationGuideText import com.ruleup.challenge.presentation.common.capacityLabel import com.ruleup.designsystem.component.RuleUpCard import com.ruleup.designsystem.component.StatusChip @@ -423,6 +424,7 @@ internal fun VerificationRuleCard( color = RuleUpTheme.colors.textSlate, style = RuleUpTheme.typography.body, ) + VerificationGuideText(guide = detail.verification.guide) RequiredPermissionList(tokens = requiredPermissions, snapshot = permissions) } }