Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[UI/#14] 회원가입 뷰 / UI 구현 #46

Merged
merged 24 commits into from
Jul 11, 2024
Merged
Show file tree
Hide file tree
Changes from 17 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
731883d
[FEAT/#14] navigateToSignUp()
leeeyubin Jul 10, 2024
ecd1f10
Merge branch 'develop' of https://github.com/teamterning/Terning-Andr…
leeeyubin Jul 10, 2024
d101e4e
[FEAT/#14] SignUpProfile 구현
leeeyubin Jul 10, 2024
bc3e526
[FEAT/#14] NameTextField
leeeyubin Jul 10, 2024
89405e7
[FIX/#14] 컨플릭 해결
leeeyubin Jul 10, 2024
b2671ce
[FIX/#14] 컨플릭 해결
leeeyubin Jul 10, 2024
e6f35ef
[FEAT/#14] SignUpTextField 구현
leeeyubin Jul 10, 2024
b01077a
[FEAT/#14] drawLineColor 구현
leeeyubin Jul 10, 2024
6372c07
[FEAT/#14] 회원가입 프로필 이름 구현
leeeyubin Jul 10, 2024
c2d1b25
[FEAT/#14] drawLineColor 구현
leeeyubin Jul 10, 2024
f9dbc60
[FEAT/#14] 회원가입 UI 구현
leeeyubin Jul 10, 2024
fc58c97
[FEAT/#14] RectangleButton 활성화, 비활성화 구현
leeeyubin Jul 10, 2024
0106f8e
[FEAT/#14] SignUpBottomSheet 연결
leeeyubin Jul 10, 2024
e7b273a
[FEAT/#14] 버튼 세밀 구현
leeeyubin Jul 10, 2024
ee0ca25
[FEAT/#14] startDestination 수정
leeeyubin Jul 10, 2024
f925bb4
[CHORE/#14] 코드 줄바꿈
leeeyubin Jul 10, 2024
02e7a05
[FEAT/#14] 글자수 제한
leeeyubin Jul 10, 2024
39ec9e6
[FIX/#14] solving conflict
leeeyubin Jul 11, 2024
cb3b7a0
[FIX/#14] solving conflict
leeeyubin Jul 11, 2024
0b584c1
Merge branch 'develop' of https://github.com/teamterning/Terning-Andr…
leeeyubin Jul 11, 2024
af144e7
[FEAT/#14] 비활성화 버튼 수정
leeeyubin Jul 11, 2024
4ab493f
[MOVE/#14] bottom sheet 위치 수정
leeeyubin Jul 11, 2024
0c69b82
[FEAT/#14] bottom sheet 사라지는 애니메이션 구현
leeeyubin Jul 11, 2024
e7d162b
[FEAT/#14] startDestination 수정
leeeyubin Jul 11, 2024
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
Original file line number Diff line number Diff line change
Expand Up @@ -6,25 +6,24 @@ import androidx.compose.ui.graphics.SolidColor
import com.terning.core.designsystem.theme.Black
import com.terning.core.designsystem.theme.Grey300
import com.terning.core.designsystem.theme.Grey400
import com.terning.core.designsystem.theme.Grey500
import com.terning.core.designsystem.theme.TerningMain
import com.terning.core.designsystem.theme.TerningTheme

@Composable
fun NameTextField(
text: String,
value: String,
onValueChange: (String) -> Unit,
hint: String,
drawLineColor: Color,
helperMessage: String,
helperColor: Color,
helperIcon: Int? = null,
helperColor: Color = TerningMain,
) {
TerningBasicTextField(
value = text,
value = value,
onValueChange = onValueChange,
textStyle = TerningTheme.typography.detail1,
textColor = Black,
drawLineColor = Grey500,
drawLineColor = drawLineColor,
cursorBrush = SolidColor(Grey400),
hint = hint,
hintColor = Grey300,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.terning.core.designsystem.component.textfield

import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.SolidColor
import com.terning.core.designsystem.theme.Grey300
import com.terning.core.designsystem.theme.Grey400
Expand Down Expand Up @@ -28,5 +29,6 @@ fun SearchTextField(
leftIcon = leftIcon,
leftIconColor = TerningMain,
readOnly = readOnly,
helperColor = TerningMain
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ fun TerningBasicTextField(
hint: String = "",
helperMessage: String = "",
helperIcon: Int? = null,
helperColor: Color = TerningMain,
helperColor: Color,
readOnly: Boolean = false,
) {
val keyboardController = LocalSoftwareKeyboardController.current
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import com.terning.feature.calendar.navigation.navigateCalendar
import com.terning.feature.home.navigation.navigateHome
import com.terning.feature.mypage.navigation.navigateMyPage
import com.terning.feature.onboarding.signin.navigation.SignIn
import com.terning.feature.search.navigation.Search
import com.terning.feature.search.navigation.navigateSearch

class MainNavigator(
Expand Down
4 changes: 3 additions & 1 deletion feature/src/main/java/com/terning/feature/main/MainScreen.kt
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import com.terning.core.util.NoRippleInteractionSource
import com.terning.feature.calendar.navigation.calendarNavGraph
import com.terning.feature.home.navigation.homeNavGraph
import com.terning.feature.mypage.navigation.myPageNavGraph
import com.terning.feature.onboarding.filtering.navigation.filteringNavGraph
import com.terning.feature.onboarding.signin.navigation.signInNavGraph
import com.terning.feature.onboarding.signup.navigation.signUpNavGraph
import com.terning.feature.search.navigation.searchNavGraph
Expand Down Expand Up @@ -67,7 +68,8 @@ fun MainScreen(
searchNavGraph()
myPageNavGraph()
signInNavGraph(navHostController = navigator.navController)
signUpNavGraph()
signUpNavGraph(navHostController = navigator.navController)
filteringNavGraph(navHostController = navigator.navController)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,17 @@
package com.terning.feature.onboarding.filtering

import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import com.terning.feature.onboarding.filtering.navigation.FilteringNavigation
import androidx.navigation.NavController

@Composable
fun FilteringRoute(){
fun FilteringRoute(
navController: NavController
) {
FilteringScreen()
}

}
@Composable
fun FilteringScreen() {
Text(text = "filtering")
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,30 @@
package com.terning.feature.onboarding.filtering.navigation

class FilteringNavigation {
}
import androidx.navigation.NavController
import androidx.navigation.NavGraphBuilder
import androidx.navigation.NavHostController
import androidx.navigation.NavOptions
import androidx.navigation.compose.composable
import com.terning.core.navigation.Route
import com.terning.feature.onboarding.filtering.FilteringRoute
import kotlinx.serialization.Serializable

fun NavController.navigateFiltering(navOptions: NavOptions? = null) {
navigate(
route = Filtering,
navOptions = navOptions
)
}

fun NavGraphBuilder.filteringNavGraph(
navHostController: NavHostController
) {
composable<Filtering> {
FilteringRoute(
navController = navHostController
)
}
}

@Serializable
data object Filtering : Route
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import com.terning.core.extension.toast
import com.terning.feature.R
import com.terning.feature.home.navigation.navigateHome
import com.terning.feature.onboarding.signin.component.KakaoButton
import com.terning.feature.onboarding.signup.navigation.navigateSignUp

@Composable
fun SignInRoute(
Expand All @@ -41,7 +42,7 @@ fun SignInRoute(
.collect { sideEffect ->
when (sideEffect) {
is SignInSideEffect.ShowToast -> context.toast(sideEffect.message)
is SignInSideEffect.NavigateToHome -> navController.navigateHome()
is SignInSideEffect.NavigateToHome -> navController.navigateSignUp()
}
}
}
Expand All @@ -56,7 +57,6 @@ fun SignInScreen(
modifier: Modifier = Modifier,
onSignInClick: () -> Unit = {},
) {

Column(
modifier = modifier
.wrapContentHeight()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import androidx.navigation.NavGraphBuilder
import androidx.navigation.NavHostController
import androidx.navigation.NavOptions
import androidx.navigation.compose.composable
import com.terning.core.navigation.MainTabRoute
import com.terning.core.navigation.Route
import com.terning.feature.onboarding.signin.SignInRoute
import kotlinx.serialization.Serializable

Expand All @@ -27,4 +27,4 @@ fun NavGraphBuilder.signInNavGraph(
}

@Serializable
data object SignIn : MainTabRoute
data object SignIn : Route
Original file line number Diff line number Diff line change
@@ -1,13 +1,126 @@
package com.terning.feature.onboarding.signup

import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Text
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.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.navigation.NavController
import com.terning.core.designsystem.component.button.RectangleButton
import com.terning.core.designsystem.component.textfield.NameTextField
import com.terning.core.designsystem.theme.TerningTheme
import com.terning.core.extension.addFocusCleaner
import com.terning.core.extension.noRippleClickable
import com.terning.feature.R
import com.terning.feature.onboarding.filtering.navigation.navigateFiltering
import com.terning.feature.onboarding.signup.component.SignUpBottomSheet
import com.terning.feature.onboarding.signup.component.SignUpProfile

@Composable
fun SignUpRoute() {
SignUpScreen()
fun SignUpRoute(
signUpViewModel: SignUpViewModel = hiltViewModel(),
navController: NavController
) {
val signUpState by signUpViewModel.state.collectAsStateWithLifecycle()
Comment on lines +33 to +36
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SignUpScreen이 아니라 SignUpRoute에서 뷰모델을 생성해서 넘기는 이유가 있나용!?? .....진짜모름

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

저는 화면을 그리는 UI하고 다른 로직을 적는 걸 분리하고 싶어서 SignUpRoute에서 생성했었습니다!
나중에 성공했을 때의 로직만 screen으로 넘기도록 리팩해볼게요!


SignUpScreen(
signUpViewModel = signUpViewModel,
signUpState = signUpState,
onButtonClick = { navController.navigateFiltering() }
)
}

@Composable
fun SignUpScreen() {
fun SignUpScreen(
modifier: Modifier = Modifier,
signUpState: SignUpState,
signUpViewModel: SignUpViewModel,
onButtonClick: () -> Unit
) {
val focusManager = LocalFocusManager.current
var showBottomSheet by remember { mutableStateOf(false) }

}
Column(
modifier = modifier
.fillMaxSize()
.addFocusCleaner(focusManager)
) {
Spacer(modifier = modifier.weight(1f))
Text(
text = stringResource(id = R.string.sign_up_title),
style = TerningTheme.typography.heading2,
modifier = modifier.padding(
bottom = 42.dp,
start = 24.dp
)
)
if (showBottomSheet) {
SignUpBottomSheet(
onDismiss = { showBottomSheet = false },
onSaveClick = { showBottomSheet = false }
)
}
Text(
text = stringResource(id = R.string.sign_up_profile_image),
style = TerningTheme.typography.body2,
modifier = modifier
.padding(
start = 24.dp,
bottom = 20.dp
)
)
Column(
modifier = modifier
.align(Alignment.CenterHorizontally)
.padding(bottom = 52.dp)
) {
SignUpProfile(
modifier = modifier.noRippleClickable {
showBottomSheet = true
}
)
}
Column(
modifier = modifier
.align(Alignment.CenterHorizontally)
.padding(horizontal = 24.dp)
) {
Text(
text = stringResource(id = R.string.sign_up_name),
modifier = modifier.padding(bottom = 20.dp)
)
NameTextField(
value = signUpState.name,
onValueChange = { name ->
signUpViewModel.isInputValid(name)
Comment on lines +105 to +108
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

뷰모델 네이밍 방식 통일해야 할 것 같은데 얘기해보면 좋을 것 같습니당!~!~~! ~~~!

},
hint = stringResource(id = R.string.sign_up_hint),
drawLineColor = signUpState.drawLineColor,
helperMessage = signUpState.helper,
helperIcon = signUpState.helperIcon,
helperColor = signUpState.helperColor
)
}
Spacer(modifier = modifier.weight(5f))
RectangleButton(
style = TerningTheme.typography.button1,
paddingVertical = 20.dp,
text = R.string.sign_up_next_button,
onButtonClick = { onButtonClick() },
modifier = modifier.padding(bottom = 12.dp),
isEnabled = signUpState.isButtonValid
)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.terning.feature.onboarding.signup

import androidx.compose.ui.graphics.Color
import com.terning.core.designsystem.theme.Grey400
import com.terning.core.designsystem.theme.Grey500
import com.terning.feature.onboarding.signup.SignUpViewModel.Companion.HELPER

data class SignUpState(
val name: String = "",
val character: Int = 0,
val drawLineColor: Color = Grey500,
val helper: String = HELPER,
val helperIcon: Int? = null,
val helperColor: Color = Grey400,
val isButtonValid : Boolean = false
)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

나중에 리컴포지션에 대한 리팩토링을 하게 된다면, 뷰모델에서 텍스트를 관리하는 것보단 스크린 자체에서 관리를 하는 방향의 수정을 시도해봐도 좋을 것 같아요!!

Original file line number Diff line number Diff line change
@@ -1,10 +1,62 @@
package com.terning.feature.onboarding.signup

import androidx.lifecycle.ViewModel
import com.terning.core.designsystem.theme.Grey400
import com.terning.core.designsystem.theme.Grey500
import com.terning.core.designsystem.theme.TerningMain
import com.terning.core.designsystem.theme.WarningRed
import com.terning.feature.R
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import javax.inject.Inject

@HiltViewModel
class SignUpViewModel @Inject constructor() : ViewModel(){
class SignUpViewModel @Inject constructor() : ViewModel() {

}
private val _state: MutableStateFlow<SignUpState> = MutableStateFlow(SignUpState())
val state: StateFlow<SignUpState> get() = _state.asStateFlow()

fun isInputValid(name: String) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Regex!! 새롭게 알아갑니다ㅎㅎㅎㅎ

val nameErrorRegex = Regex(NAME_ERROR)
val trimmedName = if (name.length > MAX_LENGTH) name.substring(0, MAX_LENGTH) else name

when {
nameErrorRegex.containsMatchIn(trimmedName) -> _state.value = _state.value.copy(
name = trimmedName,
drawLineColor = WarningRed,
helper = HELPER_ERROR,
helperIcon = R.drawable.ic_sign_up_error,
helperColor = WarningRed,
isButtonValid = false
)

trimmedName.isEmpty() -> _state.value = _state.value.copy(
name = trimmedName,
drawLineColor = Grey500,
helper = HELPER,
helperIcon = null,
helperColor = Grey400,
isButtonValid = false
)

else -> _state.value = _state.value.copy(
name = trimmedName,
drawLineColor = TerningMain,
helper = HELPER_AVAILABLE,
helperIcon = R.drawable.ic_sign_up_available,
helperColor = TerningMain,
isButtonValid = true
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이렇게 한번에 관리하니까 직관적이네요 ㅜ ㅜ 🥹

)
}
}

companion object {
const val NAME_ERROR = "[!@#\$%^&*(),.?\":{}|<>\\[\\]\\\\/]"
const val HELPER = "12자리 이내, 문자/숫자 가능, 특수문자/기호 입력불가"
private const val MAX_LENGTH = 12
private const val HELPER_ERROR = "이름에 특수문자는 입력할 수 없어요"
private const val HELPER_AVAILABLE = "이용 가능한 이름이에요"
}
Comment on lines +55 to +62
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

여기도 string으로 빼는게 가능할까요?? 가능하다면 string 분리하는게 더 좋을 것 같아서요...!

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

저도 그렇게 생각하는데 뷰모델에서 제대로 추출이 안 돼서,, 추후에 더 해보겠습니당

}
Loading
Loading