diff --git a/Near/app/src/main/java/com/alarmy/near/presentation/feature/friendcontactcycle/components/ContactCycleContent.kt b/Near/app/src/main/java/com/alarmy/near/presentation/feature/friendcontactcycle/components/ContactCycleContent.kt index ae5c5116..0125e1fd 100644 --- a/Near/app/src/main/java/com/alarmy/near/presentation/feature/friendcontactcycle/components/ContactCycleContent.kt +++ b/Near/app/src/main/java/com/alarmy/near/presentation/feature/friendcontactcycle/components/ContactCycleContent.kt @@ -27,6 +27,7 @@ import androidx.compose.ui.unit.dp import com.alarmy.near.R import com.alarmy.near.model.ReminderInterval import com.alarmy.near.presentation.feature.friendcontactcycle.model.FriendContactUIModel +import com.alarmy.near.presentation.ui.component.bottomsheet.CycleSettingBottomSheet import com.alarmy.near.presentation.ui.component.checkbox.NearBackgroundCheckbox import com.alarmy.near.presentation.ui.extension.onNoRippleClick import com.alarmy.near.presentation.ui.theme.NearTheme @@ -64,10 +65,10 @@ fun ColumnScope.ContactCycleContent( ) } - Spacer(modifier = Modifier.size(14.dp)) - // 한번에 설정이 활성화되었을 때만 표시 if (isBulkSettingEnabled) { + Spacer(modifier = Modifier.size(12.dp)) + Row( modifier = Modifier @@ -85,7 +86,9 @@ fun ColumnScope.ContactCycleContent( verticalAlignment = Alignment.CenterVertically, ) { Text( - text = selectedCycle?.let { DateExtension.getCycleText(it) } ?: stringResource(R.string.friend_contact_cycle_weekly_format, DateExtension.getTodayDayOfWeekInKorean()), + text = + selectedCycle?.let { DateExtension.getCycleText(it) } + ?: stringResource(R.string.friend_contact_cycle_weekly_format, DateExtension.getTodayDayOfWeekInKorean()), style = NearTheme.typography.B2_14_MEDIUM, color = NearTheme.colors.BLACK_1A1A1A, ) @@ -101,7 +104,7 @@ fun ColumnScope.ContactCycleContent( // 리스트가 있을 때만 밑에 리스트 표시 if (contacts.isNotEmpty()) { - Spacer(modifier = Modifier.size(16.dp)) + Spacer(modifier = Modifier.size(24.dp)) LazyColumn( modifier = Modifier.weight(1f), diff --git a/Near/app/src/main/java/com/alarmy/near/presentation/feature/friendcontactcycle/components/ContactLoadContent.kt b/Near/app/src/main/java/com/alarmy/near/presentation/feature/friendcontactcycle/components/ContactLoadContent.kt index d6eed8a4..0d57214e 100644 --- a/Near/app/src/main/java/com/alarmy/near/presentation/feature/friendcontactcycle/components/ContactLoadContent.kt +++ b/Near/app/src/main/java/com/alarmy/near/presentation/feature/friendcontactcycle/components/ContactLoadContent.kt @@ -117,7 +117,7 @@ fun FriendListItem( modifier = Modifier.weight(1f), ) { Image( - painter = painterResource(R.drawable.img_100_character_default), + painter = painterResource(R.drawable.img_64_user_gray), contentDescription = null, modifier = Modifier.size(24.dp), ) diff --git a/Near/app/src/main/java/com/alarmy/near/presentation/feature/friendcontactcycle/components/CycleSettingBottomSheet.kt b/Near/app/src/main/java/com/alarmy/near/presentation/feature/friendcontactcycle/components/CycleSettingBottomSheet.kt deleted file mode 100644 index 826334a4..00000000 --- a/Near/app/src/main/java/com/alarmy/near/presentation/feature/friendcontactcycle/components/CycleSettingBottomSheet.kt +++ /dev/null @@ -1,214 +0,0 @@ -package com.alarmy.near.presentation.feature.friendcontactcycle.components - -import androidx.compose.foundation.background -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.padding -import androidx.compose.foundation.layout.size -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material3.BottomSheetDefaults -import androidx.compose.material3.ExperimentalMaterial3Api -import androidx.compose.material3.ModalBottomSheet -import androidx.compose.material3.Text -import androidx.compose.material3.VerticalDivider -import androidx.compose.material3.rememberModalBottomSheetState -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.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.SpanStyle -import androidx.compose.ui.text.buildAnnotatedString -import androidx.compose.ui.text.withStyle -import androidx.compose.ui.tooling.preview.Preview -import androidx.compose.ui.unit.dp -import com.alarmy.near.R -import com.alarmy.near.model.ReminderInterval -import com.alarmy.near.presentation.ui.component.checkbox.NearCheckbox -import com.alarmy.near.presentation.ui.extension.onNoRippleClick -import com.alarmy.near.presentation.ui.theme.NearTheme -import com.alarmy.near.utils.extensions.DateExtension - -@OptIn(ExperimentalMaterial3Api::class) -@Composable -fun CycleSettingBottomSheet( - isVisible: Boolean, - onDismiss: () -> Unit, - onComplete: (ReminderInterval) -> Unit = {}, - currentSelectedInterval: ReminderInterval? = null, - modifier: Modifier = Modifier, -) { - // 선택된 주기 상태 관리 (기존 선택값이 있으면 그것을 사용, 없으면 매주를 기본값으로) - var selectedInterval by remember(isVisible) { - mutableStateOf(currentSelectedInterval ?: ReminderInterval.EVERY_WEEK) - } - - if (isVisible) { - val bottomSheetState = - rememberModalBottomSheetState( - skipPartiallyExpanded = true, - ) - - ModalBottomSheet( - onDismissRequest = onDismiss, - sheetState = bottomSheetState, - dragHandle = { - BottomSheetDefaults.DragHandle( - color = NearTheme.colors.BLACK_1A1A1A.copy(alpha = 0.1f), - width = 36.dp, - height = 5.dp, - ) - }, - modifier = modifier, - containerColor = NearTheme.colors.WHITE_FFFFFF, - ) { - Column( - modifier = - Modifier - .fillMaxWidth() - .padding(horizontal = 24.dp), - ) { - Text( - text = stringResource(R.string.friend_contact_cycle_cycle_setting_text), - style = NearTheme.typography.B1_16_BOLD, - ) - - Spacer(modifier = Modifier.size(24.dp)) - - Row( - horizontalArrangement = Arrangement.SpaceBetween, - verticalAlignment = Alignment.CenterVertically, - modifier = - modifier - .fillMaxWidth() - .clip(RoundedCornerShape(12.dp)) - .background(NearTheme.colors.BG02_F4F9FD) - .padding(vertical = 18.dp, horizontal = 20.dp), - ) { - Text( - text = - buildAnnotatedString { - withStyle( - style = - SpanStyle( - color = NearTheme.colors.BLACK_1A1A1A, - fontWeight = NearTheme.typography.B2_14_MEDIUM.fontWeight, - ), - ) { - append(stringResource(R.string.friend_contact_cycle_weekly_prefix)) - } - withStyle( - style = - SpanStyle( - color = NearTheme.colors.BLUE01_5AA2E9, - fontWeight = NearTheme.typography.B2_14_BOLD.fontWeight, - ), - ) { - append(DateExtension.getTodayDayOfWeekInKorean()) - } - }, - style = NearTheme.typography.B2_14_MEDIUM, - ) - - Row( - verticalAlignment = Alignment.CenterVertically, - ) { - Spacer(modifier = Modifier.size(20.dp)) - - VerticalDivider( - modifier = - Modifier - .size(width = 1.dp, height = 28.dp), - color = - NearTheme.colors.BLACK_1A1A1A.copy( - alpha = 0.1f, - ), - ) - - Spacer(modifier = Modifier.size(20.dp)) - - Text( - text = "다음 주기 : ${ - selectedInterval?.let { DateExtension.getNextCycleDate(it) } - ?: DateExtension.getNextWeekSameDay() - }", - style = NearTheme.typography.B2_14_MEDIUM, - color = NearTheme.colors.GRAY01_888888, - ) - } - } - - Spacer(modifier = Modifier.size(8.dp)) - - ReminderInterval.entries.forEach { interval -> - val isSelected = selectedInterval == interval - - Row( - horizontalArrangement = Arrangement.SpaceBetween, - verticalAlignment = Alignment.CenterVertically, - modifier = - modifier - .fillMaxWidth() - .onNoRippleClick { - if (!isSelected) { - selectedInterval = interval - } - }.padding(vertical = 15.dp), - ) { - Text( - text = stringResource(interval.labelRes), - style = - if (isSelected) { - NearTheme.typography.B1_16_BOLD - } else { - NearTheme.typography.B2_14_MEDIUM - }, - ) - - if (isSelected) { - NearCheckbox( - checked = true, - onCheckedChange = { checked -> - // 체크박스 클릭 시 해제되지 않도록 수정 - // 체크된 상태를 유지 - }, - ) - } - } - } - Spacer(modifier = Modifier.size(24.dp)) - - ContactCycleButtons( - onLeftButtonClick = onDismiss, - onRightButtonClick = { - selectedInterval?.let { interval -> - onComplete(interval) - onDismiss() - } - }, - leftButtonText = stringResource(R.string.friend_contact_cycle_cancel_button), - rightButtonText = stringResource(R.string.friend_contact_cycle_complete_button), - ) - Spacer(modifier = Modifier.size(24.dp)) - } - } - } -} - -@Preview -@Composable -fun CycleSettingBottomSheetPreview() { - NearTheme { - CycleSettingBottomSheet( - isVisible = true, - onDismiss = {}, - ) - } -} diff --git a/Near/app/src/main/java/com/alarmy/near/presentation/feature/friendcontactcycle/components/NearListModuleBackground.kt b/Near/app/src/main/java/com/alarmy/near/presentation/feature/friendcontactcycle/components/NearListModuleBackground.kt index 151d6f8c..1e698cca 100644 --- a/Near/app/src/main/java/com/alarmy/near/presentation/feature/friendcontactcycle/components/NearListModuleBackground.kt +++ b/Near/app/src/main/java/com/alarmy/near/presentation/feature/friendcontactcycle/components/NearListModuleBackground.kt @@ -12,12 +12,13 @@ import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.shadow +import androidx.compose.ui.graphics.Color import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import com.alarmy.near.R +import com.alarmy.near.presentation.ui.extension.dropShadow import com.alarmy.near.presentation.ui.extension.onNoRippleClick import com.alarmy.near.presentation.ui.theme.NearTheme @@ -38,8 +39,12 @@ fun NearListModuleBackground( modifier = modifier .fillMaxWidth() - .shadow( - elevation = 4.dp, + .dropShadow( + blur = 16.dp, + offsetX = 0.dp, + offsetY = 4.dp, + spread = 0.dp, + color = Color.Black.copy(alpha = 0.12f), shape = RoundedCornerShape(12.dp), ).background( color = NearTheme.colors.WHITE_FFFFFF, diff --git a/Near/app/src/main/java/com/alarmy/near/presentation/feature/friendprofileedittor/FriendProfileEditorScreen.kt b/Near/app/src/main/java/com/alarmy/near/presentation/feature/friendprofileedittor/FriendProfileEditorScreen.kt index 7729f3f8..aab62b35 100644 --- a/Near/app/src/main/java/com/alarmy/near/presentation/feature/friendprofileedittor/FriendProfileEditorScreen.kt +++ b/Near/app/src/main/java/com/alarmy/near/presentation/feature/friendprofileedittor/FriendProfileEditorScreen.kt @@ -45,7 +45,7 @@ import com.alarmy.near.model.Friend import com.alarmy.near.model.Relation import com.alarmy.near.model.ReminderInterval import com.alarmy.near.presentation.feature.friendprofileedittor.component.NearDatePicker -import com.alarmy.near.presentation.feature.friendprofileedittor.component.ReminderIntervalBottomSheet +import com.alarmy.near.presentation.ui.component.bottomsheet.CycleSettingBottomSheet import com.alarmy.near.presentation.feature.friendprofileedittor.dialog.EditorExitDialog import com.alarmy.near.presentation.feature.friendprofileedittor.uistate.FriendProfileEditorUIEvent import com.alarmy.near.presentation.feature.friendprofileedittor.uistate.FriendProfileEditorUIState @@ -140,14 +140,16 @@ fun FriendProfileEditorScreen( onCloseDialog: () -> Unit = {}, ) { val showBottomSheet = remember { mutableStateOf(false) } - if (showBottomSheet.value) { - ReminderIntervalBottomSheet(onDismissRequest = { + CycleSettingBottomSheet( + isVisible = showBottomSheet.value, + onDismiss = { showBottomSheet.value = false - }, onSelectReminderInterval = { - onReminderIntervalChanged(it) - showBottomSheet.value = false - }) - } + }, + onComplete = { selectedInterval -> + onReminderIntervalChanged(selectedInterval) + }, + currentSelectedInterval = friendProfileEditorUIState.contactFrequency.reminderInterval, + ) if (dialogState) { EditorExitDialog( onDismissRequest = { diff --git a/Near/app/src/main/java/com/alarmy/near/presentation/feature/friendprofileedittor/component/ReminderIntervalBottomSheet.kt b/Near/app/src/main/java/com/alarmy/near/presentation/feature/friendprofileedittor/component/ReminderIntervalBottomSheet.kt deleted file mode 100644 index ce7902f1..00000000 --- a/Near/app/src/main/java/com/alarmy/near/presentation/feature/friendprofileedittor/component/ReminderIntervalBottomSheet.kt +++ /dev/null @@ -1,205 +0,0 @@ -package com.alarmy.near.presentation.feature.friendprofileedittor.component - -import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.PaddingValues -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.layout.padding -import androidx.compose.foundation.layout.width -import androidx.compose.foundation.lazy.LazyColumn -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material3.ExperimentalMaterial3Api -import androidx.compose.material3.ModalBottomSheet -import androidx.compose.material3.SheetState -import androidx.compose.material3.SheetValue -import androidx.compose.material3.Surface -import androidx.compose.material3.Text -import androidx.compose.material3.VerticalDivider -import androidx.compose.material3.rememberModalBottomSheetState -import androidx.compose.material3.rememberStandardBottomSheetState -import androidx.compose.runtime.Composable -import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.remember -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.SpanStyle -import androidx.compose.ui.text.buildAnnotatedString -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.text.withStyle -import androidx.compose.ui.tooling.preview.Preview -import androidx.compose.ui.unit.dp -import com.alarmy.near.model.ReminderInterval -import com.alarmy.near.presentation.ui.component.button.NearLineTypeButton -import com.alarmy.near.presentation.ui.component.button.NearSolidTypeButton -import com.alarmy.near.presentation.ui.component.checkbox.NearCheckbox -import com.alarmy.near.presentation.ui.extension.onNoRippleClick -import com.alarmy.near.presentation.ui.theme.NearTheme - -@OptIn(ExperimentalMaterial3Api::class) -@Composable -fun ReminderIntervalBottomSheet( - modifier: Modifier = Modifier, - selectedReminderInterval: ReminderInterval = ReminderInterval.EVERY_WEEK, - onSelectReminderInterval: (ReminderInterval) -> Unit = {}, - sheetState: SheetState = - rememberModalBottomSheetState( - skipPartiallyExpanded = true, - ), - onDismissRequest: () -> Unit = {}, -) { - val initialReminderInterval = remember { selectedReminderInterval } - - val tempSelected = remember { mutableStateOf(initialReminderInterval) } - ModalBottomSheet( - modifier = modifier, - containerColor = NearTheme.colors.WHITE_FFFFFF, - sheetState = sheetState, - onDismissRequest = { - tempSelected.value = initialReminderInterval - onDismissRequest() - }, - dragHandle = { - Surface( - modifier = Modifier.padding(top = 12.dp, bottom = 24.dp), - color = Color.Black.copy(alpha = 0.1f), - ) { - Box( - modifier = - Modifier - .width(36.dp) - .height(5.dp), - ) - } - }, - ) { - Text( - modifier = Modifier.padding(start = 24.dp), - text = "주기 설정", - style = NearTheme.typography.B1_16_BOLD, - color = Color.Black, - ) - Spacer(modifier = Modifier.height(24.dp)) - Surface( - modifier = - Modifier - .fillMaxWidth() - .padding(horizontal = 20.dp), - color = NearTheme.colors.BG02_F4F9FD, - shape = RoundedCornerShape(12.dp), - ) { - Row( - modifier = Modifier.padding(horizontal = 20.dp, vertical = 14.dp), - verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.SpaceBetween, - ) { - Text( - buildAnnotatedString { - append("매주") - withStyle( - style = - SpanStyle( - color = NearTheme.colors.BLUE01_5AA2E9, - fontWeight = FontWeight.Bold, - ), - ) { - append(" 화요일") - } - }, - color = NearTheme.colors.BLACK_1A1A1A, - style = NearTheme.typography.B2_14_MEDIUM, - ) - Row(verticalAlignment = Alignment.CenterVertically) { - VerticalDivider( - thickness = 1.dp, - modifier = Modifier.height(28.dp), - color = NearTheme.colors.BLACK_1A1A1A.copy(0.1f), - ) - Spacer(modifier = Modifier.width(20.dp)) - Text( - text = "다음 주기 : 4/8 화", - style = NearTheme.typography.B2_14_MEDIUM, - color = NearTheme.colors.GRAY01_888888, - ) - } - } - } - Spacer(modifier = Modifier.height(8.dp)) - LazyColumn( - verticalArrangement = Arrangement.spacedBy(28.dp), - contentPadding = PaddingValues(vertical = 14.dp), - ) { - items( - count = ReminderInterval.entries.size, - key = { index -> ReminderInterval.entries[index] }, - ) { item -> - val reminderInterval = ReminderInterval.entries[item] - Row( - modifier = - Modifier - .fillMaxWidth() - .padding(start = 24.dp, end = 14.dp) - .onNoRippleClick(onClick = { - tempSelected.value = reminderInterval - }), - horizontalArrangement = Arrangement.SpaceBetween, - verticalAlignment = Alignment.CenterVertically, - ) { - Text( - stringResource(reminderInterval.labelRes), - style = - if (reminderInterval == tempSelected.value) { - NearTheme.typography.B1_16_BOLD - } else { - NearTheme.typography.B1_16_MEDIUM - }, - color = NearTheme.colors.BLACK_1A1A1A, - ) - NearCheckbox( - checked = tempSelected.value == reminderInterval, - onCheckedChange = {}, - ) - } - } - } - Spacer(modifier = Modifier.height(24.dp)) - Row(modifier = Modifier.padding(horizontal = 20.dp)) { - NearLineTypeButton( - modifier = Modifier.weight(1f), - text = "취소", - onClick = { - tempSelected.value = initialReminderInterval - onDismissRequest() - }, - contentPadding = PaddingValues(vertical = 17.dp), - enabled = true, - ) - Spacer(modifier = Modifier.width(7.dp)) - NearSolidTypeButton( - modifier = Modifier.weight(1f), - text = "확인", - onClick = { - onSelectReminderInterval(tempSelected.value) - }, - enabled = true, - contentPadding = PaddingValues(vertical = 17.dp), - ) - } - Spacer(modifier = Modifier.height(24.dp)) - } -} - -@OptIn(ExperimentalMaterial3Api::class) -@Preview(showBackground = true) -@Composable -fun ReminderIntervalBottomSheetPreview() { - NearTheme { - ReminderIntervalBottomSheet( - sheetState = rememberStandardBottomSheetState(initialValue = SheetValue.Expanded), - ) - } -} diff --git a/Near/app/src/main/java/com/alarmy/near/presentation/ui/component/bottomsheet/CycleSettingBottomSheet.kt b/Near/app/src/main/java/com/alarmy/near/presentation/ui/component/bottomsheet/CycleSettingBottomSheet.kt new file mode 100644 index 00000000..394b7cb9 --- /dev/null +++ b/Near/app/src/main/java/com/alarmy/near/presentation/ui/component/bottomsheet/CycleSettingBottomSheet.kt @@ -0,0 +1,202 @@ +package com.alarmy.near.presentation.ui.component.bottomsheet + +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material3.Text +import androidx.compose.material3.VerticalDivider +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.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.SpanStyle +import androidx.compose.ui.text.buildAnnotatedString +import androidx.compose.ui.text.withStyle +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import com.alarmy.near.R +import com.alarmy.near.model.ReminderInterval +import com.alarmy.near.presentation.feature.friendcontactcycle.components.ContactCycleButtons +import com.alarmy.near.presentation.ui.component.checkbox.NearCheckbox +import com.alarmy.near.presentation.ui.extension.onNoRippleClick +import com.alarmy.near.presentation.ui.theme.NearTheme +import com.alarmy.near.utils.extensions.DateExtension + +@Composable +fun CycleSettingBottomSheet( + isVisible: Boolean, + onDismiss: () -> Unit, + onComplete: (ReminderInterval) -> Unit = {}, + currentSelectedInterval: ReminderInterval? = null, + modifier: Modifier = Modifier, +) { + var selectedInterval by remember(isVisible) { + mutableStateOf(currentSelectedInterval ?: ReminderInterval.EVERY_WEEK) + } + + NearBottomSheet( + isVisible = isVisible, + onDismiss = onDismiss, + modifier = modifier, + ) { + Text( + text = stringResource(R.string.friend_contact_cycle_cycle_setting_text), + style = NearTheme.typography.B1_16_BOLD, + ) + + Spacer(modifier = Modifier.size(24.dp)) + + Row( + horizontalArrangement = Arrangement.SpaceBetween, + verticalAlignment = Alignment.CenterVertically, + modifier = + Modifier + .fillMaxWidth() + .clip(RoundedCornerShape(12.dp)) + .background(NearTheme.colors.BG02_F4F9FD) + .padding(vertical = 18.dp, horizontal = 20.dp), + ) { + Text( + text = + buildAnnotatedString { + val interval = selectedInterval ?: ReminderInterval.EVERY_WEEK + val cycleText = DateExtension.getCycleText(interval) + val firstSpaceIndex = cycleText.indexOf(' ') + + if (firstSpaceIndex != -1) { + withStyle( + style = + SpanStyle( + color = NearTheme.colors.BLACK_1A1A1A, + fontWeight = NearTheme.typography.B2_14_MEDIUM.fontWeight, + ), + ) { + append(cycleText.substring(0, firstSpaceIndex + 1)) + } + withStyle( + style = + SpanStyle( + color = NearTheme.colors.BLUE01_5AA2E9, + fontWeight = NearTheme.typography.B2_14_BOLD.fontWeight, + ), + ) { + append(cycleText.substring(firstSpaceIndex + 1)) + } + } else { + withStyle( + style = + SpanStyle( + color = NearTheme.colors.BLACK_1A1A1A, + fontWeight = NearTheme.typography.B2_14_MEDIUM.fontWeight, + ), + ) { + append(cycleText) + } + } + }, + style = NearTheme.typography.B2_14_MEDIUM, + ) + + Row( + verticalAlignment = Alignment.CenterVertically, + ) { + Spacer(modifier = Modifier.size(20.dp)) + + VerticalDivider( + modifier = + Modifier + .size(width = 1.dp, height = 28.dp), + color = + NearTheme.colors.BLACK_1A1A1A.copy( + alpha = 0.1f, + ), + ) + + Spacer(modifier = Modifier.size(20.dp)) + + Text( + text = + stringResource(R.string.friend_contact_cycle_next_cycle_prefix) + + ( + selectedInterval?.let { DateExtension.getNextCycleDate(it) } + ?: DateExtension.getNextWeekSameDay() + ), + style = NearTheme.typography.B2_14_MEDIUM, + color = NearTheme.colors.GRAY01_888888, + ) + } + } + + Spacer(modifier = Modifier.size(8.dp)) + + ReminderInterval.entries.forEach { interval -> + val isSelected = selectedInterval == interval + + Row( + horizontalArrangement = Arrangement.SpaceBetween, + verticalAlignment = Alignment.CenterVertically, + modifier = + Modifier + .fillMaxWidth() + .onNoRippleClick { + if (!isSelected) { + selectedInterval = interval + } + }.padding(vertical = 15.dp), + ) { + Text( + text = stringResource(interval.labelRes), + style = + if (isSelected) { + NearTheme.typography.B1_16_BOLD + } else { + NearTheme.typography.B2_14_MEDIUM + }, + ) + + if (isSelected) { + NearCheckbox( + checked = true, + onCheckedChange = {}, + ) + } + } + } + Spacer(modifier = Modifier.size(24.dp)) + + ContactCycleButtons( + onLeftButtonClick = onDismiss, + onRightButtonClick = { + selectedInterval?.let { interval -> + onComplete(interval) + onDismiss() + } + }, + leftButtonText = stringResource(R.string.friend_contact_cycle_cancel_button), + rightButtonText = stringResource(R.string.friend_contact_cycle_complete_button), + ) + Spacer(modifier = Modifier.size(24.dp)) + } +} + +@Preview +@Composable +fun CycleSettingBottomSheetPreview() { + NearTheme { + CycleSettingBottomSheet( + isVisible = true, + onDismiss = {}, + ) + } +} + diff --git a/Near/app/src/main/java/com/alarmy/near/presentation/ui/component/bottomsheet/NearBottomSheet.kt b/Near/app/src/main/java/com/alarmy/near/presentation/ui/component/bottomsheet/NearBottomSheet.kt new file mode 100644 index 00000000..191162cf --- /dev/null +++ b/Near/app/src/main/java/com/alarmy/near/presentation/ui/component/bottomsheet/NearBottomSheet.kt @@ -0,0 +1,83 @@ +package com.alarmy.near.presentation.ui.component.bottomsheet + +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.ColumnScope +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.width +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.ModalBottomSheet +import androidx.compose.material3.rememberModalBottomSheetState +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import com.alarmy.near.presentation.ui.theme.NearTheme + +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun NearBottomSheet( + isVisible: Boolean, + onDismiss: () -> Unit, + modifier: Modifier = Modifier, + content: @Composable ColumnScope.() -> Unit, +) { + if (isVisible) { + val bottomSheetState = + rememberModalBottomSheetState( + skipPartiallyExpanded = true, + ) + + ModalBottomSheet( + onDismissRequest = onDismiss, + sheetState = bottomSheetState, + dragHandle = { + Box( + modifier = + Modifier + .fillMaxWidth() + .padding(top = 12.dp, bottom = 24.dp), + contentAlignment = Alignment.Center, + ) { + Box( + modifier = + Modifier + .width(36.dp) + .height(5.dp) + .clip(RoundedCornerShape(2.5.dp)) + .background(NearTheme.colors.BLACK_1A1A1A.copy(alpha = 0.1f)), + ) + } + }, + modifier = modifier, + containerColor = NearTheme.colors.WHITE_FFFFFF, + ) { + Column( + modifier = + Modifier + .fillMaxWidth() + .padding(horizontal = 24.dp), + ) { + content() + } + } + } +} + +@Preview +@Composable +fun NearBottomSheetPreview() { + NearTheme { + NearBottomSheet( + isVisible = true, + onDismiss = { }, + content = {}, + ) + } +} diff --git a/Near/app/src/main/java/com/alarmy/near/presentation/ui/component/textfield/internal/NearSearchTextFieldDecorationBox.kt b/Near/app/src/main/java/com/alarmy/near/presentation/ui/component/textfield/internal/NearSearchTextFieldDecorationBox.kt index 04b3ac0b..04a0a72e 100644 --- a/Near/app/src/main/java/com/alarmy/near/presentation/ui/component/textfield/internal/NearSearchTextFieldDecorationBox.kt +++ b/Near/app/src/main/java/com/alarmy/near/presentation/ui/component/textfield/internal/NearSearchTextFieldDecorationBox.kt @@ -66,6 +66,7 @@ internal fun NearSearchTextFieldDecorationBox( painter = painterResource(id = R.drawable.ic_24_search), contentDescription = "검색", modifier = Modifier.size(24.dp), + tint = NearTheme.colors.GRAY01_888888, ) } } diff --git a/Near/app/src/main/res/drawable/img_64_user_gray.xml b/Near/app/src/main/res/drawable/img_64_user_gray.xml new file mode 100644 index 00000000..dab3a810 --- /dev/null +++ b/Near/app/src/main/res/drawable/img_64_user_gray.xml @@ -0,0 +1,24 @@ + + + + + + + + + diff --git a/Near/app/src/main/res/values/strings.xml b/Near/app/src/main/res/values/strings.xml index b926446c..97d54c0e 100644 --- a/Near/app/src/main/res/values/strings.xml +++ b/Near/app/src/main/res/values/strings.xml @@ -179,6 +179,7 @@ 주기 설정 매주 %1$s 매주 + 다음 주기 : 취소 완료 나중에 하기