Skip to content

Commit

Permalink
Merge pull request #27 from YAPP-Github/feature/tgyuu/PC-300
Browse files Browse the repository at this point in the history
[PC-300] 약관 디테일 화면 구현
  • Loading branch information
tgyuuAn authored Jan 8, 2025
2 parents dba8062 + b4e3fb0 commit abeb37a
Show file tree
Hide file tree
Showing 26 changed files with 210 additions and 90 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinCompile

internal fun Project.configureKotlinAndroid() {
pluginManager.apply("org.jetbrains.kotlin.android")
pluginManager.apply("org.jetbrains.kotlin.plugin.serialization")

androidExtension.apply {
compileSdk = 35
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import org.gradle.kotlin.dsl.dependencies
internal fun Project.configureAndroidCompose() {
with(plugins) {
apply("org.jetbrains.kotlin.plugin.compose")
apply("org.jetbrains.kotlin.plugin.serialization")
}

val libs = extensions.libs
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,23 +17,23 @@ class TermsRepositoryImpl @Inject constructor(
val terms = termDataSource.loadTerms()
.getOrThrow()
.toDomain()
.filter { it.termId != UNKNOWN_INT }
.filter { it.id != UNKNOWN_INT }

val termsEntity = terms.map {
TermEntity(
id = it.termId,
id = it.id,
title = it.title,
content = it.content,
required = it.required,
startDate = it.startDate,
)
}

localTermDataSource.clearAndInsertTerms(termsEntity)
localTermDataSource.replaceTerms(termsEntity)
}

override suspend fun getTerms(): Result<List<Term>> = suspendRunCatching {
localTermDataSource.getTerms()
override suspend fun getTerms(): Result<List<Term>> = runCatching {
localTermDataSource.retrieveTerms()
.map(TermEntity::toDomain)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -48,15 +48,15 @@ class TermsRepositoryImplTest {

coEvery { termDataSource.loadTerms() } returns
Result.success(LoadTermsResponse(listOf(invalidTerm, validTerm)))
coEvery { localTermDataSource.clearAndInsertTerms(any()) } just Runs
coEvery { localTermDataSource.replaceTerms(any()) } just Runs

// when
val result = termsRepository.loadTerms()

// then
assertTrue(result.isSuccess)
coVerify(exactly = 1) {
localTermDataSource.clearAndInsertTerms(
localTermDataSource.replaceTerms(
match {
it.size == 1 && it.first().id == validTerm.termId
}
Expand Down Expand Up @@ -85,14 +85,14 @@ class TermsRepositoryImplTest {
)

coEvery { termDataSource.loadTerms() } returns Result.success(LoadTermsResponse(validTerms))
coEvery { localTermDataSource.clearAndInsertTerms(any()) } just Runs
coEvery { localTermDataSource.replaceTerms(any()) } just Runs

// when
termsRepository.loadTerms()

// then
coVerify(exactly = 1) {
localTermDataSource.clearAndInsertTerms(
localTermDataSource.replaceTerms(
match {
it.size == validTerms.size && it.all { entity ->
validTerms.any { term ->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ class TermsDaoTest {
val expected = listOf(
TermEntity(2, "새로운 약관", "새로운 내용", false, "2024-06-01T00:00:00".parseDateTime())
)
termsDao.clearAndInsertTerms(*expected.toTypedArray())
termsDao.replaceTerms(*expected.toTypedArray())
val actual = termsDao.getTerms()

// then
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ interface TermsDao {
suspend fun clearTerms()

@Transaction
suspend fun clearAndInsertTerms(vararg terms: TermEntity) {
suspend fun replaceTerms(vararg terms: TermEntity) {
clearTerms()
insertTerms(*terms)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ data class TermEntity(
@ColumnInfo(name = "start_date") val startDate: LocalDateTime,
) {
fun toDomain() = Term(
termId = id,
id = id,
title = title,
content = content,
required = required,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import javax.inject.Singleton
class LocalTermDataSource @Inject constructor(
private val termsDao: TermsDao,
) {
suspend fun getTerms() = termsDao.getTerms()
suspend fun clearAndInsertTerms(terms: List<TermEntity>) =
termsDao.clearAndInsertTerms(*terms.toTypedArray())
suspend fun retrieveTerms() = termsDao.getTerms()
suspend fun replaceTerms(terms: List<TermEntity>) = termsDao.replaceTerms(*terms.toTypedArray())
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
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.material3.Text
Expand All @@ -30,7 +31,9 @@ fun PieceMainTopBar(
) {
Row(
verticalAlignment = Alignment.CenterVertically,
modifier = modifier,
modifier = modifier
.fillMaxWidth()
.height(60.dp),
) {
Text(
text = title,
Expand All @@ -54,7 +57,9 @@ fun PieceSubTopBar(
Row(
horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically,
modifier = modifier,
modifier = modifier
.fillMaxWidth()
.height(60.dp),
) {
Image(
painter = painterResource(R.drawable.ic_arrow_left),
Expand All @@ -78,7 +83,11 @@ fun PieceSubBackTopBar(
onBackClick: () -> Unit,
modifier: Modifier = Modifier,
) {
Box(modifier = modifier.fillMaxWidth()) {
Box(
modifier = modifier
.fillMaxWidth()
.height(60.dp),
) {
Image(
painter = painterResource(R.drawable.ic_arrow_left),
contentDescription = "뒤로 가기 버튼",
Expand All @@ -105,7 +114,11 @@ fun PieceSubCloseTopBar(
closeButtonEnabled: Boolean = true,
contentColor: Color = PieceTheme.colors.black,
) {
Box(modifier = modifier.fillMaxWidth()) {
Box(
modifier = modifier
.fillMaxWidth()
.height(60.dp),
) {
Text(
text = title,
style = PieceTheme.typography.headingSSB,
Expand Down Expand Up @@ -176,9 +189,7 @@ fun PreviewPieceSubTopBar() {
modifier = Modifier.size(32.dp),
)
},
modifier = Modifier
.fillMaxWidth()
.padding(vertical = 20.dp),
modifier = Modifier.padding(vertical = 20.dp),
)
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package com.puzzle.designsystem.component

import android.webkit.WebChromeClient
import android.webkit.WebView
import android.webkit.WebViewClient
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.viewinterop.AndroidView

@Composable
fun PieceWebView(
url: String,
modifier: Modifier = Modifier,
) {
val context = LocalContext.current
var webView by remember { mutableStateOf<WebView?>(null) }

AndroidView(
factory = {
webView = WebView(context).apply {
settings.javaScriptEnabled = true
webViewClient = object : WebViewClient() {}
webChromeClient = object : WebChromeClient() {}
}
webView!!
},
update = { it.loadUrl(url) },
onRelease = { webView?.destroy() },
modifier = modifier,
)
}
5 changes: 5 additions & 0 deletions core/designsystem/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!--Term-->
<string name="next">다음</string>
<string name="agree">동의하기</string>
<string name="all_term_agree">약관 전체 동의</string>

<!--Matching-->
<string name="matching_title">Matching</string>
<string name="check_the_matching_pieces">매칭 조각을 확인해주세요!</string>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package com.puzzle.domain.model.terms
import java.time.LocalDateTime

data class Term(
val termId: Int,
val id: Int,
val title: String,
val content: String,
val required: Boolean,
Expand Down
1 change: 1 addition & 0 deletions core/navigation/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
plugins {
id("piece.android.library")
alias(libs.plugins.kotlin.serialization)
}

android {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ data class TermResponse(
val startDate: String?,
) {
fun toDomain(): Term = Term(
termId = termId ?: UNKNOWN_INT,
id = termId ?: UNKNOWN_INT,
title = title ?: UNKNOWN_STRING,
content = content ?: UNKNOWN_STRING,
required = required ?: false,
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,15 @@ import androidx.compose.foundation.layout.Column
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.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.SpanStyle
import androidx.compose.ui.text.buildAnnotatedString
import androidx.compose.ui.text.withStyle
Expand All @@ -19,22 +22,36 @@ import com.airbnb.mvrx.compose.mavericksViewModel
import com.puzzle.auth.graph.registration.contract.RegistrationIntent
import com.puzzle.auth.graph.registration.contract.RegistrationSideEffect
import com.puzzle.auth.graph.registration.contract.RegistrationState
import com.puzzle.auth.graph.registration.ui.RegistrationDetailScreen
import com.puzzle.designsystem.R
import com.puzzle.designsystem.component.PieceCheckList
import com.puzzle.designsystem.component.PieceSolidButton
import com.puzzle.designsystem.component.PieceSubBackTopBar
import com.puzzle.designsystem.foundation.PieceTheme
import com.puzzle.domain.model.terms.Term
import com.puzzle.navigation.NavigationEvent

@Composable
internal fun RegistrationRoute(
viewModel: RegistrationViewModel = mavericksViewModel()
) {
val state by viewModel.collectAsState()
var selectedTerm by remember { mutableStateOf<Term?>(null) }

RegistrationScreen(
selectedTerm?.let { term ->
RegistrationDetailScreen(
term = term,
onBackClick = { selectedTerm = null },
onAgreeClick = {
viewModel.onIntent(RegistrationIntent.CheckTerm(term.id))
selectedTerm = null
}
)
} ?: RegistrationScreen(
state = state,
checkAllTerms = { viewModel.onIntent(RegistrationIntent.CheckAllTerms) },
checkTerm = { viewModel.onIntent(RegistrationIntent.CheckTerm(it)) },
showTermDetail = { selectedTerm = it },
navigate = { event -> viewModel.onSideEffect(RegistrationSideEffect.Navigate(event)) }
)
}
Expand All @@ -44,6 +61,7 @@ private fun RegistrationScreen(
state: RegistrationState,
checkAllTerms: () -> Unit,
checkTerm: (Int) -> Unit,
showTermDetail: (Term) -> Unit,
navigate: (NavigationEvent) -> Unit,
) {
Column(
Expand All @@ -54,7 +72,6 @@ private fun RegistrationScreen(
PieceSubBackTopBar(
title = "",
onBackClick = { navigate(NavigationEvent.NavigateUp) },
modifier = Modifier.height(60.dp),
)

Text(
Expand All @@ -80,21 +97,21 @@ private fun RegistrationScreen(

PieceCheckList(
checked = state.allTermsAgreed,
label = "약관 전체 동의",
label = stringResource(R.string.all_term_agree),
containerColor = PieceTheme.colors.light3,
onCheckedChange = checkAllTerms,
modifier = Modifier
.fillMaxWidth()
.padding(bottom = 12.dp),
)

state.terms.forEach { termInfo ->
state.terms.forEach { term ->
PieceCheckList(
checked = state.termsCheckedInfo.getOrDefault(termInfo.termId, false),
checked = state.termsCheckedInfo.getOrDefault(term.id, false),
arrowEnabled = true,
label = termInfo.title,
onCheckedChange = { checkTerm(termInfo.termId) },
onArrowClick = {},
label = term.title,
onCheckedChange = { checkTerm(term.id) },
onArrowClick = { showTermDetail(term) },
modifier = Modifier.fillMaxWidth(),
)
}
Expand All @@ -106,7 +123,7 @@ private fun RegistrationScreen(
)

PieceSolidButton(
label = "다음",
label = stringResource(R.string.next),
onClick = {},
modifier = Modifier
.fillMaxWidth()
Expand Down
Loading

0 comments on commit abeb37a

Please sign in to comment.