-
Notifications
You must be signed in to change notification settings - Fork 2
✨Feat: 비밀번호 변경 컴포넌트 구현 #80
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Walkthrough마이페이지(프로필 수정/비밀번호 변경) 기능이 새롭게 도입되었습니다. 인증 및 대시보드 관련 HTTP 클라이언트가 Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant ProfileEditForm
participant ProfileImageUpload
participant useUploadProfileImageMutation
participant useUpdateMyProfileMutation
participant API
User->>ProfileEditForm: 프로필 정보 입력 및 제출
ProfileEditForm->>ProfileImageUpload: 이미지 선택
ProfileEditForm->>useUploadProfileImageMutation: (이미지 변경 시) 이미지 업로드
useUploadProfileImageMutation->>API: 이미지 업로드 요청
API-->>useUploadProfileImageMutation: 업로드 결과(이미지 URL)
ProfileEditForm->>useUpdateMyProfileMutation: 닉네임/이미지 URL로 프로필 수정
useUpdateMyProfileMutation->>API: 프로필 수정 요청
API-->>useUpdateMyProfileMutation: 수정 결과
useUpdateMyProfileMutation-->>ProfileEditForm: 성공/실패 알림
ProfileEditForm-->>User: 성공 토스트 및 페이지 새로고침
sequenceDiagram
participant User
participant PasswordChangeForm
participant useChangePasswordMutation
participant API
User->>PasswordChangeForm: 현재/새 비밀번호 입력 및 제출
PasswordChangeForm->>useChangePasswordMutation: 비밀번호 변경 요청
useChangePasswordMutation->>API: 비밀번호 변경 API 호출
API-->>useChangePasswordMutation: 성공/실패 응답
useChangePasswordMutation-->>PasswordChangeForm: 성공/실패 알림
PasswordChangeForm-->>User: 성공 토스트 및 폼 리셋
Possibly related issues
Possibly related PRs
Suggested labels
Suggested reviewers
Poem
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 ESLint
npm error Exit handler never called! ✨ Finishing Touches
🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🧹 Nitpick comments (8)
src/app/features/mypage/hook/useUserQurey.ts (2)
1-11: 파일명 오타를 수정해주세요.파일명에 오타가 있습니다:
useUserQurey.ts→useUserQuery.ts로 수정이 필요합니다.- // 파일명: useUserQurey.ts + // 파일명: useUserQuery.ts
7-7: 쿼리 키를 더 구체적으로 개선하는 것을 고려해보세요.현재
['loadUser']쿼리 키보다는['user', 'me']와 같이 더 구체적이고 계층적인 키를 사용하는 것이 쿼리 관리에 유리할 수 있습니다.- queryKey: ['loadUser'], + queryKey: ['user', 'me'],src/app/shared/components/common/WhitePenIcon/WhitePenIcon.tsx (1)
1-21: 아이콘 컴포넌트가 잘 구현되었습니다.타입스크립트 타입 정의와 기본값 설정이 적절하며, SVG props 확장을 통한 유연성도 좋습니다.
다만
viewBox="0 0 24 24"가 고정되어 있어서 size가 24와 크게 다를 때 비례 조정이 어려울 수 있습니다. 큰 문제는 아니지만 향후 고려해볼 점입니다.src/app/shared/components/common/CloseCircleIcon/CloseCircleIcon.tsx (1)
10-11: 불필요한 Fragment 래퍼를 제거하세요.SVG 엘리먼트 하나만 반환하므로 Fragment가 필요하지 않습니다.
- <> <svg width={size} height={size} viewBox="0 0 24 24" fill="none" {...props} > {/* ... SVG content ... */} </svg> - </>Also applies to: 38-39
src/app/features/mypage/components/ProfileEditForm.tsx (2)
55-90: 폼 제출 로직이 복잡하지만 잘 구조화되어 있습니다.이미지 업로드 후 프로필 업데이트 순서가 논리적이며, 에러 처리도 포괄적입니다. 다만 mutation hook과 컴포넌트에서 에러 처리 로직이 중복되는 부분이 있습니다.
에러 처리 로직을 공통 유틸리티로 추출하는 것을 고려해보세요:
+// utils/errorHandler.ts +export const handleApiError = (error: unknown, fallbackMessage: string) => { + if (isAxiosError(error)) { + const serverMessage = (error.response?.data as { message?: string })?.message + const message = serverMessage ?? error.message ?? fallbackMessage + showError(message) + } else { + showError('알 수 없는 에러 발생') + } +}
76-77: router.refresh() 사용에 대한 검토가 필요합니다.React Query의 캐시 무효화를 사용하는 것이 더 효율적일 수 있습니다. 전체 페이지 새로고침보다는 쿼리 무효화를 고려해보세요.
-showSuccess('프로필 변경이 완료되었습니다.') -router.refresh() +showSuccess('프로필 변경이 완료되었습니다.') +// React Query 캐시 무효화 사용 고려 +queryClient.invalidateQueries(['loadUser'])src/app/features/mypage/components/ProfileImageUpload.tsx (2)
28-42: 파일 선택 로직이 잘 구현되었습니다. Optional chaining 사용을 고려해보세요.파일 선택 및 미리보기 URL 생성, 상위 컴포넌트로의 파일 전달 로직이 모두 적절합니다. 같은 파일 재선택을 위한 input 값 초기화도 좋습니다.
다만 41번째 라인에서 optional chaining을 사용하면 더 간결해집니다:
- if (inputRef.current) inputRef.current.value = '' + inputRef.current && (inputRef.current.value = '')
44-52: 메모리 누수 방지 로직이 훌륭합니다. Optional chaining 적용을 고려해보세요.blob URL 확인 후
URL.revokeObjectURL호출로 메모리 누수를 방지하는 로직이 잘 구현되어 있습니다. 상태 초기화도 적절합니다.51번째 라인에서도 optional chaining을 사용할 수 있습니다:
- if (inputRef.current) inputRef.current.value = '' + inputRef.current && (inputRef.current.value = '')
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (27)
src/app/features/auth/api/authApi.ts(1 hunks)src/app/features/auth/components/SignupForm.tsx(2 hunks)src/app/features/auth/hooks/useConfirmPasswordValidation.ts(0 hunks)src/app/features/auth/hooks/useLoginMutation.ts(1 hunks)src/app/features/auth/hooks/useSignupMutation.ts(1 hunks)src/app/features/mypage/api/mypageApi.ts(1 hunks)src/app/features/mypage/api/mypageEndPoint.ts(1 hunks)src/app/features/mypage/components/PasswordChangeForm.tsx(1 hunks)src/app/features/mypage/components/ProfileEditForm.tsx(1 hunks)src/app/features/mypage/components/ProfileImageUpload.tsx(1 hunks)src/app/features/mypage/hook/useChangePasswordMutation.ts(1 hunks)src/app/features/mypage/hook/useNewPasswordValidation.ts(1 hunks)src/app/features/mypage/hook/useUpdateMyProfileMutation.ts(1 hunks)src/app/features/mypage/hook/useUploadProfileImageMutation.ts(1 hunks)src/app/features/mypage/hook/useUserQurey.ts(1 hunks)src/app/features/mypage/schemas/mypageValidation.ts(1 hunks)src/app/features/mypage/types/mypage.type.ts(1 hunks)src/app/globals.css(1 hunks)src/app/mypage/page.tsx(2 hunks)src/app/shared/components/Input.tsx(2 hunks)src/app/shared/components/common/CloseCircleIcon/CloseCircleIcon.tsx(1 hunks)src/app/shared/components/common/PlusIcon/PlusIcon.tsx(1 hunks)src/app/shared/components/common/WhitePenIcon/WhitePenIcon.tsx(1 hunks)src/app/shared/components/common/sidebar/modal/CreateDashboardModal.tsx(2 hunks)src/app/shared/hooks/useConfirmPasswordValidation.ts(1 hunks)src/app/shared/hooks/useDashboard.ts(2 hunks)src/app/shared/lib/axios.ts(1 hunks)
💤 Files with no reviewable changes (1)
- src/app/features/auth/hooks/useConfirmPasswordValidation.ts
🧰 Additional context used
🧠 Learnings (2)
src/app/features/auth/components/SignupForm.tsx (1)
Learnt from: Insung-Jo
PR: CoPlay-FE/coplan#57
File: src/app/features/auth/hooks/useSignupSubmit.ts:12-0
Timestamp: 2025-06-16T09:44:38.218Z
Learning: In src/app/features/auth/hooks/useSignupSubmit.ts, the developer intentionally uses SignupRequest type instead of SignupFormData for the submit function parameter to prevent sending unnecessary confirmPassword field to the API, aligning the function signature with server expectations.
src/app/shared/components/common/CloseCircleIcon/CloseCircleIcon.tsx (1)
Learnt from: Insung-Jo
PR: CoPlay-FE/coplan#78
File: src/app/shared/components/common/CloseCircleIcon/CloseCircleIcon.tsx:24-24
Timestamp: 2025-06-18T19:28:36.654Z
Learning: In the CloseCircleIcon component (src/app/shared/components/common/CloseCircleIcon/CloseCircleIcon.tsx), the stroke color for the X lines is intentionally hardcoded as "black" for contrast purposes, while the circle fill uses "currentColor" to adapt to themes. This is a deliberate design choice, not an oversight.
🧬 Code Graph Analysis (15)
src/app/shared/hooks/useDashboard.ts (1)
src/app/shared/types/dashboard.ts (1)
DashboardListResponse(13-17)
src/app/features/auth/hooks/useSignupMutation.ts (1)
src/app/shared/lib/toast.ts (1)
showError(4-4)
src/app/features/auth/api/authApi.ts (2)
src/app/features/auth/types/auth.type.ts (3)
LoginRequest(3-6)LoginResponse(8-11)SignupRequest(13-17)src/app/features/auth/api/authEndpoint.ts (1)
AUTH_ENDPOINT(1-4)
src/app/features/auth/hooks/useLoginMutation.ts (1)
src/app/shared/lib/toast.ts (1)
showError(4-4)
src/app/features/auth/components/SignupForm.tsx (1)
src/app/shared/hooks/useConfirmPasswordValidation.ts (1)
useConfirmPasswordValidation(1-7)
src/app/features/mypage/hook/useNewPasswordValidation.ts (1)
src/app/features/mypage/schemas/mypageValidation.ts (1)
mypageValidation(1-15)
src/app/features/mypage/hook/useUserQurey.ts (1)
src/app/features/mypage/api/mypageApi.ts (1)
loadUser(12-15)
src/app/features/mypage/hook/useUpdateMyProfileMutation.ts (2)
src/app/features/mypage/types/mypage.type.ts (1)
UpdateProfileRequest(1-4)src/app/features/mypage/api/mypageApi.ts (1)
updateMyProfile(17-25)
src/app/features/mypage/hook/useUploadProfileImageMutation.ts (2)
src/app/features/mypage/types/mypage.type.ts (1)
UploadProfileImageResponse(6-8)src/app/features/mypage/api/mypageApi.ts (1)
uploadProfileImage(27-37)
src/app/features/mypage/hook/useChangePasswordMutation.ts (3)
src/app/features/mypage/types/mypage.type.ts (1)
PasswordChangeRequest(10-13)src/app/features/mypage/api/mypageApi.ts (1)
changePassword(39-43)src/app/shared/lib/toast.ts (1)
showError(4-4)
src/app/shared/lib/axios.ts (1)
src/app/features/auth/store/useAuthStore.ts (1)
useAuthStore(5-20)
src/app/features/mypage/components/PasswordChangeForm.tsx (7)
src/app/features/mypage/types/mypage.type.ts (1)
PasswordChangeRequest(10-13)src/app/features/mypage/api/mypageApi.ts (1)
changePassword(39-43)src/app/features/mypage/hook/useChangePasswordMutation.ts (1)
useChangePasswordMutation(10-25)src/app/features/mypage/hook/useNewPasswordValidation.ts (1)
useNewPasswordValidation(3-13)src/app/shared/hooks/useConfirmPasswordValidation.ts (1)
useConfirmPasswordValidation(1-7)src/app/shared/lib/toast.ts (1)
showSuccess(3-3)src/app/shared/lib/cn.ts (1)
cn(4-6)
src/app/features/mypage/api/mypageApi.ts (2)
src/app/features/mypage/api/mypageEndPoint.ts (1)
MYPAGE_ENDPOINT(1-5)src/app/features/mypage/types/mypage.type.ts (3)
UpdateProfileRequest(1-4)UploadProfileImageResponse(6-8)PasswordChangeRequest(10-13)
src/app/features/mypage/components/ProfileEditForm.tsx (6)
src/app/features/mypage/hook/useUserQurey.ts (1)
useUserQuery(5-10)src/app/features/mypage/hook/useUploadProfileImageMutation.ts (1)
useUploadProfileImageMutation(7-11)src/app/features/mypage/hook/useUpdateMyProfileMutation.ts (1)
useUpdateMyProfileMutation(9-17)src/app/shared/lib/toast.ts (2)
showSuccess(3-3)showError(4-4)src/app/features/mypage/components/ProfileImageUpload.tsx (1)
ProfileImageUpload(15-102)src/app/features/mypage/schemas/mypageValidation.ts (1)
mypageValidation(1-15)
src/app/features/mypage/components/ProfileImageUpload.tsx (3)
src/app/shared/components/common/WhitePenIcon/WhitePenIcon.tsx (1)
WhitePenIcon(5-20)src/app/shared/components/common/PlusIcon/PlusIcon.tsx (1)
PlusIcon(6-38)src/app/shared/components/common/CloseCircleIcon/CloseCircleIcon.tsx (1)
CloseCircleIcon(5-40)
🪛 Biome (1.9.4)
src/app/features/mypage/components/ProfileImageUpload.tsx
[error] 55-56: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
🔇 Additional comments (37)
src/app/globals.css (1)
81-83: 새로운 텍스트 색상 유틸리티 클래스가 적절히 추가되었습니다.다크/라이트 테마를 모두 지원하는
.Text-blue클래스가 기존 패턴을 잘 따라 구현되었습니다.src/app/shared/hooks/useDashboard.ts (2)
5-5: HTTP 클라이언트 import 업데이트가 적절합니다.
authHttpClient로의 import 변경이 전체 리팩토링과 일관성 있게 적용되었습니다.
24-26: 대시보드 API 호출이 올바르게 업데이트되었습니다.
authHttpClient.get을 사용하여 인증이 필요한 대시보드 데이터를 요청하는 것이 적절합니다.src/app/shared/components/common/sidebar/modal/CreateDashboardModal.tsx (2)
7-7: HTTP 클라이언트 import 업데이트가 적절합니다.
authHttpClient로의 import 변경이 일관되게 적용되었습니다.
49-52: 대시보드 생성 API 호출이 올바르게 업데이트되었습니다.인증이 필요한 대시보드 생성 요청에
authHttpClient.post를 사용하는 것이 적절합니다.src/app/features/auth/api/authApi.ts (3)
8-11: 로그인 API 호출 검증 필요
authHttpClient를 사용하는 로그인 요청이 Authorization 헤더로 인해 실패할 수 있습니다.
16-19: 회원가입 API 호출 검증 필요
authHttpClient를 사용하는 회원가입 요청이 Authorization 헤더로 인해 실패할 수 있습니다.
1-1: ```shell
#!/usr/bin/env bashDisplay the content of authApi.ts to verify login/signup implementation
file=$(rg -l "authApi.ts" . | head -n1)
echo "Found auth API file at: $file"
echo "---- authApi.ts content ----"
sed -n '1,200p' "$file"</details> <details> <summary>src/app/features/auth/hooks/useLoginMutation.ts (1)</summary> `25-29`: **타이포 수정이 정확합니다.** `severMessage`를 `serverMessage`로 수정한 것이 올바릅니다. 변수명이 더 명확해졌습니다. </details> <details> <summary>src/app/shared/hooks/useConfirmPasswordValidation.ts (1)</summary> `1-7`: **재사용 가능한 훅 구현이 깔끔합니다.** 콜백 함수를 받아 비밀번호 확인 검증을 수행하는 구조가 잘 설계되었습니다. 이전 구현보다 더 간단하고 재사용성이 높아졌습니다. </details> <details> <summary>src/app/shared/components/common/PlusIcon/PlusIcon.tsx (1)</summary> `1-38`: **아이콘 컴포넌트 구현이 표준적입니다.** SVG 프로퍼티를 적절히 확장하고 재사용 가능한 구조로 잘 작성되었습니다. `currentColor` 사용으로 테마 대응도 가능합니다. </details> <details> <summary>src/app/features/mypage/schemas/mypageValidation.ts (1)</summary> `1-15`: **검증 스키마가 적절하게 구성되었습니다.** 닉네임 정규식이 한글과 영문을 올바르게 검증하고, 비밀번호 최소 길이 요구사항도 적절합니다. 사용자 친화적인 한국어 에러 메시지도 좋습니다. </details> <details> <summary>src/app/features/auth/hooks/useSignupMutation.ts (1)</summary> `24-28`: **로그인 훅과 일관된 타이포 수정입니다.** `severMessage`를 `serverMessage`로 수정하여 로그인 훅과 동일한 패턴으로 일관성을 유지했습니다. </details> <details> <summary>src/app/shared/components/Input.tsx (1)</summary> `48-48`: **읽기 전용 상태의 시각적 피드백이 잘 구현되었습니다.** 읽기 전용 입력 필드에 회색 텍스트와 기본 커서 스타일을 적용하여 사용자 경험을 개선했습니다. 비밀번호 입력과 일반 입력 모두에 일관되게 적용되어 좋습니다. Also applies to: 76-76 </details> <details> <summary>src/app/features/auth/components/SignupForm.tsx (2)</summary> `4-4`: **공통 훅으로 이동한 import 경로 변경이 적절합니다.** `useConfirmPasswordValidation` 훅을 공통 위치로 이동하고 절대 경로로 import하는 것이 코드 재사용성과 유지보수성 측면에서 좋습니다. --- `32-32`: **훅 사용법 개선이 보안성과 명확성을 향상시켰습니다.** 이전에 `getValues` 함수 전체를 전달하던 방식에서 `() => getValues('password')` 함수를 전달하는 방식으로 변경된 것이 더 명확하고 안전합니다. 필요한 값만 정확히 전달하는 방식이 좋습니다. </details> <details> <summary>src/app/features/mypage/api/mypageEndPoint.ts (1)</summary> `1-6`: **엔드포인트 정의가 깔끔하고 일관성 있게 구현되었습니다.** 환경 변수를 사용한 동적 엔드포인트 구성이 적절하며, REST 규칙을 잘 따르고 있습니다. `NEXT_PUBLIC_TEAM_ID` 환경 변수가 undefined일 경우를 대비한 검증이 필요할 수 있습니다. 다음 스크립트로 환경 변수 사용을 확인해보겠습니다: ```shell #!/bin/bash # Description: Check if NEXT_PUBLIC_TEAM_ID is properly configured and used # Expected: Find environment variable configuration and usage patterns # Check for environment variable configuration fd -e env -e local | xargs grep -l "NEXT_PUBLIC_TEAM_ID" 2>/dev/null || echo "No .env files found with NEXT_PUBLIC_TEAM_ID" # Check for other usages of this environment variable rg "NEXT_PUBLIC_TEAM_ID" -A 2 -B 2src/app/features/mypage/hook/useUpdateMyProfileMutation.ts (1)
9-17: 잘 구현된 React Query 뮤테이션 훅입니다.타입 정의가 명확하고 React Query의 모범 사례를 잘 따르고 있습니다. 에러 처리도 적절히 설정되어 있습니다.
src/app/features/mypage/hook/useUploadProfileImageMutation.ts (1)
7-11: 파일 업로드를 위한 뮤테이션 훅이 잘 구현되었습니다.File 타입을 사용하여 이미지 업로드에 적합하게 구성되었고, 다른 뮤테이션 훅과 일관된 패턴을 따르고 있습니다.
src/app/features/mypage/hook/useNewPasswordValidation.ts (1)
3-13: 비밀번호 유효성 검사 훅이 잘 구현되었습니다.콜백 함수를 사용하여 현재 비밀번호를 유연하게 가져올 수 있도록 설계되었고, 기존 validation을 확장하는 방식이 좋습니다. 다만 클라이언트 측 유효성 검사와 함께 서버 측에서도 동일한 검증이 이루어지는지 확인해 주세요.
src/app/shared/components/common/CloseCircleIcon/CloseCircleIcon.tsx (1)
1-40: 잘 구현된 아이콘 컴포넌트입니다.TypeScript 인터페이스가 적절하게 정의되었고, props spreading과 기본값 설정이 잘 되어 있습니다. stroke 색상이 하드코딩된 것은 의도적인 디자인 선택임을 확인했습니다.
src/app/mypage/page.tsx (2)
6-7: 컴포넌트 분리를 통한 좋은 리팩토링입니다.ProfileEditForm과 PasswordChangeForm으로 분리하여 관심사의 분리가 잘 되었고, 코드의 가독성과 유지보수성이 향상되었습니다.
Also applies to: 41-41, 43-43
36-38: 버튼 타입 명시가 잘 되었습니다.
type="button"을 명시적으로 지정하여 의도하지 않은 폼 제출을 방지할 수 있어 좋습니다.src/app/features/mypage/hook/useChangePasswordMutation.ts (1)
13-23: 에러 처리 로직이 잘 구현되어 있습니다.서버 메시지 추출과 폴백 메시지 처리가 적절하며, Axios 에러와 일반 에러를 구분해서 처리하는 점이 좋습니다.
src/app/features/mypage/types/mypage.type.ts (1)
1-13: 타입 정의가 명확하고 적절합니다.인터페이스들이 각각의 용도에 맞게 잘 정의되어 있으며,
profileImageUrl의 null 허용 등 실제 사용 시나리오를 잘 반영하고 있습니다.src/app/features/mypage/components/PasswordChangeForm.tsx (3)
63-69: 현재 비밀번호 필드에 대한 설계 결정이 보안상 적절합니다.현재 비밀번호에 유효성 검사를 하지 않는 것은 보안상 올바른 접근입니다. 서버에서 검증하도록 하는 것이 더 안전합니다.
76-84: 교차 필드 유효성 검사가 잘 구현되어 있습니다.새 비밀번호와 확인 비밀번호 필드에서 서로를 트리거하는 로직이 사용자 경험을 향상시킵니다.
41-54: 폼 제출 로직과 성공 처리가 적절합니다.성공 시 폼 리셋과 토스트 알림 표시가 좋은 사용자 경험을 제공합니다. mutation의 onSuccess 콜백 사용도 적절합니다.
src/app/features/mypage/api/mypageApi.ts (2)
27-37: 이미지 업로드 함수가 올바르게 구현되었습니다.FormData를 사용한 파일 업로드 처리가 적절하며, 타입 안정성도 잘 유지되고 있습니다.
39-43: 비밀번호 변경 API 함수가 간결하고 명확합니다.void 반환 타입과 PUT 메서드 사용이 적절하며, 타입 안정성이 보장되고 있습니다.
src/app/features/mypage/components/ProfileEditForm.tsx (1)
44-53: useEffect를 사용한 폼 초기화 로직이 적절합니다.비동기 사용자 데이터 로딩에 대응하는 방식이 좋으며, SSR 도입 예정이라는 주석도 유용합니다.
src/app/features/mypage/components/ProfileImageUpload.tsx (6)
1-13: 인터페이스 정의가 명확하고 적절합니다.필요한 의존성들이 올바르게 import되었고, Props 인터페이스가 명확하게 정의되어 있습니다. 한국어 주석으로 각 prop의 역할이 잘 설명되어 있습니다.
15-26: 상태 관리 로직이 적절합니다.useRef와 useState 훅을 올바르게 사용하고 있으며, useEffect를 통한 상위 컴포넌트의 value prop과 내부 preview 상태 동기화가 잘 구현되어 있습니다.
54-60: 컨테이너 구조와 접근성이 잘 구현되었습니다.적절한 크기 설정과 접근성을 위한 label-input 연결이 올바르게 구현되어 있습니다. 스타일링도 적절합니다.
참고: 정적 분석 도구에서 55-56라인에 대해 optional chain 사용을 제안했지만, 해당 라인에는 체이닝 연산이 없으므로 거짓 양성으로 판단됩니다.
61-79: 이미지 미리보기 UI가 훌륭하게 구현되었습니다.조건부 렌더링, hover 효과가 있는 연필 아이콘 오버레이, Next.js의 최적화된 Image 컴포넌트 사용 등이 모두 적절하게 구현되어 있습니다. z-index 설정으로 레이어 순서도 올바르게 관리되고 있습니다.
81-90: 삭제 버튼 구현이 적절합니다.조건부 렌더링으로 미리보기가 있을 때만 삭제 버튼을 표시하고, 적절한 positioning과 hover 효과가 구현되어 있습니다. button 타입도 올바르게 설정되었습니다.
92-102: 파일 input 구현이 표준적이고 적절합니다.숨겨진 파일 input, 이미지 파일만 허용하는 accept 속성, ref를 통한 프로그래매틱 접근 등이 모두 올바르게 구현되어 있습니다.
| const authHttpClient = axios.create({ | ||
| baseURL: process.env.NEXT_PUBLIC_API_URL, | ||
| }) | ||
|
|
||
| api.interceptors.request.use( | ||
| authHttpClient.interceptors.request.use( | ||
| (config) => { | ||
| const token = useAuthStore.getState().accessToken | ||
| const publicPaths = [AUTH_ENDPOINT.LOGIN, AUTH_ENDPOINT.SIGNUP] | ||
| const isPulicPath = publicPaths.some((path) => config.url?.includes(path)) | ||
|
|
||
| if (!isPulicPath && token) { | ||
| if (token) { | ||
| config.headers.Authorization = `Bearer ${token}` | ||
| } | ||
|
|
||
| return config | ||
| }, | ||
| (error) => { | ||
| return Promise.reject(error) | ||
| }, | ||
| ) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Verification correct
인증 엔드포인트에 Authorization 헤더가 추가되는 문제를 확인해야 합니다.
요청 인터셉터가 단순화되면서 모든 요청에 토큰이 있으면 Authorization 헤더를 추가하도록 변경되었습니다. 하지만 로그인/회원가입 엔드포인트는 일반적으로 Authorization 헤더가 없어야 합니다.
이 변경으로 인해 인증 API 호출이 실패할 수 있습니다.
다음 스크립트로 인증 엔드포인트 사용 현황을 확인해보겠습니다:
🏁 Script executed:
#!/bin/bash
# 인증 엔드포인트에서 authHttpClient 사용을 확인하고 잠재적 문제점을 파악합니다.
echo "=== 인증 API 엔드포인트 확인 ==="
rg -A 3 "AUTH_ENDPOINT" --type ts
echo -e "\n=== authHttpClient를 사용하는 인증 관련 함수들 ==="
rg -A 10 "authHttpClient\.post.*login|authHttpClient\.post.*signup" --type tsLength of output: 1279
인증 엔드포인트에 Authorization 헤더가 추가되는 문제를 확인해야 합니다.
요청 인터셉터가 단순화되면서 모든 요청에 토큰이 있으면 Authorization 헤더를 추가하도록 변경되었습니다. 하지만 로그인/회원가입 엔드포인트는 일반적으로 Authorization 헤더가 없어야 합니다.
이 변경으로 인해 인증 API 호출이 실패할 수 있습니다.
다음 스크립트로 인증 엔드포인트 사용 현황을 확인해보겠습니다:
#!/bin/bash
# 인증 엔드포인트에서 authHttpClient 사용을 확인하고 잠재적 문제점을 파악합니다.
echo "=== 인증 API 엔드포인트 확인 ==="
rg -A 3 "AUTH_ENDPOINT" --type ts
echo -e "\n=== authHttpClient를 사용하는 인증 관련 함수들 ==="
rg -A 10 "authHttpClient\.post.*login|authHttpClient\.post.*signup" --type ts🤖 Prompt for AI Agents
In src/app/shared/lib/axios.ts between lines 5 and 21, the request interceptor
adds the Authorization header to all requests if a token exists, which causes
issues for authentication endpoints like login and signup that should not
include this header. To fix this, modify the interceptor to check the request
URL and exclude adding the Authorization header for authentication endpoints
before returning the config.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
그 부분은 리다이렉트 부분 구현하면 자연스럽게 바뀔 예정
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Insung-Jo 네, 리다이렉트 기능 구현 시 인증 플로우가 개선될 예정이군요. 현재 상태를 이해했습니다. 감사합니다!
(・ω・) ✨
✏️ Learnings added
Learnt from: Insung-Jo
PR: CoPlay-FE/coplan#80
File: src/app/shared/lib/axios.ts:5-21
Timestamp: 2025-06-19T03:57:11.459Z
Learning: 프로젝트에서 axios 인터셉터의 인증 헤더 처리는 현재 모든 요청에 토큰을 추가하는 상태이며, 리다이렉트 기능 구현 시 적절히 개선될 예정입니다.
Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.
dkslel1225
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
비밀번호 변경 컴포넌트 구현 수고하셨습니다!
📌 변경 사항 개요
✨ 요약
useConfirmPasswordValidation, mypageEndPoint, useChangePasswordMutation, mypageValidation, useNewPasswordValidation, PasswordChangeForm등이 변경 및 추가 되었습니다.useConfirmPasswordValidation공통 훅으로 분리 (다른 페이지에도 적용 완료)📝 상세 내용
useConfirmPasswordValidation
컴포넌트 관련
PasswordChangeForm
react-query를 사용하여 응답 성공과 에러를 관리 하였습니다.reset()을 사용하여 제출 후 필드 값을 초기화 하였습니다.검증 관련
useNewPasswordValidation
🔗 관련 이슈
#79
🖼️ 스크린샷
2025-06-19.06-29-58.mp4
✅ 체크리스트
💡 참고 사항
Summary by CodeRabbit
신규 기능
버그 수정
스타일
.Text-blueCSS 클래스가 추가되었습니다.리팩터
문서화 및 검증