-
Notifications
You must be signed in to change notification settings - Fork 0
모집 공고 생성 페이지 일부 수정( feat/#355 ) #357
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/훅 도입, 태그 선택 로직 개선, 스타일 및 불필요한 import 정리 등 다양한 리팩토링과 UI/UX 개선이 이루어졌습니다. 주요 로직과 스타일 변경이 여러 파일에 걸쳐 반영되었습니다. Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant InputComponent
participant Validation
participant ProjectForm
participant API
User->>InputComponent: 값 입력 (예: maxVolunteers, duration)
InputComponent->>Validation: 숫자/최소값 검증, 유닛 표시
Validation-->>InputComponent: 유효성 결과 반환
InputComponent->>ProjectForm: 유효한 값 전달
ProjectForm->>API: 값(Number로 변환) 포함하여 제출
API-->>ProjectForm: 결과 반환
sequenceDiagram
participant AdminPage
participant useGetInquiriesPreview
participant getInquiriesPreview API
AdminPage->>useGetInquiriesPreview: 프리뷰 데이터 요청
useGetInquiriesPreview->>getInquiriesPreview API: /inquiry/preview 호출
getInquiriesPreview API-->>useGetInquiriesPreview: 데이터(최대 5개) 반환
useGetInquiriesPreview-->>AdminPage: allInquiriesPreviewData 전달
Estimated code review effort3 (~45분) 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! 📜 Recent review detailsConfiguration used: CodeRabbit UI ⛔ Files ignored due to path filters (1)
📒 Files selected for processing (5)
✅ Files skipped from review due to trivial changes (1)
🚧 Files skipped from review as they are similar to previous changes (4)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
✨ 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: 4
🧹 Nitpick comments (3)
src/components/user/projectFormComponents/projectInformationInput/ProjectInformationInput.tsx (1)
29-46: 입력 컴포넌트 개선이 잘 구현되었습니다.Fragment 제거와 unit prop 추가는 좋은 변경입니다. 다만
min={1}이 모든 입력 타입에 하드코딩되어 있는데, 체크박스나 다른 타입의 입력에는 적용되지 않아야 할 수 있습니다.다음과 같이 조건부로 min prop을 전달하는 것을 고려해보세요:
<Input indexInfo={input.id} control={control} errors={errors} name={input.name} type={input.type} unit={input.unit} - min={1} + {...(input.type === 'text' && { min: 1 })} />src/hooks/user/ProjectHooks/useTagSelectors.ts (1)
54-97: 태그 선택 로직이 요구사항에 맞게 잘 구현되었습니다.전체 선택과 개별 선택 간의 상호작용이 올바르게 처리되고 있으며, 사용자에게 적절한 확인 절차를 제공합니다. 코드 주석도 잘 작성되어 가독성이 좋습니다.
더 일관성 있는 UI/UX를 위해
window.confirm()대신 프로젝트의 커스텀 모달 컴포넌트 사용을 고려해보세요:// useModal 훅 활용 예시 const { isOpen, handleModalOpen, handleModalClose } = useModal(); // window.confirm 대신 if (selectedTag.length > 0 && !selectedTag.includes(1)) { handleModalOpen('선택된 카테고리가 해제됩니다.'); // 모달에서 확인/취소 처리 }src/components/user/projectFormComponents/inputComponent/InputComponent.styled.ts (1)
69-75: 스타일 일관성이 좋지만 너비를 검토해주세요숫자 입력 필드의 조건부 스타일링이
InputStyle과 일관성 있게 구현되었습니다. 다만 30px 너비가 일반적인 숫자 값에 충분한지 검토가 필요할 수 있습니다.더 넉넉한 너비가 필요하다면 다음과 같이 조정할 수 있습니다:
-width: 30px; +width: 40px;
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (13)
src/api/admin/customerService/inquiry.api.ts(1 hunks)src/components/admin/previewComponent/inquiresPreview/InquiresPreview.tsx(2 hunks)src/components/admin/previewComponent/noticePreview/NoticePreview.tsx(1 hunks)src/components/user/mypage/ContentTab.tsx(0 hunks)src/components/user/projectFormComponents/inputComponent/InputComponent.styled.ts(2 hunks)src/components/user/projectFormComponents/inputComponent/InputComponent.tsx(2 hunks)src/components/user/projectFormComponents/projectInformationInput/ProjectInformationInput.styled.ts(1 hunks)src/components/user/projectFormComponents/projectInformationInput/ProjectInformationInput.tsx(2 hunks)src/constants/user/projectConstants.ts(3 hunks)src/hooks/admin/useGetInquiriesPreview.ts(1 hunks)src/hooks/user/ProjectHooks/useTagSelectors.ts(1 hunks)src/pages/user/createProject/CreateProject.tsx(1 hunks)src/pages/user/modifyProject/ModifyProject.tsx(2 hunks)
💤 Files with no reviewable changes (1)
- src/components/user/mypage/ContentTab.tsx
🧰 Additional context used
🧠 Learnings (5)
📓 Common learnings
Learnt from: YouD0313
PR: devpalsPlus/frontend#334
File: src/components/common/admin/title/AdminTitle.styled.ts:4-10
Timestamp: 2025-06-05T15:59:56.230Z
Learning: YouD0313 prefers using position: fixed for admin headers due to layout requirements, even if it requires viewport-relative width calculations like calc(100vw - 20rem).
src/components/admin/previewComponent/noticePreview/NoticePreview.tsx (2)
Learnt from: YouD0313
PR: #278
File: src/pages/login/LoginSuccess.tsx:13-24
Timestamp: 2025-05-11T09:39:02.041Z
Learning: 사용자 알림은 브라우저의 기본 alert() 대신 애플리케이션의 Modal 컴포넌트(src/components/common/modal/Modal.tsx)를 사용하는 것이 선호됩니다.
Learnt from: YouD0313
PR: #278
File: src/pages/login/LoginSuccess.tsx:13-24
Timestamp: 2025-05-11T09:39:02.041Z
Learning: 사용자 알림은 브라우저의 기본 alert() 대신 애플리케이션의 Modal 컴포넌트(src/components/common/modal/Modal.tsx)를 사용하는 것이 선호됩니다.
src/hooks/admin/useGetInquiriesPreview.ts (2)
Learnt from: layout-SY
PR: #246
File: src/hooks/useAlarmList.ts:1-21
Timestamp: 2025-04-23T13:39:08.960Z
Learning: React Query의 useQuery 훅에서 queryFn으로 Promise를 반환하는 함수를 사용할 때는 불필요한 async/await을 사용하지 않는 것이 좋습니다. 예를 들어 queryFn: async () => await getAlarmList() 대신에 queryFn: () => getAlarmList()와 같이 직접 Promise를 반환하는 형태로 작성하는 것이 더 효율적입니다.
Learnt from: layout-SY
PR: #246
File: src/hooks/useAlarmList.ts:1-21
Timestamp: 2025-04-23T13:39:08.960Z
Learning: React Query의 useQuery 훅에서 queryFn으로 Promise를 반환하는 함수를 사용할 때는 불필요한 async/await을 사용하지 않는 것이 좋습니다. 예를 들어 queryFn: async () => await getAlarmList() 대신에 queryFn: () => getAlarmList()와 같이 직접 Promise를 반환하는 형태로 작성하는 것이 더 효율적입니다.
src/components/user/projectFormComponents/inputComponent/InputComponent.tsx (1)
Learnt from: YouD0313
PR: #259
File: src/components/common/customerService/inquiry/Inquiry.tsx:80-83
Timestamp: 2025-04-29T12:55:53.136Z
Learning: React에서 controlled 컴포넌트(value prop이 있는 input)를 사용할 때는 onChange 핸들러도 함께 제공해야 합니다. 그렇지 않으면 입력 필드가 읽기 전용이 되어 사용자가 값을 입력할 수 없습니다.
src/components/user/projectFormComponents/inputComponent/InputComponent.styled.ts (1)
Learnt from: YouD0313
PR: #330
File: src/components/common/admin/searchBar/SearchBar.styled.ts:20-23
Timestamp: 2025-06-03T02:14:04.020Z
Learning: devpalsPlus 프로젝트에서는 sanitize.css와 GlobalStyle을 통해 CSS reset이 적용되어 있어, input 요소의 기본 border와 outline 스타일이 이미 정규화되어 있다.
🧬 Code Graph Analysis (4)
src/components/user/projectFormComponents/projectInformationInput/ProjectInformationInput.tsx (1)
src/components/user/comment/commentInput/CommentInput.styled.ts (1)
Input(9-13)
src/hooks/admin/useGetInquiriesPreview.ts (1)
src/api/admin/customerService/inquiry.api.ts (1)
getInquiriesPreview(24-27)
src/components/admin/previewComponent/inquiresPreview/InquiresPreview.tsx (1)
src/hooks/admin/useGetInquiriesPreview.ts (1)
useGetInquiriesPreview(5-17)
src/api/admin/customerService/inquiry.api.ts (2)
src/api/http.api.ts (1)
httpClient(80-80)src/models/inquiry.ts (1)
ApiAdminInquiry(25-27)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: accessibility-test
🔇 Additional comments (15)
src/components/admin/previewComponent/noticePreview/NoticePreview.tsx (1)
18-18: 타이포 수정 완료"공지사힝이"를 "공지사항이"로 수정한 것이 올바른 변경입니다. 사용자 경험 개선에 도움이 됩니다.
src/hooks/admin/useGetInquiriesPreview.ts (1)
5-17: React Query 훅 구현 우수새로운
useGetInquiriesPreview훅이 잘 구현되었습니다:
queryFn에서 불필요한 async/await 래핑을 피하고 직접 Promise를 반환하는 함수를 사용한 점이 좋습니다select옵션을 사용해 클라이언트 사이드에서 효율적으로 처음 5개 항목으로 제한하는 것이 적절합니다- 반환값과 네이밍 컨벤션이 일관됩니다
src/components/admin/previewComponent/inquiresPreview/InquiresPreview.tsx (1)
6-6: 데이터 소스 교체 완료
useGetAllInquiries에서useGetInquiriesPreview로 데이터 소스를 성공적으로 교체했습니다:
- 임포트와 훅 사용법이 올바르게 업데이트되었습니다
- 변수명이
allInquiriesPreviewData로 일관되게 변경되었습니다- 조건부 렌더링과 맵핑 로직이 새로운 데이터 소스에 맞게 적절히 수정되었습니다
미리보기 전용 데이터를 사용하는 것이 이 컴포넌트의 목적에 더 적합합니다.
Also applies to: 9-10, 20-20, 26-26
src/components/user/projectFormComponents/projectInformationInput/ProjectInformationInput.styled.ts (1)
20-25: 새로운 스타일 컴포넌트가 잘 구현되었습니다.테마 기반 스타일링을 적절히 활용하고 있으며, 라벨 설명 텍스트를 위한 명확한 목적을 가지고 있습니다. 네이밍과 스타일 속성도 일관성 있게 작성되었습니다.
src/pages/user/createProject/CreateProject.tsx (2)
46-46: 명시적 타입 변환이 올바르게 적용되었습니다.입력 필드 타입 변경에 따른 적절한 대응입니다. 폼 스키마에서 숫자 유효성 검사를 수행하고 있는지 확인해주세요.
51-51: 타입 변환과 단위 포맷팅이 올바르게 구현되었습니다.duration 필드의 명시적 숫자 변환과 단위 추가가 적절히 처리되었습니다.
src/components/user/projectFormComponents/projectInformationInput/ProjectInformationInput.tsx (1)
61-66: 사용자 안내 메시지가 적절히 추가되었습니다.모집 분야 선택에 대한 명확한 안내 문구가 추가되어 사용자 경험이 개선될 것입니다.
src/pages/user/modifyProject/ModifyProject.tsx (3)
60-60: 입력 타입 변경에 맞는 적절한 수정입니다.Number 변환을 제거하고 문자열 슬라이스만 사용하는 것이 새로운 입력 타입에 맞습니다.
76-76: 명시적 타입 변환이 올바르게 추가되었습니다.CreateProject.tsx와 일관성 있는 변경입니다.
81-81: 단위 불일치 확인 필요현재 프로젝트 생성(CreateProject.tsx)와 수정(ModifyProject.tsx) 화면에서
estimatedPeriod에 사용된 단위가 서로 다릅니다.
의도된 변경인지 확인 부탁드립니다.
- src/pages/user/createProject/CreateProject.tsx
estimatedPeriod: `${Number(data.duration)}개월`,- src/pages/user/modifyProject/ModifyProject.tsx
estimatedPeriod: `${Number(data.duration)}일`,위 차이가 의도된 것이 아니라면, 두 화면에서 동일한 단위(예: 개월 또는 일)를 사용하도록 수정해 주세요.
src/components/user/projectFormComponents/inputComponent/InputComponent.tsx (2)
13-14: 새로운 props 추가가 적절합니다
unit과minprops 추가로 입력 필드의 단위 표시와 최소값 설정이 가능해졌습니다. PR 목표에 부합하는 변경사항입니다.
57-87: 렌더링 로직이 일관성 있게 구현되었습니다
InputWrapper와UnitText를 활용한 레이아웃과 조건부 단위 표시가 잘 구현되었습니다. 두 입력 케이스 모두 일관된 구조를 가지고 있습니다.src/constants/user/projectConstants.ts (1)
10-11: 상수 변경이 적절합니다
maxVolunteers와duration필드의 타입을 'text'로 변경하고 단위를 추가한 것은 입력 컴포넌트의 변경사항과 일치합니다.Also applies to: 26-27
src/components/user/projectFormComponents/inputComponent/InputComponent.styled.ts (2)
9-19: 새로운 스타일 컴포넌트가 잘 설계되었습니다
InputWrapper와UnitText컴포넌트가 입력 필드와 단위 텍스트의 레이아웃을 깔끔하게 처리합니다. 2px 간격과 테마 일관성이 좋습니다.
30-36: 조건부 스타일링이 적절합니다
maxVolunteers와duration필드에 대한 좁은 너비(60px)와 우측 정렬은 숫자 입력과 단위 표시에 적합합니다.
| const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => { | ||
| const value = e.target.value; | ||
|
|
||
| // 숫자 입력 필드인 경우 숫자만 허용 | ||
| if (name === 'maxVolunteers' || name === 'duration') { | ||
| // 숫자가 아닌 문자 제거 | ||
| const numericValue = value.replace(/[^0-9]/g, ''); | ||
| if (numericValue !== value) { | ||
| e.target.value = numericValue; | ||
| } | ||
|
|
||
| // 음수 방지 (0보다 작은 값은 허용하지 않음) | ||
| const numValue = Number(numericValue); | ||
| if (numValue < min) { | ||
| return; | ||
| } | ||
| } | ||
|
|
||
| field.onChange(e); | ||
| }; |
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
입력 검증 로직을 개선해주세요
숫자 입력 검증 로직이 잘 구현되었지만, e.target.value를 직접 수정한 후 field.onChange(e)를 호출하는 방식은 일관성 문제를 야기할 수 있습니다.
더 안정적인 구현을 위해 다음과 같이 수정하는 것을 권장합니다:
const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
- const value = e.target.value;
+ let value = e.target.value;
// 숫자 입력 필드인 경우 숫자만 허용
if (name === 'maxVolunteers' || name === 'duration') {
// 숫자가 아닌 문자 제거
- const numericValue = value.replace(/[^0-9]/g, '');
- if (numericValue !== value) {
- e.target.value = numericValue;
- }
+ value = value.replace(/[^0-9]/g, '');
// 음수 방지 (0보다 작은 값은 허용하지 않음)
- const numValue = Number(numericValue);
+ const numValue = Number(value);
if (numValue < min) {
return;
}
}
- field.onChange(e);
+ field.onChange(value);
};🤖 Prompt for AI Agents
In src/components/user/projectFormComponents/inputComponent/InputComponent.tsx
around lines 33 to 52, avoid directly modifying e.target.value before calling
field.onChange(e) as it can cause inconsistencies. Instead, extract and sanitize
the input value first, then call field.onChange with a synthetic event or
directly pass the sanitized value to update the form state. This ensures
consistent and reliable input handling without mutating the original event
object.
| const value = e.target.value; | ||
|
|
||
| // 숫자 입력 필드인 경우 숫자만 허용 | ||
| if (name === 'maxVolunteers' || name === 'duration') { |
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 agent
🧩 Analysis chain
스키마와 입력 검증의 일관성을 확인해주세요
maxVolunteers와 duration 필드가 텍스트 입력으로 변경되었는데, 프로젝트 상수 파일의 검증 스키마가 이 변경사항과 일치하는지 확인이 필요합니다.
다음 스크립트를 실행하여 스키마 일관성을 확인해주세요:
🏁 Script executed:
#!/bin/bash
# 스키마에서 maxVolunteers와 duration 필드의 타입 확인
rg -A 10 "maxVolunteers.*z\." src/constants/user/projectConstants.ts
rg -A 10 "duration.*z\." src/constants/user/projectConstants.tsLength of output: 136
다음 스크립트로 projectConstants.ts 내 검증 스키마 정의와 maxVolunteers·duration 타입을 다시 확인해주세요:
🏁 Script executed:
#!/bin/bash
# Zod 스키마 정의 위치 확인
rg -n "z.object" -A 20 src/constants/user/projectConstants.ts || true
# 각 필드 타입 확인
rg -n "maxVolunteers" -A 5 src/constants/user/projectConstants.ts || true
rg -n "duration" -A 5 src/constants/user/projectConstants.ts || trueLength of output: 2145
duration 필드 스키마 타입 불일치 보강 필요
프로젝트 상수(src/constants/user/projectConstants.ts)의 createProjectScheme에서:
maxVolunteers
• z.number — UI에서 text 입력 후 숫자로 변환 → 검증 일치duration
• z.string — UI에서 text 입력만 검증(refine) → 반환 타입은 string
두 필드를 모두 숫자형으로 다룰 예정이라면 duration도 z.number로 변경하거나, 반대로 maxVolunteers를 z.string 기반 검증으로 통일해야 합니다.
수정 예시:
--- a/src/constants/user/projectConstants.ts
+++ b/src/constants/user/projectConstants.ts
@@ -95,7 +95,7 @@ export const createProjectScheme = z.object({
- duration: z
- .string({ message: '예상 기간을 입력해주세요.' })
- .min(1, { message: '예상 기간을 입력해주세요.' })
- .refine((val) => {
- const num = Number(val);
- return !isNaN(num) && num > 0;
- }, { message: '유효한 기간을 입력해주세요.' }),
+ duration: z
+ .number({ message: '예상 기간을 입력해주세요.' })
+ .min(1, { message: '예상 기간을 입력해주세요.' }),위와 같이 duration을 z.number로 변경해 일관성을 맞춰주세요.
📝 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 (name === 'maxVolunteers' || name === 'duration') { | |
| export const createProjectScheme = z.object({ | |
| // ... other schema fields ... | |
| - duration: z | |
| - .string({ message: '예상 기간을 입력해주세요.' }) | |
| - .min(1, { message: '예상 기간을 입력해주세요.' }) | |
| - .refine((val) => { | |
| - const num = Number(val); | |
| - return !isNaN(num) && num > 0; | |
| - }, { message: '유효한 기간을 입력해주세요.' }), | |
| + duration: z | |
| + .number({ message: '예상 기간을 입력해주세요.' }) | |
| + .min(1, { message: '예상 기간을 입력해주세요.' }), | |
| maxVolunteers: z | |
| .number({ message: '모집 인원을 입력해주세요.' }) | |
| .min(1, { message: '모집 인원은 1명이상이어야 합니다.' }), | |
| // ... other schema fields ... | |
| }); |
🤖 Prompt for AI Agents
In src/components/user/projectFormComponents/inputComponent/InputComponent.tsx
at line 37, the condition checks for 'duration' and 'maxVolunteers' fields, but
the schema type for 'duration' in src/constants/user/projectConstants.ts's
createProjectScheme is z.string while 'maxVolunteers' is z.number. To maintain
consistency and handle both as numbers, update the createProjectScheme to change
the 'duration' field type from z.string to z.number, ensuring the validation and
UI handling align with numeric types for both fields.
| maxVolunteers: z | ||
| .number({ message: '모집 인원을 입력해주세요.' }) | ||
| .min(1, { message: '모집 인원은 1명 이상이어야 합니다.' }) | ||
| .max(1000, { message: '모집 인원은 1000명 이하이어야 합니다.' }), | ||
| .min(1, { message: '모집 인원을 입력해주세요.' }) | ||
| .refine( | ||
| (val) => { | ||
| const num = Number(val); | ||
| return !isNaN(num) && num >= 1 && num <= 1000; | ||
| }, | ||
| { message: '모집 인원은 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.
스키마 타입 불일치를 수정해주세요
maxVolunteers와 duration 필드에서 타입 불일치가 발생하고 있습니다. z.number()로 정의되어 있지만 refine 함수 내부에서는 문자열로 처리하고 있습니다.
다음과 같이 수정하여 일관성을 맞춰주세요:
-maxVolunteers: z
- .number({ message: '모집 인원을 입력해주세요.' })
- .min(1, { message: '모집 인원을 입력해주세요.' })
- .refine(
- (val) => {
- const num = Number(val);
- return !isNaN(num) && num >= 1 && num <= 1000;
- },
- { message: '모집 인원은 1명 이상 1000명 이하여야 합니다.' }
- ),
+maxVolunteers: z
+ .string({ message: '모집 인원을 입력해주세요.' })
+ .min(1, { message: '모집 인원을 입력해주세요.' })
+ .refine(
+ (val) => {
+ const num = Number(val);
+ return !isNaN(num) && num >= 1 && num <= 1000;
+ },
+ { message: '모집 인원은 1명 이상 1000명 이하여야 합니다.' }
+ ),
-duration: z
- .string({ message: '예상 기간을 입력해주세요.' })
- .min(1, { message: '예상 기간을 입력해주세요.' })
- .refine(
- (val) => {
- const num = Number(val);
- return !isNaN(num) && num >= 1 && num <= 365;
- },
- { message: '예상 기간은 1일 이상 365일 이하여야 합니다.' }
- ),
+duration: z
+ .string({ message: '예상 기간을 입력해주세요.' })
+ .min(1, { message: '예상 기간을 입력해주세요.' })
+ .refine(
+ (val) => {
+ const num = Number(val);
+ return !isNaN(num) && num >= 1 && num <= 365;
+ },
+ { message: '예상 기간은 1일 이상 365일 이하여야 합니다.' }
+ ),Also applies to: 95-104
🤖 Prompt for AI Agents
In src/constants/user/projectConstants.ts around lines 79 to 88 and 95 to 104,
the maxVolunteers and duration fields are defined as z.number() but the refine
function treats the input as a string by converting it with Number(). To fix
this, remove the Number() conversion inside the refine function and directly
validate the numeric value since z.number() already ensures the input is a
number. Adjust the refine callbacks to work with numbers consistently to resolve
the type mismatch.
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 (1)
src/api/http.api.ts (1)
54-66: 주석처리된 코드의 일관성 개선 필요주석처리된 코드에서 여전히 제거된
login함수와postRefresh함수를 참조하고 있습니다. 향후 이 코드를 활성화할 때 혼란을 방지하기 위해 주석을 업데이트하는 것을 고려해보세요.- // login(newAccessToken,null); + // // TODO: login 함수 호출 필요 (제거된 함수)
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (18)
src/api/admin/tag.api.ts(1 hunks)src/api/http.api.ts(1 hunks)src/components/admin/adminInquiry/AdminInquiryList.tsx(1 hunks)src/components/admin/adminTags/AdminTagsBasic.tsx(1 hunks)src/components/admin/adminUserReport/AdminReportDetail.tsx(0 hunks)src/components/admin/mainCard/graphCard/GraphCard.tsx(0 hunks)src/components/admin/previewComponent/allUserPreview/AllUserPreview.tsx(0 hunks)src/components/admin/userCard/UserCard.tsx(0 hunks)src/components/user/comment/DropDownItem.tsx(0 hunks)src/components/user/mypage/activityLog/inquiries/inquiry/Inquiry.tsx(2 hunks)src/components/user/mypage/myProfile/editProfile/ProfileGithubSuccess.tsx(0 hunks)src/hooks/useOauth.ts(0 hunks)src/hooks/user/useMyInfo.ts(2 hunks)src/models/auth.ts(1 hunks)src/pages/admin/adminUser/AdminUser.tsx(1 hunks)src/routes/AdminRoutes.tsx(2 hunks)src/routes/AppRoutes.tsx(0 hunks)src/store/authStore.ts(0 hunks)
🧠 Learnings (3)
📓 Common learnings
Learnt from: YouD0313
PR: devpalsPlus/frontend#334
File: src/components/common/admin/title/AdminTitle.styled.ts:4-10
Timestamp: 2025-06-05T15:59:56.230Z
Learning: YouD0313 prefers using position: fixed for admin headers due to layout requirements, even if it requires viewport-relative width calculations like calc(100vw - 20rem).
src/pages/admin/adminUser/AdminUser.tsx (2)
Learnt from: YouD0313
PR: #278
File: src/pages/login/LoginSuccess.tsx:13-24
Timestamp: 2025-05-11T09:39:02.041Z
Learning: 사용자 알림은 브라우저의 기본 alert() 대신 애플리케이션의 Modal 컴포넌트(src/components/common/modal/Modal.tsx)를 사용하는 것이 선호됩니다.
Learnt from: YouD0313
PR: #278
File: src/pages/login/LoginSuccess.tsx:13-24
Timestamp: 2025-05-11T09:39:02.041Z
Learning: 사용자 알림은 브라우저의 기본 alert() 대신 애플리케이션의 Modal 컴포넌트(src/components/common/modal/Modal.tsx)를 사용하는 것이 선호됩니다.
src/hooks/user/useMyInfo.ts (4)
Learnt from: YouD0313
PR: #278
File: src/pages/login/LoginSuccess.tsx:13-24
Timestamp: 2025-05-11T09:39:02.041Z
Learning: 사용자 알림은 브라우저의 기본 alert() 대신 애플리케이션의 Modal 컴포넌트(src/components/common/modal/Modal.tsx)를 사용하는 것이 선호됩니다.
Learnt from: YouD0313
PR: #278
File: src/pages/login/LoginSuccess.tsx:13-24
Timestamp: 2025-05-11T09:39:02.041Z
Learning: 사용자 알림은 브라우저의 기본 alert() 대신 애플리케이션의 Modal 컴포넌트(src/components/common/modal/Modal.tsx)를 사용하는 것이 선호됩니다.
Learnt from: layout-SY
PR: #246
File: src/hooks/useAlarmList.ts:1-21
Timestamp: 2025-04-23T13:39:08.960Z
Learning: React Query의 useQuery 훅에서 queryFn으로 Promise를 반환하는 함수를 사용할 때는 불필요한 async/await을 사용하지 않는 것이 좋습니다. 예를 들어 queryFn: async () => await getAlarmList() 대신에 queryFn: () => getAlarmList()와 같이 직접 Promise를 반환하는 형태로 작성하는 것이 더 효율적입니다.
Learnt from: layout-SY
PR: #246
File: src/hooks/useAlarmList.ts:1-21
Timestamp: 2025-04-23T13:39:08.960Z
Learning: React Query의 useQuery 훅에서 queryFn으로 Promise를 반환하는 함수를 사용할 때는 불필요한 async/await을 사용하지 않는 것이 좋습니다. 예를 들어 queryFn: async () => await getAlarmList() 대신에 queryFn: () => getAlarmList()와 같이 직접 Promise를 반환하는 형태로 작성하는 것이 더 효율적입니다.
🧬 Code Graph Analysis (1)
src/hooks/user/useMyInfo.ts (3)
src/models/userProject.ts (1)
AppliedProject(20-24)src/hooks/queries/keys.ts (1)
ProjectListKey(22-25)src/api/mypage.api.ts (1)
getMyAppliedStatusList(79-90)
💤 Files with no reviewable changes (9)
- src/components/admin/adminUserReport/AdminReportDetail.tsx
- src/components/admin/userCard/UserCard.tsx
- src/components/admin/previewComponent/allUserPreview/AllUserPreview.tsx
- src/routes/AppRoutes.tsx
- src/components/user/comment/DropDownItem.tsx
- src/store/authStore.ts
- src/components/admin/mainCard/graphCard/GraphCard.tsx
- src/components/user/mypage/myProfile/editProfile/ProfileGithubSuccess.tsx
- src/hooks/useOauth.ts
✅ Files skipped from review due to trivial changes (5)
- src/components/admin/adminTags/AdminTagsBasic.tsx
- src/api/admin/tag.api.ts
- src/models/auth.ts
- src/routes/AdminRoutes.tsx
- src/components/admin/adminInquiry/AdminInquiryList.tsx
🧰 Additional context used
🧠 Learnings (3)
📓 Common learnings
Learnt from: YouD0313
PR: devpalsPlus/frontend#334
File: src/components/common/admin/title/AdminTitle.styled.ts:4-10
Timestamp: 2025-06-05T15:59:56.230Z
Learning: YouD0313 prefers using position: fixed for admin headers due to layout requirements, even if it requires viewport-relative width calculations like calc(100vw - 20rem).
src/pages/admin/adminUser/AdminUser.tsx (2)
Learnt from: YouD0313
PR: #278
File: src/pages/login/LoginSuccess.tsx:13-24
Timestamp: 2025-05-11T09:39:02.041Z
Learning: 사용자 알림은 브라우저의 기본 alert() 대신 애플리케이션의 Modal 컴포넌트(src/components/common/modal/Modal.tsx)를 사용하는 것이 선호됩니다.
Learnt from: YouD0313
PR: #278
File: src/pages/login/LoginSuccess.tsx:13-24
Timestamp: 2025-05-11T09:39:02.041Z
Learning: 사용자 알림은 브라우저의 기본 alert() 대신 애플리케이션의 Modal 컴포넌트(src/components/common/modal/Modal.tsx)를 사용하는 것이 선호됩니다.
src/hooks/user/useMyInfo.ts (4)
Learnt from: YouD0313
PR: #278
File: src/pages/login/LoginSuccess.tsx:13-24
Timestamp: 2025-05-11T09:39:02.041Z
Learning: 사용자 알림은 브라우저의 기본 alert() 대신 애플리케이션의 Modal 컴포넌트(src/components/common/modal/Modal.tsx)를 사용하는 것이 선호됩니다.
Learnt from: YouD0313
PR: #278
File: src/pages/login/LoginSuccess.tsx:13-24
Timestamp: 2025-05-11T09:39:02.041Z
Learning: 사용자 알림은 브라우저의 기본 alert() 대신 애플리케이션의 Modal 컴포넌트(src/components/common/modal/Modal.tsx)를 사용하는 것이 선호됩니다.
Learnt from: layout-SY
PR: #246
File: src/hooks/useAlarmList.ts:1-21
Timestamp: 2025-04-23T13:39:08.960Z
Learning: React Query의 useQuery 훅에서 queryFn으로 Promise를 반환하는 함수를 사용할 때는 불필요한 async/await을 사용하지 않는 것이 좋습니다. 예를 들어 queryFn: async () => await getAlarmList() 대신에 queryFn: () => getAlarmList()와 같이 직접 Promise를 반환하는 형태로 작성하는 것이 더 효율적입니다.
Learnt from: layout-SY
PR: #246
File: src/hooks/useAlarmList.ts:1-21
Timestamp: 2025-04-23T13:39:08.960Z
Learning: React Query의 useQuery 훅에서 queryFn으로 Promise를 반환하는 함수를 사용할 때는 불필요한 async/await을 사용하지 않는 것이 좋습니다. 예를 들어 queryFn: async () => await getAlarmList() 대신에 queryFn: () => getAlarmList()와 같이 직접 Promise를 반환하는 형태로 작성하는 것이 더 효율적입니다.
🧬 Code Graph Analysis (1)
src/hooks/user/useMyInfo.ts (3)
src/models/userProject.ts (1)
AppliedProject(20-24)src/hooks/queries/keys.ts (1)
ProjectListKey(22-25)src/api/mypage.api.ts (1)
getMyAppliedStatusList(79-90)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: accessibility-test
🔇 Additional comments (4)
src/components/user/mypage/activityLog/inquiries/inquiry/Inquiry.tsx (1)
1-1: 사용하지 않는 코드 제거를 승인합니다.
useRef임포트와answerRef,handleChangeAnswerRef함수가 제거된 것이 적절합니다. 현재 컴포넌트에서는 답변을 정적 div 요소로 표시하고 있어 동적 textarea 크기 조정 기능이 실제로 사용되지 않았습니다. 불필요한 코드를 제거하여 코드의 가독성과 유지보수성이 향상되었습니다.Also applies to: 25-25, 27-32
src/api/http.api.ts (1)
8-8: 변경사항 승인
login함수가 더 이상 사용되지 않으므로 destructuring에서 제거한 것은 올바른 변경입니다.src/hooks/user/useMyInfo.ts (2)
19-19: 타입 변경 승인
ApiAppliedProject에서AppliedProject로의 타입 변경이 적절합니다.
133-140: getMyAppliedStatusList 반환값 이용이 올바릅니다
src/api/mypage.api.ts의 구현을 확인한 결과,처럼export const getMyAppliedStatusList = async () => { const response = await httpClient.get<ApiAppliedProject>('/user/applications'); return response.data.data; };response.data.data를 직접 반환하고 있습니다.- 따라서
useQuery에서 받는data는 이미AppliedProject[]형태이며, 추가적인data?.data접근 없이도 올바른 데이터가 내려옵니다.해당 코드는 수정이 필요 없으니, 원래 리뷰 코멘트는 무시하셔도 됩니다.
Likely an incorrect or invalid review comment.
| const onBan = () => { | ||
| // TODO : 버튼을 누르면 해당 유저 강퇴 조치 API 전송. | ||
| }; |
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 agent
🧩 Analysis chain
userId 매개변수 제거로 인한 잠재적 문제 확인 필요
onBan 함수에서 userId 매개변수가 제거되었지만, 실제 사용자 차단 기능을 구현할 때 어떤 사용자를 차단할지 식별할 방법이 없습니다. UserCard 컴포넌트가 이 함수를 어떻게 호출하는지 확인이 필요합니다.
다음 스크립트를 실행하여 UserCard 컴포넌트가 onBan 함수를 어떻게 사용하는지 확인해주세요:
🏁 Script executed:
#!/bin/bash
# UserCard 컴포넌트에서 onBan 함수 사용법 확인
ast-grep --pattern $'const UserCard = ($$$) => {
$$$
onBan($$$)
$$$
}'
# UserCard 컴포넌트의 props 타입 정의 확인
rg -A 10 -B 5 "interface.*UserCard" src/components/admin/userCard/
rg -A 10 -B 5 "type.*UserCard" src/components/admin/userCard/Length of output: 1374
onBan 함수에 userId 매개변수 추가 필요
UserCardProps.onBan의 타입이 (userId: number) => void로 정의되어 있어, 현재 AdminUser.tsx에서 매개변수 없이 선언된 onBan은 호출 시 전달되는 userId를 받을 수 없습니다. 다음과 같이 수정해주세요:
• src/pages/admin/adminUser/AdminUser.tsx
- const onBan = () => {
- // TODO : 버튼을 누르면 해당 유저 강퇴 조치 API 전송.
- };
+ const onBan = (userId: number) => {
+ // TODO : 버튼을 누르면 userId에 해당하는 유저 강퇴 조치 API 전송.
+ };• UserCard 호출부 확인
<UserCard
userData={user}
- onBan={onBan}
+ onBan={onBan} // UserCard 내부에서 userData.id를 인자로 넘겨야 합니다.
…
/>위 변경으로 UserCard가 전달하는 userId를 받아 실제 차단 API 호출 로직을 구현할 수 있습니다.
🤖 Prompt for AI Agents
In src/pages/admin/adminUser/AdminUser.tsx around lines 30 to 32, the onBan
function is currently declared without parameters, but it needs to accept a
userId parameter as defined by UserCardProps.onBan type. Modify the onBan
function to include a userId parameter and update the UserCard component usage
to ensure it passes userData.id as the argument to onBan. This will allow onBan
to receive the userId and implement the ban API call correctly.
구현내용
공고 생성 페이지(createProject)
공고 상세 페이지(project-detail)
신고하기 컴포넌트
연관이슈
#355
Summary by CodeRabbit
신규 기능
버그 수정
UI/스타일
기능 개선
리팩터/정리
문서화