Skip to content

feat - 프로필 설정 작업#44

Merged
mark77234 merged 9 commits intodevfrom
feat/39
Mar 5, 2026
Merged

feat - 프로필 설정 작업#44
mark77234 merged 9 commits intodevfrom
feat/39

Conversation

@mark77234
Copy link
Collaborator

작업내용

  • 프로필 설정 페이지 리팩토링
  • 팬덤, PICKS 비활성화
  • 프로필 이미지 삭제, 수정 API 연동
  • 태그 수정 API 연동

Copilot AI review requested due to automatic review settings March 5, 2026 12:04
@mark77234 mark77234 linked an issue Mar 5, 2026 that may be closed by this pull request
@mark77234 mark77234 merged commit fe111b7 into dev Mar 5, 2026
2 checks passed
@mark77234 mark77234 deleted the feat/39 branch March 5, 2026 12:04
mark77234 added a commit that referenced this pull request Mar 5, 2026
* refactor(MyCollectionProfileSettings): 프로필 설정 페이지 분리작업

* feat(ProfileCard): 팬덤, PICKS 비활성화

* feat(ProfileSetting): 프로필 이미지 변경, 삭제, 태그 수정 API 연동

* feat(ProfileSetting): 프로필 설정 페이지 UI/UX 업데이트

* feat(ProfileSetting): UI 디테일 수정

* feat(ProfileSetting): 태그 수정 시 도움말 추가

* refactor(ProfileSetting): 리팩토링

* feat(ProfileSetting): 여백 설정

* feat(1.0.18): 버전 업데이트
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

내 컬렉션(MyCollection) 내 프로필 설정 화면을 리팩토링하고, 프로필 이미지 삭제/수정 및 태그 수정 APIProfileSettingViewModel 기반으로 연동한 변경입니다. 팬덤/PICKS 표시는 비활성화되었습니다.

Changes:

  • 프로필 설정 UI를 컴포넌트 단위로 분리하고, 태그 편집(검증/상태/키보드 대응) UX 추가
  • ProfileSettingViewModel + UserService 확장으로 프로필 이미지(프리사인드 업로드) / 태그 업데이트 API 연동
  • MyCollection 화면에서 프로필 설정 전용 VM을 분리해 화면 전환/유저 동기화 처리

Reviewed changes

