Skip to content

Commit aea5aee

Browse files
authored
[MERGE] #66 -> develop
[FEAT/#66] 홈 화면 UI 구현
2 parents 911862d + c13ca9f commit aea5aee

25 files changed

Lines changed: 1270 additions & 13 deletions

‎app/src/main/java/com/cherrish/android/core/common/extension/ModifierExt.kt‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import androidx.compose.ui.input.pointer.pointerInput
2020
import androidx.compose.ui.platform.LocalDensity
2121
import androidx.compose.ui.unit.Dp
2222
import androidx.compose.ui.unit.dp
23+
import com.cherrish.android.core.designsystem.theme.CherrishTheme
2324

2425
@Composable
2526
inline fun Modifier.noRippleClickable(
@@ -45,7 +46,7 @@ fun Modifier.addFocusCleaner(focusManager: FocusManager): Modifier {
4546
@Composable
4647
fun Modifier.dropShadow(
4748
shape: Shape,
48-
color: Color = Color.Black.copy(0.25f),
49+
color: Color = CherrishTheme.colors.shadow,
4950
blur: Dp = 1.dp,
5051
offsetY: Dp = 1.dp,
5152
offsetX: Dp = 1.dp,
Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,15 @@
11
package com.cherrish.android.core.designsystem.component.type
22

3+
import androidx.annotation.DrawableRes
4+
import com.cherrish.android.R
5+
36
enum class CherrishGaugeType(
4-
val step: Int
7+
val step: Int,
8+
val percent: Int,
9+
@DrawableRes val image: Int
510
) {
6-
LEVEL1(1),
7-
LEVEL2(2),
8-
LEVEL3(3),
9-
LEVEL4(4)
11+
LEVEL1(step = 1, percent = 25, image = R.drawable.img_lv1),
12+
LEVEL2(step = 2, percent = 50, image = R.drawable.img_lv2),
13+
LEVEL3(step = 3, percent = 75, image = R.drawable.img_lv3),
14+
LEVEL4(step = 4, percent = 100, image = R.drawable.img_lv4)
1015
}

‎app/src/main/java/com/cherrish/android/core/designsystem/theme/Color.kt‎

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@ val green3 = Color(0xFF9AD342)
3737

3838
val shadow = Color(0xFF9098A7).copy(alpha = 0.12f)
3939

40+
val graStart = Color(0xFFFFF7f7)
41+
val graEnd = Color(0xFFFFFDFD)
42+
4043
val bottomSheetScrimColor = Color(0x1A464C52)
4144

4245
@Immutable
@@ -69,6 +72,9 @@ data class CherrishColors(
6972

7073
val shadow: Color,
7174

75+
val graStart: Color,
76+
val graEnd: Color,
77+
7278
val bottomSheetScrimColor: Color
7379
)
7480

@@ -101,6 +107,9 @@ val defaultCherrishColors = CherrishColors(
101107

102108
shadow = shadow,
103109

110+
graStart = graStart,
111+
graEnd = graEnd,
112+
104113
bottomSheetScrimColor = bottomSheetScrimColor
105114
)
106115

@@ -222,6 +231,16 @@ private fun CherrishGrayColorsPreview() {
222231
style = CherrishTheme.typography.body1M14,
223232
color = CherrishTheme.colors.shadow
224233
)
234+
Text(
235+
text = "GraStart",
236+
style = CherrishTheme.typography.body1M14,
237+
color = CherrishTheme.colors.graStart
238+
)
239+
Text(
240+
text = "GraEnd",
241+
style = CherrishTheme.typography.body1M14,
242+
color = CherrishTheme.colors.graEnd
243+
)
225244
Text(
226245
text = "BottomSheetScrimColor",
227246
style = CherrishTheme.typography.body1M14,
Lines changed: 120 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,138 @@
11
package com.cherrish.android.presentation.home
22

3+
import androidx.compose.foundation.background
4+
import androidx.compose.foundation.layout.Arrangement
5+
import androidx.compose.foundation.layout.Box
36
import androidx.compose.foundation.layout.PaddingValues
7+
import androidx.compose.foundation.layout.fillMaxSize
8+
import androidx.compose.foundation.layout.fillMaxWidth
9+
import androidx.compose.foundation.layout.height
410
import androidx.compose.foundation.layout.padding
5-
import androidx.compose.material3.Text
11+
import androidx.compose.foundation.lazy.LazyColumn
612
import androidx.compose.runtime.Composable
13+
import androidx.compose.runtime.getValue
714
import androidx.compose.ui.Modifier
15+
import androidx.compose.ui.graphics.Brush
16+
import androidx.compose.ui.tooling.preview.Preview
17+
import androidx.compose.ui.unit.dp
18+
import androidx.hilt.navigation.compose.hiltViewModel
19+
import androidx.lifecycle.compose.collectAsStateWithLifecycle
20+
import com.cherrish.android.core.common.state.UiState
21+
import com.cherrish.android.core.designsystem.theme.CherrishTheme
22+
import com.cherrish.android.core.designsystem.theme.graEnd
23+
import com.cherrish.android.core.designsystem.theme.graStart
24+
import com.cherrish.android.presentation.home.component.ChallengeSection
25+
import com.cherrish.android.presentation.home.component.PlanBoxSection
26+
import com.cherrish.android.presentation.home.component.UpcomingPlanSection
27+
import java.time.LocalDate
28+
import kotlinx.collections.immutable.persistentListOf
829

930
@Composable
1031
fun HomeRoute(
11-
paddingValues: PaddingValues
32+
paddingValues: PaddingValues,
33+
viewModel: HomeViewModel = hiltViewModel()
1234
) {
13-
HomeScreen(paddingValues = paddingValues)
35+
val uiState by viewModel.uiState.collectAsStateWithLifecycle()
36+
37+
when (val state = uiState) {
38+
is UiState.Loading -> {
39+
}
40+
41+
is UiState.Failure -> {
42+
}
43+
44+
is UiState.Success -> {
45+
HomeScreen(
46+
uiState = state.data,
47+
paddingValues = paddingValues,
48+
onUpcomingPlanClick = viewModel::onUpcomingPlanClick,
49+
onChallengeStartClick = viewModel::onAddChallengeClick,
50+
onAddPlanClick = viewModel::onAddPlanClick
51+
)
52+
}
53+
54+
else -> {}
55+
}
1456
}
1557

1658
@Composable
1759
private fun HomeScreen(
60+
uiState: HomeUiState,
1861
paddingValues: PaddingValues,
62+
onUpcomingPlanClick: (LocalDate) -> Unit,
63+
onChallengeStartClick: () -> Unit,
64+
onAddPlanClick: () -> Unit,
1965
modifier: Modifier = Modifier
2066
) {
21-
Text(
22-
text = "Home",
23-
modifier = modifier.padding(paddingValues)
24-
)
67+
Box(
68+
modifier = modifier
69+
.fillMaxSize()
70+
.background(color = CherrishTheme.colors.graEnd)
71+
) {
72+
Box(
73+
modifier = Modifier
74+
.fillMaxWidth()
75+
.height(270.dp)
76+
.background(
77+
brush = Brush.verticalGradient(
78+
colors = persistentListOf(
79+
graStart,
80+
graEnd
81+
)
82+
)
83+
)
84+
)
85+
86+
LazyColumn(
87+
modifier = Modifier
88+
.fillMaxSize()
89+
.padding(paddingValues),
90+
contentPadding = PaddingValues(
91+
start = 17.dp,
92+
end = 17.dp,
93+
top = 30.dp,
94+
bottom = 20.dp
95+
),
96+
verticalArrangement = Arrangement.spacedBy(12.dp)
97+
) {
98+
item {
99+
ChallengeSection(
100+
imageRes = uiState.gauges[uiState.selectedIndex].image,
101+
currentStep = uiState.currentStep,
102+
gauges = uiState.gauges,
103+
onChallengeStartClick = onChallengeStartClick,
104+
challengeName = uiState.challengeName
105+
)
106+
}
107+
108+
item {
109+
PlanBoxSection(
110+
todayDate = uiState.todayDate,
111+
plans = uiState.plans
112+
)
113+
}
114+
115+
item {
116+
UpcomingPlanSection(
117+
onAddPlanClick = onAddPlanClick,
118+
plans = uiState.upcomingPlans,
119+
onUpcomingPlanClick = onUpcomingPlanClick
120+
)
121+
}
122+
}
123+
}
124+
}
125+
126+
@Preview(showBackground = true)
127+
@Composable
128+
private fun Preview() {
129+
CherrishTheme {
130+
HomeScreen(
131+
uiState = HomeUiState.fake,
132+
paddingValues = PaddingValues(0.dp),
133+
onUpcomingPlanClick = {},
134+
onAddPlanClick = {},
135+
onChallengeStartClick = {}
136+
)
137+
}
25138
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
package com.cherrish.android.presentation.home
2+
3+
import androidx.compose.runtime.Immutable
4+
import com.cherrish.android.core.designsystem.component.type.CherrishGaugeType
5+
import com.cherrish.android.presentation.home.model.PlanUiModel
6+
import com.cherrish.android.presentation.home.model.UpcomingPlanUiModel
7+
import com.cherrish.android.presentation.home.type.DowntimePhase
8+
import java.time.LocalDate
9+
import kotlinx.collections.immutable.ImmutableList
10+
import kotlinx.collections.immutable.persistentListOf
11+
import kotlinx.collections.immutable.toImmutableList
12+
13+
@Immutable
14+
data class HomeUiState(
15+
val currentStep: Int,
16+
val gauges: ImmutableList<CherrishGaugeType>,
17+
val challengeName: String,
18+
val todayDate: String,
19+
val plans: ImmutableList<PlanUiModel>,
20+
val upcomingPlans: ImmutableList<UpcomingPlanUiModel>,
21+
val selectedIndex: Int
22+
) {
23+
companion object {
24+
val fake = HomeUiState(
25+
currentStep = 1,
26+
gauges = CherrishGaugeType.entries.toImmutableList(),
27+
challengeName = "웰니스 • 마음챙김",
28+
todayDate = "2026년 1월 1일 (목)",
29+
plans = List(10) {
30+
PlanUiModel(
31+
procedureName = "슈링크",
32+
daysSince = 2,
33+
downtimePhase = DowntimePhase.SENSITIVE
34+
)
35+
}.toImmutableList(),
36+
upcomingPlans = persistentListOf(
37+
UpcomingPlanUiModel(
38+
upcomingPlanDate = LocalDate.now().plusDays(3),
39+
procedureName = "써마지",
40+
procedureCount = 2,
41+
dDay = 3
42+
),
43+
UpcomingPlanUiModel(
44+
upcomingPlanDate = LocalDate.now().plusDays(3),
45+
procedureName = "써마지",
46+
procedureCount = 2,
47+
dDay = 3
48+
)
49+
),
50+
selectedIndex = 0
51+
)
52+
}
53+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package com.cherrish.android.presentation.home
2+
3+
import androidx.lifecycle.ViewModel
4+
import com.cherrish.android.core.common.state.UiState
5+
import dagger.hilt.android.lifecycle.HiltViewModel
6+
import java.time.LocalDate
7+
import javax.inject.Inject
8+
import kotlinx.coroutines.flow.MutableStateFlow
9+
import kotlinx.coroutines.flow.StateFlow
10+
import kotlinx.coroutines.flow.asStateFlow
11+
12+
@HiltViewModel
13+
class HomeViewModel @Inject constructor() : ViewModel() {
14+
15+
private val _uiState = MutableStateFlow<UiState<HomeUiState>>(
16+
UiState.Success(HomeUiState.fake)
17+
)
18+
val uiState: StateFlow<UiState<HomeUiState>> = _uiState.asStateFlow()
19+
20+
fun onUpcomingPlanClick(date: LocalDate) {
21+
}
22+
23+
fun onAddChallengeClick() {
24+
}
25+
26+
fun onAddPlanClick() {
27+
}
28+
}

0 commit comments

Comments
 (0)