Skip to content

Commit 8e0e7e9

Browse files
committed
Feat: 제보 히스토리 UI 구현
1 parent ae7206f commit 8e0e7e9

12 files changed

Lines changed: 552 additions & 0 deletions

File tree

core/designsystem/src/main/java/com/threegap/bitnagil/designsystem/color/BitnagilColors.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,10 @@ data class BitnagilColors(
1212
val error: Color = Error,
1313
val error10: Color = Error10,
1414
val skyBlue10: Color = SkyBlue10,
15+
val blue300: Color = Blue300,
1516
val purple10: Color = Purple10,
1617
val green10: Color = Green10,
18+
val green300: Color = Green300,
1719
val pink10: Color = Pink10,
1820
val yellow10: Color = Yellow10,
1921
val progressBarGradientStartColor: Color = ProgressBarGradientStartColor,

core/designsystem/src/main/java/com/threegap/bitnagil/designsystem/color/Color.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,10 @@ val Kakao = Color(0xFFFEE500)
88
val Error = Color(0xFFFF6868)
99
val Error10 = Color(0xFFFF5858)
1010
val SkyBlue10 = Color(0xFFDBF1FF)
11+
val Blue300 = Color(0xFF0093F5)
1112
val Purple10 = Color(0xFFE6E2FF)
1213
val Green10 = Color(0xFFE6F5C6)
14+
val Green300 = Color(0xFF3FAF00)
1315
val Pink10 = Color(0xFFFEE3E9)
1416
val Yellow10 = Color(0xFFFFF5C7)
1517
val ProgressBarGradientStartColor = Color(0xFFA9CFFF)
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
package com.threegap.bitnagil.designsystem.component.atom
2+
3+
import androidx.compose.foundation.background
4+
import androidx.compose.foundation.layout.Arrangement
5+
import androidx.compose.foundation.layout.Box
6+
import androidx.compose.foundation.layout.Column
7+
import androidx.compose.foundation.layout.height
8+
import androidx.compose.foundation.layout.padding
9+
import androidx.compose.foundation.shape.RoundedCornerShape
10+
import androidx.compose.material3.Text
11+
import androidx.compose.runtime.Composable
12+
import androidx.compose.ui.Alignment
13+
import androidx.compose.ui.Modifier
14+
import androidx.compose.ui.tooling.preview.Preview
15+
import androidx.compose.ui.unit.dp
16+
import com.threegap.bitnagil.designsystem.BitnagilTheme
17+
import com.threegap.bitnagil.designsystem.modifier.clickableWithoutRipple
18+
19+
@Composable
20+
fun BitnagilChip(
21+
title: String,
22+
isSelected: Boolean,
23+
onCategorySelected: () -> Unit,
24+
modifier: Modifier = Modifier,
25+
count: Int? = null,
26+
) {
27+
val chipTitle = if (count == null) title else "$title $count"
28+
29+
Box(
30+
contentAlignment = Alignment.Center,
31+
modifier = modifier
32+
.background(
33+
color = if (!isSelected) BitnagilTheme.colors.white else BitnagilTheme.colors.coolGray10,
34+
shape = RoundedCornerShape(20.dp),
35+
)
36+
.height(36.dp)
37+
.clickableWithoutRipple(onClick = onCategorySelected)
38+
.padding(
39+
vertical = 6.dp,
40+
horizontal = 14.dp,
41+
),
42+
) {
43+
Text(
44+
text = chipTitle,
45+
color = if (!isSelected) BitnagilTheme.colors.coolGray60 else BitnagilTheme.colors.white,
46+
style = if (!isSelected) BitnagilTheme.typography.caption1Medium else BitnagilTheme.typography.caption1SemiBold,
47+
)
48+
}
49+
}
50+
51+
@Preview
52+
@Composable
53+
private fun RecommendCategoryChipStatesPreview() {
54+
Column(
55+
verticalArrangement = Arrangement.spacedBy(8.dp),
56+
) {
57+
BitnagilChip(
58+
title = "맞춤 추천",
59+
isSelected = true,
60+
onCategorySelected = {},
61+
)
62+
63+
BitnagilChip(
64+
title = "나가봐요",
65+
isSelected = false,
66+
onCategorySelected = {},
67+
count = 1,
68+
)
69+
}
70+
}
Lines changed: 179 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,179 @@
1+
package com.threegap.bitnagil.presentation.reporthistory
2+
3+
import androidx.compose.foundation.background
4+
import androidx.compose.foundation.horizontalScroll
5+
import androidx.compose.foundation.layout.Arrangement
6+
import androidx.compose.foundation.layout.Box
7+
import androidx.compose.foundation.layout.Column
8+
import androidx.compose.foundation.layout.PaddingValues
9+
import androidx.compose.foundation.layout.Row
10+
import androidx.compose.foundation.layout.Spacer
11+
import androidx.compose.foundation.layout.fillMaxSize
12+
import androidx.compose.foundation.layout.fillMaxWidth
13+
import androidx.compose.foundation.layout.height
14+
import androidx.compose.foundation.layout.padding
15+
import androidx.compose.foundation.layout.size
16+
import androidx.compose.foundation.layout.statusBarsPadding
17+
import androidx.compose.foundation.layout.width
18+
import androidx.compose.foundation.lazy.LazyColumn
19+
import androidx.compose.foundation.lazy.itemsIndexed
20+
import androidx.compose.foundation.rememberScrollState
21+
import androidx.compose.material3.Text
22+
import androidx.compose.runtime.Composable
23+
import androidx.compose.ui.Alignment
24+
import androidx.compose.ui.Modifier
25+
import androidx.compose.ui.tooling.preview.Preview
26+
import androidx.compose.ui.unit.dp
27+
import com.threegap.bitnagil.designsystem.BitnagilTheme
28+
import com.threegap.bitnagil.designsystem.R
29+
import com.threegap.bitnagil.designsystem.component.atom.BitnagilChip
30+
import com.threegap.bitnagil.designsystem.component.atom.BitnagilIcon
31+
import com.threegap.bitnagil.designsystem.component.block.BitnagilTopBar
32+
import com.threegap.bitnagil.designsystem.modifier.clickableWithoutRipple
33+
import com.threegap.bitnagil.presentation.reporthistory.component.block.ReportHistoryItem
34+
import com.threegap.bitnagil.presentation.reporthistory.model.ReportCategory
35+
import com.threegap.bitnagil.presentation.reporthistory.model.ReportHistoriesPerDayUiModel
36+
import com.threegap.bitnagil.presentation.reporthistory.model.ReportHistoryState
37+
import com.threegap.bitnagil.presentation.reporthistory.model.ReportHistoryUiModel
38+
import com.threegap.bitnagil.presentation.reporthistory.model.ReportProcess
39+
40+
@Composable
41+
fun ReportHistoryScreenContainer() {
42+
}
43+
44+
@Composable
45+
private fun ReportHistoryScreen(
46+
modifier: Modifier = Modifier,
47+
state: ReportHistoryState,
48+
) {
49+
val horizontalScreenState = rememberScrollState()
50+
51+
Column(
52+
modifier = modifier
53+
.fillMaxSize()
54+
.background(color = BitnagilTheme.colors.coolGray99)
55+
.statusBarsPadding(),
56+
) {
57+
BitnagilTopBar(
58+
title = "내 제보 기록",
59+
showBackButton = true,
60+
onBackClick = {},
61+
)
62+
63+
Spacer(modifier = Modifier.height(16.dp))
64+
65+
Row(
66+
modifier = Modifier.horizontalScroll(horizontalScreenState),
67+
horizontalArrangement = Arrangement.spacedBy(8.dp),
68+
) {
69+
Spacer(modifier = Modifier.width(8.dp))
70+
71+
state.reportProcessWithCounts.forEach { reportProcessWithCount ->
72+
BitnagilChip(
73+
title = reportProcessWithCount.process.title,
74+
isSelected = state.selectedReportProcess == reportProcessWithCount.process,
75+
onCategorySelected = {},
76+
count = if (reportProcessWithCount.count == 0) null else reportProcessWithCount.count,
77+
)
78+
}
79+
80+
// chip list
81+
82+
Spacer(modifier = Modifier.width(8.dp))
83+
}
84+
85+
Spacer(modifier = Modifier.height(24.dp))
86+
87+
Box(
88+
modifier = Modifier.weight(1f),
89+
) {
90+
LazyColumn(
91+
modifier = Modifier.fillMaxSize(),
92+
contentPadding = PaddingValues(horizontal = 16.dp),
93+
) {
94+
state.reportHistoriesPerDays.forEach { reportHistoriesPerDay ->
95+
stickyHeader {
96+
Box(
97+
modifier = Modifier
98+
.fillMaxWidth()
99+
.height(40.dp)
100+
.background(color = BitnagilTheme.colors.coolGray99),
101+
) {
102+
Text(
103+
text = reportHistoriesPerDay.date.toString(),
104+
modifier = Modifier.align(Alignment.CenterStart),
105+
style = BitnagilTheme.typography.body2SemiBold,
106+
)
107+
}
108+
}
109+
110+
itemsIndexed(reportHistoriesPerDay.reports) { index, report ->
111+
ReportHistoryItem(
112+
modifier = Modifier.padding(bottom = if (index == reportHistoriesPerDay.reports.lastIndex) 24.dp else 10.dp),
113+
report = report,
114+
onClick = {},
115+
)
116+
}
117+
}
118+
}
119+
120+
Row(
121+
verticalAlignment = Alignment.CenterVertically,
122+
horizontalArrangement = Arrangement.spacedBy(5.dp),
123+
modifier = Modifier
124+
.height(40.dp)
125+
.align(Alignment.TopEnd)
126+
.clickableWithoutRipple { },
127+
) {
128+
Text(
129+
text = "카테고리",
130+
color = BitnagilTheme.colors.coolGray40,
131+
style = BitnagilTheme.typography.body2Medium,
132+
modifier = Modifier.padding(start = 10.dp),
133+
)
134+
135+
BitnagilIcon(
136+
id = R.drawable.ic_down_arrow,
137+
tint = BitnagilTheme.colors.coolGray40,
138+
modifier = Modifier
139+
.padding(end = 13.dp)
140+
.size(16.dp),
141+
)
142+
}
143+
}
144+
}
145+
}
146+
147+
@Composable
148+
@Preview
149+
private fun ReportHistoryScreenPreview() {
150+
BitnagilTheme {
151+
ReportHistoryScreen(
152+
state = ReportHistoryState.Init.copy(
153+
reportHistoriesPerDays = List(10) {
154+
ReportHistoriesPerDayUiModel(
155+
date = java.time.LocalDate.now(),
156+
reports = listOf(
157+
ReportHistoryUiModel(
158+
id = "1",
159+
title = "제보 1",
160+
imageUrl = "-",
161+
location = "서울특별시 성북구 안암로 106",
162+
process = ReportProcess.Reported,
163+
category = ReportCategory.Amenities,
164+
),
165+
ReportHistoryUiModel(
166+
id = "1",
167+
title = "제보 1",
168+
imageUrl = "-",
169+
location = "서울특별시 성북구 안암로 106",
170+
process = ReportProcess.Progress,
171+
category = ReportCategory.Amenities,
172+
),
173+
),
174+
)
175+
},
176+
),
177+
)
178+
}
179+
}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
package com.threegap.bitnagil.presentation.reporthistory.component.atom
2+
3+
import androidx.compose.foundation.background
4+
import androidx.compose.foundation.layout.Arrangement
5+
import androidx.compose.foundation.layout.Column
6+
import androidx.compose.foundation.layout.padding
7+
import androidx.compose.foundation.shape.RoundedCornerShape
8+
import androidx.compose.material3.Text
9+
import androidx.compose.runtime.Composable
10+
import androidx.compose.ui.Modifier
11+
import androidx.compose.ui.graphics.Color
12+
import androidx.compose.ui.tooling.preview.Preview
13+
import androidx.compose.ui.unit.dp
14+
import com.threegap.bitnagil.designsystem.BitnagilTheme
15+
import com.threegap.bitnagil.presentation.reporthistory.model.ReportProcess
16+
17+
@Composable
18+
fun ReportProcessBadge(
19+
modifier: Modifier = Modifier,
20+
reportProcess: ReportProcess,
21+
) {
22+
Text(
23+
text = reportProcess.title,
24+
style = BitnagilTheme.typography.caption1SemiBold,
25+
color = reportProcess.getProcessBadgeTextColor(),
26+
modifier = modifier
27+
.background(color = reportProcess.getProcessBadgeBackgroundColor(), shape = RoundedCornerShape(6.dp))
28+
.padding(horizontal = 10.dp, vertical = 4.dp),
29+
)
30+
}
31+
32+
@Composable
33+
private fun ReportProcess.getProcessBadgeBackgroundColor(): Color =
34+
when (this) {
35+
ReportProcess.Reported -> BitnagilTheme.colors.green10
36+
ReportProcess.Progress -> BitnagilTheme.colors.skyBlue10
37+
else -> BitnagilTheme.colors.coolGray95
38+
}
39+
40+
@Composable
41+
private fun ReportProcess.getProcessBadgeTextColor(): Color =
42+
when (this) {
43+
ReportProcess.Reported -> BitnagilTheme.colors.green300
44+
ReportProcess.Progress -> BitnagilTheme.colors.blue300
45+
else -> BitnagilTheme.colors.coolGray40
46+
}
47+
48+
@Composable
49+
@Preview
50+
private fun ReportProcessBadgePreview() {
51+
BitnagilTheme {
52+
Column(
53+
verticalArrangement = Arrangement.spacedBy(4.dp),
54+
) {
55+
ReportProcessBadge(reportProcess = ReportProcess.Progress)
56+
ReportProcessBadge(reportProcess = ReportProcess.Reported)
57+
ReportProcessBadge(reportProcess = ReportProcess.Complete)
58+
}
59+
}
60+
}

0 commit comments

Comments
 (0)