Skip to content

7주차 미션_종이#23

Open
jongheecode wants to merge 5 commits into
mainfrom
Week7
Open

7주차 미션_종이#23
jongheecode wants to merge 5 commits into
mainfrom
Week7

Conversation

@jongheecode

Copy link
Copy Markdown
Collaborator

📝 작업 내용

  • Week2에서 구현한 Nike 앱(BottomNav + 5개 탭)을 Jetpack Compose로 마이그레이션
  • XML/Fragment 기반 UI → Composable 함수로 전환
  • NavHost + type-safe route(@serializable sealed interface)로 화면 전환 구현
  • 장바구니 → 구매하기 탭 이동을 State Hoisting 패턴으로 처리

📸 스크린샷

구현 결과를 확인할 수 있는 스크린샷을 첨부해주세요.


🙏 리뷰 요구사항 (선택)

리뷰어가 중점적으로 봐주었으면 하는 부분이 있다면 작성해주세요.

  • Compose에서 화면 간 이동 시 popUpTo + saveState/restoreState 조합이 적절한지 궁금합니다.
  • State Hoisting 적용 범위가 적당한지 피드백 부탁드립니다.

jongheecode and others added 5 commits April 17, 2026 22:45
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Hilt 의존성 주입 설정 (MyApplication, @HiltAndroidApp)
- NetworkModule: Retrofit/OkHttp DI 모듈
- RepositoryModule: Interface-Impl 바인딩
- ProductRepository / ProfileRepository 인터페이스 분리
- ProductLocalDataSource: DataStore 로컬 데이터 소스 분리
- ProductRepositoryImpl: LocalDataSource 주입 (Remote/Local 분리)
- ProfileRepositoryImpl: ReqResService 주입
- SharedViewModel: @hiltviewmodel, AndroidViewModel → ViewModel
- ProfileViewModel: @hiltviewmodel, LiveData → StateFlow + ProfileUiState
- ProfileFragment: observe → repeatOnLifecycle + collect 변환
- 전체 Activity/Fragment: @androidentrypoint 적용

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings May 16, 2026 13:03

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

This PR migrates the Nike app (BottomNav + 5 tabs) from XML/Fragment-based UI to Jetpack Compose under a new jongyee/Week7 module. It introduces type-safe routes via @Serializable sealed interface AppDestination, uses NavHost with popUpTo/saveState/restoreState, and wires the Bag → Buy navigation through state hoisting (onNavigateToBuy callback). The PR also re-adds the prior jongyee/Week5 and jongyee/Week6 projects (XML/Fragment + Hilt/Retrofit versions) as historical reference; these are not the focus of the migration.

Changes:

  • New Week7 Compose module: MainActivityMainScreen Scaffold with NavigationBar, NavHost and 5 destination Composables (HomeScreen, BuyScreen, WishlistScreen, BagScreen, ProfileScreen).
  • Type-safe navigation via AppDestination sealed interface with @Serializable data object entries; Bag → Buy uses a hoisted callback rather than direct controller access.
  • Adds Week5 (View/ViewModel + Retrofit) and Week6 (Hilt + clean architecture layers) project trees alongside the new Compose work.

Reviewed changes

Copilot reviewed 166 out of 218 changed files in this pull request and generated no comments.

