Skip to content

[Feature/#188] quiz UI#191

Merged
chanubc merged 19 commits intodevelopfrom
feature/#188-quiz-ui
Oct 24, 2025
Merged

[Feature/#188] quiz UI#191
chanubc merged 19 commits intodevelopfrom
feature/#188-quiz-ui

Conversation

@chanubc
Copy link
Copy Markdown
Member

@chanubc chanubc commented Oct 23, 2025

✅ 𝗖𝗵𝗲𝗰𝗸-𝗟𝗶𝘀𝘁

  • merge할 브랜치의 위치를 확인해 주세요(main❌/develop⭕)
  • 리뷰가 필요한 경우 리뷰어를 지정해 주세요
  • P1 단계의 리뷰는 필수로 반영합니다.
  • Approve된 PR은 assigner가 머지하고, 수정 요청이 온 경우 수정 후 다시 push를 합니다.

📌 𝗜𝘀𝘀𝘂𝗲𝘀

📎𝗪𝗼𝗿𝗸 𝗗𝗲𝘀𝗰𝗿𝗶𝗽𝘁𝗶𝗼𝗻

  • 퀴즈 화면 구현

📷 𝗦𝗰𝗿𝗲𝗲𝗻𝘀𝗵𝗼𝘁

image1 image2 image3

💬 𝗧𝗼 𝗥𝗲𝘃𝗶𝗲𝘄𝗲𝗿𝘀

Summary by CodeRabbit

릴리스 노트

  • 새로운 기능

    • 퀴즈 기능 개선: 새로운 시작 화면과 결과 화면 추가, 통계(경험치, 순위, 속도) 표시
    • 이미지 로딩 컴포넌트 추가
    • 카드 컴포넌트에 클릭 처리 및 배경색 커스터마이징 지원
    • 새로운 색상 팔레트 추가 (파란색, 빨간색 변형)
    • 새로운 타이포그래피 스타일 추가
  • 스타일

    • UI 그래디언트 효과 개선
    • 디자인 시스템 컴포넌트 확장

@chanubc chanubc requested a review from sohyun127 October 23, 2025 20:11
@chanubc chanubc self-assigned this Oct 23, 2025
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Oct 23, 2025

Walkthrough

디자인 시스템에 새로운 색상, 타이포그래피, 컴포넌트를 추가하고, 퀴즈 화면 기능을 구현했습니다. 퀴즈 메인, 시작, 결과 페이지를 조성하고 관련 네비게이션을 확장하였으며, 기존 컴포넌트의 유연성을 강화했습니다.

Changes

콘텐츠 변경 요약
디자인 시스템 기초
core/designsystem/build.gradle.kts, core/ui/src/main/res/values/colors.xml
Landscapist Glide 의존성 추가, 앱 바 색상(app_bar_purple) 추가
색상 및 타이포그래피
core/designsystem/src/main/java/com/teamwable/designsystem/theme/Color.kt, core/designsystem/src/main/java/com/teamwable/designsystem/theme/Type.kt
Blue10, Blue50, Red10 색상 상수 및 WableColors 속성 추가, PriceDownBlack 폰트 페밀리 및 priceDown 텍스트 스타일 추가
카드 및 박스 컴포넌트
core/designsystem/src/main/java/com/teamwable/designsystem/component/card/WableCustomCardWithStroke.kt, core/designsystem/src/main/java/com/teamwable/designsystem/component/card/WableShapeBox.kt
WableCustomCardWithStroke에 모디파이어, onClick, 배경색, 동적 strokeColor 파라미터 추가, radius16Style() 함수 추가
이미지 컴포넌트 및 유틸리티
core/designsystem/src/main/java/com/teamwable/designsystem/component/image/WableImage.kt, core/designsystem/src/main/java/com/teamwable/designsystem/extension/modifier/ModifierExt.kt, core/designsystem/src/main/java/com/teamwable/designsystem/extension/preview/DevicePreviews.kt
WableGlideImage 컴포넌트 추가, wableVerticalGradientBackground 모디파이어 추가, DevicePreviews 애너테이션 추가
퀴즈 스크린 및 라우팅
feature/quiz/src/main/java/com/teamwable/quiz/QuizMainFragment.kt, feature/quiz/src/main/java/com/teamwable/quiz/QuizMainScreen.kt, feature/quiz/src/main/java/com/teamwable/quiz/start/QuizStartFragment.kt, feature/quiz/src/main/java/com/teamwable/quiz/start/QuizStartScreen.kt, feature/quiz/src/main/java/com/teamwable/quiz/result/QuizResultFragment.kt, feature/quiz/src/main/java/com/teamwable/quiz/result/QuizResultScreen.kt
QuizFragment를 QuizMainFragment로 리네이밍, QuizMainScreen 레이아웃 재구성, QuizStartFragment/Screen 추가(O/X 선택 화면), QuizResultFragment/Screen 추가(결과 표시 화면)
퀴즈 컴포넌트 및 타입
feature/quiz/src/main/java/com/teamwable/quiz/component/QuizButton.kt, feature/quiz/src/main/java/com/teamwable/quiz/component/QuizComponent.kt, feature/quiz/src/main/java/com/teamwable/quiz/component/QuizStatType.kt, feature/quiz/src/main/java/com/teamwable/quiz/component/QuizResultType.kt
QuizOXButton 및 OXType 열거형 추가, QuizStatBox 확장 함수 추가, QuizStatType 열거형 추가, QuizResultType 열거형 추가
퀴즈 리소스
feature/quiz/src/main/res/drawable/ic_quiz_o.xml, feature/quiz/src/main/res/drawable/ic_quiz_x.xml, feature/quiz/src/main/res/layout/fragment_quiz_start.xml, feature/quiz/src/main/res/layout/fragment_quiz_result.xml, feature/quiz/src/main/res/navigation/graph_quiz.xml, feature/quiz/src/main/res/values/strings.xml
O/X 아이콘 벡터 드로어블 추가, 퀴즈 레이아웃 파일 추가, 네비게이션 그래프에 3개 프래그먼트 및 액션 추가, 퀴즈 관련 문자열 리소스 추가
네비게이션 및 메인
feature/main/src/main/java/com/teamwable/main/MainActivity.kt
퀴즈 네비게이션 업데이트(navigation_quiz → navigation_quiz_main), 새로운 결과 화면 대상 추가, 상태 바 색상 처리 개선
인증
feature/auth/src/main/java/com/teamwable/auth/LoginScreen.kt
wableVerticalGradientBackground 모디파이어로 수직 그래디언트 리팩토링
온보딩
feature/onboarding/src/main/java/com/teamwable/onboarding/selectlckteam/component/LckTeamItem.kt
lckTeamType 파라미터 추가, 클릭 처리를 WableCustomCardWithStroke의 onClick으로 이동

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant MainActivity
    participant QuizMainFragment
    participant QuizStartFragment
    participant QuizResultFragment
    
    User->>MainActivity: 퀴즈 선택
    activate MainActivity
    MainActivity->>QuizMainFragment: 네비게이션
    deactivate MainActivity
    
    activate QuizMainFragment
    Note over QuizMainFragment: 타이머 카운트다운 표시
    QuizMainFragment->>QuizStartFragment: 시작 버튼 클릭
    deactivate QuizMainFragment
    
    activate QuizStartFragment
    Note over QuizStartFragment: O/X 선택지 표시
    User->>QuizStartFragment: O 또는 X 선택
    QuizStartFragment->>QuizResultFragment: 제출 후 네비게이션
    deactivate QuizStartFragment
    
    activate QuizResultFragment
    Note over QuizResultFragment: 성공/실패 결과 표시<br/>XP, RANK, SPEED 통계
    User->>QuizResultFragment: 확인 버튼 클릭
    QuizResultFragment->>QuizMainFragment: 메인으로 이동
    deactivate QuizResultFragment
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

변경 사항이 다양한 파일에 걸쳐 있지만, 대부분 새로운 기능 추가(퀴즈 화면, 컴포넌트, 열거형)이며 기존 컴포넌트의 파라미터 확장 형태입니다. 디자인 시스템 개선도 일관된 패턴을 따릅니다. 복잡한 로직 밀도는 낮지만, 파일 수와 다양한 리소스 타입(레이아웃, 드로어블, 문자열, 네비게이션)으로 인해 중간 정도의 검토가 필요합니다.

Possibly related PRs

Suggested labels

⭐ [FEAT], 🐻 찬우, 💟 [UI], ☕ [COMPOSE]

Suggested reviewers

  • sohyun127

Poem

🐰 퀴즈의 길을 닦으며,
타이머 울려 시간을 재고,
O와 X가 경쟁하니,
결과 화면은 영광을 비추네!
디자인은 더욱 아름답고,
컴포넌트는 춤을 춘다! 🎨✨

Pre-merge checks and finishing touches

❌ Failed checks (2 warnings)
Check name Status Explanation Resolution
Out of Scope Changes Check ⚠️ Warning PR 분석 결과, feature/auth/src/main/java/com/teamwable/auth/LoginScreen.kt의 수정은 이슈 #188 범위를 벗어나는 변경으로 보입니다. LoginScreen에서 수동 작성된 그래디언트 브러시 코드를 새로 추가된 wableVerticalGradientBackground modifier로 리팩토링한 것은 퀴즈 화면 구현과 직접적인 관련이 없는 기존 화면의 개선사항입니다. 이는 이슈 #188에서 명시된 "퀴즈 화면 구현" 범위를 초과합니다. LoginScreen 리팩토링 변경사항을 별도의 PR로 분리하거나, 이 변경이 필요한 이유를 PR 설명의 "To Reviewers" 섹션에 명확히 기록해야 합니다. 만약 이 변경이 퀴즈 화면 구현의 필수 선행 작업이라면, PR 설명에서 명시적으로 설명하여 범위 내로 재분류할 수 있습니다.
Docstring Coverage ⚠️ Warning Docstring coverage is 7.69% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Title Check ✅ Passed PR 제목 "[Feature/#188] quiz UI"는 changeset의 주요 변경사항을 명확하게 요약하고 있습니다. raw summary를 통해 보면 여러 퀴즈 관련 UI 컴포넌트(QuizOXButton, QuizStatBox, QuizMainScreen 등)와 화면(QuizStartScreen, QuizResultScreen, QuizMainFragment 등)이 추가되었으며, 이는 제목에서 강조된 "quiz UI" 구현과 정확하게 일치합니다. 제목은 간결하면서도 개발자가 변경사항을 빠르게 파악할 수 있도록 명확합니다.
Description Check ✅ Passed PR 설명이 제공된 템플릿 구조를 충실히 따르고 있습니다. 체크리스트 항목들이 포함되어 있으며, 이슈 #188이 명시되고, "퀴즈 화면 구현"이라는 작업 설명과 함께 스크린샷 3개가 첨부되어 있습니다. 템플릿의 주요 필수 섹션들이 모두 채워져 있어 PR의 의도와 작업 범위가 명확합니다.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feature/#188-quiz-ui

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

🧹 Nitpick comments (12)
core/designsystem/src/main/java/com/teamwable/designsystem/component/image/WableImage.kt (2)

23-31: 이미지 로딩 상태 및 에러 처리 추가를 권장합니다.

현재 구현은 이미지 로딩 중이거나 실패했을 때 사용자에게 피드백을 제공하지 않습니다. GlideImageloading, failure 파라미터를 통해 로딩 상태와 에러 상태를 처리할 수 있습니다.

다음과 같이 로딩 및 에러 상태를 추가하는 것을 고려해보세요:

 GlideImage(
     imageModel = { imageUrl },
     imageOptions = ImageOptions(
         contentScale = contentScale,
         alignment = alignment,
     ),
+    loading = {
+        // 로딩 중 표시할 컴포저블 (예: CircularProgressIndicator)
+    },
+    failure = {
+        // 에러 시 표시할 컴포저블 (예: 기본 이미지)
+    },
     previewPlaceholder = painterResource(id = com.teamwable.common.R.drawable.img_empty),
     modifier = modifier.noRippleThrottleClickable(onClick = onClick),
 )

34-43: 프리뷰의 imageUrl을 더 의미있는 값으로 변경하는 것을 고려해보세요.

현재 빈 문자열을 사용하고 있어 프리뷰가 실제 사용 사례를 잘 반영하지 못할 수 있습니다. previewPlaceholder가 표시되겠지만, 실제 URL을 시뮬레이션하는 샘플 URL을 사용하면 더 명확한 프리뷰가 될 것입니다.

 @Preview(showBackground = true)
 @Composable
 private fun WableGlideImagePreview() {
     WableGlideImage(
         modifier = Modifier.size(100.dp),
-        imageUrl = "",
+        imageUrl = "https://example.com/sample-image.jpg",
         contentScale = ContentScale.Crop,
         onClick = {},
     )
 }
core/ui/src/main/res/values/colors.xml (1)

29-30: 앱바 색상 소스 일원화 제안 (XML vs Compose 상수 중복).

app_bar_purple(#FFEBE2FD) 추가가 좋습니다. 다만 core/designsystem/theme/Color.ktSystemLoginSystemAppBar = Color(0xFFEBE2FD)와 값·의미가 중복됩니다. 유지보수 관점에서 한쪽만 “단일 출처”로정리(이름 통일 포함)해 드리프트를 방지해 주세요. 예: XML만 사용하거나, Compose 테마에서만 노출하고 XML은 사용처에서 테마 반영.

feature/quiz/src/main/res/drawable/ic_quiz_o.xml (1)

1-11: 하드코드 색상 대신 리소스 참조 사용 권장.

android:strokeColor="#4699FF"를 공용 팔레트 리소스로 치환하면 테마 변경 시 유지보수가 용이합니다. (예: @color/blue_50). 모듈 종속성상 참조 가능 여부만 확인해 주세요.

가능 시 아래처럼 변경:

-      android:strokeColor="#4699FF"/>
+      android:strokeColor="@color/blue_50"/>
core/designsystem/src/main/java/com/teamwable/designsystem/component/card/WableShapeBox.kt (1)

62-69: 고정 값 API 대신 범용 반경 API 제공 제안.

radius16Style()는 유용하지만 값별 함수가 늘어나는 패턴입니다. 범용 함수로 추출하고 16dp는 별칭으로 유지하면 확장성이 좋아집니다.

아래처럼 리팩터링 제안:

+@Composable
+@ReadOnlyComposable
+fun radiusStyle(radius: Dp) = defaultShapeStyle().copy(
+    topStart = radius,
+    topEnd = radius,
+    bottomStart = radius,
+    bottomEnd = radius,
+)
+
 @Composable
 @ReadOnlyComposable
-fun radius16Style() = defaultShapeStyle().copy(
-    topStart = 16.dp,
-    topEnd = 16.dp,
-    bottomStart = 16.dp,
-    bottomEnd = 16.dp,
-)
+fun radius16Style() = radiusStyle(16.dp)
core/designsystem/src/main/java/com/teamwable/designsystem/extension/preview/DevicePreviews.kt (1)

5-17: 프리뷰 애노테이션의 Target/Retention 지정 권장.

함수에만 적용되도록 @Target(AnnotationTarget.FUNCTION)와 IDE 전용으로 @Retention(AnnotationRetention.SOURCE)를 명시하면 오용을 줄일 수 있습니다.

예시:

 @Preview(
   /* ... */
 )
 @Preview(
   /* ... */
 )
-annotation class DevicePreviews
+@Target(AnnotationTarget.FUNCTION)
+@Retention(AnnotationRetention.SOURCE)
+annotation class DevicePreviews
feature/quiz/src/main/java/com/teamwable/quiz/component/QuizStatType.kt (1)

23-29: Composable 프로퍼티 대신 함수 형태 권장.

val titleColor: Color@Composable 게터를 붙이면 사용자가 비-Composable 문맥에서 오해할 수 있습니다. @Composable fun titleColor(): Color로 바꾸면 사용 맥락이 명확합니다. (호출부 영향은 있으나 유지보수 이점 큼)

제안:

-    val titleColor: Color
-        @Composable
-        get() = when (this) {
+    @Composable
+    fun titleColor(): Color = when (this) {
         XP -> WableTheme.colors.sky50
         RANK -> WableTheme.colors.blue50
         SPEED -> WableTheme.colors.purple50
-        }
+    }
core/designsystem/src/main/java/com/teamwable/designsystem/extension/modifier/ModifierExt.kt (1)

158-177: TileMode.Decal 사용을 확인해주세요.

TileMode.Decal을 사용하면 그라디언트가 gradientEndY를 넘어가는 영역에 타일링되지 않고 마지막 색상으로 채워집니다. 뷰의 높이가 screenHeight * ratio보다 클 경우 의도한 동작인지 확인이 필요합니다.

추가로, 기본 ratio 값 0.514f의 의미를 문서화하는 것을 고려해보세요.

// 예시: 문서화 추가
/**
 * Wable 디자인 시스템의 세로 그라디언트 배경을 적용합니다.
 * 
 * @param ratio 화면 높이 대비 그라디언트가 끝나는 지점의 비율 (기본값: 0.514f는 화면 절반 정도)
 * @param colorStops 그라디언트 색상 정의
 */
@Composable
fun Modifier.wableVerticalGradientBackground(
    ratio: Float = 0.514f,
    colorStops: Array<Pair<Float, Color>> = WableGradientColorStops,
): Modifier {
feature/quiz/src/main/java/com/teamwable/quiz/QuizMainFragment.kt (1)

13-33: 주석 처리된 코드와 미사용 메서드 처리 필요

checkQuizStatus()navigateToStart() 메서드가 정의되어 있지만 주석 처리되어 사용되지 않고 있습니다. 퀴즈 시작 전 상태 확인 로직을 구현할 계획이라면 TODO 주석을 추가하거나, 당장 사용하지 않는다면 코드를 제거하는 것이 좋습니다.

이 부분의 구현을 도와드릴까요? 또는 향후 구현을 위한 이슈를 생성해 드릴까요?

feature/quiz/src/main/java/com/teamwable/quiz/QuizMainScreen.kt (1)

63-63: 타이머 값을 동적으로 처리하도록 구현 필요

현재 "99:99"로 하드코딩되어 있습니다. 향후 실제 타이머 기능 구현 시 상태 관리를 통해 동적으로 업데이트되도록 해야 합니다.

feature/quiz/src/main/java/com/teamwable/quiz/start/QuizStartScreen.kt (1)

71-74: 빈 이미지 URL 처리 필요

imageUrl이 빈 문자열로 설정되어 있습니다. 실제 퀴즈 이미지를 표시할 계획이라면 파라미터로 전달받도록 수정하고, 당장 사용하지 않는다면 placeholder 이미지를 사용하는 것을 고려해주세요.

feature/quiz/src/main/res/navigation/graph_quiz.xml (1)

14-16: tools:layout 속성 추가를 권장합니다.

QuizStartFragment(14-16줄)와 QuizResultFragment(23-26줄)에 tools:layout 속성이 없어서 Android Studio의 레이아웃 미리보기 기능을 사용할 수 없습니다. 코드 일관성과 개발 편의성을 위해 QuizMainFragment처럼 tools:layout 속성을 추가하는 것을 권장합니다.

     <fragment
         android:id="@+id/navigation_quiz_start"
         android:name="com.teamwable.quiz.start.QuizStartFragment"
-        android:label="QuizStartFragment">
+        android:label="QuizStartFragment"
+        tools:layout="@layout/fragment_quiz_start">
     <fragment
         android:id="@+id/navigation_quiz_result"
         android:name="com.teamwable.quiz.result.QuizResultFragment"
-        android:label="QuizResultFragment">
+        android:label="QuizResultFragment"
+        tools:layout="@layout/fragment_quiz_result">

Also applies to: 23-26

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0011c97 and 2d3e2ea.

⛔ Files ignored due to path filters (3)
  • core/designsystem/src/main/res/font/price_down_black.otf is excluded by !**/*.otf
  • feature/quiz/src/main/res/drawable/img_quiz_fail.png is excluded by !**/*.png
  • feature/quiz/src/main/res/drawable/img_quiz_success.png is excluded by !**/*.png
📒 Files selected for processing (28)
  • core/designsystem/build.gradle.kts (1 hunks)
  • core/designsystem/src/main/java/com/teamwable/designsystem/component/card/WableCustomCardWithStroke.kt (1 hunks)
  • core/designsystem/src/main/java/com/teamwable/designsystem/component/card/WableShapeBox.kt (1 hunks)
  • core/designsystem/src/main/java/com/teamwable/designsystem/component/image/WableImage.kt (1 hunks)
  • core/designsystem/src/main/java/com/teamwable/designsystem/extension/modifier/ModifierExt.kt (3 hunks)
  • core/designsystem/src/main/java/com/teamwable/designsystem/extension/preview/DevicePreviews.kt (1 hunks)
  • core/designsystem/src/main/java/com/teamwable/designsystem/theme/Color.kt (7 hunks)
  • core/designsystem/src/main/java/com/teamwable/designsystem/theme/Type.kt (7 hunks)
  • core/ui/src/main/res/values/colors.xml (1 hunks)
  • feature/auth/src/main/java/com/teamwable/auth/LoginScreen.kt (2 hunks)
  • feature/main/src/main/java/com/teamwable/main/MainActivity.kt (4 hunks)
  • feature/onboarding/src/main/java/com/teamwable/onboarding/selectlckteam/component/LckTeamItem.kt (2 hunks)
  • feature/quiz/src/main/java/com/teamwable/quiz/QuizMainFragment.kt (2 hunks)
  • feature/quiz/src/main/java/com/teamwable/quiz/QuizMainScreen.kt (3 hunks)
  • feature/quiz/src/main/java/com/teamwable/quiz/component/QuizButton.kt (1 hunks)
  • feature/quiz/src/main/java/com/teamwable/quiz/component/QuizComponent.kt (1 hunks)
  • feature/quiz/src/main/java/com/teamwable/quiz/component/QuizResultType.kt (1 hunks)
  • feature/quiz/src/main/java/com/teamwable/quiz/component/QuizStatType.kt (1 hunks)
  • feature/quiz/src/main/java/com/teamwable/quiz/result/QuizResultFragment.kt (1 hunks)
  • feature/quiz/src/main/java/com/teamwable/quiz/result/QuizResultScreen.kt (1 hunks)
  • feature/quiz/src/main/java/com/teamwable/quiz/start/QuizStartFragment.kt (1 hunks)
  • feature/quiz/src/main/java/com/teamwable/quiz/start/QuizStartScreen.kt (1 hunks)
  • feature/quiz/src/main/res/drawable/ic_quiz_o.xml (1 hunks)
  • feature/quiz/src/main/res/drawable/ic_quiz_x.xml (1 hunks)
  • feature/quiz/src/main/res/layout/fragment_quiz_result.xml (1 hunks)
  • feature/quiz/src/main/res/layout/fragment_quiz_start.xml (1 hunks)
  • feature/quiz/src/main/res/navigation/graph_quiz.xml (1 hunks)
  • feature/quiz/src/main/res/values/strings.xml (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (8)
feature/quiz/src/main/java/com/teamwable/quiz/component/QuizComponent.kt (1)
core/designsystem/src/main/java/com/teamwable/designsystem/component/card/WableShapeBox.kt (2)
  • WableShapeBox (19-39)
  • radius16Style (62-69)
feature/quiz/src/main/java/com/teamwable/quiz/result/QuizResultFragment.kt (3)
feature/quiz/src/main/java/com/teamwable/quiz/start/QuizStartFragment.kt (1)
  • initComposeView (17-29)
core/designsystem/src/main/java/com/teamwable/designsystem/theme/Theme.kt (1)
  • WableTheme (54-65)
feature/quiz/src/main/java/com/teamwable/quiz/result/QuizResultScreen.kt (1)
  • QuizResultRoute (29-36)
feature/quiz/src/main/java/com/teamwable/quiz/result/QuizResultScreen.kt (3)
feature/quiz/src/main/java/com/teamwable/quiz/component/QuizComponent.kt (1)
  • QuizStatBox (21-53)
core/designsystem/src/main/java/com/teamwable/designsystem/component/button/WableButton.kt (1)
  • WableButton (45-65)
core/designsystem/src/main/java/com/teamwable/designsystem/theme/Theme.kt (1)
  • WableTheme (54-65)
feature/quiz/src/main/java/com/teamwable/quiz/component/QuizButton.kt (3)
core/designsystem/src/main/java/com/teamwable/designsystem/component/card/WableCustomCardWithStroke.kt (1)
  • WableCustomCardWithStroke (15-41)
core/designsystem/src/main/java/com/teamwable/designsystem/extension/composable/ImageExt.kt (1)
  • toImageVector (8-9)
core/designsystem/src/main/java/com/teamwable/designsystem/theme/Theme.kt (1)
  • WableTheme (54-65)
feature/quiz/src/main/java/com/teamwable/quiz/start/QuizStartScreen.kt (5)
core/designsystem/src/main/java/com/teamwable/designsystem/component/topbar/WableTopBar.kt (1)
  • WableAppBar (22-89)
core/designsystem/src/main/java/com/teamwable/designsystem/component/image/WableImage.kt (1)
  • WableGlideImage (15-32)
feature/quiz/src/main/java/com/teamwable/quiz/component/QuizButton.kt (1)
  • QuizOXButton (27-50)
core/designsystem/src/main/java/com/teamwable/designsystem/component/button/WableButton.kt (1)
  • WableButton (45-65)
core/designsystem/src/main/java/com/teamwable/designsystem/theme/Theme.kt (1)
  • WableTheme (54-65)
feature/quiz/src/main/java/com/teamwable/quiz/QuizMainScreen.kt (2)
core/designsystem/src/main/java/com/teamwable/designsystem/component/dot/WableDot.kt (1)
  • WableDot (16-27)
core/designsystem/src/main/java/com/teamwable/designsystem/component/button/WableBoardRequestButton.kt (1)
  • BoardRequestButton (13-24)
feature/main/src/main/java/com/teamwable/main/MainActivity.kt (2)
core/ui/src/main/java/com/teamwable/ui/extensions/ContextExt.kt (1)
  • statusBarModeOf (101-107)
core/ui/src/main/java/com/teamwable/ui/extensions/FragmentExt.kt (1)
  • statusBarModeOf (56-58)
feature/quiz/src/main/java/com/teamwable/quiz/start/QuizStartFragment.kt (3)
feature/quiz/src/main/java/com/teamwable/quiz/result/QuizResultFragment.kt (1)
  • initComposeView (17-28)
core/designsystem/src/main/java/com/teamwable/designsystem/theme/Theme.kt (1)
  • WableTheme (54-65)
feature/quiz/src/main/java/com/teamwable/quiz/start/QuizStartScreen.kt (1)
  • QuizStartRoute (32-41)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: PR Checker
🔇 Additional comments (27)
core/designsystem/src/main/java/com/teamwable/designsystem/theme/Type.kt (2)

204-210: 매우 큰 폰트 크기가 의도된 것인지 확인해주세요.

priceDown 스타일의 폰트 크기가 88.sp로 설정되어 있습니다. 이는 기존 스타일 중 가장 큰 head00(24.sp)의 약 3.7배에 해당하는 매우 큰 크기입니다. 퀴즈 화면의 디자인 스펙과 일치하는지 확인이 필요합니다.


20-20: 폰트 리소스 확인 완료 - 문제 없음

price_down_black.otf 파일이 core/designsystem/src/main/res/font/ 디렉토리에 정상적으로 추가되어 있습니다. 코드의 R.font.price_down_black 참조가 올바르게 해석될 것입니다.

core/designsystem/build.gradle.kts (1)

12-12: LGTM! Glide 이미지 로딩 의존성 추가가 적절합니다.

새로운 WableGlideImage 컴포넌트를 지원하기 위한 Landscapist Glide 번들 추가가 올바르게 구성되었습니다.

core/designsystem/src/main/java/com/teamwable/designsystem/component/image/WableImage.kt (1)

1-14: LGTM! 필요한 import가 모두 적절하게 구성되었습니다.

feature/quiz/src/main/res/values/strings.xml (1)

3-18: 문자열 추가 적절합니다.

UI 맥락에 맞는 키와 복수 화면에서의 재사용성이 좋아 보입니다. 줄바꿈(\n) 의도치 않은 줄바꿈 여부만 화면에서 한번 확인 부탁드립니다.

core/designsystem/src/main/java/com/teamwable/designsystem/theme/Color.kt (1)

17-19: 팔레트/테마 확장 구성 적절합니다.

Blue10/Blue50/Red10 추가 및 WableColors(생성자/프로퍼티/copy/update/factory) 반영이 누락 없이 정합적입니다. 빌드 시 컬러 접근부(예: WableTheme.colors.blue50)가 정상 컴파일되는지만 최종 확인 부탁드립니다. 또한 앱바 색상은 XML app_bar_purple와의 중복(값 동일) 관리를 고려해 주세요.

Also applies to: 107-109, 193-198, 242-245, 289-292, 337-340

feature/onboarding/src/main/java/com/teamwable/onboarding/selectlckteam/component/LckTeamItem.kt (1)

17-17: 리팩토링이 잘 되었습니다!

onClick 핸들링을 modifier 레벨에서 Card 컴포넌트 레벨로 이동한 것은 더 명확하고 의미적으로 적절합니다.

Also applies to: 31-31, 39-39

feature/quiz/src/main/res/drawable/ic_quiz_x.xml (1)

1-18: 벡터 드로어블이 올바르게 구현되었습니다.

X 아이콘이 퀴즈 UI에서 O 아이콘과 쌍을 이루어 사용될 수 있도록 잘 정의되어 있습니다.

feature/quiz/src/main/res/layout/fragment_quiz_result.xml (1)

1-15: 표준 레이아웃 패턴이 잘 적용되었습니다.

ComposeView를 호스팅하는 표준적인 방식으로 구현되어 있으며, 다른 퀴즈 레이아웃과 일관성을 유지하고 있습니다.

feature/auth/src/main/java/com/teamwable/auth/LoginScreen.kt (1)

36-36: 디자인 시스템 통합이 잘 되었습니다!

수동 그라디언트 설정을 공통 modifier로 대체하여 코드 중복을 제거하고 유지보수성을 향상시켰습니다.

Also applies to: 90-90

feature/quiz/src/main/res/layout/fragment_quiz_start.xml (1)

1-15: 일관된 레이아웃 패턴을 유지하고 있습니다.

다른 퀴즈 화면들과 동일한 구조로 구현되어 코드 일관성이 좋습니다.

core/designsystem/src/main/java/com/teamwable/designsystem/extension/modifier/ModifierExt.kt (2)

4-4: 필요한 임포트가 올바르게 추가되었습니다.

그라디언트 구현에 필요한 모든 의존성이 적절하게 임포트되었습니다.

Also applies to: 18-18, 22-22, 26-27


151-156: 그라디언트 컬러 정의가 잘 되어 있습니다.

색상 분포가 적절하며 부드러운 그라디언트를 형성합니다.

feature/quiz/src/main/java/com/teamwable/quiz/component/QuizComponent.kt (1)

21-53: 재사용 가능한 컴포넌트가 잘 구현되었습니다!

RowScope 확장 함수로 구현하여 Row 내에서 동일한 너비를 가진 stat box들을 쉽게 배치할 수 있도록 했습니다. aspectRatio와 weight을 적절히 사용하여 정사각형 형태의 균등 분할이 가능합니다.

feature/quiz/src/main/java/com/teamwable/quiz/start/QuizStartFragment.kt (2)

10-15: Fragment 구조가 올바르게 구현되었습니다.

Hilt 의존성 주입과 BindingFragment 패턴을 적절히 사용하고 있습니다.


17-34: Compose 통합과 내비게이션이 올바르게 구현되었습니다.

ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed를 사용하여 Fragment 생명주기에 맞게 Compose를 관리하고 있으며, Safe Args를 통한 타입 안전한 내비게이션을 구현했습니다.

feature/quiz/src/main/java/com/teamwable/quiz/result/QuizResultFragment.kt (1)

1-34: LGTM! 잘 구현되었습니다.

프래그먼트 구조와 네비게이션 패턴이 프로젝트의 다른 퀴즈 화면들(QuizStartFragment)과 일관성 있게 구현되어 있습니다.

feature/main/src/main/java/com/teamwable/main/MainActivity.kt (2)

149-150: LGTM! 퀴즈 화면에서 하단 네비게이션 숨김 처리가 올바릅니다.

퀴즈 시작 및 결과 화면에서 하단 네비게이션을 숨기는 것이 UX 관점에서 적절합니다.


218-241: LGTM! 퀴즈 화면별 상태 바 색상 처리가 잘 구현되었습니다.

각 퀴즈 화면(메인, 결과)에 맞는 상태 바 색상과 모드가 적절하게 설정되어 있습니다.

feature/quiz/src/main/java/com/teamwable/quiz/result/QuizResultScreen.kt (1)

29-36: LGTM! Route 패턴이 올바릅니다.

네비게이션 콜백을 화면으로 전달하는 구조가 깔끔하게 구현되었습니다.

feature/quiz/src/main/java/com/teamwable/quiz/component/QuizResultType.kt (1)

1-32: LGTM! 깔끔한 enum 구현입니다.

리소스 타입 안정성을 위한 어노테이션 사용과 when 표현식을 통한 타입별 리소스 매핑이 잘 구현되었습니다.

feature/quiz/src/main/java/com/teamwable/quiz/QuizMainScreen.kt (1)

30-69: LGTM! 레이아웃 리팩토링이 잘 되었습니다.

SpaceBetween을 사용한 수직 배치와 Box를 이용한 타이머 오버레이 구현이 깔끔합니다.

feature/quiz/src/main/java/com/teamwable/quiz/start/QuizStartScreen.kt (1)

32-41: LGTM! Route 구현이 올바릅니다.

네비게이션 콜백 전달이 명확하게 구현되었습니다.

feature/quiz/src/main/java/com/teamwable/quiz/component/QuizButton.kt (2)

27-50: LGTM! 재사용 가능한 컴포넌트 구현이 우수합니다.

선택 상태에 따른 동적 스타일링이 잘 구현되었으며, 타입 안전성을 위한 enum 활용이 좋습니다.


52-83: LGTM! enum 설계가 훌륭합니다.

테마 색상을 위한 @Composable 속성 사용과 타입별 커스텀 패딩 설정이 잘 구현되었습니다.

feature/quiz/src/main/res/navigation/graph_quiz.xml (2)

6-6: 퀴즈 메인 화면을 시작 목적지로 설정한 것이 적절합니다.

QuizMainFragment를 시작 목적지로 설정하는 것은 사용자가 퀴즈 기능에 진입할 때 메인 화면부터 시작하도록 하는 직관적인 흐름입니다.


27-31: 결과 화면에서 전체 그래프를 팝업하는 동작을 검증해주세요.

28-31줄에서 QuizResultFragment에서 QuizMainFragment로 이동할 때 app:popUpTo="@id/graph_quiz"app:popUpToInclusive="true"를 사용합니다. 이는 전체 네비게이션 백스택을 제거하는 동작입니다. 이것이 의도적인 설계인지, 아니면 @id/navigation_quiz_start로 변경되어야 하는지 확인해주세요. 만약 사용자가 퀴즈 결과 화면에서 뒤로 가기를 누르면 앱이 종료될 수 있습니다.

Comment on lines +17 to 26
modifier: Modifier = Modifier,
connerRadius: Dp = 8.dp,
strokeWidth: Dp = 1.dp,
strokeColor: Color = WableTheme.colors.gray300,
strokeColor: @Composable (Boolean) -> Color = { enabled ->
if (enabled) WableTheme.colors.purple50 else WableTheme.colors.gray300
},
backGroundColor: Color = WableTheme.colors.white,
enabled: Boolean = false,
onClick: () -> Unit = {},
content: @Composable () -> Unit,
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion | 🟠 Major

공개 API 파라미터 오타 수정 권장: corner/background.

connerRadiuscornerRadius, backGroundColorbackgroundColor. 공개 API이므로 지금 정정하는 편이 장기적으로 이득입니다. (필요 시 @deprecated 대체자 제공)

제안 diff:

-    connerRadius: Dp = 8.dp,
+    cornerRadius: Dp = 8.dp,
@@
-    backGroundColor: Color = WableTheme.colors.white,
+    backgroundColor: Color = WableTheme.colors.white,

사용부:

-        shape = RoundedCornerShape(connerRadius),
+        shape = RoundedCornerShape(cornerRadius),
@@
-            containerColor = backGroundColor,
+            containerColor = backgroundColor,

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In
core/designsystem/src/main/java/com/teamwable/designsystem/component/card/WableCustomCardWithStroke.kt
around lines 17 to 26, the public API parameter names have typos: "connerRadius"
should be renamed to "cornerRadius" and "backGroundColor" to "backgroundColor";
update the function signature and all internal usages to the corrected names,
and add short @Deprecated aliases with the old names (pointing to the new names)
to preserve binary/source compatibility for callers while encouraging migration.

Comment on lines +37 to 38
modifier = modifier.noRippleClickable(onClick = onClick),
) {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

enabled=false인데도 클릭 가능한 문제.

modifier.noRippleClickable(onClick = onClick)enabled와 연동되지 않아 비활성 상태에서도 클릭됩니다. 클릭 가드가 필요합니다.

다음 둘 중 하나를 적용해 주세요(사용중인 확장 함수 시그니처에 맞춰 선택):

-        modifier = modifier.noRippleClickable(onClick = onClick),
+        modifier = if (enabled) modifier.noRippleClickable(onClick = onClick) else modifier,

또는(시그니처가 지원한다면):

-        modifier = modifier.noRippleClickable(onClick = onClick),
+        modifier = modifier.noRippleClickable(enabled = enabled, onClick = onClick),

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In
core/designsystem/src/main/java/com/teamwable/designsystem/component/card/WableCustomCardWithStroke.kt
around lines 37-38, the current modifier uses modifier.noRippleClickable(onClick
= onClick) which ignores the component's enabled state and allows clicks when
disabled; update it so clicks are blocked when enabled==false. Fix by either
using the extension that accepts an enabled flag (e.g.,
modifier.noRippleClickable(enabled = enabled, onClick = onClick)) if that
signature exists, or wrap the clickable application to only add the
noRippleClickable when enabled is true and otherwise leave the modifier
unmodified (or add a non-clickable fallback) so disabled cards cannot be
clicked.

Comment on lines +23 to +31
GlideImage(
imageModel = { imageUrl },
imageOptions = ImageOptions(
contentScale = contentScale,
alignment = alignment,
),
previewPlaceholder = painterResource(id = com.teamwable.common.R.drawable.img_empty),
modifier = modifier.noRippleThrottleClickable(onClick = onClick),
)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

접근성을 위한 contentDescription 추가가 필요합니다.

이미지 컴포넌트에 contentDescription이 없어 스크린 리더 사용자가 이미지의 내용을 알 수 없습니다. 접근성 지원을 위해 contentDescription 파라미터를 추가해야 합니다.

다음과 같이 수정하는 것을 권장합니다:

 @Composable
 fun WableGlideImage(
     modifier: Modifier = Modifier,
     imageUrl: String,
+    contentDescription: String?,
     contentScale: ContentScale = ContentScale.Crop,
     alignment: Alignment = Alignment.Center,
     onClick: () -> Unit = {},
 ) {
     GlideImage(
         imageModel = { imageUrl },
         imageOptions = ImageOptions(
             contentScale = contentScale,
             alignment = alignment,
+            contentDescription = contentDescription,
         ),
         previewPlaceholder = painterResource(id = com.teamwable.common.R.drawable.img_empty),
         modifier = modifier.noRippleThrottleClickable(onClick = onClick),
     )
 }

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In
core/designsystem/src/main/java/com/teamwable/designsystem/component/image/WableImage.kt
around lines 23-31, the GlideImage call is missing a contentDescription which
breaks accessibility; add a contentDescription parameter to the WableImage
composable (e.g., contentDescription: String? = null), update all WableImage
callers as needed (or keep default null for backwards compatibility), and pass
that value into GlideImage’s contentDescription parameter so screen readers
receive the descriptive text (use null for purely decorative images).

Comment on lines +81 to +95
QuizStatBox(
title = stringResource(id = QuizStatType.XP.title),
titleColor = QuizStatType.XP.titleColor,
value = "8",
)
QuizStatBox(
title = stringResource(id = QuizStatType.RANK.title),
titleColor = QuizStatType.RANK.titleColor,
value = "16",
)
QuizStatBox(
title = stringResource(id = QuizStatType.SPEED.title),
titleColor = QuizStatType.SPEED.titleColor,
value = "20",
)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

하드코딩된 통계 값을 파라미터로 전달받도록 수정 필요

현재 XP, RANK, SPEED 값이 하드코딩되어 있습니다. 실제 퀴즈 결과 데이터를 반영하도록 QuizResultScreen에 파라미터를 추가하거나 ViewModel을 통해 상태를 관리해야 합니다.

다음과 같이 수정하는 것을 권장합니다:

 @Composable
 fun QuizResultScreen(
     type: QuizResultType = QuizResultType.FAIL,
+    xpValue: String,
+    rankValue: String,
+    speedValue: String,
     onXpClick: () -> Unit = {},
 ) {

그리고 값을 전달:

             QuizStatBox(
                 title = stringResource(id = QuizStatType.XP.title),
                 titleColor = QuizStatType.XP.titleColor,
-                value = "8",
+                value = xpValue,
             )

백엔드 연동 시 이 부분을 구현하시겠습니까?

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In feature/quiz/src/main/java/com/teamwable/quiz/result/QuizResultScreen.kt
around lines 81 to 95, the XP/RANK/SPEED values are hardcoded ("8","16","20");
change QuizResultScreen to accept these stats (either as parameters to the
composable or by exposing them from a ViewModel/state holder) and replace the
literal strings with the passed values (convert types as needed and format for
display). Ensure callers supply the real data (or ViewModel is observed) so the
QuizStatBox invocations use the dynamic values instead of constants.

Comment on lines +79 to +86
text = "이 룬은 칼날비라는 룬으로\n" +
"적에게 기본 공격을 3번 가하면\n" +
"일정 시간 동안 공격 속도가\n" +
"크게 증가하는 룬이다.",
style = WableTheme.typography.head01,
textAlign = TextAlign.Center,
color = WableTheme.colors.gray800,
maxLines = 4,
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion | 🟠 Major

하드코딩된 텍스트를 strings.xml로 이동 필요

퀴즈 설명 텍스트가 코드에 직접 하드코딩되어 있습니다. 다른 UI 텍스트들과 마찬가지로 strings.xml로 이동하여 관리해야 합니다.

feature/quiz/src/main/res/values/strings.xml에 추가:

<string name="str_quiz_start_description">이 룬은 칼날비라는 룬으로\n적에게 기본 공격을 3번 가하면\n일정 시간 동안 공격 속도가\n크게 증가하는 룬이다.</string>

그리고 코드에서:

         Text(
-            text = "이 룬은 칼날비라는 룬으로\n" +
-                "적에게 기본 공격을 3번 가하면\n" +
-                "일정 시간 동안 공격 속도가\n" +
-                "크게 증가하는 룬이다.",
+            text = stringResource(R.string.str_quiz_start_description),
             style = WableTheme.typography.head01,
🤖 Prompt for AI Agents
In feature/quiz/src/main/java/com/teamwable/quiz/start/QuizStartScreen.kt around
lines 79 to 86 the quiz description is hardcoded in the Composable; move this
text into feature/quiz/src/main/res/values/strings.xml as a new string resource
(e.g., name="str_quiz_start_description") preserving the line breaks, then
replace the hardcoded literal with a call to
stringResource(R.string.str_quiz_start_description) (or the appropriate
generated ID) so the UI reads the text from resources instead of embedding it in
code.

Copy link
Copy Markdown
Collaborator

@sohyun127 sohyun127 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

고생하셨습니다!! 👍

@chanubc
Copy link
Copy Markdown
Member Author

chanubc commented Oct 24, 2025

다음 pr에서 수정 사항 적용하겠습니다!

@chanubc chanubc merged commit 132dde1 into develop Oct 24, 2025
2 checks passed
@chanubc chanubc deleted the feature/#188-quiz-ui branch October 24, 2025 11:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FEAT] : 퀴즈 화면 구현

2 participants