diff --git a/core/designsystem/src/main/java/com/teamsolply/solply/designsystem/component/dropdown/SolplyBasicDropDown.kt b/core/designsystem/src/main/java/com/teamsolply/solply/designsystem/component/dropdown/SolplyBasicDropDown.kt
new file mode 100644
index 00000000..8f732d6d
--- /dev/null
+++ b/core/designsystem/src/main/java/com/teamsolply/solply/designsystem/component/dropdown/SolplyBasicDropDown.kt
@@ -0,0 +1,103 @@
+package com.teamsolply.solply.designsystem.component.dropdown
+
+import androidx.compose.animation.AnimatedVisibility
+import androidx.compose.animation.slideInVertically
+import androidx.compose.animation.slideOutVertically
+import androidx.compose.foundation.background
+import androidx.compose.foundation.border
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.ColumnScope
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.fillMaxWidth
+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.HorizontalDivider
+import androidx.compose.material3.Icon
+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.draw.scale
+import androidx.compose.ui.res.painterResource
+import androidx.compose.ui.unit.dp
+import com.teamsolply.solply.designsystem.R
+import com.teamsolply.solply.designsystem.theme.SolplyTheme
+import com.teamsolply.solply.ui.extension.customClickable
+
+@Composable
+fun SolplyBasicDropDown(
+ defaultLabel: String,
+ onClickDropIcon: () -> Unit,
+ modifier: Modifier = Modifier,
+ isDropped: Boolean = false,
+ content: @Composable ColumnScope.() -> Unit,
+) {
+ Column(
+ modifier = modifier
+ .clip(
+ RoundedCornerShape(20.dp)
+ )
+ .border(
+ width = 1.dp,
+ color = SolplyTheme.colors.gray300,
+ shape = RoundedCornerShape(20.dp)
+ )
+ ) {
+ Row(
+ modifier = Modifier
+ .fillMaxWidth()
+ .then(
+ if (isDropped) {
+ Modifier.background(
+ color = SolplyTheme.colors.gray100
+ )
+ } else {
+ Modifier.background(
+ color = SolplyTheme.colors.white
+ )
+ }
+ ),
+ verticalAlignment = Alignment.CenterVertically,
+ horizontalArrangement = Arrangement.SpaceBetween
+ ) {
+ Text(
+ text = defaultLabel,
+ color = SolplyTheme.colors.gray900,
+ style = SolplyTheme.typography.body16M,
+ modifier = Modifier.padding(start = 20.dp)
+ )
+ Icon(
+ painter = painterResource(R.drawable.ic_arrow_down),
+ contentDescription = "",
+ modifier = Modifier
+ .padding(end = 20.dp, top = 14.dp, bottom = 14.dp)
+ .height(24.dp)
+ .width(24.dp)
+ .scale(
+ scaleX = 1f,
+ scaleY = if (isDropped) -1f else 1f
+ )
+ .customClickable(
+ rippleEnabled = false,
+ onClick = onClickDropIcon
+ )
+ )
+ }
+ HorizontalDivider(color = SolplyTheme.colors.gray300)
+ AnimatedVisibility(
+ visible = isDropped,
+ enter = slideInVertically(),
+ exit = slideOutVertically()
+ ) {
+ Column(
+ modifier = Modifier.fillMaxWidth()
+ ) {
+ content()
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/core/designsystem/src/main/res/drawable/ic_arrow_down.xml b/core/designsystem/src/main/res/drawable/ic_arrow_down.xml
new file mode 100644
index 00000000..83903eac
--- /dev/null
+++ b/core/designsystem/src/main/res/drawable/ic_arrow_down.xml
@@ -0,0 +1,13 @@
+
+
+
diff --git a/feature/main/src/main/java/com/teamsolply/solply/main/MainNavigator.kt b/feature/main/src/main/java/com/teamsolply/solply/main/MainNavigator.kt
index 0338c729..33085e7f 100644
--- a/feature/main/src/main/java/com/teamsolply/solply/main/MainNavigator.kt
+++ b/feature/main/src/main/java/com/teamsolply/solply/main/MainNavigator.kt
@@ -17,6 +17,7 @@ import com.teamsolply.solply.course.navigation.navigateCourse
import com.teamsolply.solply.main.splash.Splash
import com.teamsolply.solply.maps.navigation.navigateMaps
import com.teamsolply.solply.mypage.navigation.navigateMypage
+import com.teamsolply.solply.mypage.profile.navigation.navigateProfile
import com.teamsolply.solply.oauth.navigation.navigateOauth
import com.teamsolply.solply.onboarding.navigation.navigateOnBoarding
import com.teamsolply.solply.place.navigation.navigatePlace
@@ -137,6 +138,22 @@ internal class MainNavigator(
)
}
+ fun navigateToMypage(
+ navOptions: NavOptions
+ ) {
+ navController.navigateMypage(
+ navOptions = navOptions
+ )
+ }
+
+ fun navigateToProfile(
+ navOptions: NavOptions
+ ) {
+ navController.navigateProfile(
+ navOptions = navOptions
+ )
+ }
+
fun navigateToFavoriteTown(navOptions: NavOptions = navOptions {}) {
navController.navigateFavoriteTown(navOptions)
}
diff --git a/feature/main/src/main/java/com/teamsolply/solply/main/MainScreen.kt b/feature/main/src/main/java/com/teamsolply/solply/main/MainScreen.kt
index 990eede9..394a55fb 100644
--- a/feature/main/src/main/java/com/teamsolply/solply/main/MainScreen.kt
+++ b/feature/main/src/main/java/com/teamsolply/solply/main/MainScreen.kt
@@ -39,7 +39,10 @@ import com.teamsolply.solply.main.model.SolplySnackBarData
import com.teamsolply.solply.main.splash.splashNavGraph
import com.teamsolply.solply.maps.navigation.mapsNavGraph
import com.teamsolply.solply.model.SnackBarType
+import com.teamsolply.solply.mypage.navigation.Mypage
import com.teamsolply.solply.mypage.navigation.mypageNavGraph
+import com.teamsolply.solply.mypage.profile.navigation.Profile
+import com.teamsolply.solply.mypage.profile.navigation.profileNavGraph
import com.teamsolply.solply.oauth.navigation.oauthNavGraph
import com.teamsolply.solply.onboarding.navigation.onBoardingNavGraph
import com.teamsolply.solply.place.navigation.placeNavGraph
@@ -333,7 +336,22 @@ internal fun MainScreen(
)
mypageNavGraph(
paddingValues = innerPadding,
- navigateToBack = navigator::navigateToBack
+ navigateToBack = navigator::navigateToBack,
+ navigateToProfile = {
+ val navOptions = navOptions { }
+ navigator.navigateToProfile(navOptions)
+ }
+ )
+ profileNavGraph(
+ paddingValues = innerPadding,
+ navigateToBack = navigator::navigateToBack,
+ navigateToMypage = {
+ val navOptions = navOptions {
+ popUpTo { inclusive = true }
+ launchSingleTop = true
+ }
+ navigator.navigateToMypage(navOptions = navOptions)
+ }
)
favoriteTownNavGraph(
paddingValues = innerPadding,
diff --git a/feature/mypage/src/main/java/com/teamsolply/solply/mypage/MypageContract.kt b/feature/mypage/src/main/java/com/teamsolply/solply/mypage/MypageContract.kt
index d39ae945..a8cdbe30 100644
--- a/feature/mypage/src/main/java/com/teamsolply/solply/mypage/MypageContract.kt
+++ b/feature/mypage/src/main/java/com/teamsolply/solply/mypage/MypageContract.kt
@@ -1,13 +1,22 @@
package com.teamsolply.solply.mypage
+import com.teamsolply.solply.mypage.model.DropDownPersonaItem
import com.teamsolply.solply.ui.base.SideEffect
import com.teamsolply.solply.ui.base.UiIntent
import com.teamsolply.solply.ui.base.UiState
+import kotlinx.collections.immutable.persistentListOf
data class MypageState(
- val town: String = "연희동"
+ val town: String = "연희동",
+ val nickname: String = "",
) : UiState
-sealed interface MypageIntent : UiIntent
+sealed interface MypageIntent : UiIntent {
-sealed interface MypageSideEffect : SideEffect
+}
+
+sealed interface MypageSideEffect : SideEffect {
+ data object NavigateToBack : MypageSideEffect
+ data object NavigateToProfile : MypageSideEffect
+ data object NavigateToMypage : MypageSideEffect
+}
diff --git a/feature/mypage/src/main/java/com/teamsolply/solply/mypage/MypageScreen.kt b/feature/mypage/src/main/java/com/teamsolply/solply/mypage/MypageScreen.kt
index ae130c99..94ee26f8 100644
--- a/feature/mypage/src/main/java/com/teamsolply/solply/mypage/MypageScreen.kt
+++ b/feature/mypage/src/main/java/com/teamsolply/solply/mypage/MypageScreen.kt
@@ -34,17 +34,20 @@ import com.teamsolply.solply.ui.extension.customClickable
fun MypageRoute(
paddingValues: PaddingValues,
navigateToBack: () -> Unit,
+ navigateToProfile: () -> Unit,
viewModel: MypageViewModel = hiltViewModel()
) {
MypageScreen(
+ onBackButtonClick = navigateToBack,
+ onProfileEditClick = navigateToProfile,
modifier = Modifier.padding(paddingValues),
- onBackButtonClick = navigateToBack
)
}
@Composable
fun MypageScreen(
onBackButtonClick: () -> Unit,
+ onProfileEditClick: () -> Unit,
modifier: Modifier = Modifier
) {
Column(
@@ -85,7 +88,12 @@ fun MypageScreen(
style = SolplyTheme.typography.display20Sb
)
Row(
- modifier = Modifier.padding(top = 12.dp)
+ modifier = Modifier
+ .padding(top = 12.dp)
+ .customClickable(
+ rippleEnabled = false,
+ onClick = onProfileEditClick
+ )
) {
Text(
text = "프로필 수정",
@@ -172,7 +180,8 @@ fun MypageScreen(
private fun MypageScreenPreview() {
SolplyTheme {
MypageScreen(
- onBackButtonClick = {}
+ onBackButtonClick = {},
+ onProfileEditClick = {}
)
}
}
diff --git a/feature/mypage/src/main/java/com/teamsolply/solply/mypage/component/SolplyPersonaDropDown.kt b/feature/mypage/src/main/java/com/teamsolply/solply/mypage/component/SolplyPersonaDropDown.kt
new file mode 100644
index 00000000..00046180
--- /dev/null
+++ b/feature/mypage/src/main/java/com/teamsolply/solply/mypage/component/SolplyPersonaDropDown.kt
@@ -0,0 +1,137 @@
+package com.teamsolply.solply.mypage.component
+
+import androidx.compose.foundation.background
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.padding
+import androidx.compose.material3.HorizontalDivider
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableIntStateOf
+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.tooling.preview.Preview
+import androidx.compose.ui.unit.dp
+import com.teamsolply.solply.designsystem.component.dropdown.SolplyBasicDropDown
+import com.teamsolply.solply.designsystem.theme.SolplyTheme
+import com.teamsolply.solply.mypage.model.DropDownPersonaItem
+import com.teamsolply.solply.ui.extension.customClickable
+import kotlinx.collections.immutable.persistentListOf
+
+@Composable
+fun SolplyPersonaDropDown(
+ placeholder: String,
+ onClickItem: (Int) -> Unit,
+ onClickDropIcon: () -> Unit,
+ dropDownContents: List,
+ selectedIndex: Int,
+ modifier: Modifier = Modifier,
+ isDropped: Boolean = false,
+ isSelected: Boolean = false
+) {
+ SolplyBasicDropDown(
+ defaultLabel = if (isSelected) dropDownContents.get(selectedIndex).label else placeholder,
+ onClickDropIcon = onClickDropIcon,
+ isDropped = isDropped,
+ modifier = modifier
+ ) {
+ dropDownContents.forEachIndexed { index, item ->
+ if (index != selectedIndex) {
+ Row(
+ modifier = Modifier
+ .fillMaxWidth()
+ .background(
+ color = SolplyTheme.colors.white
+ )
+ .customClickable(
+ rippleEnabled = false,
+ onClick = { onClickItem(index) }
+ ),
+ verticalAlignment = Alignment.CenterVertically,
+ horizontalArrangement = Arrangement.Start
+ ) {
+ Text(
+ text = item.label,
+ color = SolplyTheme.colors.gray900,
+ style = SolplyTheme.typography.body16M,
+ modifier = Modifier.padding(
+ start = 20.dp,
+ top = 14.dp,
+ bottom = 14.dp
+ )
+ )
+ }
+ HorizontalDivider(color = SolplyTheme.colors.gray300)
+ }
+ }
+ }
+}
+
+@Preview
+@Composable
+private fun SolplyPersonaDropDownPreview() {
+ var isDropped by remember { mutableStateOf(false) }
+ var isSelected by remember { mutableStateOf(false) }
+ var selectedIndex by remember { mutableIntStateOf(-1) }
+ SolplyTheme {
+ Column(
+ modifier = Modifier
+ .fillMaxWidth()
+ .background(SolplyTheme.colors.white)
+ ) {
+ SolplyPersonaDropDown(
+ placeholder = "조용한 공간에 오래 머물고 싶어요",
+ onClickItem = {},
+ onClickDropIcon = {},
+ dropDownContents = persistentListOf(
+ DropDownPersonaItem(
+ "이곳저곳 둘러보고 싶어요"
+ ),
+ DropDownPersonaItem(
+ "취향이 담긴 곳을 찾고 싶어요"
+ ),
+ DropDownPersonaItem(
+ "자연을 감상하며 쉬고 싶어요"
+ ),
+ DropDownPersonaItem(
+ "조용한 공간에 오래 머물고 싶어요"
+ ),
+ ),
+ isDropped = false,
+ selectedIndex = 0,
+ isSelected = false
+ )
+ SolplyPersonaDropDown(
+ isDropped = isDropped,
+ placeholder = "선택해주세요",
+ onClickItem = {
+ selectedIndex = it
+ isSelected = true
+ },
+ onClickDropIcon = { isDropped = !isDropped },
+ dropDownContents = persistentListOf(
+ DropDownPersonaItem(
+ "이곳저곳 둘러보고 싶어요"
+ ),
+ DropDownPersonaItem(
+ "취향이 담긴 곳을 찾고 싶어요"
+ ),
+ DropDownPersonaItem(
+ "자연을 감상하며 쉬고 싶어요"
+ ),
+ DropDownPersonaItem(
+ "조용한 공간에 오래 머물고 싶어요"
+ ),
+ ),
+ selectedIndex = selectedIndex,
+ isSelected = isSelected
+ )
+ }
+ }
+}
\ No newline at end of file
diff --git a/feature/mypage/src/main/java/com/teamsolply/solply/mypage/model/DropDownPersonaItem.kt b/feature/mypage/src/main/java/com/teamsolply/solply/mypage/model/DropDownPersonaItem.kt
new file mode 100644
index 00000000..27d2cee9
--- /dev/null
+++ b/feature/mypage/src/main/java/com/teamsolply/solply/mypage/model/DropDownPersonaItem.kt
@@ -0,0 +1,5 @@
+package com.teamsolply.solply.mypage.model
+
+data class DropDownPersonaItem(
+ val label: String
+)
diff --git a/feature/mypage/src/main/java/com/teamsolply/solply/mypage/navigation/MypageNavigation.kt b/feature/mypage/src/main/java/com/teamsolply/solply/mypage/navigation/MypageNavigation.kt
index f40be34b..8937319c 100644
--- a/feature/mypage/src/main/java/com/teamsolply/solply/mypage/navigation/MypageNavigation.kt
+++ b/feature/mypage/src/main/java/com/teamsolply/solply/mypage/navigation/MypageNavigation.kt
@@ -18,14 +18,16 @@ fun NavController.navigateMypage(
}
fun NavGraphBuilder.mypageNavGraph(
+ navigateToBack: () -> Unit,
+ navigateToProfile: () -> Unit,
paddingValues: PaddingValues,
- navigateToBack: () -> Unit
) {
composable { backStackEntry ->
val viewModel: MypageViewModel = hiltViewModel(backStackEntry)
MypageRoute(
paddingValues = paddingValues,
navigateToBack = navigateToBack,
+ navigateToProfile = navigateToProfile,
viewModel = viewModel
)
}
diff --git a/feature/mypage/src/main/java/com/teamsolply/solply/mypage/profile/ProfileScreen.kt b/feature/mypage/src/main/java/com/teamsolply/solply/mypage/profile/ProfileScreen.kt
index cd0211e6..4fd3841e 100644
--- a/feature/mypage/src/main/java/com/teamsolply/solply/mypage/profile/ProfileScreen.kt
+++ b/feature/mypage/src/main/java/com/teamsolply/solply/mypage/profile/ProfileScreen.kt
@@ -4,6 +4,7 @@ import androidx.compose.foundation.Image
import androidx.compose.foundation.background
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.fillMaxSize
@@ -22,15 +23,34 @@ import androidx.compose.ui.res.painterResource
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.teamsolply.solply.designsystem.component.button.SolplyBasicButton
import com.teamsolply.solply.designsystem.component.textfield.SolplyNicknameTextField
import com.teamsolply.solply.designsystem.component.topbar.SolplyTopBar
import com.teamsolply.solply.designsystem.theme.SolplyTheme
+import com.teamsolply.solply.mypage.MypageViewModel
import com.teamsolply.solply.mypage.R
+import com.teamsolply.solply.mypage.component.SolplyPersonaDropDown
+import kotlinx.collections.immutable.persistentListOf
+
+@Composable
+fun ProfileRoute(
+ paddingValues: PaddingValues,
+ navigateToBack: () -> Unit,
+ navigateToMypage: () -> Unit,
+ viewModel: MypageViewModel = hiltViewModel()
+) {
+ ProfileScreen(
+ onBackButtonClick = navigateToBack,
+ onCompleteButtonClick = navigateToMypage,
+ modifier = Modifier.padding(paddingValues),
+ )
+}
@Composable
fun ProfileScreen(
onBackButtonClick: () -> Unit,
+ onCompleteButtonClick: () -> Unit,
modifier: Modifier = Modifier
) {
Column(
@@ -94,17 +114,17 @@ fun ProfileScreen(
horizontalArrangement = Arrangement.Start
) {
Text(
- text = stringResource(R.string.profile_nickname),
+ text = stringResource(R.string.profile_solply_style),
color = SolplyTheme.colors.black,
style = SolplyTheme.typography.body16M
)
}
- SolplyNicknameTextField(
- value = "",
- isNicknameDuplicate = false,
- onValueChange = {},
- checkNicknameValidate = { true },
- changeNicknameValidate = {},
+ SolplyPersonaDropDown(
+ placeholder = "선택해주세요.",
+ onClickItem = {},
+ onClickDropIcon = {},
+ dropDownContents = persistentListOf(),
+ selectedIndex = -1,
modifier = Modifier.padding(vertical = 12.dp)
)
}
@@ -121,6 +141,9 @@ fun ProfileScreen(
@Composable
private fun ProfileScreenPreview() {
SolplyTheme {
- ProfileScreen(onBackButtonClick = {})
+ ProfileScreen(
+ onBackButtonClick = {},
+ onCompleteButtonClick = {}
+ )
}
}
diff --git a/feature/mypage/src/main/java/com/teamsolply/solply/mypage/profile/navigation/ProfileNavigation.kt b/feature/mypage/src/main/java/com/teamsolply/solply/mypage/profile/navigation/ProfileNavigation.kt
new file mode 100644
index 00000000..a6e4148e
--- /dev/null
+++ b/feature/mypage/src/main/java/com/teamsolply/solply/mypage/profile/navigation/ProfileNavigation.kt
@@ -0,0 +1,38 @@
+package com.teamsolply.solply.mypage.profile.navigation
+
+import androidx.compose.foundation.layout.PaddingValues
+import androidx.hilt.navigation.compose.hiltViewModel
+import androidx.navigation.NavController
+import androidx.navigation.NavGraphBuilder
+import androidx.navigation.NavOptions
+import androidx.navigation.compose.composable
+import com.teamsolply.solply.mypage.MypageRoute
+import com.teamsolply.solply.mypage.MypageViewModel
+import com.teamsolply.solply.mypage.profile.ProfileRoute
+import com.teamsolply.solply.navigation.Route
+import kotlinx.serialization.Serializable
+
+fun NavController.navigateProfile(
+ navOptions: NavOptions
+) {
+ navigate(Profile, navOptions)
+}
+
+fun NavGraphBuilder.profileNavGraph(
+ paddingValues: PaddingValues,
+ navigateToBack: () -> Unit,
+ navigateToMypage: () -> Unit,
+) {
+ composable { backStackEntry ->
+ val viewModel: MypageViewModel = hiltViewModel(backStackEntry)
+ ProfileRoute(
+ paddingValues = paddingValues,
+ navigateToBack = navigateToBack,
+ navigateToMypage = navigateToMypage,
+ viewModel = viewModel
+ )
+ }
+}
+
+@Serializable
+data object Profile : Route
\ No newline at end of file
diff --git a/feature/mypage/src/main/res/values/strings.xml b/feature/mypage/src/main/res/values/strings.xml
index 56e17901..4bd40bea 100644
--- a/feature/mypage/src/main/res/values/strings.xml
+++ b/feature/mypage/src/main/res/values/strings.xml
@@ -3,4 +3,5 @@
프로필 수정
기본 프로필
닉네임
+ 나의 솔플 스타일
\ No newline at end of file