diff --git a/composeApp/src/commonMain/kotlin/com/chukchukhaksa/mobile/common/designsystem/component/appbar/CchAppBarWithTitle.kt b/composeApp/src/commonMain/kotlin/com/chukchukhaksa/mobile/common/designsystem/component/appbar/CchAppBarWithTitle.kt index cdeab5959..d6695d9d1 100644 --- a/composeApp/src/commonMain/kotlin/com/chukchukhaksa/mobile/common/designsystem/component/appbar/CchAppBarWithTitle.kt +++ b/composeApp/src/commonMain/kotlin/com/chukchukhaksa/mobile/common/designsystem/component/appbar/CchAppBarWithTitle.kt @@ -43,12 +43,14 @@ fun CchAppBarWithTitle( Row( modifier = Modifier .wrapContentWidth() - .height(24.dp) - .clickable { onClickBackButton() }, + .height(24.dp), verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.spacedBy(2.dp) ) { Image( + modifier = Modifier + .clip(CircleShape) + .cchClickable(onClick = onClickBackButton), painter = painterResource(resource = Res.drawable.ic_appbar_arrow_left_chukchuk), contentDescription = "", ) diff --git a/composeApp/src/commonMain/kotlin/com/chukchukhaksa/mobile/common/designsystem/component/textfield/CchRegularTextField.kt b/composeApp/src/commonMain/kotlin/com/chukchukhaksa/mobile/common/designsystem/component/textfield/CchRegularTextField.kt index a3c0836b4..832c9a02f 100644 --- a/composeApp/src/commonMain/kotlin/com/chukchukhaksa/mobile/common/designsystem/component/textfield/CchRegularTextField.kt +++ b/composeApp/src/commonMain/kotlin/com/chukchukhaksa/mobile/common/designsystem/component/textfield/CchRegularTextField.kt @@ -24,6 +24,7 @@ import com.chukchukhaksa.mobile.common.designsystem.theme.CchTheme import com.chukchukhaksa.mobile.common.designsystem.theme.Gray200 import com.chukchukhaksa.mobile.common.designsystem.theme.Gray400 import com.chukchukhaksa.mobile.common.designsystem.theme.Purple600 +import com.chukchukhaksa.mobile.common.designsystem.theme.Red300 import com.chukchukhaksa.mobile.common.designsystem.theme.White100 @Composable @@ -32,13 +33,14 @@ fun CchRegularTextField( value: String = "", placeholder: String = "", isActive: Boolean = false, + isError: Boolean = false, onValueChanged: (String) -> Unit = {}, onClickClearButton: () -> Unit = {} ) { val (borderColor, textColor, textStyle) = if(!isActive) { Triple(Gray200, Gray400, CchTheme.typography.bodyLg) } else { - Triple(Purple600, Black100, CchTheme.typography.bodyLgStrong) + Triple(if (isError) Red300 else Purple600, Black100, CchTheme.typography.bodyLgStrong) } BasicTextField( value = value, diff --git a/composeApp/src/commonMain/kotlin/com/chukchukhaksa/mobile/common/extension/TimetableNameLimit.kt b/composeApp/src/commonMain/kotlin/com/chukchukhaksa/mobile/common/extension/TimetableNameLimit.kt new file mode 100644 index 000000000..fc9fad4cf --- /dev/null +++ b/composeApp/src/commonMain/kotlin/com/chukchukhaksa/mobile/common/extension/TimetableNameLimit.kt @@ -0,0 +1,11 @@ +package com.chukchukhaksa.mobile.common.extension + +const val TIMETABLE_NAME_LIMIT = 20 + +fun checkOverTimetableNameLimit(name: String): Boolean { + return name.trim().length > TIMETABLE_NAME_LIMIT +} + +fun checkTimetableNameRule(name: String): Boolean { + return name.isNotBlank() && name.trim().length <= TIMETABLE_NAME_LIMIT +} diff --git a/composeApp/src/commonMain/kotlin/com/chukchukhaksa/mobile/presentation/timetable/timetableeditor/TimetableEditorContract.kt b/composeApp/src/commonMain/kotlin/com/chukchukhaksa/mobile/presentation/timetable/timetableeditor/TimetableEditorContract.kt index f264dd8a2..2062fc4c3 100644 --- a/composeApp/src/commonMain/kotlin/com/chukchukhaksa/mobile/presentation/timetable/timetableeditor/TimetableEditorContract.kt +++ b/composeApp/src/commonMain/kotlin/com/chukchukhaksa/mobile/presentation/timetable/timetableeditor/TimetableEditorContract.kt @@ -3,6 +3,7 @@ package com.chukchukhaksa.mobile.presentation.timetable.timetableeditor import com.chukchukhaksa.mobile.presentation.timetable.navigation.argument.TimetableEditorArgument import com.chukchukhaksa.mobile.presentation.timetable.semesterselect.semesterList import com.chukchukhaksa.mobile.presentation.timetable.semesterselect.Semester +import com.chukchukhaksa.mobile.common.extension.checkTimetableNameRule data class TimetableEditorState( @@ -13,7 +14,7 @@ data class TimetableEditorState( val selectedSemesterPosition: Int? = null, ) { val semester = selectedSemesterPosition?.let { semesterList.getOrNull(it) } - val buttonEnabled = (name.isNotEmpty() && preName != name || preSelectedSemesterPosition != selectedSemesterPosition) + val buttonEnabled = ((checkTimetableNameRule(name)) && (preName != name || preSelectedSemesterPosition != selectedSemesterPosition)) } internal fun TimetableEditorArgument.toState() = TimetableEditorState( diff --git a/composeApp/src/commonMain/kotlin/com/chukchukhaksa/mobile/presentation/timetable/timetableeditor/TimetableEditorScreen.kt b/composeApp/src/commonMain/kotlin/com/chukchukhaksa/mobile/presentation/timetable/timetableeditor/TimetableEditorScreen.kt index b9df266eb..4ac47fae2 100644 --- a/composeApp/src/commonMain/kotlin/com/chukchukhaksa/mobile/presentation/timetable/timetableeditor/TimetableEditorScreen.kt +++ b/composeApp/src/commonMain/kotlin/com/chukchukhaksa/mobile/presentation/timetable/timetableeditor/TimetableEditorScreen.kt @@ -6,12 +6,15 @@ import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.WindowInsets import androidx.compose.foundation.layout.consumeWindowInsets import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.imePadding import androidx.compose.foundation.layout.navigationBars import androidx.compose.foundation.layout.padding +import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.ui.Modifier +import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp import androidx.lifecycle.compose.collectAsStateWithLifecycle @@ -23,7 +26,10 @@ import com.chukchukhaksa.mobile.common.designsystem.component.bottomsheet.CchSel import com.chukchukhaksa.mobile.common.designsystem.component.button.CchBasicButton import com.chukchukhaksa.mobile.common.designsystem.component.container.CchSelectionButton import com.chukchukhaksa.mobile.common.designsystem.component.textfield.CchRegularTextField +import com.chukchukhaksa.mobile.common.designsystem.theme.CchTheme +import com.chukchukhaksa.mobile.common.designsystem.theme.Red300 import com.chukchukhaksa.mobile.common.designsystem.theme.White +import com.chukchukhaksa.mobile.common.extension.checkOverTimetableNameLimit import com.chukchukhaksa.mobile.common.ui.collectWithLifecycle import com.chukchukhaksa.mobile.presentation.timetable.semesterselect.semesterList import kotlinx.collections.immutable.toPersistentList @@ -100,10 +106,23 @@ fun TimetableEditorScreen( value = uiState.name, placeholder = stringResource(Res.string.create_timetable_screen_placeholder), isActive = uiState.name.isNotEmpty() && uiState.name != uiState.preName, + isError = checkOverTimetableNameLimit(uiState.name), onValueChanged = onValueChangeTimetableName, onClickClearButton = onClickTextFieldClearButton, ) + if (uiState.name.length > 20) { + Text( + modifier = Modifier + .padding(top = 12.dp, start = 4.dp, end = 4.dp) + .fillMaxWidth(), + text = "시간표 이름은 최대 20자까지 설정 가능합니다.", + textAlign = TextAlign.Start, + style = CchTheme.typography.bodyMd, + color = Red300, + ) + } + Spacer(modifier = Modifier.weight(1f)) CchBasicButton( diff --git a/composeApp/src/commonMain/kotlin/com/chukchukhaksa/mobile/presentation/timetable/timetablelist/TimetableListScreen.kt b/composeApp/src/commonMain/kotlin/com/chukchukhaksa/mobile/presentation/timetable/timetablelist/TimetableListScreen.kt index f8b248a7e..93c540705 100644 --- a/composeApp/src/commonMain/kotlin/com/chukchukhaksa/mobile/presentation/timetable/timetablelist/TimetableListScreen.kt +++ b/composeApp/src/commonMain/kotlin/com/chukchukhaksa/mobile/presentation/timetable/timetablelist/TimetableListScreen.kt @@ -104,9 +104,9 @@ fun TimetableListScreen( if (uiState.timetableList.isEmpty()) { Text( modifier = Modifier - .padding(top = 150.dp), + .padding(top = 324.dp), textAlign = TextAlign.Center, - text = stringResource(Res.string.timetable_list_screen_empty_timetable), + text = "등록된 시간표가 없어요!", style = CchTheme.typography.bodyMd, color = Gray600, ) diff --git a/composeApp/src/commonMain/kotlin/com/chukchukhaksa/mobile/presentation/timetable/timetablenameinput/TimetableNameInputContract.kt b/composeApp/src/commonMain/kotlin/com/chukchukhaksa/mobile/presentation/timetable/timetablenameinput/TimetableNameInputContract.kt index 61615cd57..ef4cfbe43 100644 --- a/composeApp/src/commonMain/kotlin/com/chukchukhaksa/mobile/presentation/timetable/timetablenameinput/TimetableNameInputContract.kt +++ b/composeApp/src/commonMain/kotlin/com/chukchukhaksa/mobile/presentation/timetable/timetablenameinput/TimetableNameInputContract.kt @@ -1,7 +1,7 @@ package com.chukchukhaksa.mobile.presentation.timetable.timetablenameinput +import com.chukchukhaksa.mobile.common.extension.checkTimetableNameRule import com.chukchukhaksa.mobile.presentation.timetable.navigation.argument.TimetableEditorArgument -import com.chukchukhaksa.mobile.presentation.timetable.semesterselect.semesterList import com.chukchukhaksa.mobile.presentation.timetable.semesterselect.Semester @@ -9,7 +9,7 @@ data class TimetableNameInputState( val name: String = "", val semester: Semester = Semester("", "") ) { - val buttonEnabled = name.isNotEmpty() + val buttonEnabled = checkTimetableNameRule(name) } internal fun TimetableEditorArgument.toState() = TimetableNameInputState( diff --git a/composeApp/src/commonMain/kotlin/com/chukchukhaksa/mobile/presentation/timetable/timetablenameinput/TimetableNameInputScreen.kt b/composeApp/src/commonMain/kotlin/com/chukchukhaksa/mobile/presentation/timetable/timetablenameinput/TimetableNameInputScreen.kt index 4212d432c..4468e6661 100644 --- a/composeApp/src/commonMain/kotlin/com/chukchukhaksa/mobile/presentation/timetable/timetablenameinput/TimetableNameInputScreen.kt +++ b/composeApp/src/commonMain/kotlin/com/chukchukhaksa/mobile/presentation/timetable/timetablenameinput/TimetableNameInputScreen.kt @@ -6,6 +6,7 @@ import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.WindowInsets import androidx.compose.foundation.layout.consumeWindowInsets import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.imePadding import androidx.compose.foundation.layout.navigationBars import androidx.compose.foundation.layout.padding @@ -28,7 +29,9 @@ import com.chukchukhaksa.mobile.common.designsystem.component.button.CchBasicBut import com.chukchukhaksa.mobile.common.designsystem.component.textfield.CchRegularTextField import com.chukchukhaksa.mobile.common.designsystem.theme.Black100 import com.chukchukhaksa.mobile.common.designsystem.theme.CchTheme +import com.chukchukhaksa.mobile.common.designsystem.theme.Red300 import com.chukchukhaksa.mobile.common.designsystem.theme.White +import com.chukchukhaksa.mobile.common.extension.checkOverTimetableNameLimit import com.chukchukhaksa.mobile.common.ui.collectWithLifecycle import org.jetbrains.compose.resources.getString import org.jetbrains.compose.resources.stringResource @@ -102,10 +105,23 @@ fun TimetableNameInputScreen( value = uiState.name, placeholder = stringResource(Res.string.create_timetable_screen_placeholder), isActive = uiState.name.isNotEmpty(), + isError = checkOverTimetableNameLimit(uiState.name), onValueChanged = onValueChangeTimetableName, onClickClearButton = onClickTextFieldClearButton, ) + if (uiState.name.length > 20) { + Text( + modifier = Modifier + .padding(top = 12.dp, start = 4.dp, end = 4.dp) + .fillMaxWidth(), + text = "시간표 이름은 최대 20자까지 설정 가능합니다.", + textAlign = TextAlign.Start, + style = CchTheme.typography.bodyMd, + color = Red300, + ) + } + Spacer(modifier = Modifier.weight(1f)) CchBasicButton(