Conversation
- Award 타입 import를 상대 경로에서 @/types/club으로 변경 - 라벨에서 이모지(🏆) 제거하여 일관성 유지
- FAQ 타입 import를 상대 경로에서 @/types/club으로 변경 - 서버에서 받아온 FAQ에 자동으로 ID 생성하는 로직 추가 - Type predicate를 사용하여 필터링 후 타입 안정성 보장 - 불필요한 null 체크 제거로 코드 간결화 - 라벨에서 이모지(❓) 제거하여 일관성 유지
- FAQ 인터페이스에 optional id 필드 추가하여 클라이언트 측 리스트 관리 지원 - RecruitmentStatus 타입 포맷 정리
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Warning
|
| Cohort / File(s) | Summary |
|---|---|
라우팅 및 임포트 업데이트 frontend/src/pages/AdminPage/AdminRoutes.tsx |
ClubIntroTab 임포트·라우트 렌더링을 ClubIntroEditTab으로 교체 |
클럽 소개 편집 탭 리네임 및 레이블/스타일 변경 frontend/src/pages/AdminPage/tabs/ClubIntroEditTab/ClubIntroEditTab.tsx, frontend/src/pages/AdminPage/tabs/ClubIntroEditTab/ClubIntroEditTab.styles.ts |
컴포넌트명·기본 export를 ClubIntroEditTab으로 변경하고 일부 이모지 레이블 제거 및 스타일 경로 업데이트 |
FAQEditor 재작성 및 이동 frontend/src/pages/AdminPage/tabs/ClubIntroEditTab/components/FAQEditor/FAQEditor.tsx |
새 FAQEditor 추가(FAQ id 자동 부여, focus 관리, 추가/삭제/수정, onChange 콜백) |
레거시 FAQEditor 제거 frontend/src/pages/AdminPage/tabs/ClubIntroTab/components/FAQEditor/FAQEditor.tsx |
기존 FAQEditor 파일 완전 삭제 |
타입 정의 업데이트 frontend/src/types/club.ts |
FAQ 인터페이스에 선택적 id?: string 추가; RecruitmentStatus 선언 형식 정리 |
클럽 정보 탭 상수/쿼리 정리 frontend/src/pages/AdminPage/tabs/ClubInfoEditTab/ClubInfoEditTab.tsx |
divisions·categories 상수를 모듈 스코프로 이동하고 useQueryClient() 사용 위치 정리 |
어워드 에디터 및 상세 뷰 소소 변경 frontend/src/pages/AdminPage/tabs/ClubIntroEditTab/components/AwardEditor/AwardEditor.tsx, frontend/src/pages/ClubDetailPage/components/ClubIntroContent/ClubIntroContent.tsx, frontend/src/pages/ClubDetailPage/components/ClubIntroContent/ClubIntroContent.styles.ts |
Award 타입 임포트 경로 변경(@/types/club), 일부 레이블 이모지 제거, AnswerBox에 white-space: pre-line 추가 |
이벤트 상수 추가 frontend/src/constants/eventName.ts |
PAGE_VIEW에 CLUB_INTRO_EDIT_PAGE 항목 추가 |
Sequence Diagram(s)
(생성 조건 미충족 — 생략)
Estimated code review effort
🎯 3 (Moderate) | ⏱️ ~20 minutes
Possibly related issues
- [fix] MOA-502 관리자가 FAQ 수정 시 하나의 답변이 모든 답변을 덮어쓰는 문제를 해결한다 #1023: FAQEditor 재작성 및
FAQ.id자동 부여로 관리자 편집 시 답변 덮어쓰기 문제와 직접 관련됩니다. - MOA-502: 관리자 FAQ 수정 시 한 답변이 모든 답변을 덮어쓰는 버그 수정 목적과 연관됩니다.
Possibly related PRs
- [feature] 관리자 페이지 > 동아리 상세정보 수정 탭 추가 및 커버 업로드 UI 제공 #958: ClubIntroTab → ClubIntroEditTab 리네임·구조 변경과 직접적인 코드 연관성 있음.
- [feature] 동아리 상세페이지 > 공통 레이아웃(UI 틀) 구현 #964:
frontend/src/types/club.ts의 FAQ/타입 변경과 중복되는 타입 수정을 포함함. - [feature] 관리자페이지 기본정보 및 소개정보 수정 api 연동 #971: 클럽 소개 관리자 UI 및 타입/경로 변경과 구조적으로 연관됨.
Suggested reviewers
- lepitaaar
- suhyun113
🚥 Pre-merge checks | ✅ 4 | ❌ 1
❌ Failed checks (1 warning)
| Check name | Status | Explanation | Resolution |
|---|---|---|---|
| Docstring Coverage | Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. | Write docstrings for the functions missing them to satisfy the coverage threshold. |
✅ Passed checks (4 passed)
| Check name | Status | Explanation |
|---|---|---|
| Description Check | ✅ Passed | Check skipped - CodeRabbit’s high-level summary is enabled. |
| Title check | ✅ Passed | PR 제목이 주요 변경사항인 FAQ 편집/삭제 버그 해결을 명확하게 설명하고 있으며, 변경사항과 직접적으로 관련이 있습니다. |
| Linked Issues check | ✅ Passed | PR의 변경사항이 MOA-502의 목표인 FAQ 편집 시 답변 덮어쓰기 버그를 해결하기 위해 FAQ 타입에 id 필드 추가, 자동 ID 생성 로직 구현, 타입 안전성 확보 등의 요구사항을 모두 충족합니다. |
| Out of Scope Changes check | ✅ Passed | 디렉토리명 변경(ClubIntroTab → ClubIntroEditTab), 이모지 제거, 절대 경로 통일 등의 변경사항이 있으나, 이들은 모두 FAQ 편집 기능 개선과 코드 정리를 위한 관련 변경으로 보여집니다. |
✏️ Tip: You can configure your own custom pre-merge checks in the settings.
✨ Finishing touches
- 📝 Generate docstrings
📜 Recent review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Disabled knowledge base sources:
- Jira integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (2)
frontend/src/constants/eventName.tsfrontend/src/pages/AdminPage/tabs/ClubIntroEditTab/ClubIntroEditTab.tsx
🧰 Additional context used
📓 Path-based instructions (3)
frontend/**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (frontend/.cursorrules)
frontend/**/*.{ts,tsx,js,jsx}: Replace magic numbers with named constants for clarity
Replace complex/nested ternaries withif/elseor IIFEs for readability
Assign complex boolean conditions to named variables for explicit meaning
Avoid hidden side effects; functions should only perform actions implied by their signature (Single Responsibility Principle)
Use unique and descriptive names for custom wrappers/functions to avoid ambiguity
Define constants near related logic or ensure names link them clearly to avoid silent failures
Break down broad state management into smaller, focused hooks/contexts to reduce coupling
Files:
frontend/src/constants/eventName.tsfrontend/src/pages/AdminPage/tabs/ClubIntroEditTab/ClubIntroEditTab.tsx
frontend/**/*.{ts,tsx}
📄 CodeRabbit inference engine (frontend/.cursorrules)
Use consistent return types for similar functions/hooks
Files:
frontend/src/constants/eventName.tsfrontend/src/pages/AdminPage/tabs/ClubIntroEditTab/ClubIntroEditTab.tsx
frontend/**/*.{tsx,jsx}
📄 CodeRabbit inference engine (frontend/.cursorrules)
frontend/**/*.{tsx,jsx}: Abstract complex logic/interactions into dedicated components/HOCs
Separate significantly different conditional UI/logic into distinct components
Colocate simple, localized logic or use inline definitions to reduce context switching
Choose field-level or form-level cohesion based on form requirements when using form libraries like react-hook-form
Use Component Composition instead of Props Drilling to reduce coupling
Files:
frontend/src/pages/AdminPage/tabs/ClubIntroEditTab/ClubIntroEditTab.tsx
🧠 Learnings (1)
📚 Learning: 2025-03-19T05:18:07.818Z
Learnt from: seongwon030
Repo: Moadong/moadong PR: 195
File: frontend/src/pages/AdminPage/AdminPage.tsx:7-7
Timestamp: 2025-03-19T05:18:07.818Z
Learning: AdminPage.tsx에서 현재 하드코딩된 클럽 ID('67d2e3b9b15c136c6acbf20b')는 로그인 기능 구현 후 동적으로 가져오는 방식으로 수정될 예정입니다.
Applied to files:
frontend/src/constants/eventName.tsfrontend/src/pages/AdminPage/tabs/ClubIntroEditTab/ClubIntroEditTab.tsx
🧬 Code graph analysis (1)
frontend/src/pages/AdminPage/tabs/ClubIntroEditTab/ClubIntroEditTab.tsx (1)
frontend/src/constants/eventName.ts (1)
PAGE_VIEW(90-105)
🔇 Additional comments (4)
frontend/src/constants/eventName.ts (1)
100-100: LGTM!새로운
CLUB_INTRO_EDIT_PAGE상수가 기존 관리자 페이지 상수들의 네이밍 컨벤션(한국어 값)을 일관되게 따르고 있습니다.frontend/src/pages/AdminPage/tabs/ClubIntroEditTab/ClubIntroEditTab.tsx (3)
12-18: LGTM!컴포넌트 이름 변경(
ClubIntroTab→ClubIntroEditTab)이 import 경로, 스타일, 페이지 뷰 트래킹 상수에 일관되게 적용되었습니다. 새로운PAGE_VIEW.CLUB_INTRO_EDIT_PAGE상수가 올바르게 사용되고 있습니다.
101-139: LGTM!레이블에서 이모지를 제거하고 텍스트를 간결하게 정리한 변경이 UI 일관성 측면에서 적절합니다. AwardEditor 정리와 동일한 방향으로 통일되었습니다.
141-141: FAQ 상태 관리 통합 패턴이 올바릅니다이 파일은 FAQ 상태를 관리하고
FAQEditor컴포넌트에 전달하는 역할을 수행하고 있습니다. FAQEditor 컴포넌트에서 구현된 자동 ID 생성 및 타입 프리디케이트를 통한 필터링이 정상적으로 작동하며, ClubIntroEditTab의 상태 관리 및 API 호출 통합도 올바르게 구성되어 있습니다.
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.
Comment @coderabbitai help to get the list of available commands and usage tips.
There was a problem hiding this comment.
Actionable comments posted: 0
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
frontend/src/pages/AdminPage/tabs/ClubIntroEditTab/ClubIntroEditTab.tsx (1)
141-141: FAQEditor의 ID 생성 로직 개선 필요FAQEditor 컴포넌트(lines 15-23, 27-31)에서 자동 ID 생성 로직이 구현되어 있습니다. 다만 현재 구현은
Date.now() + Math.random()을 사용하고 있어 동시에 여러 FAQ가 추가될 경우 ID 충돌 가능성이 있습니다. 의존성에 이미 추가된uuid또는nanoid라이브러리를 사용하여 고유한 ID 생성 방식으로 개선해주세요.
🧹 Nitpick comments (4)
frontend/src/pages/AdminPage/tabs/ClubIntroEditTab/components/AwardEditor/AwardEditor.tsx (1)
225-226: 배열 인덱스를 key로 사용하는 것에 대한 고려
achievementIndex를 key로 사용하고 있습니다. 항목이 추가/삭제될 때 React가 잘못된 요소를 재사용할 수 있어 입력 필드 상태가 꼬일 가능성이 있습니다. 다만, 이는 기존 코드이므로 이번 PR 범위를 벗어납니다.향후 개선 시 고유 ID 기반 key 사용을 고려해보세요:
♻️ 선택적 개선 제안
- <Styled.AchievementItem key={achievementIndex}> + <Styled.AchievementItem key={`${award.semester}-${achievementIndex}`}>또는 각 achievement에 고유 ID를 부여하는 구조 변경을 고려할 수 있습니다.
frontend/src/pages/AdminPage/tabs/ClubIntroEditTab/components/FAQEditor/FAQEditor.tsx (3)
15-24: 초기 렌더링 시 깜빡임(flicker) 가능성서버에서 ID 없는 FAQ가 전달되면, 첫 렌더링에서 line 80의
filter로 인해 빈 목록이 표시되고, 이후 이useEffect가 실행되어 ID가 할당된 후 다시 렌더링됩니다. 이로 인해 사용자에게 순간적인 깜빡임이 발생할 수 있습니다.
useMemo를 사용하여 렌더링 시점에 ID를 동기적으로 할당하면 이 문제를 방지할 수 있습니다.♻️ 리팩토링 제안
- useEffect(() => { - const hasAnyMissingId = faqs.some((faq) => !faq.id); - if (hasAnyMissingId) { - const faqsWithIds = faqs.map((faq) => ({ - ...faq, - id: faq.id || `faq-${Date.now()}-${Math.random()}`, - })); - onChange(faqsWithIds); - } - }, [faqs, onChange]); + const faqsWithIds = useMemo(() => { + const hasAnyMissingId = faqs.some((faq) => !faq.id); + if (hasAnyMissingId) { + const updated = faqs.map((faq) => ({ + ...faq, + id: faq.id || `faq-${Date.now()}-${Math.random()}`, + })); + // 부모에게 ID가 할당된 데이터를 전달 (다음 렌더에서 동기화) + queueMicrotask(() => onChange(updated)); + return updated; + } + return faqs; + }, [faqs, onChange]);그리고 아래 렌더링 로직에서
faqs대신faqsWithIds를 사용합니다.
40-52: 중복 코드 통합 고려
handleUpdateQuestion과handleUpdateAnswer가 거의 동일한 로직입니다. 단일 함수로 통합하면 코드 중복을 줄일 수 있습니다.♻️ 통합 제안
- const handleUpdateQuestion = (id: string, value: string) => { - const updatedFAQs = faqs.map((faq) => - faq.id === id ? { ...faq, question: value } : faq, - ); - onChange(updatedFAQs); - }; - - const handleUpdateAnswer = (id: string, value: string) => { - const updatedFAQs = faqs.map((faq) => - faq.id === id ? { ...faq, answer: value } : faq, - ); - onChange(updatedFAQs); - }; + const handleUpdateFAQ = (id: string, field: keyof Pick<FAQ, 'question' | 'answer'>, value: string) => { + const updatedFAQs = faqs.map((faq) => + faq.id === id ? { ...faq, [field]: value } : faq, + ); + onChange(updatedFAQs); + };사용 시:
onChange={(event) => handleUpdateFAQ(faq.id, 'question', event.target.value)} onChange={(event) => handleUpdateFAQ(faq.id, 'answer', event.target.value)}
99-113: 매직 넘버를 상수로 추출 고려코딩 가이드라인에 따라
maxLength값(100, 300)을 명명된 상수로 추출하면 의도가 더 명확해지고 유지보수가 쉬워집니다.♻️ 상수 추출 제안
파일 상단에 상수 정의:
const MAX_QUESTION_LENGTH = 100; const MAX_ANSWER_LENGTH = 300;사용 시:
- maxLength={100} + maxLength={MAX_QUESTION_LENGTH}- maxLength={300} + maxLength={MAX_ANSWER_LENGTH}- 질문: {faq.question.length}/100 | 답변: {faq.answer.length} - /300 + 질문: {faq.question.length}/{MAX_QUESTION_LENGTH} | 답변: {faq.answer.length} + /{MAX_ANSWER_LENGTH}
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Disabled knowledge base sources:
- Jira integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (10)
frontend/src/pages/AdminPage/AdminRoutes.tsxfrontend/src/pages/AdminPage/tabs/ClubInfoEditTab/ClubInfoEditTab.tsxfrontend/src/pages/AdminPage/tabs/ClubIntroEditTab/ClubIntroEditTab.styles.tsfrontend/src/pages/AdminPage/tabs/ClubIntroEditTab/ClubIntroEditTab.tsxfrontend/src/pages/AdminPage/tabs/ClubIntroEditTab/components/AwardEditor/AwardEditor.styles.tsfrontend/src/pages/AdminPage/tabs/ClubIntroEditTab/components/AwardEditor/AwardEditor.tsxfrontend/src/pages/AdminPage/tabs/ClubIntroEditTab/components/FAQEditor/FAQEditor.styles.tsfrontend/src/pages/AdminPage/tabs/ClubIntroEditTab/components/FAQEditor/FAQEditor.tsxfrontend/src/pages/AdminPage/tabs/ClubIntroTab/components/FAQEditor/FAQEditor.tsxfrontend/src/types/club.ts
💤 Files with no reviewable changes (1)
- frontend/src/pages/AdminPage/tabs/ClubIntroTab/components/FAQEditor/FAQEditor.tsx
🧰 Additional context used
📓 Path-based instructions (3)
frontend/**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (frontend/.cursorrules)
frontend/**/*.{ts,tsx,js,jsx}: Replace magic numbers with named constants for clarity
Replace complex/nested ternaries withif/elseor IIFEs for readability
Assign complex boolean conditions to named variables for explicit meaning
Avoid hidden side effects; functions should only perform actions implied by their signature (Single Responsibility Principle)
Use unique and descriptive names for custom wrappers/functions to avoid ambiguity
Define constants near related logic or ensure names link them clearly to avoid silent failures
Break down broad state management into smaller, focused hooks/contexts to reduce coupling
Files:
frontend/src/pages/AdminPage/tabs/ClubIntroEditTab/ClubIntroEditTab.tsxfrontend/src/pages/AdminPage/tabs/ClubIntroEditTab/components/AwardEditor/AwardEditor.tsxfrontend/src/pages/AdminPage/tabs/ClubIntroEditTab/components/FAQEditor/FAQEditor.tsxfrontend/src/types/club.tsfrontend/src/pages/AdminPage/AdminRoutes.tsxfrontend/src/pages/AdminPage/tabs/ClubInfoEditTab/ClubInfoEditTab.tsx
frontend/**/*.{tsx,jsx}
📄 CodeRabbit inference engine (frontend/.cursorrules)
frontend/**/*.{tsx,jsx}: Abstract complex logic/interactions into dedicated components/HOCs
Separate significantly different conditional UI/logic into distinct components
Colocate simple, localized logic or use inline definitions to reduce context switching
Choose field-level or form-level cohesion based on form requirements when using form libraries like react-hook-form
Use Component Composition instead of Props Drilling to reduce coupling
Files:
frontend/src/pages/AdminPage/tabs/ClubIntroEditTab/ClubIntroEditTab.tsxfrontend/src/pages/AdminPage/tabs/ClubIntroEditTab/components/AwardEditor/AwardEditor.tsxfrontend/src/pages/AdminPage/tabs/ClubIntroEditTab/components/FAQEditor/FAQEditor.tsxfrontend/src/pages/AdminPage/AdminRoutes.tsxfrontend/src/pages/AdminPage/tabs/ClubInfoEditTab/ClubInfoEditTab.tsx
frontend/**/*.{ts,tsx}
📄 CodeRabbit inference engine (frontend/.cursorrules)
Use consistent return types for similar functions/hooks
Files:
frontend/src/pages/AdminPage/tabs/ClubIntroEditTab/ClubIntroEditTab.tsxfrontend/src/pages/AdminPage/tabs/ClubIntroEditTab/components/AwardEditor/AwardEditor.tsxfrontend/src/pages/AdminPage/tabs/ClubIntroEditTab/components/FAQEditor/FAQEditor.tsxfrontend/src/types/club.tsfrontend/src/pages/AdminPage/AdminRoutes.tsxfrontend/src/pages/AdminPage/tabs/ClubInfoEditTab/ClubInfoEditTab.tsx
🧠 Learnings (9)
📓 Common learnings
Learnt from: seongwon030
Repo: Moadong/moadong PR: 195
File: frontend/src/pages/AdminPage/AdminPage.tsx:7-7
Timestamp: 2025-03-19T05:18:07.818Z
Learning: AdminPage.tsx에서 현재 하드코딩된 클럽 ID('67d2e3b9b15c136c6acbf20b')는 로그인 기능 구현 후 동적으로 가져오는 방식으로 수정될 예정입니다.
📚 Learning: 2025-03-19T05:18:07.818Z
Learnt from: seongwon030
Repo: Moadong/moadong PR: 195
File: frontend/src/pages/AdminPage/AdminPage.tsx:7-7
Timestamp: 2025-03-19T05:18:07.818Z
Learning: AdminPage.tsx에서 현재 하드코딩된 클럽 ID('67d2e3b9b15c136c6acbf20b')는 로그인 기능 구현 후 동적으로 가져오는 방식으로 수정될 예정입니다.
Applied to files:
frontend/src/pages/AdminPage/tabs/ClubIntroEditTab/ClubIntroEditTab.tsxfrontend/src/pages/AdminPage/AdminRoutes.tsxfrontend/src/pages/AdminPage/tabs/ClubInfoEditTab/ClubInfoEditTab.tsx
📚 Learning: 2025-11-25T14:08:23.253Z
Learnt from: CR
Repo: Moadong/moadong PR: 0
File: frontend/.cursorrules:0-0
Timestamp: 2025-11-25T14:08:23.253Z
Learning: Applies to frontend/**/*.{tsx,jsx} : Separate significantly different conditional UI/logic into distinct components
Applied to files:
frontend/src/pages/AdminPage/tabs/ClubIntroEditTab/ClubIntroEditTab.tsx
📚 Learning: 2025-11-25T14:08:23.253Z
Learnt from: CR
Repo: Moadong/moadong PR: 0
File: frontend/.cursorrules:0-0
Timestamp: 2025-11-25T14:08:23.253Z
Learning: Applies to frontend/**/*.{tsx,jsx} : Abstract complex logic/interactions into dedicated components/HOCs
Applied to files:
frontend/src/pages/AdminPage/tabs/ClubIntroEditTab/components/FAQEditor/FAQEditor.tsx
📚 Learning: 2025-11-25T14:08:23.253Z
Learnt from: CR
Repo: Moadong/moadong PR: 0
File: frontend/.cursorrules:0-0
Timestamp: 2025-11-25T14:08:23.253Z
Learning: Applies to frontend/**/*.{ts,tsx,js,jsx} : Replace magic numbers with named constants for clarity
Applied to files:
frontend/src/pages/AdminPage/tabs/ClubInfoEditTab/ClubInfoEditTab.tsx
📚 Learning: 2025-11-25T14:08:23.253Z
Learnt from: CR
Repo: Moadong/moadong PR: 0
File: frontend/.cursorrules:0-0
Timestamp: 2025-11-25T14:08:23.253Z
Learning: Applies to frontend/**/*.{ts,tsx,js,jsx} : Define constants near related logic or ensure names link them clearly to avoid silent failures
Applied to files:
frontend/src/pages/AdminPage/tabs/ClubInfoEditTab/ClubInfoEditTab.tsx
📚 Learning: 2025-11-25T14:08:23.253Z
Learnt from: CR
Repo: Moadong/moadong PR: 0
File: frontend/.cursorrules:0-0
Timestamp: 2025-11-25T14:08:23.253Z
Learning: Applies to frontend/**/*.{tsx,jsx} : Colocate simple, localized logic or use inline definitions to reduce context switching
Applied to files:
frontend/src/pages/AdminPage/tabs/ClubInfoEditTab/ClubInfoEditTab.tsx
📚 Learning: 2025-11-25T14:08:23.253Z
Learnt from: CR
Repo: Moadong/moadong PR: 0
File: frontend/.cursorrules:0-0
Timestamp: 2025-11-25T14:08:23.253Z
Learning: Applies to frontend/**/*.{ts,tsx,js,jsx} : Break down broad state management into smaller, focused hooks/contexts to reduce coupling
Applied to files:
frontend/src/pages/AdminPage/tabs/ClubInfoEditTab/ClubInfoEditTab.tsx
📚 Learning: 2025-07-19T05:05:10.196Z
Learnt from: seongwon030
Repo: Moadong/moadong PR: 548
File: frontend/src/pages/ClubDetailPage/ClubDetailPage.tsx:17-57
Timestamp: 2025-07-19T05:05:10.196Z
Learning: ClubDetailPage.tsx에서 notJoinedClubNames 배열의 하드코딩은 의도적인 설계 결정입니다. 개발자가 명시적으로 하드코딩을 선택했으므로 이에 대한 리팩토링 제안을 하지 않아야 합니다.
Applied to files:
frontend/src/pages/AdminPage/tabs/ClubInfoEditTab/ClubInfoEditTab.tsx
🧬 Code graph analysis (1)
frontend/src/pages/AdminPage/tabs/ClubIntroEditTab/components/FAQEditor/FAQEditor.tsx (2)
frontend/src/types/club.ts (1)
FAQ(54-58)frontend/src/pages/AdminPage/tabs/ClubIntroTab/components/FAQEditor/FAQEditor.tsx (1)
FAQEditorProps(11-105)
🔇 Additional comments (13)
frontend/src/types/club.ts (1)
54-58: LGTM! FAQ 타입에 optional id 필드 추가PR 목표에 맞게 FAQ 인터페이스에
id?: string필드가 추가되어 React 리스트 key 관리 및 클라이언트 측 FAQ 추적이 가능해졌습니다. optional로 선언한 것은 서버에서 ID가 없는 데이터가 올 수 있는 상황을 적절히 처리합니다.frontend/src/pages/AdminPage/tabs/ClubInfoEditTab/ClubInfoEditTab.tsx (2)
26-46: LGTM! 상수를 모듈 스코프로 추출
divisions와categories상수를 컴포넌트 외부로 추출한 것은 좋은 개선입니다. 렌더링마다 재생성되지 않아 성능이 향상되고, 코딩 가이드라인에 따라 상수를 관련 로직 근처에 명확하게 정의했습니다.
134-144: LGTM! 쿼리 무효화 로직 추가업데이트 성공 시
queryClient.invalidateQueries를 호출하여clubDetail캐시를 무효화하는 것은 React Query의 올바른 패턴입니다. 이를 통해 UI가 최신 데이터와 동기화됩니다.frontend/src/pages/AdminPage/tabs/ClubIntroEditTab/ClubIntroEditTab.tsx (2)
12-16: LGTM! 컴포넌트 이름 변경 및 스타일 경로 업데이트
ClubIntroTab에서ClubIntroEditTab으로의 이름 변경이 파일명과 일치하며, 스타일 import 경로도 올바르게 업데이트되었습니다.
101-139: LGTM! UI 라벨 일관성 개선이모지를 제거하고 깔끔한 한국어 라벨로 통일한 것은 UI 일관성을 향상시킵니다. PR 목표인 AwardEditor 정리 작업과 일관된 변경입니다.
frontend/src/pages/AdminPage/AdminRoutes.tsx (2)
12-12: LGTM! 라우트 import 업데이트
ClubIntroEditTabimport가 새로운 경로로 올바르게 업데이트되었습니다.
38-38: LGTM! 라우트 엘리먼트 변경
club-intro경로의 엘리먼트가ClubIntroEditTab으로 업데이트되었습니다. URL 경로는 유지되어 기존 링크나 북마크에 영향을 주지 않습니다.frontend/src/pages/AdminPage/tabs/ClubIntroEditTab/components/AwardEditor/AwardEditor.tsx (2)
5-5: LGTM! 절대 경로 import로 변경
Award타입의 import 경로가 상대 경로에서@/types/club절대 경로로 변경되어 코드 유지보수성이 향상되었습니다. 중앙화된 타입 모듈 사용 패턴과 일관됩니다.
143-143: LGTM! UI 라벨 일관성 유지이모지를 제거하여 다른 에디터 컴포넌트들과 UI 스타일을 통일했습니다.
frontend/src/pages/AdminPage/tabs/ClubIntroEditTab/components/FAQEditor/FAQEditor.tsx (4)
1-9: LGTM!import 경로 절대화 및 인터페이스 정의가 깔끔합니다.
26-34: LGTM!새 FAQ 추가 로직이 올바르게 구현되어 있습니다. ID 생성 후 포커스 트리거까지 잘 처리되었습니다.
54-65: LGTM!마지막 FAQ 입력 필드에 포커스를 맞추는 로직이 올바르게 구현되었습니다.
lastFAQ.id존재 여부를 확인하는 방어 코드도 적절합니다.
79-80: 타입 안정성 확보를 위한 좋은 접근Type predicate를 사용한 필터링으로 TypeScript 타입 안정성을 보장하는 좋은 패턴입니다. PR 목표인 FAQ 수정/삭제 버그 해결에 핵심적인 역할을 합니다.
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (1)
frontend/src/pages/AdminPage/tabs/ApplicationEditTab/ApplicationEditTab.tsx (1)
143-143: 사용자 메시지 간 네이밍 일관성 검토 필요유효성 검사 오류 메시지(Line 143)는 영문 브랜드명("Google Forms, Naver Form 또는 Everytime")을 사용하고, 힌트 텍스트(Line 369)는 한글("구글폼, 네이버폼, 에브리타임")을 사용합니다. 사용자 경험 일관성을 위해 둘 중 하나로 통일하는 것을 권장합니다.
♻️ 한글로 통일하는 경우
if (!isValidUrl) { alert( - '외부 지원서 링크는 Google Forms, Naver Form 또는 Everytime 링크여야 합니다.', + '외부 지원서 링크는 구글폼, 네이버폼 또는 에브리타임 링크여야 합니다.', ); return; }Also applies to: 369-369
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Disabled knowledge base sources:
- Jira integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (2)
frontend/src/pages/AdminPage/tabs/ApplicationEditTab/ApplicationEditTab.tsxfrontend/src/pages/ClubDetailPage/components/ClubIntroContent/ClubIntroContent.styles.ts
🧰 Additional context used
📓 Path-based instructions (3)
frontend/**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (frontend/.cursorrules)
frontend/**/*.{ts,tsx,js,jsx}: Replace magic numbers with named constants for clarity
Replace complex/nested ternaries withif/elseor IIFEs for readability
Assign complex boolean conditions to named variables for explicit meaning
Avoid hidden side effects; functions should only perform actions implied by their signature (Single Responsibility Principle)
Use unique and descriptive names for custom wrappers/functions to avoid ambiguity
Define constants near related logic or ensure names link them clearly to avoid silent failures
Break down broad state management into smaller, focused hooks/contexts to reduce coupling
Files:
frontend/src/pages/ClubDetailPage/components/ClubIntroContent/ClubIntroContent.styles.tsfrontend/src/pages/AdminPage/tabs/ApplicationEditTab/ApplicationEditTab.tsx
frontend/**/*.{ts,tsx}
📄 CodeRabbit inference engine (frontend/.cursorrules)
Use consistent return types for similar functions/hooks
Files:
frontend/src/pages/ClubDetailPage/components/ClubIntroContent/ClubIntroContent.styles.tsfrontend/src/pages/AdminPage/tabs/ApplicationEditTab/ApplicationEditTab.tsx
frontend/**/*.{tsx,jsx}
📄 CodeRabbit inference engine (frontend/.cursorrules)
frontend/**/*.{tsx,jsx}: Abstract complex logic/interactions into dedicated components/HOCs
Separate significantly different conditional UI/logic into distinct components
Colocate simple, localized logic or use inline definitions to reduce context switching
Choose field-level or form-level cohesion based on form requirements when using form libraries like react-hook-form
Use Component Composition instead of Props Drilling to reduce coupling
Files:
frontend/src/pages/AdminPage/tabs/ApplicationEditTab/ApplicationEditTab.tsx
🧠 Learnings (3)
📓 Common learnings
Learnt from: seongwon030
Repo: Moadong/moadong PR: 195
File: frontend/src/pages/AdminPage/AdminPage.tsx:7-7
Timestamp: 2025-03-19T05:18:07.818Z
Learning: AdminPage.tsx에서 현재 하드코딩된 클럽 ID('67d2e3b9b15c136c6acbf20b')는 로그인 기능 구현 후 동적으로 가져오는 방식으로 수정될 예정입니다.
📚 Learning: 2025-11-25T14:08:23.253Z
Learnt from: CR
Repo: Moadong/moadong PR: 0
File: frontend/.cursorrules:0-0
Timestamp: 2025-11-25T14:08:23.253Z
Learning: Applies to frontend/**/*.{ts,tsx,js,jsx} : Replace magic numbers with named constants for clarity
Applied to files:
frontend/src/pages/AdminPage/tabs/ApplicationEditTab/ApplicationEditTab.tsx
📚 Learning: 2025-11-25T14:08:23.253Z
Learnt from: CR
Repo: Moadong/moadong PR: 0
File: frontend/.cursorrules:0-0
Timestamp: 2025-11-25T14:08:23.253Z
Learning: Applies to frontend/**/*.{ts,tsx,js,jsx} : Define constants near related logic or ensure names link them clearly to avoid silent failures
Applied to files:
frontend/src/pages/AdminPage/tabs/ApplicationEditTab/ApplicationEditTab.tsx
🔇 Additional comments (2)
frontend/src/pages/ClubDetailPage/components/ClubIntroContent/ClubIntroContent.styles.ts (1)
206-228: LGTM! FAQ 답변 줄바꿈 보존을 위한 적절한 스타일 추가입니다.
white-space: pre-line속성 추가는 동일 파일 내Text컴포넌트(58번 라인)와 일관된 패턴을 따르고 있으며, FAQ 답변에서 멀티라인 콘텐츠를 올바르게 표시할 수 있도록 합니다.frontend/src/pages/AdminPage/tabs/ApplicationEditTab/ApplicationEditTab.tsx (1)
23-29: 상수 모듈 스코프로 추출 잘 되었습니다.허용된 URL 목록을 모듈 스코프 상수로 정의하여 코드 가독성과 유지보수성이 향상되었습니다. 코딩 가이드라인에 따라 상수를 관련 로직 근처에 정의하는 패턴을 잘 따르고 있습니다.
https://everytime.kr도메인도 에브리타임 외부 공유 링크의 올바른 형식입니다.
oesnuj
left a comment
There was a problem hiding this comment.
FAQ 기능을 급하게 구현했던 코드라 다시 읽어보니 개선할 여지가 꽤 있네요
나중에 시간 날 때 좀 더 깔끔하게 리팩토링해보겠습니다
빠른 버그 픽스 수고하셨습니다~
#️⃣연관된 이슈
📝작업 내용
문제상황
해결
1. 타입 정의 개선
id?: string필드 추가2. FAQ Editor 컴포넌트 개선
3. AwardEditor 컴포넌트 정리
4. 디렉토리명 변경
중점적으로 리뷰받고 싶은 부분(선택)
논의하고 싶은 부분(선택)
🫡 참고사항
Summary by CodeRabbit
New Features
UI 개선
Refactor
✏️ Tip: You can customize this high-level summary in your review settings.