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을