From 41e24534c3f793cad1f42ea48da5ca004e420514 Mon Sep 17 00:00:00 2001 From: jinsu4755 Date: Wed, 14 Dec 2022 03:46:01 +0900 Subject: [PATCH 1/5] =?UTF-8?q?feat:=20MissionListModel=20=EC=9E=91?= =?UTF-8?q?=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit feature/mission-list --- .../stamp/feature/mission/model/MissionListUiModel.kt | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 app/src/main/java/org/sopt/stamp/feature/mission/model/MissionListUiModel.kt diff --git a/app/src/main/java/org/sopt/stamp/feature/mission/model/MissionListUiModel.kt b/app/src/main/java/org/sopt/stamp/feature/mission/model/MissionListUiModel.kt new file mode 100644 index 0000000..cbb1902 --- /dev/null +++ b/app/src/main/java/org/sopt/stamp/feature/mission/model/MissionListUiModel.kt @@ -0,0 +1,8 @@ +package org.sopt.stamp.feature.mission.model + +import org.sopt.stamp.designsystem.component.mission.model.MissionUiModel + +data class MissionListUiModel( + val title: String, + val missionList: List +) From 1d2b6235dfca2eb05232d54b3445034c29ccfaae Mon Sep 17 00:00:00 2001 From: jinsu4755 Date: Wed, 14 Dec 2022 03:46:31 +0900 Subject: [PATCH 2/5] =?UTF-8?q?feat:=20MissionListScreen=20=ED=8C=8C?= =?UTF-8?q?=EC=9D=BC=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit feature/mission-list --- .../java/org/sopt/stamp/feature/mission/MissionListScreen.kt | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 app/src/main/java/org/sopt/stamp/feature/mission/MissionListScreen.kt diff --git a/app/src/main/java/org/sopt/stamp/feature/mission/MissionListScreen.kt b/app/src/main/java/org/sopt/stamp/feature/mission/MissionListScreen.kt new file mode 100644 index 0000000..93ed44a --- /dev/null +++ b/app/src/main/java/org/sopt/stamp/feature/mission/MissionListScreen.kt @@ -0,0 +1,2 @@ +package org.sopt.stamp.feature.mission + From 7cba6c18cebd634bf2fb2a49c2c7f57d5339d315 Mon Sep 17 00:00:00 2001 From: jinsu4755 Date: Wed, 14 Dec 2022 03:47:25 +0900 Subject: [PATCH 3/5] =?UTF-8?q?feat:=20MissionFilter=20Enum=20=EC=9E=91?= =?UTF-8?q?=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit feature/mission-list --- .../sopt/stamp/feature/mission/MissionFilter.kt | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 app/src/main/java/org/sopt/stamp/feature/mission/MissionFilter.kt diff --git a/app/src/main/java/org/sopt/stamp/feature/mission/MissionFilter.kt b/app/src/main/java/org/sopt/stamp/feature/mission/MissionFilter.kt new file mode 100644 index 0000000..222eb95 --- /dev/null +++ b/app/src/main/java/org/sopt/stamp/feature/mission/MissionFilter.kt @@ -0,0 +1,16 @@ +package org.sopt.stamp.feature.mission + +enum class MissionFilter( + val text: String, + val path: String, + var isSelected: Boolean +) { + ALL("전체 미션", "all", true), + COMPLETE("완료 미션", "complete", false), + INCOMPLETE("미완료 미션", "incomplete", false); + + fun select() { + values().map { it.isSelected = false } + this.isSelected = true + } +} From e9ece75195cf8aa4cd3196ccd0cb659279101362 Mon Sep 17 00:00:00 2001 From: jinsu4755 Date: Wed, 14 Dec 2022 05:22:59 +0900 Subject: [PATCH 4/5] =?UTF-8?q?feat:=20Soptamp=20=EA=B3=B5=ED=86=B5=20?= =?UTF-8?q?=ED=94=8C=EB=A1=9C=ED=8C=85=20=EB=B2=84=ED=8A=BC=20=EC=9E=91?= =?UTF-8?q?=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit feature/mission-list --- .../component/button/SoptampFloatingButton.kt | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 app/src/main/java/org/sopt/stamp/designsystem/component/button/SoptampFloatingButton.kt diff --git a/app/src/main/java/org/sopt/stamp/designsystem/component/button/SoptampFloatingButton.kt b/app/src/main/java/org/sopt/stamp/designsystem/component/button/SoptampFloatingButton.kt new file mode 100644 index 0000000..35dd181 --- /dev/null +++ b/app/src/main/java/org/sopt/stamp/designsystem/component/button/SoptampFloatingButton.kt @@ -0,0 +1,35 @@ +package org.sopt.stamp.designsystem.component.button + +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material.ExtendedFloatingActionButton +import androidx.compose.material.Icon +import androidx.compose.material.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.unit.dp +import org.sopt.stamp.R +import org.sopt.stamp.designsystem.style.SoptTheme + +@Composable +fun SoptampFloatingButton(text: String) { + ExtendedFloatingActionButton( + text = { + Text( + text = text, + color = Color.White, + style = SoptTheme.typography.h2 + ) + }, + icon = { + Icon( + painter = painterResource(id = R.drawable.trophy), + contentDescription = "Extended Floating Action Button Trophy Icon", + tint = Color.White + ) + }, + onClick = { }, + shape = RoundedCornerShape(46.dp), + backgroundColor = SoptTheme.colors.purple300 + ) +} From d41ff945f9ddd6d9e4f1d49652f65be214f00310 Mon Sep 17 00:00:00 2001 From: jinsu4755 Date: Wed, 14 Dec 2022 05:23:28 +0900 Subject: [PATCH 5/5] =?UTF-8?q?feat:=20=EB=AF=B8=EC=85=98=20=EB=A6=AC?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=20Ui=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit feature/mission-list --- .../feature/mission/MissionListScreen.kt | 207 ++++++++++++++++++ 1 file changed, 207 insertions(+) diff --git a/app/src/main/java/org/sopt/stamp/feature/mission/MissionListScreen.kt b/app/src/main/java/org/sopt/stamp/feature/mission/MissionListScreen.kt index 93ed44a..f4a38b8 100644 --- a/app/src/main/java/org/sopt/stamp/feature/mission/MissionListScreen.kt +++ b/app/src/main/java/org/sopt/stamp/feature/mission/MissionListScreen.kt @@ -1,2 +1,209 @@ package org.sopt.stamp.feature.mission +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Box +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.foundation.lazy.grid.GridCells +import androidx.compose.foundation.lazy.grid.LazyVerticalGrid +import androidx.compose.foundation.lazy.grid.items +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material.DropdownMenuItem +import androidx.compose.material.DropdownMenu +import androidx.compose.material.FabPosition +import androidx.compose.material.Scaffold +import androidx.compose.material.Text +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.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.vector.ImageVector +import androidx.compose.ui.res.vectorResource +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.DpOffset +import androidx.compose.ui.unit.dp +import org.sopt.stamp.R +import org.sopt.stamp.designsystem.component.button.SoptampFloatingButton +import org.sopt.stamp.designsystem.component.button.SoptampIconButton +import org.sopt.stamp.designsystem.component.mission.MissionComponent +import org.sopt.stamp.designsystem.component.mission.model.MissionUiModel +import org.sopt.stamp.designsystem.component.topappbar.SoptTopAppBar +import org.sopt.stamp.designsystem.style.SoptTheme +import org.sopt.stamp.domain.MissionLevel +import org.sopt.stamp.feature.mission.model.MissionListUiModel + +@Composable +fun MissionListScreen( + missionListUiModel: MissionListUiModel +) { + Scaffold( + topBar = { + MissionListHeader( + title = missionListUiModel.title, + onMenuClick = {} + ) + }, + floatingActionButton = { SoptampFloatingButton("랭킹 보기") }, + floatingActionButtonPosition = FabPosition.Center + ) { paddingValues -> + Column( + modifier = Modifier.fillMaxSize() + .padding( + top = 0.dp, + bottom = paddingValues.calculateBottomPadding(), + start = 8.dp, + end = 8.dp + ) + ) { + LazyVerticalGrid( + columns = GridCells.Fixed(2) + ) { + items(missionListUiModel.missionList) { missionUiModel -> + MissionComponent( + mission = missionUiModel, + modifier = Modifier.padding(horizontal = 4.dp, vertical = 20.dp) + ) + } + } + } + } +} + +@Composable +fun MissionListHeader( + title: String, + onMenuClick: (MissionFilter) -> Unit = {} +) { + SoptTopAppBar( + title = { MissionListHeaderTitle(title = title) }, + dropDownButton = { DropDownMenuButton() } + ) +} + +@Composable +fun MissionListHeaderTitle( + title: String +) { + Text( + text = title, + color = Color.Black, + style = SoptTheme.typography.h2 + ) +} + +@Composable +fun DropDownMenuButton( + onMenuClick: (MissionFilter) -> Unit = {} +) { + var isMenuExpanded by remember { mutableStateOf(false) } + Box { + SoptampIconButton( + imageVector = if (isMenuExpanded) { + ImageVector.vectorResource(id = R.drawable.up_expand) + } else { + ImageVector.vectorResource(id = R.drawable.down_expand) + } + ) + DropdownMenu( + modifier = Modifier.background( + shape = RoundedCornerShape(10.dp), + color = Color.White + ).padding(vertical = 12.dp), + expanded = isMenuExpanded, + offset = DpOffset((-69).dp, 12.dp), + onDismissRequest = { isMenuExpanded = false } + ) { + MissionFilter.values().forEach { + DropdownMenuItem( + contentPadding = PaddingValues( + horizontal = 20.dp, + vertical = 8.dp + ), + onClick = { + onMenuClick(it) + it.select() + isMenuExpanded = false + } + ) { + Text( + text = it.text, + style = SoptTheme.typography.h3, + color = if (it.isSelected) Color.Black else SoptTheme.colors.onSurface40 + ) + } + } + } + } +} + +@Preview +@Composable +fun PreviewMissionListScreen() { + val missionListUiModel = MissionListUiModel( + title = "완료 미션", + missionList = listOf( + MissionUiModel( + id = 1, + title = "세미나 끝나고 뒷풀이 1시까지 달리기", + level = MissionLevel.of(3), + isCompleted = true + ), + MissionUiModel( + id = 2, + title = "세미나 끝나고 뒷풀이 2시까지 달리기", + level = MissionLevel.of(1), + isCompleted = false + ), + MissionUiModel( + id = 3, + title = "세미나 끝나고 뒷풀이 3시까지 달리기", + level = MissionLevel.of(2), + isCompleted = false + ), + MissionUiModel( + id = 4, + title = "세미나 끝나고 뒷풀이 4시까지 달리기", + level = MissionLevel.of(3), + isCompleted = true + ), + MissionUiModel( + id = 5, + title = "세미나 끝나고 뒷풀이 5시까지 달리기", + level = MissionLevel.of(1), + isCompleted = false + ), + MissionUiModel( + id = 6, + title = "세미나 끝나고 뒷풀이 6시까지 달리기", + level = MissionLevel.of(2), + isCompleted = false + ), + MissionUiModel( + id = 7, + title = "세미나 끝나고 뒷풀이 7시까지 달리기", + level = MissionLevel.of(3), + isCompleted = false + ), + MissionUiModel( + id = 8, + title = "세미나 끝나고 뒷풀이 8시까지 달리기", + level = MissionLevel.of(1), + isCompleted = false + ), + MissionUiModel( + id = 9, + title = "세미나 끝나고 뒷풀이 9시까지 달리기", + level = MissionLevel.of(2), + isCompleted = true + ) + ) + ) + SoptTheme { + MissionListScreen(missionListUiModel) + } +}