[Feat] 블로그 후기 페이지 ui 제작 - #28
Conversation
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthrough블로그 후기 관리 페이지와 Changes블로그 후기 기능
Storybook 설정
커밋 스킬 문서
리뷰 페이지 문서 보정
Possibly related PRs
🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (2 warnings)
✅ Passed checks (3 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
CI 결과
|
There was a problem hiding this comment.
Actionable comments posted: 5
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@e2e/reviews.spec.ts`:
- Around line 13-22: Extend the `/blog-review` test around the existing test
`'블로그 후기 진입 시 블로그 후기 메뉴와 별도 페이지가 보인다'` to cover the state-change flow: verify
saving is disabled or blocked until required fields are valid, confirm a newly
saved review row appears, and delete the final row on the last page to assert
pagination is corrected. Include the relevant form validation, submit, visible
state transition, and query invalidation outcomes without changing the existing
initial-page assertions.
In `@src/components/blog-reviews/BlogReviewModal/BlogReviewModal.tsx`:
- Around line 86-93: Update the placeholder in the BlogReviewModal link
Inputfield to say “링크를 입력해주세요” instead of “링크를 업로드해주세요”, leaving the
onLinkChange handling unchanged.
In `@src/components/common/Inputfield/Inputfield.tsx`:
- Line 9: Update the hasValue calculation in Inputfield so numeric values such
as 0 are treated as non-empty. Check that props.value is not null or undefined,
then evaluate its string length while preserving empty-string behavior.
In `@src/pages/blog-reviews/BlogReviewsPage.tsx`:
- Around line 67-80: Update the save flow around setRows and setModalOpen so the
newly created row is immediately visible: prepend it to the rows list and reset
the current pagination page to page 1, using the existing pagination state
setter. Preserve the existing resetForm and modal-closing behavior.
- Around line 60-80: Update the form validation around handleSave and the
title/link controls so values containing only whitespace are invalid. Use
trim-based checks consistently for both the save-button enabled state and the
final validation in handleSave, while preserving the existing activity
validation and saving trimmed title/link values only when all required fields
are valid.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: e8433049-c3ef-456f-ab88-fe500d7bccdb
📒 Files selected for processing (11)
.claude/skills/commit-kr/SKILL.mde2e/reviews.spec.tssrc/components/blog-reviews/BlogReviewModal/BlogReviewModal.stories.tsxsrc/components/blog-reviews/BlogReviewModal/BlogReviewModal.test.tsxsrc/components/blog-reviews/BlogReviewModal/BlogReviewModal.tsxsrc/components/common/Inputfield/Inputfield.tsxsrc/components/common/SelectField/SelectField.tsxsrc/pages/blog-reviews/BlogReviewsPage.mock.tssrc/pages/blog-reviews/BlogReviewsPage.tsxsrc/routes.tssrc/routes/(main)/blogReview.tsx
| test('/blog-review 진입 시 블로그 후기 메뉴와 별도 페이지가 보인다', async ({ page }) => { | ||
| await page.goto('/blog-review') | ||
|
|
||
| await expect(page.getByRole('link', { name: '블로그 후기', exact: true })).toHaveAttribute( | ||
| 'aria-current', | ||
| 'page', | ||
| ) | ||
| await expect(page.getByRole('heading', { name: '블로그 후기 관리', exact: true })).toBeVisible() | ||
| await expect(page.getByText('프론트엔드 파트 활동 후기')).toBeVisible() | ||
| }) |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
블로그 후기의 상태 변경 흐름도 검증하세요.
현재 테스트는 초기 화면만 확인합니다. /blog-review에서 필수값 충족 전 저장 불가, 저장 후 새 행 표시, 마지막 페이지 삭제 후 페이지 보정까지 검증해야 Lines 60-80의 상태 로직 회귀를 잡을 수 있습니다.
As per coding guidelines, “form은 검증 동작과 submit 동작을 테스트합니다.” 및 “관리자 상태 변경은 화면상의 상태 전환과 query invalidation 동작을 테스트합니다.”
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@e2e/reviews.spec.ts` around lines 13 - 22, Extend the `/blog-review` test
around the existing test `'블로그 후기 진입 시 블로그 후기 메뉴와 별도 페이지가 보인다'` to cover the
state-change flow: verify saving is disabled or blocked until required fields
are valid, confirm a newly saved review row appears, and delete the final row on
the last page to assert pagination is corrected. Include the relevant form
validation, submit, visible state transition, and query invalidation outcomes
without changing the existing initial-page assertions.
Source: Coding guidelines
CI 결과
|
CI 결과
|
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
src/pages/blog-reviews/BlogReviewsPage.tsx (2)
27-33: 📐 Maintainability & Code Quality | 🟠 Major | 🏗️ Heavy lift등록 폼을 React Hook Form과 Zod로 통합하세요.
현재 필드 상태와 검증이 여러
useState,saveDisabled,handleSave에 분산되어 있습니다. Zod schema와handleSubmit을 사용해 공백 검증과 submit 규칙을 한 곳에서 관리하세요.As per coding guidelines, “폼에는 React Hook Form과 Zod를 함께 사용합니다.”
Also applies to: 60-67, 139-139
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/pages/blog-reviews/BlogReviewsPage.tsx` around lines 27 - 33, 등록 폼의 필드 상태와 검증을 개별 useState, saveDisabled, handleSave에서 제거하고 React Hook Form의 useForm과 Zod schema로 통합하세요. BlogReviewsPage의 activity, title, link, part 필드에 스키마 기반 공백 검증과 기본값을 정의한 뒤, handleSave는 handleSubmit을 통해서만 실행되도록 연결하고 검증 실패 시 저장되지 않게 하세요.Source: Coding guidelines
123-125: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win닫기 경로에서 폼 초기화를 함께 처리하세요.
onOpenChange={setModalOpen}로는 Escape/backdrop 닫기가handleCancel를 우회합니다. 닫을 때resetForm()도 호출해야 이전 제목·링크·활동 값이 남지 않습니다.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/pages/blog-reviews/BlogReviewsPage.tsx` around lines 123 - 125, Update the BlogReviewModal onOpenChange handling in BlogReviewsPage so every close path, including Escape and backdrop dismissal, also invokes resetForm(). Preserve the existing modal state update through setModalOpen while ensuring resetForm runs whenever the modal closes.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/pages/blog-reviews/BlogReviewsPage.tsx`:
- Around line 69-79: Connect thumbnail state to the BlogReviewsPage save flow:
add thumbnail data to the page’s row/state model, include it when creating the
new row in the setRows callback, and pass thumbnailUrl, onThumbnailChange, and
onThumbnailDelete to BlogReviewModal in the modal render block. Ensure reset and
save operations preserve, clear, and persist the thumbnail consistently with the
other form fields.
---
Outside diff comments:
In `@src/pages/blog-reviews/BlogReviewsPage.tsx`:
- Around line 27-33: 등록 폼의 필드 상태와 검증을 개별 useState, saveDisabled, handleSave에서
제거하고 React Hook Form의 useForm과 Zod schema로 통합하세요. BlogReviewsPage의 activity,
title, link, part 필드에 스키마 기반 공백 검증과 기본값을 정의한 뒤, handleSave는 handleSubmit을 통해서만
실행되도록 연결하고 검증 실패 시 저장되지 않게 하세요.
- Around line 123-125: Update the BlogReviewModal onOpenChange handling in
BlogReviewsPage so every close path, including Escape and backdrop dismissal,
also invokes resetForm(). Preserve the existing modal state update through
setModalOpen while ensuring resetForm runs whenever the modal closes.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: 51acd994-7f6a-4d63-bb37-c078157f1acd
📒 Files selected for processing (6)
e2e/reviews.spec.tssrc/components/blog-reviews/BlogReviewModal/BlogReviewModal.test.tsxsrc/components/blog-reviews/BlogReviewModal/BlogReviewModal.tsxsrc/components/common/Inputfield/Inputfield.test.tsxsrc/components/common/Inputfield/Inputfield.tsxsrc/pages/blog-reviews/BlogReviewsPage.tsx
CI 결과
|
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/pages/blog-reviews/BlogReviewsPage.tsx (1)
92-115: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win페이지 상태 전이를 직접 테스트하세요.
저장 성공 시 trimmed 값과 썸네일이 row에 보존되는지, 저장 후 1페이지로 이동하는지, 취소·닫기·삭제 시 썸네일 URL이 해제되는지에 대한 페이지 단위 테스트를 추가하거나 확인해야 합니다. 모달 렌더링 테스트만으로는 이 상태 전이를 보장할 수 없습니다.
As per coding guidelines: form은 검증 동작과 submit 동작을 테스트해야 합니다. As per path instructions: TypeScript/TSX 변경 시 테스트 필요성을 검토해야 합니다.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/pages/blog-reviews/BlogReviewsPage.tsx` around lines 92 - 115, BlogReviewsPage의 handleSave와 취소·닫기·삭제 핸들러에 대해 페이지 단위 테스트를 추가하거나 보강하세요. 유효한 폼 제출 시 trim된 title/link와 thumbnailUrl이 새 row에 보존되고 setPage(1)이 호출되는지 검증하며, 각 종료·삭제 경로에서는 썸네일 URL이 해제되는지 확인하세요. 유효성 검증 실패 시 저장되지 않는 submit 동작도 테스트하세요.Sources: Coding guidelines, Path instructions
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/pages/blog-reviews/BlogReviewsPage.tsx`:
- Around line 72-80: Update the thumbnail URL lifecycle around
handleThumbnailChange so the current blob URL is also revoked when
BlogReviewsPage unmounts. Track the active object URL and add component cleanup
that revokes any remaining URL, while preserving the existing replacement
cleanup behavior.
---
Outside diff comments:
In `@src/pages/blog-reviews/BlogReviewsPage.tsx`:
- Around line 92-115: BlogReviewsPage의 handleSave와 취소·닫기·삭제 핸들러에 대해 페이지 단위 테스트를
추가하거나 보강하세요. 유효한 폼 제출 시 trim된 title/link와 thumbnailUrl이 새 row에 보존되고 setPage(1)이
호출되는지 검증하며, 각 종료·삭제 경로에서는 썸네일 URL이 해제되는지 확인하세요. 유효성 검증 실패 시 저장되지 않는 submit 동작도
테스트하세요.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: 029e0a4e-6cfa-4c3c-bf32-8995ec3124ff
📒 Files selected for processing (2)
src/pages/blog-reviews/BlogReviewsPage.mock.tssrc/pages/blog-reviews/BlogReviewsPage.tsx
| function handleThumbnailChange(file: File) { | ||
| const nextThumbnailUrl = URL.createObjectURL(file) | ||
|
|
||
| setThumbnailUrl((currentThumbnailUrl) => { | ||
| if (currentThumbnailUrl) { | ||
| URL.revokeObjectURL(currentThumbnailUrl) | ||
| } | ||
| return nextThumbnailUrl | ||
| }) |
There was a problem hiding this comment.
🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
file="src/pages/blog-reviews/BlogReviewsPage.tsx"
echo "== outline =="
ast-grep outline "$file" --view expanded || true
echo
echo "== relevant ranges =="
nl -ba "$file" | sed -n '1,260p'Repository: kusitms-com/makers-admin-fe
Length of output: 509
🏁 Script executed:
#!/bin/bash
set -euo pipefail
file="src/pages/blog-reviews/BlogReviewsPage.tsx"
python3 - <<'PY'
from pathlib import Path
p = Path("src/pages/blog-reviews/BlogReviewsPage.tsx")
text = p.read_text()
for needle in [
"URL.createObjectURL",
"URL.revokeObjectURL",
"useEffect",
"return () =>",
"thumbnailUrl",
"savedRows",
]:
print(f"\n== {needle} ==")
for i, line in enumerate(text.splitlines(), 1):
if needle in line:
start = max(1, i-8)
end = min(len(text.splitlines()), i+12)
for j in range(start, end+1):
print(f"{j:4d}: {text.splitlines()[j-1]}")
break
else:
print("not found")
PYRepository: kusitms-com/makers-admin-fe
Length of output: 2740
페이지 언마운트 시 남은 blob: URL도 해제하세요. 저장 후 행에 남긴 썸네일 URL은 교체/삭제/리셋 경로에서만 정리되고, 라우트 이동으로 컴포넌트가 사라질 때는 남을 수 있습니다. 남은 URL을 추적해 unmount cleanup에서 revoke하는 처리가 필요합니다.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/pages/blog-reviews/BlogReviewsPage.tsx` around lines 72 - 80, Update the
thumbnail URL lifecycle around handleThumbnailChange so the current blob URL is
also revoked when BlogReviewsPage unmounts. Track the active object URL and add
component cleanup that revokes any remaining URL, while preserving the existing
replacement cleanup behavior.
CI 결과
|
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/pages/blog-reviews/BlogReviewsPage.tsx`:
- Line 136: Update the modal’s onOpenChange handling in BlogReviewsPage so that
when the open value becomes false, it calls resetForm() before or alongside
setModalOpen; preserve normal state updates when opening and closing through any
trigger, including Escape and backdrop clicks.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: 6e40714c-16c1-4bd2-ab30-94e449b82b05
📒 Files selected for processing (1)
src/pages/blog-reviews/BlogReviewsPage.tsx
|
|
||
| <BlogReviewModal | ||
| open={modalOpen} | ||
| onOpenChange={setModalOpen} |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
외부 닫기에서도 폼을 초기화하세요.
Escape나 배경 클릭으로 모달이 닫힐 때 resetForm()이 호출되지 않습니다. 다시 열면 이전 활동·제목·링크·썸네일이 남으므로, open === false일 때 폼을 초기화하는 wrapper를 전달해야 합니다.
수정 예시
+ function handleModalOpenChange(open: boolean) {
+ setModalOpen(open)
+ if (!open) {
+ resetForm()
+ }
+ }
+
<BlogReviewModal
open={modalOpen}
- onOpenChange={setModalOpen}
+ onOpenChange={handleModalOpenChange}📝 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.
| onOpenChange={setModalOpen} | |
| function handleModalOpenChange(open: boolean) { | |
| setModalOpen(open) | |
| if (!open) { | |
| resetForm() | |
| } | |
| } | |
| <BlogReviewModal | |
| open={modalOpen} | |
| onOpenChange={handleModalOpenChange} |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/pages/blog-reviews/BlogReviewsPage.tsx` at line 136, Update the modal’s
onOpenChange handling in BlogReviewsPage so that when the open value becomes
false, it calls resetForm() before or alongside setModalOpen; preserve normal
state updates when opening and closing through any trigger, including Escape and
backdrop clicks.
leemanjae02
left a comment
There was a problem hiding this comment.
블로그 리뷰 등록 모달에서 받은 링크가 목록 테이블에 전혀 표시되지 않고 있는데 제목을 link로 연결하면 좋을 것 같아요!
| placeholder="제목을 입력해주세요" | ||
| /> | ||
| </FormField> | ||
| <FormField label="링크"> |
There was a problem hiding this comment.
저번에 블로그 리뷰 get에 대해서 모달로 입력된 정보를 본다 이런 얘기를 나눴던 것 같은데 API reference의 BlogReviewResponse는 비어있고 link가 필수인데 request에는 link 필드가 없어서 이 부분 확인이 필요할 것 같아요!
leemanjae02
left a comment
There was a problem hiding this comment.
고생하셨습니다! 코멘트 남겨드렸으니 확인 부탁드려요 :)
CI 결과
|
CI 결과
|
#️⃣ 연관된 이슈
Close #27
🚧 Work in Progress
📌 주요 변경사항
/blog-review라우트 추가📝 작업 내용
pnpm exec vitest run src/components/common/SelectField/SelectField.test.tsx src/components/blog-reviews/BlogReviewModal/BlogReviewModal.test.tsx,pnpm build,pnpm exec playwright test e2e/reviews.spec.ts(6 passed)📸 스크린샷 (선택)
💬 리뷰 요구사항(선택)
Summary by CodeRabbit
/blog-review라우팅을 추가했습니다./blog-review관련 E2E와 Inputfield 단위 테스트를 추가했습니다.