diff --git a/core/designsystem/src/main/res/values/strings.xml b/core/designsystem/src/main/res/values/strings.xml
index e1025876..dede9b1f 100644
--- a/core/designsystem/src/main/res/values/strings.xml
+++ b/core/designsystem/src/main/res/values/strings.xml
@@ -6,7 +6,6 @@
%d월
%d일
원
- %s원
검색 아이콘
뒤로가기 아이콘
로고 이미지
diff --git a/core/ui/src/main/res/values/strings.xml b/core/ui/src/main/res/values/strings.xml
index a1bd3ed6..18c08d76 100644
--- a/core/ui/src/main/res/values/strings.xml
+++ b/core/ui/src/main/res/values/strings.xml
@@ -28,4 +28,5 @@
다음
완료
필터 적용하기
+ %s원
diff --git a/feature/navigator/src/main/java/com/susu/feature/navigator/MainNavigator.kt b/feature/navigator/src/main/java/com/susu/feature/navigator/MainNavigator.kt
index e31da1ce..7f231205 100644
--- a/feature/navigator/src/main/java/com/susu/feature/navigator/MainNavigator.kt
+++ b/feature/navigator/src/main/java/com/susu/feature/navigator/MainNavigator.kt
@@ -14,6 +14,7 @@ import com.susu.feature.community.navigation.navigateCommunity
import com.susu.feature.loginsignup.navigation.LoginSignupRoute
import com.susu.feature.mypage.navigation.navigateMyPage
import com.susu.feature.received.navigation.ReceivedRoute
+import com.susu.feature.received.navigation.navigateEnvelopeAdd
import com.susu.feature.received.navigation.navigateLedgerAdd
import com.susu.feature.received.navigation.navigateLedgerDetail
import com.susu.feature.received.navigation.navigateLedgerEdit
@@ -134,6 +135,10 @@ internal class MainNavigator(
navController.navigateLedgerAdd()
}
+ fun navigateEnvelopeAdd() {
+ navController.navigateEnvelopeAdd()
+ }
+
fun popBackStackIfNotHome() {
if (!isSameCurrentDestination(SentRoute.route)) {
navController.popBackStack()
diff --git a/feature/navigator/src/main/java/com/susu/feature/navigator/MainScreen.kt b/feature/navigator/src/main/java/com/susu/feature/navigator/MainScreen.kt
index 41f7dbfb..3fd4985f 100644
--- a/feature/navigator/src/main/java/com/susu/feature/navigator/MainScreen.kt
+++ b/feature/navigator/src/main/java/com/susu/feature/navigator/MainScreen.kt
@@ -107,6 +107,7 @@ internal fun MainScreen(
navigateLedgerEdit = navigator::navigateLedgerEdit,
navigateLedgerFilter = navigator::navigateLedgerFilter,
navigateLedgerAdd = navigator::navigateLedgerAdd,
+ navigateEnvelopAdd = navigator::navigateEnvelopeAdd,
onShowSnackbar = viewModel::onShowSnackbar,
onShowDialog = viewModel::onShowDialog,
handleException = viewModel::handleException,
diff --git a/feature/received/src/main/java/com/susu/feature/received/envelopeadd/ReceivedEnvelopeAddScreen.kt b/feature/received/src/main/java/com/susu/feature/received/envelopeadd/ReceivedEnvelopeAddScreen.kt
new file mode 100644
index 00000000..865a75dc
--- /dev/null
+++ b/feature/received/src/main/java/com/susu/feature/received/envelopeadd/ReceivedEnvelopeAddScreen.kt
@@ -0,0 +1,141 @@
+package com.susu.feature.received.envelopeadd
+
+import androidx.compose.animation.AnimatedContent
+import androidx.compose.foundation.background
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.imePadding
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
+import androidx.compose.runtime.setValue
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.RectangleShape
+import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.tooling.preview.Preview
+import com.susu.core.designsystem.component.appbar.SusuProgressAppBar
+import com.susu.core.designsystem.component.appbar.icon.BackIcon
+import com.susu.core.designsystem.component.button.FilledButtonColor
+import com.susu.core.designsystem.component.button.MediumButtonStyle
+import com.susu.core.designsystem.component.button.SusuFilledButton
+import com.susu.core.designsystem.theme.SusuTheme
+import com.susu.core.ui.extension.susuDefaultAnimatedContentTransitionSpec
+import com.susu.feature.received.R
+import com.susu.feature.received.envelopeadd.content.MemoContent
+import com.susu.feature.received.envelopeadd.content.MoneyContent
+import com.susu.feature.received.envelopeadd.content.MoreContent
+import com.susu.feature.received.envelopeadd.content.NameContent
+import com.susu.feature.received.envelopeadd.content.PhoneContent
+import com.susu.feature.received.envelopeadd.content.PresentContent
+import com.susu.feature.received.envelopeadd.content.RelationshipContent
+import com.susu.feature.received.envelopeadd.content.VisitedContent
+
+enum class EnvelopeAddStep {
+ MONEY,
+ NAME,
+ RELATIONSHIP,
+ MORE,
+ VISITED,
+ PRESENT,
+ PHONE,
+ MEMO,
+}
+
+@Composable
+fun ReceivedEnvelopeAddRoute(
+ popBackStack: () -> Unit,
+) {
+ var currentStep by remember { mutableStateOf(EnvelopeAddStep.MONEY) }
+
+ ReceivedEnvelopeAddScreen(
+ currentStep = currentStep,
+ onClickBack = popBackStack,
+ onClickNext = {
+ // TODO: 수정 필요 (MORE 이후 분리 필요)
+ currentStep = when (currentStep) {
+ EnvelopeAddStep.MONEY -> EnvelopeAddStep.NAME
+ EnvelopeAddStep.NAME -> EnvelopeAddStep.RELATIONSHIP
+ EnvelopeAddStep.RELATIONSHIP -> EnvelopeAddStep.MORE
+ EnvelopeAddStep.MORE -> EnvelopeAddStep.VISITED
+ EnvelopeAddStep.VISITED -> EnvelopeAddStep.PRESENT
+ EnvelopeAddStep.PRESENT -> EnvelopeAddStep.PHONE
+ EnvelopeAddStep.PHONE -> EnvelopeAddStep.MEMO
+ else -> EnvelopeAddStep.MEMO
+ }
+ },
+ )
+}
+
+@Composable
+fun ReceivedEnvelopeAddScreen(
+ modifier: Modifier = Modifier,
+ currentStep: EnvelopeAddStep = EnvelopeAddStep.MONEY,
+ onClickBack: () -> Unit = {},
+ onClickNext: () -> Unit = {},
+) {
+ // TODO: 수정 필요
+ val relationshipList = listOf("친구", "가족", "친척", "동료", "직접 입력")
+ val friendList = listOf("김철수", "국영수", "신짱구", "홍길동")
+ val moreList = listOf("방문여부", "선물", "메모", "보낸 이의 연락처")
+ val visitedList = listOf("예", "아니요")
+
+ Column(
+ modifier = modifier
+ .background(SusuTheme.colorScheme.background15)
+ .fillMaxSize(),
+ ) {
+ SusuProgressAppBar(
+ leftIcon = {
+ BackIcon(
+ onClick = onClickBack,
+ )
+ },
+ currentStep = currentStep.ordinal + 1,
+ entireStep = EnvelopeAddStep.entries.size,
+ )
+ AnimatedContent(
+ modifier = modifier.weight(1f),
+ targetState = currentStep,
+ label = "SentEnvelopeAddScreen",
+ transitionSpec = {
+ susuDefaultAnimatedContentTransitionSpec(
+ leftDirectionCondition = targetState.ordinal > initialState.ordinal,
+ )
+ },
+ ) { targetState ->
+ when (targetState) {
+ EnvelopeAddStep.MONEY -> MoneyContent()
+ EnvelopeAddStep.NAME -> NameContent(friendList = friendList)
+ EnvelopeAddStep.RELATIONSHIP -> RelationshipContent(relationshipList = relationshipList)
+ EnvelopeAddStep.MORE -> MoreContent(moreList = moreList)
+ EnvelopeAddStep.VISITED -> VisitedContent(
+ event = "결혼식",
+ visitedList = visitedList,
+ )
+ EnvelopeAddStep.PRESENT -> PresentContent()
+ EnvelopeAddStep.PHONE -> PhoneContent(name = "김철수")
+ EnvelopeAddStep.MEMO -> MemoContent()
+ }
+ }
+ SusuFilledButton(
+ color = FilledButtonColor.Black,
+ style = MediumButtonStyle.height60,
+ shape = RectangleShape,
+ text = stringResource(id = com.susu.core.ui.R.string.word_next),
+ onClick = onClickNext,
+ modifier = modifier
+ .fillMaxWidth()
+ .imePadding(),
+ )
+ }
+}
+
+@Preview
+@Composable
+fun ReceivedEnvelopeAddScreenPreview() {
+ SusuTheme {
+ ReceivedEnvelopeAddScreen()
+ }
+}
diff --git a/feature/received/src/main/java/com/susu/feature/received/envelopeadd/content/MemoContent.kt b/feature/received/src/main/java/com/susu/feature/received/envelopeadd/content/MemoContent.kt
new file mode 100644
index 00000000..a64a3c4c
--- /dev/null
+++ b/feature/received/src/main/java/com/susu/feature/received/envelopeadd/content/MemoContent.kt
@@ -0,0 +1,66 @@
+package com.susu.feature.received.envelopeadd.content
+
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.PaddingValues
+import androidx.compose.foundation.layout.Spacer
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.size
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
+import androidx.compose.runtime.setValue
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.tooling.preview.Preview
+import com.susu.core.designsystem.component.textfield.SusuBasicTextField
+import com.susu.core.designsystem.theme.Gray100
+import com.susu.core.designsystem.theme.Gray40
+import com.susu.core.designsystem.theme.SusuTheme
+import com.susu.feature.received.R
+
+@Composable
+fun MemoContent(
+ modifier: Modifier = Modifier,
+ padding: PaddingValues = PaddingValues(
+ horizontal = SusuTheme.spacing.spacing_m,
+ vertical = SusuTheme.spacing.spacing_xl,
+ ),
+) {
+ var memo by remember { mutableStateOf("") }
+
+ Column(
+ modifier = modifier
+ .fillMaxSize()
+ .padding(padding),
+ ) {
+ Text(
+ text = stringResource(R.string.memo_content_title),
+ style = SusuTheme.typography.title_m,
+ color = Gray100,
+ )
+ Spacer(
+ modifier = modifier
+ .size(SusuTheme.spacing.spacing_m),
+ )
+ SusuBasicTextField(
+ text = memo,
+ onTextChange = { memo = it },
+ placeholder = stringResource(R.string.memo_content_placeholder),
+ placeholderColor = Gray40,
+ modifier = modifier.fillMaxWidth(),
+ )
+ Spacer(modifier = modifier.size(SusuTheme.spacing.spacing_xl))
+ }
+}
+
+@Preview(showBackground = true, backgroundColor = 0xFFF6F6F6)
+@Composable
+fun MemoContentPreview() {
+ SusuTheme {
+ MemoContent()
+ }
+}
diff --git a/feature/received/src/main/java/com/susu/feature/received/envelopeadd/content/MoneyContent.kt b/feature/received/src/main/java/com/susu/feature/received/envelopeadd/content/MoneyContent.kt
new file mode 100644
index 00000000..9637b13b
--- /dev/null
+++ b/feature/received/src/main/java/com/susu/feature/received/envelopeadd/content/MoneyContent.kt
@@ -0,0 +1,95 @@
+package com.susu.feature.received.envelopeadd.content
+
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.ExperimentalLayoutApi
+import androidx.compose.foundation.layout.FlowRow
+import androidx.compose.foundation.layout.PaddingValues
+import androidx.compose.foundation.layout.Spacer
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.size
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
+import androidx.compose.runtime.setValue
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.tooling.preview.Preview
+import com.susu.core.designsystem.component.button.FilledButtonColor
+import com.susu.core.designsystem.component.button.SmallButtonStyle
+import com.susu.core.designsystem.component.button.SusuFilledButton
+import com.susu.core.designsystem.component.textfield.SusuPriceTextField
+import com.susu.core.designsystem.theme.Gray100
+import com.susu.core.designsystem.theme.SusuTheme
+import com.susu.core.ui.extension.toMoneyFormat
+import com.susu.feature.received.R
+
+@OptIn(ExperimentalLayoutApi::class)
+@Composable
+fun MoneyContent(
+ modifier: Modifier = Modifier,
+ padding: PaddingValues = PaddingValues(
+ horizontal = SusuTheme.spacing.spacing_m,
+ vertical = SusuTheme.spacing.spacing_xl,
+ ),
+) {
+ val moneyList = listOf(
+ 10000,
+ 30000,
+ 50000,
+ 100000,
+ 500000,
+ )
+ var clickedMoney by remember { mutableStateOf("") }
+
+ Column(
+ modifier = modifier
+ .fillMaxSize()
+ .padding(padding),
+ ) {
+ Text(
+ text = stringResource(R.string.money_content_title),
+ style = SusuTheme.typography.title_m,
+ color = Gray100,
+ )
+ Spacer(
+ modifier = modifier
+ .size(SusuTheme.spacing.spacing_m),
+ )
+ SusuPriceTextField(
+ text = clickedMoney,
+ onTextChange = { clickedMoney = it },
+ placeholder = stringResource(R.string.money_content_placeholder),
+ )
+ Spacer(
+ modifier = modifier
+ .size(SusuTheme.spacing.spacing_xxl),
+ )
+ FlowRow(
+ horizontalArrangement = Arrangement.spacedBy(SusuTheme.spacing.spacing_xxs),
+ verticalArrangement = Arrangement.spacedBy(SusuTheme.spacing.spacing_xxs),
+ ) {
+ for (money in moneyList) {
+ SusuFilledButton(
+ color = FilledButtonColor.Orange,
+ style = SmallButtonStyle.height32,
+ text = stringResource(id = com.susu.core.ui.R.string.money_unit_format, money.toMoneyFormat()),
+ onClick = {
+ clickedMoney = money.toString()
+ },
+ )
+ }
+ }
+ }
+}
+
+@Preview(showBackground = true, backgroundColor = 0xFFF6F6F6)
+@Composable
+fun MoneyContentPreview() {
+ SusuTheme {
+ MoneyContent()
+ }
+}
diff --git a/feature/received/src/main/java/com/susu/feature/received/envelopeadd/content/MoreContent.kt b/feature/received/src/main/java/com/susu/feature/received/envelopeadd/content/MoreContent.kt
new file mode 100644
index 00000000..92cbddc0
--- /dev/null
+++ b/feature/received/src/main/java/com/susu/feature/received/envelopeadd/content/MoreContent.kt
@@ -0,0 +1,106 @@
+package com.susu.feature.received.envelopeadd.content
+
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.PaddingValues
+import androidx.compose.foundation.layout.Spacer
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.size
+import androidx.compose.foundation.rememberScrollState
+import androidx.compose.foundation.verticalScroll
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
+import androidx.compose.runtime.setValue
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.tooling.preview.Preview
+import com.susu.core.designsystem.component.button.FilledButtonColor
+import com.susu.core.designsystem.component.button.GhostButtonColor
+import com.susu.core.designsystem.component.button.MediumButtonStyle
+import com.susu.core.designsystem.component.button.SusuFilledButton
+import com.susu.core.designsystem.component.button.SusuGhostButton
+import com.susu.core.designsystem.theme.Gray100
+import com.susu.core.designsystem.theme.Gray70
+import com.susu.core.designsystem.theme.SusuTheme
+import com.susu.feature.received.R
+
+@Composable
+fun MoreContent(
+ modifier: Modifier = Modifier,
+ padding: PaddingValues = PaddingValues(
+ horizontal = SusuTheme.spacing.spacing_m,
+ vertical = SusuTheme.spacing.spacing_xl,
+ ),
+ moreList: List,
+) {
+ val scrollState = rememberScrollState()
+ var selectedItem by remember { mutableStateOf(-1) }
+
+ Column(
+ modifier = modifier
+ .fillMaxSize()
+ .padding(padding)
+ .verticalScroll(scrollState),
+ ) {
+ Text(
+ text = stringResource(R.string.more_content_title),
+ style = SusuTheme.typography.title_m,
+ color = Gray100,
+ )
+ Spacer(
+ modifier = modifier
+ .size(SusuTheme.spacing.spacing_xxxxs),
+ )
+ Text(
+ text = stringResource(R.string.more_content_description),
+ style = SusuTheme.typography.text_xs,
+ color = Gray70,
+ )
+ Spacer(
+ modifier = modifier
+ .size(SusuTheme.spacing.spacing_xxl),
+ )
+ Column(
+ verticalArrangement = Arrangement.spacedBy(SusuTheme.spacing.spacing_xxs),
+ ) {
+ moreList.forEachIndexed { index, category ->
+ if (selectedItem == index) {
+ SusuFilledButton(
+ color = FilledButtonColor.Orange,
+ style = MediumButtonStyle.height60,
+ text = category,
+ onClick = {
+ selectedItem = index
+ },
+ modifier = modifier.fillMaxWidth(),
+ )
+ } else {
+ SusuGhostButton(
+ color = GhostButtonColor.Black,
+ style = MediumButtonStyle.height60,
+ text = category,
+ onClick = {
+ selectedItem = index
+ },
+ modifier = modifier.fillMaxWidth(),
+ )
+ }
+ }
+ }
+ }
+}
+
+@Preview(showBackground = true, backgroundColor = 0xFFF6F6F6)
+@Composable
+fun MoreContentPreview() {
+ val moreList = mutableListOf("방문여부", "선물", "메모", "보낸 이의 연락처")
+
+ SusuTheme {
+ MoreContent(moreList = moreList)
+ }
+}
diff --git a/feature/received/src/main/java/com/susu/feature/received/envelopeadd/content/NameContent.kt b/feature/received/src/main/java/com/susu/feature/received/envelopeadd/content/NameContent.kt
new file mode 100644
index 00000000..970f876d
--- /dev/null
+++ b/feature/received/src/main/java/com/susu/feature/received/envelopeadd/content/NameContent.kt
@@ -0,0 +1,81 @@
+package com.susu.feature.received.envelopeadd.content
+
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.PaddingValues
+import androidx.compose.foundation.layout.Spacer
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.size
+import androidx.compose.foundation.lazy.LazyColumn
+import androidx.compose.foundation.lazy.items
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
+import androidx.compose.runtime.setValue
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.tooling.preview.Preview
+import com.susu.core.designsystem.component.textfield.SusuBasicTextField
+import com.susu.core.designsystem.theme.Gray100
+import com.susu.core.designsystem.theme.Gray40
+import com.susu.core.designsystem.theme.SusuTheme
+import com.susu.feature.received.R
+import com.susu.feature.received.envelopeadd.content.component.FriendListItem
+
+@Composable
+fun NameContent(
+ modifier: Modifier = Modifier,
+ padding: PaddingValues = PaddingValues(
+ horizontal = SusuTheme.spacing.spacing_m,
+ vertical = SusuTheme.spacing.spacing_xl,
+ ),
+ friendList: List = emptyList(),
+) {
+ var name by remember { mutableStateOf("") }
+
+ Column(
+ modifier = modifier
+ .fillMaxSize()
+ .padding(padding),
+ ) {
+ Text(
+ text = stringResource(R.string.name_content_title),
+ style = SusuTheme.typography.title_m,
+ color = Gray100,
+ )
+ Spacer(
+ modifier = modifier
+ .size(SusuTheme.spacing.spacing_m),
+ )
+ SusuBasicTextField(
+ text = name,
+ onTextChange = { name = it },
+ placeholder = stringResource(R.string.name_content_placeholder),
+ placeholderColor = Gray40,
+ modifier = modifier.fillMaxWidth(),
+ )
+ Spacer(modifier = modifier.size(SusuTheme.spacing.spacing_xl))
+
+ if (friendList.isNotEmpty()) {
+ // TODO: 친구 목록 서버 연동
+ LazyColumn {
+ items(friendList) { friend ->
+ FriendListItem(friend)
+ }
+ }
+ }
+ }
+}
+
+@Preview(showBackground = true, backgroundColor = 0xFFF6F6F6)
+@Composable
+fun NameContentPreview() {
+ SusuTheme {
+ val friendList = listOf("김철수", "국영수", "가나다")
+
+ NameContent(friendList = friendList)
+ }
+}
diff --git a/feature/received/src/main/java/com/susu/feature/received/envelopeadd/content/PhoneContent.kt b/feature/received/src/main/java/com/susu/feature/received/envelopeadd/content/PhoneContent.kt
new file mode 100644
index 00000000..191d349d
--- /dev/null
+++ b/feature/received/src/main/java/com/susu/feature/received/envelopeadd/content/PhoneContent.kt
@@ -0,0 +1,71 @@
+package com.susu.feature.received.envelopeadd.content
+
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.PaddingValues
+import androidx.compose.foundation.layout.Spacer
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.size
+import androidx.compose.foundation.text.KeyboardOptions
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
+import androidx.compose.runtime.setValue
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.text.input.KeyboardType
+import androidx.compose.ui.tooling.preview.Preview
+import com.susu.core.designsystem.component.textfield.SusuBasicTextField
+import com.susu.core.designsystem.theme.Gray40
+import com.susu.core.designsystem.theme.Gray60
+import com.susu.core.designsystem.theme.SusuTheme
+import com.susu.core.ui.util.AnnotatedText
+import com.susu.feature.received.R
+
+@Composable
+fun PhoneContent(
+ modifier: Modifier = Modifier,
+ padding: PaddingValues = PaddingValues(
+ horizontal = SusuTheme.spacing.spacing_m,
+ vertical = SusuTheme.spacing.spacing_xl,
+ ),
+ name: String,
+) {
+ var phoneNumber by remember { mutableStateOf("") }
+
+ Column(
+ modifier = modifier
+ .fillMaxSize()
+ .padding(padding),
+ ) {
+ AnnotatedText(
+ originalText = stringResource(R.string.phone_content_title, name),
+ originalTextStyle = SusuTheme.typography.title_m,
+ targetTextList = listOf(stringResource(R.string.phone_content_title_highlight, name)),
+ spanStyle = SusuTheme.typography.title_m.copy(Gray60).toSpanStyle(),
+ )
+ Spacer(
+ modifier = modifier
+ .size(SusuTheme.spacing.spacing_m),
+ )
+ SusuBasicTextField(
+ text = phoneNumber,
+ onTextChange = { phoneNumber = it },
+ placeholder = stringResource(R.string.phone_content_placeholder),
+ placeholderColor = Gray40,
+ modifier = modifier.fillMaxWidth(),
+ keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number),
+ )
+ Spacer(modifier = modifier.size(SusuTheme.spacing.spacing_xl))
+ }
+}
+
+@Preview(showBackground = true, backgroundColor = 0xFFF6F6F6)
+@Composable
+fun PhoneContentPreview() {
+ SusuTheme {
+ PhoneContent(name = "김철수")
+ }
+}
diff --git a/feature/received/src/main/java/com/susu/feature/received/envelopeadd/content/PresentContent.kt b/feature/received/src/main/java/com/susu/feature/received/envelopeadd/content/PresentContent.kt
new file mode 100644
index 00000000..b18e7cf3
--- /dev/null
+++ b/feature/received/src/main/java/com/susu/feature/received/envelopeadd/content/PresentContent.kt
@@ -0,0 +1,66 @@
+package com.susu.feature.received.envelopeadd.content
+
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.PaddingValues
+import androidx.compose.foundation.layout.Spacer
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.size
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
+import androidx.compose.runtime.setValue
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.tooling.preview.Preview
+import com.susu.core.designsystem.component.textfield.SusuBasicTextField
+import com.susu.core.designsystem.theme.Gray100
+import com.susu.core.designsystem.theme.Gray40
+import com.susu.core.designsystem.theme.SusuTheme
+import com.susu.feature.received.R
+
+@Composable
+fun PresentContent(
+ modifier: Modifier = Modifier,
+ padding: PaddingValues = PaddingValues(
+ horizontal = SusuTheme.spacing.spacing_m,
+ vertical = SusuTheme.spacing.spacing_xl,
+ ),
+) {
+ var sentPresent by remember { mutableStateOf("") }
+
+ Column(
+ modifier = modifier
+ .fillMaxSize()
+ .padding(padding),
+ ) {
+ Text(
+ text = stringResource(R.string.present_content_title),
+ style = SusuTheme.typography.title_m,
+ color = Gray100,
+ )
+ Spacer(
+ modifier = modifier
+ .size(SusuTheme.spacing.spacing_m),
+ )
+ SusuBasicTextField(
+ text = sentPresent,
+ onTextChange = { sentPresent = it },
+ placeholder = stringResource(R.string.present_content_placeholder),
+ placeholderColor = Gray40,
+ modifier = modifier.fillMaxWidth(),
+ )
+ Spacer(modifier = modifier.size(SusuTheme.spacing.spacing_xl))
+ }
+}
+
+@Preview(showBackground = true, backgroundColor = 0xFFF6F6F6)
+@Composable
+fun PresentContentPreview() {
+ SusuTheme {
+ PresentContent()
+ }
+}
diff --git a/feature/received/src/main/java/com/susu/feature/received/envelopeadd/content/RelationshipContent.kt b/feature/received/src/main/java/com/susu/feature/received/envelopeadd/content/RelationshipContent.kt
new file mode 100644
index 00000000..3bea7a52
--- /dev/null
+++ b/feature/received/src/main/java/com/susu/feature/received/envelopeadd/content/RelationshipContent.kt
@@ -0,0 +1,96 @@
+package com.susu.feature.received.envelopeadd.content
+
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.PaddingValues
+import androidx.compose.foundation.layout.Spacer
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.size
+import androidx.compose.foundation.rememberScrollState
+import androidx.compose.foundation.verticalScroll
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
+import androidx.compose.runtime.setValue
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.tooling.preview.Preview
+import com.susu.core.designsystem.component.button.FilledButtonColor
+import com.susu.core.designsystem.component.button.GhostButtonColor
+import com.susu.core.designsystem.component.button.MediumButtonStyle
+import com.susu.core.designsystem.component.button.SusuFilledButton
+import com.susu.core.designsystem.component.button.SusuGhostButton
+import com.susu.core.designsystem.theme.Gray100
+import com.susu.core.designsystem.theme.SusuTheme
+import com.susu.feature.received.R
+
+@Composable
+fun RelationshipContent(
+ modifier: Modifier = Modifier,
+ padding: PaddingValues = PaddingValues(
+ horizontal = SusuTheme.spacing.spacing_m,
+ vertical = SusuTheme.spacing.spacing_xl,
+ ),
+ relationshipList: List,
+) {
+ val scrollState = rememberScrollState()
+ var selectedItem by remember { mutableStateOf(-1) }
+
+ Column(
+ modifier = modifier
+ .fillMaxSize()
+ .padding(padding)
+ .verticalScroll(scrollState),
+ ) {
+ Text(
+ text = stringResource(R.string.relationship_content_title),
+ style = SusuTheme.typography.title_m,
+ color = Gray100,
+ )
+ Spacer(
+ modifier = modifier
+ .size(SusuTheme.spacing.spacing_xxl),
+ )
+ Column(
+ verticalArrangement = Arrangement.spacedBy(SusuTheme.spacing.spacing_xxs),
+ ) {
+ relationshipList.forEachIndexed { index, relationship ->
+ if (selectedItem == index) {
+ SusuFilledButton(
+ color = FilledButtonColor.Orange,
+ style = MediumButtonStyle.height60,
+ text = relationship,
+ onClick = {
+ selectedItem = index
+ },
+ modifier = modifier.fillMaxWidth(),
+ )
+ } else {
+ SusuGhostButton(
+ color = GhostButtonColor.Black,
+ style = MediumButtonStyle.height60,
+ text = relationship,
+ onClick = {
+ selectedItem = index
+ },
+ modifier = modifier.fillMaxWidth(),
+ )
+ }
+ }
+ }
+ }
+}
+
+@Preview(showBackground = true, backgroundColor = 0xFFF6F6F6)
+@Composable
+fun RelationshipContentPreview() {
+ val relationshipList = mutableListOf("친구", "가족", "친척", "동료", "직접 입력")
+
+ SusuTheme {
+ RelationshipContent(relationshipList = relationshipList)
+ }
+}
diff --git a/feature/received/src/main/java/com/susu/feature/received/envelopeadd/content/VisitedContent.kt b/feature/received/src/main/java/com/susu/feature/received/envelopeadd/content/VisitedContent.kt
new file mode 100644
index 00000000..f5e7de51
--- /dev/null
+++ b/feature/received/src/main/java/com/susu/feature/received/envelopeadd/content/VisitedContent.kt
@@ -0,0 +1,97 @@
+package com.susu.feature.received.envelopeadd.content
+
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.PaddingValues
+import androidx.compose.foundation.layout.Spacer
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.size
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
+import androidx.compose.runtime.setValue
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.tooling.preview.Preview
+import com.susu.core.designsystem.component.button.FilledButtonColor
+import com.susu.core.designsystem.component.button.GhostButtonColor
+import com.susu.core.designsystem.component.button.MediumButtonStyle
+import com.susu.core.designsystem.component.button.SusuFilledButton
+import com.susu.core.designsystem.component.button.SusuGhostButton
+import com.susu.core.designsystem.theme.Gray60
+import com.susu.core.designsystem.theme.SusuTheme
+import com.susu.core.ui.util.AnnotatedText
+import com.susu.feature.received.R
+
+@Composable
+fun VisitedContent(
+ modifier: Modifier = Modifier,
+ padding: PaddingValues = PaddingValues(
+ horizontal = SusuTheme.spacing.spacing_m,
+ vertical = SusuTheme.spacing.spacing_xl,
+ ),
+ event: String,
+ visitedList: List,
+) {
+ var selectedItem by remember { mutableStateOf(-1) }
+
+ Column(
+ modifier = modifier
+ .fillMaxSize()
+ .padding(padding),
+ ) {
+ AnnotatedText(
+ originalText = stringResource(R.string.visited_content_title, event),
+ originalTextStyle = SusuTheme.typography.title_m,
+ targetTextList = listOf(stringResource(R.string.visited_content_title_highlight, event)),
+ spanStyle = SusuTheme.typography.title_m.copy(Gray60).toSpanStyle(),
+ )
+ Spacer(
+ modifier = modifier
+ .size(SusuTheme.spacing.spacing_xxl),
+ )
+ Column(
+ verticalArrangement = Arrangement.spacedBy(SusuTheme.spacing.spacing_xxs),
+ ) {
+ visitedList.forEachIndexed { index, answer ->
+ if (selectedItem == index) {
+ SusuFilledButton(
+ color = FilledButtonColor.Orange,
+ style = MediumButtonStyle.height60,
+ text = answer,
+ onClick = {
+ selectedItem = index
+ },
+ modifier = modifier.fillMaxWidth(),
+ )
+ } else {
+ SusuGhostButton(
+ color = GhostButtonColor.Black,
+ style = MediumButtonStyle.height60,
+ text = answer,
+ onClick = {
+ selectedItem = index
+ },
+ modifier = modifier.fillMaxWidth(),
+ )
+ }
+ }
+ }
+ }
+}
+
+@Preview(showBackground = true, backgroundColor = 0xFFF6F6F6)
+@Composable
+fun VisitedContentPreview() {
+ val visitedList = mutableListOf("예", "아니요")
+
+ SusuTheme {
+ VisitedContent(
+ event = "결혼식",
+ visitedList = visitedList,
+ )
+ }
+}
diff --git a/feature/received/src/main/java/com/susu/feature/received/envelopeadd/content/component/FriendListItem.kt b/feature/received/src/main/java/com/susu/feature/received/envelopeadd/content/component/FriendListItem.kt
new file mode 100644
index 00000000..759a3213
--- /dev/null
+++ b/feature/received/src/main/java/com/susu/feature/received/envelopeadd/content/component/FriendListItem.kt
@@ -0,0 +1,67 @@
+package com.susu.feature.received.envelopeadd.content.component
+
+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.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.tooling.preview.Preview
+import com.susu.core.designsystem.theme.Gray100
+import com.susu.core.designsystem.theme.Gray40
+import com.susu.core.designsystem.theme.Gray60
+import com.susu.core.designsystem.theme.SusuTheme
+
+@Composable
+fun FriendListItem(
+ friend: String,
+ modifier: Modifier = Modifier,
+) {
+ Row(
+ modifier = modifier
+ .fillMaxWidth()
+ .padding(
+ vertical = SusuTheme.spacing.spacing_s,
+ ),
+ horizontalArrangement = Arrangement.spacedBy(SusuTheme.spacing.spacing_xxs),
+ verticalAlignment = Alignment.CenterVertically,
+ ) {
+ Text(
+ text = friend,
+ style = SusuTheme.typography.title_xs,
+ color = Gray100,
+ )
+ Text(
+ text = "친구",
+ style = SusuTheme.typography.title_xs,
+ color = Gray60,
+ )
+ Text(
+ text = "결혼식",
+ style = SusuTheme.typography.text_xs,
+ color = Gray40,
+ )
+ Text(
+ text = "2022.01.11",
+ style = SusuTheme.typography.text_xs,
+ color = Gray40,
+ )
+ }
+}
+
+@Preview(showBackground = true, backgroundColor = 0xFFF6F6F6)
+@Composable
+fun FriendListItemPreview() {
+ val friendList = listOf("김철수", "국영수", "가나다")
+
+ SusuTheme {
+ Column {
+ for (friend in friendList) {
+ FriendListItem(friend = friend)
+ }
+ }
+ }
+}
diff --git a/feature/received/src/main/java/com/susu/feature/received/ledgerdetail/LedgerDetailContract.kt b/feature/received/src/main/java/com/susu/feature/received/ledgerdetail/LedgerDetailContract.kt
index 744f7af1..0b07876d 100644
--- a/feature/received/src/main/java/com/susu/feature/received/ledgerdetail/LedgerDetailContract.kt
+++ b/feature/received/src/main/java/com/susu/feature/received/ledgerdetail/LedgerDetailContract.kt
@@ -14,6 +14,7 @@ data class LedgerDetailState(
) : UiState
sealed interface LedgerDetailSideEffect : SideEffect {
+ data object NavigateEnvelopeAdd : LedgerDetailSideEffect
data class NavigateLedgerEdit(val ledger: Ledger) : LedgerDetailSideEffect
data class PopBackStackWithLedger(val ledger: String) : LedgerDetailSideEffect
data class PopBackStackWithDeleteLedgerId(val ledgerId: Int) : LedgerDetailSideEffect
diff --git a/feature/received/src/main/java/com/susu/feature/received/ledgerdetail/LedgerDetailScreen.kt b/feature/received/src/main/java/com/susu/feature/received/ledgerdetail/LedgerDetailScreen.kt
index 87010765..526093f4 100644
--- a/feature/received/src/main/java/com/susu/feature/received/ledgerdetail/LedgerDetailScreen.kt
+++ b/feature/received/src/main/java/com/susu/feature/received/ledgerdetail/LedgerDetailScreen.kt
@@ -52,6 +52,7 @@ fun LedgerDetailRoute(
viewModel: LedgerDetailViewModel = hiltViewModel(),
ledger: String?,
navigateLedgerEdit: (Ledger) -> Unit,
+ navigateEnvelopAdd: () -> Unit,
popBackStackWithLedger: (String) -> Unit,
popBackStackWithDeleteLedgerId: (Int) -> Unit,
onShowSnackbar: (SnackbarToken) -> Unit,
@@ -87,6 +88,7 @@ fun LedgerDetailRoute(
is LedgerDetailSideEffect.PopBackStackWithDeleteLedgerId -> popBackStackWithDeleteLedgerId(sideEffect.ledgerId)
is LedgerDetailSideEffect.HandleException -> handleException(sideEffect.throwable, sideEffect.retry)
is LedgerDetailSideEffect.ShowSnackbar -> onShowSnackbar(SnackbarToken(message = sideEffect.msg))
+ LedgerDetailSideEffect.NavigateEnvelopeAdd -> navigateEnvelopAdd()
}
}
@@ -101,6 +103,7 @@ fun LedgerDetailRoute(
onClickEdit = viewModel::navigateLedgerEdit,
onClickDelete = viewModel::showDeleteDialog,
onClickBack = viewModel::popBackStackWithLedger,
+ onClickFloatingButton = viewModel::navigateEnvelopeAdd,
)
}
diff --git a/feature/received/src/main/java/com/susu/feature/received/ledgerdetail/LedgerDetailViewModel.kt b/feature/received/src/main/java/com/susu/feature/received/ledgerdetail/LedgerDetailViewModel.kt
index e6f2ab24..5b0a3893 100644
--- a/feature/received/src/main/java/com/susu/feature/received/ledgerdetail/LedgerDetailViewModel.kt
+++ b/feature/received/src/main/java/com/susu/feature/received/ledgerdetail/LedgerDetailViewModel.kt
@@ -80,4 +80,6 @@ class LedgerDetailViewModel @Inject constructor(
}
}
}
+
+ fun navigateEnvelopeAdd() = postSideEffect(LedgerDetailSideEffect.NavigateEnvelopeAdd)
}
diff --git a/feature/received/src/main/java/com/susu/feature/received/navigation/ReceivedNavigation.kt b/feature/received/src/main/java/com/susu/feature/received/navigation/ReceivedNavigation.kt
index 91efea55..38f82d76 100644
--- a/feature/received/src/main/java/com/susu/feature/received/navigation/ReceivedNavigation.kt
+++ b/feature/received/src/main/java/com/susu/feature/received/navigation/ReceivedNavigation.kt
@@ -11,6 +11,7 @@ import com.susu.core.model.Ledger
import com.susu.core.ui.DialogToken
import com.susu.core.ui.SnackbarToken
import com.susu.core.ui.extension.encodeToUri
+import com.susu.feature.received.envelopeadd.ReceivedEnvelopeAddRoute
import com.susu.feature.received.ledgeradd.LedgerAddRoute
import com.susu.feature.received.ledgerdetail.LedgerDetailRoute
import com.susu.feature.received.ledgeredit.LedgerEditRoute
@@ -43,6 +44,10 @@ fun NavController.navigateLedgerAdd() {
navigate(ReceivedRoute.ledgerAddRoute)
}
+fun NavController.navigateEnvelopeAdd() {
+ navigate(ReceivedRoute.envelopeAddRoute)
+}
+
fun NavGraphBuilder.receivedNavGraph(
padding: PaddingValues,
navigateLedgerDetail: (Ledger) -> Unit,
@@ -53,6 +58,7 @@ fun NavGraphBuilder.receivedNavGraph(
navigateLedgerEdit: (Ledger) -> Unit,
navigateLedgerFilter: () -> Unit,
navigateLedgerAdd: () -> Unit,
+ navigateEnvelopAdd: () -> Unit,
onShowSnackbar: (SnackbarToken) -> Unit,
onShowDialog: (DialogToken) -> Unit,
handleException: (Throwable, () -> Unit) -> Unit,
@@ -83,6 +89,7 @@ fun NavGraphBuilder.receivedNavGraph(
LedgerDetailRoute(
ledger = ledger,
navigateLedgerEdit = navigateLedgerEdit,
+ navigateEnvelopAdd = navigateEnvelopAdd,
popBackStackWithLedger = popBackStackWithLedger,
popBackStackWithDeleteLedgerId = popBackStackWithDeleteLedgerId,
onShowSnackbar = onShowSnackbar,
@@ -119,6 +126,14 @@ fun NavGraphBuilder.receivedNavGraph(
popBackStack = popBackStack,
)
}
+
+ composable(
+ route = ReceivedRoute.envelopeAddRoute,
+ ) {
+ ReceivedEnvelopeAddRoute(
+ popBackStack = popBackStack,
+ )
+ }
}
object ReceivedRoute {
@@ -131,4 +146,6 @@ object ReceivedRoute {
const val ledgerAddRoute = "ledger-add" // TODO 파라미터 넘기는 방식으로 수정해야함.
const val ledgerFilterRoute = "ledger-filter" // TODO 파라미터 넘기는 방식으로 수정해야함.
+
+ const val envelopeAddRoute = "envelope-add"
}
diff --git a/feature/received/src/main/res/values/strings.xml b/feature/received/src/main/res/values/strings.xml
index f9cee99c..88184dc8 100644
--- a/feature/received/src/main/res/values/strings.xml
+++ b/feature/received/src/main/res/values/strings.xml
@@ -28,4 +28,20 @@
장부를 삭제할까요?
삭제한 장부와 봉투는 다시 복구할 수 없어요
장부가 삭제되었어요
+ 추가로 남기실 내용이 있나요
+ 입력해주세요
+ 얼마를 받았나요
+ 금액을 입력해주세요
+ 더 기록할 내용이 있다면 알려주세요
+ 복수로 선택하셔도 좋아요
+ 누구에게 받았나요
+ 이름을 입력해주세요
+ 01012345678
+ %s님의 연락처를 남겨주세요
+ %s님의
+ 받은 선물을 알려주세요
+ 무엇을 선물받았나요
+ 나와는\n어떤 사이 인가요
+ %s을 방문했나요?
+ %s을