From ccba1ff260de90211d564ca36251aa96b3f2b76b Mon Sep 17 00:00:00 2001 From: BEEEAM-J Date: Wed, 4 Mar 2026 23:20:21 +0900 Subject: [PATCH 1/6] =?UTF-8?q?feat:=20Total=20Grade=20Container=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - CchTotalGradeContainer, CchTotalGradeContainerPreview 추가 --- .../home/CchTotalGradeContainerPreview.kt | 18 ++++ .../home/component/CchTotalGradeContainer.kt | 86 +++++++++++++++++++ 2 files changed, 104 insertions(+) create mode 100644 composeApp/src/androidMain/kotlin/com/chukchukhaksa/mobile/preview/component/home/CchTotalGradeContainerPreview.kt create mode 100644 composeApp/src/commonMain/kotlin/com/chukchukhaksa/mobile/presentation/home/component/CchTotalGradeContainer.kt diff --git a/composeApp/src/androidMain/kotlin/com/chukchukhaksa/mobile/preview/component/home/CchTotalGradeContainerPreview.kt b/composeApp/src/androidMain/kotlin/com/chukchukhaksa/mobile/preview/component/home/CchTotalGradeContainerPreview.kt new file mode 100644 index 00000000..29044f50 --- /dev/null +++ b/composeApp/src/androidMain/kotlin/com/chukchukhaksa/mobile/preview/component/home/CchTotalGradeContainerPreview.kt @@ -0,0 +1,18 @@ +package com.chukchukhaksa.mobile.preview.component.home + +import androidx.compose.runtime.Composable +import androidx.compose.ui.tooling.preview.Preview +import com.chukchukhaksa.mobile.common.designsystem.theme.CchTheme +import com.chukchukhaksa.mobile.presentation.home.component.CchTotalGradeContainer + +@Preview(heightDp = 93) +@Composable +fun CchTotalGradeContainerPreview() { + CchTheme { + CchTotalGradeContainer( + totalEarnedCredits = 109, + cumulativeGpa = 3.03, + percentile = 83.2, + ) + } +} diff --git a/composeApp/src/commonMain/kotlin/com/chukchukhaksa/mobile/presentation/home/component/CchTotalGradeContainer.kt b/composeApp/src/commonMain/kotlin/com/chukchukhaksa/mobile/presentation/home/component/CchTotalGradeContainer.kt new file mode 100644 index 00000000..397c8469 --- /dev/null +++ b/composeApp/src/commonMain/kotlin/com/chukchukhaksa/mobile/presentation/home/component/CchTotalGradeContainer.kt @@ -0,0 +1,86 @@ +package com.chukchukhaksa.mobile.presentation.home.component + +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxHeight +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.wrapContentHeight +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material3.Text +import androidx.compose.material3.VerticalDivider +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.unit.dp +import com.chukchukhaksa.mobile.common.designsystem.theme.Black100 +import com.chukchukhaksa.mobile.common.designsystem.theme.CchTheme +import com.chukchukhaksa.mobile.common.designsystem.theme.Purple500 +import com.chukchukhaksa.mobile.common.designsystem.theme.White100 + +@Composable +fun CchTotalGradeContainer( + totalEarnedCredits: Int, + cumulativeGpa: Double, + percentile: Double, +) { + Row( + modifier = Modifier + .clip(RoundedCornerShape(16.dp)) + .background(Black100) + .padding(vertical = 16.dp, horizontal = 29.dp) + .wrapContentHeight(), + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.spacedBy(32.dp) + ) { + CchTotalGradeContainerItem( + title = "취득학점", + value = totalEarnedCredits.toString() + ) + CchTotalGradeContainerDivider() + CchTotalGradeContainerItem( + title = "평점 평균", + value = cumulativeGpa.toString() + ) + CchTotalGradeContainerDivider() + CchTotalGradeContainerItem( + title = "백분위", + value = percentile.toString() + ) + } +} + +@Composable +fun CchTotalGradeContainerItem( + title: String, + value: String, +) { + Column( + modifier = Modifier.fillMaxHeight(), + verticalArrangement = Arrangement.spacedBy(4.dp), + horizontalAlignment = Alignment.CenterHorizontally + ) { + Text( + text = title, + color = White100, + style = CchTheme.typography.bodySm + ) + Text( + text = value, + color = Purple500, + style = CchTheme.typography.bodyExlg + ) + } +} + +@Composable +fun CchTotalGradeContainerDivider() { + VerticalDivider( + modifier = Modifier.padding(vertical = 17.dp), + thickness = 1.dp, + color = Color(0xFF505050) + ) +} From a94b347d6ce551f845f199f6d203c7b79ae79959 Mon Sep 17 00:00:00 2001 From: BEEEAM-J Date: Mon, 9 Mar 2026 22:34:15 +0900 Subject: [PATCH 2/6] =?UTF-8?q?feat:=20Graduation=20Requirements=20Contain?= =?UTF-8?q?er=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - CchGraduationRequirementsContainer.kt, CchGraduationRequirementsContainerPreview.kt, ">" 이미지 추가 --- ...hGraduationRequirementsContainerPreview.kt | 21 +++ .../ic_appbar_arrow_right_chukchuk.xml | 11 ++ .../CchGraduationRequirementsContainer.kt | 123 ++++++++++++++++++ 3 files changed, 155 insertions(+) create mode 100644 composeApp/src/androidMain/kotlin/com/chukchukhaksa/mobile/preview/component/home/CchGraduationRequirementsContainerPreview.kt create mode 100644 composeApp/src/commonMain/composeResources/drawable/ic_appbar_arrow_right_chukchuk.xml create mode 100644 composeApp/src/commonMain/kotlin/com/chukchukhaksa/mobile/presentation/home/component/CchGraduationRequirementsContainer.kt diff --git a/composeApp/src/androidMain/kotlin/com/chukchukhaksa/mobile/preview/component/home/CchGraduationRequirementsContainerPreview.kt b/composeApp/src/androidMain/kotlin/com/chukchukhaksa/mobile/preview/component/home/CchGraduationRequirementsContainerPreview.kt new file mode 100644 index 00000000..d411f4b6 --- /dev/null +++ b/composeApp/src/androidMain/kotlin/com/chukchukhaksa/mobile/preview/component/home/CchGraduationRequirementsContainerPreview.kt @@ -0,0 +1,21 @@ +package com.chukchukhaksa.mobile.preview.component.home + +import androidx.compose.runtime.Composable +import androidx.compose.ui.tooling.preview.Preview +import com.chukchukhaksa.mobile.common.designsystem.theme.CchTheme +import com.chukchukhaksa.mobile.presentation.home.component.CchGraduationRequirementsContainer + +//@Preview(heightDp = 131) +@Preview +@Composable +fun CchGraduationRequirementsContainerPreview() { + CchTheme { + CchGraduationRequirementsContainer( + major = "정보통신학부", + gradeLevel = 18, + totalEarnedCredits = 109, + requiredCredits = 130, + onClickGraduationProgress = {}, + ) + } +} diff --git a/composeApp/src/commonMain/composeResources/drawable/ic_appbar_arrow_right_chukchuk.xml b/composeApp/src/commonMain/composeResources/drawable/ic_appbar_arrow_right_chukchuk.xml new file mode 100644 index 00000000..06f32032 --- /dev/null +++ b/composeApp/src/commonMain/composeResources/drawable/ic_appbar_arrow_right_chukchuk.xml @@ -0,0 +1,11 @@ + + + diff --git a/composeApp/src/commonMain/kotlin/com/chukchukhaksa/mobile/presentation/home/component/CchGraduationRequirementsContainer.kt b/composeApp/src/commonMain/kotlin/com/chukchukhaksa/mobile/presentation/home/component/CchGraduationRequirementsContainer.kt new file mode 100644 index 00000000..5bd1101c --- /dev/null +++ b/composeApp/src/commonMain/kotlin/com/chukchukhaksa/mobile/presentation/home/component/CchGraduationRequirementsContainer.kt @@ -0,0 +1,123 @@ +package com.chukchukhaksa.mobile.presentation.home.component + +import androidx.compose.foundation.Image +import androidx.compose.foundation.background +import androidx.compose.foundation.border +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.wrapContentHeight +import androidx.compose.foundation.shape.CircleShape +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.text.SpanStyle +import androidx.compose.ui.text.buildAnnotatedString +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.text.withStyle +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import chukchukhaksa.composeapp.generated.resources.Res +import chukchukhaksa.composeapp.generated.resources.ic_appbar_arrow_left_chukchuk +import chukchukhaksa.composeapp.generated.resources.ic_appbar_arrow_right_chukchuk +import com.chukchukhaksa.mobile.common.designsystem.theme.Black100 +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.Purple500 +import com.chukchukhaksa.mobile.common.designsystem.theme.Purple600 +import com.chukchukhaksa.mobile.common.designsystem.theme.White100 +import com.chukchukhaksa.mobile.common.ui.cchClickable +import org.jetbrains.compose.resources.painterResource + +@Composable +fun CchGraduationRequirementsContainer( + major: String, + gradeLevel: Int, + totalEarnedCredits: Int, + requiredCredits: Int, + onClickGraduationProgress: () -> Unit +) { + Column( + modifier = Modifier + .clip(RoundedCornerShape(16.dp)) + .background(White100) + .border(1.dp, Gray200, RoundedCornerShape(16.dp)) + .padding(18.dp) + .wrapContentHeight(), + ) { + Text( + modifier = Modifier + .fillMaxWidth() + .padding(bottom = 8.dp), + text = major, + color = Gray400, + style = CchTheme.typography.bodySm, + textAlign = TextAlign.Start + ) + Row( + modifier = Modifier + .fillMaxWidth() + .padding(bottom = 18.dp), + horizontalArrangement = Arrangement.SpaceBetween, + verticalAlignment = Alignment.CenterVertically, + ) { + Text( + text = "${gradeLevel}학번 ${major} 졸업요건", + color = Black100, + style = CchTheme.typography.bodyLgStrong, + ) + Image( + modifier = Modifier + .clip(CircleShape) + .cchClickable(onClick = onClickGraduationProgress), + painter = painterResource(resource = Res.drawable.ic_appbar_arrow_right_chukchuk), + contentDescription = "", + ) + } + Row( + modifier = Modifier.fillMaxWidth(), + horizontalArrangement = Arrangement.SpaceBetween, + verticalAlignment = Alignment.CenterVertically, + ) { + CreaditStatusText(value = totalEarnedCredits) + Text( + text = "$totalEarnedCredits / $requiredCredits", + color = Gray400, + style = CchTheme.typography.bodySm, + ) + } + } +} + +@Composable +fun CreaditStatusText(value: Int) { + val annotatedString = buildAnnotatedString { + append("총 ") + + withStyle( + style = SpanStyle( + color = Purple600, + fontWeight = FontWeight.ExtraBold, + fontSize = 14.sp + ) + ) { + append(value.toString()) + } + + append(" 학점을 이수했어요 \uD83C\uDF89") + } + + Text( + text = annotatedString, + color = Black100, + style = CchTheme.typography.bodySm + ) +} From 6bbd194f975f75e1e1e90363124f86f754b8c517 Mon Sep 17 00:00:00 2001 From: BEEEAM-J Date: Mon, 9 Mar 2026 22:43:09 +0900 Subject: [PATCH 3/6] =?UTF-8?q?feat:=20Semester=20Grade=20Button=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - CchSemesterGradeButton.kt, CchSemesterGradeButtonPreview.kt 추가 --- .../home/CchSemesterGradeButtonPreview.kt | 19 +++++ .../CchGraduationRequirementsContainer.kt | 3 - .../home/component/CchSemesterGradeButton.kt | 69 +++++++++++++++++++ 3 files changed, 88 insertions(+), 3 deletions(-) create mode 100644 composeApp/src/androidMain/kotlin/com/chukchukhaksa/mobile/preview/component/home/CchSemesterGradeButtonPreview.kt create mode 100644 composeApp/src/commonMain/kotlin/com/chukchukhaksa/mobile/presentation/home/component/CchSemesterGradeButton.kt diff --git a/composeApp/src/androidMain/kotlin/com/chukchukhaksa/mobile/preview/component/home/CchSemesterGradeButtonPreview.kt b/composeApp/src/androidMain/kotlin/com/chukchukhaksa/mobile/preview/component/home/CchSemesterGradeButtonPreview.kt new file mode 100644 index 00000000..21f30ab2 --- /dev/null +++ b/composeApp/src/androidMain/kotlin/com/chukchukhaksa/mobile/preview/component/home/CchSemesterGradeButtonPreview.kt @@ -0,0 +1,19 @@ +package com.chukchukhaksa.mobile.preview.component.home + +import androidx.compose.runtime.Composable +import androidx.compose.ui.tooling.preview.Preview +import com.chukchukhaksa.mobile.common.designsystem.theme.CchTheme +import com.chukchukhaksa.mobile.presentation.home.component.CchGraduationRequirementsContainer +import com.chukchukhaksa.mobile.presentation.home.component.CchSemesterGradeButton + +@Preview +@Composable +fun CchSemesterGradeButtonPreview() { + CchTheme { + CchSemesterGradeButton( + startSemester = "1학년 1학기", + endSemester = "3학년 1학기", + onClick = {} + ) + } +} diff --git a/composeApp/src/commonMain/kotlin/com/chukchukhaksa/mobile/presentation/home/component/CchGraduationRequirementsContainer.kt b/composeApp/src/commonMain/kotlin/com/chukchukhaksa/mobile/presentation/home/component/CchGraduationRequirementsContainer.kt index 5bd1101c..7e2fb93d 100644 --- a/composeApp/src/commonMain/kotlin/com/chukchukhaksa/mobile/presentation/home/component/CchGraduationRequirementsContainer.kt +++ b/composeApp/src/commonMain/kotlin/com/chukchukhaksa/mobile/presentation/home/component/CchGraduationRequirementsContainer.kt @@ -11,7 +11,6 @@ import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.wrapContentHeight import androidx.compose.foundation.shape.CircleShape import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment @@ -25,13 +24,11 @@ import androidx.compose.ui.text.withStyle import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import chukchukhaksa.composeapp.generated.resources.Res -import chukchukhaksa.composeapp.generated.resources.ic_appbar_arrow_left_chukchuk import chukchukhaksa.composeapp.generated.resources.ic_appbar_arrow_right_chukchuk import com.chukchukhaksa.mobile.common.designsystem.theme.Black100 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.Purple500 import com.chukchukhaksa.mobile.common.designsystem.theme.Purple600 import com.chukchukhaksa.mobile.common.designsystem.theme.White100 import com.chukchukhaksa.mobile.common.ui.cchClickable diff --git a/composeApp/src/commonMain/kotlin/com/chukchukhaksa/mobile/presentation/home/component/CchSemesterGradeButton.kt b/composeApp/src/commonMain/kotlin/com/chukchukhaksa/mobile/presentation/home/component/CchSemesterGradeButton.kt new file mode 100644 index 00000000..ba172db4 --- /dev/null +++ b/composeApp/src/commonMain/kotlin/com/chukchukhaksa/mobile/presentation/home/component/CchSemesterGradeButton.kt @@ -0,0 +1,69 @@ +package com.chukchukhaksa.mobile.presentation.home.component + +import androidx.compose.foundation.Image +import androidx.compose.foundation.background +import androidx.compose.foundation.border +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.wrapContentHeight +import androidx.compose.foundation.shape.CircleShape +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.unit.dp +import chukchukhaksa.composeapp.generated.resources.Res +import chukchukhaksa.composeapp.generated.resources.ic_appbar_arrow_right_chukchuk +import com.chukchukhaksa.mobile.common.designsystem.theme.Black100 +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.White100 +import com.chukchukhaksa.mobile.common.ui.cchClickable +import org.jetbrains.compose.resources.painterResource + +@Composable +fun CchSemesterGradeButton( + startSemester: String, + endSemester: String, + onClick: () -> Unit +) { + Column( + modifier = Modifier + .clip(RoundedCornerShape(16.dp)) + .background(White100) + .border(1.dp, Gray200, RoundedCornerShape(16.dp)) + .padding(18.dp) + .wrapContentHeight(), + verticalArrangement = Arrangement.spacedBy(18.dp) + ) { + Row( + modifier = Modifier.fillMaxWidth(), + horizontalArrangement = Arrangement.SpaceBetween, + verticalAlignment = Alignment.CenterVertically, + ) { + Text( + text = "학기별 세부 성적 확인하기", + color = Black100, + style = CchTheme.typography.bodyLgStrong, + ) + Image( + modifier = Modifier + .clip(CircleShape) + .cchClickable(onClick = onClick), + painter = painterResource(resource = Res.drawable.ic_appbar_arrow_right_chukchuk), + contentDescription = "", + ) + } + Text( + text = "$startSemester - $endSemester", + color = Gray400, + style = CchTheme.typography.bodySm + ) + } +} From 52c19a99d6b12d3138faa836235b2cb574065cc0 Mon Sep 17 00:00:00 2001 From: BEEEAM-J Date: Thu, 12 Mar 2026 23:31:04 +0900 Subject: [PATCH 4/6] =?UTF-8?q?feat:=20Grade=20Progress=20Container=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - CchGraduationProgressContainer.kt, CchGraduationProgressContainerPreview.kt 추가 --- .../CchGraduationProgressContainerPreview.kt | 60 +++++++ .../drawable/ic_arrow_down_black.xml | 11 ++ .../drawable/ic_arrow_down_white.xml | 11 ++ .../drawable/ic_arrow_up_black.xml | 11 ++ .../drawable/ic_arrow_up_white.xml | 11 ++ .../drawable/ic_check_box.xml | 27 +++ .../mobile/common/ui/GradeColor.kt | 20 +++ .../CchGraduationProgressContainer.kt | 160 ++++++++++++++++++ 8 files changed, 311 insertions(+) create mode 100644 composeApp/src/androidMain/kotlin/com/chukchukhaksa/mobile/preview/component/home/CchGraduationProgressContainerPreview.kt create mode 100644 composeApp/src/commonMain/composeResources/drawable/ic_arrow_down_black.xml create mode 100644 composeApp/src/commonMain/composeResources/drawable/ic_arrow_down_white.xml create mode 100644 composeApp/src/commonMain/composeResources/drawable/ic_arrow_up_black.xml create mode 100644 composeApp/src/commonMain/composeResources/drawable/ic_arrow_up_white.xml create mode 100644 composeApp/src/commonMain/composeResources/drawable/ic_check_box.xml create mode 100644 composeApp/src/commonMain/kotlin/com/chukchukhaksa/mobile/common/ui/GradeColor.kt create mode 100644 composeApp/src/commonMain/kotlin/com/chukchukhaksa/mobile/presentation/home/component/CchGraduationProgressContainer.kt diff --git a/composeApp/src/androidMain/kotlin/com/chukchukhaksa/mobile/preview/component/home/CchGraduationProgressContainerPreview.kt b/composeApp/src/androidMain/kotlin/com/chukchukhaksa/mobile/preview/component/home/CchGraduationProgressContainerPreview.kt new file mode 100644 index 00000000..ad114f60 --- /dev/null +++ b/composeApp/src/androidMain/kotlin/com/chukchukhaksa/mobile/preview/component/home/CchGraduationProgressContainerPreview.kt @@ -0,0 +1,60 @@ +package com.chukchukhaksa.mobile.preview.component.home + +import androidx.compose.runtime.Composable +import androidx.compose.ui.tooling.preview.Preview +import com.chukchukhaksa.mobile.common.designsystem.theme.CchTheme +import com.chukchukhaksa.mobile.common.model.graduation.GraduationProcessCourse +import com.chukchukhaksa.mobile.presentation.home.component.CchGraduationProgressContainer +import com.chukchukhaksa.mobile.presentation.home.component.CchGraduationRequirementsContainer + +//@Preview(heightDp = 131) +@Preview +@Composable +fun CchGraduationProgressContainerPreview() { + val courses = listOf( + GraduationProcessCourse( + courseName = "회로이론", + credits = 2, + grade = "A+", + semester = 10, + year = 2023, + ), + GraduationProcessCourse( + courseName = "회로이론", + credits = 2, + grade = "B+", + semester = 10, + year = 2023, + ), + GraduationProcessCourse( + courseName = "회로이론", + credits = 2, + grade = "C+", + semester = 10, + year = 2023, + ), + GraduationProcessCourse( + courseName = "회로이론", + credits = 2, + grade = "D+", + semester = 10, + year = 2023, + ), + GraduationProcessCourse( + courseName = "회로이론", + credits = 2, + grade = "F", + semester = 10, + year = 2023, + ), + ) + CchTheme { + CchGraduationProgressContainer( + requirementStatus = true, + areaType = "중요핵심", + earnedCredits = 5, + requiredCredits = 6, + courses = courses, + ) + } +} diff --git a/composeApp/src/commonMain/composeResources/drawable/ic_arrow_down_black.xml b/composeApp/src/commonMain/composeResources/drawable/ic_arrow_down_black.xml new file mode 100644 index 00000000..45ac141d --- /dev/null +++ b/composeApp/src/commonMain/composeResources/drawable/ic_arrow_down_black.xml @@ -0,0 +1,11 @@ + + + diff --git a/composeApp/src/commonMain/composeResources/drawable/ic_arrow_down_white.xml b/composeApp/src/commonMain/composeResources/drawable/ic_arrow_down_white.xml new file mode 100644 index 00000000..20e5544e --- /dev/null +++ b/composeApp/src/commonMain/composeResources/drawable/ic_arrow_down_white.xml @@ -0,0 +1,11 @@ + + + diff --git a/composeApp/src/commonMain/composeResources/drawable/ic_arrow_up_black.xml b/composeApp/src/commonMain/composeResources/drawable/ic_arrow_up_black.xml new file mode 100644 index 00000000..a18707b4 --- /dev/null +++ b/composeApp/src/commonMain/composeResources/drawable/ic_arrow_up_black.xml @@ -0,0 +1,11 @@ + + + diff --git a/composeApp/src/commonMain/composeResources/drawable/ic_arrow_up_white.xml b/composeApp/src/commonMain/composeResources/drawable/ic_arrow_up_white.xml new file mode 100644 index 00000000..e4073e08 --- /dev/null +++ b/composeApp/src/commonMain/composeResources/drawable/ic_arrow_up_white.xml @@ -0,0 +1,11 @@ + + + diff --git a/composeApp/src/commonMain/composeResources/drawable/ic_check_box.xml b/composeApp/src/commonMain/composeResources/drawable/ic_check_box.xml new file mode 100644 index 00000000..8e99ecfc --- /dev/null +++ b/composeApp/src/commonMain/composeResources/drawable/ic_check_box.xml @@ -0,0 +1,27 @@ + + + + + + + + diff --git a/composeApp/src/commonMain/kotlin/com/chukchukhaksa/mobile/common/ui/GradeColor.kt b/composeApp/src/commonMain/kotlin/com/chukchukhaksa/mobile/common/ui/GradeColor.kt new file mode 100644 index 00000000..96441b3e --- /dev/null +++ b/composeApp/src/commonMain/kotlin/com/chukchukhaksa/mobile/common/ui/GradeColor.kt @@ -0,0 +1,20 @@ +package com.chukchukhaksa.mobile.common.ui + +import androidx.compose.ui.graphics.Color +import com.chukchukhaksa.mobile.common.designsystem.theme.Black100 +import com.chukchukhaksa.mobile.common.designsystem.theme.Gray500 +import com.chukchukhaksa.mobile.common.designsystem.theme.Green200 +import com.chukchukhaksa.mobile.common.designsystem.theme.Purple600 +import com.chukchukhaksa.mobile.common.designsystem.theme.Red400 +import com.chukchukhaksa.mobile.common.designsystem.theme.Yellow200 + +fun String.gradeColor(): Color { + return when(this) { + "A+", "A0" -> return Red400 + "B+", "B0" -> return Yellow200 + "C+", "C0" -> return Green200 + "D+", "D0", "F" -> return Gray500 + "P" -> return Purple600 + else -> Black100 + } +} diff --git a/composeApp/src/commonMain/kotlin/com/chukchukhaksa/mobile/presentation/home/component/CchGraduationProgressContainer.kt b/composeApp/src/commonMain/kotlin/com/chukchukhaksa/mobile/presentation/home/component/CchGraduationProgressContainer.kt new file mode 100644 index 00000000..fec955d7 --- /dev/null +++ b/composeApp/src/commonMain/kotlin/com/chukchukhaksa/mobile/presentation/home/component/CchGraduationProgressContainer.kt @@ -0,0 +1,160 @@ +package com.chukchukhaksa.mobile.presentation.home.component + +import androidx.compose.animation.animateContentSize +import androidx.compose.animation.core.Spring +import androidx.compose.animation.core.animateFloatAsState +import androidx.compose.animation.core.spring +import androidx.compose.foundation.Image +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.wrapContentHeight +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.draw.rotate +import androidx.compose.ui.unit.dp +import chukchukhaksa.composeapp.generated.resources.Res +import chukchukhaksa.composeapp.generated.resources.ic_arrow_down_black +import chukchukhaksa.composeapp.generated.resources.ic_arrow_down_white +import chukchukhaksa.composeapp.generated.resources.ic_arrow_up_black +import chukchukhaksa.composeapp.generated.resources.ic_arrow_up_white +import chukchukhaksa.composeapp.generated.resources.ic_check_box +import com.chukchukhaksa.mobile.common.designsystem.theme.Black100 +import com.chukchukhaksa.mobile.common.designsystem.theme.CchTheme +import com.chukchukhaksa.mobile.common.designsystem.theme.Gray400 +import com.chukchukhaksa.mobile.common.designsystem.theme.Purple300 +import com.chukchukhaksa.mobile.common.designsystem.theme.Purple500 +import com.chukchukhaksa.mobile.common.designsystem.theme.Purple600 +import com.chukchukhaksa.mobile.common.designsystem.theme.White100 +import com.chukchukhaksa.mobile.common.model.graduation.GraduationProcessCourse +import com.chukchukhaksa.mobile.common.ui.cchClickable +import com.chukchukhaksa.mobile.common.ui.gradeColor +import org.jetbrains.compose.resources.DrawableResource +import org.jetbrains.compose.resources.painterResource + +@Composable +fun CchGraduationProgressContainer( + requirementStatus: Boolean, + areaType: String, + earnedCredits: Int, + requiredCredits: Int, + courses: List, +) { + val isExpanded = remember { mutableStateOf(false) } + val backgroundColor = if (requirementStatus) Black100 else White100 + val areaTypeTextColor = if (requirementStatus) Purple500 else Black100 + val creditTextColor = if (requirementStatus) White100 else Gray400 + val courseTextColor = if (requirementStatus) White100 else Black100 + val courseCreditTextColor = if (requirementStatus) Purple300 else Purple600 + val arrowIcon: DrawableResource = if (requirementStatus) Res.drawable.ic_arrow_down_white else Res.drawable.ic_arrow_down_black + + val rotationAngle by animateFloatAsState( + targetValue = if (isExpanded.value) 180f else 0f, + label = "Rotation" + ) + + Column( + modifier = Modifier + .clip(RoundedCornerShape(16.dp)) + .background(backgroundColor) + .animateContentSize( + animationSpec = spring( + dampingRatio = Spring.DampingRatioLowBouncy, + stiffness = Spring.StiffnessLow + ) + ) + .wrapContentHeight(), + ) { + Row( + modifier = Modifier + .fillMaxWidth() + .cchClickable(onClick = { isExpanded.value = !isExpanded.value }) + .padding(start = 18.dp, end = 18.dp, top = 20.dp, bottom = if(isExpanded.value) 14.dp else 20.dp), + horizontalArrangement = Arrangement.SpaceBetween, + ) { + Row( + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.spacedBy(8.dp), + ) { + Text( + text = areaType, + color = areaTypeTextColor, + style = CchTheme.typography.bodyLgStrong, + ) + Text( + text = "$earnedCredits / $requiredCredits", + color = creditTextColor, + style = CchTheme.typography.bodyMdStrong, + ) + if (requirementStatus) { + Image( + painter = painterResource(resource = Res.drawable.ic_check_box), + contentDescription = "", + ) + } + } + Image( + modifier = Modifier.rotate(rotationAngle), + painter = painterResource(resource = arrowIcon), + contentDescription = "", + ) + } + if (isExpanded.value) { + Column( + modifier = Modifier.padding(bottom = 18.dp, start = 20.dp, end = 20.dp), + verticalArrangement = Arrangement.spacedBy(14.dp), + ) { + courses.forEach { + Row( + modifier = Modifier.fillMaxWidth(), + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.SpaceBetween, + ) { + Row( + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.spacedBy(8.dp), + ) { + Text( + text = it.courseName, + color = courseTextColor, + style = CchTheme.typography.bodyMdStrong, + ) + Text( + text = "${it.year}-${it.semester}", + color = Gray400, + style = CchTheme.typography.bodySm, + ) + } + Row( + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.spacedBy(8.dp), + ) { + Text( + text = "${it.credits}학점", + color = courseCreditTextColor, + style = CchTheme.typography.bodySm, + ) + Text( + text = it.grade, + color = it.grade.gradeColor(), + style = CchTheme.typography.bodySm, + ) + } + } + } + } + } + } + +} From 3a14c1452010b12527d1a5fb131954e01445d789 Mon Sep 17 00:00:00 2001 From: BEEEAM-J Date: Fri, 13 Mar 2026 00:09:48 +0900 Subject: [PATCH 5/6] =?UTF-8?q?feat:=20Course=20Detail=20Container=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - CchCourseDetailContainer.kt, CchCourseDetailContainerPreview.kt 추가 --- .../home/CchCourseDetailContainerPreview.kt | 34 +++++++ .../common/model/academic/AcademicRecord.kt | 23 +---- .../academic/AcademicRecordResponse.kt | 7 +- .../component/CchCourseDetailContainer.kt | 93 +++++++++++++++++++ .../CchGraduationProgressContainer.kt | 3 - 5 files changed, 133 insertions(+), 27 deletions(-) create mode 100644 composeApp/src/androidMain/kotlin/com/chukchukhaksa/mobile/preview/component/home/CchCourseDetailContainerPreview.kt create mode 100644 composeApp/src/commonMain/kotlin/com/chukchukhaksa/mobile/presentation/home/component/CchCourseDetailContainer.kt diff --git a/composeApp/src/androidMain/kotlin/com/chukchukhaksa/mobile/preview/component/home/CchCourseDetailContainerPreview.kt b/composeApp/src/androidMain/kotlin/com/chukchukhaksa/mobile/preview/component/home/CchCourseDetailContainerPreview.kt new file mode 100644 index 00000000..6061c99f --- /dev/null +++ b/composeApp/src/androidMain/kotlin/com/chukchukhaksa/mobile/preview/component/home/CchCourseDetailContainerPreview.kt @@ -0,0 +1,34 @@ +package com.chukchukhaksa.mobile.preview.component.home + +import androidx.compose.runtime.Composable +import androidx.compose.ui.tooling.preview.Preview +import com.chukchukhaksa.mobile.common.designsystem.theme.CchTheme +import com.chukchukhaksa.mobile.common.model.academic.CourseDetail +import com.chukchukhaksa.mobile.presentation.home.component.CchCourseDetailContainer +import com.chukchukhaksa.mobile.presentation.home.component.CchTotalGradeContainer + +@Preview +@Composable +fun CchCourseDetailContainerPreview() { + val course = CourseDetail( + areaType = "전공선택", + courseCode = "09643", + courseName = "모바일프로그래밍", + credits = 3, + grade = "B+", + id = "0", + isOnline = false, + isRetake = false, + isRetakeDelete = true, + originalScore = 40, + professor = "정원용", + score = 94, + semester = 10, + year = 2023, + ) + CchTheme { + CchCourseDetailContainer( + course = course + ) + } +} diff --git a/composeApp/src/commonMain/kotlin/com/chukchukhaksa/mobile/common/model/academic/AcademicRecord.kt b/composeApp/src/commonMain/kotlin/com/chukchukhaksa/mobile/common/model/academic/AcademicRecord.kt index 51f4478c..52f59dd9 100644 --- a/composeApp/src/commonMain/kotlin/com/chukchukhaksa/mobile/common/model/academic/AcademicRecord.kt +++ b/composeApp/src/commonMain/kotlin/com/chukchukhaksa/mobile/common/model/academic/AcademicRecord.kt @@ -6,8 +6,8 @@ data class AcademicRecord( ) data class AcademicRecordCourses( - val liberal: List, - val major: List + val liberal: List, + val major: List ) data class SemesterGrade( @@ -21,24 +21,7 @@ data class SemesterGrade( val year: Int ) -data class Major( - val areaType: String, - val courseCode: String, - val courseName: String, - val credits: Int, - val grade: String, - val id: String, - val isOnline: Boolean, - val isRetake: Boolean, - val isRetakeDelete: Boolean, - val originalScore: Int, - val professor: String, - val score: Int, - val semester: Int, - val year: Int -) - -data class Liberal( +data class CourseDetail( val areaType: String, val courseCode: String, val courseName: String, diff --git a/composeApp/src/commonMain/kotlin/com/chukchukhaksa/mobile/common/model/response/academic/AcademicRecordResponse.kt b/composeApp/src/commonMain/kotlin/com/chukchukhaksa/mobile/common/model/response/academic/AcademicRecordResponse.kt index 590c6e65..cd0934ef 100644 --- a/composeApp/src/commonMain/kotlin/com/chukchukhaksa/mobile/common/model/response/academic/AcademicRecordResponse.kt +++ b/composeApp/src/commonMain/kotlin/com/chukchukhaksa/mobile/common/model/response/academic/AcademicRecordResponse.kt @@ -2,8 +2,7 @@ package com.chukchukhaksa.mobile.common.model.response.academic import com.chukchukhaksa.mobile.common.model.academic.AcademicRecord import com.chukchukhaksa.mobile.common.model.academic.AcademicRecordCourses -import com.chukchukhaksa.mobile.common.model.academic.Liberal -import com.chukchukhaksa.mobile.common.model.academic.Major +import com.chukchukhaksa.mobile.common.model.academic.CourseDetail import com.chukchukhaksa.mobile.common.model.academic.SemesterGrade data class AcademicRecordResponse( @@ -71,7 +70,7 @@ data class MajorData( val semester: Int, val year: Int ) { - fun toMajor() = Major( + fun toMajor() = CourseDetail( areaType = areaType, courseCode = courseCode, courseName = courseName, @@ -105,7 +104,7 @@ data class LiberalData( val semester: Int, val year: Int ) { - fun toLiberal() = Liberal( + fun toLiberal() = CourseDetail( areaType = areaType, courseCode = courseCode, courseName = courseName, diff --git a/composeApp/src/commonMain/kotlin/com/chukchukhaksa/mobile/presentation/home/component/CchCourseDetailContainer.kt b/composeApp/src/commonMain/kotlin/com/chukchukhaksa/mobile/presentation/home/component/CchCourseDetailContainer.kt new file mode 100644 index 00000000..8ac5ba04 --- /dev/null +++ b/composeApp/src/commonMain/kotlin/com/chukchukhaksa/mobile/presentation/home/component/CchCourseDetailContainer.kt @@ -0,0 +1,93 @@ +package com.chukchukhaksa.mobile.presentation.home.component + +import androidx.compose.foundation.background +import androidx.compose.foundation.border +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.wrapContentHeight +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.unit.dp +import com.chukchukhaksa.mobile.common.designsystem.theme.Black100 +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.Red400 +import com.chukchukhaksa.mobile.common.designsystem.theme.White100 +import com.chukchukhaksa.mobile.common.model.academic.CourseDetail +import com.chukchukhaksa.mobile.common.ui.gradeColor + +@Composable +fun CchCourseDetailContainer( + course: CourseDetail +) { + Column( + modifier = Modifier + .clip(RoundedCornerShape(16.dp)) + .background(White100) + .border(1.dp, Gray200, RoundedCornerShape(16.dp)) + .padding(top = 18.dp, bottom = 20.dp, start = 18.dp, end = 18.dp) + .wrapContentHeight(), + ) { + Row( + modifier = Modifier + .fillMaxWidth() + .padding(bottom = 17.dp), + horizontalArrangement = Arrangement.SpaceBetween, + verticalAlignment = Alignment.CenterVertically, + ) { + Text( + text = "${course.courseCode} | ${course.areaType} | ${course.credits}학점", + color = Gray400, + style = CchTheme.typography.bodySm, + ) + Text( + text = "${course.professor} 교수", + color = Gray400, + style = CchTheme.typography.bodySm, + ) + } + Row( + modifier = Modifier + .fillMaxWidth() + .padding(bottom = 8.dp), + horizontalArrangement = Arrangement.SpaceBetween, + verticalAlignment = Alignment.CenterVertically, + ) { + Text( + text = course.courseName, + color = Black100, + style = CchTheme.typography.bodyLgStrong, + ) + Row( + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.spacedBy(6.dp), + ) { + Text( + text = course.grade, + color = course.grade.gradeColor(), + style = CchTheme.typography.bodyLgStrong, + ) + Text( + text = "${course.score}", + color = Black100, + style = CchTheme.typography.bodySm, + ) + } + } + if(course.isRetakeDelete) { + Text( + text = "재수강삭제", + color = Red400, + style = CchTheme.typography.bodySm, + ) + } + } +} diff --git a/composeApp/src/commonMain/kotlin/com/chukchukhaksa/mobile/presentation/home/component/CchGraduationProgressContainer.kt b/composeApp/src/commonMain/kotlin/com/chukchukhaksa/mobile/presentation/home/component/CchGraduationProgressContainer.kt index fec955d7..0b4142b8 100644 --- a/composeApp/src/commonMain/kotlin/com/chukchukhaksa/mobile/presentation/home/component/CchGraduationProgressContainer.kt +++ b/composeApp/src/commonMain/kotlin/com/chukchukhaksa/mobile/presentation/home/component/CchGraduationProgressContainer.kt @@ -7,7 +7,6 @@ import androidx.compose.animation.core.spring import androidx.compose.foundation.Image import androidx.compose.foundation.background import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.fillMaxWidth @@ -27,8 +26,6 @@ import androidx.compose.ui.unit.dp import chukchukhaksa.composeapp.generated.resources.Res import chukchukhaksa.composeapp.generated.resources.ic_arrow_down_black import chukchukhaksa.composeapp.generated.resources.ic_arrow_down_white -import chukchukhaksa.composeapp.generated.resources.ic_arrow_up_black -import chukchukhaksa.composeapp.generated.resources.ic_arrow_up_white import chukchukhaksa.composeapp.generated.resources.ic_check_box import com.chukchukhaksa.mobile.common.designsystem.theme.Black100 import com.chukchukhaksa.mobile.common.designsystem.theme.CchTheme From 06f1b1104cbe8cb94c4df4db860345a8181024d5 Mon Sep 17 00:00:00 2001 From: BEEEAM-J Date: Fri, 13 Mar 2026 00:24:11 +0900 Subject: [PATCH 6/6] =?UTF-8?q?feat:=20CchTotalGradeContainer=20=EB=82=B4?= =?UTF-8?q?=EB=B6=80=20=EA=B0=84=EA=B2=A9=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - spacedBy 32dp -> spaceEvenly 수정 --- .../component/home/CchTotalGradeContainerPreview.kt | 2 +- .../home/component/CchTotalGradeContainer.kt | 10 +++++++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/composeApp/src/androidMain/kotlin/com/chukchukhaksa/mobile/preview/component/home/CchTotalGradeContainerPreview.kt b/composeApp/src/androidMain/kotlin/com/chukchukhaksa/mobile/preview/component/home/CchTotalGradeContainerPreview.kt index 29044f50..a70c939f 100644 --- a/composeApp/src/androidMain/kotlin/com/chukchukhaksa/mobile/preview/component/home/CchTotalGradeContainerPreview.kt +++ b/composeApp/src/androidMain/kotlin/com/chukchukhaksa/mobile/preview/component/home/CchTotalGradeContainerPreview.kt @@ -5,7 +5,7 @@ import androidx.compose.ui.tooling.preview.Preview import com.chukchukhaksa.mobile.common.designsystem.theme.CchTheme import com.chukchukhaksa.mobile.presentation.home.component.CchTotalGradeContainer -@Preview(heightDp = 93) +@Preview @Composable fun CchTotalGradeContainerPreview() { CchTheme { diff --git a/composeApp/src/commonMain/kotlin/com/chukchukhaksa/mobile/presentation/home/component/CchTotalGradeContainer.kt b/composeApp/src/commonMain/kotlin/com/chukchukhaksa/mobile/presentation/home/component/CchTotalGradeContainer.kt index 397c8469..ada7e1b1 100644 --- a/composeApp/src/commonMain/kotlin/com/chukchukhaksa/mobile/presentation/home/component/CchTotalGradeContainer.kt +++ b/composeApp/src/commonMain/kotlin/com/chukchukhaksa/mobile/presentation/home/component/CchTotalGradeContainer.kt @@ -5,6 +5,8 @@ import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.fillMaxHeight +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.wrapContentHeight import androidx.compose.foundation.shape.RoundedCornerShape @@ -32,9 +34,10 @@ fun CchTotalGradeContainer( .clip(RoundedCornerShape(16.dp)) .background(Black100) .padding(vertical = 16.dp, horizontal = 29.dp) + .fillMaxWidth() .wrapContentHeight(), verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.spacedBy(32.dp) + horizontalArrangement = Arrangement.SpaceEvenly ) { CchTotalGradeContainerItem( title = "취득학점", @@ -59,7 +62,6 @@ fun CchTotalGradeContainerItem( value: String, ) { Column( - modifier = Modifier.fillMaxHeight(), verticalArrangement = Arrangement.spacedBy(4.dp), horizontalAlignment = Alignment.CenterHorizontally ) { @@ -79,7 +81,9 @@ fun CchTotalGradeContainerItem( @Composable fun CchTotalGradeContainerDivider() { VerticalDivider( - modifier = Modifier.padding(vertical = 17.dp), + modifier = Modifier + .padding(vertical = 17.dp) + .height(27.dp), thickness = 1.dp, color = Color(0xFF505050) )