diff --git a/core/designsystem/src/main/res/drawable/ic_alarm_black.xml b/core/designsystem/src/main/res/drawable/ic_alarm_black.xml
new file mode 100644
index 00000000..7a4b701f
--- /dev/null
+++ b/core/designsystem/src/main/res/drawable/ic_alarm_black.xml
@@ -0,0 +1,29 @@
+
+
+
+
+
+
diff --git a/core/designsystem/src/main/res/drawable/ic_arrow_right_black.xml b/core/designsystem/src/main/res/drawable/ic_arrow_right_black.xml
new file mode 100644
index 00000000..273eb91a
--- /dev/null
+++ b/core/designsystem/src/main/res/drawable/ic_arrow_right_black.xml
@@ -0,0 +1,13 @@
+
+
+
diff --git a/core/designsystem/src/main/res/drawable/ic_question.xml b/core/designsystem/src/main/res/drawable/ic_question.xml
index 31ec4b74..8d1667da 100644
--- a/core/designsystem/src/main/res/drawable/ic_question.xml
+++ b/core/designsystem/src/main/res/drawable/ic_question.xml
@@ -4,11 +4,11 @@
android:viewportWidth="20"
android:viewportHeight="20">
+ android:strokeColor="#1B1A2A" />
+ android:fillColor="#1B1A2A" />
diff --git a/core/designsystem/src/main/res/drawable/ic_talk.xml b/core/designsystem/src/main/res/drawable/ic_talk.xml
new file mode 100644
index 00000000..4adcbe30
--- /dev/null
+++ b/core/designsystem/src/main/res/drawable/ic_talk.xml
@@ -0,0 +1,12 @@
+
+
+
diff --git a/core/designsystem/src/main/res/values/strings.xml b/core/designsystem/src/main/res/values/strings.xml
index 8c73d806..93506708 100644
--- a/core/designsystem/src/main/res/values/strings.xml
+++ b/core/designsystem/src/main/res/values/strings.xml
@@ -53,10 +53,13 @@
세
년생
키
+ cm
종교
활동 지역
직업
흡연
+ 몸무게
+ kg
전체
나와 같은
나와 다른
@@ -91,4 +94,12 @@
매칭 알림
푸쉬 알림
로그인 계정
+
+
+ Profile
+ 나의 매칭 조각
+ 가치관 Talk
+ 꿈과 목표, 관심사와 취향, 연애에 관련된\n내 생각을 확인하고 수정할 수 있습니다.
+ 가치관 Pick
+ 퀴즈를 통해 나의 연애 스타일을 파악해보고\n선택한 답변을 수정할 수 있습니다.
\ No newline at end of file
diff --git a/feature/matching/src/main/java/com/puzzle/matching/graph/detail/common/component/BasicInfoHeader.kt b/feature/matching/src/main/java/com/puzzle/matching/graph/detail/common/component/BasicInfoHeader.kt
index 5c241cca..49c0a409 100644
--- a/feature/matching/src/main/java/com/puzzle/matching/graph/detail/common/component/BasicInfoHeader.kt
+++ b/feature/matching/src/main/java/com/puzzle/matching/graph/detail/common/component/BasicInfoHeader.kt
@@ -2,13 +2,10 @@ package com.puzzle.matching.graph.detail.common.component
import androidx.compose.foundation.Image
import androidx.compose.foundation.clickable
+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.height
-import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
-import androidx.compose.foundation.layout.width
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
@@ -25,15 +22,13 @@ internal fun BasicInfoHeader(
onMoreClick: () -> Unit,
modifier: Modifier = Modifier
) {
- Column(modifier = modifier) {
+ Column(verticalArrangement = Arrangement.spacedBy(8.dp), modifier = modifier) {
Text(
text = selfDescription,
style = PieceTheme.typography.bodyMR,
color = PieceTheme.colors.black,
)
- Spacer(modifier = Modifier.height(8.dp))
-
Row(verticalAlignment = Alignment.CenterVertically) {
Text(
text = nickName,
@@ -42,8 +37,6 @@ internal fun BasicInfoHeader(
modifier = Modifier.weight(1f)
)
- Spacer(modifier = Modifier.width(28.dp))
-
Image(
painter = painterResource(id = R.drawable.ic_more),
contentDescription = "basic info 배경화면",
diff --git a/feature/matching/src/main/java/com/puzzle/matching/graph/detail/page/BasicInfoPage.kt b/feature/matching/src/main/java/com/puzzle/matching/graph/detail/page/BasicInfoPage.kt
index 71f8bfac..d3f92839 100644
--- a/feature/matching/src/main/java/com/puzzle/matching/graph/detail/page/BasicInfoPage.kt
+++ b/feature/matching/src/main/java/com/puzzle/matching/graph/detail/page/BasicInfoPage.kt
@@ -17,6 +17,7 @@ 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.graphics.Color
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
@@ -52,10 +53,10 @@ internal fun BasicInfoPage(
age = age,
birthYear = birthYear,
height = height,
- religion = religion,
activityRegion = activityRegion,
occupation = occupation,
smokeStatue = smokeStatue,
+ modifier = Modifier.padding(horizontal = 20.dp)
)
}
}
@@ -67,12 +68,11 @@ private fun BasicInfoName(
onMoreClick: () -> Unit,
modifier: Modifier = Modifier,
) {
- Column(modifier = modifier) {
+ Column(modifier = modifier.padding(horizontal = 20.dp)) {
Text(
text = stringResource(R.string.basicinfo_main_label),
style = PieceTheme.typography.bodyMM,
color = PieceTheme.colors.primaryDefault,
- modifier = Modifier.padding(horizontal = 20.dp),
)
Spacer(modifier = Modifier.weight(1f))
@@ -81,138 +81,133 @@ private fun BasicInfoName(
nickName = nickName,
selfDescription = selfDescription,
onMoreClick = onMoreClick,
- modifier = Modifier
- .padding(
- vertical = 20.dp,
- horizontal = 20.dp
- ),
)
}
}
@Composable
-private fun BasicInfoCard(
+private fun ColumnScope.BasicInfoCard(
age: String,
birthYear: String,
height: String,
- religion: String,
activityRegion: String,
occupation: String,
smokeStatue: String,
modifier: Modifier = Modifier,
) {
- Column(
+ Row(
+ horizontalArrangement = Arrangement.spacedBy(4.dp),
modifier = modifier
.fillMaxWidth()
- .padding(horizontal = 20.dp, vertical = 12.dp),
+ .padding(top = 12.dp, bottom = 4.dp)
) {
- Row(
- horizontalArrangement = Arrangement.spacedBy(4.dp),
- ) {
- InfoItem(
- title = stringResource(R.string.basicinfocard_age),
- text = {
- Row(verticalAlignment = Alignment.Bottom) {
- Text(
- text = stringResource(R.string.basicinfocard_age_particle),
- style = PieceTheme.typography.bodySM,
- color = PieceTheme.colors.black,
- )
-
- Spacer(modifier = Modifier.width(4.dp))
+ InfoItem(
+ title = stringResource(R.string.basicinfocard_age),
+ text = {
+ Row(verticalAlignment = Alignment.CenterVertically) {
+ Text(
+ text = stringResource(R.string.basicinfocard_age_particle),
+ style = PieceTheme.typography.bodySM,
+ color = PieceTheme.colors.black,
+ )
- Text(
- text = age,
- style = PieceTheme.typography.headingSSB,
- color = PieceTheme.colors.black,
- )
+ Spacer(modifier = Modifier.width(4.dp))
- Text(
- text = stringResource(R.string.basicinfocard_age_classifier),
- style = PieceTheme.typography.bodySM,
- color = PieceTheme.colors.black,
- )
+ Text(
+ text = age,
+ style = PieceTheme.typography.headingSSB,
+ color = PieceTheme.colors.black,
+ )
- Spacer(modifier = Modifier.width(4.dp))
+ Text(
+ text = stringResource(R.string.basicinfocard_age_classifier),
+ style = PieceTheme.typography.bodySM,
+ color = PieceTheme.colors.black,
+ )
- Text(
- text = birthYear + stringResource(R.string.basicinfocard_age_suffix),
- style = PieceTheme.typography.bodySM,
- color = PieceTheme.colors.dark2,
- modifier = Modifier.padding(top = 1.dp),
- )
- }
- },
- modifier = modifier.width(width = 144.dp),
- )
+ Spacer(modifier = Modifier.width(4.dp))
- InfoItem(
- title = stringResource(R.string.basicinfocard_height),
- text = {
- Row(verticalAlignment = Alignment.Bottom) {
- Text(
- text = height,
- style = PieceTheme.typography.headingSSB,
- color = PieceTheme.colors.black,
- )
+ Text(
+ text = birthYear + stringResource(R.string.basicinfocard_age_suffix),
+ style = PieceTheme.typography.bodySM,
+ color = PieceTheme.colors.dark2,
+ modifier = Modifier.padding(top = 1.dp),
+ )
+ }
+ },
+ modifier = Modifier.size(
+ width = 144.dp,
+ height = 80.dp,
+ ),
+ )
- Text(
- text = "cm",
- style = PieceTheme.typography.bodySM,
- color = PieceTheme.colors.black,
- )
- }
- },
- modifier = modifier.weight(1f),
- )
+ InfoItem(
+ title = stringResource(R.string.basicinfocard_height),
+ text = {
+ Row(verticalAlignment = Alignment.CenterVertically) {
+ Text(
+ text = height,
+ style = PieceTheme.typography.headingSSB,
+ color = PieceTheme.colors.black,
+ )
- InfoItem(
- title = "몸무게",
- text = {
- Row(verticalAlignment = Alignment.Bottom) {
- Text(
- text = "72",
- style = PieceTheme.typography.headingSSB,
- color = PieceTheme.colors.black,
- )
+ Text(
+ text = "cm",
+ style = PieceTheme.typography.bodySM,
+ color = PieceTheme.colors.black,
+ )
+ }
+ },
+ modifier = Modifier.weight(1f),
+ )
- Text(
- text = "kg",
- style = PieceTheme.typography.bodySM,
- color = PieceTheme.colors.black,
- )
- }
- },
- modifier = modifier.weight(1f),
- )
- }
+ InfoItem(
+ title = "몸무게",
+ text = {
+ Row(verticalAlignment = Alignment.CenterVertically) {
+ Text(
+ text = "72",
+ style = PieceTheme.typography.headingSSB,
+ color = PieceTheme.colors.black,
+ )
- Spacer(modifier = Modifier.height(4.dp))
+ Text(
+ text = "kg",
+ style = PieceTheme.typography.bodySM,
+ color = PieceTheme.colors.black,
+ )
+ }
+ },
+ modifier = Modifier.weight(1f),
+ )
+ }
- Row(
- horizontalArrangement = Arrangement.spacedBy(5.5.dp),
- ) {
- InfoItem(
- title = stringResource(R.string.basicinfocard_activityRegion),
- content = activityRegion,
- modifier = modifier.size(
- width = 144.dp,
- height = 80.dp,
- ),
- )
+ Row(
+ horizontalArrangement = Arrangement.spacedBy(4.dp),
+ modifier = modifier
+ .fillMaxWidth()
+ .padding(bottom = 12.dp)
+ ) {
+ InfoItem(
+ title = stringResource(R.string.basicinfocard_activityRegion),
+ content = activityRegion,
+ modifier = Modifier.size(
+ width = 144.dp,
+ height = 80.dp,
+ ),
+ )
- InfoItem(
- title = stringResource(R.string.basicinfocard_occupation),
- content = occupation,
- modifier = modifier.weight(1f),
- )
+ InfoItem(
+ title = stringResource(R.string.basicinfocard_occupation),
+ content = occupation,
+ modifier = Modifier.weight(1f),
+ )
- InfoItem(
- title = stringResource(R.string.basicinfocard_smokeStatue),
- content = smokeStatue,
- modifier = modifier.weight(1f),
- )
- }
+ InfoItem(
+ title = stringResource(R.string.basicinfocard_smokeStatue),
+ content = smokeStatue,
+ modifier = Modifier.weight(1f),
+ )
}
}
@@ -221,15 +216,20 @@ private fun InfoItem(
title: String,
modifier: Modifier = Modifier,
content: String? = null,
+ backgroundColor: Color = PieceTheme.colors.white,
text: @Composable ColumnScope.() -> Unit? = {},
) {
Column(
+ verticalArrangement = Arrangement.spacedBy(
+ space = 8.dp,
+ alignment = Alignment.CenterVertically
+ ),
horizontalAlignment = Alignment.CenterHorizontally,
modifier = modifier
.height(80.dp)
.clip(RoundedCornerShape(8.dp))
- .background(PieceTheme.colors.white)
- .padding(vertical = 16.dp, horizontal = 12.dp),
+ .background(backgroundColor)
+ .padding(horizontal = 12.dp),
) {
Text(
text = title,
@@ -237,8 +237,6 @@ private fun InfoItem(
color = PieceTheme.colors.dark2,
)
- Spacer(modifier = Modifier.height(8.dp))
-
if (content != null) {
Text(
text = content,
diff --git a/feature/profile/src/main/java/com/puzzle/profile/graph/home/ProfileScreen.kt b/feature/profile/src/main/java/com/puzzle/profile/graph/home/ProfileScreen.kt
deleted file mode 100644
index 10a2f348..00000000
--- a/feature/profile/src/main/java/com/puzzle/profile/graph/home/ProfileScreen.kt
+++ /dev/null
@@ -1,25 +0,0 @@
-package com.puzzle.profile.graph.home
-
-import androidx.compose.foundation.layout.Box
-import androidx.compose.foundation.layout.fillMaxSize
-import androidx.compose.material3.Text
-import androidx.compose.runtime.Composable
-import androidx.compose.ui.Alignment
-import androidx.compose.ui.Modifier
-import androidx.compose.ui.unit.sp
-
-@Composable
-internal fun ProfileRoute() {
- ProfileScreen()
-}
-
-@Composable
-private fun ProfileScreen(
-) {
- Box(
- modifier = Modifier.fillMaxSize(),
- contentAlignment = Alignment.Center,
- ) {
- Text(text = "MyPageRoute", fontSize = 30.sp)
- }
-}
\ No newline at end of file
diff --git a/feature/profile/src/main/java/com/puzzle/profile/graph/main/MainProfileScreen.kt b/feature/profile/src/main/java/com/puzzle/profile/graph/main/MainProfileScreen.kt
new file mode 100644
index 00000000..4845854f
--- /dev/null
+++ b/feature/profile/src/main/java/com/puzzle/profile/graph/main/MainProfileScreen.kt
@@ -0,0 +1,464 @@
+package com.puzzle.profile.graph.main
+
+import androidx.compose.foundation.Image
+import androidx.compose.foundation.background
+import androidx.compose.foundation.clickable
+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.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.layout.width
+import androidx.compose.foundation.shape.RoundedCornerShape
+import androidx.compose.material3.HorizontalDivider
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.LaunchedEffect
+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.ColorFilter
+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.lifecycle.compose.LocalLifecycleOwner
+import com.airbnb.mvrx.compose.collectAsState
+import com.airbnb.mvrx.compose.mavericksViewModel
+import com.puzzle.common.ui.repeatOnStarted
+import com.puzzle.designsystem.R
+import com.puzzle.designsystem.component.PieceMainTopBar
+import com.puzzle.designsystem.foundation.PieceTheme
+import com.puzzle.profile.graph.main.contract.MainProfileSideEffect
+import com.puzzle.profile.graph.main.contract.MainProfileState
+
+@Composable
+internal fun MainProfileRoute(
+ viewModel: MainProfileViewModel = mavericksViewModel()
+) {
+ val state by viewModel.collectAsState()
+ val lifecycleOwner = LocalLifecycleOwner.current
+
+ LaunchedEffect(viewModel) {
+ lifecycleOwner.repeatOnStarted {
+ viewModel.sideEffects.collect { sideEffect ->
+ when (sideEffect) {
+ is MainProfileSideEffect.Navigate ->
+ viewModel.navigationHelper.navigate(sideEffect.navigationEvent)
+ }
+ }
+ }
+ }
+
+ MainProfileScreen(
+ state = state,
+ onMyProfileClick = {},
+ onValueTalkClick = {},
+ onValuePickClick = {},
+ )
+}
+
+@Composable
+private fun MainProfileScreen(
+ state: MainProfileState,
+ onMyProfileClick: () -> Unit,
+ onValueTalkClick: () -> Unit,
+ onValuePickClick: () -> Unit,
+ modifier: Modifier = Modifier,
+) {
+ Column(
+ modifier = modifier
+ .fillMaxSize()
+ .background(PieceTheme.colors.white),
+ ) {
+ PieceMainTopBar(
+ title = stringResource(R.string.main_profile_topbar_title),
+ rightComponent = {
+ Image(
+ painter = painterResource(R.drawable.ic_alarm_black),
+ contentDescription = "알람",
+ )
+ },
+ modifier = Modifier.padding(vertical = 14.dp, horizontal = 20.dp),
+ )
+
+ MyProfile(
+ nickName = state.nickName,
+ selfDescription = state.selfDescription,
+ age = state.age,
+ birthYear = state.birthYear,
+ height = state.height,
+ activityRegion = state.activityRegion,
+ occupation = state.occupation,
+ smokeStatue = state.smokeStatue,
+ weight = state.weight,
+ onMyProfileClick = onMyProfileClick,
+ modifier = Modifier.padding(horizontal = 20.dp)
+ )
+
+ HorizontalDivider(
+ thickness = 12.dp,
+ color = PieceTheme.colors.light3,
+ )
+
+ MyMatchingPiece(
+ onValueTalkClick = onValueTalkClick,
+ onValuePickClick = onValuePickClick,
+ modifier = Modifier.padding(horizontal = 20.dp)
+ )
+ }
+}
+
+@Composable
+private fun MyProfile(
+ nickName: String,
+ selfDescription: String,
+ age: String,
+ birthYear: String,
+ height: String,
+ activityRegion: String,
+ occupation: String,
+ smokeStatue: String,
+ weight: String,
+ onMyProfileClick: () -> Unit,
+ modifier: Modifier = Modifier,
+) {
+ Row(
+ modifier = modifier
+ .padding(top = 20.dp)
+ .clickable { onMyProfileClick() }
+ ) {
+ Image(
+ painter = painterResource(R.drawable.ic_profile_default),
+ contentDescription = null,
+ modifier = Modifier.size(80.dp),
+ )
+
+ Column(
+ modifier = Modifier
+ .padding(vertical = 9.dp)
+ .padding(start = 20.dp)
+ .align(Alignment.CenterVertically),
+ ) {
+ Text(
+ text = selfDescription,
+ style = PieceTheme.typography.bodyMR,
+ modifier = Modifier.padding(bottom = 6.dp),
+ )
+
+ Text(
+ text = nickName,
+ color = PieceTheme.colors.primaryDefault,
+ style = PieceTheme.typography.headingLSB,
+ )
+ }
+
+ Spacer(modifier = Modifier.weight(1f))
+
+ Image(
+ painter = painterResource(R.drawable.ic_arrow_right_black),
+ contentDescription = null,
+ modifier = Modifier
+ .size(30.dp)
+ .align(Alignment.CenterVertically),
+ )
+ }
+
+ BasicInfoCard(
+ age = age,
+ birthYear = birthYear,
+ height = height,
+ activityRegion = activityRegion,
+ occupation = occupation,
+ smokeStatue = smokeStatue,
+ weight = weight,
+ modifier = modifier,
+ )
+}
+
+@Composable
+private fun MyMatchingPiece(
+ onValueTalkClick: () -> Unit,
+ onValuePickClick: () -> Unit,
+ modifier: Modifier = Modifier,
+) {
+ Text(
+ text = stringResource(R.string.main_profile_my_matching_piece_title),
+ style = PieceTheme.typography.bodyMM,
+ color = PieceTheme.colors.dark2,
+ modifier = modifier.padding(top = 24.dp, bottom = 12.dp),
+ )
+
+ MyMatchingPieceDetail(
+ imageId = R.drawable.ic_talk,
+ title = stringResource(R.string.main_profile_value_talk_title),
+ content = stringResource(R.string.main_profile_value_talk_content),
+ onMyMatchingPieceDetailClick = onValueTalkClick,
+ modifier = modifier.padding(vertical = 16.dp),
+ )
+
+ HorizontalDivider(
+ thickness = 1.dp,
+ color = PieceTheme.colors.light2,
+ modifier = modifier.fillMaxWidth(),
+ )
+
+ MyMatchingPieceDetail(
+ imageId = R.drawable.ic_question,
+ title = stringResource(R.string.main_profile_value_pick_title),
+ content = stringResource(R.string.main_profile_value_pick_content),
+ onMyMatchingPieceDetailClick = onValuePickClick,
+ modifier = modifier.padding(vertical = 16.dp),
+ )
+}
+
+@Composable
+private fun MyMatchingPieceDetail(
+ imageId: Int,
+ title: String,
+ content: String,
+ onMyMatchingPieceDetailClick: () -> Unit,
+ modifier: Modifier = Modifier,
+) {
+ Row(
+ modifier = modifier.clickable {
+ onMyMatchingPieceDetailClick()
+ },
+ ) {
+ Column(
+ verticalArrangement = Arrangement.spacedBy(8.dp),
+ modifier = Modifier.weight(1f),
+ ) {
+ Row(
+ verticalAlignment = Alignment.CenterVertically,
+ ) {
+ Image(
+ painter = painterResource(imageId),
+ contentDescription = null,
+ colorFilter = ColorFilter.tint(PieceTheme.colors.dark1),
+ modifier = Modifier.size(20.dp),
+ )
+
+ Text(
+ text = title,
+ style = PieceTheme.typography.headingSSB,
+ color = PieceTheme.colors.dark1,
+ modifier = Modifier.padding(start = 8.dp),
+ )
+ }
+
+ Text(
+ text = content,
+ style = PieceTheme.typography.captionM,
+ color = PieceTheme.colors.dark3,
+ modifier = Modifier.padding(start = 28.dp),
+ )
+ }
+
+ Image(
+ painter = painterResource(R.drawable.ic_arrow_right_black),
+ contentDescription = null,
+ modifier = Modifier.size(24.dp),
+ )
+ }
+}
+
+@Composable
+private fun BasicInfoCard(
+ age: String,
+ birthYear: String,
+ height: String,
+ weight: String,
+ activityRegion: String,
+ occupation: String,
+ smokeStatue: String,
+ modifier: Modifier = Modifier,
+) {
+ Row(
+ horizontalArrangement = Arrangement.spacedBy(4.dp),
+ modifier = modifier
+ .fillMaxWidth()
+ .padding(top = 24.dp, bottom = 4.dp),
+ ) {
+ InfoItem(
+ title = stringResource(R.string.basicinfocard_age),
+ text = {
+ Row(verticalAlignment = Alignment.CenterVertically) {
+ Text(
+ text = stringResource(R.string.basicinfocard_age_particle),
+ style = PieceTheme.typography.bodySM,
+ color = PieceTheme.colors.black,
+ )
+
+ Spacer(modifier = Modifier.width(4.dp))
+
+ Text(
+ text = age,
+ style = PieceTheme.typography.headingSSB,
+ color = PieceTheme.colors.black,
+ )
+
+ Text(
+ text = stringResource(R.string.basicinfocard_age_classifier),
+ style = PieceTheme.typography.bodySM,
+ color = PieceTheme.colors.black,
+ )
+
+ Spacer(modifier = Modifier.width(4.dp))
+
+ Text(
+ text = birthYear + stringResource(R.string.basicinfocard_age_suffix),
+ style = PieceTheme.typography.bodySM,
+ color = PieceTheme.colors.dark2,
+ modifier = Modifier.padding(top = 1.dp),
+ )
+ }
+ },
+ backgroundColor = PieceTheme.colors.light3,
+ modifier = Modifier.size(
+ width = 144.dp,
+ height = 80.dp,
+ ),
+ )
+
+ InfoItem(
+ title = stringResource(R.string.basicinfocard_height),
+ text = {
+ Row(verticalAlignment = Alignment.CenterVertically) {
+ Text(
+ text = height,
+ style = PieceTheme.typography.headingSSB,
+ color = PieceTheme.colors.black,
+ )
+
+ Text(
+ text = stringResource(R.string.basicinfocard_height_unit),
+ style = PieceTheme.typography.bodySM,
+ color = PieceTheme.colors.black,
+ )
+ }
+ },
+ backgroundColor = PieceTheme.colors.light3,
+ modifier = Modifier.weight(1f),
+ )
+
+ InfoItem(
+ title = stringResource(R.string.basicinfocard_weight),
+ text = {
+ Row(verticalAlignment = Alignment.CenterVertically) {
+ Text(
+ text = weight,
+ style = PieceTheme.typography.headingSSB,
+ color = PieceTheme.colors.black,
+ )
+
+ Text(
+ text = stringResource(R.string.basicinfocard_weight_unit),
+ style = PieceTheme.typography.bodySM,
+ color = PieceTheme.colors.black,
+ )
+ }
+ },
+ backgroundColor = PieceTheme.colors.light3,
+ modifier = Modifier.weight(1f),
+ )
+ }
+
+ Row(
+ horizontalArrangement = Arrangement.spacedBy(4.dp),
+ modifier = modifier
+ .fillMaxWidth()
+ .padding(bottom = 32.dp),
+ ) {
+ InfoItem(
+ title = stringResource(R.string.basicinfocard_activityRegion),
+ content = activityRegion,
+ backgroundColor = PieceTheme.colors.light3,
+ modifier = Modifier.size(
+ width = 144.dp,
+ height = 80.dp,
+ ),
+ )
+
+ InfoItem(
+ title = stringResource(R.string.basicinfocard_occupation),
+ content = occupation,
+ backgroundColor = PieceTheme.colors.light3,
+ modifier = Modifier.weight(1f),
+ )
+
+ InfoItem(
+ title = stringResource(R.string.basicinfocard_smokeStatue),
+ content = smokeStatue,
+ backgroundColor = PieceTheme.colors.light3,
+ modifier = Modifier.weight(1f),
+ )
+ }
+}
+
+@Composable
+private fun InfoItem(
+ title: String,
+ modifier: Modifier = Modifier,
+ content: String? = null,
+ backgroundColor: Color = PieceTheme.colors.white,
+ text: @Composable ColumnScope.() -> Unit? = {},
+) {
+ Column(
+ verticalArrangement = Arrangement.spacedBy(
+ space = 8.dp,
+ alignment = Alignment.CenterVertically,
+ ),
+ horizontalAlignment = Alignment.CenterHorizontally,
+ modifier = modifier
+ .height(80.dp)
+ .clip(RoundedCornerShape(8.dp))
+ .background(backgroundColor)
+ .padding(horizontal = 12.dp),
+ ) {
+ Text(
+ text = title,
+ style = PieceTheme.typography.bodySM,
+ color = PieceTheme.colors.dark2,
+ )
+
+ if (content != null) {
+ Text(
+ text = content,
+ style = PieceTheme.typography.headingSSB,
+ color = PieceTheme.colors.black,
+ )
+ } else {
+ text()
+ }
+ }
+}
+
+@Preview
+@Composable
+private fun ProfileScreenPreview() {
+ PieceTheme {
+ MainProfileScreen(
+ state = MainProfileState(
+ nickName = "수줍은 수달",
+ selfDescription = "음악과 요리를 좋아하는",
+ age = "14",
+ birthYear = "00",
+ height = "100",
+ activityRegion = "서울 특별시",
+ occupation = "개발자",
+ smokeStatue = "흡연",
+ ),
+ onMyProfileClick = {},
+ onValueTalkClick = {},
+ onValuePickClick = {},
+ )
+ }
+}
\ No newline at end of file
diff --git a/feature/profile/src/main/java/com/puzzle/profile/graph/main/MainProfileViewModel.kt b/feature/profile/src/main/java/com/puzzle/profile/graph/main/MainProfileViewModel.kt
new file mode 100644
index 00000000..53aea0a9
--- /dev/null
+++ b/feature/profile/src/main/java/com/puzzle/profile/graph/main/MainProfileViewModel.kt
@@ -0,0 +1,56 @@
+package com.puzzle.profile.graph.main
+
+import com.airbnb.mvrx.MavericksViewModel
+import com.airbnb.mvrx.MavericksViewModelFactory
+import com.airbnb.mvrx.hilt.AssistedViewModelFactory
+import com.airbnb.mvrx.hilt.hiltMavericksViewModelFactory
+import com.puzzle.domain.model.error.ErrorHelper
+import com.puzzle.navigation.NavigationHelper
+import com.puzzle.profile.graph.main.contract.MainProfileIntent
+import com.puzzle.profile.graph.main.contract.MainProfileSideEffect
+import com.puzzle.profile.graph.main.contract.MainProfileState
+import dagger.assisted.Assisted
+import dagger.assisted.AssistedFactory
+import dagger.assisted.AssistedInject
+import kotlinx.coroutines.channels.Channel
+import kotlinx.coroutines.channels.Channel.Factory.BUFFERED
+import kotlinx.coroutines.flow.launchIn
+import kotlinx.coroutines.flow.onEach
+import kotlinx.coroutines.flow.receiveAsFlow
+import kotlinx.coroutines.launch
+
+class MainProfileViewModel @AssistedInject constructor(
+ @Assisted initialState: MainProfileState,
+ internal val navigationHelper: NavigationHelper,
+ private val errorHelper: ErrorHelper,
+) : MavericksViewModel(initialState) {
+
+ private val intents = Channel(BUFFERED)
+ private val _sideEffects = Channel(BUFFERED)
+ val sideEffects = _sideEffects.receiveAsFlow()
+
+ init {
+ intents.receiveAsFlow()
+ .onEach(::processIntent)
+ .launchIn(viewModelScope)
+ }
+
+ internal fun onIntent(intent: MainProfileIntent) = viewModelScope.launch {
+ intents.send(intent)
+ }
+
+ private suspend fun processIntent(intent: MainProfileIntent) {
+ when (intent) {
+ is MainProfileIntent.Navigate -> _sideEffects.send(MainProfileSideEffect.Navigate(intent.navigationEvent))
+ }
+ }
+
+ @AssistedFactory
+ interface Factory : AssistedViewModelFactory {
+ override fun create(state: MainProfileState): MainProfileViewModel
+ }
+
+ companion object :
+ MavericksViewModelFactory by hiltMavericksViewModelFactory()
+
+}
\ No newline at end of file
diff --git a/feature/profile/src/main/java/com/puzzle/profile/graph/main/contract/MainProfileIntent.kt b/feature/profile/src/main/java/com/puzzle/profile/graph/main/contract/MainProfileIntent.kt
new file mode 100644
index 00000000..ec881372
--- /dev/null
+++ b/feature/profile/src/main/java/com/puzzle/profile/graph/main/contract/MainProfileIntent.kt
@@ -0,0 +1,7 @@
+package com.puzzle.profile.graph.main.contract
+
+import com.puzzle.navigation.NavigationEvent
+
+sealed class MainProfileIntent {
+ data class Navigate(val navigationEvent: NavigationEvent) : MainProfileIntent()
+}
\ No newline at end of file
diff --git a/feature/profile/src/main/java/com/puzzle/profile/graph/main/contract/MainProfileSideEffect.kt b/feature/profile/src/main/java/com/puzzle/profile/graph/main/contract/MainProfileSideEffect.kt
new file mode 100644
index 00000000..8f40711a
--- /dev/null
+++ b/feature/profile/src/main/java/com/puzzle/profile/graph/main/contract/MainProfileSideEffect.kt
@@ -0,0 +1,7 @@
+package com.puzzle.profile.graph.main.contract
+
+import com.puzzle.navigation.NavigationEvent
+
+sealed class MainProfileSideEffect {
+ data class Navigate(val navigationEvent: NavigationEvent) : MainProfileSideEffect()
+}
diff --git a/feature/profile/src/main/java/com/puzzle/profile/graph/main/contract/MainProfileState.kt b/feature/profile/src/main/java/com/puzzle/profile/graph/main/contract/MainProfileState.kt
new file mode 100644
index 00000000..3da8faa3
--- /dev/null
+++ b/feature/profile/src/main/java/com/puzzle/profile/graph/main/contract/MainProfileState.kt
@@ -0,0 +1,15 @@
+package com.puzzle.profile.graph.main.contract
+
+import com.airbnb.mvrx.MavericksState
+
+data class MainProfileState(
+ val selfDescription: String = "음악과 요리를 좋아하는",
+ val nickName: String = "수줍은 수달",
+ val age: String = "25",
+ val birthYear: String = "00",
+ val height: String = "180",
+ val weight: String = "72",
+ val activityRegion: String = "서울특별시",
+ val occupation: String = "프리랜서",
+ val smokeStatue: String = "비흡연",
+) : MavericksState
\ No newline at end of file
diff --git a/feature/profile/src/main/java/com/puzzle/profile/navigation/ProfileNavigation.kt b/feature/profile/src/main/java/com/puzzle/profile/navigation/ProfileNavigation.kt
index 9786da34..74122b73 100644
--- a/feature/profile/src/main/java/com/puzzle/profile/navigation/ProfileNavigation.kt
+++ b/feature/profile/src/main/java/com/puzzle/profile/navigation/ProfileNavigation.kt
@@ -5,13 +5,13 @@ import androidx.navigation.compose.composable
import androidx.navigation.navigation
import com.puzzle.navigation.ProfileGraph
import com.puzzle.navigation.ProfileGraphDest
-import com.puzzle.profile.graph.home.ProfileRoute
+import com.puzzle.profile.graph.main.MainProfileRoute
import com.puzzle.profile.graph.register.RegisterProfileRoute
fun NavGraphBuilder.profileNavGraph() {
navigation(startDestination = ProfileGraphDest.ProfileRoute) {
composable {
- ProfileRoute()
+ MainProfileRoute()
}
composable {
diff --git a/feature/setting/src/main/java/com/puzzle/setting/graph/main/SettingScreen.kt b/feature/setting/src/main/java/com/puzzle/setting/graph/main/SettingScreen.kt
index b5ee10a2..a3868c22 100644
--- a/feature/setting/src/main/java/com/puzzle/setting/graph/main/SettingScreen.kt
+++ b/feature/setting/src/main/java/com/puzzle/setting/graph/main/SettingScreen.kt
@@ -75,7 +75,7 @@ private fun SettingScreen(
) {
PieceMainTopBar(
title = stringResource(R.string.setting_screen),
- modifier = Modifier.padding(horizontal = 20.dp),
+ modifier = Modifier.padding(horizontal = 20.dp, vertical = 19.dp),
)
HorizontalDivider(
diff --git a/presentation/src/main/java/com/puzzle/presentation/di/ViewModelsModule.kt b/presentation/src/main/java/com/puzzle/presentation/di/ViewModelsModule.kt
index ef265705..1d0d7cf1 100644
--- a/presentation/src/main/java/com/puzzle/presentation/di/ViewModelsModule.kt
+++ b/presentation/src/main/java/com/puzzle/presentation/di/ViewModelsModule.kt
@@ -8,6 +8,7 @@ import com.puzzle.auth.graph.signup.SignUpViewModel
import com.puzzle.auth.graph.verification.VerificationViewModel
import com.puzzle.matching.graph.detail.MatchingDetailViewModel
import com.puzzle.matching.graph.main.MatchingViewModel
+import com.puzzle.profile.graph.main.MainProfileViewModel
import com.puzzle.profile.graph.register.RegisterProfileViewModel
import com.puzzle.setting.graph.main.SettingViewModel
import com.puzzle.setting.graph.withdraw.WithdrawViewModel
@@ -50,6 +51,11 @@ interface ViewModelsModule {
@ViewModelKey(RegisterProfileViewModel::class)
fun registerProfileViewModelFactory(factory: RegisterProfileViewModel.Factory): AssistedViewModelFactory<*, *>
+ @Binds
+ @IntoMap
+ @ViewModelKey(MainProfileViewModel::class)
+ fun mainProfileViewModelFactory(factory: MainProfileViewModel.Factory): AssistedViewModelFactory<*, *>
+
@Binds
@IntoMap
@ViewModelKey(SettingViewModel::class)