diff --git a/core/designsystem/src/main/res/drawable/ic_google_logo.xml b/core/designsystem/src/main/res/drawable/ic_google_logo.xml
new file mode 100644
index 00000000..55e2eeaf
--- /dev/null
+++ b/core/designsystem/src/main/res/drawable/ic_google_logo.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
diff --git a/data/onboarding/src/main/java/com/teamsolply/solply/onboarding/dto/request/PatchUserInfoRequestDto.kt b/data/onboarding/src/main/java/com/teamsolply/solply/onboarding/dto/request/PatchUserInfoRequestDto.kt
index c06efd1c..99121e84 100644
--- a/data/onboarding/src/main/java/com/teamsolply/solply/onboarding/dto/request/PatchUserInfoRequestDto.kt
+++ b/data/onboarding/src/main/java/com/teamsolply/solply/onboarding/dto/request/PatchUserInfoRequestDto.kt
@@ -8,12 +8,12 @@ data class PatchUserInfoRequestDto(
@SerialName("selectedTownId")
val selectedTownId: Long,
- @SerialName("favoriteTownIdList")
- val favoriteTownIdList: List,
-
@SerialName("persona")
val persona: String,
@SerialName("nickname")
- val nickname: String
+ val nickname: String,
+
+ @SerialName("policyAgreementInfos")
+ val policyAgreementInfos: List
)
diff --git a/data/onboarding/src/main/java/com/teamsolply/solply/onboarding/dto/request/PolicyAgreementInfoDto.kt b/data/onboarding/src/main/java/com/teamsolply/solply/onboarding/dto/request/PolicyAgreementInfoDto.kt
new file mode 100644
index 00000000..e22889f2
--- /dev/null
+++ b/data/onboarding/src/main/java/com/teamsolply/solply/onboarding/dto/request/PolicyAgreementInfoDto.kt
@@ -0,0 +1,13 @@
+package com.teamsolply.solply.onboarding.dto.request
+
+import kotlinx.serialization.SerialName
+import kotlinx.serialization.Serializable
+
+@Serializable
+data class PolicyAgreementInfoDto(
+ @SerialName("policyId")
+ val policyId: Long,
+
+ @SerialName("isAgree")
+ val isAgree: Boolean
+)
diff --git a/data/onboarding/src/main/java/com/teamsolply/solply/onboarding/dto/response/GetAllTownResponseDto.kt b/data/onboarding/src/main/java/com/teamsolply/solply/onboarding/dto/response/GetAllTownResponseDto.kt
index 6d4b84ed..db9d53da 100644
--- a/data/onboarding/src/main/java/com/teamsolply/solply/onboarding/dto/response/GetAllTownResponseDto.kt
+++ b/data/onboarding/src/main/java/com/teamsolply/solply/onboarding/dto/response/GetAllTownResponseDto.kt
@@ -15,6 +15,8 @@ data class TownDto(
val townId: Long,
@SerialName("townName")
val townName: String,
+ @SerialName("parentTownId")
+ val parentTownId: Long? = null,
@SerialName("subTowns")
val subTowns: List? = null
)
diff --git a/data/onboarding/src/main/java/com/teamsolply/solply/onboarding/mapper/PolicyAgreementInfoMapper.kt b/data/onboarding/src/main/java/com/teamsolply/solply/onboarding/mapper/PolicyAgreementInfoMapper.kt
new file mode 100644
index 00000000..ba5145f5
--- /dev/null
+++ b/data/onboarding/src/main/java/com/teamsolply/solply/onboarding/mapper/PolicyAgreementInfoMapper.kt
@@ -0,0 +1,10 @@
+package com.teamsolply.solply.onboarding.mapper
+
+import com.teamsolply.solply.onboarding.dto.request.PolicyAgreementInfoDto
+import com.teamsolply.solply.onboarding.model.PolicyAgreementInfoEntity
+
+fun PolicyAgreementInfoEntity.toDto(): PolicyAgreementInfoDto =
+ PolicyAgreementInfoDto(
+ policyId = this.policyId,
+ isAgree = this.isAgree
+ )
diff --git a/data/onboarding/src/main/java/com/teamsolply/solply/onboarding/mapper/TownEntitiyMapper.kt b/data/onboarding/src/main/java/com/teamsolply/solply/onboarding/mapper/TownEntitiyMapper.kt
index 33388052..c0309801 100644
--- a/data/onboarding/src/main/java/com/teamsolply/solply/onboarding/mapper/TownEntitiyMapper.kt
+++ b/data/onboarding/src/main/java/com/teamsolply/solply/onboarding/mapper/TownEntitiyMapper.kt
@@ -2,19 +2,44 @@ package com.teamsolply.solply.onboarding.mapper
import com.teamsolply.solply.onboarding.dto.response.GetAllTownResponseDto
import com.teamsolply.solply.onboarding.dto.response.TownDto
+import com.teamsolply.solply.onboarding.model.ParentTownEntity
import com.teamsolply.solply.onboarding.model.SubTownEntity
import com.teamsolply.solply.onboarding.model.TownEntity
fun GetAllTownResponseDto.toEntity(): TownEntity {
+ val parentTowns = towns.filter { it.parentTownId == null }
+
+ val grouped = parentTowns.map { parent ->
+ ParentTownEntity(
+ townId = parent.townId,
+ townName = parent.townName,
+ subTowns = towns
+ .filter { it.parentTownId == parent.townId }
+ .map { dto ->
+ SubTownEntity(
+ townId = dto.townId,
+ townName = dto.townName
+ )
+ }
+ )
+ }
+
return TownEntity(
- towns = towns.map { it.toSubEntity() }
+ parentTowns = grouped
+ )
+}
+
+fun TownDto.toParentEntity(): ParentTownEntity {
+ return ParentTownEntity(
+ townId = townId,
+ townName = townName,
+ subTowns = subTowns?.map { it.toSubEntity() } ?: emptyList()
)
}
fun TownDto.toSubEntity(): SubTownEntity {
return SubTownEntity(
- townId = this.townId,
- townName = this.townName,
- subTowns = this.subTowns?.map { it.toSubEntity() }
+ townId = townId,
+ townName = townName
)
}
diff --git a/data/onboarding/src/main/java/com/teamsolply/solply/onboarding/repository/OnBoardingRepositoryImpl.kt b/data/onboarding/src/main/java/com/teamsolply/solply/onboarding/repository/OnBoardingRepositoryImpl.kt
index 898c0f24..cb48db68 100644
--- a/data/onboarding/src/main/java/com/teamsolply/solply/onboarding/repository/OnBoardingRepositoryImpl.kt
+++ b/data/onboarding/src/main/java/com/teamsolply/solply/onboarding/repository/OnBoardingRepositoryImpl.kt
@@ -1,8 +1,10 @@
package com.teamsolply.solply.onboarding.repository
import com.teamsolply.solply.onboarding.dto.request.PatchUserInfoRequestDto
+import com.teamsolply.solply.onboarding.mapper.toDto
import com.teamsolply.solply.onboarding.mapper.toEntity
import com.teamsolply.solply.onboarding.model.PersonaEntity
+import com.teamsolply.solply.onboarding.model.PolicyAgreementInfoEntity
import com.teamsolply.solply.onboarding.model.TownEntity
import com.teamsolply.solply.onboarding.model.UserInfoEntity
import com.teamsolply.solply.onboarding.source.remote.OnBoardingRemoteDataSource
@@ -29,16 +31,16 @@ class OnBoardingRepositoryImpl @Inject constructor(
override suspend fun patchUserInfo(
selectedTownId: Long,
- favoriteTownIdList: List,
persona: String,
- nickname: String
+ nickname: String,
+ policyAgreementInfos: List
): Result = runCatching {
onBoardingRemoteDataSource.patchUserInfo(
PatchUserInfoRequestDto(
selectedTownId = selectedTownId,
- favoriteTownIdList = favoriteTownIdList,
persona = persona,
- nickname = nickname
+ nickname = nickname,
+ policyAgreementInfos = policyAgreementInfos.map { it.toDto() }
)
)
}.mapCatching {
diff --git a/domain/onboarding/src/main/java/com/teamsolply/solply/onboarding/model/PolicyAgreementInfoEntity.kt b/domain/onboarding/src/main/java/com/teamsolply/solply/onboarding/model/PolicyAgreementInfoEntity.kt
new file mode 100644
index 00000000..f8da33e0
--- /dev/null
+++ b/domain/onboarding/src/main/java/com/teamsolply/solply/onboarding/model/PolicyAgreementInfoEntity.kt
@@ -0,0 +1,6 @@
+package com.teamsolply.solply.onboarding.model
+
+data class PolicyAgreementInfoEntity(
+ val policyId: Long,
+ val isAgree: Boolean
+)
diff --git a/domain/onboarding/src/main/java/com/teamsolply/solply/onboarding/model/TownEntity.kt b/domain/onboarding/src/main/java/com/teamsolply/solply/onboarding/model/TownEntity.kt
index 91cdeb5d..e5767279 100644
--- a/domain/onboarding/src/main/java/com/teamsolply/solply/onboarding/model/TownEntity.kt
+++ b/domain/onboarding/src/main/java/com/teamsolply/solply/onboarding/model/TownEntity.kt
@@ -1,11 +1,16 @@
package com.teamsolply.solply.onboarding.model
data class TownEntity(
- val towns: List
+ val parentTowns: List
)
-data class SubTownEntity(
+data class ParentTownEntity(
val townId: Long,
val townName: String,
- val subTowns: List? = null
+ val subTowns: List
+)
+
+data class SubTownEntity(
+ val townId: Long,
+ val townName: String
)
diff --git a/domain/onboarding/src/main/java/com/teamsolply/solply/onboarding/repository/OnBoardingRepository.kt b/domain/onboarding/src/main/java/com/teamsolply/solply/onboarding/repository/OnBoardingRepository.kt
index 8d965d09..b21d6347 100644
--- a/domain/onboarding/src/main/java/com/teamsolply/solply/onboarding/repository/OnBoardingRepository.kt
+++ b/domain/onboarding/src/main/java/com/teamsolply/solply/onboarding/repository/OnBoardingRepository.kt
@@ -1,6 +1,7 @@
package com.teamsolply.solply.onboarding.repository
import com.teamsolply.solply.onboarding.model.PersonaEntity
+import com.teamsolply.solply.onboarding.model.PolicyAgreementInfoEntity
import com.teamsolply.solply.onboarding.model.TownEntity
import com.teamsolply.solply.onboarding.model.UserInfoEntity
@@ -10,8 +11,8 @@ interface OnBoardingRepository {
suspend fun checkNicknameDuplicate(nickname: String): Result
suspend fun patchUserInfo(
selectedTownId: Long,
- favoriteTownIdList: List,
persona: String,
- nickname: String
+ nickname: String,
+ policyAgreementInfos: List
): Result
}
diff --git a/feature/oauth/src/main/java/com/teamsolply/solply/oauth/OauthScreen.kt b/feature/oauth/src/main/java/com/teamsolply/solply/oauth/OauthScreen.kt
index 487f8f2d..d155ea1e 100644
--- a/feature/oauth/src/main/java/com/teamsolply/solply/oauth/OauthScreen.kt
+++ b/feature/oauth/src/main/java/com/teamsolply/solply/oauth/OauthScreen.kt
@@ -82,7 +82,7 @@ fun OauthScreen(
Column(
modifier.fillMaxSize()
) {
- Spacer(modifier = Modifier.height(115.dp))
+ Spacer(modifier = Modifier.height(180.dp))
Image(
painter = painterResource(R.drawable.ic_logo_full_vector),
contentDescription = "app_logo",
@@ -151,7 +151,7 @@ fun OauthScreen(
.height(52.dp)
.padding(start = 20.dp, end = 20.dp)
.background(
- color = SolplyTheme.colors.black,
+ color = SolplyTheme.colors.white,
shape = RoundedCornerShape(12.dp)
)
.customClickable(
@@ -163,16 +163,16 @@ fun OauthScreen(
horizontalArrangement = Arrangement.Start
) {
Icon(
- painter = painterResource(R.drawable.ic_apple_logo),
- contentDescription = "kakao_logo",
+ painter = painterResource(R.drawable.ic_google_logo),
+ contentDescription = "google_logo",
tint = Color.Unspecified,
modifier = Modifier
.padding(start = 16.dp, end = 12.dp, top = 12.dp, bottom = 12.dp)
)
Text(
- text = stringResource(com.teamsolply.solply.oauth.R.string.apple_login),
+ text = stringResource(com.teamsolply.solply.oauth.R.string.google_login),
style = SolplyTheme.typography.button16M,
- color = SolplyTheme.colors.white
+ color = SolplyTheme.colors.black
)
}
Spacer(modifier = Modifier.height(48.dp))
diff --git a/feature/oauth/src/main/res/values/strings.xml b/feature/oauth/src/main/res/values/strings.xml
index bec778d5..1bc495ae 100644
--- a/feature/oauth/src/main/res/values/strings.xml
+++ b/feature/oauth/src/main/res/values/strings.xml
@@ -1,5 +1,5 @@
카카오로 계속하기
- Apple로 계속하기
+ Google로 계속하기
\ No newline at end of file
diff --git a/feature/onboarding/src/main/java/com/teamsolply/solply/onboarding/OnBoardingContract.kt b/feature/onboarding/src/main/java/com/teamsolply/solply/onboarding/OnBoardingContract.kt
index e6ee1c14..f00aa866 100644
--- a/feature/onboarding/src/main/java/com/teamsolply/solply/onboarding/OnBoardingContract.kt
+++ b/feature/onboarding/src/main/java/com/teamsolply/solply/onboarding/OnBoardingContract.kt
@@ -8,21 +8,25 @@ import com.teamsolply.solply.ui.base.UiState
data class OnBoardingState(
val currentPage: Int = 0,
- val totalPageCount: Int = 3,
+ val totalPageCount: Int = 4,
val townList: TownEntity = TownEntity(
- towns = emptyList()
+ parentTowns = emptyList()
),
val selectedRegionId: Long? = 1,
val selectedTownId: Long? = null,
val townBottomSheetShown: Boolean = false,
+
val personaList: PersonaEntity = PersonaEntity(personaList = emptyList()),
val selectedPersona: String? = null,
val userNickname: String = "",
val isNicknameDuplicate: Boolean = false,
val showStartingScreen: Boolean = false,
- val isOnBoardingSuccess: Boolean = false
+ val isOnBoardingSuccess: Boolean = false,
+ val agree14: Boolean = false,
+ val agreeService: Boolean = false,
+ val agreePrivacy: Boolean = false
) : UiState
sealed interface OnBoardingIntent : UiIntent {
@@ -40,6 +44,9 @@ sealed interface OnBoardingIntent : UiIntent {
) : OnBoardingIntent
data object ShowStartingScreen : OnBoardingIntent
+ data class ChangeAgree14(val isChecked: Boolean) : OnBoardingIntent
+ data class ChangeAgreeService(val isChecked: Boolean) : OnBoardingIntent
+ data class ChangeAgreePrivacy(val isChecked: Boolean) : OnBoardingIntent
}
sealed interface OnBoardingSideEffect : SideEffect {
diff --git a/feature/onboarding/src/main/java/com/teamsolply/solply/onboarding/OnBoardingViewModel.kt b/feature/onboarding/src/main/java/com/teamsolply/solply/onboarding/OnBoardingViewModel.kt
index c1ebe070..ace2de8e 100644
--- a/feature/onboarding/src/main/java/com/teamsolply/solply/onboarding/OnBoardingViewModel.kt
+++ b/feature/onboarding/src/main/java/com/teamsolply/solply/onboarding/OnBoardingViewModel.kt
@@ -1,6 +1,7 @@
package com.teamsolply.solply.onboarding
import androidx.lifecycle.viewModelScope
+import com.teamsolply.solply.onboarding.model.PolicyAgreementInfoEntity
import com.teamsolply.solply.onboarding.repository.OnBoardingRepository
import com.teamsolply.solply.ui.base.BaseViewModel
import dagger.hilt.android.lifecycle.HiltViewModel
@@ -83,6 +84,17 @@ class OnBoardingViewModel @Inject constructor(
is OnBoardingIntent.ShowStartingScreen -> {
patchUserInfo()
}
+ is OnBoardingIntent.ChangeAgree14 -> {
+ reduce { copy(agree14 = intent.isChecked) }
+ }
+
+ is OnBoardingIntent.ChangeAgreeService -> {
+ reduce { copy(agreeService = intent.isChecked) }
+ }
+
+ is OnBoardingIntent.ChangeAgreePrivacy -> {
+ reduce { copy(agreePrivacy = intent.isChecked) }
+ }
}
}
@@ -118,11 +130,18 @@ class OnBoardingViewModel @Inject constructor(
viewModelScope.launch {
uiState.value.selectedTownId?.let { selectedTownId ->
uiState.value.selectedPersona?.let { selectedPersona ->
+
+ val policyInfos = listOf(
+ PolicyAgreementInfoEntity(1, uiState.value.agree14),
+ PolicyAgreementInfoEntity(2, uiState.value.agreeService),
+ PolicyAgreementInfoEntity(3, uiState.value.agreePrivacy)
+ )
+
onBoardingRepository.patchUserInfo(
selectedTownId = selectedTownId,
- favoriteTownIdList = uiState.value.townList.towns.map { it.townId },
persona = selectedPersona,
- nickname = uiState.value.userNickname
+ nickname = uiState.value.userNickname,
+ policyAgreementInfos = policyInfos
).onSuccess {
reduce { copy(showStartingScreen = true) }
}
diff --git a/feature/onboarding/src/main/java/com/teamsolply/solply/onboarding/screen/AllowClauseScreen.kt b/feature/onboarding/src/main/java/com/teamsolply/solply/onboarding/screen/AllowClauseScreen.kt
index aa2933b8..b74a2554 100644
--- a/feature/onboarding/src/main/java/com/teamsolply/solply/onboarding/screen/AllowClauseScreen.kt
+++ b/feature/onboarding/src/main/java/com/teamsolply/solply/onboarding/screen/AllowClauseScreen.kt
@@ -17,11 +17,6 @@ import androidx.compose.foundation.layout.width
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
-import androidx.compose.runtime.LaunchedEffect
-import androidx.compose.runtime.getValue
-import androidx.compose.runtime.mutableStateOf
-import androidx.compose.runtime.remember
-import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.painterResource
@@ -38,14 +33,10 @@ fun AllowClauseScreen(
onNextClick: () -> Unit,
onBoardingIntent: (OnBoardingIntent) -> Unit
) {
- var isAllChecked by remember { mutableStateOf(false) }
- var agree14 by remember { mutableStateOf(false) }
- var agreeService by remember { mutableStateOf(false) }
- var agreePrivacy by remember { mutableStateOf(false) }
-
- LaunchedEffect(agree14, agreeService, agreePrivacy) {
- isAllChecked = agree14 && agreeService && agreePrivacy
- }
+ val agree14 = state.agree14
+ val agreeService = state.agreeService
+ val agreePrivacy = state.agreePrivacy
+ val isAllChecked = agree14 && agreeService && agreePrivacy
Column(
modifier = Modifier
@@ -77,10 +68,9 @@ fun AllowClauseScreen(
)
.customClickable(rippleEnabled = false) {
val toggle = !isAllChecked
- isAllChecked = toggle
- agree14 = toggle
- agreeService = toggle
- agreePrivacy = toggle
+ onBoardingIntent(OnBoardingIntent.ChangeAgree14(toggle))
+ onBoardingIntent(OnBoardingIntent.ChangeAgreeService(toggle))
+ onBoardingIntent(OnBoardingIntent.ChangeAgreePrivacy(toggle))
}
) {
Row(
@@ -114,13 +104,17 @@ fun AllowClauseScreen(
AgreementItem(
text = "(필수) 만 14세 이상입니다",
checked = agree14,
- onClick = { agree14 = !agree14 }
+ onClick = {
+ onBoardingIntent(OnBoardingIntent.ChangeAgree14(!agree14))
+ }
)
AgreementItem(
text = "(필수) 서비스 이용 약관",
checked = agreeService,
- onClick = { agreeService = !agreeService },
+ onClick = {
+ onBoardingIntent(OnBoardingIntent.ChangeAgreeService(!agreeService))
+ },
showArrow = true,
onArrowClick = {
// TODO: 서비스 이용 약관 이동
@@ -130,7 +124,9 @@ fun AllowClauseScreen(
AgreementItem(
text = "(필수) 개인정보 처리방침",
checked = agreePrivacy,
- onClick = { agreePrivacy = !agreePrivacy },
+ onClick = {
+ onBoardingIntent(OnBoardingIntent.ChangeAgreePrivacy(!agreePrivacy))
+ },
showArrow = true,
onArrowClick = {
// TODO: 개인정보 처리방침 이동
diff --git a/feature/onboarding/src/main/java/com/teamsolply/solply/onboarding/screen/SelectTownScreen.kt b/feature/onboarding/src/main/java/com/teamsolply/solply/onboarding/screen/SelectTownScreen.kt
index e6a76da3..e6cc50ee 100644
--- a/feature/onboarding/src/main/java/com/teamsolply/solply/onboarding/screen/SelectTownScreen.kt
+++ b/feature/onboarding/src/main/java/com/teamsolply/solply/onboarding/screen/SelectTownScreen.kt
@@ -33,6 +33,7 @@ import com.teamsolply.solply.designsystem.theme.SolplyTheme
import com.teamsolply.solply.onboarding.OnBoardingIntent
import com.teamsolply.solply.onboarding.OnBoardingState
import com.teamsolply.solply.onboarding.component.OnBoardingTownBottomSheet
+import com.teamsolply.solply.onboarding.model.ParentTownEntity
import com.teamsolply.solply.onboarding.model.SubTownEntity
import com.teamsolply.solply.ui.extension.customClickable
@@ -77,11 +78,13 @@ fun SelectTownScreen(
)
} else {
AddLocalAreaButton(
- text = townList.towns
- .flatMap { it.subTowns ?: emptyList() }
+ text = townList.parentTowns
+ .flatMap { it.subTowns }
.find { it.townId == state.selectedTownId }
?.townName ?: "",
- onClick = {},
+ onClick = {
+ onBoardingIntent(OnBoardingIntent.ChangeTownBottomSheetShown)
+ },
selected = true
)
}
@@ -112,15 +115,9 @@ fun SelectTownScreen(
) {
LeftRegionPane(
borderColor = borderColor,
- regions = townList.towns,
+ regions = townList.parentTowns,
selectedRegionId = state.selectedRegionId,
- onSelect = { id ->
- onBoardingIntent(
- OnBoardingIntent.ChangeRegion(
- id
- )
- )
- }
+ onSelect = { id -> onBoardingIntent(OnBoardingIntent.ChangeRegion(id)) }
)
VerticalDivider(
thickness = 1.dp,
@@ -128,17 +125,11 @@ fun SelectTownScreen(
)
RightTownPane(
borderColor = borderColor,
- towns = townList.towns
+ towns = townList.parentTowns
.find { it.townId == state.selectedRegionId }
?.subTowns ?: emptyList(),
selectedTownId = state.selectedTownId,
- onSelect = { id ->
- onBoardingIntent(
- OnBoardingIntent.OnTownSelected(
- id
- )
- )
- }
+ onSelect = { id -> onBoardingIntent(OnBoardingIntent.OnTownSelected(id)) }
)
}
}
@@ -184,7 +175,7 @@ fun SelectTownScreen(
@Composable
private fun LeftRegionPane(
borderColor: Color,
- regions: List,
+ regions: List,
selectedRegionId: Long?,
onSelect: (Long) -> Unit
) {
@@ -194,7 +185,7 @@ private fun LeftRegionPane(
.fillMaxHeight()
.background(SolplyTheme.colors.gray100)
) {
- itemsIndexed(items = regions) { index: Int, item: SubTownEntity ->
+ itemsIndexed(items = regions) { index: Int, item: ParentTownEntity ->
val selected = selectedRegionId == item.townId
val bg = if (selected) SolplyTheme.colors.white else SolplyTheme.colors.gray100
val textColor = if (selected) SolplyTheme.colors.black else SolplyTheme.colors.gray600
@@ -233,7 +224,7 @@ private fun LeftRegionPane(
) {
Text(
text = item.townName,
- style = SolplyTheme.typography.body14M.copy(fontWeight = fontWeight),
+ style = SolplyTheme.typography.body16M.copy(fontWeight = fontWeight),
color = textColor
)
}