Copilot reviewed 15 out of 18 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
KillingPart/Views/Screens/Main/My/MyCollection/ProfileSetting/components/MyCollectionProfileTagSectionView.swift 태그 표시/편집 입력 영역 UI 추가
KillingPart/Views/Screens/Main/My/MyCollection/ProfileSetting/components/MyCollectionProfileTagEditActionRowView.swift 태그 편집 취소/저장 액션 UI 추가
KillingPart/Views/Screens/Main/My/MyCollection/ProfileSetting/components/MyCollectionProfileSettingsInfoRowView.swift (현재 미사용) 프로필 정보 Row UI 추가
KillingPart/Views/Screens/Main/My/MyCollection/ProfileSetting/components/MyCollectionProfileSettingsInfoCardView.swift (현재 미사용) 프로필 정보 카드 UI 추가
KillingPart/Views/Screens/Main/My/MyCollection/ProfileSetting/components/MyCollectionProfileSettingsHeaderView.swift 프로필 설정 헤더 UI 교체/단순화
KillingPart/Views/Screens/Main/My/MyCollection/ProfileSetting/components/MyCollectionProfileSettingPageContainerView.swift 프로필 설정 페이지 컨테이너(배경/패딩/높이) 추가
KillingPart/Views/Screens/Main/My/MyCollection/ProfileSetting/components/MyCollectionProfileImageColumnView.swift PhotosPicker 기반 프로필 이미지 선택/리셋 UI 추가
KillingPart/Views/Screens/Main/My/MyCollection/ProfileSetting/components/MyCollectionAccountActionButton.swift 로그아웃/회원탈퇴 진입 버튼 컴포넌트 추가
KillingPart/Views/Screens/Main/My/MyCollection/ProfileSetting/ProfileSettingSection.swift 프로필 설정 섹션 본체(키보드 inset, 태그 검증/제출, 이미지 처리) 구현
KillingPart/Views/Screens/Main/My/MyCollection/MyCollectionView.swift 프로필 설정 전용 VM 주입/유저 동기화/업데이트 반영 연결
KillingPart/Views/Screens/Main/My/MyCollection/Components/ProfileSettingSection/MyCollectionProfileSettingsSection.swift 기존 단순 프로필 설정 섹션 제거
KillingPart/Views/Screens/Main/My/MyCollection/Components/ProfileSettingSection/MyCollectionProfileSettingsHeaderView.swift 기존 헤더 제거(새 헤더로 대체)
KillingPart/Views/Screens/Main/My/MyCollection/Components/ProfileCard/MyCollectionProfileCard.swift 팬덤/PICKS UI 비활성화(현재는 주석 처리)
KillingPart/ViewModels/My/MyCollection/ProfileSetting/ProfileSettingViewModel.swift 프로필 설정 전용 VM 신설(태그/이미지 업데이트, 상태/메시지 관리)
KillingPart/ViewModels/My/MyCollection/MyCollectionViewModel.swift 유저 업데이트 반영 헬퍼(applyUpdatedUser) 추가
KillingPart/Services/UserService.swift 프로필 이미지 삭제/프리사인드 발급/업로드/태그 업데이트 API 추가 + 에러 메시지 정규화
KillingPart/Models/UserModel.swift Presigned URL/요청 DTO 추가
KillingPart.xcodeproj/project.pbxproj 앱 버전(빌드/마케팅) 업데이트 (16→18)

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

Comment on lines +186 to +189
return TagHelperMessage(
text: "30자 이내의 영문과 숫자, 특수문자([.],[_])로 조합해주세요.",
color: .red.opacity(0.95)
)
Copy link

Copilot AI Mar 5, 2026

Choose a reason for hiding this comment

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

The helper copy here says "영문" but the actual tag validator only allows lowercase a–z (allowedCharacters excludes A–Z). Align the helper text with the real rule (e.g., explicitly say "영문 소문자") or change validation to accept/normalize uppercase to avoid confusing rejections.

Copilot uses AI. Check for mistakes.
Comment on lines +234 to +257
let normalizedMessage = message?
.trimmingCharacters(in: .whitespacesAndNewlines)
.lowercased() ?? ""

if normalizedMessage.contains("이미 존재")
|| normalizedMessage.contains("이미 사용")
|| normalizedMessage.contains("already")
{
tagValidationFeedback = .duplicate
return
}

if normalizedMessage.contains("tag는")
|| normalizedMessage.contains("30")
|| normalizedMessage.contains("영문")
|| normalizedMessage.contains("소문자")
|| normalizedMessage.contains("연속")
|| normalizedMessage.contains("형식")
{
tagValidationFeedback = .invalidFormat
return
}

tagValidationFeedback = .unavailable
Copy link

Copilot AI Mar 5, 2026

Choose a reason for hiding this comment

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

updateTagValidationFeedback(from:) classifies failures by substring-matching (localized) error messages. This is brittle (server copy/locale changes can misclassify). Prefer propagating a typed error/code from UserService/ProfileSettingViewModel and switching on that instead of parsing strings.

