diff --git a/app/src/main/java/com/kikidan/todakun/TodakunApp.kt b/app/src/main/java/com/kikidan/todakun/TodakunApp.kt
index 901d878f..2b3afbc1 100644
--- a/app/src/main/java/com/kikidan/todakun/TodakunApp.kt
+++ b/app/src/main/java/com/kikidan/todakun/TodakunApp.kt
@@ -145,6 +145,7 @@ fun TodakunApp(
onFinish = { navigator.resetTo(TodakunRoute.Home) },
onNavigateTerm = { navigator.goBack() },
onboardingToken = OnboardingToken(route.onboardingToken),
+ snackbarHostState = snackbarHostState,
)
}
diff --git a/core/designsystem/src/main/res/values/strings.xml b/core/designsystem/src/main/res/values/strings.xml
index c6051eb1..f7605165 100644
--- a/core/designsystem/src/main/res/values/strings.xml
+++ b/core/designsystem/src/main/res/values/strings.xml
@@ -314,6 +314,8 @@
다음
시작하기
확인
+ 회원가입에 실패했어요. 잠시 후 다시 시도해주세요
+ 입력한 정보를 다시 확인해주세요.
약관 동의
diff --git a/feature/auth/src/main/java/com/kikidan/auth/component/SocialLoginButton.kt b/feature/auth/src/main/java/com/kikidan/auth/component/SocialLoginButton.kt
index a3a4f346..8436459e 100644
--- a/feature/auth/src/main/java/com/kikidan/auth/component/SocialLoginButton.kt
+++ b/feature/auth/src/main/java/com/kikidan/auth/component/SocialLoginButton.kt
@@ -11,6 +11,7 @@ import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.RoundedCornerShape
+import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.Text
import androidx.compose.material3.ripple
import androidx.compose.runtime.Composable
@@ -58,6 +59,7 @@ internal fun SocialLoginButton(
provider: SocialLoginProvider,
onClick: () -> Unit,
modifier: Modifier = Modifier,
+ isLoading: Boolean = false,
) {
Box(
modifier =
@@ -74,20 +76,28 @@ internal fun SocialLoginButton(
),
contentAlignment = Alignment.Center,
) {
- Row(
- verticalAlignment = Alignment.CenterVertically,
- horizontalArrangement = Arrangement.spacedBy(8.dp),
- ) {
- Image(
- painter = painterResource(id = provider.iconRes),
- contentDescription = null,
+ if (isLoading) {
+ CircularProgressIndicator(
modifier = Modifier.size(20.dp),
- )
- Text(
- text = stringResource(id = provider.labelRes),
- style = TodakunTypography.body2Medium,
color = provider.contentColor,
+ strokeWidth = 2.dp,
)
+ } else {
+ Row(
+ verticalAlignment = Alignment.CenterVertically,
+ horizontalArrangement = Arrangement.spacedBy(8.dp),
+ ) {
+ Image(
+ painter = painterResource(id = provider.iconRes),
+ contentDescription = null,
+ modifier = Modifier.size(20.dp),
+ )
+ Text(
+ text = stringResource(id = provider.labelRes),
+ style = TodakunTypography.body2Medium,
+ color = provider.contentColor,
+ )
+ }
}
}
}
diff --git a/feature/auth/src/main/java/com/kikidan/auth/screen/LoginScreen.kt b/feature/auth/src/main/java/com/kikidan/auth/screen/LoginScreen.kt
index a391f07f..4e2259f7 100644
--- a/feature/auth/src/main/java/com/kikidan/auth/screen/LoginScreen.kt
+++ b/feature/auth/src/main/java/com/kikidan/auth/screen/LoginScreen.kt
@@ -13,6 +13,11 @@ import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.systemBarsPadding
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
@@ -34,6 +39,10 @@ internal fun LoginScreen(
modifier: Modifier = Modifier,
) {
val loginEnabled = state is LoginState.Idle || state is LoginState.Failure
+ var loadingProvider by remember { mutableStateOf(null) }
+ LaunchedEffect(state) {
+ if (state !is LoginState.Loading) loadingProvider = null
+ }
Box(
modifier =
modifier
@@ -77,8 +86,12 @@ internal fun LoginScreen(
SocialLoginProvider.entries.forEach { provider ->
SocialLoginButton(
enabled = loginEnabled,
+ isLoading = state is LoginState.Loading && loadingProvider == provider,
provider = provider,
- onClick = { onProviderClick(provider) },
+ onClick = {
+ loadingProvider = provider
+ onProviderClick(provider)
+ },
)
}
}
diff --git a/feature/onboarding/src/main/java/com/kikidan/onboarding/OnboardingRoute.kt b/feature/onboarding/src/main/java/com/kikidan/onboarding/OnboardingRoute.kt
index 586058b3..db38745a 100644
--- a/feature/onboarding/src/main/java/com/kikidan/onboarding/OnboardingRoute.kt
+++ b/feature/onboarding/src/main/java/com/kikidan/onboarding/OnboardingRoute.kt
@@ -5,6 +5,7 @@ import android.os.Build
import androidx.activity.compose.BackHandler
import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.result.contract.ActivityResultContracts
+import androidx.compose.material3.SnackbarHostState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
@@ -12,7 +13,9 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
+import androidx.compose.ui.res.stringResource
import androidx.hilt.navigation.compose.hiltViewModel
+import com.kikidan.designsystem.R
import com.kikidan.designsystem.component.wheelpicker.BirthDateState
import com.kikidan.designsystem.component.wheelpicker.BirthDateWheelPicker
import com.kikidan.designsystem.component.wheelpicker.SajuBirthTimeWheelPicker
@@ -34,6 +37,7 @@ fun OnboardingRoute(
onFinish: () -> Unit,
onNavigateTerm: () -> Unit,
onboardingToken: OnboardingToken,
+ snackbarHostState: SnackbarHostState,
modifier: Modifier = Modifier,
viewModel: OnboardingViewModel = hiltViewModel(),
) {
@@ -48,6 +52,8 @@ fun OnboardingRoute(
// 권한을 허락하지 않더라도 앱 진입
permissionHandled = true
}
+ val signupErrorMessage = stringResource(R.string.onboarding_signup_error)
+ val invalidInputErrorMessage = stringResource(R.string.onboarding_invalid_input_error)
viewModel.collectSideEffect { sideEffect ->
when (sideEffect) {
@@ -67,7 +73,13 @@ fun OnboardingRoute(
}
}
- else -> { /* TODO 에러 처리 스낵바 또는 다이얼로그 */ }
+ OnboardingSideEffect.InvalidInput -> {
+ snackbarHostState.showSnackbar(invalidInputErrorMessage)
+ }
+
+ is OnboardingSideEffect.Failure -> {
+ snackbarHostState.showSnackbar(signupErrorMessage)
+ }
}
}