Show a summary per file
File Description
jongyee/Week7/app/src/main/java/com/example/week7/MainActivity.kt Compose entry point, applies Week7Theme and renders MainScreen.
jongyee/Week7/app/src/main/java/com/example/week7/ui/MainScreen.kt Scaffold with BottomNav + NavHost, defines 5 tabs and popUpTo/saveState navigation.
jongyee/Week7/app/src/main/java/com/example/week7/navigation/AppDestination.kt Type-safe @Serializable sealed interface for routes.
jongyee/Week7/app/src/main/java/com/example/week7/ui/{home,buy,wishlist,bag,profile}/*Screen.kt Composable screen migrations of each tab; Bag exposes onNavigateToBuy for hoisting.
jongyee/Week7/app/src/main/java/com/example/week7/ui/theme/{Theme,Color}.kt Material3 light color scheme and Nike palette.
jongyee/Week7/{build.gradle.kts, app/build.gradle.kts, gradle/libs.versions.toml, settings.gradle.kts, gradle.properties, gradle/wrapper/*, gradlew.bat} Gradle/Kotlin/Compose BOM/Navigation setup, kotlin-serialization plugin.
jongyee/Week7/app/src/main/AndroidManifest.xml + res/* Manifest declaring MainActivity, theme Theme.Week7, launcher icons, strings/colors.
jongyee/Week7/app/proguard-rules.pro Keeps navigation.** classes for @Serializable routes.
jongyee/Week7/app/src/{test,androidTest}/... Default JUnit/Android test stubs.
jongyee/Week6/** Re-added prior XML/Fragment + Hilt/Retrofit/DataStore project (not part of the Compose migration).
jongyee/Week5/** Re-added even earlier XML/Fragment + Retrofit project (not part of the Compose migration).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@kimdoyeon1234 kimdoyeon1234 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

수고하셨습니다!
Type-safe Navigation 올바르게 적용하셨고, 파일 분리도 화면마다 패키지까지 나눠서 깔끔하게 잘 됐어요 ! BagScreen의 onNavigateToBuy 람다 패턴도 Events Flow Up 원칙에 맞게 잘 적용하셨어요!

질문 주신 popUpTo + saveState/restoreState 조합은 적절하게 잘 쓰셨어요
BottomNav 탭 전환 시 Home까지 백스택을 정리하면서 상태도 저장하는 올바른 패턴이에요!

State Hoisting 관련해서는 BuyScreen 내부의 selectedTab 상태가 고립되어 있어요.
지금은 문제없어 보이지만 백스택에서 복귀할 때 탭이 초기화될 수 있으니 상위로 끌어올려보세요 :)

fun BuyScreen(
selectedTab: Int,
onTabSelected: (Int) -> Unit
)

추가로 ProfileScreen의 프로필 수정 버튼 onClick이 비어있어요!
onEditClick: () -> Unit 람다를 받아서 MainScreen에서 네비게이션을 처리해주세요 :)

전반적으로 완성도가 높은 코드예요! 다음 주차도 화이팅 !

Comment on lines +29 to +31
fun BuyScreen() {
var selectedTab by remember { mutableIntStateOf(0) }

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

탭 선택 상태가 BuyScreen 내부에 고립되어 있어요! 현재는 문제없어 보이지만 백스택에서 복귀할 때 탭이 초기화될 수 있습니다! 여기에 State Hoisting을 적용해보면은 좋을거 같아요!

fun BuyScreen(
selectedTab: Int,
onTabSelected: (Int) -> Unit
)

Comment on lines +37 to +38
onClick = {},
colors = ButtonDefaults.buttonColors(containerColor = NikeBlack)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

프로필 수정 버튼의 onClick이 비어있어요!
NavController를 직접 주입하는 대신 람다로 이벤트를 올려주세요 :)

fun ProfileScreen(onEditClick: () -> Unit)

// MainScreen에서
composable<AppDestination.Profile> {
ProfileScreen(onEditClick = { navController.navigate(...) })
}

Comment on lines +35 to +47
private data class BottomNavItem(
val label: String,
val icon: ImageVector,
val destination: AppDestination,
)

private val bottomNavItems = listOf(
BottomNavItem("홈", Icons.Default.Home, AppDestination.Home),
BottomNavItem("구매하기", Icons.Default.ShoppingCart, AppDestination.Buy),
BottomNavItem("위시리스트", Icons.Default.Favorite, AppDestination.Wishlist),
BottomNavItem("장바구니", Icons.Default.ShoppingBag, AppDestination.Bag),
BottomNavItem("프로필", Icons.Default.Person, AppDestination.Profile),
)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

BottomNavItem이 MainScreen.kt 안에 private으로 정의되어 있어요!
별도 파일로 분리하면 더 깔끔해질 것 같아요 :)

@jongheecode

Copy link
Copy Markdown
Collaborator Author

넵 감사합니다

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.

3 participants