Suggested change
let normalizedMessage = message?
.trimmingCharacters(in: .whitespacesAndNewlines)
.lowercased() ?? ""
if normalizedMessage.contains("이미 존재")
|| normalizedMessage.contains("이미 사용")
|| normalizedMessage.contains("already")
{
tagValidationFeedback = .duplicate
return
}
if normalizedMessage.contains("tag는")
|| normalizedMessage.contains("30")
|| normalizedMessage.contains("영문")
|| normalizedMessage.contains("소문자")
|| normalizedMessage.contains("연속")
|| normalizedMessage.contains("형식")
{
tagValidationFeedback = .invalidFormat
return
}
tagValidationFeedback = .unavailable
// Treat `message` as a stable, non-localized error code (e.g. "tag_duplicate",
// "tag_invalid_format", "tag_unavailable") instead of parsing localized text.
let normalizedCode = message?
.trimmingCharacters(in: .whitespacesAndNewlines)
.lowercased() ?? ""
switch normalizedCode {
case "tag_duplicate",
"duplicate",
"tag_already_exists":
tagValidationFeedback = .duplicate
case "tag_invalid_format",
"invalid_format",
"bad_request_tag_format":
tagValidationFeedback = .invalidFormat
case "tag_unavailable",
"unavailable",
"":
// Default or explicit "unavailable" error.
fallthrough
default:
tagValidationFeedback = .unavailable
}

Copilot uses AI. Check for mistakes.
Comment on lines +14 to +18
Button(action: onBackTap) {
HStack(spacing: 6) {
Image(systemName: "arrow.left")
.font(.system(size: 20, weight: .semibold))
}
Copy link

Copilot AI Mar 5, 2026

Choose a reason for hiding this comment

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

The back button is image-only and lacks an accessibility label. Add an accessibilityLabel (e.g., "뒤로가기") so VoiceOver users can navigate reliably.

Copilot uses AI. Check for mistakes.
Comment on lines +38 to +39
// MyCollectionProfileStatItemView(value: fanStatText, title: "팬덤")
// MyCollectionProfileStatItemView(value: pickStatText, title: "PICKS")
Copy link

Copilot AI Mar 5, 2026

Choose a reason for hiding this comment

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

Commented-out SwiftUI views tend to linger and make future edits harder (and keep unused props like fanStatText/pickStatText around). If 팬덤/PICKS are intentionally disabled, prefer deleting these lines and cleaning up the unused properties (or gating behind a clear feature flag).

Suggested change
// MyCollectionProfileStatItemView(value: fanStatText, title: "팬덤")
// MyCollectionProfileStatItemView(value: pickStatText, title: "PICKS")

Copilot uses AI. Check for mistakes.

func syncUser(_ user: UserModel?) {
self.user = user
tagDraft = user?.tag ?? ""
Copy link

Copilot AI Mar 5, 2026

Choose a reason for hiding this comment

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

tagDraft is set directly from user.tag, which can already include an "@" (other view models treat user.tag as optionally prefixed). Since the edit UI renders a separate "@" label, this can result in a duplicated "@@" in the text field. Consider storing a normalized (no-leading-@, trimmed) value in tagDraft in syncUser (and in applyUpdatedUser).

Suggested change
tagDraft = user?.tag ?? ""
let rawTag = user?.tag ?? ""
tagDraft = normalizedTag(from: rawTag)

Copilot uses AI. Check for mistakes.
Comment on lines +13 to +16
Button(action: onCancel) {
Image(systemName: "xmark.circle.fill")
.font(.system(size: 22, weight: .semibold))
.foregroundStyle(.white.opacity(0.72))
Copy link

Copilot AI Mar 5, 2026

Choose a reason for hiding this comment

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

This cancel button is icon-only, but it doesn't provide an accessibility label/hint. Add accessibilityLabel (e.g., "태그 편집 취소") so VoiceOver users can understand the action.

Copilot uses AI. Check for mistakes.
Comment on lines +21 to +25
Button(action: onSubmit) {
if isProcessing {
ProgressView()
.tint(AppColors.primary600)
} else {
Copy link

Copilot AI Mar 5, 2026

Choose a reason for hiding this comment

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

This submit button (including the loading ProgressView state) is effectively icon-only and lacks an accessibility label. Add accessibilityLabel (and optionally a loading hint/value) so the action is understandable with VoiceOver.

Copilot uses AI. Check for mistakes.
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