-
Notifications
You must be signed in to change notification settings - Fork 0
관리자 문의 ( #issue 335 ) #341
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이 변경사항은 관리자 문의 기능을 전면적으로 도입하고, 관련 API, React 컴포넌트, 스타일 파일, 커스텀 훅, 라우팅 구조를 추가 및 리팩토링합니다. 문의 전체 조회, 상세 조회, 답변 작성/수정/삭제 등 관리자 문의의 CRUD를 지원하는 기능이 구현되었습니다. 기존 관련 API 함수의 위치도 변경되었습니다. Changes
Sequence Diagram(s)sequenceDiagram
participant Admin as 관리자
participant UI as AdminInquiryList/AdminInquiryDetail
participant Hook as useAdminInquiry/useGetAllInquiries
participant API as Inquiry.api.ts
participant Server as 서버
Admin->>UI: 문의 리스트 페이지 접근
UI->>Hook: useGetAllInquiries 호출
Hook->>API: getAllInquiries()
API->>Server: GET /admin/inquiries
Server-->>API: 문의 리스트 반환
API-->>Hook: 데이터 반환
Hook-->>UI: 데이터 전달
UI-->>Admin: 문의 리스트 렌더링
Admin->>UI: 문의 상세 클릭
UI->>Hook: useAdminInquiry({id})
Hook->>API: getInquiryDetail(id)
API->>Server: GET /admin/inquiries/:id
Server-->>API: 문의 상세 반환
API-->>Hook: 데이터 반환
Hook-->>UI: 데이터 전달
UI-->>Admin: 문의 상세/답변 UI 렌더링
Admin->>UI: 답변 작성/수정
UI->>Hook: post/patchInquiryAnswerMutate({id, answer})
Hook->>API: postInquiryAnswer/patchInquiryAnswer
API->>Server: POST/PATCH /admin/inquiries/:id/answer
Server-->>API: 성공/실패 응답
API-->>Hook: 응답 반환
Hook-->>UI: 모달 등 상태 업데이트
UI-->>Admin: 결과 알림 및 UI 갱신
Assessment against linked issues
Assessment against linked issues: Out-of-scope changes해당 변경사항에서 요구사항과 무관한 기능적 코드 변경은 발견되지 않았습니다. Possibly related PRs
Suggested labels
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
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. 🪧 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: 12
🧹 Nitpick comments (21)
src/hooks/admin/useGetAllInquiries.ts (1)
2-3: 상대경로 최적화 고려 및 alias 적용 제안
새 API 모듈과 중앙화된 쿼리 키를 올바르게 import 했습니다. 다만../../api/admin/customerService/Inquiry.api와 같은 상대경로가 길어지므로,@/api/...및@/hooks/...같은 경로 alias 설정을 도입하면 가독성과 유지보수성이 향상됩니다.src/components/admin/adminInquiry/AdminInquiryAnswer.tsx (1)
28-28: 조건문을 단순화하세요.
createdAt이 존재하는지 확인하는 조건문이 불필요합니다.- {createdAt ? createdAt : ''} + {createdAt || ''}src/components/admin/adminInquiry/AdminInquiryAnswerWrite.styled.ts (1)
38-43: 컴포넌트 확장의 의미적 일관성을 확인하세요.
InquiryAnswerWrite가InquiryContent(div)를 확장하면서resize: none속성을 사용하는 것으로 보아 textarea로 사용될 것 같습니다. 의미적으로 더 명확한 네이밍이나 적절한 기본 컴포넌트 확장을 고려해보세요.-export const InquiryAnswerWrite = styled(InquiryContent)` +export const InquiryAnswerWriteTextarea = styled.textarea` + font-size: 1.1rem; + width: 100%; resize: none; border: 1px solid ${({ theme }) => theme.color.placeholder}; border-radius: ${({ theme }) => theme.borderRadius.primary}; padding: 1rem; `;src/components/admin/adminInquiry/AdminInquiryAnswerWrite.tsx (2)
8-22: 인터페이스 정의가 불필요합니다.
AdminInquiryAnswerWriteProps인터페이스가 정의되어 있지만 실제로는useOutletContext에서 타입을 직접 사용하고 있습니다. 이 인터페이스는 제거하거나 outlet context의 타입 안전성을 위해 활용하는 것이 좋겠습니다.-interface AdminInquiryAnswerWriteProps { - answerData: string; - isWrite: boolean; - id: string; - postInquiryAnswerMutate: UseMutationResult< - void, - AxiosError, - InquiryAnswerBody - >; - patchInquiryAnswerMutate: UseMutationResult< - void, - AxiosError, - InquiryAnswerBody - >; -}
55-58: Optional chaining을 사용하여 코드를 간소화하세요.정적 분석 도구에서 제안한 대로 optional chaining을 사용하면 더 안전하고 간결한 코드가 됩니다.
- if (inputRef && inputRef.current) { - inputRef.current.style.height = 'auto'; - inputRef.current.style.height = `${inputRef.current.scrollHeight}px`; - } + if (inputRef.current) { + inputRef.current.style.height = 'auto'; + inputRef.current.style.height = `${inputRef.current.scrollHeight}px`; + }🧰 Tools
🪛 Biome (1.9.4)
[error] 55-55: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
src/components/admin/adminInquiry/AdminInquiryDetail.tsx (1)
15-16: 빈 문자열 폴백 처리를 개선할 수 있습니다.
inquiryId가 undefined일 때 빈 문자열로 폴백하는 것보다 더 명시적인 처리를 고려해보세요.- const { inquiryId } = useParams(); - const id = inquiryId || ''; + const { inquiryId } = useParams(); + const id = inquiryId ?? ''; + + if (!inquiryId) { + return <div>잘못된 문의 ID입니다.</div>; + }src/api/admin/customerService/Inquiry.api.ts (2)
14-14: 에러 메시지가 일관성이 없습니다.한국어 에러 메시지와 영어 console.error가 혼재되어 있습니다. 일관성을 위해 통일하는 것을 권장합니다.
- console.error('전체 문의 조회 에러', e); + console.error('getAllInquiries error:', e);
27-28: 에러 로깅에 컨텍스트 정보가 부족합니다.어떤 함수에서 에러가 발생했는지 알기 어렵습니다. 에러 로깅에 함수명을 포함시키는 것을 권장합니다.
- console.error(e); + console.error('getInquiryDetail error:', e);다른 함수들도 마찬가지로 수정해주세요:
postInquiryAnswer error:patchInquiryAnswer error:deleteInquiry error:Also applies to: 38-39, 49-50, 58-59
src/components/admin/adminInquiry/AdminInquiryAnswer.styled.ts (2)
32-32: 빈 스타일드 컴포넌트가 불필요해 보입니다.
AnswerButtonSpan이 스타일링 없이 정의되어 있습니다. 실제로 사용되지 않는다면 제거하는 것을 고려해보세요.- export const AnswerButtonSpan = styled.span``;만약 향후 스타일링을 위해 유지한다면 주석을 추가해주세요:
+ // TODO: 향후 스타일링 추가 예정 export const AnswerButtonSpan = styled.span``;
17-20: 반응형 디자인을 고려한 스타일링이 필요할 수 있습니다.고정된
gap: 3rem과font-size값들이 모바일 환경에서 적절한지 확인해보세요.export const AnswerHeaderWrapper = styled(InquiryHeaderWrapper)` display: flex; - gap: 3rem; + gap: clamp(1rem, 5vw, 3rem); `;Also applies to: 22-25, 27-30
src/components/admin/adminInquiry/AdminInquiry.styled.ts (4)
4-4: 불필요한 빈 스타일드 컴포넌트
styled(Link)\`;에 CSS가 정의되어 있지 않습니다. 사용 목적이 명확하지 않다면 직접Link` 컴포넌트를 사용하거나 스타일을 추가하는 편이 좋습니다.
6-13: 그리드 정렬 속성 검토
justify-content: center;는 그리드 컨테이너를 부모 내에서 중앙으로 배치합니다. 아이템 간 중앙 정렬을 원한다면justify-items: center;를 고려해 보세요.
15-15: 불필요한 빈 스타일드 컴포넌트
styled.div\`;에 스타일이 없으므로, 실제 스타일링이 필요 없으면 일반div`로 대체하거나 스타일을 추가 검토해 주세요.
22-22: 불필요한 빈 스타일드 컴포넌트
styled.div\`;에 CSS가 없어 일반div`로 대체 가능 여부를 검토해 주세요.src/components/admin/adminInquiry/AdminInquiryDetailContent.styled.ts (7)
17-17: 빈 래퍼 컴포넌트
styled.div\`;`에 스타일이 없으므로, 불필요하다면 제거하거나 실제 스타일을 추가해 주세요.
50-50: 버튼 컴포넌트 이름 검토
InquiryFileImgBlowUpButton명칭이 다소 직관적이지 않을 수 있습니다.ZoomButton또는EnlargeButton등으로 네이밍을 간결하게 다듬는 것을 제안합니다.
52-54: 이미지 크기 고정 검토
width: 5rem로 고정되면 비율이 깨질 수 있습니다.max-width와height: auto조합을 고려해 보세요.
60-62: 과도한 z-index 사용
1000000000은 너무 큰 값입니다. 테마나 상수로 관리하거나, 적절한 범위(예: 9999)로 조정하는 것을 권장합니다.
64-65: 빈 스타일드 컴포넌트
확장된ModalImgWrapper에 스타일이 없어 불필요할 수 있습니다. 실제 커스터마이징이 필요 없다면 제거를 검토해 주세요.
66-68: 빈 스타일드 컴포넌트
ModalImgMessageWrapper상속 후 변경된 스타일이 없습니다. 제거 여부를 검토해 주세요.
70-70: 빈 스타일드 컴포넌트
ModalImg상속 후 별도 스타일이 없으므로, 직접 사용 가능 여부를 확인해 보세요.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (66)
src/api/activityLog.api.ts(0 hunks)src/api/admin/customerService/Inquiry.api.ts(1 hunks)src/components/admin/adminInquiry/AdminInquiry.styled.ts(1 hunks)src/components/admin/adminInquiry/AdminInquiry.tsx(1 hunks)src/components/admin/adminInquiry/AdminInquiryAnswer.styled.ts(1 hunks)src/components/admin/adminInquiry/AdminInquiryAnswer.tsx(1 hunks)src/components/admin/adminInquiry/AdminInquiryAnswerWrite.styled.ts(1 hunks)src/components/admin/adminInquiry/AdminInquiryAnswerWrite.tsx(1 hunks)src/components/admin/adminInquiry/AdminInquiryDetail.styled.ts(1 hunks)src/components/admin/adminInquiry/AdminInquiryDetail.tsx(1 hunks)src/components/admin/adminInquiry/AdminInquiryDetailContent.styled.ts(1 hunks)src/components/admin/adminInquiry/AdminInquiryDetailContent.tsx(1 hunks)src/components/admin/adminInquiry/AdminInquiryList.styled.ts(1 hunks)src/components/admin/adminInquiry/AdminInquiryList.tsx(1 hunks)src/hooks/admin/useAdminFAQ.ts(1 hunks)src/hooks/admin/useAdminInquiry.ts(1 hunks)src/hooks/admin/useAdminNotice.ts(1 hunks)src/hooks/admin/useGetAllInquiries.ts(1 hunks)src/hooks/admin/useGetAllReports.ts(1 hunks)src/hooks/admin/useGetAllUsers.ts(1 hunks)src/hooks/admin/useGetAllUsersPreview.ts(1 hunks)src/hooks/queries/keys.ts(1 hunks)src/hooks/useAuth.ts(1 hunks)src/hooks/user/CommentHooks/useDeleteComment.ts(1 hunks)src/hooks/user/CommentHooks/useDeleteReply.ts(1 hunks)src/hooks/user/CommentHooks/useGetComment.ts(1 hunks)src/hooks/user/CommentHooks/useGetReply.ts(1 hunks)src/hooks/user/CommentHooks/usePatchReply.ts(1 hunks)src/hooks/user/CommentHooks/usePostComment.ts(1 hunks)src/hooks/user/CommentHooks/usePostReply.ts(1 hunks)src/hooks/user/CommentHooks/usePutComment.ts(1 hunks)src/hooks/user/ProjectHooks/useApplyProject.ts(1 hunks)src/hooks/user/ProjectHooks/useCreateProject.ts(1 hunks)src/hooks/user/ProjectHooks/useUpdateProject.ts(1 hunks)src/hooks/user/evaluationHooks/useGetEvaluation.ts(1 hunks)src/hooks/user/evaluationHooks/usePostEvaluation.ts(1 hunks)src/hooks/user/useAlarmDelete.ts(1 hunks)src/hooks/user/useAlarmList.ts(1 hunks)src/hooks/user/useAlarmPatch.ts(1 hunks)src/hooks/user/useApllicantList.ts(1 hunks)src/hooks/user/useApplicantInfo.ts(1 hunks)src/hooks/user/useChartData.ts(1 hunks)src/hooks/user/useGetFAQ.ts(1 hunks)src/hooks/user/useGetMyComments.ts(1 hunks)src/hooks/user/useGetMyInquiries.ts(1 hunks)src/hooks/user/useGetNotice.ts(1 hunks)src/hooks/user/useGetNoticeDetail.ts(1 hunks)src/hooks/user/useGetProjectData.ts(1 hunks)src/hooks/user/useGetUserProjectList.ts(1 hunks)src/hooks/user/useManagedProjects.ts(1 hunks)src/hooks/user/useMyInfo.ts(1 hunks)src/hooks/user/useNotification.ts(1 hunks)src/hooks/user/usePassNonPassList.ts(1 hunks)src/hooks/user/usePassNonPassMutation.ts(1 hunks)src/hooks/user/usePostInquiry.ts(1 hunks)src/hooks/user/useSendResultMutation.ts(1 hunks)src/hooks/user/useUserInfo.ts(1 hunks)src/models/activityLog.ts(1 hunks)src/models/inquiry.ts(1 hunks)src/pages/admin/adminInquiries/AdminInquiries.styled.ts(0 hunks)src/pages/admin/adminInquiries/AdminInquiries.tsx(1 hunks)src/pages/admin/adminInquiries/adminInquiryDetail/AdminInquiryDetailPage.tsx(1 hunks)src/pages/admin/adminInquiries/adminInquiryList/AdminInquiryListPage.tsx(1 hunks)src/pages/admin/adminInquiries/adminInquiryWrite/AdminInquiryWritePage.tsx(1 hunks)src/pages/login/LoginSuccess.tsx(0 hunks)src/routes/AdminRoutes.tsx(3 hunks)
💤 Files with no reviewable changes (3)
- src/pages/login/LoginSuccess.tsx
- src/api/activityLog.api.ts
- src/pages/admin/adminInquiries/AdminInquiries.styled.ts
🧰 Additional context used
🧬 Code Graph Analysis (16)
src/components/admin/adminInquiry/AdminInquiryList.styled.ts (2)
src/components/admin/adminInquiry/AdminInquiryDetail.styled.ts (1)
SpinnerWrapper(4-4)src/components/user/mypage/Spinner.styled.ts (1)
SpinnerWrapperStyled(29-35)
src/components/admin/adminInquiry/AdminInquiry.tsx (2)
src/models/inquiry.ts (1)
AdminInquiry(10-17)src/constants/routes.ts (1)
ADMIN_ROUTE(34-48)
src/pages/admin/adminInquiries/adminInquiryList/AdminInquiryListPage.tsx (1)
src/components/admin/adminInquiry/AdminInquiryList.tsx (1)
AdminInquiryList(6-26)
src/pages/admin/adminInquiries/adminInquiryDetail/AdminInquiryDetailPage.tsx (1)
src/components/admin/adminInquiry/AdminInquiryDetail.tsx (1)
AdminInquiryDetail(9-60)
src/pages/admin/adminInquiries/adminInquiryWrite/AdminInquiryWritePage.tsx (1)
src/components/admin/adminInquiry/AdminInquiryAnswerWrite.tsx (1)
AdminInquiryAnswerWrite(24-80)
src/components/admin/adminInquiry/AdminInquiryAnswerWrite.styled.ts (2)
src/components/admin/adminInquiry/AdminInquiryAnswer.styled.ts (4)
InquiryAnswerContentContainer(11-13)AnswerHeaderWrapper(17-20)InquiryAnswerInfo(22-25)InquiryAnswerButton(27-30)src/components/admin/adminInquiry/AdminInquiryDetailContent.styled.ts (3)
AdminInquiryContentContainer(10-15)AdminInquiryContentWrapper(17-17)InquiryContent(45-48)
src/components/admin/adminInquiry/AdminInquiryDetail.tsx (4)
src/hooks/useModal.ts (1)
useModal(3-36)src/hooks/admin/useAdminInquiry.ts (1)
useAdminInquiry(15-114)src/components/common/loadingSpinner/LoadingSpinner.styled.ts (1)
Spinner(21-28)src/components/admin/adminInquiry/AdminInquiryDetailContent.tsx (1)
AdminInquiryDetailContent(10-64)
src/components/admin/adminInquiry/AdminInquiryDetail.styled.ts (2)
src/components/admin/adminInquiry/AdminInquiryList.styled.ts (1)
SpinnerWrapper(4-4)src/components/user/mypage/Spinner.styled.ts (1)
SpinnerWrapperStyled(29-35)
src/components/admin/adminInquiry/AdminInquiryAnswer.styled.ts (2)
src/components/admin/adminInquiry/AdminInquiryDetailContent.styled.ts (5)
AdminInquiryContentContainer(10-15)AdminInquiryContentWrapper(17-17)InquiryHeaderWrapper(19-21)InquiryInfo(35-38)InquiryContent(45-48)src/components/user/customerService/inquiry/Inquiry.styled.ts (1)
SendButton(205-222)
src/components/admin/adminInquiry/AdminInquiryAnswer.tsx (1)
src/constants/routes.ts (1)
ADMIN_ROUTE(34-48)
src/models/inquiry.ts (2)
src/models/apiCommon.ts (1)
ApiCommonType(1-4)src/models/activityLog.ts (1)
MyInquiries(3-14)
src/components/admin/adminInquiry/AdminInquiryAnswerWrite.tsx (1)
src/models/inquiry.ts (1)
InquiryAnswerBody(27-30)
src/components/admin/adminInquiry/AdminInquiryDetailContent.tsx (2)
src/models/activityLog.ts (1)
MyInquiries(3-14)src/constants/user/customerService.ts (1)
My_INQUIRIES_MESSAGE(15-20)
src/api/admin/customerService/Inquiry.api.ts (3)
src/api/http.api.ts (1)
httpClient(80-80)src/models/inquiry.ts (3)
ApiAdminInquiry(19-21)ApiAdminInquiryDetail(23-25)InquiryAnswerBody(27-30)src/models/apiCommon.ts (1)
ApiCommonBasicType(6-8)
src/hooks/admin/useAdminInquiry.ts (5)
src/hooks/admin/useAdminFAQ.ts (1)
State(14-14)src/constants/admin/adminModal.ts (1)
ADMIN_MODAL_MESSAGE(1-8)src/hooks/queries/keys.ts (1)
CustomerService(56-61)src/api/admin/customerService/Inquiry.api.ts (4)
getInquiryDetail(19-30)postInquiryAnswer(32-41)patchInquiryAnswer(43-52)deleteInquiry(54-61)src/models/inquiry.ts (1)
InquiryAnswerBody(27-30)
src/components/admin/adminInquiry/AdminInquiryDetailContent.styled.ts (2)
src/components/user/customerService/inquiry/Inquiry.styled.ts (1)
SendButton(205-222)src/components/user/mypage/activityLog/inquiries/inquiry/Inquiry.styled.ts (4)
ModalImgContainer(58-72)ModalImgWrapper(74-84)ModalImgMessageWrapper(86-92)ModalImg(94-97)
🪛 Biome (1.9.4)
src/components/admin/adminInquiry/AdminInquiry.tsx
[error] 10-10: Shouldn't redeclare 'AdminInquiry'. Consider to delete it or rename it.
'AdminInquiry' is defined here:
(lint/suspicious/noRedeclare)
src/components/admin/adminInquiry/AdminInquiryAnswerWrite.tsx
[error] 55-55: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
⏰ Context from checks skipped due to timeout of 90000ms (1)
- GitHub Check: accessibility-test
🔇 Additional comments (78)
src/hooks/queries/keys.ts (1)
60-60: 관리자 문의 상세 조회용inquiryDetail키 추가 승인
CustomerService에 문의 상세 조회를 위한inquiryDetail키가 올바르게 추가되었습니다.src/hooks/user/CommentHooks/usePostComment.ts (1)
3-3: 쿼리 키 경로 수정 승인
ProjectCommentList의 import 경로가 기존 사용자 경로에서 중앙queries/keys모듈로 정상적으로 변경되었습니다.src/hooks/user/evaluationHooks/useGetEvaluation.ts (1)
3-3: 쿼리 키 경로 수정 승인
ProjectMemberListEval의 import 경로가 중앙queries/keys모듈로 일관되게 업데이트되었습니다.src/hooks/user/evaluationHooks/usePostEvaluation.ts (1)
3-3: 쿼리 키 경로 수정 승인
ProjectMemberListEvalimport 경로가../../queries/keys로 맞춰져 경로 일관성이 확보되었습니다.src/hooks/user/CommentHooks/useGetReply.ts (1)
2-2: 쿼리 키 경로 수정 승인
ProjectReplyList의 import 경로를 새 중앙 모듈(queries/keys)에서 가져오도록 변경하여 일관성을 유지했습니다.src/hooks/user/useGetUserProjectList.ts (1)
6-6: 쿼리 키 경로 업데이트 확인
import 경로 변경이 전체 리팩토링 방침과 일치하며 올바르게 적용되었습니다.src/hooks/user/CommentHooks/usePostReply.ts (1)
3-3: 쿼리 키 경로 일관성 확인
ProjectReplyList를 공통queries/keys모듈에서 가져오도록 경로가 정확히 갱신되었습니다.src/hooks/user/CommentHooks/usePatchReply.ts (1)
3-3: 쿼리 키 경로 일관성 확인
ProjectReplyList의 import 경로가 중앙화된queries/keys로 올바르게 변경되었습니다.src/hooks/user/CommentHooks/usePutComment.ts (1)
3-3: 쿼리 키 경로 일관성 확인
ProjectCommentList의 import가 통합된queries/keys모듈로 적절히 이동되었습니다.src/hooks/user/CommentHooks/useGetComment.ts (1)
3-3: 쿼리 키 경로 일관성 확인
ProjectCommentListimport가 새queries/keys위치로 정확히 반영되었습니다.src/hooks/user/CommentHooks/useDeleteReply.ts (1)
2-2: 경로 변경이 올바르게 적용되었습니다.
기존../../queries/user/keys에서 중앙 모듈인../../queries/keys로 리팩토링되어 일관성이 향상되었습니다. 로직에 영향이 없습니다.src/hooks/user/CommentHooks/useDeleteComment.ts (1)
2-2: 쿼리 키 임포트 경로가 일관적으로 중앙화되었습니다.
../../queries/keys로 변경되어 다른 훅들과 동일한 구조로 통일되었습니다. 기능상 문제 없습니다.src/hooks/user/ProjectHooks/useApplyProject.ts (1)
2-2: 쿼리 키 경로 리팩토링이 적절히 반영되었습니다.
../../queries/keys로 이동해 유지보수성과 가독성이 개선되었습니다. 기존 동작에는 영향 없습니다.src/hooks/user/useChartData.ts (1)
3-3: 쿼리 키 임포트 경로가 중앙 모듈로 통합되었습니다.
../queries/keys로 변경되어 경로 일관성이 확보되었습니다. 기능 변경 없음.src/hooks/user/useAlarmDelete.ts (1)
3-3: AlarmList 키 임포트 경로가 표준화되었습니다.
../queries/keys로 리팩토링되어 다른 훅들과 동일한 구조를 유지합니다. 로직에는 영향 없습니다.src/hooks/user/usePassNonPassMutation.ts (1)
3-3: 쿼리 키 import 경로 통합
applicantKey를 중앙화된../queries/keys에서 참조하도록 변경한 것이 일관성에 부합합니다.src/hooks/user/usePostInquiry.ts (1)
1-1: 쿼리 키 import 경로 통합
ActivityLog를../queries/keys로 불러오는 변경이 기존 구조와 일관되며 적절합니다.src/hooks/user/useSendResultMutation.ts (1)
3-3: 쿼리 키 import 경로 통합
managedProjectKey를 중앙화된../queries/keys에서 불러오도록 한 것은 캐시 무효화 관리에 일관성을 제공합니다.src/hooks/user/ProjectHooks/useCreateProject.ts (1)
5-5: 쿼리 키 import 경로 통합
managedProjectKey를../../queries/keys로 참조하도록 변경해 모듈 구조 일관성을 유지했습니다.src/hooks/user/ProjectHooks/useUpdateProject.ts (1)
4-4: 쿼리 키 import 경로 통합
managedProjectKey를 중앙화된../../queries/keys에서 가져오도록 업데이트된 것이 적절합니다.src/hooks/user/useApplicantInfo.ts (1)
4-4: 쿼리 키 import 경로 중앙화 반영 확인
기존의'../queries/user/keys'에서'../queries/keys'로 올바르게 변경되었습니다.src/hooks/user/useMyInfo.ts (1)
4-4: 쿼리 키 import 경로 업데이트 확인
myInfoKey와ProjectListKey가'../queries/keys'로 일관성 있게 옮겨졌습니다.src/hooks/useAuth.ts (1)
9-9: 쿼리 키 import 경로 업데이트 확인
myInfoKey가'./queries/keys'로 중앙화된 경로로 올바르게 변경되었습니다.src/hooks/user/useUserInfo.ts (1)
2-2: 쿼리 키 import 경로 업데이트 확인
userInfoKey가'../queries/keys'로 일관성 있게 중앙화되었습니다.src/hooks/user/useGetNotice.ts (1)
4-4: 쿼리 키 import 경로 업데이트 확인
CustomerService키가'../queries/keys'로 올바르게 업데이트되었습니다.src/hooks/user/useApllicantList.ts (1)
2-2: 쿼리 키 import 경로 업데이트 승인
applicantKey를queries/keys로 중앙화된 경로로 가져오도록 변경한 것은 일관적이며 적절합니다.src/hooks/user/usePassNonPassList.ts (1)
2-2: 쿼리 키 import 경로 업데이트 승인
applicantKey의 import 경로를queries/keys로 통일한 변경이 올바르게 반영되었습니다.src/hooks/admin/useGetAllUsersPreview.ts (1)
2-2: 쿼리 키 import 경로 업데이트 승인
UserData의 경로를 중앙화된queries/keys모듈로 수정한 것은 일관성을 높이는 적절한 리팩토링입니다.src/hooks/user/useAlarmList.ts (1)
2-2: 쿼리 키 import 경로 업데이트 승인
AlarmList를queries/keys에서 가져오도록 경로를 통합한 변경이 정확히 적용되었습니다.src/hooks/user/useManagedProjects.ts (1)
2-2: 쿼리 키 import 경로 업데이트 승인
managedProjectKey를 중앙화된 경로로 옮긴 것은 코드베이스 전반의 일관성 유지에 도움이 됩니다.src/hooks/user/useGetMyComments.ts (1)
4-4:ActivityLog쿼리 키 경로가 중앙 모듈로 올바르게 업데이트되었습니다.
이 변경으로 다른 훅들과 쿼리 키 참조 경로가 일관화되었습니다.src/hooks/user/useGetNoticeDetail.ts (1)
3-3:CustomerService쿼리 키 경로가 중앙 모듈로 올바르게 업데이트되었습니다.
다른 고객 서비스 훅들과 동일한queries/keys모듈을 사용하여 일관성을 유지합니다.src/hooks/user/useGetFAQ.ts (1)
3-3:CustomerService쿼리 키 경로가 중앙 모듈로 올바르게 업데이트되었습니다.
키 관리가 통합되어 유지보수성이 향상되었습니다.src/hooks/user/useGetProjectData.ts (1)
2-2:managedProjectKey쿼리 키 경로가 중앙 모듈로 올바르게 업데이트되었습니다.
다른 프로젝트 관련 훅들과 경로 구조가 일치합니다.src/hooks/user/useGetMyInquiries.ts (1)
4-4:ActivityLog쿼리 키 경로가 중앙 모듈로 올바르게 업데이트되었습니다.
기존 경로에서 통합된queries/keys모듈로의 전환이 적절히 반영되었습니다.src/hooks/admin/useGetAllReports.ts (1)
2-2:Details
✅ Verification successful
쿼리 키 import 경로 통합을 승인합니다.
query key import를 중앙화하는 좋은 리팩토링입니다. 새로운 경로가 올바르게 작동하는지 확인해 주세요.
다음 스크립트로 새로운 import 경로가 유효한지 확인해 주세요:
🏁 Script executed:
#!/bin/bash # Description: 새로운 query keys 파일이 존재하고 ReportData를 export하는지 확인 # 새로운 keys 파일 존재 확인 fd -t f "keys" src/hooks/queries # ReportData export 확인 rg -A 3 "export.*ReportData" src/hooks/queriesLength of output: 273
쿼리 키 import 경로 통합 검증 완료
src/hooks/queries/keys.ts 파일이 존재하며
export const ReportData가 확인되어 새로운 import 경로가 올바르게 작동합니다. 변경 승인합니다.src/hooks/admin/useGetAllUsers.ts (1)
2-2: 쿼리 키 import 경로 통합을 승인합니다.일관된 리팩토링으로 코드 구조가 개선되었습니다.
src/hooks/user/useAlarmPatch.ts (1)
3-3: 쿼리 키 import 경로 통합을 승인합니다.알람 관련 쿼리 키 import가 성공적으로 중앙화되었습니다.
src/hooks/admin/useAdminNotice.ts (1)
8-8: 쿼리 키 import 경로 통합을 승인합니다.CustomerService 쿼리 키가 여러 곳에서 사용되고 있어 이 변경이 특히 중요합니다. 올바르게 리팩토링되었습니다.
src/hooks/user/useNotification.ts (1)
3-3: 쿼리 키 import 경로 통합을 승인합니다.import 경로 변경과 함께 코드 포맷팅도 개선되어 가독성이 향상되었습니다.
src/pages/admin/adminInquiries/adminInquiryList/AdminInquiryListPage.tsx (1)
1-2: Page 컴포넌트 단순 래퍼 구현 적절
AdminInquiryListPage가 단순히AdminInquiryList를 렌더링하는 래퍼로서 역할을 명확히 분리하고 있습니다. 불필요한 로직 없이 구성 요소가 모듈화된 점을 승인합니다.src/pages/admin/adminInquiries/adminInquiryWrite/AdminInquiryWritePage.tsx (1)
1-2: 작성 페이지 래퍼 컴포넌트 승인
AdminInquiryWritePage가AdminInquiryAnswerWrite컴포넌트를 직접 렌더링하는 단순 구조로, 명확하게 책임이 분리되어 있습니다.src/pages/admin/adminInquiries/adminInquiryDetail/AdminInquiryDetailPage.tsx (1)
1-2: 상세 페이지 래퍼 컴포넌트 구조 확인
AdminInquiryDetailPage가AdminInquiryDetail컴포넌트를 단일 책임으로 처리하며, 추가 props 없이 작동하도록 설계되었습니다. 페이지 수준에서 캐싱, 로딩 상태 관리 등 추가 기능이 필요한지 검토했으며, 현재 구조는 적절합니다.src/hooks/admin/useAdminFAQ.ts (2)
12-12: import 경로 변경이 올바르게 적용되었습니다.쿼리 키 구조의 리팩토링에 맞춰 import 경로가 중앙집중화된 구조로 변경되었습니다.
14-14: 타입을 export로 변경한 것이 좋습니다.
State타입을 export하여 다른 모듈에서 재사용 가능하도록 만든 것은 좋은 변경사항입니다.src/pages/admin/adminInquiries/AdminInquiries.tsx (1)
1-5: CommonAdminPage 컴포넌트 사용으로 코드가 간소화되었습니다.공통 컴포넌트를 활용하여 일관성을 높이고 코드 중복을 줄인 좋은 리팩토링입니다.
src/components/admin/adminInquiry/AdminInquiryList.tsx (1)
17-25: 문의 목록 렌더링 로직이 잘 구현되었습니다.데이터 매핑과 컴포넌트 구조가 깔끔하게 작성되었습니다.
src/components/admin/adminInquiry/AdminInquiryDetail.styled.ts (2)
4-4: 기존 스피너 스타일 컴포넌트를 재사용하는 것이 좋습니다.일관성을 유지하기 위해 기존의
SpinnerWrapperStyled를 재사용한 것은 좋은 접근입니다.
6-12: 컨테이너 스타일링이 적절합니다.Flexbox를 사용한 레이아웃과 적절한 간격 설정으로 깔끔한 UI 구조를 제공합니다.
src/components/admin/adminInquiry/AdminInquiryList.styled.ts (1)
1-15: LGTM! 스타일 컴포넌트 구조가 깔끔합니다.기존 스피너 컴포넌트를 재사용하고 새로운 레이아웃 컴포넌트들을 명확하게 정의했습니다. 컨테이너와 래퍼의 역할 분리도 적절합니다.
src/components/admin/adminInquiry/AdminInquiryAnswerWrite.styled.ts (1)
1-43: LGTM! 전반적인 스타일 구조가 잘 구성되어 있습니다.기존 컴포넌트들을 적절히 확장하여 일관된 디자인 시스템을 유지하고 있습니다. 테마 변수 사용도 적절합니다.
src/routes/AdminRoutes.tsx (3)
64-69: Suspense wrapper 추가가 좋습니다.Lazy loading을 위한 Suspense wrapper 추가로 성능이 개선되었습니다. 스피너 fallback도 적절하게 설정되어 있습니다.
36-56: 문의 관련 컴포넌트의 lazy loading 구현이 적절합니다.새로운 문의 관련 컴포넌트들이 올바르게 lazy loading으로 설정되어 있고, 컴포넌트 명명도 일관성 있게 되어 있습니다.
125-142: 중첩 라우팅 구조가 잘 설계되었습니다.문의 관련 라우팅이 기존 공지사항, FAQ와 유사한 패턴으로 일관성 있게 구현되어 있습니다. 답변 작성과 수정을 위한 중첩 라우트도 적절하게 설계되어 있습니다.
src/models/inquiry.ts (3)
10-17: AdminInquiry 인터페이스가 잘 설계되었습니다.관리자 문의 목록에 필요한 핵심 필드들이 적절하게 정의되어 있고, 타입 안전성이 확보되어 있습니다.
19-25: API 응답 인터페이스가 일관성 있게 구현되었습니다.
ApiCommonType을 확장하여 기존 API 응답 패턴과 일관성을 유지하고 있으며, 제네릭 타입 활용도 적절합니다.
27-30: InquiryAnswerBody 인터페이스가 API 요구사항과 일치합니다.답변 제출/수정 시 필요한 필드들이 정확하게 정의되어 있고, AdminInquiryAnswerWrite 컴포넌트에서 사용하는 구조와 일치합니다.
src/components/admin/adminInquiry/AdminInquiryDetailContent.tsx (4)
13-16: 이미지 모달 상태 관리가 적절합니다.이미지 모달을 위한 상태 구조가 명확하고, 필요한 정보(열림 상태와 URL)를 효율적으로 관리하고 있습니다.
26-43: 이미지 표시 및 확대 기능이 잘 구현되었습니다.이미지 배열을 적절하게 렌더링하고, 사용자 가이드 메시지도 조건부로 표시하여 UX가 우수합니다. 키 prop도 올바르게 설정되어 있습니다.
45-61: 이미지 모달 구현이 사용자 친화적입니다.모달 클릭으로 닫기 기능과 사용자 안내 메시지가 잘 구현되어 있어 직관적인 사용자 경험을 제공합니다.
22-24: 문의 정보 표시가 적절합니다.카테고리와 제목을 결합한 헤더 형식과 사용자 정보 및 생성일시 표시가 관리자 인터페이스에 적합하게 구성되어 있습니다.
src/components/admin/adminInquiry/AdminInquiryDetail.tsx (2)
1-7: 임포트 구문이 깔끔하게 정리되어 있습니다.모든 필요한 의존성이 적절히 임포트되었고, 타입 안전성을 위한 TypeScript 사용이 잘 되어 있습니다.
41-50: Outlet context 데이터 구조가 잘 설계되었습니다.중첩 라우팅을 통해 하위 컴포넌트에 필요한 데이터와 함수들을 효율적으로 전달하고 있습니다.
src/api/admin/customerService/Inquiry.api.ts (1)
32-41: API 함수 구조가 일관성 있게 잘 구현되었습니다.POST와 PATCH 함수 모두 동일한 InquiryAnswerBody 타입을 사용하고 적절한 HTTP 메서드를 사용하고 있습니다.
Also applies to: 43-52
src/hooks/admin/useAdminInquiry.ts (1)
57-61: useQuery 설정이 적절합니다.ID가 있을 때만 쿼리를 활성화하는
enabled조건과 적절한 쿼리 키 사용이 잘 구현되었습니다.src/components/admin/adminInquiry/AdminInquiryAnswer.styled.ts (1)
11-15: 스타일 컴포넌트 확장이 효율적입니다.기존 컴포넌트를 확장하여 코드 중복을 방지하고 일관성을 유지하는 좋은 접근법입니다.
src/components/admin/adminInquiry/AdminInquiry.styled.ts (3)
1-3: 라이브러리 import 구조 적절
react-router-dom과 styled-components import 순서가 가독성에 적합합니다.
17-20: 카테고리 스타일 적절
폰트 크기와 굵기 설정이 의도대로 적용되어 있으며, UI 일관성을 잘 유지하고 있습니다.
29-41: 답변 상태 스타일링 적절
$hasAnswer프로퍼티를 기반으로 색상과 배경을 조건부로 적용한 구현이 명확합니다.src/components/admin/adminInquiry/AdminInquiryDetailContent.styled.ts (9)
1-8: 라이브러리 및 내부 컴포넌트 import
외부 styled-components와 내부 버튼, 모달 이미지 컴포넌트를 잘 가져오고 있습니다.
10-15: 컨테이너 스타일 적절
width,padding,border,border-radius설정이 문의 상세 컨텐츠 영역에 적합합니다.
19-21: 헤더 래퍼 스타일 적절
마진으로 하단 여백을 확보해 헤더와 본문을 구분한 점이 좋습니다.
23-27: 제목 스타일 적절
폰트 크기, 굵기, 여백 설정으로 시멘틱한 제목 강조가 잘 구현되었습니다.
29-33: 정보 래퍼 스타일 적절
Flexbox와 gap으로 정보 항목 간 간격을 일관되게 적용한 점이 인상적입니다.
35-38: 정보 텍스트 스타일 적절
플레이스홀더 색상을 활용해 부차적 정보임을 명확히 표현했습니다.
40-43: 삭제 버튼 스타일 상속
SendButton에서 상속받아 폰트 크기와 패딩만 조정한 것은 DRY 원칙에 부합합니다.
45-48: 본문 컨텐츠 스타일 적절
폰트 크기와 넓이 설정이 본문 가독성을 고려한 합리적인 선택입니다.
56-58: 메시지 래퍼 스타일 적절
폰트 크기로 부가 설명을 구분하는 방식이 명확합니다.
| const [answer, setAnswer] = useState<string>(''); | ||
| const selectButton: LinkType = answer === null ? '작성하기' : '수정하기'; |
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.
버튼 선택 로직의 타입 불일치를 수정하세요.
answer 상태가 string으로 타입이 지정되어 있는데 null과 비교하고 있습니다. answerData가 없는 경우를 올바르게 처리해야 합니다.
- const [answer, setAnswer] = useState<string>('');
- const selectButton: LinkType = answer === null ? '작성하기' : '수정하기';
+ const [answer, setAnswer] = useState<string | null>(null);
+ const selectButton: LinkType = !answer || answer.trim() === '' ? '작성하기' : '수정하기';🤖 Prompt for AI Agents
In src/components/admin/adminInquiry/AdminInquiryAnswer.tsx around lines 16 to
17, the code compares the string-typed state variable 'answer' to null, which is
a type mismatch. To fix this, adjust the condition to check if 'answer' is an
empty string instead of null, or modify the state type to include null if that
is intended. Ensure the button selection logic correctly reflects whether
'answer' has meaningful content by using a proper check like answer === '' or
answer.length === 0.
| const handleSubmitAnswer = (e: React.FormEvent<HTMLFormElement>) => { | ||
| e.preventDefault(); | ||
|
|
||
| if (isWrite) { | ||
| postInquiryAnswerMutate.mutate({ id, answer: answer }); | ||
| } else { | ||
| patchInquiryAnswerMutate.mutate({ id, answer: answer }); | ||
| } | ||
| }; |
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.
🛠️ Refactor suggestion
입력 검증과 로딩 상태 처리가 필요합니다.
답변 제출 시 빈 값 검증과 mutation 진행 중 로딩 상태 처리가 없습니다. 사용자 경험 개선을 위해 추가하는 것이 좋겠습니다.
const handleSubmitAnswer = (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault();
+
+ if (!answer.trim()) {
+ return;
+ }
if (isWrite) {
postInquiryAnswerMutate.mutate({ id, answer: answer });
} else {
patchInquiryAnswerMutate.mutate({ id, answer: answer });
}
};또한 버튼에 로딩 상태를 반영하는 것을 고려해보세요:
+ const isLoading = postInquiryAnswerMutate.isPending || patchInquiryAnswerMutate.isPending;
<S.InquiryAnswerWriteButton type='submit'
+ disabled={isLoading}
>
<S.InquiryAnswerWriteButtonSpan>
- 답변하기
+ {isLoading ? '처리 중...' : '답변하기'}
</S.InquiryAnswerWriteButtonSpan>
</S.InquiryAnswerWriteButton>📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| const handleSubmitAnswer = (e: React.FormEvent<HTMLFormElement>) => { | |
| e.preventDefault(); | |
| if (isWrite) { | |
| postInquiryAnswerMutate.mutate({ id, answer: answer }); | |
| } else { | |
| patchInquiryAnswerMutate.mutate({ id, answer: answer }); | |
| } | |
| }; | |
| // --- handleSubmitAnswer with empty-string check --- | |
| const handleSubmitAnswer = (e: React.FormEvent<HTMLFormElement>) => { | |
| e.preventDefault(); | |
| // Prevent submitting empty or whitespace-only answers | |
| if (!answer.trim()) { | |
| return; | |
| } | |
| if (isWrite) { | |
| postInquiryAnswerMutate.mutate({ id, answer: answer }); | |
| } else { | |
| patchInquiryAnswerMutate.mutate({ id, answer: answer }); | |
| } | |
| }; | |
| // --- derive a combined loading flag for both mutations --- | |
| const isLoading = | |
| postInquiryAnswerMutate.isPending || | |
| patchInquiryAnswerMutate.isPending; | |
| {/* ...later in your JSX... */} | |
| <S.InquiryAnswerWriteButton | |
| type='submit' | |
| disabled={isLoading} | |
| > | |
| <S.InquiryAnswerWriteButtonSpan> | |
| {isLoading ? '처리 중...' : '답변하기'} | |
| </S.InquiryAnswerWriteButtonSpan> | |
| </S.InquiryAnswerWriteButton> |
🤖 Prompt for AI Agents
In src/components/admin/adminInquiry/AdminInquiryAnswerWrite.tsx around lines 41
to 49, the handleSubmitAnswer function lacks input validation for empty answers
and does not handle loading states during mutation. Add a check to prevent
submission if the answer is empty, and implement loading state management to
disable the submit button and show a loading indicator while the mutation is in
progress. Update the button component to reflect the loading state accordingly.
| ); | ||
| } | ||
|
|
||
| if (!data) return; |
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.
🛠️ Refactor suggestion
데이터 없음 처리가 부족합니다.
데이터가 없을 때 아무것도 반환하지 않는 대신 사용자에게 명확한 메시지를 표시해야 합니다.
- if (!data) return;
+ if (!data) {
+ return (
+ <S.AdminInquiryDetailContainer>
+ <div>문의 데이터를 찾을 수 없습니다.</div>
+ </S.AdminInquiryDetailContainer>
+ );
+ }📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| if (!data) return; | |
| if (!data) { | |
| return ( | |
| <S.AdminInquiryDetailContainer> | |
| <div>문의 데이터를 찾을 수 없습니다.</div> | |
| </S.AdminInquiryDetailContainer> | |
| ); | |
| } |
🤖 Prompt for AI Agents
In src/components/admin/adminInquiry/AdminInquiryDetail.tsx at line 36, the code
currently returns nothing when data is absent, which provides no feedback to the
user. Modify this to render a clear and user-friendly message indicating that no
data is available, ensuring the UI communicates this state effectively.
src/hooks/admin/useAdminInquiry.ts
Outdated
| setTimeout(() => { | ||
| if (id) { | ||
| return navigate(`/admin/inquiries/detail/${id}`); | ||
| } else { | ||
| return navigate(-1); | ||
| } | ||
| }, 1000); |
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.
🛠️ Refactor suggestion
네비게이션 로직에 잠재적 문제가 있습니다.
setTimeout을 사용한 지연 네비게이션은 사용자가 페이지를 빠르게 떠날 경우 메모리 누수를 일으킬 수 있습니다.
+ const [timeoutId, setTimeoutId] = useState<NodeJS.Timeout | null>(null);
+
+ useEffect(() => {
+ return () => {
+ if (timeoutId) {
+ clearTimeout(timeoutId);
+ }
+ };
+ }, [timeoutId]);
const handleButtonState = (state: State, isDeleteApi: boolean = false) => {
switch (state) {
case 'success':
// ... existing code ...
- setTimeout(() => {
+ const id = setTimeout(() => {
if (id) {
return navigate(`/admin/inquiries/detail/${id}`);
} else {
return navigate(-1);
}
}, 1000);
+ setTimeoutId(id);
break;Committable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
In src/hooks/admin/useAdminInquiry.ts around lines 36 to 42, the use of
setTimeout for delayed navigation can cause memory leaks if the user leaves the
page quickly. To fix this, replace setTimeout with a safer approach such as
using a cleanup mechanism like clearTimeout in a useEffect cleanup function or
switching to a promise-based delay that can be cancelled on component unmount to
prevent the navigation callback from executing after the component is gone.
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
♻️ Duplicate comments (1)
src/components/admin/adminInquiry/AdminInquiryAnswerWrite.tsx (1)
81-85: 🛠️ Refactor suggestion로딩 상태를 버튼 UI에 반영하세요.
로딩 상태가 정의되어 있지만 버튼의 disabled 속성이나 텍스트에 반영되지 않아 사용자가 로딩 상태를 인지하기 어렵습니다.
- <S.InquiryAnswerWriteButton type='submit'> + <S.InquiryAnswerWriteButton type='submit' disabled={isLoading}> <S.InquiryAnswerWriteButtonSpan> - 답변하기 + {isLoading ? '처리 중...' : '답변하기'} </S.InquiryAnswerWriteButtonSpan> </S.InquiryAnswerWriteButton>
🧹 Nitpick comments (1)
src/components/admin/adminInquiry/AdminInquiryAnswerWrite.tsx (1)
67-67: 옵셔널 체이닝을 사용하여 코드를 간소화할 수 있습니다.현재의 조건문을 옵셔널 체이닝으로 간소화하면 더 읽기 쉬운 코드가 됩니다.
- if (inputRef && inputRef.current) { + if (inputRef.current) { inputRef.current.style.height = 'auto'; inputRef.current.style.height = `${inputRef.current.scrollHeight}px`; }🧰 Tools
🪛 Biome (1.9.4)
[error] 67-67: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (7)
src/components/admin/adminInquiry/AdminInquiry.styled.ts(1 hunks)src/components/admin/adminInquiry/AdminInquiry.tsx(1 hunks)src/components/admin/adminInquiry/AdminInquiryAnswer.tsx(1 hunks)src/components/admin/adminInquiry/AdminInquiryAnswerWrite.tsx(1 hunks)src/components/admin/adminInquiry/AdminInquiryList.tsx(1 hunks)src/hooks/admin/useAdminInquiry.ts(1 hunks)src/models/activityLog.ts(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (6)
- src/models/activityLog.ts
- src/components/admin/adminInquiry/AdminInquiryList.tsx
- src/components/admin/adminInquiry/AdminInquiry.tsx
- src/components/admin/adminInquiry/AdminInquiry.styled.ts
- src/components/admin/adminInquiry/AdminInquiryAnswer.tsx
- src/hooks/admin/useAdminInquiry.ts
🧰 Additional context used
🪛 Biome (1.9.4)
src/components/admin/adminInquiry/AdminInquiryAnswerWrite.tsx
[error] 67-67: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
⏰ Context from checks skipped due to timeout of 90000ms (1)
- GitHub Check: accessibility-test
🔇 Additional comments (2)
src/components/admin/adminInquiry/AdminInquiryAnswerWrite.tsx (2)
88-93: 이전 리뷰에서 지적된 ref 할당 문제가 해결되었습니다.textarea 요소에
ref={inputRef}가 추가되어 auto-resize 기능이 정상적으로 작동할 것입니다.
55-57: 이전 리뷰에서 제안된 입력 검증이 추가되었습니다.빈 답변 검증이 추가되어 사용자 경험이 개선되었습니다.
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: 0
🧹 Nitpick comments (2)
src/components/admin/adminInquiry/AdminInquiryAnswerWrite.tsx (2)
71-74: Optional chaining을 사용하여 코드를 개선하세요.Static analysis 도구에서 제안한 대로 optional chaining을 사용하면 더 간결하고 안전한 코드가 됩니다.
- if (inputRef && inputRef.current) { + if (inputRef?.current) { inputRef.current.style.height = 'auto'; inputRef.current.style.height = `${inputRef.current.scrollHeight}px`; }🧰 Tools
🪛 Biome (1.9.4)
[error] 71-71: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
92-97: 접근성 개선을 위해 aria 속성을 추가하는 것을 고려해보세요.textarea에 적절한 aria 속성을 추가하면 스크린 리더 사용자들에게 더 나은 경험을 제공할 수 있습니다.
<S.InquiryAnswerWrite as='textarea' value={answer} ref={inputRef} onChange={handleChangeAnswer} + aria-label="문의 답변 내용" + placeholder="답변을 입력해주세요" ></S.InquiryAnswerWrite>
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
src/components/admin/adminInquiry/AdminInquiryAnswer.tsx(1 hunks)src/components/admin/adminInquiry/AdminInquiryAnswerWrite.styled.ts(1 hunks)src/components/admin/adminInquiry/AdminInquiryAnswerWrite.tsx(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
- src/components/admin/adminInquiry/AdminInquiryAnswerWrite.styled.ts
- src/components/admin/adminInquiry/AdminInquiryAnswer.tsx
🧰 Additional context used
🪛 Biome (1.9.4)
src/components/admin/adminInquiry/AdminInquiryAnswerWrite.tsx
[error] 71-71: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
⏰ Context from checks skipped due to timeout of 90000ms (1)
- GitHub Check: accessibility-test
🔇 Additional comments (1)
src/components/admin/adminInquiry/AdminInquiryAnswerWrite.tsx (1)
1-104: 전반적으로 잘 구현된 컴포넌트입니다.과거 리뷰에서 지적되었던 ref 할당, 로딩 상태 처리, 입력 검증 등의 이슈들이 모두 적절히 해결되었습니다. 관리자 문의 답변 작성/수정 기능이 깔끔하게 구현되어 있습니다.
🧰 Tools
🪛 Biome (1.9.4)
[error] 71-71: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
구현내용
관리자 문의 페이지
관리자 문의 전체 조회, 상세 조회 api
관리자 답변 페이지
관리자 문의 답변, 수정, 삭제 api
연관이슈
close #335
Summary by CodeRabbit
신규 기능
스타일
버그 수정
리팩터
기타