Skip to content

Conversation

wjdrjs00
Copy link
Member

@wjdrjs00 wjdrjs00 commented Aug 11, 2025

[ PR Content ]

루틴 리스트 화면을 구현했습니다.

Related issue

Screenshot 📸

Screen_recording_20250812_032443.mp4

Work Description

  • 루틴 리스트 화면 ui 구현

To Reviewers 📢

  • api 연동 작업도 같이 진행하려고 했으나, api 버저닝 변동 가능성(v1 -> v2)이 높다고 판단되어 ui만 우선적으로 구현하는 방향으로 진행했습니다.
  • 추후 api 가 확정되면 연동 작업과 ui 로직을 구현하는 방향으로 진행해보겠습니다!

Summary by CodeRabbit

  • 신기능
    • 루틴 리스트 화면 추가(주간 날짜 선택, 루틴 카드, 빈 상태, 삭제 확인 시트).
    • 탈퇴(Withdrawal) 화면 및 탈퇴 완료 다이얼로그 추가; 홈/설정에서 탈퇴 경로 연결.
  • 스타일
    • 디자인 시스템 아이콘 다수 추가(연결·성장·외부·휴식·반짝임·기상·추가 등).
    • 편집·휴지통 아이콘 등 아이콘 리파인, 버튼 색상 프리셋(삭제·취소) 및 옐로우 계열 추가.
    • 하단 네비게이션 바 상단 구분선 추가.

@wjdrjs00 wjdrjs00 requested a review from l5x5l August 11, 2025 18:39
@wjdrjs00 wjdrjs00 self-assigned this Aug 11, 2025
@wjdrjs00 wjdrjs00 added ✨ Feature 새로운 기능 구현 🧤 대현 labels Aug 11, 2025
Copy link

coderabbitai bot commented Aug 11, 2025

Walkthrough

루틴 리스트 화면을 MVI 구조로 추가하고 NavHost에 Route.RoutineList 및 Route.Withdrawal를 등록했으며, 루틴 리스트 관련 UI(주간 날짜 선택, 루틴 카드, 삭제 확인 시트)와 탈퇴 화면·뷰모델을 새로 추가하고 디자인시스템 색상·아이콘·컴포넌트 여러 개를 변경·추가했습니다.

Changes

