diff --git a/core/designsystem/src/main/res/drawable/ic_warning.xml b/core/designsystem/src/main/res/drawable/ic_warning.xml
new file mode 100644
index 00000000..fb6d8061
--- /dev/null
+++ b/core/designsystem/src/main/res/drawable/ic_warning.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
diff --git a/core/designsystem/src/main/res/drawable/img_default_progile.xml b/core/designsystem/src/main/res/drawable/img_default_progile.xml
new file mode 100644
index 00000000..ec518560
--- /dev/null
+++ b/core/designsystem/src/main/res/drawable/img_default_progile.xml
@@ -0,0 +1,45 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/presentation/src/main/java/com/threegap/bitnagil/presentation/mypage/MyPageScreen.kt b/presentation/src/main/java/com/threegap/bitnagil/presentation/mypage/MyPageScreen.kt
index bbe92722..165129f5 100644
--- a/presentation/src/main/java/com/threegap/bitnagil/presentation/mypage/MyPageScreen.kt
+++ b/presentation/src/main/java/com/threegap/bitnagil/presentation/mypage/MyPageScreen.kt
@@ -17,7 +17,8 @@ import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
-import androidx.compose.ui.graphics.painter.ColorPainter
+import androidx.compose.ui.graphics.vector.ImageVector
+import androidx.compose.ui.res.vectorResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
@@ -77,10 +78,10 @@ private fun MyPageScreen(
Spacer(modifier = Modifier.height(32.dp))
Image(
- painter = ColorPainter(BitnagilTheme.colors.coolGray98),
+ imageVector = ImageVector.vectorResource(R.drawable.img_default_progile),
contentDescription = null,
modifier = Modifier
- .size(80.dp)
+ .size(90.dp)
.clip(shape = CircleShape),
)
diff --git a/presentation/src/main/java/com/threegap/bitnagil/presentation/setting/SettingScreen.kt b/presentation/src/main/java/com/threegap/bitnagil/presentation/setting/SettingScreen.kt
index 068dd103..c3c1daf8 100644
--- a/presentation/src/main/java/com/threegap/bitnagil/presentation/setting/SettingScreen.kt
+++ b/presentation/src/main/java/com/threegap/bitnagil/presentation/setting/SettingScreen.kt
@@ -29,6 +29,7 @@ import com.threegap.bitnagil.designsystem.component.block.BitnagilTopBar
import com.threegap.bitnagil.presentation.common.flow.collectAsEffect
import com.threegap.bitnagil.presentation.setting.component.atom.settingtitle.SettingTitle
import com.threegap.bitnagil.presentation.setting.component.atom.toggleswitch.ToggleSwitch
+import com.threegap.bitnagil.presentation.setting.component.block.ConfirmDialog
import com.threegap.bitnagil.presentation.setting.model.mvi.SettingSideEffect
import com.threegap.bitnagil.presentation.setting.model.mvi.SettingState
@@ -48,6 +49,14 @@ fun SettingScreenContainer(
}
}
+ state.showConfirmDialog?.let { dialogType ->
+ ConfirmDialog(
+ type = dialogType,
+ onDismiss = viewModel::hideConfirmDialog,
+ onConfirm = viewModel::confirmDialogAction,
+ )
+ }
+
SettingScreen(
state = state,
toggleServiceAlarm = viewModel::toggleServiceAlarm,
@@ -56,8 +65,8 @@ fun SettingScreenContainer(
onClickBack = navigateToBack,
onClickTermsOfService = navigateToTermsOfService,
onClickPrivacyPolicy = navigateToPrivacyPolicy,
- onClickLogout = viewModel::logout,
- onClickWithdrawal = viewModel::withdrawal,
+ onClickLogout = viewModel::showLogoutDialog,
+ onClickWithdrawal = viewModel::showWithdrawalDialog,
)
}
@@ -213,6 +222,7 @@ fun SettingScreenPreview() {
version = "1.0.1",
latestVersion = "1.0.0",
loading = false,
+ showConfirmDialog = null,
),
toggleServiceAlarm = {},
togglePushAlarm = {},
diff --git a/presentation/src/main/java/com/threegap/bitnagil/presentation/setting/SettingViewModel.kt b/presentation/src/main/java/com/threegap/bitnagil/presentation/setting/SettingViewModel.kt
index baa49ba5..9b8c4e88 100644
--- a/presentation/src/main/java/com/threegap/bitnagil/presentation/setting/SettingViewModel.kt
+++ b/presentation/src/main/java/com/threegap/bitnagil/presentation/setting/SettingViewModel.kt
@@ -5,6 +5,7 @@ import androidx.lifecycle.viewModelScope
import com.threegap.bitnagil.domain.auth.usecase.LogoutUseCase
import com.threegap.bitnagil.domain.auth.usecase.WithdrawalUseCase
import com.threegap.bitnagil.presentation.common.mviviewmodel.MviViewModel
+import com.threegap.bitnagil.presentation.setting.model.ConfirmDialogType
import com.threegap.bitnagil.presentation.setting.model.mvi.SettingIntent
import com.threegap.bitnagil.presentation.setting.model.mvi.SettingSideEffect
import com.threegap.bitnagil.presentation.setting.model.mvi.SettingState
@@ -41,15 +42,20 @@ class SettingViewModel @Inject constructor(
)
}
SettingIntent.TogglePushAlarm -> {
- return state.copy(
- usePushAlarm = !state.usePushAlarm,
- )
+ return state.copy(usePushAlarm = !state.usePushAlarm)
}
SettingIntent.ToggleServiceAlarm -> {
- return state.copy(
- useServiceAlarm = !state.useServiceAlarm,
- )
+ return state.copy(useServiceAlarm = !state.useServiceAlarm)
+ }
+
+ is SettingIntent.ShowConfirmDialog -> {
+ return state.copy(showConfirmDialog = intent.type)
+ }
+
+ is SettingIntent.HideConfirmDialog -> {
+ return state.copy(showConfirmDialog = null)
}
+
SettingIntent.LogoutSuccess -> {
sendSideEffect(SettingSideEffect.NavigateToIntro)
return null
@@ -73,6 +79,30 @@ class SettingViewModel @Inject constructor(
}
}
+ fun showLogoutDialog() {
+ sendIntent(SettingIntent.ShowConfirmDialog(ConfirmDialogType.LOGOUT))
+ }
+
+ fun showWithdrawalDialog() {
+ sendIntent(SettingIntent.ShowConfirmDialog(ConfirmDialogType.WITHDRAW))
+ }
+
+ fun hideConfirmDialog() {
+ sendIntent(SettingIntent.HideConfirmDialog)
+ }
+
+ fun confirmDialogAction() {
+ val currentDialogType = container.stateFlow.value.showConfirmDialog
+
+ sendIntent(SettingIntent.HideConfirmDialog)
+
+ when (currentDialogType) {
+ ConfirmDialogType.LOGOUT -> executeLogout()
+ ConfirmDialogType.WITHDRAW -> executeWithdrawal()
+ null -> {}
+ }
+ }
+
fun toggleServiceAlarm() {
sendIntent(SettingIntent.ToggleServiceAlarm)
setServiceAlarmJob?.cancel()
@@ -89,7 +119,7 @@ class SettingViewModel @Inject constructor(
}
}
- fun logout() {
+ private fun executeLogout() {
viewModelScope.launch {
sendIntent(SettingIntent.LogoutLoading)
logoutUseCase().onSuccess {
@@ -100,7 +130,7 @@ class SettingViewModel @Inject constructor(
}
}
- fun withdrawal() {
+ private fun executeWithdrawal() {
viewModelScope.launch {
sendIntent(SettingIntent.WithdrawalLoading)
withdrawalUseCase().onSuccess {
diff --git a/presentation/src/main/java/com/threegap/bitnagil/presentation/setting/component/block/ConfirmDialog.kt b/presentation/src/main/java/com/threegap/bitnagil/presentation/setting/component/block/ConfirmDialog.kt
new file mode 100644
index 00000000..83889373
--- /dev/null
+++ b/presentation/src/main/java/com/threegap/bitnagil/presentation/setting/component/block/ConfirmDialog.kt
@@ -0,0 +1,115 @@
+package com.threegap.bitnagil.presentation.setting.component.block
+
+import androidx.compose.foundation.background
+import androidx.compose.foundation.border
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.Spacer
+import androidx.compose.foundation.layout.height
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.size
+import androidx.compose.foundation.shape.RoundedCornerShape
+import androidx.compose.material3.BasicAlertDialog
+import androidx.compose.material3.ExperimentalMaterial3Api
+import androidx.compose.material3.Text
+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 androidx.compose.ui.window.DialogProperties
+import com.threegap.bitnagil.designsystem.BitnagilTheme
+import com.threegap.bitnagil.designsystem.R
+import com.threegap.bitnagil.designsystem.component.atom.BitnagilIcon
+import com.threegap.bitnagil.designsystem.component.atom.BitnagilTextButton
+import com.threegap.bitnagil.designsystem.component.atom.BitnagilTextButtonColor
+import com.threegap.bitnagil.presentation.setting.model.ConfirmDialogType
+
+@OptIn(ExperimentalMaterial3Api::class)
+@Composable
+fun ConfirmDialog(
+ type: ConfirmDialogType,
+ onDismiss: () -> Unit,
+ onConfirm: () -> Unit,
+ modifier: Modifier = Modifier,
+) {
+ BasicAlertDialog(
+ modifier = modifier,
+ onDismissRequest = onDismiss,
+ properties = DialogProperties(
+ dismissOnBackPress = true,
+ dismissOnClickOutside = true,
+ ),
+ ) {
+ Column(
+ modifier = Modifier
+ .background(
+ color = BitnagilTheme.colors.white,
+ shape = RoundedCornerShape(20.dp),
+ )
+ .padding(vertical = 24.dp, horizontal = 16.dp),
+ verticalArrangement = Arrangement.Center,
+ horizontalAlignment = Alignment.CenterHorizontally,
+ ) {
+ BitnagilIcon(
+ id = R.drawable.ic_warning,
+ tint = null,
+ modifier = Modifier.size(55.dp),
+ )
+
+ Spacer(modifier = Modifier.height(18.dp))
+
+ Text(
+ text = type.titleText,
+ color = BitnagilTheme.colors.coolGray10,
+ style = BitnagilTheme.typography.title2Bold,
+ )
+
+ Spacer(modifier = Modifier.height(2.dp))
+
+ Text(
+ text = type.descriptionText,
+ color = BitnagilTheme.colors.coolGray10,
+ style = BitnagilTheme.typography.caption1Regular,
+ )
+
+ Spacer(modifier = Modifier.height(18.dp))
+
+ Row(
+ modifier = Modifier.height(44.dp),
+ horizontalArrangement = Arrangement.spacedBy(8.dp),
+ ) {
+ BitnagilTextButton(
+ text = "취소",
+ onClick = onDismiss,
+ colors = BitnagilTextButtonColor.skip(),
+ modifier = Modifier
+ .weight(1f)
+ .border(
+ width = 1.dp,
+ color = BitnagilTheme.colors.navy500,
+ shape = RoundedCornerShape(8.dp),
+ ),
+ )
+
+ BitnagilTextButton(
+ text = type.confirmButtonText,
+ onClick = onConfirm,
+ shape = RoundedCornerShape(8.dp),
+ modifier = Modifier.weight(1f),
+ )
+ }
+ }
+ }
+}
+
+@Preview
+@Composable
+private fun ConfirmDialogPreview() {
+ ConfirmDialog(
+ type = ConfirmDialogType.LOGOUT,
+ onDismiss = {},
+ onConfirm = {},
+ )
+}
diff --git a/presentation/src/main/java/com/threegap/bitnagil/presentation/setting/model/ConfirmDialogType.kt b/presentation/src/main/java/com/threegap/bitnagil/presentation/setting/model/ConfirmDialogType.kt
new file mode 100644
index 00000000..c26c4cbd
--- /dev/null
+++ b/presentation/src/main/java/com/threegap/bitnagil/presentation/setting/model/ConfirmDialogType.kt
@@ -0,0 +1,18 @@
+package com.threegap.bitnagil.presentation.setting.model
+
+enum class ConfirmDialogType(
+ val titleText: String,
+ val descriptionText: String,
+ val confirmButtonText: String,
+) {
+ LOGOUT(
+ titleText = "로그아웃 하시겠어요?",
+ descriptionText = "버튼을 누르면 로그인 페이지로 이동해요.",
+ confirmButtonText = "로그아웃",
+ ),
+ WITHDRAW(
+ titleText = "정말 탈퇴하시겠어요?",
+ descriptionText = "소중한 기록들이 모두 사라져요.",
+ confirmButtonText = "탈퇴하기",
+ ),
+}
diff --git a/presentation/src/main/java/com/threegap/bitnagil/presentation/setting/model/mvi/SettingIntent.kt b/presentation/src/main/java/com/threegap/bitnagil/presentation/setting/model/mvi/SettingIntent.kt
index 066691f3..9438f5d4 100644
--- a/presentation/src/main/java/com/threegap/bitnagil/presentation/setting/model/mvi/SettingIntent.kt
+++ b/presentation/src/main/java/com/threegap/bitnagil/presentation/setting/model/mvi/SettingIntent.kt
@@ -1,6 +1,7 @@
package com.threegap.bitnagil.presentation.setting.model.mvi
import com.threegap.bitnagil.presentation.common.mviviewmodel.MviIntent
+import com.threegap.bitnagil.presentation.setting.model.ConfirmDialogType
sealed class SettingIntent : MviIntent {
data class LoadSettingSuccess(
@@ -10,6 +11,8 @@ sealed class SettingIntent : MviIntent {
val latestVersion: String,
) : SettingIntent()
+ data class ShowConfirmDialog(val type: ConfirmDialogType) : SettingIntent()
+ data object HideConfirmDialog : SettingIntent()
data object ToggleServiceAlarm : SettingIntent()
data object TogglePushAlarm : SettingIntent()
data object LogoutLoading : SettingIntent()
diff --git a/presentation/src/main/java/com/threegap/bitnagil/presentation/setting/model/mvi/SettingState.kt b/presentation/src/main/java/com/threegap/bitnagil/presentation/setting/model/mvi/SettingState.kt
index e2382526..a0b7166b 100644
--- a/presentation/src/main/java/com/threegap/bitnagil/presentation/setting/model/mvi/SettingState.kt
+++ b/presentation/src/main/java/com/threegap/bitnagil/presentation/setting/model/mvi/SettingState.kt
@@ -1,6 +1,7 @@
package com.threegap.bitnagil.presentation.setting.model.mvi
import com.threegap.bitnagil.presentation.common.mviviewmodel.MviState
+import com.threegap.bitnagil.presentation.setting.model.ConfirmDialogType
import kotlinx.parcelize.Parcelize
@Parcelize
@@ -10,6 +11,7 @@ data class SettingState(
val version: String,
val latestVersion: String,
val loading: Boolean,
+ val showConfirmDialog: ConfirmDialogType?,
) : MviState {
companion object {
val Init = SettingState(
@@ -18,6 +20,7 @@ data class SettingState(
version = "",
latestVersion = "",
loading = false,
+ showConfirmDialog = null,
)
}
}