Skip to content

[Refactor] MyPage 레이아웃 개선 및 디자인 반영02#76

Open
e0ng wants to merge 2 commits intodevfrom
refactor/mypage-layout
Open

[Refactor] MyPage 레이아웃 개선 및 디자인 반영02#76
e0ng wants to merge 2 commits intodevfrom
refactor/mypage-layout

Conversation

@e0ng
Copy link
Collaborator

@e0ng e0ng commented Feb 19, 2026

✨ PR 유형

어떤 변경 사항이 있나요??

  • 마이페이지 상세 뷰 레이아웃 통일
  • 주간 리포트 인사이트 등급 색상 수정

🛠️ 작업내용

[ 작업한 내용을 작성해주세요 ( UI 구현이라면 사진도 같이 올려주시면 좋아요! ) ]

📋 추후 진행 상황

[ 다음에 진행할 작업에 대해 작성해주세요!! ]

[ 현재 커밋 후 풀리퀘 다음으로 작업 내용을 적어주면 됩니다! ]

📌 리뷰 포인트

[ 어떤 부분을 잘 체크해야하는지 작성해주세요 ]

✅ Checklist

PR이 다음 요구 사항을 충족하는지 확인해주세요!!!

Summary by CodeRabbit

릴리스 노트

  • 새로운 기능

    • 개인화 데이터 리셋 기능 추가
    • 설정 메뉴에 앱 업데이트 확인, 오픈소스 라이선스, 약관 및 정책 항목 추가
  • 스타일

    • 전체 UI 레이아웃의 간격 및 패딩 개선
    • 다양한 섹션의 여백 조정으로 시각적 일관성 강화
    • 색상 테마 미세 조정

@coderabbitai
Copy link

coderabbitai bot commented Feb 19, 2026

📝 Walkthrough

Walkthrough

MyPage 모듈의 여러 뷰(NotificationView, PersonalizationView, SettingsView, WeeklyReportView)에서 레이아웃 일관성을 개선했습니다. VStack의 spacing과 padding 값을 표준화(horizontal 32, vertical 16 등)하고, 상태 변경 감지를 위한 onChange 핸들러를 추가했으며, PersonalizationView에 loadRecent() 데이터 로딩 로직을 포함시켰습니다. SettingsView는 "앱 정보", "약관 및 정책", "고객센터" 섹션으로 구조화되었고, InsightType의 suggestion 색상값(borderColor, backgroundColor)을 조정했습니다.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

여백을 정리하고 간격을 맞춰 ✨
상태의 변화를 놓치지 않고 👀
설정과 보고서가 옷을 입으니 👕
디자인 시스템이 한 발 더 가까워졌네 🎯


🎓 코치의 피드백

잘한 점:
레이아웃 padding/spacing을 일관되게 표준화(32/16)하고, onChange 핸들러로 상태 동기화를 명시적으로 구현한 것이 좋습니다. SettingsView의 섹션 구조 정리도 스칼라빌리티 향상이 눈에 띕니다.

개선 제안:

  1. 색상값 변경 검증 (InsightType.swift)

    • subPinksubPink2, subPink1subPink1 변경의 의도를 확인하세요
    • 디자인 시스템에 정의된 색상 팔레트와의 매핑이 정확한지, 다른 곳에서도 동일하게 적용되었는지 검토하면 좋습니다
    • 참고: 색상 일관성은 SwiftUI 앱의 유지보수성에 큰 영향을 줍니다
  2. 상태 로딩 순서 (PersonalizationView)

    • loadRecent(), loadSetting(), loadStatistics()의 실행 순서와 의존성 검토를 추천합니다
    • 특히 loadRecent()가 다른 데이터에 의존하는 경우, structured concurrency 패턴 적용을 고려해보세요
  3. Alert 로컬라이제이션

    • "개인화 데이터를 리셋하시겠습니까?" 같은 문자열은 별도의 상수나 localization 파일로 관리하면, 추후 다국어 대응이 수월합니다
🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Description check ❓ Inconclusive PR 설명이 필수 섹션을 모두 포함하고 있으나 '작업내용', '추후 진행 상황', '리뷰 포인트' 섹션이 실질적 내용 없이 템플릿 텍스트만 남아있습니다. 작업내용에 구체적인 변경 사항(패딩값 변경, 컬러 수정 등)과 스크린샷 추가, 리뷰 포인트에 검토 중점 기술이 필요합니다.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed PR 제목이 변경사항의 주요 내용을 명확히 반영하고 있습니다. 마이페이지 레이아웃 개선이라는 핵심 변화가 잘 드러나 있습니다.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ 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 refactor/mypage-layout

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.

@e0ng e0ng changed the title [Refactor] 마이페이지 레이아웃 및 UI 스타일 개선 [Refactor] MyPage 레이아웃 개선 및 디자인 반영02 Feb 19, 2026
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: 2

🧹 Nitpick comments (3)
TAMINGO/Features/MyPage/Personalization/View/PersonalizationView.swift (2)

91-95: onChange 클로저의 newValue 파라미터가 사용되지 않습니다

newValue를 선언했지만 클로저 본문에서 전혀 사용되지 않습니다. iOS 17+에서는 파라미터 없는 단축 형태를 사용할 수 있습니다.

