Skip to content

[#37] Feat/37/마이페이지 - #41

Merged
LMS10 merged 8 commits into
mainfrom
Feat/37/마이페이지
May 13, 2026

Hidden character warning

The head ref may contain hidden characters: "Feat/37/\ub9c8\uc774\ud398\uc774\uc9c0"
Merged

[#37] Feat/37/마이페이지#41
LMS10 merged 8 commits into
mainfrom
Feat/37/마이페이지

Conversation

@LMS10

@LMS10 LMS10 commented May 12, 2026

Copy link
Copy Markdown
Owner

❓이슈

📝 Description

/mypage 페이지 반응형 구현 및 프로필·비밀번호 변경 API 연동

크게 프로필 변경 섹션비밀번호 변경 섹션으로 나뉘며,
각 섹션에 필요한 API 레이어(file, user)도 함께 작성했습니다.
작업 중 발견된 드롭다운 버그와 헤더 z-index 이슈도 함께 수정했습니다.


메서드 엔드포인트 설명
POST /api/v1/files?type=PROFILE 파일 업로드 → fileId 반환
PATCH /api/v1/users/me/profile-image 프로필 이미지 변경
PATCH /api/v1/users/me 이름 수정
PATCH /api/v1/users/me/password 비밀번호 변경

🗂️ 구현 상세

1. 공통 에러 처리 — apiError.ts

fetch!res.ok일 때 status를 담은 ApiError를 throw하고, catch (err: unknown) 블록에서 isApiError(err)로 타입을 좁혀 에러 코드별 분기 처리합니다. any 타입 없이 타입 안전하게 에러를 다룰 수 있도록 설계했습니다.

2. 파일 업로드 플로우

파일 선택 → POST /api/v1/files?type=PROFILE
→ fileId 반환
→ PATCH /api/v1/users/me/profile-image { fileId }

type=PROFILE일 때는 workspaceId 없이 요청합니다. 추후 영수증 업로드 시 type=RECEIPT, workspaceId 전달만으로 동일 함수를 재사용할 수 있도록 설계했습니다.

3. 저장 버튼 활성화 조건

조건 버튼 상태
이미지·이름 모두 변경 없음 disabled
이름이 빈 문자열 disabled
이미지 또는 이름 하나 이상 변경 enabled
요청 중 loading

4. 프로필 저장 시 동시 요청

await Promise.all([
  // 이미지가 변경된 경우만
  uploadFile({ file, type: 'PROFILE' }).then(({ fileId }) =>
    updateProfileImage({ fileId })
  ),
  // 이름이 변경된 경우만
  updateName({ name }),
]);

두 요청 중 하나라도 실패하면 해당 에러 토스트만 표시하고, 나머지 성공한 요청은 유지됩니다.

5. 저장 성공 후 즉시 갱신

await queryClient.invalidateQueries({ queryKey: ['auth', 'me'] });
router.refresh();

invalidateQueriesuseGetMe() 캐시를 무효화해 헤더의 HeaderUserProfile(이름·이미지)이 새로고침 없이 즉시 갱신됩니다.

6. 이름·이미지 초기값 동기화

useSession() 대신 useGetMe()를 기준으로 useEffect에서 초기화합니다. invalidateQueriesuseGetMe()가 최신 데이터를 다시 받아오면 effect가 재실행되어 저장 후 이름·이미지가 자동으로 업데이트됩니다.

7. 비밀번호 변경 에러 처리

상황 위치 메시지
새 비밀번호 ≠ 확인 (클라이언트) 새 비밀번호 확인 하단 새 비밀번호가 일치하지 않습니다.
401 현재 비밀번호 하단 현재 비밀번호가 일치하지 않습니다.
400 새 비밀번호 하단 비밀번호는 영문, 숫자, 특수문자 포함 6자 이상입니다.
기타 토스트 비밀번호 변경에 실패했습니다.

8. 버그 수정

드롭다운 닫힘 순서
onSelect 호출 전에 setOpen(false)를 먼저 실행하도록 순서를 변경했습니다. 기존에는 router.push() 호출 후 컴포넌트가 언마운트되면서 setOpen이 무시되어 특정 페이지에서 드롭다운이 닫히지 않는 문제가 있었습니다.

헤더 z-index
headerz-10을 추가해 Image 컴포넌트의 stacking context 위로 올라오도록 수정했습니다.

HeaderUserProfile 드롭다운 경로 변경 시 닫힘
key={pathname}을 사용해 경로가 변경될 때 컴포넌트를 리마운트시켜 open state가 false로 초기화되도록 했습니다.

image

🌀 PR Type

어떤 변경 사항이 있나요?

  • 새로운 기능 추가
  • 버그 수정
  • CSS 등 사용자 UI 디자인 변경
  • 코드에 영향을 주지 않는 변경사항 (오타 수정, 탭 사이즈 변경, 변수명 변경)
  • 코드 리팩토링
  • 주석 추가 및 수정
  • 문서 수정
  • 테스트 추가, 테스트 리팩토링
  • 빌드 부분 혹은 패키지 매니저 수정
  • 파일 혹은 폴더명 수정
  • 파일 혹은 폴더 삭제

✅ Checklist

PR Checklist

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

  • Branch Convention 확인

    feat/ 기능 구현, fix/ 버그 수정, refactor/ 개선

  • Base Branch 확인
  • 커밋 메시지 컨벤션 준수
  • 적절한 Label 지정
  • Assignee 및 Reviewer 지정

Test Checklist

  • 로컬 작동 확인

@LMS10
LMS10 requested a review from minzx23 May 12, 2026 10:12
@LMS10 LMS10 self-assigned this May 12, 2026
@LMS10 LMS10 added Priority: Medium 🔖 우선순위 보통 Type: Feature ✨ 신규 기능 labels May 12, 2026
@vercel

vercel Bot commented May 12, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
remate Ready Ready Preview, Comment May 12, 2026 10:12am

@minzx23 minzx23 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.

고생하셨습니다!!

@LMS10
LMS10 merged commit 2804eff into main May 13, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Priority: Medium 🔖 우선순위 보통 Type: Feature ✨ 신규 기능

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Feat : 마이페이지 작업

2 participants