From 5f2ac69057d2b04aef18afd8e1793971cd9b9b75 Mon Sep 17 00:00:00 2001 From: Kim Nahyeon Date: Thu, 22 Jan 2026 23:52:29 +0900 Subject: [PATCH 1/8] =?UTF-8?q?[REF/#144]=20=ED=99=94=EB=A9=B4=20=EA=B8=B0?= =?UTF-8?q?=EA=B8=B0=EB=8C=80=EC=9D=91=20=EB=B9=84=EC=9C=A8=20=EC=A1=B0?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../android/presentation/calendar/CalendarScreen.kt | 6 ++++-- .../calendar/component/ProcedureScheduleCard.kt | 13 +++++++++---- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/com/cherrish/android/presentation/calendar/CalendarScreen.kt b/app/src/main/java/com/cherrish/android/presentation/calendar/CalendarScreen.kt index 39c77e90..844798e7 100644 --- a/app/src/main/java/com/cherrish/android/presentation/calendar/CalendarScreen.kt +++ b/app/src/main/java/com/cherrish/android/presentation/calendar/CalendarScreen.kt @@ -77,7 +77,7 @@ private fun CalendarScreen( .fillMaxSize() .background(color = CherrishTheme.colors.gray100) .padding(paddingValues) - .padding(top = 40.dp), + .padding(top = 40.dp, bottom = 10.dp), horizontalAlignment = Alignment.CenterHorizontally, verticalArrangement = Arrangement.spacedBy(20.dp) ) { @@ -95,7 +95,9 @@ private fun CalendarScreen( procedureInfo = uiState.procedureInfoList, onProcedureClick = onEventClick, onAddProcedureClick = onAddButtonClick, - modifier = Modifier.padding(horizontal = 17.dp) + modifier = Modifier + .padding(horizontal = 17.dp) + .weight(1f) ) } } diff --git a/app/src/main/java/com/cherrish/android/presentation/calendar/component/ProcedureScheduleCard.kt b/app/src/main/java/com/cherrish/android/presentation/calendar/component/ProcedureScheduleCard.kt index e14d9766..8ed0a9e2 100644 --- a/app/src/main/java/com/cherrish/android/presentation/calendar/component/ProcedureScheduleCard.kt +++ b/app/src/main/java/com/cherrish/android/presentation/calendar/component/ProcedureScheduleCard.kt @@ -70,8 +70,7 @@ fun ProcedureScheduleCard( EmptyCardView( modifier = Modifier .fillMaxWidth() - .padding(horizontal = 24.dp) - .padding(top = 50.dp, bottom = 24.dp), + .padding(horizontal = 24.dp), onClick = onAddProcedureClick ) } else { @@ -99,7 +98,8 @@ fun ProcedureScheduleCard( LazyColumn( state = listState, - verticalArrangement = Arrangement.spacedBy(8.dp) + verticalArrangement = Arrangement.spacedBy(8.dp), + modifier = Modifier.weight(1f) ) { items( items = procedureInfo, @@ -252,11 +252,14 @@ private fun EmptyCardView( modifier = modifier.fillMaxWidth(), horizontalAlignment = Alignment.CenterHorizontally ) { + Spacer(modifier = Modifier.weight(50f)) + Image( painter = painterResource(id = R.drawable.img_calendar_empty_view), contentDescription = null, modifier = Modifier.padding(8.dp) ) + Spacer(modifier = Modifier.weight(8f)) Text( text = "오늘 예정된 일정이 없어요.", @@ -264,11 +267,13 @@ private fun EmptyCardView( style = CherrishTheme.typography.body1R14 ) - Spacer(modifier = Modifier.height(40.dp)) + Spacer(modifier = Modifier.weight(40f)) AddProcedureButton( onClick = onClick ) + + Spacer(modifier = Modifier.weight(24f)) } } From f69d9145f1ad23a0dc150cd0dac0c2f67273bb18 Mon Sep 17 00:00:00 2001 From: Kim Nahyeon Date: Fri, 23 Jan 2026 01:51:42 +0900 Subject: [PATCH 2/8] =?UTF-8?q?[REF/#144]=20imePadding=20=EC=A0=81?= =?UTF-8?q?=EC=9A=A9=EC=9D=84=20=EC=9C=84=ED=95=9C=20=EB=A6=AC=ED=8C=A9?= =?UTF-8?q?=ED=86=A0=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../calendar/procedure/ProcedureScreen.kt | 193 ++++++++++-------- .../procedure/component/SelectionSection.kt | 39 ++-- .../content/RecoveryScheduleContent.kt | 33 ++- 3 files changed, 156 insertions(+), 109 deletions(-) diff --git a/app/src/main/java/com/cherrish/android/presentation/calendar/procedure/ProcedureScreen.kt b/app/src/main/java/com/cherrish/android/presentation/calendar/procedure/ProcedureScreen.kt index 506d37d3..a6b8e916 100644 --- a/app/src/main/java/com/cherrish/android/presentation/calendar/procedure/ProcedureScreen.kt +++ b/app/src/main/java/com/cherrish/android/presentation/calendar/procedure/ProcedureScreen.kt @@ -5,9 +5,12 @@ 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.foundation.layout.navigationBarsPadding import androidx.compose.foundation.layout.padding import androidx.compose.foundation.lazy.rememberLazyListState +import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.verticalScroll import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.rememberModalBottomSheetState import androidx.compose.runtime.Composable @@ -148,7 +151,7 @@ fun ProcedureScreen( .fillMaxSize() .background(CherrishTheme.colors.gray0) .navigationBarsPadding() - .padding(top = 44.dp, bottom = 20.dp), + .padding(top = 44.dp), horizontalAlignment = Alignment.CenterHorizontally ) { BackAndCloseTopAppBar( @@ -157,111 +160,129 @@ fun ProcedureScreen( onCloseClick = onCloseClick ) - if (uiState.showStepProgressBar) { - StepProgressBar( - totalStep = uiState.totalSteps, - currentStep = uiState.currentStepIndex, - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 26.dp) - .padding(top = 20.dp) - ) - } - Column( modifier = Modifier - .fillMaxWidth() - .padding(top = uiState.contentTopPadding) .weight(1f) + .fillMaxWidth() + .imePadding() ) { - when (uiState.flow) { - ProcedureFlow.Entry -> { - ExistenceContent( - selectedIndex = uiState.existenceSelectedIndex, - onItemClick = onExistenceClick, - modifier = Modifier - .padding(horizontal = 26.dp) - .padding(bottom = 10.dp) - ) - } + if (uiState.showStepProgressBar) { + StepProgressBar( + totalStep = uiState.totalSteps, + currentStep = uiState.currentStepIndex, + modifier = Modifier + .fillMaxWidth() + .padding(horizontal = 26.dp) + .padding(top = 20.dp) + ) + } - ProcedureFlow.NoTreat, ProcedureFlow.Treat -> { - when (uiState.step) { - ProcedureStep.Category -> { - CategoryContent( - worries = uiState.worries, - selectedWorryId = uiState.selectedWorryId, - onWorryClick = onWorryClick, - modifier = Modifier - .padding(horizontal = 26.dp) - .padding(bottom = 10.dp) - ) - } + Column( + modifier = Modifier.fillMaxWidth() + ) { + when (uiState.flow) { + ProcedureFlow.Entry -> { + ExistenceContent( + selectedIndex = uiState.existenceSelectedIndex, + onItemClick = onExistenceClick, + modifier = Modifier + .padding(top = uiState.contentTopPadding) + .padding(horizontal = 26.dp) + .padding(bottom = 10.dp) + ) + } - ProcedureStep.RecoverySchedule -> { - RecoveryScheduleContent( - selectedIndex = uiState.recoverySelectedIndex, - onItemClick = onRecoveryOptionClick, - year = uiState.year, - month = uiState.month, - day = uiState.day, - onYearChange = onYearChange, - onMonthChange = onMonthChange, - onDayChange = onDayChange, - errorMessage = uiState.dateErrorMessage, - modifier = Modifier.padding(horizontal = 26.dp) - ) - } + ProcedureFlow.NoTreat, ProcedureFlow.Treat -> { + when (uiState.step) { + ProcedureStep.Category -> { + CategoryContent( + worries = uiState.worries, + selectedWorryId = uiState.selectedWorryId, + onWorryClick = onWorryClick, + modifier = Modifier + .padding(top = uiState.contentTopPadding) + .padding(horizontal = 26.dp) + .padding(bottom = 10.dp) + ) + } - ProcedureStep.Filtering -> { - FilteringContent( - name = uiState.selectedWorryName, - cardItems = uiState.procedureItems, - selectedCardIds = uiState.selectedProcedureCardIds, - onCardClick = onProcedureCardClick, - bottomPadding = uiState.lazyColumnBottomPadding, - modifier = Modifier.fillMaxWidth() - ) - } + ProcedureStep.RecoverySchedule -> { + Column( + modifier = Modifier + .fillMaxWidth() + .verticalScroll(rememberScrollState()) + ) { + RecoveryScheduleContent( + selectedIndex = uiState.recoverySelectedIndex, + onItemClick = onRecoveryOptionClick, + year = uiState.year, + month = uiState.month, + day = uiState.day, + onYearChange = onYearChange, + onMonthChange = onMonthChange, + onDayChange = onDayChange, + errorMessage = uiState.dateErrorMessage, + modifier = Modifier + .padding(top = uiState.contentTopPadding) + .padding(horizontal = 26.dp) + ) + } + } - ProcedureStep.FilteringWithSearch -> { - FilteringWithSearchContent( - cardItems = uiState.procedureItems, - selectedCardIds = uiState.selectedProcedureCardIds, - onCardClick = onProcedureCardClick, - onSearchAction = onSearchAction, - query = uiState.searchQuery, - onQueryChange = onSearchableQueryChange, - bottomContentPadding = uiState.lazyColumnBottomPadding, - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 24.dp) - ) - } + ProcedureStep.Filtering -> { + FilteringContent( + name = uiState.selectedWorryName, + cardItems = uiState.procedureItems, + selectedCardIds = uiState.selectedProcedureCardIds, + onCardClick = onProcedureCardClick, + bottomPadding = uiState.lazyColumnBottomPadding, + modifier = Modifier.fillMaxWidth() + .padding(top = uiState.contentTopPadding) + ) + } + + ProcedureStep.FilteringWithSearch -> { + FilteringWithSearchContent( + cardItems = uiState.procedureItems, + selectedCardIds = uiState.selectedProcedureCardIds, + onCardClick = onProcedureCardClick, + onSearchAction = onSearchAction, + query = uiState.searchQuery, + onQueryChange = onSearchableQueryChange, + bottomContentPadding = uiState.lazyColumnBottomPadding, + modifier = Modifier + .fillMaxWidth() + .padding(top = uiState.contentTopPadding) + .padding(horizontal = 24.dp) + ) + } - ProcedureStep.Downtime -> { - DowntimeContent( - cardItems = uiState.selectedProcedureCardItems, - selectedCardIds = - uiState.procedureDowntimeMap.keys.toImmutableList(), - onCardClick = onDowntimeClick, - activeCardId = uiState.selectedProcedureForDowntime?.id, - isDowntimeBottomSheetVisible = uiState.showDowntimeBottomSheet, - modifier = Modifier.fillMaxWidth() - ) + ProcedureStep.Downtime -> { + DowntimeContent( + cardItems = uiState.selectedProcedureCardItems, + selectedCardIds = uiState.procedureDowntimeMap.keys.toImmutableList(), + onCardClick = onDowntimeClick, + activeCardId = uiState.selectedProcedureForDowntime?.id, + isDowntimeBottomSheetVisible = uiState.showDowntimeBottomSheet, + modifier = Modifier + .fillMaxWidth() + .padding(top = uiState.contentTopPadding) + ) + } } } } } } + CherrishButton( - text = "다음", + text = if (uiState.step == ProcedureStep.Downtime) "완료" else "다음", onClick = onNextClick, enabled = uiState.isNextEnabled, modifier = Modifier .fillMaxWidth() .padding(horizontal = 24.dp) - .padding(top = 24.dp) + .padding(vertical = 20.dp) ) } diff --git a/app/src/main/java/com/cherrish/android/presentation/calendar/procedure/component/SelectionSection.kt b/app/src/main/java/com/cherrish/android/presentation/calendar/procedure/component/SelectionSection.kt index fabc53d8..4e337305 100644 --- a/app/src/main/java/com/cherrish/android/presentation/calendar/procedure/component/SelectionSection.kt +++ b/app/src/main/java/com/cherrish/android/presentation/calendar/procedure/component/SelectionSection.kt @@ -2,12 +2,10 @@ package com.cherrish.android.presentation.calendar.procedure.component 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.fillMaxWidth import androidx.compose.foundation.layout.height -import androidx.compose.foundation.lazy.grid.GridCells -import androidx.compose.foundation.lazy.grid.LazyVerticalGrid -import androidx.compose.foundation.lazy.grid.itemsIndexed import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue @@ -44,7 +42,7 @@ fun SelectionSection( Spacer(modifier = Modifier.height(40.dp)) - ChipGrid( + ChipFlowGrid( items = items, selectedIndex = selectedIndex, onItemClick = onItemClick @@ -53,29 +51,34 @@ fun SelectionSection( } @Composable -private fun ChipGrid( +private fun ChipFlowGrid( items: ImmutableList, onItemClick: (index: Int) -> Unit, modifier: Modifier = Modifier, selectedIndex: Int? = null ) { - LazyVerticalGrid( + Column( modifier = modifier.fillMaxWidth(), - columns = GridCells.Fixed(2), - horizontalArrangement = Arrangement.spacedBy(12.dp), verticalArrangement = Arrangement.spacedBy(12.dp) ) { - itemsIndexed( - items = items, - key = { index, item -> "$item-$index" } - ) { index, text -> - - CherrishSelectionChip( - text = text, - onClick = { onItemClick(index) }, + items.chunked(2).forEachIndexed { rowIndex, rowItems -> + Row( modifier = Modifier.fillMaxWidth(), - isSelected = selectedIndex == index - ) + horizontalArrangement = Arrangement.spacedBy(12.dp) + ) { + rowItems.forEachIndexed { colIndex, text -> + val index = rowIndex * 2 + colIndex + CherrishSelectionChip( + text = text, + onClick = { onItemClick(index) }, + modifier = Modifier.weight(1f), + isSelected = selectedIndex == index + ) + } + if (rowItems.size == 1) { + Spacer(modifier = Modifier.weight(1f)) + } + } } } } diff --git a/app/src/main/java/com/cherrish/android/presentation/calendar/procedure/content/RecoveryScheduleContent.kt b/app/src/main/java/com/cherrish/android/presentation/calendar/procedure/content/RecoveryScheduleContent.kt index ff85a102..196ac588 100644 --- a/app/src/main/java/com/cherrish/android/presentation/calendar/procedure/content/RecoveryScheduleContent.kt +++ b/app/src/main/java/com/cherrish/android/presentation/calendar/procedure/content/RecoveryScheduleContent.kt @@ -8,6 +8,8 @@ import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.relocation.BringIntoViewRequester +import androidx.compose.foundation.relocation.bringIntoViewRequester import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material3.Text import androidx.compose.runtime.Composable @@ -15,10 +17,12 @@ import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableIntStateOf import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember +import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment.Companion.CenterVertically import androidx.compose.ui.Modifier import androidx.compose.ui.focus.FocusDirection +import androidx.compose.ui.focus.onFocusChanged import androidx.compose.ui.platform.LocalFocusManager import androidx.compose.ui.text.input.ImeAction import androidx.compose.ui.text.input.KeyboardType @@ -29,6 +33,8 @@ import com.cherrish.android.core.designsystem.component.textfield.CherrishTextFi import com.cherrish.android.core.designsystem.theme.CherrishTheme import com.cherrish.android.presentation.calendar.procedure.component.SelectionSection import kotlinx.collections.immutable.persistentListOf +import kotlinx.coroutines.delay +import kotlinx.coroutines.launch @Composable fun RecoveryScheduleContent( @@ -43,8 +49,10 @@ fun RecoveryScheduleContent( modifier: Modifier = Modifier, errorMessage: String? = null ) { - val hasSelection = selectedIndex != null && selectedIndex >= 0 + val coroutineScope = rememberCoroutineScope() + val bringIntoViewRequester = remember { BringIntoViewRequester() } val focusManager = LocalFocusManager.current + val hasSelection = selectedIndex != null && selectedIndex >= 0 Column(modifier = modifier) { SelectionSection( @@ -56,7 +64,9 @@ fun RecoveryScheduleContent( if (hasSelection) { Column( - modifier = Modifier.padding(top = 56.dp) + modifier = Modifier + .padding(top = 56.dp) + .bringIntoViewRequester(bringIntoViewRequester) ) { val sectionTitle = if (selectedIndex == 0) { "대략적인 회복 목표일을 정해볼까요?" @@ -72,8 +82,14 @@ fun RecoveryScheduleContent( onYearChange = onYearChange, onMonthChange = onMonthChange, onDayChange = onDayChange, + onFocus = { + coroutineScope.launch { + delay(100) + bringIntoViewRequester.bringIntoView() + } + }, onDone = { focusManager.clearFocus(force = true) }, - onNext = { focusManager.moveFocus(focusDirection = FocusDirection.Next) } + onNext = { focusManager.moveFocus(focusDirection = FocusDirection.Next) }, ) if (errorMessage != null) { @@ -93,6 +109,7 @@ private fun ScheduleSettingSection( onYearChange: (String) -> Unit, onMonthChange: (String) -> Unit, onDayChange: (String) -> Unit, + onFocus: () -> Unit, onDone: () -> Unit, onNext: () -> Unit, modifier: Modifier = Modifier @@ -123,6 +140,7 @@ private fun ScheduleSettingSection( suffix = "년", placeholder = "YYYY", onValueChange = onYearChange, + onFocus = onFocus, imeAction = ImeAction.Next, onNext = onNext, modifier = Modifier.weight(1f) @@ -132,6 +150,7 @@ private fun ScheduleSettingSection( suffix = "월", placeholder = "MM", onValueChange = onMonthChange, + onFocus = onFocus, imeAction = ImeAction.Next, onNext = onNext, modifier = Modifier.weight(1f) @@ -141,6 +160,7 @@ private fun ScheduleSettingSection( suffix = "일", placeholder = "DD", onValueChange = onDayChange, + onFocus = onFocus, imeAction = ImeAction.Done, onDone = onDone, modifier = Modifier.weight(1f) @@ -155,6 +175,7 @@ private fun DateInputBasicSection( suffix: String, placeholder: String, onValueChange: (String) -> Unit, + onFocus: () -> Unit, modifier: Modifier = Modifier, imeAction: ImeAction = ImeAction.Next, onDone: () -> Unit = {}, @@ -182,8 +203,10 @@ private fun DateInputBasicSection( keyboardImeAction = imeAction, onDoneAction = onDone, onNextAction = onNext, - paddingValues = PaddingValues(horizontal = 19.dp, vertical = 8.dp), - modifier = Modifier.weight(1f) + paddingValues = PaddingValues(horizontal = 12.dp, vertical = 8.dp), + modifier = Modifier + .weight(1f) + .onFocusChanged { if (it.isFocused) onFocus() } ) Text( From c81cf2a895f4e08f67ada5b85c9072604a2e937c Mon Sep 17 00:00:00 2001 From: Kim Nahyeon Date: Fri, 23 Jan 2026 02:39:26 +0900 Subject: [PATCH 3/8] =?UTF-8?q?[FIX/#144]=20=EC=98=A8=EB=B3=B4=EB=94=A9=20?= =?UTF-8?q?=ED=99=94=EB=A9=B4=20imePadding=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../OnboardingInformationScreen.kt | 141 ++++++++++-------- 1 file changed, 78 insertions(+), 63 deletions(-) diff --git a/app/src/main/java/com/cherrish/android/presentation/onboarding/information/OnboardingInformationScreen.kt b/app/src/main/java/com/cherrish/android/presentation/onboarding/information/OnboardingInformationScreen.kt index bf6ee21f..d72c1838 100644 --- a/app/src/main/java/com/cherrish/android/presentation/onboarding/information/OnboardingInformationScreen.kt +++ b/app/src/main/java/com/cherrish/android/presentation/onboarding/information/OnboardingInformationScreen.kt @@ -1,15 +1,23 @@ package com.cherrish.android.presentation.onboarding.information +import androidx.compose.animation.animateContentSize +import androidx.compose.animation.core.Spring +import androidx.compose.animation.core.spring import androidx.compose.foundation.background import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.WindowInsets import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.ime +import androidx.compose.foundation.layout.imePadding import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.windowInsetsPadding import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material3.Scaffold import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue @@ -36,6 +44,8 @@ import com.cherrish.android.core.designsystem.component.button.CherrishButton import com.cherrish.android.core.designsystem.component.textfield.CherrishTextField import com.cherrish.android.core.designsystem.theme.CherrishTheme import com.cherrish.android.presentation.onboarding.information.extension.AgeSuffixTransformation +import kotlinx.coroutines.delay +import kotlinx.coroutines.launch @Composable fun OnboardingInformationRoute( @@ -80,75 +90,80 @@ private fun OnboardingInformationScreen( val focusManager = LocalFocusManager.current val keyboardController = LocalSoftwareKeyboardController.current val ageFocusRequester = remember { FocusRequester() } - var isAgeFocused by remember { mutableStateOf(false) } - Column( - modifier = modifier - .fillMaxSize() - .background(color = CherrishTheme.colors.gray0) - .addFocusCleaner(focusManager) - .padding(paddingValues = paddingValues) - ) { - Spacer(modifier = Modifier.weight(135f)) - - UserInfoHeader() - - Spacer(modifier = Modifier.weight(70f)) - - UserInfoTextField( - textFieldName = "이름", - value = username, - onValueChange = onNameChange, - placeholder = "김체리", - keyboardImeAction = ImeAction.Next, - onNextAction = { - ageFocusRequester.requestFocus() - }, - keyboardType = KeyboardType.Text, - errorText = "이름은 최대 7자까지 입력 가능합니다.", - errorCase = nameErrorCase - ) + Scaffold( + bottomBar = { + CherrishButton( + text = "다음", + onClick = onNextClick, + enabled = enabled, + modifier = Modifier + .fillMaxWidth() + .padding(horizontal = 24.dp, vertical = 30.dp) + .background(CherrishTheme.colors.gray0) - Spacer(modifier = Modifier.weight(30f)) - - UserInfoTextField( - textFieldName = "나이", - value = age, - onValueChange = onAgeChange, - placeholder = "20", - keyboardImeAction = ImeAction.Done, - onDoneAction = { - keyboardController?.hide() - focusManager.clearFocus() - }, - keyboardType = KeyboardType.Number, - visualTransformation = if (isAgeFocused) { - VisualTransformation.None - } else { - AgeSuffixTransformation( - " 세" - ) - }, - errorText = "입력 가능한 최대 나이 100세를 초과했습니다.", - errorCase = ageErrorCase, - modifier = Modifier - .focusRequester(ageFocusRequester) - .onFocusChanged { state -> - isAgeFocused = state.isFocused - } - ) + ) + } + ) { innerPadding -> + Column( + modifier = modifier + .fillMaxSize() + .background(color = CherrishTheme.colors.gray0) + .addFocusCleaner(focusManager) + .padding(paddingValues = paddingValues) + .imePadding() + ) { + Spacer(modifier = Modifier.weight(135f)) + UserInfoHeader() + Spacer(modifier = Modifier.weight(70f)) - Spacer(modifier = Modifier.weight(200f)) + UserInfoTextField( + textFieldName = "이름", + value = username, + onValueChange = onNameChange, + placeholder = "김체리", + keyboardImeAction = ImeAction.Next, + onNextAction = { ageFocusRequester.requestFocus() }, + keyboardType = KeyboardType.Text, + errorText = "이름은 최대 7자까지 입력 가능합니다.", + errorCase = nameErrorCase + ) - CherrishButton( - text = "다음", - onClick = onNextClick, - enabled = enabled, - modifier = Modifier.padding(horizontal = 24.dp) - ) + Spacer(modifier = Modifier.weight(30f)) + + UserInfoTextField( + textFieldName = "나이", + value = age, + onValueChange = onAgeChange, + placeholder = "20", + keyboardImeAction = ImeAction.Done, + onDoneAction = { + keyboardController?.hide() + kotlinx.coroutines.MainScope().launch { + delay(100) + focusManager.clearFocus() + } + }, + keyboardType = KeyboardType.Number, + visualTransformation = if (isAgeFocused) { + VisualTransformation.None + } else { + AgeSuffixTransformation(" 세") + }, + errorText = "입력 가능한 최대 나이 100세를 초과했습니다.", + errorCase = ageErrorCase, + modifier = Modifier + .focusRequester(ageFocusRequester) + .onFocusChanged { state -> + isAgeFocused = state.isFocused + } + ) - Spacer(modifier = Modifier.weight(30f)) + Spacer(modifier = Modifier.weight(200f)) + + Spacer(modifier = Modifier.padding(innerPadding.calculateBottomPadding())) + } } } From 92f982d5432b21a8b75ec1ef846c2e79214b504a Mon Sep 17 00:00:00 2001 From: Kim Nahyeon Date: Fri, 23 Jan 2026 02:46:05 +0900 Subject: [PATCH 4/8] =?UTF-8?q?[FIX/#144]=20=EC=8B=9C=EC=88=A0=20=EC=84=A0?= =?UTF-8?q?=ED=83=9D=20=ED=94=8C=EB=A1=9C=EC=9A=B0=20=ED=99=94=EB=A9=B4=20?= =?UTF-8?q?imePadding=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../calendar/procedure/ProcedureScreen.kt | 235 +++++++++--------- 1 file changed, 124 insertions(+), 111 deletions(-) diff --git a/app/src/main/java/com/cherrish/android/presentation/calendar/procedure/ProcedureScreen.kt b/app/src/main/java/com/cherrish/android/presentation/calendar/procedure/ProcedureScreen.kt index a6b8e916..2c99ecd0 100644 --- a/app/src/main/java/com/cherrish/android/presentation/calendar/procedure/ProcedureScreen.kt +++ b/app/src/main/java/com/cherrish/android/presentation/calendar/procedure/ProcedureScreen.kt @@ -3,8 +3,10 @@ package com.cherrish.android.presentation.calendar.procedure import androidx.activity.compose.BackHandler import androidx.compose.foundation.background import androidx.compose.foundation.layout.Column +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.imePadding import androidx.compose.foundation.layout.navigationBarsPadding import androidx.compose.foundation.layout.padding @@ -12,6 +14,7 @@ import androidx.compose.foundation.lazy.rememberLazyListState import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.verticalScroll import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.Scaffold import androidx.compose.material3.rememberModalBottomSheetState import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect @@ -146,144 +149,154 @@ fun ProcedureScreen( BackHandler { onBackClick() } - Column( + Scaffold( modifier = modifier .fillMaxSize() .background(CherrishTheme.colors.gray0) .navigationBarsPadding() .padding(top = 44.dp), - horizontalAlignment = Alignment.CenterHorizontally - ) { - BackAndCloseTopAppBar( - title = uiState.title, - onBackClick = onBackClick, - onCloseClick = onCloseClick - ) - + containerColor = CherrishTheme.colors.gray0, + bottomBar = { + CherrishButton( + text = if (uiState.step == ProcedureStep.Downtime) "완료" else "다음", + onClick = onNextClick, + enabled = uiState.isNextEnabled, + modifier = Modifier + .fillMaxWidth() + .padding(horizontal = 24.dp) + .padding(vertical = 20.dp) + .background(CherrishTheme.colors.gray0) + ) + } + ) { innerPadding -> Column( modifier = Modifier - .weight(1f) - .fillMaxWidth() - .imePadding() + .fillMaxSize() + .imePadding(), + horizontalAlignment = Alignment.CenterHorizontally ) { - if (uiState.showStepProgressBar) { - StepProgressBar( - totalStep = uiState.totalSteps, - currentStep = uiState.currentStepIndex, - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 26.dp) - .padding(top = 20.dp) - ) - } + BackAndCloseTopAppBar( + title = uiState.title, + onBackClick = onBackClick, + onCloseClick = onCloseClick + ) Column( - modifier = Modifier.fillMaxWidth() + modifier = Modifier + .weight(1f) + .fillMaxWidth() ) { - when (uiState.flow) { - ProcedureFlow.Entry -> { - ExistenceContent( - selectedIndex = uiState.existenceSelectedIndex, - onItemClick = onExistenceClick, - modifier = Modifier - .padding(top = uiState.contentTopPadding) - .padding(horizontal = 26.dp) - .padding(bottom = 10.dp) - ) - } + if (uiState.showStepProgressBar) { + StepProgressBar( + totalStep = uiState.totalSteps, + currentStep = uiState.currentStepIndex, + modifier = Modifier + .fillMaxWidth() + .padding(horizontal = 26.dp) + .padding(top = 20.dp) + ) + } - ProcedureFlow.NoTreat, ProcedureFlow.Treat -> { - when (uiState.step) { - ProcedureStep.Category -> { - CategoryContent( - worries = uiState.worries, - selectedWorryId = uiState.selectedWorryId, - onWorryClick = onWorryClick, - modifier = Modifier - .padding(top = uiState.contentTopPadding) - .padding(horizontal = 26.dp) - .padding(bottom = 10.dp) - ) - } + Column( + modifier = Modifier.fillMaxWidth() + ) { + when (uiState.flow) { + ProcedureFlow.Entry -> { + ExistenceContent( + selectedIndex = uiState.existenceSelectedIndex, + onItemClick = onExistenceClick, + modifier = Modifier + .padding(top = uiState.contentTopPadding) + .padding(horizontal = 26.dp) + .padding(bottom = 10.dp) + ) + } - ProcedureStep.RecoverySchedule -> { - Column( - modifier = Modifier - .fillMaxWidth() - .verticalScroll(rememberScrollState()) - ) { - RecoveryScheduleContent( - selectedIndex = uiState.recoverySelectedIndex, - onItemClick = onRecoveryOptionClick, - year = uiState.year, - month = uiState.month, - day = uiState.day, - onYearChange = onYearChange, - onMonthChange = onMonthChange, - onDayChange = onDayChange, - errorMessage = uiState.dateErrorMessage, + ProcedureFlow.NoTreat, ProcedureFlow.Treat -> { + when (uiState.step) { + ProcedureStep.Category -> { + CategoryContent( + worries = uiState.worries, + selectedWorryId = uiState.selectedWorryId, + onWorryClick = onWorryClick, modifier = Modifier .padding(top = uiState.contentTopPadding) .padding(horizontal = 26.dp) + .padding(bottom = 10.dp) ) } - } - ProcedureStep.Filtering -> { - FilteringContent( - name = uiState.selectedWorryName, - cardItems = uiState.procedureItems, - selectedCardIds = uiState.selectedProcedureCardIds, - onCardClick = onProcedureCardClick, - bottomPadding = uiState.lazyColumnBottomPadding, - modifier = Modifier.fillMaxWidth() - .padding(top = uiState.contentTopPadding) - ) - } + ProcedureStep.RecoverySchedule -> { + Column( + modifier = Modifier + .fillMaxWidth() + .verticalScroll(rememberScrollState()) + ) { + RecoveryScheduleContent( + selectedIndex = uiState.recoverySelectedIndex, + onItemClick = onRecoveryOptionClick, + year = uiState.year, + month = uiState.month, + day = uiState.day, + onYearChange = onYearChange, + onMonthChange = onMonthChange, + onDayChange = onDayChange, + errorMessage = uiState.dateErrorMessage, + modifier = Modifier + .padding(top = uiState.contentTopPadding) + .padding(horizontal = 26.dp) + ) + } + } - ProcedureStep.FilteringWithSearch -> { - FilteringWithSearchContent( - cardItems = uiState.procedureItems, - selectedCardIds = uiState.selectedProcedureCardIds, - onCardClick = onProcedureCardClick, - onSearchAction = onSearchAction, - query = uiState.searchQuery, - onQueryChange = onSearchableQueryChange, - bottomContentPadding = uiState.lazyColumnBottomPadding, - modifier = Modifier - .fillMaxWidth() - .padding(top = uiState.contentTopPadding) - .padding(horizontal = 24.dp) - ) - } + ProcedureStep.Filtering -> { + FilteringContent( + name = uiState.selectedWorryName, + cardItems = uiState.procedureItems, + selectedCardIds = uiState.selectedProcedureCardIds, + onCardClick = onProcedureCardClick, + bottomPadding = uiState.lazyColumnBottomPadding, + modifier = Modifier.fillMaxWidth() + .padding(top = uiState.contentTopPadding) + ) + } + + ProcedureStep.FilteringWithSearch -> { + FilteringWithSearchContent( + cardItems = uiState.procedureItems, + selectedCardIds = uiState.selectedProcedureCardIds, + onCardClick = onProcedureCardClick, + onSearchAction = onSearchAction, + query = uiState.searchQuery, + onQueryChange = onSearchableQueryChange, + bottomContentPadding = uiState.lazyColumnBottomPadding, + modifier = Modifier + .fillMaxWidth() + .padding(top = uiState.contentTopPadding) + .padding(horizontal = 24.dp) + ) + } - ProcedureStep.Downtime -> { - DowntimeContent( - cardItems = uiState.selectedProcedureCardItems, - selectedCardIds = uiState.procedureDowntimeMap.keys.toImmutableList(), - onCardClick = onDowntimeClick, - activeCardId = uiState.selectedProcedureForDowntime?.id, - isDowntimeBottomSheetVisible = uiState.showDowntimeBottomSheet, - modifier = Modifier - .fillMaxWidth() - .padding(top = uiState.contentTopPadding) - ) + ProcedureStep.Downtime -> { + DowntimeContent( + cardItems = uiState.selectedProcedureCardItems, + selectedCardIds = uiState.procedureDowntimeMap.keys.toImmutableList(), + onCardClick = onDowntimeClick, + activeCardId = uiState.selectedProcedureForDowntime?.id, + isDowntimeBottomSheetVisible = uiState.showDowntimeBottomSheet, + modifier = Modifier + .fillMaxWidth() + .padding(top = uiState.contentTopPadding) + ) + } } } } } } - } - CherrishButton( - text = if (uiState.step == ProcedureStep.Downtime) "완료" else "다음", - onClick = onNextClick, - enabled = uiState.isNextEnabled, - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 24.dp) - .padding(vertical = 20.dp) - ) + Spacer(modifier = Modifier.height(innerPadding.calculateBottomPadding())) + } } SelectedProcedureBottomSheet( From 6ef28766193613a8aff8384fae30cb105d07270b Mon Sep 17 00:00:00 2001 From: Kim Nahyeon Date: Fri, 23 Jan 2026 02:49:06 +0900 Subject: [PATCH 5/8] =?UTF-8?q?[FIX/#144]=20sohee6989=20=ED=85=8D=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=EB=8C=80=EC=8B=A0=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../calendar/procedure/component/DowntimeBottomSheet.kt | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/com/cherrish/android/presentation/calendar/procedure/component/DowntimeBottomSheet.kt b/app/src/main/java/com/cherrish/android/presentation/calendar/procedure/component/DowntimeBottomSheet.kt index 1bf43f46..39170399 100644 --- a/app/src/main/java/com/cherrish/android/presentation/calendar/procedure/component/DowntimeBottomSheet.kt +++ b/app/src/main/java/com/cherrish/android/presentation/calendar/procedure/component/DowntimeBottomSheet.kt @@ -336,7 +336,12 @@ private fun DowntimeDayPicker( ) Text( - text = "보통 $minDowntimeDays-${maxDowntimeDays}일", + text = if (minDowntimeDays == 0 && maxDowntimeDays == 0) { + "보통 다운타임 0일 " + } + else { + "보통 $minDowntimeDays-${maxDowntimeDays}일" + }, color = CherrishTheme.colors.gray600, style = CherrishTheme.typography.title2M16 ) From 9cb8b7cf0e22fce8b2a1738d8a4ee181b65f8547 Mon Sep 17 00:00:00 2001 From: Kim Nahyeon Date: Fri, 23 Jan 2026 02:50:12 +0900 Subject: [PATCH 6/8] [CHORE/#144] Lint format --- .../calendar/procedure/component/DowntimeBottomSheet.kt | 5 ++--- .../calendar/procedure/content/RecoveryScheduleContent.kt | 2 +- .../onboarding/information/OnboardingInformationScreen.kt | 6 ------ 3 files changed, 3 insertions(+), 10 deletions(-) diff --git a/app/src/main/java/com/cherrish/android/presentation/calendar/procedure/component/DowntimeBottomSheet.kt b/app/src/main/java/com/cherrish/android/presentation/calendar/procedure/component/DowntimeBottomSheet.kt index 39170399..42b935e0 100644 --- a/app/src/main/java/com/cherrish/android/presentation/calendar/procedure/component/DowntimeBottomSheet.kt +++ b/app/src/main/java/com/cherrish/android/presentation/calendar/procedure/component/DowntimeBottomSheet.kt @@ -337,9 +337,8 @@ private fun DowntimeDayPicker( Text( text = if (minDowntimeDays == 0 && maxDowntimeDays == 0) { - "보통 다운타임 0일 " - } - else { + "보통 다운타임 0일" + } else { "보통 $minDowntimeDays-${maxDowntimeDays}일" }, color = CherrishTheme.colors.gray600, diff --git a/app/src/main/java/com/cherrish/android/presentation/calendar/procedure/content/RecoveryScheduleContent.kt b/app/src/main/java/com/cherrish/android/presentation/calendar/procedure/content/RecoveryScheduleContent.kt index 196ac588..7438f982 100644 --- a/app/src/main/java/com/cherrish/android/presentation/calendar/procedure/content/RecoveryScheduleContent.kt +++ b/app/src/main/java/com/cherrish/android/presentation/calendar/procedure/content/RecoveryScheduleContent.kt @@ -89,7 +89,7 @@ fun RecoveryScheduleContent( } }, onDone = { focusManager.clearFocus(force = true) }, - onNext = { focusManager.moveFocus(focusDirection = FocusDirection.Next) }, + onNext = { focusManager.moveFocus(focusDirection = FocusDirection.Next) } ) if (errorMessage != null) { diff --git a/app/src/main/java/com/cherrish/android/presentation/onboarding/information/OnboardingInformationScreen.kt b/app/src/main/java/com/cherrish/android/presentation/onboarding/information/OnboardingInformationScreen.kt index d72c1838..09251c48 100644 --- a/app/src/main/java/com/cherrish/android/presentation/onboarding/information/OnboardingInformationScreen.kt +++ b/app/src/main/java/com/cherrish/android/presentation/onboarding/information/OnboardingInformationScreen.kt @@ -1,21 +1,15 @@ package com.cherrish.android.presentation.onboarding.information -import androidx.compose.animation.animateContentSize -import androidx.compose.animation.core.Spring -import androidx.compose.animation.core.spring import androidx.compose.foundation.background import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.Spacer -import androidx.compose.foundation.layout.WindowInsets import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height -import androidx.compose.foundation.layout.ime import androidx.compose.foundation.layout.imePadding import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.windowInsetsPadding import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material3.Scaffold import androidx.compose.material3.Text From 7bee5ae53c711df1c01f5ec1d2cc943747ff18d5 Mon Sep 17 00:00:00 2001 From: Kim Nahyeon Date: Fri, 23 Jan 2026 03:06:20 +0900 Subject: [PATCH 7/8] [CHORE/#144] Lint format --- .../presentation/calendar/procedure/ProcedureScreen.kt | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/com/cherrish/android/presentation/calendar/procedure/ProcedureScreen.kt b/app/src/main/java/com/cherrish/android/presentation/calendar/procedure/ProcedureScreen.kt index 2c99ecd0..29128c39 100644 --- a/app/src/main/java/com/cherrish/android/presentation/calendar/procedure/ProcedureScreen.kt +++ b/app/src/main/java/com/cherrish/android/presentation/calendar/procedure/ProcedureScreen.kt @@ -280,10 +280,12 @@ fun ProcedureScreen( ProcedureStep.Downtime -> { DowntimeContent( cardItems = uiState.selectedProcedureCardItems, - selectedCardIds = uiState.procedureDowntimeMap.keys.toImmutableList(), + selectedCardIds = uiState.procedureDowntimeMap.keys + .toImmutableList(), onCardClick = onDowntimeClick, activeCardId = uiState.selectedProcedureForDowntime?.id, - isDowntimeBottomSheetVisible = uiState.showDowntimeBottomSheet, + isDowntimeBottomSheetVisible = uiState + .showDowntimeBottomSheet, modifier = Modifier .fillMaxWidth() .padding(top = uiState.contentTopPadding) From 9a0d8fbcefa285ddada64f9144cb21a5f6f59f95 Mon Sep 17 00:00:00 2001 From: Kim Nahyeon Date: Fri, 23 Jan 2026 03:26:17 +0900 Subject: [PATCH 8/8] =?UTF-8?q?[REF/#144]=20navigationBaraPadding=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../onboarding/information/OnboardingInformationScreen.kt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/src/main/java/com/cherrish/android/presentation/onboarding/information/OnboardingInformationScreen.kt b/app/src/main/java/com/cherrish/android/presentation/onboarding/information/OnboardingInformationScreen.kt index 09251c48..02c6407f 100644 --- a/app/src/main/java/com/cherrish/android/presentation/onboarding/information/OnboardingInformationScreen.kt +++ b/app/src/main/java/com/cherrish/android/presentation/onboarding/information/OnboardingInformationScreen.kt @@ -9,6 +9,7 @@ import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.imePadding +import androidx.compose.foundation.layout.navigationBarsPadding import androidx.compose.foundation.layout.padding import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material3.Scaffold @@ -96,6 +97,7 @@ private fun OnboardingInformationScreen( .fillMaxWidth() .padding(horizontal = 24.dp, vertical = 30.dp) .background(CherrishTheme.colors.gray0) + .navigationBarsPadding() ) }