-
Notifications
You must be signed in to change notification settings - Fork 0
[FEAT/#26] 캘린더 뷰 조립 #27
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 5 commits
1a942cc
ce326de
8be7954
2c55be0
08d0d4f
4b467d9
51aaa4b
292c583
2f0a7d7
b643530
5427e9a
7418614
e1f014b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,25 +1,130 @@ | ||
| package com.cherrish.android.presentation.calendar | ||
|
|
||
| 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.fillMaxSize | ||
| 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.Alignment | ||
| import androidx.compose.ui.Modifier | ||
| import androidx.compose.ui.tooling.preview.Preview | ||
| import androidx.compose.ui.unit.dp | ||
| import androidx.hilt.navigation.compose.hiltViewModel | ||
| import androidx.lifecycle.compose.collectAsStateWithLifecycle | ||
| import com.cherrish.android.core.common.state.UiState | ||
| import com.cherrish.android.core.designsystem.theme.CherrishTheme | ||
| import com.cherrish.android.presentation.calendar.component.CherrishCalendar | ||
| import com.cherrish.android.presentation.calendar.component.ProcedureScheduleCard | ||
| import java.time.LocalDate | ||
| import java.time.YearMonth | ||
|
|
||
| @Composable | ||
| fun CalendarRoute( | ||
| paddingValues: PaddingValues | ||
| paddingValues: PaddingValues, | ||
| viewModel: CalendarViewModel = hiltViewModel() | ||
| ) { | ||
| CalendarScreen(paddingValues = paddingValues) | ||
| val uiState by viewModel.uiState.collectAsStateWithLifecycle() | ||
|
|
||
| when (val state = uiState) { | ||
| is UiState.Loading -> { | ||
|
|
||
| } | ||
|
|
||
| is UiState.Failure -> { | ||
|
|
||
| } | ||
|
|
||
| is UiState.Success -> { | ||
| CalendarScreen( | ||
| uiState = state.data, | ||
| paddingValues = paddingValues, | ||
| onMonthChange = viewModel::onMonthChanged, | ||
| onDateClick = viewModel::onDateClick, | ||
| onEventClick = viewModel::onEventClick | ||
| ) | ||
| } | ||
|
|
||
| else -> {} | ||
| } | ||
| } | ||
|
|
||
| @Composable | ||
| private fun CalendarScreen( | ||
| paddingValues: PaddingValues, | ||
| uiState: CalendarUiState, | ||
| onMonthChange: (YearMonth) -> Unit, | ||
| onDateClick: (LocalDate) -> Unit, | ||
| onEventClick: (Long) -> Unit, | ||
| modifier: Modifier = Modifier | ||
| ) { | ||
| Text( | ||
| "Calendar", | ||
| modifier = modifier.padding(paddingValues) | ||
| ) | ||
| Column( | ||
| modifier = modifier | ||
| .fillMaxSize() | ||
| .background(color = CherrishTheme.colors.gray100) | ||
| .padding(paddingValues) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. P4: padding이 두 번 들어가있는 것 같은데 이유를 알 수 있을까욥??
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 아하 ㅎㅎ 여기서의 paddingValues는 상위 MainScreen에서 받아오는 패딩값 (Scaffold 의 innerPadding)이 전달되는거고, 아래의 패딩값은 실제 화면에서 보이는 수직, 수평 패딩을 의미합니다!
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 아아 이래서 그래야 하는거군요 !!!저도 리팩토링 요 방식으로 해보겠습니다 !! |
||
| .padding(top = 18.dp, bottom = 26.dp), | ||
| horizontalAlignment = Alignment.CenterHorizontally, | ||
| verticalArrangement = Arrangement.spacedBy(20.dp) | ||
| ) { | ||
| CherrishCalendar( | ||
| yearMonth = uiState.selectedYearMonth, | ||
| selectedDate = uiState.selectedDate, | ||
| displayMode = uiState.calendarDisplayMode, | ||
| onDateClick = onDateClick, | ||
| onMonthChange = onMonthChange, | ||
| modifier = Modifier.padding(horizontal = 5.dp) | ||
| ) | ||
|
|
||
| ProcedureScheduleCard( | ||
| displayMode = uiState.calendarDisplayMode, | ||
| procedureInfo = uiState.procedureInfoList, | ||
| onClick = onEventClick, | ||
| modifier = Modifier.padding(horizontal = 17.dp) | ||
| ) | ||
| } | ||
| } | ||
|
nhyeonii marked this conversation as resolved.
|
||
|
|
||
| @Preview | ||
| @Composable | ||
| private fun CalendarScreenNormalPreview() { | ||
| CherrishTheme { | ||
| CalendarScreen( | ||
| paddingValues = PaddingValues(0.dp), | ||
| uiState = CalendarUiState.FakeNormal, | ||
| onDateClick = { }, | ||
| onMonthChange = { }, | ||
| onEventClick = { } | ||
| ) | ||
| } | ||
| } | ||
|
|
||
| @Preview | ||
| @Composable | ||
| private fun CalendarScreenDowntimePreview() { | ||
| CherrishTheme { | ||
| CalendarScreen( | ||
| paddingValues = PaddingValues(0.dp), | ||
| uiState = CalendarUiState.FakeDowntime, | ||
| onDateClick = { }, | ||
| onMonthChange = { }, | ||
| onEventClick = { } | ||
| ) | ||
| } | ||
| } | ||
|
|
||
| @Preview | ||
| @Composable | ||
| private fun CalendarScreenNoSchedulePreview() { | ||
| CherrishTheme { | ||
| CalendarScreen( | ||
| paddingValues = PaddingValues(0.dp), | ||
| uiState = CalendarUiState.FakeEmpty, | ||
| onDateClick = { }, | ||
| onMonthChange = { }, | ||
| onEventClick = { } | ||
| ) | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,78 @@ | ||
| package com.cherrish.android.presentation.calendar | ||
|
|
||
| import androidx.compose.runtime.Immutable | ||
| import com.cherrish.android.presentation.calendar.model.CalendarDisplayMode | ||
| import com.cherrish.android.presentation.calendar.model.DownTimeStatus | ||
| import com.cherrish.android.presentation.calendar.model.ProcedureInfoModel | ||
| import kotlinx.collections.immutable.ImmutableList | ||
| import kotlinx.collections.immutable.persistentListOf | ||
| import java.time.LocalDate | ||
| import java.time.YearMonth | ||
|
|
||
| @Immutable | ||
| data class CalendarUiState( | ||
| val selectedYearMonth: YearMonth = YearMonth.now(), | ||
| val calendarDisplayMode: CalendarDisplayMode = CalendarDisplayMode.Normal(), | ||
| val selectedDate: LocalDate? = LocalDate.now(), | ||
| val procedureInfoList: ImmutableList<ProcedureInfoModel> = persistentListOf(), | ||
| ) { | ||
| companion object { | ||
| private val today = LocalDate.of(2026, 1, 7) | ||
|
|
||
| private val mockProcedures = persistentListOf( | ||
| ProcedureInfoModel( | ||
| procedureId = 1L, | ||
| procedureName = "레이저 토닝", | ||
| procedureDay = "1월 7일 수요일", | ||
| downTimeDuration = 5 | ||
| ), | ||
| ProcedureInfoModel( | ||
| procedureId = 2L, | ||
| procedureName = "레이저 토닝", | ||
| procedureDay = "1월 7일 수요일", | ||
| downTimeDuration = 5 | ||
| ), | ||
| ProcedureInfoModel( | ||
| procedureId = 3L, | ||
| procedureName = "울쎄라", | ||
| procedureDay = "1월 7일 수요일", | ||
| downTimeDuration = 3 | ||
| ) | ||
| ) | ||
|
|
||
| val FakeNormal = CalendarUiState( | ||
| selectedYearMonth = YearMonth.of(2026, 1), | ||
| calendarDisplayMode = CalendarDisplayMode.Normal( | ||
| procedureCountByDate = mapOf( | ||
| today to 3, | ||
| LocalDate.of(2026, 1, 9) to 1, | ||
| LocalDate.of(2026, 1, 19) to 2 | ||
| ) | ||
| ), | ||
| selectedDate = today, | ||
| procedureInfoList = mockProcedures | ||
| ) | ||
|
|
||
| val FakeDowntime = CalendarUiState( | ||
| selectedYearMonth = YearMonth.of(2026, 1), | ||
| calendarDisplayMode = CalendarDisplayMode.Downtime( | ||
| downtimeByDate = mapOf( | ||
| today to DownTimeStatus.SENSITIVE, | ||
| today.plusDays(1) to DownTimeStatus.SENSITIVE, | ||
| today.plusDays(2) to DownTimeStatus.CAUTION, | ||
| today.plusDays(3) to DownTimeStatus.RECOVERY | ||
| ), | ||
| selectedProcedureId = 1L | ||
| ), | ||
| selectedDate = today, | ||
| procedureInfoList = mockProcedures | ||
| ) | ||
|
|
||
| val FakeEmpty = CalendarUiState( | ||
| selectedYearMonth = YearMonth.of(2026, 1), | ||
| calendarDisplayMode = CalendarDisplayMode.Normal(), | ||
| selectedDate = LocalDate.of(2026, 1, 15), | ||
| procedureInfoList = persistentListOf() | ||
| ) | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,41 @@ | ||
| package com.cherrish.android.presentation.calendar | ||
|
|
||
| import androidx.lifecycle.ViewModel | ||
| import com.cherrish.android.core.common.extension.updateSuccess | ||
| import com.cherrish.android.core.common.state.UiState | ||
| import dagger.hilt.android.lifecycle.HiltViewModel | ||
| import kotlinx.collections.immutable.persistentListOf | ||
| import kotlinx.coroutines.flow.MutableStateFlow | ||
| import kotlinx.coroutines.flow.StateFlow | ||
| import kotlinx.coroutines.flow.asStateFlow | ||
| import java.time.LocalDate | ||
| import java.time.YearMonth | ||
| import javax.inject.Inject | ||
|
|
||
| @HiltViewModel | ||
| class CalendarViewModel @Inject constructor() : ViewModel() { | ||
|
|
||
| private val _uiState = MutableStateFlow<UiState<CalendarUiState>>( | ||
| UiState.Success(CalendarUiState.FakeNormal) | ||
| ) | ||
| val uiState: StateFlow<UiState<CalendarUiState>> = _uiState.asStateFlow() | ||
|
|
||
| fun onMonthChanged(yearMonth: YearMonth) { | ||
| _uiState.updateSuccess { currentState -> | ||
| currentState.copy( | ||
| selectedYearMonth = yearMonth, | ||
| selectedDate = null, | ||
| procedureInfoList = persistentListOf() | ||
| ) | ||
| } | ||
| } | ||
|
|
||
| fun onDateClick(date: LocalDate) { | ||
|
|
||
| } | ||
|
|
||
| fun onEventClick(procedureId: Long) { | ||
|
|
||
| } | ||
|
|
||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,14 +1,15 @@ | ||
| package com.cherrish.android.presentation.calendar.model | ||
|
|
||
| import kotlinx.collections.immutable.persistentMapOf | ||
| import java.time.LocalDate | ||
|
|
||
| sealed interface CalendarDisplayMode { | ||
| data class Normal( | ||
| val procedureCountByDate: Map<LocalDate, Int> | ||
| val procedureCountByDate: Map<LocalDate, Int> = persistentMapOf() | ||
| ) : CalendarDisplayMode | ||
|
|
||
| data class Downtime( | ||
| val downtimeByDate: Map<LocalDate, DownTimeStatus>, | ||
| val downtimeByDate: Map<LocalDate, DownTimeStatus> = persistentMapOf(), | ||
| val selectedProcedureId: Long? = null | ||
| ) : CalendarDisplayMode | ||
| } |
Uh oh!
There was an error while loading. Please reload this page.