diff --git a/app/build.gradle.kts b/app/build.gradle.kts index cc91936f..50aee71b 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -92,4 +92,8 @@ dependencies { //실시간 위치 implementation(libs.play.services.location) + + // 회원가입 + implementation ("androidx.compose.foundation:foundation:1.4.0") + } \ No newline at end of file diff --git a/app/src/main/java/com/paw/key/core/designsystem/component/CourseDetail.kt b/app/src/main/java/com/paw/key/core/designsystem/component/CourseDetail.kt index 854f9cb9..e38cdd4d 100644 --- a/app/src/main/java/com/paw/key/core/designsystem/component/CourseDetail.kt +++ b/app/src/main/java/com/paw/key/core/designsystem/component/CourseDetail.kt @@ -15,6 +15,7 @@ import androidx.compose.foundation.layout.width import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material3.Divider +import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.Icon import androidx.compose.material3.Text import androidx.compose.runtime.Composable @@ -152,7 +153,7 @@ fun CourseDetail( style = PawKeyTheme.typography.caption12Sb1, color = PawKeyTheme.colors.gray200 ) - Divider(modifier = Modifier.padding(10.dp)) + HorizontalDivider(modifier = Modifier.padding(10.dp)) Text( text = "이런 점이 좋았어요", diff --git a/app/src/main/java/com/paw/key/core/designsystem/component/PawkeyButton.kt b/app/src/main/java/com/paw/key/core/designsystem/component/PawkeyButton.kt index 97e7e4dd..d64b2b60 100644 --- a/app/src/main/java/com/paw/key/core/designsystem/component/PawkeyButton.kt +++ b/app/src/main/java/com/paw/key/core/designsystem/component/PawkeyButton.kt @@ -1,6 +1,9 @@ package com.paw.key.core.designsystem.component import androidx.compose.foundation.BorderStroke +import androidx.compose.foundation.background +import androidx.compose.foundation.border +import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxWidth @@ -11,11 +14,14 @@ import androidx.compose.material3.Button import androidx.compose.material3.ButtonDefaults import androidx.compose.material3.Text import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color +import androidx.compose.ui.draw.clip import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import com.paw.key.core.designsystem.theme.PawKeyTheme +import com.paw.key.core.util.noRippleClickable @Preview(showBackground = true) @@ -91,7 +97,6 @@ fun PawkeyButton( } val borderColor = when { - isBorder -> Color.Transparent enabled && isBackGround -> PawKeyTheme.colors.green500 !enabled && isBackGround -> PawKeyTheme.colors.gray200 else -> PawKeyTheme.colors.white1 diff --git a/app/src/main/java/com/paw/key/core/designsystem/component/SubChip.kt b/app/src/main/java/com/paw/key/core/designsystem/component/SubChip.kt index 590e8144..5e7cd4f7 100644 --- a/app/src/main/java/com/paw/key/core/designsystem/component/SubChip.kt +++ b/app/src/main/java/com/paw/key/core/designsystem/component/SubChip.kt @@ -17,7 +17,6 @@ private fun PreviewSubChip() { SubChip( text = "4km" ) - } @Composable @@ -36,9 +35,7 @@ fun SubChip( Text( text = text, color = PawKeyTheme.colors.gray300, - style = PawKeyTheme.typography.body14M ) } - } \ No newline at end of file diff --git a/app/src/main/java/com/paw/key/core/designsystem/theme/Type.kt b/app/src/main/java/com/paw/key/core/designsystem/theme/Type.kt index 7c8cc441..86ae6931 100644 --- a/app/src/main/java/com/paw/key/core/designsystem/theme/Type.kt +++ b/app/src/main/java/com/paw/key/core/designsystem/theme/Type.kt @@ -22,6 +22,8 @@ val PretendardRegular = FontFamily(Font(R.font.pretendard_regular, FontWeight.No // Todo : 네이밍과 함께 나중에 lineHeight 등 변경 예정 @Stable class PawKeyTypography internal constructor( + head24B: TextStyle, + head24Sb: TextStyle, head22B: TextStyle, head22Sb: TextStyle, head20B1: TextStyle, @@ -38,6 +40,10 @@ class PawKeyTypography internal constructor( caption12M: TextStyle, caption12R: TextStyle ) { + var head24B: TextStyle by mutableStateOf(head24B) + private set + var head24Sb: TextStyle by mutableStateOf(head24B) + private set var head22B: TextStyle by mutableStateOf(head22B) private set var head22Sb: TextStyle by mutableStateOf(head22Sb) @@ -70,6 +76,8 @@ class PawKeyTypography internal constructor( private set fun copy( + head24B: TextStyle = this.head24B, + head24Sb: TextStyle = this.head24Sb, head22B: TextStyle = this.head22B, head22Sb: TextStyle = this.head22Sb, head20B1: TextStyle = this.head20B1, @@ -86,6 +94,8 @@ class PawKeyTypography internal constructor( caption12M: TextStyle = this.caption12M, caption12R: TextStyle = this.caption12R ): PawKeyTypography = PawKeyTypography( + head24B, + head24Sb, head22B, head22Sb, head20B1, @@ -104,6 +114,8 @@ class PawKeyTypography internal constructor( ) fun update(other: PawKeyTypography) { + head24B = other.head24B + head24Sb = other.head24Sb head22B = other.head22B head22Sb = other.head22Sb head20B1 = other.head20B1 @@ -143,6 +155,20 @@ fun pawKeyTextStyle( @Composable fun pawKeyTypography(): PawKeyTypography { return PawKeyTypography( + head24B = pawKeyTextStyle( + fontFamily = PretendardBold, + fontWeight = FontWeight.Bold, + fontSize = 24.sp, + lineHeight = (24 * 1.0).sp, + letterSpacing = TextUnit.Unspecified + ), + head24Sb = pawKeyTextStyle( + fontFamily = PretendardSemiBold, + fontWeight = FontWeight.SemiBold, + fontSize = 24.sp, + lineHeight = (24 * 1.4).sp, + letterSpacing = TextUnit.Unspecified + ), head22B = pawKeyTextStyle( fontFamily = PretendardBold, fontWeight = FontWeight.Bold, diff --git a/app/src/main/java/com/paw/key/presentation/ui/home/HomeScreen.kt b/app/src/main/java/com/paw/key/presentation/ui/home/HomeScreen.kt index afa84a16..234945e2 100644 --- a/app/src/main/java/com/paw/key/presentation/ui/home/HomeScreen.kt +++ b/app/src/main/java/com/paw/key/presentation/ui/home/HomeScreen.kt @@ -1,3 +1,5 @@ +@file:Suppress("DEPRECATION") + package com.paw.key.presentation.ui.home import android.app.Activity @@ -14,15 +16,17 @@ import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.width -import androidx.compose.material3.SnackbarHostState import androidx.compose.runtime.Composable import androidx.compose.runtime.SideEffect +import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.getValue import androidx.compose.runtime.remember import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.toArgb import androidx.compose.ui.platform.LocalView +import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.core.view.ViewCompat import androidx.hilt.navigation.compose.hiltViewModel @@ -37,21 +41,28 @@ import com.paw.key.presentation.ui.home.component.TrackingCard import com.paw.key.presentation.ui.home.component.WeatherCard import com.paw.key.presentation.ui.home.viewmodel.HomeViewModel +@Preview +@Composable +private fun HomeScreenPreview() { + PawKeyTheme { + HomeScreen( + paddingValues = PaddingValues(), + navigateNext = {},) + } + +} + @Composable fun HomeRoute( paddingValues: PaddingValues, - navigateUp: () -> Unit, navigateNext: () -> Unit, - snackBarHostState: SnackbarHostState, modifier: Modifier = Modifier, viewModel: HomeViewModel = hiltViewModel(), ) { HomeScreen( paddingValues = paddingValues, - navigateUp = navigateUp, navigateNext = navigateNext, - snackBarHostState = snackBarHostState, modifier = modifier, viewModel = viewModel ) @@ -60,13 +71,11 @@ fun HomeRoute( @Composable fun HomeScreen( paddingValues: PaddingValues, - navigateUp: () -> Unit, navigateNext: () -> Unit, - snackBarHostState: SnackbarHostState, modifier: Modifier = Modifier, - viewModel: HomeViewModel, + viewModel: HomeViewModel = hiltViewModel(), ) { - val isLocationMenuVisible = viewModel.isLocationMenuVisible + val state by viewModel.state.collectAsState() val view = LocalView.current val window = (view.context as? Activity)?.window @@ -113,7 +122,7 @@ fun HomeScreen( Spacer(modifier = Modifier.width(12.dp)) - TrackingCard(onClick = {navigateNext()}) + TrackingCard(onClick = { navigateNext() }) } Spacer(modifier = Modifier.height(12.dp)) @@ -124,7 +133,7 @@ fun HomeScreen( } } - if (isLocationMenuVisible) { + if (state.isLocationMenuVisible) { Box( modifier = Modifier .fillMaxSize() @@ -146,20 +155,3 @@ fun HomeScreen( } } } - -//@Preview -//@Composable -//private fun HomeScreenPreview() { -// PawKeyTheme { -// HomeScreen( -// paddingValues = PaddingValues(), -// navigateUp = {}, -// navigateNext = {}, -// snackBarHostState = SnackbarHostState(), -// -// ) -// -// } -// -//} -// viewmodel 을 파라미터로 넣으면 못본다! 알고싶지않았음 diff --git a/app/src/main/java/com/paw/key/presentation/ui/home/component/DaytimeCard.kt b/app/src/main/java/com/paw/key/presentation/ui/home/component/DaytimeCard.kt index 4e8d3ad7..ea38973a 100644 --- a/app/src/main/java/com/paw/key/presentation/ui/home/component/DaytimeCard.kt +++ b/app/src/main/java/com/paw/key/presentation/ui/home/component/DaytimeCard.kt @@ -20,19 +20,20 @@ import com.paw.key.core.designsystem.theme.PawKeyTheme @Preview(showBackground = true) @Composable -private fun previewDaytimeCard() { +private fun PreviewDaytimeCard() { PawKeyTheme { DaytimeCard(daytime = "05:06", daystate = "일출") } } @Composable -internal fun DaytimeCard( +fun DaytimeCard( daytime: String, daystate: String, + modifier: Modifier = Modifier, ) { Box( - modifier = Modifier + modifier = modifier .width(81.dp) .height(110.dp) .background(color = PawKeyTheme.colors.white1) @@ -42,7 +43,6 @@ internal fun DaytimeCard( horizontalAlignment = Alignment.CenterHorizontally, verticalArrangement = Arrangement.spacedBy(31.dp), modifier = Modifier - .fillMaxWidth() .fillMaxWidth() .padding(horizontal = 11.dp, vertical = 12.dp), ) { diff --git a/app/src/main/java/com/paw/key/presentation/ui/home/component/HistoryCard.kt b/app/src/main/java/com/paw/key/presentation/ui/home/component/HistoryCard.kt index 22df4cc0..c6e17b31 100644 --- a/app/src/main/java/com/paw/key/presentation/ui/home/component/HistoryCard.kt +++ b/app/src/main/java/com/paw/key/presentation/ui/home/component/HistoryCard.kt @@ -33,20 +33,20 @@ private fun PreviewHistoryCard() { } @Composable -internal fun HistoryCard( - +fun HistoryCard( + modifier: Modifier = Modifier, ) { Box( - modifier = Modifier + modifier = modifier .fillMaxWidth() .height(298.dp) + .clip(RoundedCornerShape(12.dp)) .background( color = PawKeyTheme.colors.white2, - shape = RoundedCornerShape(12.dp) ), + ) { - Column() - { + Column { Box( modifier = Modifier .fillMaxWidth() diff --git a/app/src/main/java/com/paw/key/presentation/ui/home/component/HistoryChip.kt b/app/src/main/java/com/paw/key/presentation/ui/home/component/HistoryChip.kt index 51d98a97..1ebfc6ce 100644 --- a/app/src/main/java/com/paw/key/presentation/ui/home/component/HistoryChip.kt +++ b/app/src/main/java/com/paw/key/presentation/ui/home/component/HistoryChip.kt @@ -22,7 +22,7 @@ private fun PreviewHistoryChip() { } @Composable -internal fun HistoryChip( +fun HistoryChip( text: String, modifier: Modifier = Modifier, ) { diff --git a/app/src/main/java/com/paw/key/presentation/ui/home/component/RowCalendar.kt b/app/src/main/java/com/paw/key/presentation/ui/home/component/RowCalendar.kt index 45a1935e..e35f7f49 100644 --- a/app/src/main/java/com/paw/key/presentation/ui/home/component/RowCalendar.kt +++ b/app/src/main/java/com/paw/key/presentation/ui/home/component/RowCalendar.kt @@ -52,11 +52,12 @@ private fun PreviewRowCalendar() { } @Composable -internal fun RowCalendar( +fun RowCalendar( date: String, + modifier: Modifier = Modifier, ) { Box( - modifier = Modifier + modifier = modifier .fillMaxWidth() .height(103.dp) .border( @@ -100,11 +101,12 @@ internal fun RowCalendar( private fun CalendarItem( date: String, day: String, + modifier: Modifier = Modifier, state: Boolean = false, ) { Column( horizontalAlignment = Alignment.CenterHorizontally, - modifier = Modifier + modifier = modifier .width(42.dp) .height(74.dp), ) { diff --git a/app/src/main/java/com/paw/key/presentation/ui/home/component/SettingButton.kt b/app/src/main/java/com/paw/key/presentation/ui/home/component/SettingButton.kt index 57c852ee..3939e4ce 100644 --- a/app/src/main/java/com/paw/key/presentation/ui/home/component/SettingButton.kt +++ b/app/src/main/java/com/paw/key/presentation/ui/home/component/SettingButton.kt @@ -30,7 +30,7 @@ private fun PreviewSettingButton() { } @Composable -internal fun SettingButton(){ +fun SettingButton(){ Box( modifier = Modifier .height(64.dp) diff --git a/app/src/main/java/com/paw/key/presentation/ui/home/component/TopBar.kt b/app/src/main/java/com/paw/key/presentation/ui/home/component/TopBar.kt index 49581be0..8df477fc 100644 --- a/app/src/main/java/com/paw/key/presentation/ui/home/component/TopBar.kt +++ b/app/src/main/java/com/paw/key/presentation/ui/home/component/TopBar.kt @@ -38,7 +38,7 @@ private fun PreviewTopBar() { } @Composable -internal fun TopBar( +fun TopBar( location: String, onLocationClick: () -> Unit, modifier: Modifier = Modifier, diff --git a/app/src/main/java/com/paw/key/presentation/ui/home/component/TrackingCard.kt b/app/src/main/java/com/paw/key/presentation/ui/home/component/TrackingCard.kt index a3916a7f..029baf6a 100644 --- a/app/src/main/java/com/paw/key/presentation/ui/home/component/TrackingCard.kt +++ b/app/src/main/java/com/paw/key/presentation/ui/home/component/TrackingCard.kt @@ -25,7 +25,7 @@ private fun PreviewTrackingCard() { } @Composable -internal fun TrackingCard( +fun TrackingCard( onClick: () -> Unit, ) { Box( diff --git a/app/src/main/java/com/paw/key/presentation/ui/home/component/WeatherCard.kt b/app/src/main/java/com/paw/key/presentation/ui/home/component/WeatherCard.kt index c5e96727..5930752a 100644 --- a/app/src/main/java/com/paw/key/presentation/ui/home/component/WeatherCard.kt +++ b/app/src/main/java/com/paw/key/presentation/ui/home/component/WeatherCard.kt @@ -34,7 +34,7 @@ private fun PreviewWeatherCard() { } @Composable -internal fun WeatherCard( +fun WeatherCard( weathertitle: String, weathersub1: String, weathersub2: String, @@ -63,12 +63,12 @@ internal fun WeatherCard( style = PawKeyTheme.typography.head22B.copy( fontSize = 24.sp ), - modifier = modifier.padding(start = 4.dp), + modifier = Modifier.padding(start = 4.dp), ) Row( verticalAlignment = Alignment.CenterVertically, - modifier = modifier.padding(start = 8.dp), + modifier = Modifier.padding(start = 8.dp), ) { Text( text = weathersub1, @@ -79,7 +79,7 @@ internal fun WeatherCard( text = weathersub2, style = PawKeyTheme.typography.body14R, color = PawKeyTheme.colors.black.copy(alpha = 0.5f), - modifier = modifier.padding(start = 6.dp), + modifier = Modifier.padding(start = 6.dp), ) } diff --git a/app/src/main/java/com/paw/key/presentation/ui/home/navigation/HomeNavigation.kt b/app/src/main/java/com/paw/key/presentation/ui/home/navigation/HomeNavigation.kt index 72f24dfa..9df33869 100644 --- a/app/src/main/java/com/paw/key/presentation/ui/home/navigation/HomeNavigation.kt +++ b/app/src/main/java/com/paw/key/presentation/ui/home/navigation/HomeNavigation.kt @@ -1,7 +1,6 @@ package com.paw.key.presentation.ui.home.navigation import androidx.compose.foundation.layout.PaddingValues -import androidx.compose.material3.SnackbarHostState import androidx.compose.ui.Modifier import androidx.navigation.NavController import androidx.navigation.NavGraphBuilder @@ -19,17 +18,13 @@ fun NavController.navigateHome( fun NavGraphBuilder.homeNavGraph( paddingValues: PaddingValues, - navigateUp: () -> Unit, navigateNext: () -> Unit, - snackBarHostState: SnackbarHostState, modifier: Modifier = Modifier ) { composable { HomeRoute( paddingValues = paddingValues, - navigateUp = navigateUp, navigateNext = navigateNext, - snackBarHostState = snackBarHostState, modifier = modifier ) } diff --git a/app/src/main/java/com/paw/key/presentation/ui/home/state/HomeContract.kt b/app/src/main/java/com/paw/key/presentation/ui/home/state/HomeContract.kt new file mode 100644 index 00000000..2b545ea7 --- /dev/null +++ b/app/src/main/java/com/paw/key/presentation/ui/home/state/HomeContract.kt @@ -0,0 +1,9 @@ +package com.paw.key.presentation.ui.home.state + +import androidx.compose.runtime.Immutable + +@Immutable +data class HomeState( + val isLocationMenuVisible: Boolean = false, + val isVisible: Boolean = false, +) \ No newline at end of file diff --git a/app/src/main/java/com/paw/key/presentation/ui/home/viewmodel/HomeViewModel.kt b/app/src/main/java/com/paw/key/presentation/ui/home/viewmodel/HomeViewModel.kt index 27e4679c..764f3f3e 100644 --- a/app/src/main/java/com/paw/key/presentation/ui/home/viewmodel/HomeViewModel.kt +++ b/app/src/main/java/com/paw/key/presentation/ui/home/viewmodel/HomeViewModel.kt @@ -1,24 +1,34 @@ package com.paw.key.presentation.ui.home.viewmodel -import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.setValue import androidx.lifecycle.ViewModel +import com.paw.key.presentation.ui.home.state.HomeState 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 HomeViewModel @Inject constructor( +class HomeViewModel @Inject constructor() : ViewModel() { -) : ViewModel() { - var isLocationMenuVisible by mutableStateOf(false) - private set + private val _state = MutableStateFlow(HomeState()) + val state: StateFlow = _state.asStateFlow() fun toggleLocationMenu() { - isLocationMenuVisible = !isLocationMenuVisible + _state.value = _state.value.copy( + isLocationMenuVisible = !_state.value.isLocationMenuVisible + ) } fun hideLocationMenu() { - isLocationMenuVisible = false + _state.value = _state.value.copy( + isLocationMenuVisible = false + ) + } + + fun toggleVisible() { + _state.value = _state.value.copy( + isVisible = !_state.value.isVisible + ) } } diff --git a/app/src/main/java/com/paw/key/presentation/ui/login/navigation/LoginNavigation.kt b/app/src/main/java/com/paw/key/presentation/ui/login/navigation/LoginNavigation.kt index 2d15f6d5..bd565803 100644 --- a/app/src/main/java/com/paw/key/presentation/ui/login/navigation/LoginNavigation.kt +++ b/app/src/main/java/com/paw/key/presentation/ui/login/navigation/LoginNavigation.kt @@ -9,6 +9,7 @@ import androidx.navigation.NavGraphBuilder import androidx.navigation.NavOptions import androidx.navigation.compose.composable import com.paw.key.core.navigation.Route +import com.paw.key.presentation.ui.home.navigation.navigateHome import com.paw.key.presentation.ui.login.LoginRoute import kotlinx.serialization.Serializable diff --git a/app/src/main/java/com/paw/key/presentation/ui/main/MainNavigator.kt b/app/src/main/java/com/paw/key/presentation/ui/main/MainNavigator.kt index bb758e2e..3a75bfdb 100644 --- a/app/src/main/java/com/paw/key/presentation/ui/main/MainNavigator.kt +++ b/app/src/main/java/com/paw/key/presentation/ui/main/MainNavigator.kt @@ -25,7 +25,12 @@ import com.paw.key.presentation.ui.mypage.navigation.navigateUserProfile import com.paw.key.presentation.ui.region.navigation.navigateRegional import com.paw.key.presentation.ui.mypage.navigation.navigateMyPage import com.paw.key.presentation.ui.onboard.navigation.navigateOnboarding +import com.paw.key.presentation.ui.signup.navigation.navigateSignLevel +import com.paw.key.presentation.ui.signup.navigation.navigateSignUp +import com.paw.key.presentation.ui.signup.navigation.navigateSignUpActivity +import com.paw.key.presentation.ui.signup.navigation.navigateSignUpDog import com.paw.key.presentation.ui.splash.navigation.Splash +import com.paw.key.presentation.ui.splash.navigation.navigateSplash class MainNavigator( val navController: NavHostController, @@ -77,15 +82,15 @@ class MainNavigator( navController.navigateLogin(navOptions = navOptions) } - /*메인 탭 이동*/ - fun navigateMyPage(navOptions: NavOptions? = null) { - navController.navigateMyPage(navOptions = navOptions) + fun navigateSignUp(navOptions: NavOptions? = null) { + navController.navigateSignUp(navOptions = navOptions) } - + /*메인 탭 이동*/ fun navigateMyPage(navOptions: NavOptions? = null) { navController.navigateMyPage(navOptions = navOptions) } + fun navigateUserProfile(navOptions: NavOptions? = null) { navController.navigateUserProfile(navOptions = navOptions) } @@ -135,14 +140,24 @@ class MainNavigator( navController.navigateSplash(navOptions = navOptions) } - fun navigateLogin(navOptions: NavOptions? = null) { - navController.navigateLogin(navOptions = navOptions) - } - fun navigateRegional(navOptions: NavOptions? = null) { navController.navigateRegional(navOptions = navOptions) } + fun navigateSignUpActivity(navOptions: NavOptions? = null) { + navController.navigateSignUpActivity(navOptions = navOptions) + } + + fun navigateSignUpDog(navOptions: NavOptions? = null) { + navController.navigateSignUpDog(navOptions = navOptions) + } + + fun navigateSignUpLevel(navOptions: NavOptions? = null) { + navController.navigateSignLevel(navOptions = navOptions) + } + + + @Composable fun showBottomBar() = MainTab.contains { currentDestination?.hasRoute(it::class) == true @@ -155,4 +170,3 @@ fun rememberMainNavigator( ): MainNavigator = remember(navController) { MainNavigator(navController) } - diff --git a/app/src/main/java/com/paw/key/presentation/ui/main/PawKeyNavHost.kt b/app/src/main/java/com/paw/key/presentation/ui/main/PawKeyNavHost.kt index 9770b7c5..3f18279a 100644 --- a/app/src/main/java/com/paw/key/presentation/ui/main/PawKeyNavHost.kt +++ b/app/src/main/java/com/paw/key/presentation/ui/main/PawKeyNavHost.kt @@ -27,6 +27,10 @@ import com.paw.key.presentation.ui.mypage.navigation.savedCourseNavGraph import com.paw.key.presentation.ui.mypage.navigation.userProfileNavGraph import com.paw.key.presentation.ui.region.navigation.regionalNavGraph import com.paw.key.presentation.ui.mypage.navigation.myPageNavGraph +import com.paw.key.presentation.ui.signup.navigation.signupLevelNavGraph +import com.paw.key.presentation.ui.signup.navigation.signupNavGraph +import com.paw.key.presentation.ui.signup.navigation.signupactivityNavGraph +import com.paw.key.presentation.ui.signup.navigation.signupdogNavGraph import com.paw.key.presentation.ui.onboard.navigation.onboardingNavGraph import com.paw.key.presentation.ui.splash.navigation.splashNavGraph @@ -48,9 +52,7 @@ fun PawKeyNavHost( ) { homeNavGraph( paddingValues = paddingValues, - navigateUp = navigator.navController::navigateUp, - navigateNext = navigator::navigateCourse, - snackBarHostState = snackbarHostState, + navigateNext = navigator::navigateWalkCourse, modifier = modifier, ) @@ -73,6 +75,7 @@ fun PawKeyNavHost( paddingValues = paddingValues, navigateUp = navigator::navigateUp, navigateNext = navigator::navigateWalkReview, + snackBarHostState = snackbarHostState ) walkReviewNavGraph( @@ -135,8 +138,6 @@ fun PawKeyNavHost( splashNavGraph( paddingValues = paddingValues, - navigateUp = navigator::navigateUp, - navigateNext = navigator::navigateDummyNext, navigateLogin = { val options = navOptions { popUpTo(0) { @@ -147,7 +148,6 @@ fun PawKeyNavHost( navigator.navigateOnboarding(navOptions = options) }, - snackBarHostState = snackbarHostState ) onboardingNavGraph( @@ -160,8 +160,8 @@ fun PawKeyNavHost( loginNavGraph( paddingValues = paddingValues, - navigateUp = navigator::navigateUp, - navigateNext = navigator::navigateHome, + navigateUp = navigator::navigateHome, + navigateNext = navigator::navigateSignUp, snackBarHostState = snackbarHostState ) @@ -169,8 +169,25 @@ fun PawKeyNavHost( paddingValues = paddingValues, navigateUp = navigator::navigateUp, navigateNext = navigator::navigateDummyNext, - navigateSignUp = navigator::navigateMyPage, + navigateSignUp = navigator::navigateSignUp, snackBarHostState = snackbarHostState ) + + signupNavGraph( + navigateSignUpActivity = navigator::navigateSignUpActivity, + ) + + signupactivityNavGraph( + navigateSignUpDog = navigator::navigateSignUpDog, + ) + + signupdogNavGraph( + navigateNext = navigator::navigateSignUpLevel, + ) + + signupLevelNavGraph( + navigateNext = navigator::navigateHome, + + ) } } \ No newline at end of file diff --git a/app/src/main/java/com/paw/key/presentation/ui/mypage/MyPageScreen.kt b/app/src/main/java/com/paw/key/presentation/ui/mypage/MyPageScreen.kt index 26e54efa..353193d5 100644 --- a/app/src/main/java/com/paw/key/presentation/ui/mypage/MyPageScreen.kt +++ b/app/src/main/java/com/paw/key/presentation/ui/mypage/MyPageScreen.kt @@ -7,6 +7,7 @@ import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.shape.CircleShape import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material3.Divider +import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.Icon import androidx.compose.material3.SnackbarHostState import androidx.compose.material3.Text @@ -117,7 +118,6 @@ fun OwnerCard( Spacer(modifier = Modifier.weight(1f)) Icon( imageVector = ImageVector.vectorResource(id = R.drawable.ic_arrow_right), - modifier = modifier.clickable { navigateUserProfile() }, contentDescription = "견주 프로필 이동" ) } @@ -259,7 +259,7 @@ fun WalkRouteList( routes.forEachIndexed { index, route -> if (index != 0) { - Divider(color = PawKeyTheme.colors.gray50, thickness = 1.dp) + HorizontalDivider(thickness = 1.dp, color = PawKeyTheme.colors.gray50) } Row( modifier = Modifier diff --git a/app/src/main/java/com/paw/key/presentation/ui/signup/SignUpActivityScreen.kt b/app/src/main/java/com/paw/key/presentation/ui/signup/SignUpActivityScreen.kt new file mode 100644 index 00000000..af6902a2 --- /dev/null +++ b/app/src/main/java/com/paw/key/presentation/ui/signup/SignUpActivityScreen.kt @@ -0,0 +1,115 @@ +package com.paw.key.presentation.ui.signup + +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.runtime.Composable +import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.getValue +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import androidx.hilt.navigation.compose.hiltViewModel +import com.paw.key.R +import com.paw.key.core.designsystem.component.PawkeyButton +import com.paw.key.core.designsystem.theme.PawKeyTheme +import com.paw.key.presentation.ui.signup.component.FormField +import com.paw.key.presentation.ui.signup.component.LocationButton +import com.paw.key.presentation.ui.signup.component.LocationList +import com.paw.key.presentation.ui.signup.component.SignUpHeader +import com.paw.key.presentation.ui.signup.viewmodel.SignUpViewModel + +@Preview(showBackground = true) +@Composable +private fun PreviewSignUpActivityScreen() { + PawKeyTheme { + SignUpActivityScreen( + step = 0.25F, + navigateSignUpDog = {}, + ) + } +} + +@Composable +fun SignUpActivityRoute( + navugateSignUpDog: () -> Unit, + modifier: Modifier = Modifier, +) { + SignUpActivityScreen( + step = 0.5F, + navigateSignUpDog = navugateSignUpDog, + modifier = modifier, + ) +} + +@Composable +fun SignUpActivityScreen( + step: Float, + navigateSignUpDog: () -> Unit, + modifier: Modifier = Modifier, + viewModel: SignUpViewModel = hiltViewModel(), +) { + val state by viewModel.state.collectAsState() + + Column( + modifier = modifier + .fillMaxSize() + .padding(horizontal = 16.dp) + ) { + SignUpHeader( + title = stringResource(R.string.ic_onboarding_signup), + subtitle = stringResource(id = R.string.ic_onboarding_signup_subtitle_step2), + progress = step, + ) + + Spacer(modifier = Modifier.height(27.dp)) + + FormField( + label = stringResource(id = R.string.ic_onboarding_signup_main_location), + content = { + LocationButton( + isEnable = true, + location = "강남구", + onClick = { viewModel.toggleLocationMenu() } + ) + } + ) + + Spacer(modifier = Modifier.height(46.dp)) + + FormField( + label = stringResource(id = R.string.ic_onboarding_signup_sub_location), + content = { + if (state.isLocationMenuVisible) { + LocationList( + selected = state.selectedLocation, + locations = listOf("개포동", "논현동", "뭔동", "동동동", "스꾸삐", "4글자유"), + onLocationSelected = { location -> + viewModel.selectLocation(location) + } + ) + } + } + ) + + Spacer(modifier = Modifier.weight(1f)) + + val isFormValid = state.selectedLocation.isNotEmpty() + + PawkeyButton( + text = stringResource(id = R.string.ic_onboarding_signup_button), + enabled = isFormValid, + onClick = { + if (isFormValid) { + navigateSignUpDog() + } + } + ) + + Spacer(modifier = Modifier.height(46.dp)) + + } +} \ No newline at end of file diff --git a/app/src/main/java/com/paw/key/presentation/ui/signup/SignUpDogScreen.kt b/app/src/main/java/com/paw/key/presentation/ui/signup/SignUpDogScreen.kt new file mode 100644 index 00000000..dc539280 --- /dev/null +++ b/app/src/main/java/com/paw/key/presentation/ui/signup/SignUpDogScreen.kt @@ -0,0 +1,314 @@ +package com.paw.key.presentation.ui.signup + +import androidx.compose.foundation.background +import androidx.compose.foundation.border +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +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.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.shape.CircleShape +import androidx.compose.material3.Icon +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.collectAsState +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.Color +import androidx.compose.ui.graphics.vector.ImageVector +import androidx.compose.ui.res.stringResource +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 +import com.paw.key.R +import com.paw.key.core.designsystem.component.PawkeyButton +import com.paw.key.core.designsystem.theme.PawKeyTheme +import com.paw.key.core.util.noRippleClickable +import com.paw.key.presentation.ui.signup.component.FormField +import com.paw.key.presentation.ui.signup.component.SignUpHeader +import com.paw.key.presentation.ui.signup.component.SignUpTextField +import com.paw.key.presentation.ui.signup.component.SignUpUserSelectButton +import com.paw.key.presentation.ui.signup.state.SignUpContract +import com.paw.key.presentation.ui.signup.viewmodel.SignUpViewModel + +@Preview(showBackground = true) +@Composable +private fun PreviewSignUpDogScreen() { + PawKeyTheme { + SignUpDogScreen( + step = 0.75F, + navigateNext = {}, + ) + } +} + +@Composable +fun SignUpDogRoute( + navigateNext: () -> Unit, + modifier: Modifier = Modifier, + viewModel: SignUpViewModel = hiltViewModel(), +) { + SignUpDogScreen( + step = 0.75F, + navigateNext = navigateNext, + modifier = modifier, + viewModel = viewModel + ) +} + +@Composable +fun SignUpDogScreen( + step: Float, + navigateNext: () -> Unit, + modifier: Modifier = Modifier, + viewModel: SignUpViewModel = hiltViewModel(), +) { + val state by viewModel.state.collectAsState() + + Box(modifier = modifier.fillMaxSize()) { + Column(modifier = Modifier.fillMaxSize()) { + SignUpHeader( + title = stringResource(R.string.ic_onboarding_signup), + subtitle = stringResource(id = R.string.ic_onboarding_signup_subtitle_step3), + progress = step, + ) + + LazyColumn( + verticalArrangement = Arrangement.spacedBy(32.dp), + contentPadding = PaddingValues(16.dp), + modifier = Modifier.fillMaxSize() + ) { + item { DogProfileImage() } + item { + Column( + verticalArrangement = Arrangement.spacedBy(10.dp), + ) { + DogNameField( + value = state.dogName, + onValueChange = viewModel::onDogNameChanged + ) + DogGenderSection( + selectedGender = state.dogGender, + onGenderSelected = viewModel::selectDogGender + ) + } + } + item { + NeuteringCheckbox( + isNeutered = state.isNeutered, + onToggle = viewModel::toggleNeutering + ) + } + item { + DogBreedField( + value = state.dogBreed, + onValueChange = viewModel::onDogBreedChanged + ) + } + item { + DogAgeSection( + ageKnown = state.ageKnown, + dogAge = state.dogAge, + onAgeKnownSelected = viewModel::selectAgeKnown, + onDogAgeChanged = viewModel::onDogAgeChanged + ) + } + item { Spacer(modifier = Modifier.height(80.dp)) } + } + } + + val isFormValid = state.dogName.isNotEmpty() && + state.dogGender != SignUpContract.DogGender.UNKNOWN && + state.dogBreed.isNotEmpty() && + state.ageKnown != SignUpContract.AgeKnown.UNKNOWN && + state.dogAge.isNotEmpty() + + PawkeyButton( + text = "다음으로", + enabled = isFormValid, + onClick = navigateNext, + modifier = Modifier + .align(Alignment.BottomCenter) + .fillMaxWidth() + .padding(16.dp) + ) + + Spacer(modifier = Modifier.height(34.dp)) + } +} + +@Composable +private fun DogProfileImage() { + Column { + Box( + contentAlignment = Alignment.Center, + modifier = Modifier + .fillMaxWidth() + .height(96.dp) + ) { + Box( + contentAlignment = Alignment.Center, + modifier = Modifier + .size(96.dp) + .clip(CircleShape) + .border(1.dp, PawKeyTheme.colors.white2, CircleShape) + .background(PawKeyTheme.colors.white2) + ) { + Icon( + imageVector = ImageVector.vectorResource(R.drawable.ic_onboarding_img_plus), + contentDescription = "앨범", + tint = PawKeyTheme.colors.gray100 + ) + } + } + } +} + +@Composable +private fun DogNameField( + value: String, + onValueChange: (String) -> Unit, +) { + FormField( + label = stringResource(id = R.string.ic_onboarding_signup_dog_name), + content = { + SignUpTextField( + value = value, + onValueChange = onValueChange, + + placeholder = "강아지 이름을 입력해주세요" + ) + } + ) +} + +@Composable +private fun DogGenderSection( + selectedGender: SignUpContract.DogGender, + onGenderSelected: (SignUpContract.DogGender) -> Unit, +) { + FormField( + label = stringResource(id = R.string.ic_onboarding_signup_gender), + content = { + Row( + horizontalArrangement = Arrangement.spacedBy(10.dp), + modifier = Modifier.fillMaxWidth() + ) { + SignUpUserSelectButton( + user = "남성", + isSelect = selectedGender == SignUpContract.DogGender.MALE, + onClick = { onGenderSelected(SignUpContract.DogGender.MALE) }, + modifier = Modifier.weight(1f) + ) + SignUpUserSelectButton( + user = "여성", + isSelect = selectedGender == SignUpContract.DogGender.FEMALE, + onClick = { onGenderSelected(SignUpContract.DogGender.FEMALE) }, + modifier = Modifier.weight(1f) + ) + } + } + ) +} + +@Composable +private fun NeuteringCheckbox( + isNeutered: Boolean, + onToggle: () -> Unit, +) { + Row( + horizontalArrangement = Arrangement.spacedBy(4.dp), + modifier = Modifier + .fillMaxWidth() + .noRippleClickable { onToggle() } + ) { + Icon( + imageVector = if (isNeutered) + ImageVector.vectorResource(R.drawable.ic_roundcheck_valid) + else + ImageVector.vectorResource(R.drawable.ic_roundcheck_invalid), + contentDescription = "", + tint = Color.Unspecified + ) + Text( + text = "중성화했어요", + color = if (isNeutered) + PawKeyTheme.colors.black + else PawKeyTheme.colors.gray300, + style = if (isNeutered) + PawKeyTheme.typography.body14Sb + else PawKeyTheme.typography.body14R + ) + } +} + +@Composable +private fun DogBreedField( + value: String, + onValueChange: (String) -> Unit, +) { + FormField( + label = stringResource(id = R.string.ic_onboarding_signup_dog_breed), + content = { + SignUpTextField( + value = value, + onValueChange = onValueChange, + placeholder = "견종을 입력해주세요" + ) + } + ) +} + +@Composable +private fun DogAgeSection( + ageKnown: SignUpContract.AgeKnown, + dogAge: String, + onAgeKnownSelected: (SignUpContract.AgeKnown) -> Unit, + onDogAgeChanged: (String) -> Unit, +) { + FormField( + label = stringResource(id = R.string.ic_onboarding_signup_age), + content = { + Column( + verticalArrangement = Arrangement.spacedBy(10.dp) + ) { + Row( + horizontalArrangement = Arrangement.spacedBy(10.dp), + modifier = Modifier.fillMaxWidth() + ) { + SignUpUserSelectButton( + user = "나이를 알아요", + isSelect = ageKnown == SignUpContract.AgeKnown.KNOWN, + onClick = { onAgeKnownSelected(SignUpContract.AgeKnown.KNOWN) }, + modifier = Modifier.weight(1f) + ) + + SignUpUserSelectButton( + user = "나이를 몰라요", + isSelect = ageKnown == SignUpContract.AgeKnown.UNKNOWN, + onClick = { onAgeKnownSelected(SignUpContract.AgeKnown.UNKNOWN) }, + modifier = Modifier.weight(1f) + ) + } + + if (ageKnown == SignUpContract.AgeKnown.KNOWN) { + SignUpTextField( + value = dogAge, + onValueChange = onDogAgeChanged, + placeholder = "나이를 입력해주세요" + ) + } + } + } + ) +} \ No newline at end of file diff --git a/app/src/main/java/com/paw/key/presentation/ui/signup/SignUpLevelScreen.kt b/app/src/main/java/com/paw/key/presentation/ui/signup/SignUpLevelScreen.kt new file mode 100644 index 00000000..bea46023 --- /dev/null +++ b/app/src/main/java/com/paw/key/presentation/ui/signup/SignUpLevelScreen.kt @@ -0,0 +1,154 @@ +package com.paw.key.presentation.ui.signup + +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.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.getValue +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import androidx.hilt.navigation.compose.hiltViewModel +import com.paw.key.R +import com.paw.key.core.designsystem.component.PawkeyButton +import com.paw.key.core.designsystem.theme.PawKeyTheme +import com.paw.key.presentation.ui.signup.component.SignUpHeader +import com.paw.key.presentation.ui.signup.component.SignUpUserSelectButton +import com.paw.key.presentation.ui.signup.viewmodel.SignUpViewModel + +@Preview(showBackground = true) +@Composable +private fun PreviewSignUpLevelScreen() { + PawKeyTheme { + SignUpLevelScreen( + navigateNext = {}, + selectedEnergyLevel = "", + selectedSocialLevel = "", + ) + } +} + +@Composable +fun SignUpLevelRoute( + navigateNext: () -> Unit, + modifier: Modifier = Modifier, + viewModel: SignUpViewModel = hiltViewModel(), +) { + val state by viewModel.state.collectAsState() + + SignUpLevelScreen( + enabled = viewModel.isNextButtonEnabled(), + selectedEnergyLevel = state.selectedEnergyLevel, + selectedSocialLevel = state.selectedSocialLevel, + navigateNext = navigateNext, + modifier = modifier, + viewModel = viewModel, + ) +} + +@Composable +fun SignUpLevelScreen( + navigateNext: () -> Unit, + modifier: Modifier = Modifier, + enabled: Boolean = false, + selectedEnergyLevel: String = "", + selectedSocialLevel: String = "", + viewModel: SignUpViewModel = hiltViewModel(), +) { + Column( + modifier = modifier.fillMaxSize() + ) { + SignUpHeader( + title = stringResource(id = R.string.ic_onboarding_signup), + subtitle = stringResource(id = R.string.ic_onboarding_signup_subtitle_step4) + ) + + Spacer(modifier = Modifier.height(42.dp)) + + Column( + modifier = Modifier + .fillMaxSize() + .padding(horizontal = 16.dp) + ) { + LevelSection( + title = stringResource(id = R.string.ic_onboarding_signup_energy_level), + options = listOf( + listOf("매우 차분해요", "조금 느릿해요"), + listOf("활동적이에요", "아주 활발해요") + ), + selectedOption = selectedEnergyLevel, + onOptionClick = { option -> + viewModel.selectEnergyLevel(option) + } + ) + + Spacer(modifier = Modifier.height(36.dp)) + + LevelSection( + title = stringResource(id = R.string.ic_onboarding_signup_social_level), + options = listOf( + listOf("잘 안 친해요", "친해려 친해해요"), + listOf("잘 친해해요", "친구왕이에요") + ), + selectedOption = selectedSocialLevel, + onOptionClick = { option -> + viewModel.selectSocialLevel(option) + } + ) + + Spacer(modifier = Modifier.weight(1f)) + + PawkeyButton( + text = stringResource(id = R.string.ic_onboarding_signup_button), + enabled = enabled, + onClick = navigateNext + ) + + Spacer(modifier = Modifier.height(46.dp)) + } + } +} + +@Composable +private fun LevelSection( + title: String, + options: List>, + selectedOption: String, + onOptionClick: (String) -> Unit, +) { + Column { + Text( + text = title, + style = PawKeyTheme.typography.body14Sb, + color = PawKeyTheme.colors.black + ) + + Spacer(modifier = Modifier.height(12.dp)) + + options.forEach { rowOptions -> + Row( + horizontalArrangement = Arrangement.spacedBy(10.dp), + modifier = Modifier + .fillMaxWidth() + .padding(bottom = 10.dp) + ) { + rowOptions.forEach { option -> + SignUpUserSelectButton( + user = option, + isSelect = selectedOption == option, + onClick = { onOptionClick(option) }, + modifier = Modifier.weight(1f) + ) + } + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/paw/key/presentation/ui/signup/SignUpScreen.kt b/app/src/main/java/com/paw/key/presentation/ui/signup/SignUpScreen.kt new file mode 100644 index 00000000..024867bf --- /dev/null +++ b/app/src/main/java/com/paw/key/presentation/ui/signup/SignUpScreen.kt @@ -0,0 +1,153 @@ +package com.paw.key.presentation.ui.signup + +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.fillMaxSize +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.collectAsState +import androidx.compose.runtime.getValue +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import androidx.hilt.navigation.compose.hiltViewModel +import com.paw.key.R +import com.paw.key.core.designsystem.component.PawkeyButton +import com.paw.key.core.designsystem.theme.PawKeyTheme +import com.paw.key.presentation.ui.signup.component.FormField +import com.paw.key.presentation.ui.signup.component.SignUpHeader +import com.paw.key.presentation.ui.signup.component.SignUpTextField +import com.paw.key.presentation.ui.signup.component.SignUpUserSelectButton +import com.paw.key.presentation.ui.signup.state.SignUpContract +import com.paw.key.presentation.ui.signup.viewmodel.SignUpViewModel + +@Preview(showBackground = true) +@Composable +private fun PreviewSignUpScreen() { + PawKeyTheme { + SignUpScreen( + step = 0.25F, + navigateSignUpActivity = {}, + ) + } +} + +@Composable +fun SignUpRoute( + navigateSignUpActivity: () -> Unit, + modifier: Modifier = Modifier, +) { + SignUpScreen( + step = 0.25F, + navigateSignUpActivity = navigateSignUpActivity, + modifier = modifier, + ) +} + +@Composable +fun SignUpScreen( + step: Float, + navigateSignUpActivity: () -> Unit, + modifier: Modifier = Modifier, + viewModel: SignUpViewModel = hiltViewModel(), +) { + val state by viewModel.state.collectAsState() + + Column( + modifier = modifier + .fillMaxSize() + .padding(horizontal = 16.dp) + ) { + SignUpHeader( + title = stringResource(R.string.ic_onboarding_signup), + subtitle = stringResource(id = R.string.ic_onboarding_signup_subtitle_step1), + progress = step, + ) + + Spacer(modifier = Modifier.height(42.dp)) + + FormField( + label = stringResource(id = R.string.ic_onboarding_signup_name), + content = { + SignUpTextField( + value = state.name, + onValueChange = viewModel::onNameChanged, + placeholder = "이름을 입력해주세요" + ) + } + ) + + Spacer(modifier = Modifier.height(33.dp)) + + FormField( + label = stringResource(id = R.string.ic_onboarding_signup_gender), + content = { + GenderSelector( + selectedGender = state.selectedGender, + onGenderSelected = viewModel::selectGender + ) + } + ) + + Spacer(modifier = Modifier.height(33.dp)) + + FormField( + label = stringResource(id = R.string.ic_onboarding_signup_age), + content = { + SignUpTextField( + value = state.age, + onValueChange = viewModel::onAgeChanged, + placeholder = "나이를 입력해주세요" + ) + } + ) + + Spacer(modifier = Modifier.weight(1f)) + + val isFormValid = state.name.isNotBlank() && + state.age.isNotBlank() && + state.selectedGender != SignUpContract.Gender.UNKNOWN + + PawkeyButton( + text = stringResource(id = R.string.ic_onboarding_signup_name), + enabled = isFormValid, + onClick = { + if (isFormValid) { + navigateSignUpActivity() + } + } + ) + + Spacer(modifier = Modifier.height(46.dp)) + } +} + +@Composable +private fun GenderSelector( + selectedGender: SignUpContract.Gender, + onGenderSelected: (SignUpContract.Gender) -> Unit, +) { + Row( + horizontalArrangement = Arrangement.spacedBy(10.dp), + modifier = Modifier.fillMaxWidth() + ) { + SignUpUserSelectButton( + user = "남성", + isSelect = selectedGender == SignUpContract.Gender.MALE, + onClick = { onGenderSelected(SignUpContract.Gender.MALE) }, + modifier = Modifier.weight(1f) + ) + + SignUpUserSelectButton( + user = "여성", + isSelect = selectedGender == SignUpContract.Gender.FEMALE, + onClick = { onGenderSelected(SignUpContract.Gender.FEMALE) }, + modifier = Modifier.weight(1f) + ) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/paw/key/presentation/ui/signup/component/FormField.kt b/app/src/main/java/com/paw/key/presentation/ui/signup/component/FormField.kt new file mode 100644 index 00000000..568fbd45 --- /dev/null +++ b/app/src/main/java/com/paw/key/presentation/ui/signup/component/FormField.kt @@ -0,0 +1,43 @@ +package com.paw.key.presentation.ui.signup.component + +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.height +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import com.paw.key.core.designsystem.theme.PawKeyTheme + +@Preview(showBackground = true) +@Composable +private fun PreviewFormField() { + PawKeyTheme { + FormField( + label = "이름", + content = { + SignUpTextField( + value = "", + onValueChange = {}, + placeholder = "이름을 입력해주세요." + ) + } + ) + } +} + +@Composable +fun FormField( + label: String, + content: @Composable () -> Unit, +) { + Text( + text = label, + color = PawKeyTheme.colors.black, + style = PawKeyTheme.typography.body16Sb + ) + + Spacer(modifier = Modifier.height(10.dp)) + + content() +} \ No newline at end of file diff --git a/app/src/main/java/com/paw/key/presentation/ui/signup/component/LocationButton.kt b/app/src/main/java/com/paw/key/presentation/ui/signup/component/LocationButton.kt new file mode 100644 index 00000000..41dce16b --- /dev/null +++ b/app/src/main/java/com/paw/key/presentation/ui/signup/component/LocationButton.kt @@ -0,0 +1,70 @@ +package com.paw.key.presentation.ui.signup.component + +import androidx.compose.foundation.background +import androidx.compose.foundation.border +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.width +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import com.paw.key.core.designsystem.theme.PawKeyTheme +import com.paw.key.core.util.noRippleClickable + +@Preview(showBackground = true) +@Composable +private fun PreviewLocationButton() { + PawKeyTheme { + LocationButton( + location = "강남구", + isEnable = true, + onClick = {} + ) + } +} + +@Composable +fun LocationButton( + location: String, + isEnable: Boolean, + onClick: () -> Unit, + modifier: Modifier = Modifier, +) { + Box( + contentAlignment = Alignment.Center, + modifier = modifier + .height(42.dp) + .width(77.dp) + .noRippleClickable { onClick() } + .background(color = PawKeyTheme.colors.white1) + .border( + width = 2.dp, + color = if (isEnable) { + PawKeyTheme.colors.green500 + } else { + PawKeyTheme.colors.gray200 + }, + shape = RoundedCornerShape(8.dp) + ) + .clip(RoundedCornerShape(8.dp)) + ) { + Text( + text = location, + color = if (isEnable) { + PawKeyTheme.colors.green500 + } else { + PawKeyTheme.colors.gray200 + }, + style = if (isEnable) { + PawKeyTheme.typography.body14Sb + } else { + PawKeyTheme.typography.body14R + } + ) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/paw/key/presentation/ui/signup/component/LocationList.kt b/app/src/main/java/com/paw/key/presentation/ui/signup/component/LocationList.kt new file mode 100644 index 00000000..a0487af7 --- /dev/null +++ b/app/src/main/java/com/paw/key/presentation/ui/signup/component/LocationList.kt @@ -0,0 +1,50 @@ +package com.paw.key.presentation.ui.signup.component + +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.ExperimentalLayoutApi +import androidx.compose.foundation.layout.FlowRow +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import com.paw.key.core.designsystem.theme.PawKeyTheme + +@Preview(showBackground = true) +@Composable +private fun PreviewLocationList() { + PawKeyTheme { + LocationList( + selected = "서울", + locations = listOf("서울", "경기", "인천", "강원", "충북", "충남", "전북", "전남", "경북", "경남", "제주"), + onLocationSelected = {} + ) + } +} + +@OptIn(ExperimentalLayoutApi::class) +@Composable +fun LocationList( + locations: List, + selected: String, + onLocationSelected: (String) -> Unit, + modifier: Modifier = Modifier, +) { + FlowRow( + modifier = modifier.fillMaxWidth(), + horizontalArrangement = Arrangement.spacedBy(8.dp), + verticalArrangement = Arrangement.spacedBy(12.dp), + maxItemsInEachRow = 3 + ) { + locations.forEach { location -> + LocationButton( + location = location, + isEnable = location == selected, + onClick = { + onLocationSelected(location) + } + ) + } + } +} + diff --git a/app/src/main/java/com/paw/key/presentation/ui/signup/component/SignUpHeader.kt b/app/src/main/java/com/paw/key/presentation/ui/signup/component/SignUpHeader.kt new file mode 100644 index 00000000..695870c3 --- /dev/null +++ b/app/src/main/java/com/paw/key/presentation/ui/signup/component/SignUpHeader.kt @@ -0,0 +1,86 @@ +package com.paw.key.presentation.ui.signup.component + +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.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.material3.LinearProgressIndicator +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 com.paw.key.core.designsystem.theme.PawKeyTheme + +@Preview(showBackground = true) +@Composable +private fun PreviewSignUpHeader() { + PawKeyTheme { + SignUpHeader( + progress = 0.5F, + title = "회원가입", + subtitle = "견주님에 대해 알려주세요." + ) + } +} + +@Composable +fun SignUpHeader( + title: String, + subtitle: String, + modifier: Modifier = Modifier, + progress: Float = 1F, +) { + Column( + modifier = modifier + .fillMaxWidth() + .height(131.dp) + ) { + Row( + verticalAlignment = Alignment.Bottom, + modifier = modifier + .fillMaxWidth() + .height(60.dp) + ) { + Column( + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.Center, + modifier = Modifier + .weight(1F) + .fillMaxSize() + ) { + Text( + text = title, + color = PawKeyTheme.colors.black, + style = PawKeyTheme.typography.body16Sb, + modifier = Modifier + .padding(top = 16.dp), + ) + + Spacer(modifier = Modifier.weight(1F)) + + LinearProgressIndicator( + progress = { progress }, + modifier = Modifier + .fillMaxWidth() + .height(2.dp), + color = PawKeyTheme.colors.green500, + trackColor = PawKeyTheme.colors.gray100, + ) + } + } + Text( + text = subtitle, + color = PawKeyTheme.colors.black, + style = PawKeyTheme.typography.head22Sb, + modifier = Modifier + .padding(top = 36.dp) + .padding(horizontal = 16.dp) + ) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/paw/key/presentation/ui/signup/component/SignUpLoationGrid.kt b/app/src/main/java/com/paw/key/presentation/ui/signup/component/SignUpLoationGrid.kt new file mode 100644 index 00000000..5c23727c --- /dev/null +++ b/app/src/main/java/com/paw/key/presentation/ui/signup/component/SignUpLoationGrid.kt @@ -0,0 +1,25 @@ +package com.paw.key.presentation.ui.signup.component + +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.tooling.preview.Preview +import com.paw.key.core.designsystem.theme.PawKeyTheme + +@Preview(showBackground = true) +@Composable +private fun PreviewSignUpLoationGrid() { + PawKeyTheme { + SignUpLoationGrid() + } +} + +@Composable +fun SignUpLoationGrid( + modifier: Modifier = Modifier, +) { + LocationButton( + location = "개포동", + isEnable = true, + onClick = {} + ) +} \ No newline at end of file diff --git a/app/src/main/java/com/paw/key/presentation/ui/signup/component/SignUpTextField.kt b/app/src/main/java/com/paw/key/presentation/ui/signup/component/SignUpTextField.kt new file mode 100644 index 00000000..504a42cb --- /dev/null +++ b/app/src/main/java/com/paw/key/presentation/ui/signup/component/SignUpTextField.kt @@ -0,0 +1,77 @@ +package com.paw.key.presentation.ui.signup.component + +import androidx.compose.foundation.background +import androidx.compose.foundation.border +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.foundation.text.BasicTextField +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.unit.dp +import com.paw.key.core.designsystem.theme.PawKeyTheme +import com.paw.key.core.util.noRippleClickable + + +@Composable +fun SignUpTextField( + value: String, + onValueChange: (String) -> Unit, + modifier: Modifier = Modifier, + placeholder: String = "", + enabled: Boolean = true, +) { + val isClicked = remember { mutableStateOf(false) } + + val borderColor = when { + !enabled -> PawKeyTheme.colors.gray100 + isClicked.value -> PawKeyTheme.colors.green500 + else -> PawKeyTheme.colors.gray200 + } + + + BasicTextField( + value = value, + onValueChange = onValueChange, + modifier = modifier + .fillMaxWidth() + .height(52.dp) + .clip(RoundedCornerShape(8.dp)) + .noRippleClickable { + isClicked.value = true + } + .background(color = PawKeyTheme.colors.white1) + .border( + width = 1.dp, + color = borderColor, + shape = RoundedCornerShape(8.dp) + ), + textStyle = PawKeyTheme.typography.body14R, + maxLines = 1, + enabled = enabled, + decorationBox = { innerTextField -> + androidx.compose.foundation.layout.Box( + modifier = Modifier + .fillMaxWidth() + .height(52.dp) + .padding(horizontal = 16.dp), + contentAlignment = androidx.compose.ui.Alignment.CenterStart + ) { + if (value.isEmpty()) { + Text( + text = placeholder, + style = PawKeyTheme.typography.body14R, + color = PawKeyTheme.colors.gray200 + ) + } + innerTextField() + } + } + ) +} + diff --git a/app/src/main/java/com/paw/key/presentation/ui/signup/component/SignUpUserSelectButton.kt b/app/src/main/java/com/paw/key/presentation/ui/signup/component/SignUpUserSelectButton.kt new file mode 100644 index 00000000..e9b0a966 --- /dev/null +++ b/app/src/main/java/com/paw/key/presentation/ui/signup/component/SignUpUserSelectButton.kt @@ -0,0 +1,77 @@ +package com.paw.key.presentation.ui.signup.component + +import androidx.compose.foundation.background +import androidx.compose.foundation.border +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.width +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import com.paw.key.core.designsystem.theme.PawKeyTheme +import com.paw.key.core.util.noRippleClickable + +@Preview(showBackground = true) +@Composable +private fun PreviewSignUpUserSelectButton() { + PawKeyTheme { + SignUpUserSelectButton( + user = "남성", + isSelect = true, + onClick = {} + ) + } +} + +@Composable +fun SignUpUserSelectButton( + user: String, + isSelect: Boolean, + onClick: () -> Unit, + modifier: Modifier = Modifier +) { + Box( + contentAlignment = Alignment.Center, + modifier = modifier + .height(48.dp) + .width(158.dp) + .background(color = PawKeyTheme.colors.white1) + .noRippleClickable { onClick() } + .border( + width = if (isSelect){ + 2.dp + } else { + 1.dp + }, + color = if (isSelect) { + PawKeyTheme.colors.green500 + } else { + PawKeyTheme.colors.gray200 + }, + shape = RoundedCornerShape(8.dp) + ) + .clip(RoundedCornerShape(8.dp)) + ) { + Text( + text = user, + color = if (isSelect) { + PawKeyTheme.colors.green500 + } else { + PawKeyTheme.colors.gray200 + }, + style = if (isSelect) { + PawKeyTheme.typography.body14Sb + } else { + PawKeyTheme.typography.body14R + }, + modifier = Modifier + .padding(horizontal = 21.dp, vertical = 13.dp) + ) + } +} diff --git a/app/src/main/java/com/paw/key/presentation/ui/signup/navigation/SignUpActivityNavigation.kt b/app/src/main/java/com/paw/key/presentation/ui/signup/navigation/SignUpActivityNavigation.kt new file mode 100644 index 00000000..5f937a1e --- /dev/null +++ b/app/src/main/java/com/paw/key/presentation/ui/signup/navigation/SignUpActivityNavigation.kt @@ -0,0 +1,31 @@ +package com.paw.key.presentation.ui.signup.navigation + +import androidx.compose.ui.Modifier +import androidx.navigation.NavController +import androidx.navigation.NavGraphBuilder +import androidx.navigation.NavOptions +import androidx.navigation.compose.composable +import com.paw.key.core.navigation.Route +import com.paw.key.presentation.ui.signup.SignUpActivityRoute +import kotlinx.serialization.Serializable + +fun NavController.navigateSignUpActivity( + navOptions: NavOptions?, +) { + navigate(SignUpActivity, navOptions) +} + +fun NavGraphBuilder.signupactivityNavGraph( + navigateSignUpDog: () -> Unit, + modifier: Modifier = Modifier, +) { + composable { + SignUpActivityRoute( + navugateSignUpDog = navigateSignUpDog, + modifier = modifier + ) + } +} + +@Serializable +data object SignUpActivity : Route \ No newline at end of file diff --git a/app/src/main/java/com/paw/key/presentation/ui/signup/navigation/SignUpDogNavigation.kt b/app/src/main/java/com/paw/key/presentation/ui/signup/navigation/SignUpDogNavigation.kt new file mode 100644 index 00000000..81f92f3d --- /dev/null +++ b/app/src/main/java/com/paw/key/presentation/ui/signup/navigation/SignUpDogNavigation.kt @@ -0,0 +1,31 @@ +package com.paw.key.presentation.ui.signup.navigation + +import androidx.compose.ui.Modifier +import androidx.navigation.NavController +import androidx.navigation.NavGraphBuilder +import androidx.navigation.NavOptions +import androidx.navigation.compose.composable +import com.paw.key.core.navigation.Route +import com.paw.key.presentation.ui.signup.SignUpDogRoute +import kotlinx.serialization.Serializable + +fun NavController.navigateSignUpDog( + navOptions: NavOptions?, +) { + navigate(SignUpDog, navOptions) +} + +fun NavGraphBuilder.signupdogNavGraph( + navigateNext: () -> Unit, + modifier: Modifier = Modifier, +) { + composable { + SignUpDogRoute( + navigateNext = navigateNext, + modifier = modifier + ) + } +} + +@Serializable +data object SignUpDog : Route \ No newline at end of file diff --git a/app/src/main/java/com/paw/key/presentation/ui/signup/navigation/SignUpLevelNavigation.kt b/app/src/main/java/com/paw/key/presentation/ui/signup/navigation/SignUpLevelNavigation.kt new file mode 100644 index 00000000..2f06bb76 --- /dev/null +++ b/app/src/main/java/com/paw/key/presentation/ui/signup/navigation/SignUpLevelNavigation.kt @@ -0,0 +1,31 @@ +package com.paw.key.presentation.ui.signup.navigation + +import androidx.compose.ui.Modifier +import androidx.navigation.NavController +import androidx.navigation.NavGraphBuilder +import androidx.navigation.NavOptions +import androidx.navigation.compose.composable +import com.paw.key.core.navigation.Route +import com.paw.key.presentation.ui.signup.SignUpLevelRoute +import kotlinx.serialization.Serializable + +fun NavController.navigateSignLevel( + navOptions: NavOptions?, +) { + navigate(SignUpLevel, navOptions) +} + +fun NavGraphBuilder.signupLevelNavGraph( + navigateNext: () -> Unit, + modifier: Modifier = Modifier, +) { + composable { + SignUpLevelRoute( + navigateNext = navigateNext, + modifier = modifier + ) + } +} + +@Serializable +data object SignUpLevel : Route \ No newline at end of file diff --git a/app/src/main/java/com/paw/key/presentation/ui/signup/navigation/SignUpNavigation.kt b/app/src/main/java/com/paw/key/presentation/ui/signup/navigation/SignUpNavigation.kt new file mode 100644 index 00000000..08c0568d --- /dev/null +++ b/app/src/main/java/com/paw/key/presentation/ui/signup/navigation/SignUpNavigation.kt @@ -0,0 +1,31 @@ +package com.paw.key.presentation.ui.signup.navigation + +import androidx.compose.ui.Modifier +import androidx.navigation.NavController +import androidx.navigation.NavGraphBuilder +import androidx.navigation.NavOptions +import androidx.navigation.compose.composable +import com.paw.key.core.navigation.Route +import com.paw.key.presentation.ui.signup.SignUpRoute +import kotlinx.serialization.Serializable + +fun NavController.navigateSignUp( + navOptions: NavOptions?, +) { + navigate(SignUp, navOptions) +} + +fun NavGraphBuilder.signupNavGraph( + navigateSignUpActivity: () -> Unit, + modifier: Modifier = Modifier, +) { + composable { + SignUpRoute( + navigateSignUpActivity = navigateSignUpActivity, + modifier = modifier + ) + } +} + +@Serializable +data object SignUp : Route \ No newline at end of file diff --git a/app/src/main/java/com/paw/key/presentation/ui/signup/state/SignUpContract.kt b/app/src/main/java/com/paw/key/presentation/ui/signup/state/SignUpContract.kt new file mode 100644 index 00000000..fa21213b --- /dev/null +++ b/app/src/main/java/com/paw/key/presentation/ui/signup/state/SignUpContract.kt @@ -0,0 +1,50 @@ +package com.paw.key.presentation.ui.signup.state + +import androidx.compose.runtime.Immutable + +class SignUpContract { + @Immutable + data class SignUpState( + val selectedGender: Gender = Gender.UNKNOWN, + val selectedLocation: String = "", + val isLocationMenuVisible: Boolean = false, + val name: String = "", + val age: String = "", + + val dogName: String = "", + val dogGender: DogGender = DogGender.UNKNOWN, + val isNeutered: Boolean = false, + val dogBreed: String = "", + val ageKnown: AgeKnown = AgeKnown.UNKNOWN, + val dogAge: String = "", + + val selectedEnergyLevel: String = "", + val selectedSocialLevel: String = "", + + val selectedDistrict: List = emptyList(), + val isDistrictMenuVisible: Boolean = false, + ) + + enum class Gender { + MALE, + FEMALE, + UNKNOWN + } + + enum class DogGender { + MALE, + FEMALE, + UNKNOWN + } + + enum class AgeKnown { + KNOWN, + UNKNOWN + } + + sealed class SignUpSideEffect { + data class ShowSnackBar(val message: String) : SignUpSideEffect() + data object NavigateUp: SignUpSideEffect() + data object NavigateNext: SignUpSideEffect() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/paw/key/presentation/ui/signup/viewmodel/SignUpViewModel.kt b/app/src/main/java/com/paw/key/presentation/ui/signup/viewmodel/SignUpViewModel.kt new file mode 100644 index 00000000..eb3546b1 --- /dev/null +++ b/app/src/main/java/com/paw/key/presentation/ui/signup/viewmodel/SignUpViewModel.kt @@ -0,0 +1,108 @@ +package com.paw.key.presentation.ui.signup.viewmodel + +import androidx.lifecycle.ViewModel +import com.paw.key.presentation.ui.signup.state.SignUpContract +import dagger.hilt.android.lifecycle.HiltViewModel +import kotlinx.coroutines.flow.MutableSharedFlow +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() { + + private val _state = MutableStateFlow(SignUpContract.SignUpState()) + val state: StateFlow + get() = _state.asStateFlow() + + private val _sideEffect = MutableSharedFlow() + val sideEffect: MutableSharedFlow + get() = _sideEffect + + fun selectGender(gender: SignUpContract.Gender) { + _state.value = _state.value.copy( + selectedGender = gender + ) + } + + fun selectDistrict(districts: List) { + _state.value = _state.value.copy( + selectedDistrict = districts + ) + } + + fun selectLocation(location: String) { + _state.value = _state.value.copy( + selectedLocation = location + ) + } + + fun onLocationChanged(location: String) { + _state.value = _state.value.copy( + selectedLocation = location + ) + } + + fun toggleLocationMenu() { + _state.value = _state.value.copy( + isLocationMenuVisible = !_state.value.isLocationMenuVisible + ) + } + + fun onNameChanged(name: String) { + _state.value = _state.value.copy(name = name) + } + + fun onAgeChanged(age: String) { + _state.value = _state.value.copy(age = age) + } + + fun hideLocationMenu() { + _state.value = _state.value.copy( + isLocationMenuVisible = false + ) + } + + fun onDogNameChanged(dogName: String) { + _state.value = _state.value.copy(dogName = dogName) + } + + fun selectDogGender(dogGender: SignUpContract.DogGender) { + _state.value = _state.value.copy(dogGender = dogGender) + } + + fun toggleNeutering() { + _state.value = _state.value.copy(isNeutered = !_state.value.isNeutered) + } + + fun onDogBreedChanged(dogBreed: String) { + _state.value = _state.value.copy(dogBreed = dogBreed) + } + + fun selectAgeKnown(ageKnown: SignUpContract.AgeKnown) { + _state.value = _state.value.copy(ageKnown = ageKnown) + } + + fun onDogAgeChanged(dogAge: String) { + _state.value = _state.value.copy(dogAge = dogAge) + } + + fun selectEnergyLevel(energyLevel: String) { + _state.value = _state.value.copy( + selectedEnergyLevel = energyLevel + ) + } + + fun selectSocialLevel(socialLevel: String) { + _state.value = _state.value.copy( + selectedSocialLevel = socialLevel + ) + } + + fun isNextButtonEnabled(): Boolean { + return _state.value.selectedEnergyLevel.isNotEmpty() && + _state.value.selectedSocialLevel.isNotEmpty() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/paw/key/presentation/ui/splash/SplashScreen.kt b/app/src/main/java/com/paw/key/presentation/ui/splash/SplashScreen.kt index 0225c7d5..85da1217 100644 --- a/app/src/main/java/com/paw/key/presentation/ui/splash/SplashScreen.kt +++ b/app/src/main/java/com/paw/key/presentation/ui/splash/SplashScreen.kt @@ -14,7 +14,6 @@ import androidx.compose.material3.SnackbarHostState import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect -import androidx.compose.runtime.collectAsState import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color @@ -31,14 +30,11 @@ import com.paw.key.presentation.ui.splash.viewmodel.SplashViewModel @Preview(showBackground = true) @Composable -fun PreviewSplashScreen() { +private fun PreviewSplashScreen() { PawKeyTheme { SplashScreen( paddingValues = PaddingValues(), - navigateUp = {}, - navigateNext = {}, - navigateLogin = {}, - snackBarHostState = SnackbarHostState() + modifier = Modifier ) } } @@ -46,10 +42,7 @@ fun PreviewSplashScreen() { @Composable fun SplashRoute( paddingValues: PaddingValues, - navigateUp: () -> Unit, - navigateNext: () -> Unit, navigateLogin: () -> Unit, - snackBarHostState: SnackbarHostState, modifier: Modifier = Modifier, viewModel: SplashViewModel = hiltViewModel(), ) { @@ -65,10 +58,6 @@ fun SplashRoute( SplashScreen( paddingValues = paddingValues, - navigateUp = navigateUp, - navigateNext = navigateNext, - navigateLogin = navigateLogin, - snackBarHostState = snackBarHostState, modifier = modifier ) } @@ -77,10 +66,6 @@ fun SplashRoute( @Composable fun SplashScreen( paddingValues: PaddingValues, - navigateUp: () -> Unit, - navigateNext: () -> Unit, - navigateLogin: () -> Unit, - snackBarHostState: SnackbarHostState, modifier: Modifier = Modifier, ) { Box( diff --git a/app/src/main/java/com/paw/key/presentation/ui/splash/navigation/SplashNavigation.kt b/app/src/main/java/com/paw/key/presentation/ui/splash/navigation/SplashNavigation.kt index 58b2beab..9c0d2b48 100644 --- a/app/src/main/java/com/paw/key/presentation/ui/splash/navigation/SplashNavigation.kt +++ b/app/src/main/java/com/paw/key/presentation/ui/splash/navigation/SplashNavigation.kt @@ -19,20 +19,13 @@ fun NavController.navigateSplash( fun NavGraphBuilder.splashNavGraph( paddingValues: PaddingValues, - navigateUp: () -> Unit, - navigateNext: () -> Unit, - //TODO: 안쓰는 navigate 처리는 그냥 지워도 되는지 navigateLogin: () -> Unit, - snackBarHostState: SnackbarHostState, modifier: Modifier = Modifier, ) { composable { SplashRoute( paddingValues = paddingValues, - navigateUp = navigateUp, - navigateNext = navigateNext, navigateLogin = navigateLogin, - snackBarHostState = snackBarHostState, modifier = modifier ) } diff --git a/app/src/main/res/drawable/ic_roundcheck_invalid.xml b/app/src/main/res/drawable/ic_roundcheck_invalid.xml new file mode 100644 index 00000000..194239ca --- /dev/null +++ b/app/src/main/res/drawable/ic_roundcheck_invalid.xml @@ -0,0 +1,20 @@ + + + + diff --git a/app/src/main/res/drawable/ic_roundcheck_valid.xml b/app/src/main/res/drawable/ic_roundcheck_valid.xml new file mode 100644 index 00000000..b8fdbc78 --- /dev/null +++ b/app/src/main/res/drawable/ic_roundcheck_valid.xml @@ -0,0 +1,16 @@ + + + + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 24b9fbb1..b68dac70 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -8,6 +8,30 @@ PAWKEY + + 신규계정으로 회원가입 + 기존 계정으로 회원가입 + + 회원가입 + 다음으로 + 견주님에 대해 알려주세요 + 활동 범위가 어떻게 되시나요? + 견주님의 반려견이 궁금해요! + 반려견 성향은 어떤가요? + + 이름 + 성별 + 나이 + 나이 알고 있음 + 지역구 + 법정동 + + 반려견 이름 + 견종 + + 활동성 + 친밀도 + home