Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
15 commits
Select commit Hold shift + click to select a range
98b32bb
refactor: PrezelDialog 내 description 필드 선택 사항으로 변경
moondev03 May 5, 2026
72eeebf
refactor: `PrezelButtonArea` 컴포넌트 구조 개선 및 DSL 방식 제거
moondev03 May 5, 2026
a5754a0
feat: UI 유틸리티 `noRippleClickable` 확장 함수 추가
moondev03 May 5, 2026
1387d7f
feat: 약관 관련 내비게이션 구조 개선 및 상세 화면 분리
moondev03 May 5, 2026
726bde6
feat: Setting 기능 모듈 생성 및 네비게이션 연동
moondev03 May 5, 2026
ffac987
refactor: MyTopAppBar 내 설정 버튼을 Material 3 표준 컴포넌트로 변경
moondev03 May 5, 2026
48ba5ad
feat: 설정 및 회원 탈퇴 기능 구현
moondev03 May 6, 2026
68fd6c3
refactor: 회원 탈퇴 및 설정 화면 UI 컴포넌트 구조 개선
moondev03 May 6, 2026
c12fe81
refactor: 회원 탈퇴 안내 화면 스트링 관리 방식 개선 및 태그 기반 스타일링 도입
moondev03 May 6, 2026
a672b7f
refactor: 탈퇴 사유 개선
moondev03 May 6, 2026
e62bfb3
refactor: 탈퇴 사유 매핑 로직 개선 및 유저 정보 조회 실패 메시지 추가
moondev03 May 6, 2026
e44e85a
refactor: SnackbarHost의 스낵바 노출 위치 제어 로직 개선
moondev03 May 6, 2026
e252093
feat: 로그아웃 및 회원 탈퇴 성공 피드백 추가 및 UI 로직 개선
moondev03 May 6, 2026
1946bfe
build: feature:setting 모듈 내 불필요한 의존성 제거
moondev03 May 6, 2026
de94a5c
refactor: 종료 확인 스낵바 표시 설정 수정
moondev03 May 6, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Prezel/app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ dependencies {
implementation(projects.featureHistoryImpl)
implementation(projects.featureMyApi)
implementation(projects.featureMyImpl)
implementation(projects.featureSettingApi)
implementation(projects.featureSettingImpl)
implementation(projects.featureProfileImpl)

implementation(libs.androidx.core.ktx)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,8 @@ internal fun DoubleBackToExitHandler(navigationState: NavigationState) {
snackbarState.showPrezelSnackbar(
id = SNACKBAR_IDENTIFIER,
message = resources.getString(R.string.double_back_to_exit_snackbar_message),
actionLabel = resources.getString(R.string.double_back_to_exit_snackbar_action_label),
onAction = { backPressState = BackPressState.Idle },
onDismiss = { backPressState = BackPressState.Idle },
useRaisedPosition = false,
)
}

Expand Down
3 changes: 1 addition & 2 deletions Prezel/app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,5 @@
<string name="bottom_nav_history">히스토리</string>
<string name="bottom_nav_profile">프로필</string>

<string name="double_back_to_exit_snackbar_message">한 번 더 누르면 앱을 종료합니다</string>
<string name="double_back_to_exit_snackbar_action_label">닫기</string>
<string name="double_back_to_exit_snackbar_message">한 번 더 누르면 앱을 종료합니다.</string>
</resources>
Original file line number Diff line number Diff line change
Expand Up @@ -37,30 +37,24 @@ internal class AuthRepositoryImpl @Inject constructor(
override suspend fun withdraw(reason: WithdrawReason): Result<Unit> =
runCatching {
authRemoteDataSource.withdraw(
reasonCategory = reason.toCategory(),
reasonText = reason.toReasonText(),
reasonCategory = reason.toReasonCategory(),
reasonText = (reason as? WithdrawReason.Etc)?.text,
)
clearLocalSession()
}.mapDomainFailure()

private fun WithdrawReason.toCategory(): String =
when (this) {
WithdrawReason.NotUsedOften -> "NOT_USED_OFTEN"
WithdrawReason.NoLongerNeeded -> "NO_LONGER_NEEDED"
WithdrawReason.TooDifficultOrComplex -> "TOO_COMPLEX"
WithdrawReason.AnalysisResultInaccurate -> "INACCURATE_ANALYSIS"
WithdrawReason.TooManyErrors -> "MANY_ERRORS"
is WithdrawReason.Other -> "ETC"
}

private fun WithdrawReason.toReasonText(): String =
when (this) {
is WithdrawReason.Other -> text
else -> ""
}

private suspend fun clearLocalSession() {
authLocalDataSource.clearTokens()
authSessionCache.clear()
}

private fun WithdrawReason.toReasonCategory(): String =
when (this) {
WithdrawReason.NotUsedOften -> "NOT_USED_OFTEN"
WithdrawReason.NoLongerNeeded -> "NO_LONGER_NEEDED"
WithdrawReason.TooComplex -> "TOO_COMPLEX"
WithdrawReason.InaccurateAnalysis -> "INACCURATE_ANALYSIS"
WithdrawReason.ManyErrors -> "MANY_ERRORS"
is WithdrawReason.Etc -> "ETC"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.team.prezel.core.designsystem.component.PrezelDividerType
import com.team.prezel.core.designsystem.component.PrezelHorizontalDivider
import com.team.prezel.core.designsystem.component.actions.button.PrezelButton
import com.team.prezel.core.designsystem.component.actions.button.config.ButtonHierarchy
import com.team.prezel.core.designsystem.component.actions.button.config.ButtonType
import com.team.prezel.core.designsystem.icon.PrezelIcons
import com.team.prezel.core.designsystem.preview.PreviewSection
import com.team.prezel.core.designsystem.theme.PrezelTheme
Expand All @@ -40,16 +43,9 @@ fun PrezelButtonArea(
showBackground: Boolean = false,
isNested: Boolean = false,
config: PrezelButtonAreaDefault = PrezelButtonAreaDefaults.getDefault(),
content: ButtonAreaScope.() -> Unit,
mainButton: @Composable (Modifier) -> Unit,
subButton: @Composable ((Modifier) -> Unit)? = null,
) {
val scope = DefaultButtonAreaScope().apply {
this.content()
}

val mainButton = requireNotNull(scope.buttons.firstOrNull()) {
"PrezelButtonArea에는 최소 1개의 버튼이 필요합니다."
}
val subButton = scope.buttons.getOrNull(1)
val contentModifier = if (isNested) Modifier else Modifier.padding(config.contentPadding)

Column(
Expand Down Expand Up @@ -247,21 +243,29 @@ private fun ButtonAreaPreviewSample(
isVertical = variant.isVertical,
isStrongStrength = variant.isStrongStrength,
showBackground = showBackground,
) {
MainButton(
iconResId = PrezelIcons.Blank,
label = "Label",
enabled = enabled,
onClick = {},
)

SubButton(
iconResId = PrezelIcons.Blank,
label = "Label",
enabled = enabled,
onClick = {},
)
}
mainButton = { modifier ->
PrezelButton(
modifier = modifier,
text = "Label",
iconResId = PrezelIcons.Blank,
onClick = { },
enabled = enabled,
type = ButtonType.FILLED,
hierarchy = ButtonHierarchy.PRIMARY,
)
},
subButton = { modifier ->
PrezelButton(
modifier = modifier,
text = "Label",
iconResId = PrezelIcons.Blank,
onClick = { },
enabled = enabled,
type = ButtonType.FILLED,
hierarchy = ButtonHierarchy.SECONDARY,
)
},
)
}

@Composable
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ import com.team.prezel.core.designsystem.component.PrezelDividerType
import com.team.prezel.core.designsystem.component.PrezelHorizontalDivider
import com.team.prezel.core.designsystem.component.PrezelTopAppBar
import com.team.prezel.core.designsystem.component.actions.area.PrezelButtonArea
import com.team.prezel.core.designsystem.component.actions.button.PrezelButton
import com.team.prezel.core.designsystem.component.actions.button.config.ButtonHierarchy
import com.team.prezel.core.designsystem.component.actions.button.config.ButtonType
import com.team.prezel.core.designsystem.component.datepicker.config.DatePickerDefault
import com.team.prezel.core.designsystem.component.datepicker.config.DatePickerDefaults
import com.team.prezel.core.designsystem.component.datepicker.config.DatePickerMonth
Expand Down Expand Up @@ -120,18 +123,20 @@ private fun DatePickerFooter(
enabled: Boolean,
onClick: () -> Unit,
) {
val buttonLabel = stringResource(R.string.core_designsystem_date_picker_confirm_btn)

PrezelButtonArea(
isVertical = false,
showBackground = true,
) {
MainButton(
label = buttonLabel,
enabled = enabled,
onClick = onClick,
)
}
mainButton = { modifier ->
PrezelButton(
modifier = modifier,
text = stringResource(R.string.core_designsystem_date_picker_confirm_btn),
onClick = onClick,
enabled = enabled,
type = ButtonType.FILLED,
hierarchy = ButtonHierarchy.PRIMARY,
)
},
)
}

@Composable
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@ import com.team.prezel.core.designsystem.theme.PrezelTheme
@Composable
fun PrezelDialog(
title: String,
description: String,
onDismiss: () -> Unit,
modifier: Modifier = Modifier,
description: String? = null,
content: @Composable PrezelDialogScope.() -> Unit,
) {
val scope = remember { PrezelDialogScope() }
Expand Down Expand Up @@ -59,15 +59,17 @@ fun PrezelDialog(
@Composable
private fun DialogContent(
title: String,
description: String,
description: String?,
modifier: Modifier = Modifier,
) {
Column(
modifier = modifier.padding(vertical = PrezelTheme.spacing.V24),
) {
Text(text = title, style = PrezelTheme.typography.title2Bold, color = PrezelTheme.colors.textLarge)
Spacer(modifier = Modifier.height(PrezelTheme.spacing.V12))
Text(text = description, style = PrezelTheme.typography.body3Medium, color = PrezelTheme.colors.textRegular)
description?.let { text ->
Text(text = text, style = PrezelTheme.typography.body3Medium, color = PrezelTheme.colors.textRegular)
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ suspend fun SnackbarHostState.showPrezelSnackbar(
@DrawableRes leadingIconResId: Int? = null,
duration: SnackbarDuration = SnackbarDuration.Short,
id: String? = null,
offsetY: Dp = 0.dp,
useRaisedPosition: Boolean = true,
onDismiss: (() -> Unit)? = null,
) {
val result = showSnackbar(
Expand All @@ -38,7 +38,7 @@ suspend fun SnackbarHostState.showPrezelSnackbar(
duration = duration,
id = id,
leadingIconResId = leadingIconResId,
offsetY = offsetY,
offsetY = if (useRaisedPosition) (-98).dp else 0.dp,
),
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@ sealed interface WithdrawReason {

data object NoLongerNeeded : WithdrawReason

data object TooDifficultOrComplex : WithdrawReason
data object TooComplex : WithdrawReason

data object AnalysisResultInaccurate : WithdrawReason
data object InaccurateAnalysis : WithdrawReason

data object TooManyErrors : WithdrawReason
data object ManyErrors : WithdrawReason

data class Other(
data class Etc(
val text: String,
) : WithdrawReason
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,6 @@ interface AuthRemoteDataSource {

suspend fun withdraw(
reasonCategory: String,
reasonText: String,
reasonText: String?,
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,10 @@ internal class AuthRemoteDataSourceImpl @Inject constructor(

override suspend fun withdraw(
reasonCategory: String,
reasonText: String,
reasonText: String?,
) {
authService
.withdraw(
request = WithdrawRequest(reasonCategory = reasonCategory, reasonText = reasonText),
).requireSuccess()
.withdraw(request = WithdrawRequest(reasonCategory = reasonCategory, reasonText = reasonText))
.requireSuccess()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,5 @@ data class WithdrawRequest(
@SerialName("reasonCategory")
val reasonCategory: String,
@SerialName("reasonText")
val reasonText: String,
val reasonText: String?,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.team.prezel.core.ui.util

import androidx.compose.foundation.clickable
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.composed

fun Modifier.noRippleClickable(onClick: () -> Unit): Modifier =
composed {
clickable(
indication = null,
interactionSource = remember { MutableInteractionSource() },
onClick = onClick,
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.navigation3.ui.LocalNavAnimatedContentScope
import com.team.prezel.core.auth.AuthManager
import com.team.prezel.core.designsystem.component.actions.area.PrezelButtonArea
import com.team.prezel.core.designsystem.component.actions.button.PrezelButton
import com.team.prezel.core.designsystem.component.actions.button.config.ButtonHierarchy
import com.team.prezel.core.designsystem.component.actions.button.config.ButtonSize
import com.team.prezel.core.designsystem.component.actions.button.config.ButtonType
Expand Down Expand Up @@ -153,16 +154,6 @@ private fun LoginFooter(
modifier: Modifier = Modifier,
) {
var isButtonVisible by remember { mutableStateOf(false) }
val startWithKakaoLabel = stringResource(R.string.feature_login_impl_start_with_kakao)
val kakaoButtonConfig = PrezelButtonDefaults.getDefault(
isIconOnly = false,
type = ButtonType.FILLED,
size = ButtonSize.REGULAR,
hierarchy = ButtonHierarchy.SECONDARY,
isRounded = false,
backgroundColor = Color(0xFFFEE500),
contentColor = PrezelTheme.colors.textLarge,
)

LaunchedEffect(Unit) {
isButtonVisible = true
Expand All @@ -180,15 +171,26 @@ private fun LoginFooter(
),
exit = ExitTransition.None,
) {
PrezelButtonArea {
CustomButton(
iconResId = PrezelIcons.Kakao,
label = startWithKakaoLabel,
enabled = enabled,
onClick = onLogin,
config = kakaoButtonConfig,
)
}
PrezelButtonArea(
mainButton = { modifier ->
PrezelButton(
modifier = modifier,
text = stringResource(R.string.feature_login_impl_start_with_kakao),
iconResId = PrezelIcons.Kakao,
enabled = enabled,
onClick = onLogin,
config = PrezelButtonDefaults.getDefault(
isIconOnly = false,
type = ButtonType.FILLED,
size = ButtonSize.REGULAR,
hierarchy = ButtonHierarchy.SECONDARY,
isRounded = false,
backgroundColor = Color(0xFFFEE500),
contentColor = PrezelTheme.colors.textLarge,
),
)
},
)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ internal fun EntryProviderScope<NavKey>.featureLoginEntryBuilder(authManager: Au
navigator.replaceRoot(HomeNavKey)
},
navigateToTerms = {
navigator.navigate(TermsNavKey)
navigator.navigate(TermsNavKey.List)
},
navigateToCreateProfile = {
navigator.navigate(ProfileNavKey.Create)
Expand Down
1 change: 1 addition & 0 deletions Prezel/feature/my/impl/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ dependencies {
implementation(projects.coreModel)

implementation(projects.featureMyApi)
implementation(projects.featureSettingApi)
implementation(projects.featureProfileApi)

implementation(libs.kotlinx.collections.immutable)
Expand Down
Loading