Skip to content

Commit

Permalink
#33 [feat] : 휴대폰 인증 뷰 구현
Browse files Browse the repository at this point in the history
  • Loading branch information
sayyyho committed Jan 17, 2025
1 parent 33e4595 commit 01f159d
Show file tree
Hide file tree
Showing 9 changed files with 191 additions and 26 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,6 @@ fun PreviewFullOptionBasicShortTextField() {
errorMessage = if (!isValid) "\"텍스트\"라고 입력해주세요." else ""
value = input
enabled = value != "불가"

},
errorMessage = errorMessage,
visibleLength = true,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ import kotlinx.serialization.Serializable
sealed interface Route {
@Serializable
data object TermsOfUse : Route
@Serializable
data object PhoneNumberAuth : Route
@Serializable
data object NickNameAuth : Route
}

sealed interface MainTabRoute : Route {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@ import com.sopt.withsuhyeon.feature.findsuhyeon.navigation.navigateToFindSuhyeon
import com.sopt.withsuhyeon.feature.gallery.navigation.navigateToGallery
import com.sopt.withsuhyeon.feature.home.navigation.navigateToHome
import com.sopt.withsuhyeon.feature.mypage.navigation.navigateToMyPage
import com.sopt.withsuhyeon.feature.onboarding.navigation.navigateToTermsOfUse
import com.sopt.withsuhyeon.feature.onboarding.navigation.navigateToNickNameAuth
import com.sopt.withsuhyeon.feature.onboarding.navigation.navigateToPhoneNumberAuth


class MainNavigator(
val navController: NavHostController,
Expand All @@ -25,7 +27,7 @@ class MainNavigator(
@Composable get() = navController
.currentBackStackEntryAsState().value?.destination

val startDestination = Route.TermsOfUse
val startDestination = Route.PhoneNumberAuth

val currentTab: MainTab?
@SuppressLint("RestrictedApi") @Composable get() = MainTab.find { tab ->
Expand All @@ -49,9 +51,12 @@ class MainNavigator(
MainTab.MYPAGE -> navController.navigateToMyPage(navOptions)
}
}
fun navigateToPhoneNumberAuth() {
navController.navigateToPhoneNumberAuth()
}

fun navigateToTermsOfUse() {
navController.navigateToTermsOfUse()
fun navigateToNicknameAuth() {
navController.navigateToNickNameAuth()
}

fun navigateToHome(navOptions: NavOptions? = null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import com.sopt.withsuhyeon.feature.gallery.navigation.galleryNavGraph
import com.sopt.withsuhyeon.feature.home.navigation.homeNavGraph
import com.sopt.withsuhyeon.feature.main.MainNavigator
import com.sopt.withsuhyeon.feature.mypage.navigation.myPageNavGraph
import com.sopt.withsuhyeon.feature.onboarding.navigation.termsOfUseNavGraph
import com.sopt.withsuhyeon.feature.onboarding.navigation.onBoardingNavGraph
import com.sopt.withsuhyeon.ui.theme.WithSuhyeonTheme.colors

@Composable
Expand Down Expand Up @@ -47,9 +47,9 @@ fun MainNavHost(
myPageNavGraph(
padding = padding,
)
termsOfUseNavGraph(
padding = padding,
onNavigateToNext = navigator::navigateToHome,
onBoardingNavGraph(
onNavigateToPhoneNumberAuth = navigator::navigateToPhoneNumberAuth,
onNavigateToNickNameAuth = navigator::navigateToNicknameAuth
)
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
package com.sopt.withsuhyeon.feature.onboarding

import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
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.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
import com.sopt.withsuhyeon.R
import com.sopt.withsuhyeon.core.component.button.BasicButtonForTextField
import com.sopt.withsuhyeon.core.component.button.LargeButton
import com.sopt.withsuhyeon.core.component.progressbar.AnimatedProgressBar
import com.sopt.withsuhyeon.core.component.textfield.BasicShortTextField
import com.sopt.withsuhyeon.core.util.KeyStorage.NEXT_BUTTON_TEXT
import com.sopt.withsuhyeon.feature.onboarding.components.OnBoardingTitle

@Composable
fun PhoneNumberAuthenticationRoute(
navigateToNext: () -> Unit,
viewModel: OnBoardingViewModel = hiltViewModel()
) {
PhoneNumberAuthenticationScreen(
onButtonClick = navigateToNext
)
}

@Composable
fun PhoneNumberAuthenticationScreen(
onButtonClick: () -> Unit,
modifier: Modifier = Modifier
) {
var phoneNumberValue by remember { mutableStateOf("") }
var isPhoneNumberInputValid by remember { mutableStateOf(false) }
var isPhoneNumberInputEnabled by remember { mutableStateOf(true) }
var isPhoneNumberInputFocused by remember { mutableStateOf(false) }
var isPhoneNumberAuthVisible by remember { mutableStateOf(false) }
var isPhoneNumberAuthButtonEnabled by remember { mutableStateOf(false) }
var phoneNumberAuthButtonText by remember { mutableStateOf("인증요청") }
var authNumberValue by remember { mutableStateOf("") }
var isAuthNumberInputValid by remember { mutableStateOf(false) }
var isAuthNumberInputEnabled by remember { mutableStateOf(true) }
var isAuthNumberInputFocused by remember { mutableStateOf(false) }

Column(
modifier = modifier
.padding(16.dp)
.fillMaxWidth()
.fillMaxHeight(),
) {
AnimatedProgressBar(progress = 0.33f)
Spacer(
modifier = Modifier.height(16.dp)
)
OnBoardingTitle(text = stringResource(R.string.onboarding_phone_number_title))
Spacer(
modifier = Modifier.height(32.dp)
)
BasicShortTextField(
value = phoneNumberValue,
title = stringResource(R.string.onboarding_phone_number_input_title),
hint = stringResource(R.string.onboarding_phone_number_input_hint),
isValid = isPhoneNumberInputValid,
enabled = isPhoneNumberInputEnabled,
onFocusChange = {
isPhoneNumberInputFocused = it
},
onValueChange = { input ->
isPhoneNumberInputValid = input.length == 11
isPhoneNumberAuthButtonEnabled = input.length == 11
phoneNumberValue = input
},
maxLength = 11,
errorMessage = stringResource(R.string.onboarding_phone_number_duplication_error_message),
trailingContent = {
BasicButtonForTextField(
text = phoneNumberAuthButtonText,
onClick = {
isPhoneNumberAuthVisible = true
isPhoneNumberAuthButtonEnabled = false
phoneNumberAuthButtonText = "전송완료"
},
modifier = Modifier,
enabled = isPhoneNumberAuthButtonEnabled
)
}
)
Spacer(
modifier = Modifier.height(12.dp)
)
if (isPhoneNumberAuthVisible) {
BasicShortTextField(
value = authNumberValue,
title = stringResource(R.string.onboarding_phone_number_auth_input_title),
hint = stringResource(R.string.onboarding_phone_number_auth_input_hint),
isValid = isAuthNumberInputValid,
enabled = isAuthNumberInputEnabled,
onFocusChange = {
isAuthNumberInputFocused = it
},
onValueChange = { input ->
isAuthNumberInputValid = input.length == 6
authNumberValue = input
},
maxLength = 6,
errorMessage = stringResource(R.string.onboarding_phone_number_duplication_error_message),
)
}
Spacer(modifier = Modifier.weight(1f))
LargeButton(
onClick = onButtonClick,
text = NEXT_BUTTON_TEXT,
isDisabled = !isAuthNumberInputValid
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package com.sopt.withsuhyeon.feature.onboarding
import androidx.compose.foundation.border
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxHeight
Expand All @@ -12,7 +11,6 @@ import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
Expand All @@ -32,17 +30,15 @@ import com.sopt.withsuhyeon.core.util.KeyStorage.CHECKED
import com.sopt.withsuhyeon.core.util.KeyStorage.DEFAULT
import com.sopt.withsuhyeon.core.util.KeyStorage.NEXT_BUTTON_TEXT
import com.sopt.withsuhyeon.core.util.KeyStorage.SECONDARY_TYPE
import com.sopt.withsuhyeon.feature.onboarding.components.OnBoardingTitle
import com.sopt.withsuhyeon.ui.theme.WithSuhyeonTheme.colors
import com.sopt.withsuhyeon.ui.theme.WithSuhyeonTheme.typography

@Composable
fun TermsOfUseRoute(
padding: PaddingValues,
navigateToNext: () -> Unit,
viewModel: OnBoardingViewModel = hiltViewModel()
) {
TermsOfUseScreen(
padding = padding,
onButtonClick = {
navigateToNext()
}
Expand All @@ -51,7 +47,6 @@ fun TermsOfUseRoute(

@Composable
fun TermsOfUseScreen(
padding: PaddingValues,
onButtonClick: () -> Unit,
modifier: Modifier = Modifier,

Expand All @@ -78,10 +73,7 @@ fun TermsOfUseScreen(
Spacer(
modifier = Modifier.height(16.dp)
)
Text(
text = stringResource(R.string.onboarding_temrs_of_use_title),
style = typography.title02_B,
)
OnBoardingTitle(stringResource(R.string.onboarding_temrs_of_use_title),)
Spacer(
modifier = Modifier.height(32.dp)
)
Expand Down Expand Up @@ -183,7 +175,9 @@ fun TermsOfUseScreen(
Spacer(modifier = Modifier.height(16.dp))
LargeButton(
onClick = {
// TODO - Navigate 시키기
if (isAllTermsSelected) {
onButtonClick()
}
},
text = NEXT_BUTTON_TEXT,
isDisabled = !isAllTermsSelected,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.sopt.withsuhyeon.feature.onboarding.components

import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import com.sopt.withsuhyeon.ui.theme.WithSuhyeonTheme.typography

@Composable
fun OnBoardingTitle(
text: String,
modifier: Modifier = Modifier
) {
Text(
modifier = modifier.padding(vertical = 20.dp),
text = text,
style = typography.title02_B,
)
}
Original file line number Diff line number Diff line change
@@ -1,24 +1,37 @@
package com.sopt.withsuhyeon.feature.onboarding.navigation

import androidx.compose.foundation.layout.PaddingValues
import androidx.navigation.NavController
import androidx.navigation.NavGraphBuilder
import androidx.navigation.compose.composable
import com.sopt.withsuhyeon.feature.onboarding.PhoneNumberAuthenticationRoute
import com.sopt.withsuhyeon.feature.onboarding.TermsOfUseRoute
import com.sopt.withsuhyeon.core.navigation.Route.TermsOfUse as TermsOfUseRoute
import com.sopt.withsuhyeon.core.navigation.Route.PhoneNumberAuth as PhoneNumberAuthRoute
import com.sopt.withsuhyeon.core.navigation.Route.NickNameAuth as NickNameAuthRoute

fun NavController.navigateToTermsOfUse() {
navigate(TermsOfUseRoute)
}
fun NavController.navigateToPhoneNumberAuth() {
navigate(PhoneNumberAuthRoute)
}

fun NavController.navigateToNickNameAuth() {
navigate(NickNameAuthRoute)
}

fun NavGraphBuilder.termsOfUseNavGraph(
padding: PaddingValues,
onNavigateToNext: () -> Unit
fun NavGraphBuilder.onBoardingNavGraph(
onNavigateToPhoneNumberAuth: () -> Unit,
onNavigateToNickNameAuth: () -> Unit
) {
composable<TermsOfUseRoute> {
TermsOfUseRoute(
padding = padding,
navigateToNext = onNavigateToNext
navigateToNext = onNavigateToPhoneNumberAuth
)
}
composable<PhoneNumberAuthRoute> {
PhoneNumberAuthenticationRoute(
navigateToNext = onNavigateToNickNameAuth
)
}
}
6 changes: 6 additions & 0 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -75,4 +75,10 @@
<string name="onboarding_terms_of_use_age">[필수] 만 18세 이상</string>
<string name="onboarding_terms_of_use_agree">[필수] 이용약관 동의</string>
<string name="onboarding_temrs_of_use_personal_information">[필수] 개인정보 처리방침 동의</string>
<string name="onboarding_phone_number_title">본인인증을 위한\n휴대폰 번호 인증이 필요해요</string>
<string name="onboarding_phone_number_duplication_error_message">이미 가입된 번호입니다</string>
<string name="onboarding_phone_number_input_title">휴대폰 번호</string>
<string name="onboarding_phone_number_input_hint"> - 를 제외한 휴대폰 번호를 입력해주세요</string>
<string name="onboarding_phone_number_auth_input_title">인증 번호 (6자리)</string>
<string name="onboarding_phone_number_auth_input_hint">인증번호 6자리</string>
</resources>

0 comments on commit 01f159d

Please sign in to comment.