From 7a14521f7ad73372901610e709094186cf705715 Mon Sep 17 00:00:00 2001 From: ImHyungsuk Date: Fri, 26 Sep 2025 01:21:15 +0900 Subject: [PATCH 1/5] =?UTF-8?q?feature#140=20persona=20dropdown=20?= =?UTF-8?q?=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mypage/component/SolplyPersonaDropDown.kt | 207 ++++++++++++++++++ .../mypage/model/DropDownPersonaItem.kt | 5 + .../src/main/res/drawable/ic_arrow_down.xml | 13 ++ 3 files changed, 225 insertions(+) create mode 100644 feature/mypage/src/main/java/com/teamsolply/solply/mypage/component/SolplyPersonaDropDown.kt create mode 100644 feature/mypage/src/main/java/com/teamsolply/solply/mypage/model/DropDownPersonaItem.kt create mode 100644 feature/mypage/src/main/res/drawable/ic_arrow_down.xml 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..2999e0b8 --- /dev/null +++ b/feature/mypage/src/main/java/com/teamsolply/solply/mypage/component/SolplyPersonaDropDown.kt @@ -0,0 +1,207 @@ +package com.teamsolply.solply.mypage.component + +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.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.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.draw.clip +import androidx.compose.ui.draw.drawBehind +import androidx.compose.ui.draw.scale +import androidx.compose.ui.geometry.Offset +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import com.teamsolply.solply.designsystem.theme.SolplyTheme +import com.teamsolply.solply.mypage.R +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, + isDropped: Boolean = false, + isSelected: Boolean = false +) { + val borderColor = SolplyTheme.colors.gray100 + Column( + modifier = Modifier + .clip( + RoundedCornerShape(20.dp) + ) + .border( + width = 1.dp, + color = SolplyTheme.colors.gray300, + shape = RoundedCornerShape(20.dp) + ) + ) { + Row( + modifier = Modifier + .fillMaxWidth() + .drawBehind { + val strokeWidth = 1.dp.toPx() + val y = size.height - strokeWidth / 2 + drawLine( + color = borderColor, // 선 색상 + start = Offset(0f, y), // 왼쪽 시작점 + end = Offset(size.width, y), // 오른쪽 끝점 + strokeWidth = strokeWidth + ) + } + .then( + if (isDropped) { + Modifier.background( + color = SolplyTheme.colors.gray100 + ) + } else { + Modifier.background( + color = SolplyTheme.colors.white + ) + } + ), + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.SpaceBetween + ) { + Text( + text = if (isSelected) { + dropDownContents.get(selectedIndex).label + } else { + placeholder + }, + 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() + ) { + 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(), + 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/res/drawable/ic_arrow_down.xml b/feature/mypage/src/main/res/drawable/ic_arrow_down.xml new file mode 100644 index 00000000..83903eac --- /dev/null +++ b/feature/mypage/src/main/res/drawable/ic_arrow_down.xml @@ -0,0 +1,13 @@ + + + From a30fe1a4988c78fb50f8f25cba1c24ad74a38186 Mon Sep 17 00:00:00 2001 From: ImHyungsuk Date: Fri, 26 Sep 2025 01:47:30 +0900 Subject: [PATCH 2/5] =?UTF-8?q?feature#140=20solply=20basic=20dropdown=20?= =?UTF-8?q?=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../component/dropdown/SolplyBasicDropDown.kt | 102 ++++++++++++++++++ .../src/main/res/drawable/ic_arrow_down.xml | 0 2 files changed, 102 insertions(+) create mode 100644 core/designsystem/src/main/java/com/teamsolply/solply/designsystem/component/dropdown/SolplyBasicDropDown.kt rename {feature/mypage => core/designsystem}/src/main/res/drawable/ic_arrow_down.xml (100%) 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..1571cf9f --- /dev/null +++ b/core/designsystem/src/main/java/com/teamsolply/solply/designsystem/component/dropdown/SolplyBasicDropDown.kt @@ -0,0 +1,102 @@ +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, + 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/feature/mypage/src/main/res/drawable/ic_arrow_down.xml b/core/designsystem/src/main/res/drawable/ic_arrow_down.xml similarity index 100% rename from feature/mypage/src/main/res/drawable/ic_arrow_down.xml rename to core/designsystem/src/main/res/drawable/ic_arrow_down.xml From ae71e813e0f1124909bbb8811d081ce624671f73 Mon Sep 17 00:00:00 2001 From: ImHyungsuk Date: Fri, 26 Sep 2025 01:48:10 +0900 Subject: [PATCH 3/5] =?UTF-8?q?feature#140=20solply=20persona=20dropdown?= =?UTF-8?q?=20=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mypage/component/SolplyPersonaDropDown.kt | 156 +++++------------- 1 file changed, 42 insertions(+), 114 deletions(-) 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 index 2999e0b8..38312903 100644 --- 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 @@ -1,20 +1,12 @@ package com.teamsolply.solply.mypage.component -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.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.runtime.getValue @@ -24,15 +16,10 @@ import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.draw.drawBehind -import androidx.compose.ui.draw.scale -import androidx.compose.ui.geometry.Offset -import androidx.compose.ui.res.painterResource 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.R import com.teamsolply.solply.mypage.model.DropDownPersonaItem import com.teamsolply.solply.ui.extension.customClickable import kotlinx.collections.immutable.persistentListOf @@ -47,110 +34,38 @@ fun SolplyPersonaDropDown( isDropped: Boolean = false, isSelected: Boolean = false ) { - val borderColor = SolplyTheme.colors.gray100 - Column( - modifier = Modifier - .clip( - RoundedCornerShape(20.dp) - ) - .border( - width = 1.dp, - color = SolplyTheme.colors.gray300, - shape = RoundedCornerShape(20.dp) - ) + SolplyBasicDropDown( + defaultLabel = if (isSelected) dropDownContents.get(selectedIndex).label else placeholder, + onClickDropIcon = onClickDropIcon, + isDropped = isDropped, ) { - Row( - modifier = Modifier - .fillMaxWidth() - .drawBehind { - val strokeWidth = 1.dp.toPx() - val y = size.height - strokeWidth / 2 - drawLine( - color = borderColor, // 선 색상 - start = Offset(0f, y), // 왼쪽 시작점 - end = Offset(size.width, y), // 오른쪽 끝점 - strokeWidth = strokeWidth - ) - } - .then( - if (isDropped) { - Modifier.background( - color = SolplyTheme.colors.gray100 - ) - } else { - Modifier.background( + dropDownContents.forEachIndexed { index, item -> + if (index != selectedIndex) { + Row( + modifier = Modifier + .fillMaxWidth() + .background( color = SolplyTheme.colors.white ) - } - ), - verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.SpaceBetween - ) { - Text( - text = if (isSelected) { - dropDownContents.get(selectedIndex).label - } else { - placeholder - }, - 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 + .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) - AnimatedVisibility( - visible = isDropped, - enter = slideInVertically(), - exit = slideOutVertically() - ) { - Column( - modifier = Modifier.fillMaxWidth() - ) { - 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) - } } + HorizontalDivider(color = SolplyTheme.colors.gray300) } } } @@ -172,7 +87,20 @@ private fun SolplyPersonaDropDownPreview() { placeholder = "조용한 공간에 오래 머물고 싶어요", onClickItem = {}, onClickDropIcon = {}, - dropDownContents = persistentListOf(), + dropDownContents = persistentListOf( + DropDownPersonaItem( + "이곳저곳 둘러보고 싶어요" + ), + DropDownPersonaItem( + "취향이 담긴 곳을 찾고 싶어요" + ), + DropDownPersonaItem( + "자연을 감상하며 쉬고 싶어요" + ), + DropDownPersonaItem( + "조용한 공간에 오래 머물고 싶어요" + ), + ), isDropped = false, selectedIndex = 0, isSelected = false From c03932132b30a4ba6dea2200444ce5458dca3e9b Mon Sep 17 00:00:00 2001 From: ImHyungsuk Date: Fri, 26 Sep 2025 01:59:53 +0900 Subject: [PATCH 4/5] =?UTF-8?q?feature#132=20=ED=94=84=EB=A1=9C=ED=95=84?= =?UTF-8?q?=20=EC=88=98=EC=A0=95=20=ED=8E=98=EC=9D=B4=EC=A7=80=20ui=20?= =?UTF-8?q?=EC=99=84=EB=A3=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../component/dropdown/SolplyBasicDropDown.kt | 3 ++- .../mypage/component/SolplyPersonaDropDown.kt | 2 ++ .../solply/mypage/profile/ProfileScreen.kt | 16 +++++++++------- feature/mypage/src/main/res/values/strings.xml | 1 + 4 files changed, 14 insertions(+), 8 deletions(-) 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 index 1571cf9f..8f732d6d 100644 --- 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 @@ -32,11 +32,12 @@ import com.teamsolply.solply.ui.extension.customClickable fun SolplyBasicDropDown( defaultLabel: String, onClickDropIcon: () -> Unit, + modifier: Modifier = Modifier, isDropped: Boolean = false, content: @Composable ColumnScope.() -> Unit, ) { Column( - modifier = Modifier + modifier = modifier .clip( RoundedCornerShape(20.dp) ) 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 index 38312903..00046180 100644 --- 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 @@ -31,6 +31,7 @@ fun SolplyPersonaDropDown( onClickDropIcon: () -> Unit, dropDownContents: List, selectedIndex: Int, + modifier: Modifier = Modifier, isDropped: Boolean = false, isSelected: Boolean = false ) { @@ -38,6 +39,7 @@ fun SolplyPersonaDropDown( defaultLabel = if (isSelected) dropDownContents.get(selectedIndex).label else placeholder, onClickDropIcon = onClickDropIcon, isDropped = isDropped, + modifier = modifier ) { dropDownContents.forEachIndexed { index, item -> if (index != selectedIndex) { 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..15b60f7d 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 @@ -27,6 +27,8 @@ import com.teamsolply.solply.designsystem.component.textfield.SolplyNicknameText import com.teamsolply.solply.designsystem.component.topbar.SolplyTopBar import com.teamsolply.solply.designsystem.theme.SolplyTheme import com.teamsolply.solply.mypage.R +import com.teamsolply.solply.mypage.component.SolplyPersonaDropDown +import kotlinx.collections.immutable.persistentListOf @Composable fun ProfileScreen( @@ -94,17 +96,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) ) } 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 From fd6ea0d9c9ebc810595c2fb3bb4c8a798529cefb Mon Sep 17 00:00:00 2001 From: ImHyungsuk Date: Fri, 26 Sep 2025 14:41:18 +0900 Subject: [PATCH 5/5] =?UTF-8?q?feature#132=20=ED=94=84=EB=A1=9C=ED=95=84?= =?UTF-8?q?=20=EC=88=98=EC=A0=95=20=ED=8E=98=EC=9D=B4=EC=A7=80=20navigatio?= =?UTF-8?q?n=20=EC=97=B0=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../teamsolply/solply/main/MainNavigator.kt | 17 +++++++++ .../com/teamsolply/solply/main/MainScreen.kt | 20 +++++++++- .../solply/mypage/MypageContract.kt | 15 ++++++-- .../teamsolply/solply/mypage/MypageScreen.kt | 15 ++++++-- .../mypage/navigation/MypageNavigation.kt | 4 +- .../solply/mypage/profile/ProfileScreen.kt | 23 ++++++++++- .../profile/navigation/ProfileNavigation.kt | 38 +++++++++++++++++++ 7 files changed, 123 insertions(+), 9 deletions(-) create mode 100644 feature/mypage/src/main/java/com/teamsolply/solply/mypage/profile/navigation/ProfileNavigation.kt 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/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 15b60f7d..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,17 +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( @@ -123,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