Cohort / File(s) Summary
Navigation
app/src/main/java/com/threegap/bitnagil/MainNavHost.kt, app/src/main/java/com/threegap/bitnagil/Route.kt
Route.RoutineList, Route.Withdrawal 추가 및 NavHost에 해당 composable 등록; HomeNavHost/Settings에 navigateToWithdrawal 경로 연결.
RoutineList UI / MVI
presentation/src/main/java/com/threegap/bitnagil/presentation/routinelist/*
RoutineListScreen, RoutineListScreenContainer, RoutineListViewModel, RoutineListState/Intent/SideEffect, WeeklyDatePicker, RoutineDetailsCard, DeleteConfirmBottomSheet, EmptyRoutineListView 등 화면 및 관련 컴포저블·뷰모델 추가.
Withdrawal UI / MVI
presentation/src/main/java/com/threegap/bitnagil/presentation/withdrawal/*
WithdrawalScreenContainer, WithdrawalScreen, WithdrawalViewModel, WithdrawalState/Intent/SideEffect, WithdrawalConfirmDialog, WithdrawalReason 등 탈퇴 흐름 UI·MVI 추가.
DesignSystem · Components
core/designsystem/src/main/java/.../BitnagilTextButton.kt, .../BitnagilFloatingButton.kt, .../BitnagilSelectButton.kt, .../BitnagilOptionButton.kt
BitnagilTextButton에 textPadding 파라미터 및 delete/cancel 컬러 프리셋 추가. BitnagilFloatingButton에 테마 색상·isActive 지원 추가; BitnagilSelectButton 레이아웃·시그니처 변경(타이틀 스타일 파라미터 추가) 등 UI 컴포넌트 API 변경.
DesignSystem · Colors
core/designsystem/src/main/java/.../color/BitnagilColors.kt, .../Color.kt
색상 상수 Yellow10 추가 및 BitnagilColors 생성자에 yellow10 필드 삽입(시그니처 변경).
DesignSystem · Drawables (추가/수정)
core/designsystem/src/main/res/drawable/*
다수 벡터 아이콘 추가(ic_connect.xml, ic_grow.xml, ic_outside.xml, ic_rest.xml, ic_shine.xml, ic_check_circle_orange.xml, ic_add.xml, ic_wakeup.xml) 및 기존 아이콘들(ic_edit.xml, ic_trash.xml, ic_close.xml, ic_setting.xml 등) 수정/크기 변경/경로 재작성.
Home · UI/Model 리팩터
presentation/src/main/java/com/threegap/bitnagil/presentation/home/*, presentation/src/main/java/com/threegap/bitnagil/presentation/home/model/*
Home 화면 전반 리팩터: Emotion -> TodayEmotion 흐름으로 전환, Routine/Routines/DayRoutines/RecommendedRoutineType 등 도메인·UI 모델 변경, 서브루틴 식별자→인덱스 변경, 여러 bottom-sheet/삭제/정렬 관련 컴포넌트 제거 또는 API 변경.
Routine 데이터 계층 API 변경
data/src/main/java/com/threegap/bitnagil/data/routine/*, data/src/main/java/com/threegap/bitnagil/data/emotion/*
Routines API 응답 구조 v2로 변경(RoutinesResponseDto, DayRoutinesDto, RoutineDto 재구조화), RoutineCompletion 관련 요청/DTO 구조 변경 (RoutineCompletionInfos 등), emotion API v2 및 TodayEmotion 리네이밍 및 매핑 변경.
기타 변경: AndroidManifest / Insets
app/src/main/AndroidManifest.xml, app/src/main/java/com/threegap/bitnagil/MainScreen.kt, presentation/.../WriteRoutineScreen.kt
MainActivity에 windowSoftInputMode="adjustResize" 추가, Scaffold insets 처리 변경 (navigationBars.exclude(ime) → ime 등 일부 insets 조정).

Sequence Diagram(s)

sequenceDiagram
  participant User as 사용자
  participant Nav as MainNavHost
  participant Screen as RoutineListScreenContainer
  participant VM as RoutineListViewModel

  User->>Nav: Route.RoutineList로 이동
  Nav->>Screen: RoutineListScreenContainer 렌더
  Screen->>VM: state/sideEffect 구독 (collectAsStateWithLifecycle / collectAsEffect)

  User->>Screen: 날짜 선택
  Screen->>VM: Intent.OnDateSelect(date)
  VM-->>Screen: State(selectedDate = date)

  User->>Screen: 삭제 아이콘 클릭
  Screen->>VM: Intent.ShowDeleteConfirmBottomSheet
  VM-->>Screen: State(deleteConfirmBottomSheetVisible = true)

  User->>Screen: 뒤로가기
  Screen->>Nav: popBackStack() (if previousBackStackEntry != null)
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Assessment against linked issues

Objective Addressed Explanation
루틴 리스트 화면 UI 구현 (#97)
API 연동 (UseCase 호출 및 데이터 바인딩) (#97) RoutineListViewModel에 UseCase 주입 여부는 확인되나, PR에서 fetch/UseCase 호출과 서버 응답 바인딩(예: FetchWeeklyRoutinesUseCase 호출 후 state 반영)이 구현된 증거가 없습니다.

Assessment against linked issues: Out-of-scope changes

Code Change Explanation
core/designsystem/src/main/res/drawable/ic_connect.xml 추가 루틴 리스트 화면 구현 이슈(#97)의 최소 목표(화면 UI + API 연동)와 직접 관련이 없는 디자인 자산 추가입니다.
core/designsystem/src/main/res/drawable/ic_grow.xml 추가 루틴 리스트 UI/데이터 통합 요구사항과 무관한 신규 아이콘 리소스입니다.
core/designsystem/src/main/res/drawable/ic_outside.xml 추가 이 이슈의 명시적 목표(루틴 리스트 화면 및 API 연동)와 직접 연관되지 않는 디자인 리소스입니다.

Possibly related PRs

Suggested labels

📱 UI

Suggested reviewers

  • l5x5l

(\_/)
(•ᴥ•) 나는 토끼, 달력 위를 깡충
날짜 고르면 카드가 줄지어 와
삭제 시트는 살짝, 탈퇴는 확인
아이콘과 색깔도 한 움큼 챙겼네 🥕✨

Tip

🔌 Remote MCP (Model Context Protocol) integration is now available!

Pro plan users can now connect to remote MCP servers from the Integrations page. Connect with popular remote MCPs such as Notion and Linear to add more context to your reviews and chats.

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feature/#97-routine-list

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
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@wjdrjs00 wjdrjs00 changed the title [Feature/#97] 루틴 리스트 화면 구현 [FEATURE/#97] 루틴 리스트 화면 구현 Aug 11, 2025
@wjdrjs00 wjdrjs00 changed the title [FEATURE/#97] 루틴 리스트 화면 구현 [Feature/#97] 루틴 리스트 화면 구현 Aug 11, 2025
Copy link

@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: 0

🧹 Nitpick comments (9)
core/designsystem/src/main/res/drawable/ic_grow.xml (1)

10-12: 아이콘 컬러 하드코딩 → 리소스화 검토

현재 #F55174가 여러 경로에 직접 기입되어 있습니다. 테마/다크모드/브랜드 컬러 변경 대응을 위해 colors.xml 리소스로 추출 후 참조하는 방식을 권장합니다.

Also applies to: 14-15, 19-22

core/designsystem/src/main/res/drawable/ic_connect.xml (1)

21-29: 중복 path 병합으로 파일 크기/렌더 오버헤드 절감

동일 pathData를 가진 fill 전용, stroke 전용 path가 중복됩니다. 아래처럼 하나의 path에서 fill+stroke를 함께 지정해 병합할 수 있습니다.

-    <path
-        android:fillColor="#715DF1"
-        android:pathData="M17.966,20.911C..."
-    />
-    <path
-        android:fillColor="#00000000"
-        android:pathData="M17.966,20.911C..."
-        android:strokeWidth="2"
-        android:strokeColor="#715DF1"
-        android:strokeLineCap="round"
-        android:strokeLineJoin="round" />
+    <path
+        android:fillColor="#715DF1"
+        android:pathData="M17.966,20.911C..."
+        android:strokeWidth="2"
+        android:strokeColor="#715DF1"
+        android:strokeLineCap="round"
+        android:strokeLineJoin="round" />

추가로, #715DF1 컬러도 리소스화 검토 부탁드립니다.

core/designsystem/src/main/res/drawable/ic_shine.xml (1)

9-14: strokeLineCap 일관성 제안

다른 신규 아이콘들과 시각적 일관성을 위해 외곽선 path에도 strokeLineCap="round" 추가를 권장합니다.

     <path
         android:fillColor="#00000000"
         android:pathData="M11.054,3.342C..."
         android:strokeWidth="2"
         android:strokeColor="#FFBF00"
-        android:strokeLineJoin="round" />
+        android:strokeLineJoin="round"
+        android:strokeLineCap="round" />
core/designsystem/src/main/res/drawable/ic_wakeup.xml (1)

6-8: 불필요한 clip-path 제거 및 중복 path 병합, 컬러 리소스화 제안

  • group 내 전체 캔버스 clip-path는 대부분 불필요합니다. 제거 시 파일 크기 감소와 단순화에 도움이 됩니다.
  • 동일 pathData에 대해 fill 전용과 stroke 전용 path가 중복됩니다. 한 path로 병합 가능하며 렌더 오버헤드를 줄일 수 있습니다.
  • #FE7120 컬러는 리소스화하여 테마 대응을 용이하게 해 주세요.

Also applies to: 65-73

presentation/src/main/java/com/threegap/bitnagil/presentation/routinelist/model/RoutineListSideEffect.kt (1)

5-7: 사이드이펙트 네이밍 컨벤션 정합성 제안

NavigateToBack 보다는 NavigateBack 처럼 불필요한 전치사 없이 짧은 형태가 선호되는 편입니다. 기존 화면들의 네이밍 컨벤션과 일치하는지 한번만 확인 부탁드립니다.

기존 사이드이펙트/인텐트 네이밍을 함께 확인해 주세요(예: NavigateBack, PopBackStack 등).

core/designsystem/src/main/res/drawable/ic_outside.xml (1)

6-16: 동일 도형의 fill/stroke 중복 선언 → 단일 path로 병합 권장

한 path에서 fillColor와 strokeColor를 함께 지정하면 중복을 제거할 수 있습니다. 또한 #0093F5/#ffffff 컬러는 colors.xml로 리소스화 검토 부탁드립니다.

core/designsystem/src/main/java/com/threegap/bitnagil/designsystem/component/atom/BitnagilTextButton.kt (2)

114-132: delete/cancel 프리셋의 pressed/disabled 시각 피드백 보완 제안

  • 현재 pressed/disabled가 default와 동일하여(특히 delete) 상호작용 피드백이 없거나 약합니다. 최소한 pressed/disabled에 알파/명도 변화를 주거나 ripple을 사용해 피드백을 제공해 주세요.
  • 접근성(터치 피드백) 관점에서도 개선이 필요합니다.

예시(알파로 간단히 구분):

 @Composable
 fun delete(): BitnagilTextButtonColor = BitnagilTextButtonColor(
-    defaultBackgroundColor = BitnagilTheme.colors.error10,
-    pressedBackgroundColor = BitnagilTheme.colors.error10,
-    disabledBackgroundColor = BitnagilTheme.colors.error10,
-    defaultTextColor = BitnagilTheme.colors.white,
-    pressedTextColor = BitnagilTheme.colors.white,
-    disabledTextColor = BitnagilTheme.colors.white,
+    defaultBackgroundColor = BitnagilTheme.colors.error10,
+    pressedBackgroundColor = BitnagilTheme.colors.error10.copy(alpha = 0.9f),
+    disabledBackgroundColor = BitnagilTheme.colors.error10.copy(alpha = 0.5f),
+    defaultTextColor = BitnagilTheme.colors.white,
+    pressedTextColor = BitnagilTheme.colors.white,
+    disabledTextColor = BitnagilTheme.colors.white.copy(alpha = 0.7f),
 )

 @Composable
 fun cancel(): BitnagilTextButtonColor = BitnagilTextButtonColor(
-    defaultBackgroundColor = BitnagilTheme.colors.coolGray97,
-    pressedBackgroundColor = BitnagilTheme.colors.coolGray97,
-    disabledBackgroundColor = BitnagilTheme.colors.coolGray97,
-    defaultTextColor = BitnagilTheme.colors.coolGray40,
-    pressedTextColor = BitnagilTheme.colors.coolGray40,
-    disabledTextColor = BitnagilTheme.colors.coolGray40,
+    defaultBackgroundColor = BitnagilTheme.colors.coolGray97,
+    pressedBackgroundColor = BitnagilTheme.colors.coolGray97.copy(alpha = 0.9f),
+    disabledBackgroundColor = BitnagilTheme.colors.coolGray97.copy(alpha = 0.6f),
+    defaultTextColor = BitnagilTheme.colors.coolGray40,
+    pressedTextColor = BitnagilTheme.colors.coolGray40,
+    disabledTextColor = BitnagilTheme.colors.coolGray40.copy(alpha = 0.6f),
 )

추가로, 과거 학습 메모대로 임시 TextButton을 DS 컴포넌트로 치환하는 방향은 매우 좋습니다. 이번 프리셋 추가는 그 정합성을 높여줍니다.


59-70: ripple 비활성(indication = null)로 인한 피드백 부재

시각 피드백 강화를 위해 ripple 사용을 고려해 주세요. pressed 컬러 변화가 미미하거나 동일한 프리셋에서는 특히 필요합니다.

변경 예시(파일 외부 적용 가이드):

.clickable(
    enabled = enabled,
    onClick = onClick,
    interactionSource = interactionSource,
    indication = rememberRipple(), // Ripple 추가
)

또한 Preview에 delete()/cancel() 변형을 추가해 디자인 확인성을 높이는 것도 추천합니다.

@Preview
@Composable
private fun BitnagilTextButtonVariantsPreview() {
    Column(Modifier.padding(16.dp)) {
        BitnagilTextButton(
            text = "삭제",
            onClick = {},
            colors = BitnagilTextButtonColor.delete(),
            modifier = Modifier.fillMaxWidth(),
        )
        Spacer(Modifier.height(12.dp))
        BitnagilTextButton(
            text = "취소",
            onClick = {},
            colors = BitnagilTextButtonColor.cancel(),
            modifier = Modifier.fillMaxWidth(),
        )
    }
}
presentation/src/main/java/com/threegap/bitnagil/presentation/routinelist/RoutineListScreen.kt (1)

104-104: 하드코딩된 아이템 개수에 대한 주석 추가를 권장합니다.

현재 items(5)로 하드코딩되어 있는데, API 연동이 완료되지 않아 임시로 사용하는 것임을 명시하는 주석을 추가하면 좋겠습니다.

+ // TODO: API 연동 완료 후 실제 데이터로 변경 예정
  items(5) {
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f6820de and 489b5d2.

📒 Files selected for processing (19)
  • app/src/main/java/com/threegap/bitnagil/MainNavHost.kt (2 hunks)
  • app/src/main/java/com/threegap/bitnagil/Route.kt (1 hunks)
  • core/designsystem/src/main/java/com/threegap/bitnagil/designsystem/component/atom/BitnagilTextButton.kt (1 hunks)
  • core/designsystem/src/main/res/drawable/ic_connect.xml (1 hunks)
  • core/designsystem/src/main/res/drawable/ic_edit.xml (1 hunks)
  • core/designsystem/src/main/res/drawable/ic_grow.xml (1 hunks)
  • core/designsystem/src/main/res/drawable/ic_outside.xml (1 hunks)
  • core/designsystem/src/main/res/drawable/ic_rest.xml (1 hunks)
  • core/designsystem/src/main/res/drawable/ic_shine.xml (1 hunks)
  • core/designsystem/src/main/res/drawable/ic_trash.xml (1 hunks)
  • core/designsystem/src/main/res/drawable/ic_wakeup.xml (1 hunks)
  • presentation/src/main/java/com/threegap/bitnagil/presentation/routinelist/RoutineListScreen.kt (1 hunks)
  • presentation/src/main/java/com/threegap/bitnagil/presentation/routinelist/RoutineListViewModel.kt (1 hunks)
  • presentation/src/main/java/com/threegap/bitnagil/presentation/routinelist/component/template/DeleteConfirmBottomSheet.kt (1 hunks)
  • presentation/src/main/java/com/threegap/bitnagil/presentation/routinelist/component/template/RoutineDetailsCard.kt (1 hunks)
  • presentation/src/main/java/com/threegap/bitnagil/presentation/routinelist/component/template/WeeklyDatePicker.kt (1 hunks)
  • presentation/src/main/java/com/threegap/bitnagil/presentation/routinelist/model/RoutineListIntent.kt (1 hunks)
  • presentation/src/main/java/com/threegap/bitnagil/presentation/routinelist/model/RoutineListSideEffect.kt (1 hunks)
  • presentation/src/main/java/com/threegap/bitnagil/presentation/routinelist/model/RoutineListState.kt (1 hunks)
🧰 Additional context used
🧠 Learnings (2)
📚 Learning: 2025-07-23T13:32:26.263Z
Learnt from: l5x5l
PR: YAPP-Github/Bitnagil-Android#41
File: presentation/src/main/java/com/threegap/bitnagil/presentation/mypage/model/MyPageIntent.kt:6-6
Timestamp: 2025-07-23T13:32:26.263Z
Learning: In the Bitnagil Android project's MVI architecture, Intent classes like `LoadMyPageSuccess` are named to represent successful API response results that carry loaded data, not just user actions. This naming convention is used for future API integration where the intent will be triggered when my page data loading succeeds from the server.

Applied to files:

  • presentation/src/main/java/com/threegap/bitnagil/presentation/routinelist/model/RoutineListIntent.kt
📚 Learning: 2025-07-21T10:38:49.104Z
Learnt from: l5x5l
PR: YAPP-Github/Bitnagil-Android#38
File: presentation/src/main/java/com/threegap/bitnagil/presentation/writeroutine/component/atom/textbutton/TextButton.kt:30-35
Timestamp: 2025-07-21T10:38:49.104Z
Learning: presentation/src/main/java/com/threegap/bitnagil/presentation/writeroutine/component/atom/textbutton/TextButton.kt의 TextButton 컴포넌트는 임시로 구현된 컴포넌트로, 디자인 시스템 구현시 대체 예정입니다.

Applied to files:

  • core/designsystem/src/main/java/com/threegap/bitnagil/designsystem/component/atom/BitnagilTextButton.kt
🧬 Code Graph Analysis (5)
app/src/main/java/com/threegap/bitnagil/MainNavHost.kt (1)
presentation/src/main/java/com/threegap/bitnagil/presentation/routinelist/RoutineListScreen.kt (1)
  • RoutineListScreenContainer (33-64)
presentation/src/main/java/com/threegap/bitnagil/presentation/routinelist/component/template/RoutineDetailsCard.kt (1)
core/designsystem/src/main/java/com/threegap/bitnagil/designsystem/component/atom/BitnagilIcon.kt (2)
  • BitnagilIcon (21-33)
  • BitnagilIconButton (35-58)
presentation/src/main/java/com/threegap/bitnagil/presentation/routinelist/component/template/DeleteConfirmBottomSheet.kt (1)
core/designsystem/src/main/java/com/threegap/bitnagil/designsystem/component/atom/BitnagilTextButton.kt (1)
  • BitnagilTextButton (33-82)
presentation/src/main/java/com/threegap/bitnagil/presentation/routinelist/RoutineListScreen.kt (4)
presentation/src/main/java/com/threegap/bitnagil/presentation/routinelist/component/template/DeleteConfirmBottomSheet.kt (1)
  • DeleteConfirmBottomSheet (21-39)
core/designsystem/src/main/java/com/threegap/bitnagil/designsystem/component/block/BitnagilTopBar.kt (1)
  • BitnagilTopBar (22-63)
presentation/src/main/java/com/threegap/bitnagil/presentation/routinelist/component/template/WeeklyDatePicker.kt (1)
  • WeeklyDatePicker (30-52)
presentation/src/main/java/com/threegap/bitnagil/presentation/routinelist/component/template/RoutineDetailsCard.kt (1)
  • RoutineDetailsCard (24-139)
presentation/src/main/java/com/threegap/bitnagil/presentation/routinelist/RoutineListViewModel.kt (1)
presentation/src/main/java/com/threegap/bitnagil/presentation/common/mviviewmodel/MviViewModel.kt (1)
  • sendSideEffect (23-23)
⏰ 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: build
🔇 Additional comments (22)
app/src/main/java/com/threegap/bitnagil/Route.kt (1)

42-43: Route.RoutineList 네비게이션 등록 확인 및 역방향 동작 점검 필요

다음 위치에서 Route.RoutineList가 정상 등록됨을 확인했습니다.

  • app/src/main/java/com/threegap/bitnagil/MainNavHost.kt (228–229행): composable<Route.RoutineList>
  • presentation/src/.../RoutineListScreen.kt: RoutineListScreenContainer 호출

이제 백 스택이 비었을 때(뒤로가기 시) 앱이 안전하게 종료(finish)되는지, MainActivity나 NavHost 내 onBackPressed/BackHandler 처리 로직을 꼭 검증해 주세요.

presentation/src/main/java/com/threegap/bitnagil/presentation/routinelist/model/RoutineListState.kt (1)

7-11: 깔끔한 MVI State 구현입니다!

@Parcelize 어노테이션과 기본값 설정이 적절하며, MVI 패턴을 올바르게 따르고 있습니다.

core/designsystem/src/main/res/drawable/ic_rest.xml (1)

1-30: 아이콘 리소스가 잘 구성되어 있습니다

벡터 드로어블이 적절한 구조로 되어 있고, 색상 테마도 일관성이 있습니다.

core/designsystem/src/main/res/drawable/ic_trash.xml (2)

2-5: 아이콘 크기 조정이 적절합니다

24dp에서 20dp로 크기를 줄이고 뷰포트도 맞게 조정한 것이 좋습니다.


6-36: 다층 구조의 아이콘 디자인이 잘 구현되었습니다

여러 패스를 활용한 스트로크와 채우기 조합으로 세련된 아이콘을 만들었습니다.

presentation/src/main/java/com/threegap/bitnagil/presentation/routinelist/component/template/WeeklyDatePicker.kt (2)

30-52: 주간 날짜 선택기가 잘 구현되었습니다

컴포저블 구조가 깔끔하고, SpaceBetween을 사용한 레이아웃이 적절합니다.


54-89: DateItem의 상태 처리가 우수합니다

선택된 날짜와 오늘을 구분하여 표시하는 로직이 명확하고, 스타일링도 일관성 있게 적용되었습니다.

presentation/src/main/java/com/threegap/bitnagil/presentation/routinelist/component/template/DeleteConfirmBottomSheet.kt (3)

21-39: 바텀시트 구현이 Material3 가이드라인을 잘 따르고 있습니다

ExperimentalMaterial3Api를 적절히 사용하고 테마 색상 적용도 일관성이 있습니다.


67-82: 반복 루틴 삭제 UI가 사용자 친화적입니다

"오늘만 삭제"와 "모든 날짜에서 삭제" 옵션을 명확히 구분한 것이 좋은 UX 설계입니다. TODO 주석은 현재 단계에서 적절합니다.


115-128: 단일 루틴 삭제 UI의 버튼 배치가 적절합니다

취소와 삭제 버튼의 가중치를 동일하게 설정하고, 색상으로 구분한 것이 좋습니다.

core/designsystem/src/main/res/drawable/ic_edit.xml (2)

2-5: 아이콘 크기 통일이 잘 되었습니다

다른 아이콘들과 마찬가지로 20dp로 크기를 맞춘 것이 일관성 있습니다.


13-22: 새로운 다층 구조 디자인이 효과적입니다

스트로크와 채우기를 분리한 구조로 더 세련된 아이콘이 되었습니다.

app/src/main/java/com/threegap/bitnagil/MainNavHost.kt (2)

15-15: 네비게이션 import가 적절히 추가되었습니다

루틴 리스트 화면 컨테이너 import가 올바르게 추가되었습니다.


228-236: 루틴 리스트 네비게이션 구성이 일관성 있습니다

다른 화면들과 동일한 패턴으로 백 네비게이션을 구현하여 일관성을 유지했습니다.

presentation/src/main/java/com/threegap/bitnagil/presentation/routinelist/component/template/RoutineDetailsCard.kt (3)

43-52: 아이콘과 배경 스타일링이 잘 적용되었습니다

ic_wakeup 아이콘을 오렌지 배경에 배치한 것이 시각적으로 좋습니다.


63-75: 액션 버튼 구성이 적절합니다

편집과 삭제 버튼의 패딩값과 콜백 처리가 일관성 있게 구현되었습니다. 편집 기능의 TODO 주석은 현재 단계에서 적절합니다.


94-108: 플레이스홀더 컨텐츠 사용이 적절합니다

"어쩌구" 플레이스홀더는 UI 구현 단계에서 적절한 임시 텍스트입니다.

presentation/src/main/java/com/threegap/bitnagil/presentation/routinelist/model/RoutineListIntent.kt (1)

6-11: MVI Intent 패턴이 올바르게 구현되었습니다.

날짜 선택, 바텀시트 표시/숨김, 뒤로 가기 등 루틴 리스트 화면에 필요한 모든 인텐트가 적절히 정의되어 있습니다. 데이터 클래스와 data object의 사용도 적절합니다.

presentation/src/main/java/com/threegap/bitnagil/presentation/routinelist/RoutineListScreen.kt (2)

33-64: MVI 컨테이너 구현이 우수합니다.

상태 수집, 사이드 이펙트 처리, 바텀시트 조건부 표시 등이 올바르게 구현되어 있습니다. Hilt를 통한 의존성 주입과 프레젠테이션 컴포넌트와의 깔끔한 분리도 잘 되어 있습니다.


113-122: 프리뷰 구현이 적절합니다.

기본 상태와 빈 콜백을 사용한 프리뷰 설정이 올바르게 되어 있습니다.

presentation/src/main/java/com/threegap/bitnagil/presentation/routinelist/RoutineListViewModel.kt (2)

13-20: 뷰모델 구조가 올바르게 설계되었습니다.

Hilt 어노테이션, MVI 패턴 상속, 의존성 주입이 적절히 구현되어 있습니다. FetchWeeklyRoutinesUseCase는 향후 API 연동 시 사용될 예정으로 보입니다.


21-37: reduceState 메서드가 완벽하게 구현되었습니다.

모든 인텐트에 대한 상태 처리가 올바르게 되어 있습니다. 특히 NavigateToBack에서 사이드 이펙트를 발생시키고 null을 반환하는 패턴이 적절합니다.

- v1 -> v2 버전업
- response 변화에 따른 모델 수정
- v1 -> v2로 마이그레이션
- 루틴 완료 로직 인덱스 값 기반으로 수정
- 루틴 완료 requestDto 수정
- 네이밍 변경
- 감정 조회 호출 시 LocalDate.now()를 통하도록 변경
- items() API를 사용해 키/콘텐츠 타입을 명시
-  AsyncImage의 model 생성 시 remember를 사용하여 불필요한 재생성 방지
- 중복 검증 처리 제거
[Feature/#90] 홈 화면 리디자인 변경 사항을 반영합니다.
Copy link

@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: 0

🧹 Nitpick comments (8)
presentation/src/main/java/com/threegap/bitnagil/presentation/routinelist/component/template/EmptyRoutineListView.kt (8)

20-65: 구현 방향 좋습니다 — 명확한 빈 상태 UI 컴포넌트

간결한 API와 테마 토큰 활용이 일관적입니다. 아래 몇 가지 접근성/구성 개선 제안만 반영하면 더 탄탄해질 것 같습니다.


3-19: 필요한 import 정리 (접근성/크기/문자열 리소스 적용용)

아래 개선 제안들(최소 터치 타깃, semantics, stringResource)을 적용하려면 다음 import가 필요합니다.

 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.Spacer
 import androidx.compose.foundation.layout.height
 import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.sizeIn
 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.res.stringResource
+import androidx.compose.ui.semantics.Role
+import androidx.compose.ui.semantics.heading
+import androidx.compose.ui.semantics.role
+import androidx.compose.ui.semantics.semantics
 import androidx.compose.ui.tooling.preview.Preview
 import androidx.compose.ui.unit.dp
 import com.threegap.bitnagil.designsystem.BitnagilTheme
 import com.threegap.bitnagil.designsystem.modifier.clickableWithoutRipple

20-24: Compose 컨벤션: modifier를 첫 번째 파라미터로

Compose 가이드에 맞춰 modifier를 첫 번째 인자로 배치하면 호출부 일관성이 좋아집니다.

- fun EmptyRoutineListView(
-     onRegisterRoutineClick: () -> Unit,
-     modifier: Modifier = Modifier,
- ) {
+ fun EmptyRoutineListView(
+     modifier: Modifier = Modifier,
+     onRegisterRoutineClick: () -> Unit,
+ ) {

25-29: 실제 중앙 정렬 보장: fillMaxSize() 추가

비어있는 상태를 화면 중앙에 배치하려면 부모 여백과 무관하게 영역을 채우는 게 안전합니다.

-    Column(
+    Column(
         verticalArrangement = Arrangement.Center,
         horizontalAlignment = Alignment.CenterHorizontally,
-        modifier = modifier,
+        modifier = modifier.fillMaxSize(),
     ) {

30-35: 텍스트 고정 높이 제거 + heading semantics 부여

고정 높이(28.dp)는 폰트 스케일(접근성)에서 잘림을 유발할 수 있습니다. 헤더 텍스트에는 heading semantics를 부여하세요.

         Text(
             text = "등록한 루틴이 없어요",
             style = BitnagilTheme.typography.subtitle1SemiBold,
             color = BitnagilTheme.colors.coolGray30,
-            modifier = Modifier.height(28.dp),
+            modifier = Modifier.semantics { heading() },
         )

31-41: 하드코딩된 문자열을 stringResource로 교체 (다국어/접근성 대비)

문자열 리소스로 분리하면 로컬라이제이션, 다크모드 대비, 테스트가 용이합니다.

-            text = "등록한 루틴이 없어요",
+            text = stringResource(R.string.routine_empty_title),
-            text = "루틴을 등록하고, 작은 변화부터 시작해보세요!",
+            text = stringResource(R.string.routine_empty_description),
-                text = "루틴 등록하기",
+                text = stringResource(R.string.routine_register),

리소스 추가 예시(프로젝트 외부 파일 수정):

<!-- res/values/strings.xml -->
<resources>
    <string name="routine_empty_title">등록한 루틴이 없어요</string>
    <string name="routine_empty_description">루틴을 등록하고, 작은 변화부터 시작해보세요!</string>
    <string name="routine_register">루틴 등록하기</string>
</resources>

필요하시면 제가 리소스 키 네이밍 컨벤션에 맞춰 일괄 적용 패치도 만들어드릴게요.

Also applies to: 59-61


45-57: 버튼 역할 명시, 최소 터치 타깃 48dp 보장, 모서리 clip 적용

접근성 및 사용성 강화를 위해 버튼 역할을 semantics로 명시하고, 최소 48x48dp 터치 타깃을 보장하며, 모서리 clip을 적용하세요. ripple을 사용하지 않더라도 clip은 일관된 모서리 처리를 보장합니다.

         Box(
             modifier = Modifier
-                .background(
-                    color = BitnagilTheme.colors.coolGray96,
-                    shape = RoundedCornerShape(8.dp),
-                )
-                .clickableWithoutRipple { onRegisterRoutineClick() }
+                .clip(RoundedCornerShape(8.dp))
+                .background(
+                    color = BitnagilTheme.colors.coolGray96,
+                    shape = RoundedCornerShape(8.dp),
+                )
+                .sizeIn(minWidth = 48.dp, minHeight = 48.dp)
+                .clickableWithoutRipple { onRegisterRoutineClick() }
+                .semantics { role = Role.Button }
                 .padding(
                     vertical = 10.dp,
                     horizontal = 14.dp,
                 ),
             contentAlignment = Alignment.Center,
         ) {

67-71: Preview에 테마 래핑 및 배경 표시

디자인 토큰(타이포/컬러)을 정확히 확인하려면 Preview를 테마로 감싸고 배경을 표시하는 게 좋습니다.

-@Preview
+@Preview(showBackground = true)
 @Composable
 private fun EmptyRoutineListViewPreview() {
-    EmptyRoutineListView(onRegisterRoutineClick = {})
+    BitnagilTheme {
+        EmptyRoutineListView(onRegisterRoutineClick = {})
+    }
 }
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between a13305a and b94a04c.

📒 Files selected for processing (1)
  • presentation/src/main/java/com/threegap/bitnagil/presentation/routinelist/component/template/EmptyRoutineListView.kt (1 hunks)
🔇 Additional comments (1)
presentation/src/main/java/com/threegap/bitnagil/presentation/routinelist/component/template/EmptyRoutineListView.kt (1)

31-35: 색상 대비(contrast) 검토 요청

텍스트 색상(coolGray30)과 배경(coolGray96) 조합의 대비비가 WCAG 기준(일반 텍스트 4.5:1, 굵은/대형 텍스트 3:1)을 충족하는지 디자인 시스템 값 기준으로 한번 확인 부탁드립니다. 토큰 명만으로는 수치 확인이 어려워 확인 후 필요 시 색상 톤업/다운이 필요할 수 있습니다.

Also applies to: 38-41, 59-61

Copy link

@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

@wjdrjs00 wjdrjs00 closed this Aug 15, 2025
@wjdrjs00 wjdrjs00 deleted the feature/#97-routine-list branch August 15, 2025 23:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

✨ Feature 새로운 기능 구현 🧤 대현

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FEATURE] 루틴 리스트 화면 구현

1 participant