✨ 간결하게 정리
-.onChange(of: viewModel.personalizationSetting) { _, newValue in
+.onChange(of: viewModel.personalizationSetting) {
     Task {
         await viewModel.updateSetting()
     }
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@TAMINGO/Features/MyPage/Personalization/View/PersonalizationView.swift`
around lines 91 - 95, The onChange closure currently declares unused parameters
("_, newValue") when observing viewModel.personalizationSetting; remove the
unused parameters and use the parameterless shorthand closure (or single
implicit parameter) so the body simply starts the Task and calls await
viewModel.updateSetting(); update the call site of onChange(of:
viewModel.personalizationSetting) to omit the unused parameters and keep the
Task { await viewModel.updateSetting() } body, referencing onChange,
viewModel.personalizationSetting, and viewModel.updateSetting to locate the
change.

87-90: 명시적인 await로 병렬 작업을 명확하게 조정하세요

async let _ 패턴은 Swift에서 문법적으로 유효하지만(SE-0317), 의도가 불명확합니다. 이 패턴은 바인딩된 값을 읽지 않으므로 스코프 종료 시점에 자동으로 취소/대기되는데, 이는 개발자에게 예상치 못한 일시 중단점을 만들 수 있습니다.

세 작업이 병렬로 실행되고 모두 완료될 때까지 대기한다는 의도를 명확히 하려면, 명시적으로 이름을 붙이고 await로 조정하세요. 이는 Swift 공식 커뮤니티 가이드라인의 권장 패턴입니다:

♻️ 개선 제안
 .task {
-    async let _ = viewModel.loadSetting()
-    async let _ = viewModel.loadStatistics()
-    async let _ = viewModel.loadRecent()
+    async let setting: Void = viewModel.loadSetting()
+    async let statistics: Void = viewModel.loadStatistics()
+    async let recent: Void = viewModel.loadRecent()
+    _ = await (setting, statistics, recent)
 }

이렇게 작성하면 구조화된 동시성(structured concurrency)의 fork-join 패턴이 명확해지고, 의도하지 않은 스코프 종료 대기 동작을 피할 수 있습니다.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@TAMINGO/Features/MyPage/Personalization/View/PersonalizationView.swift`
around lines 87 - 90, The three parallel calls using "async let _ =
viewModel.loadSetting()", "async let _ = viewModel.loadStatistics()", and "async
let _ = viewModel.loadRecent()" should be made explicit: declare named async
lets (e.g., let setting = async let ... , let stats = async let ... , let recent
= async let ...) and then await them (await setting, await stats, await recent)
so the fork-join semantics are clear and you avoid implicit cancellation/await
at scope exit; update the code that currently uses those unnamed async lets to
use the named bindings and explicit awaits.
TAMINGO/Features/MyPage/WeeklyReport/Model/InsightType.swift (1)

41-41: borderColortitleColor가 둘 다 .subPink2로 동일합니다

다른 케이스들은 border와 title 색상이 서로 구분되어 있습니다:

  • .productivity: subGreen2 / subGreen3
  • .arrival: subYellow2 / subYellow3
  • .task: subBlue3 / subBlue2

.suggestionborderColor(Line 41)와 titleColor(Line 71) 둘 다 .subPink2를 사용합니다. 의도된 디자인 결정이라면 문제없지만, 일관성 차원에서 한 번 더 확인해보세요.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@TAMINGO/Features/MyPage/WeeklyReport/Model/InsightType.swift` at line 41, In
the InsightType enum's .suggestion case, borderColor and titleColor are both set
to .subPink2; update the titleColor for .suggestion from .subPink2 to .subPink3
(i.e., change the titleColor value in the .suggestion branch) so the title and
border follow the same contrasting pattern used by other cases (refer to
borderColor, titleColor and the .suggestion case in InsightType).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@TAMINGO/Features/MyPage/Setting/SettingsView.swift`:
- Around line 29-34: The SettingCard instances in SettingsView.swift currently
use print(...) placeholders (e.g., the "업데이트 확인" and "오픈소스 라이선스" SettingCard
actions and others like "서비스 이용약관", "개인정보 처리방침", "위치 정보 이용약관", "의견 보내기") —
replace each print call with an appropriate real navigation/action: use
NavigationLink for in-app screens (e.g., license or settings detail), call
UIApplication.shared.open(_:) for external URLs (terms/privacy/location), or if
the implementation is pending add a clear TODO comment (e.g., // TODO: implement
navigation for "업데이트 확인") so no inert print remains in release builds; update
the closures attached to SettingCard to perform the chosen action and keep
identifiers like SettingCard and the title strings to locate each item.
- Around line 27-34: The SettingCard for "업데이트 확인" currently hardcodes sub: "최신
버전"; change it to a non-misleading placeholder (e.g., empty string or "확인 중")
until actual version-comparison logic is implemented. Locate the SettingCard
invocation (SettingCard(title: "업데이트 확인", sub: ...)) in SettingsView and replace
the literal "최신 버전" with a safe default or viewModel-provided state (e.g., use
viewModel.appVersion or an empty string/placeholder) so the UI doesn't claim the
app is up-to-date prematurely.

---

Nitpick comments:
In `@TAMINGO/Features/MyPage/Personalization/View/PersonalizationView.swift`:
- Around line 91-95: The onChange closure currently declares unused parameters
("_, newValue") when observing viewModel.personalizationSetting; remove the
unused parameters and use the parameterless shorthand closure (or single
implicit parameter) so the body simply starts the Task and calls await
viewModel.updateSetting(); update the call site of onChange(of:
viewModel.personalizationSetting) to omit the unused parameters and keep the
Task { await viewModel.updateSetting() } body, referencing onChange,
viewModel.personalizationSetting, and viewModel.updateSetting to locate the
change.
- Around line 87-90: The three parallel calls using "async let _ =
viewModel.loadSetting()", "async let _ = viewModel.loadStatistics()", and "async
let _ = viewModel.loadRecent()" should be made explicit: declare named async
lets (e.g., let setting = async let ... , let stats = async let ... , let recent
= async let ...) and then await them (await setting, await stats, await recent)
so the fork-join semantics are clear and you avoid implicit cancellation/await
at scope exit; update the code that currently uses those unnamed async lets to
use the named bindings and explicit awaits.

In `@TAMINGO/Features/MyPage/WeeklyReport/Model/InsightType.swift`:
- Line 41: In the InsightType enum's .suggestion case, borderColor and
titleColor are both set to .subPink2; update the titleColor for .suggestion from
.subPink2 to .subPink3 (i.e., change the titleColor value in the .suggestion
branch) so the title and border follow the same contrasting pattern used by
other cases (refer to borderColor, titleColor and the .suggestion case in
InsightType).

Comment on lines +27 to +34
print("버전 정보 탭")
}
SettingCard(title: "업데이트 확인", sub: "최신 버전", subColor: .mainMint) {
print("업데이트 확인 탭")
}
SettingCard(title: "오픈소스 라이선스") {
print("오픈소스 라이선스 탭")
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

"업데이트 확인"의 sub 텍스트 "최신 버전"이 하드코딩되어 있습니다

현재는 실제 버전 비교 없이 항상 "최신 버전"을 표시합니다. 사용자에게 잘못된 정보를 줄 수 있는 UI입니다. viewModel.appVersion을 실제 앱스토어 최신 버전과 비교하는 로직이 연결되기 전까지는 빈 문자열이나 다른 상태 표시로 대체하는 것을 권장합니다.

🛡️ 임시 처리 제안
-SettingCard(title: "업데이트 확인", sub: "최신 버전", subColor: .mainMint) {
+SettingCard(title: "업데이트 확인", sub: viewModel.updateStatus) {
     print("업데이트 확인 탭")
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@TAMINGO/Features/MyPage/Setting/SettingsView.swift` around lines 27 - 34, The
SettingCard for "업데이트 확인" currently hardcodes sub: "최신 버전"; change it to a
non-misleading placeholder (e.g., empty string or "확인 중") until actual
version-comparison logic is implemented. Locate the SettingCard invocation
(SettingCard(title: "업데이트 확인", sub: ...)) in SettingsView and replace the
literal "최신 버전" with a safe default or viewModel-provided state (e.g., use
viewModel.appVersion or an empty string/placeholder) so the UI doesn't claim the
app is up-to-date prematurely.

Comment on lines +29 to +34
SettingCard(title: "업데이트 확인", sub: "최신 버전", subColor: .mainMint) {
print("업데이트 확인 탭")
}
SettingCard(title: "오픈소스 라이선스") {
print("오픈소스 라이선스 탭")
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

신규 메뉴 항목들의 print 플레이스홀더 액션이 남아 있습니다

"업데이트 확인", "오픈소스 라이선스", "서비스 이용약관", "개인정보 처리방침", "위치 정보 이용약관", "의견 보내기" 모두 print(...) 만 실행합니다. 릴리즈 빌드에서도 동작 없는 버튼이 노출됩니다.

실제 네비게이션(NavigationLink, UIApplication.shared.open(_:) 등) 또는 TODO 주석으로 대체를 권장합니다.

추적 이슈로 등록하거나, 각 항목별 네비게이션 로직을 구현하는 초안이 필요하시면 도움드릴 수 있습니다.

Also applies to: 51-68

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@TAMINGO/Features/MyPage/Setting/SettingsView.swift` around lines 29 - 34, The
SettingCard instances in SettingsView.swift currently use print(...)
placeholders (e.g., the "업데이트 확인" and "오픈소스 라이선스" SettingCard actions and others
like "서비스 이용약관", "개인정보 처리방침", "위치 정보 이용약관", "의견 보내기") — replace each print call
with an appropriate real navigation/action: use NavigationLink for in-app
screens (e.g., license or settings detail), call UIApplication.shared.open(_:)
for external URLs (terms/privacy/location), or if the implementation is pending
add a clear TODO comment (e.g., // TODO: implement navigation for "업데이트 확인") so
no inert print remains in release builds; update the closures attached to
SettingCard to perform the chosen action and keep identifiers like SettingCard
and the title strings to locate each item.

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.

1 participant