[FE] 20260303 #265 기능개선게시물 게시물 페이지 디테일 개선#285
Hidden character warning
Conversation
Walkthrough게시판 관련 UI/라우팅을 재구성하고, 하위 게시판 생성/선택, 드래그앤드롭 파일 업로드 및 키보드 접근성, 게시판 간 이동 기능과 관련 유틸/API를 추가/수정했습니다. Changes
Sequence Diagram(s)sequenceDiagram
participant User as "사용자"
participant UI as "프론트엔드 UI\n(Modal / Sidebar / Board)"
participant Router as "라우터\n(navigation)"
participant API as "API 클라이언트\n(boardApi)"
participant Server as "서버"
rect rgba(200,200,255,0.5)
User->>UI: 게시글 작성 모달 열기\n(게시판 선택, 파일 드래그)
UI->>UI: 파일 드래그/키보드 처리
UI->>API: 업로드 요청 (선택된 boardId, 파일들)
API->>Server: POST /api/... (파일 + 메타)
Server-->>API: 업로드 응답 (boardId, postId)
API-->>UI: 저장 결과 반환
UI->>Router: 게시판/게시글로 이동 또는 목록 갱신
Router-->>User: 업데이트된 화면 표시
end
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches
🧪 Generate unit tests (beta)
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 |
There was a problem hiding this comment.
Pull request overview
게시판/게시글 상세 화면 UX를 개선하고(게시판 이동, 첨부파일 다운로드/드래그앤드롭), 사이드바의 게시판 목록을 하드코딩 대신 API 기반으로 동적으로 구성하며, 게시판/하위게시판/게시글 작성 흐름을 보완하는 FE 변경입니다.
Changes:
- 게시판 이름 ↔ 라우트 세그먼트 변환 유틸(
boardRoute) 도입 및 Sidebar/Board/PostItem에서 공통 사용 - Board 페이지에서 하위 게시판 탭/검색/작성(세션 선택) 로직을 정리하고 권한 기반 하위게시판 생성 노출 추가
- PostDetail에서 게시판 이동 링크 및 첨부파일 다운로드/편집 UI(드래그앤드롭 포함) 개선
Reviewed changes
Copilot reviewed 18 out of 18 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| frontend/src/utils/boardRoute.js | 게시판명→URL 세그먼트/경로 변환 로직을 중앙화 |
| frontend/src/utils/boardApi.js | 하위 게시판 생성 엔드포인트를 /api/admin/board로 정리하고 호환 함수 추가 |
| frontend/src/pages/Board.jsx | 게시판/하위게시판 로딩, 다중 boardId 조회/검색, 글작성 세션 선택 및 권한 처리 |
| frontend/src/components/Sidebar.jsx | 게시판 목록을 API 기반으로 구성하고 메뉴 UI를 토글 리스트 형태로 변경 |
| frontend/src/components/Board/PostItem.jsx | 게시글 카드에서 작성자/시간/카운트 표시 및 상세 이동 시 origin 정보 전달 |
| frontend/src/pages/PostDetail.jsx | 게시판 이동 및 첨부파일 다운로드 URL 생성 방식 변경 |
| frontend/src/components/Board/PostDetail/* | 상세 보기/수정/첨부파일 리스트의 UI/인터랙션 개선(클릭 다운로드 등) |
| frontend/src/components/Board/Modal.jsx | 글 작성 모달에 세션 선택 + 드래그앤드롭 업로드 UX 추가 및 저장중 상태 반영 |
| *.module.css / frontend/src/index.css | 신규 UI에 맞춘 스타일 추가/조정 |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
frontend/src/components/Board/PostDetail/FileAttachmentList.jsx
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Actionable comments posted: 8
🧹 Nitpick comments (6)
frontend/src/components/Board/Modal.module.css (1)
275-289: 파일 삭제 버튼에focus-visible상태도 추가해 주세요.새로 추가된 인터랙션인데 hover만 있고 키보드 포커스 표시가 없습니다. 파일 제거 버튼은 반복 렌더링되는 컨트롤이라 포커스 링이 없으면 탐색성이 꽤 떨어집니다.
접근성 보완 예시
.fileRemoveButton:hover { color: rgba(231, 76, 60, 1); } + +.fileRemoveButton:focus-visible { + outline: 2px solid rgba(29, 128, 244, 1); + outline-offset: 2px; + border-radius: 4px; +}🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@frontend/src/components/Board/Modal.module.css` around lines 275 - 289, Add keyboard focus styling for the file removal control by updating the .fileRemoveButton rule set to include a :focus-visible state (in Modal.module.css) so keyboard users see a visible focus ring; specifically add a .fileRemoveButton:focus-visible selector that applies a clear focus indicator (e.g., outline or box-shadow with sufficient contrast and non-zero offset) and ensure it does not conflict with the existing :hover styling or remove default focus unintentionally for the .fileRemoveButton element.frontend/src/pages/Board.jsx (1)
114-126: 역할 확인 useEffect에서 에러 무시
Sidebar.jsx와 동일하게 catch 블록에서 에러를 무시합니다. 일관성은 유지되지만, 최소한의 로깅을 추가하면 디버깅에 도움이 됩니다.💡 에러 로깅 추가 제안
} catch (error) { + console.warn('역할 확인 실패:', error); setCanCreateSubBoard(false); }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@frontend/src/pages/Board.jsx` around lines 114 - 126, The catch block in the useEffect's fetchRole swallows errors silently; update the fetchRole async function to log the caught error before setting setCanCreateSubBoard(false) so failures from api.get('/api/user/details') are visible; reference the fetchRole function, the catch block, setCanCreateSubBoard, SUB_BOARD_ADMIN_ROLES and the api.get('/api/user/details') call and ensure the log provides the error object/message (use existing logger or console.error if none).frontend/src/components/Board/Modal.jsx (1)
29-57: 드래그 이벤트 핸들러 중복 호출 가능성
contentContainer와 내부textarea에 동일한 드래그 이벤트 핸들러가 연결되어 있습니다 (Lines 137-140, 153-156). 이벤트 버블링으로 인해textarea에서 발생한 이벤트가contentContainer로 전파되면서 핸들러가 두 번 호출될 수 있습니다.
e.stopPropagation()이 각 핸들러에 있어 중복 호출은 방지되지만, textarea의 드래그 핸들러는 불필요할 수 있습니다. 이벤트 버블링을 활용하여 컨테이너에서만 처리하는 것이 더 깔끔합니다.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@frontend/src/components/Board/Modal.jsx` around lines 29 - 57, The container and the inner textarea both register the same drag handlers (handleDragEnter, handleDragOver, handleDragLeave, handleDrop), causing duplicate handling via bubbling; remove the drag event props from the textarea and keep them only on the contentContainer so all drag events are handled at the container level. Ensure the container's handleDrop still builds droppedFiles and calls onFileChange({ target: { files: droppedFiles } }) and that clearDragState is used in handleDragLeave/handleDrop so visual state is preserved; no other handler changes are needed.frontend/src/components/Board/PostDetail/PostEditForm.jsx (1)
25-54: Modal.jsx와 드래그 로직 중복
handleDragEnter,handleDragOver,handleDragLeave,handleDrop로직이Modal.jsx와 거의 동일합니다. 커스텀 훅 또는 공통 컴포넌트로 추출하면 유지보수성이 향상됩니다.♻️ 커스텀 훅 추출 예시
// hooks/useDragAndDrop.js import { useState } from 'react'; export const useDragAndDrop = (onFileDrop) => { const [isDragOver, setIsDragOver] = useState(false); const handlers = { onDragEnter: (e) => { e.preventDefault(); e.stopPropagation(); setIsDragOver(true); }, onDragOver: (e) => { e.preventDefault(); e.stopPropagation(); setIsDragOver(true); }, onDragLeave: (e) => { e.preventDefault(); e.stopPropagation(); if (!e.currentTarget.contains(e.relatedTarget)) { setIsDragOver(false); } }, onDrop: (e) => { e.preventDefault(); e.stopPropagation(); setIsDragOver(false); const files = Array.from(e.dataTransfer.files || []); if (files.length > 0) onFileDrop(files); }, }; return { isDragOver, handlers }; };Also applies to: 107-116
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@frontend/src/components/Board/PostDetail/PostEditForm.jsx` around lines 25 - 54, Extract the duplicated drag-and-drop logic into a reusable hook (e.g., useDragAndDrop) and replace the local handlers in PostEditForm.jsx (handleDragEnter, handleDragOver, handleDragLeave, handleDrop) and the identical handlers in Modal.jsx with the hook's returned handlers and isDragOver state; the hook should accept a callback (onFileDrop) that receives an array of File objects and internally implement the same prevention, setIsDragOver behavior, relatedTarget check, and conversion of e.dataTransfer.files to an array before calling onFileDrop so you can call onAddNewFile({ target: { files: filesArray } }) or adapt callers to accept the files array.frontend/src/components/Sidebar.jsx (1)
65-82: 관리자 권한 확인 시 에러 무시
catch블록에서 에러를 무시하고canSeeAdminMenu를 false로 설정합니다. 네트워크 오류와 권한 없음을 구분하지 않아, 일시적 네트워크 문제로 관리자 메뉴가 숨겨질 수 있습니다.현재 동작이 의도된 것이라면 괜찮지만, 디버깅을 위해 최소한의 로깅을 추가하는 것을 권장합니다.
💡 에러 로깅 추가 제안
} catch (error) { + console.warn('관리자 권한 확인 실패:', error); setCanSeeAdminMenu(false); }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@frontend/src/components/Sidebar.jsx` around lines 65 - 82, checkAdminRole's catch block currently swallows errors and forces setCanSeeAdminMenu(false); update the catch in Sidebar.jsx (inside the checkAdminRole async function that calls api.get('/api/user/details')) to log the caught error (include the error object/message and context like "Failed to fetch user details for admin check") before setting setCanSeeAdminMenu(false); use the app's logging utility if available or console.error, and include references to ADMIN_VISIBLE_ROLES and setCanSeeAdminMenu so the log helps debug network vs permission issues.frontend/src/components/Sidebar.module.css (1)
168-188: 키보드 포커스 스타일도 같이 정의해 주세요.새로 추가된 인터랙티브 요소들이
:hover중심이라, 키보드 탐색 시 포커스가 배경에 묻혀 보일 수 있습니다.:focus-visible을 명시해 두면 접근성이 더 안정적입니다.🎯 예시
+.menuTitleToggle:focus-visible, +.boardMenuTrigger:focus-visible, +.boardMenuItem:focus-visible { + outline: 2px solid `#4d8dff`; + outline-offset: 2px; +}Also applies to: 213-225, 263-279
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@frontend/src/components/Sidebar.module.css` around lines 168 - 188, Add an accessible keyboard focus style for the interactive class .menuTitleToggle (and the other similar toggles mentioned) by defining a :focus-visible rule that makes the element's focus state visually distinct from the background (e.g., visible outline or box-shadow and preserved background contrast), so keyboard users can clearly see focus when tabbing; update the CSS by adding a .menuTitleToggle:focus-visible selector (and the corresponding selectors for the other toggle classes at the other ranges) that sets a clear outline/box-shadow, ensures outline-offset or border-radius matches the element, and does not rely solely on :hover styles.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@frontend/src/components/Board/BoardActions.jsx`:
- Line 9: The label "검색결과" is shown unconditionally because the component uses
sortedPosts.length (resultCount) regardless of search state; update BoardActions
(styles.resultCount / resultCount) to branch on the actual search flag or query
prop (e.g., isSearching or searchQuery) and render "{resultCount}건의 검색결과" only
when a search is active, otherwise render a neutral label like "{resultCount}건"
(or "전체 {resultCount}건") so the text matches the current state.
In `@frontend/src/components/Board/PostDetail/FileAttachmentList.jsx`:
- Around line 43-48: The attachment container element (attachmentItem div) and
the inner img both call handleDownload(file), which can cause duplicate
downloads via event bubbling; remove the onClick from the img (leave the
container's onClick) or, if keeping the img handler, call e.stopPropagation()
inside the img click handler to prevent propagation. Locate the img element
rendering FolderIcon in FileAttachmentList.jsx and update its onClick
accordingly so only a single handleDownload(file) invocation occurs (references:
attachmentItem div, img, handleDownload, isEditMode).
In `@frontend/src/components/Board/PostDetail/PostView.jsx`:
- Around line 28-36: The button renders when boardName is truthy but calls
onMoveToBoard without guarding against it being undefined; update the click
handler used in the PostView component so it safely invokes onMoveToBoard (e.g.,
use optional chaining or a safe noop) in the onClick for the element with
className styles.boardLink so clicking cannot throw if onMoveToBoard is not
provided.
In `@frontend/src/components/Sidebar.module.css`:
- Around line 276-284: The active menu item's hover is being overridden by
.boardMenuItem:hover so the active highlight disappears; add a more specific CSS
rule to preserve the active styles on hover (e.g., a .boardMenuItemActive:hover
or a combined selector like .boardMenuItem.boardMenuItemActive:hover) that sets
color: `#ffffff` and background: transparent to ensure the active state remains
visually identical when hovered.
In `@frontend/src/index.css`:
- Line 13: Remove the global "!important" on the background-color declarations
in index.css (the body background entries at the two occurrences) so they no
longer override page-specific rules; replace them with a plain background-color
or move the forced rule to a narrower selector such as a layout container (e.g.,
.app-root or .layout-container) if you truly need to enforce a default, and
ensure page-specific selector body { background-color: `#f4f5f8`; } in
QuantTradingDashboard can take effect.
In `@frontend/src/pages/PostDetail.jsx`:
- Around line 12-15: FILE_DOWNLOAD_BASE_URL falls back to an empty string when
VITE_API_URL is unset, producing relative download paths; update the
PostDetail.jsx initialization of FILE_DOWNLOAD_BASE_URL to explicitly warn in
development when import.meta.env.VITE_API_URL is missing (e.g., use
import.meta.env.DEV or process.env.NODE_ENV check) and/or add a clear inline
comment documenting the intended Vite-proxy behavior; reference
FILE_DOWNLOAD_BASE_URL and VITE_API_URL so the change targets that constant and
ensures developers see a console.warn in dev rather than silently using a
relative path.
In `@frontend/src/utils/boardApi.js`:
- Around line 40-53: createSubBoard currently returns response.data but the
backend returns void, so Board.jsx reading created?.boardId always misses;
update createSubBoard to ensure it returns the new board's id: after the POST in
createSubBoard, if response.data.boardId is falsy, call the boards listing
endpoint (e.g., api.get('/api/admin/boards')), find the created board by
matching normalizedBoardName and parentBoardId, and return an object that
includes boardId (or throw if not found); keep the original POST path if the
backend starts returning { boardId } so Board.jsx can use created?.boardId as
expected.
In `@frontend/src/utils/boardRoute.js`:
- Around line 36-45: The helper currently returns arbitrary strings
(withoutSuffix/normalized) when BOARD_SEGMENT_MAP has no match, producing
invalid route segments; change the function in frontend/src/utils/boardRoute.js
so it only returns a valid mapped segment (BOARD_SEGMENT_MAP[withoutSuffix]) and
otherwise returns null (or undefined) to indicate "no routable value" instead of
returning withoutSuffix/normalized; keep references to BOARD_SEGMENT_MAP,
withoutSuffix and normalized so callers (e.g. Board.jsx's boardIdMap lookup) can
handle the null case and avoid creating unreachable routes.
---
Nitpick comments:
In `@frontend/src/components/Board/Modal.jsx`:
- Around line 29-57: The container and the inner textarea both register the same
drag handlers (handleDragEnter, handleDragOver, handleDragLeave, handleDrop),
causing duplicate handling via bubbling; remove the drag event props from the
textarea and keep them only on the contentContainer so all drag events are
handled at the container level. Ensure the container's handleDrop still builds
droppedFiles and calls onFileChange({ target: { files: droppedFiles } }) and
that clearDragState is used in handleDragLeave/handleDrop so visual state is
preserved; no other handler changes are needed.
In `@frontend/src/components/Board/Modal.module.css`:
- Around line 275-289: Add keyboard focus styling for the file removal control
by updating the .fileRemoveButton rule set to include a :focus-visible state (in
Modal.module.css) so keyboard users see a visible focus ring; specifically add a
.fileRemoveButton:focus-visible selector that applies a clear focus indicator
(e.g., outline or box-shadow with sufficient contrast and non-zero offset) and
ensure it does not conflict with the existing :hover styling or remove default
focus unintentionally for the .fileRemoveButton element.
In `@frontend/src/components/Board/PostDetail/PostEditForm.jsx`:
- Around line 25-54: Extract the duplicated drag-and-drop logic into a reusable
hook (e.g., useDragAndDrop) and replace the local handlers in PostEditForm.jsx
(handleDragEnter, handleDragOver, handleDragLeave, handleDrop) and the identical
handlers in Modal.jsx with the hook's returned handlers and isDragOver state;
the hook should accept a callback (onFileDrop) that receives an array of File
objects and internally implement the same prevention, setIsDragOver behavior,
relatedTarget check, and conversion of e.dataTransfer.files to an array before
calling onFileDrop so you can call onAddNewFile({ target: { files: filesArray }
}) or adapt callers to accept the files array.
In `@frontend/src/components/Sidebar.jsx`:
- Around line 65-82: checkAdminRole's catch block currently swallows errors and
forces setCanSeeAdminMenu(false); update the catch in Sidebar.jsx (inside the
checkAdminRole async function that calls api.get('/api/user/details')) to log
the caught error (include the error object/message and context like "Failed to
fetch user details for admin check") before setting setCanSeeAdminMenu(false);
use the app's logging utility if available or console.error, and include
references to ADMIN_VISIBLE_ROLES and setCanSeeAdminMenu so the log helps debug
network vs permission issues.
In `@frontend/src/components/Sidebar.module.css`:
- Around line 168-188: Add an accessible keyboard focus style for the
interactive class .menuTitleToggle (and the other similar toggles mentioned) by
defining a :focus-visible rule that makes the element's focus state visually
distinct from the background (e.g., visible outline or box-shadow and preserved
background contrast), so keyboard users can clearly see focus when tabbing;
update the CSS by adding a .menuTitleToggle:focus-visible selector (and the
corresponding selectors for the other toggle classes at the other ranges) that
sets a clear outline/box-shadow, ensures outline-offset or border-radius matches
the element, and does not rely solely on :hover styles.
In `@frontend/src/pages/Board.jsx`:
- Around line 114-126: The catch block in the useEffect's fetchRole swallows
errors silently; update the fetchRole async function to log the caught error
before setting setCanCreateSubBoard(false) so failures from
api.get('/api/user/details') are visible; reference the fetchRole function, the
catch block, setCanCreateSubBoard, SUB_BOARD_ADMIN_ROLES and the
api.get('/api/user/details') call and ensure the log provides the error
object/message (use existing logger or console.error if none).
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 062daf3b-7ae7-497d-a9b4-82730e40ecec
📒 Files selected for processing (18)
frontend/src/components/Board/BoardActions.jsxfrontend/src/components/Board/BoardActions.module.cssfrontend/src/components/Board/CategoryTabs.jsxfrontend/src/components/Board/CategoryTabs.module.cssfrontend/src/components/Board/Modal.jsxfrontend/src/components/Board/Modal.module.cssfrontend/src/components/Board/PostDetail/FileAttachmentList.jsxfrontend/src/components/Board/PostDetail/PostEditForm.jsxfrontend/src/components/Board/PostDetail/PostView.jsxfrontend/src/components/Board/PostItem.jsxfrontend/src/components/Sidebar.jsxfrontend/src/components/Sidebar.module.cssfrontend/src/index.cssfrontend/src/pages/Board.jsxfrontend/src/pages/PostDetail.jsxfrontend/src/pages/PostDetail.module.cssfrontend/src/utils/boardApi.jsfrontend/src/utils/boardRoute.js
There was a problem hiding this comment.
Actionable comments posted: 3
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/PostDetail.jsx (1)
223-230:⚠️ Potential issue | 🟠 Major기존 첨부파일 삭제가 저장 payload에 반영되지 않습니다.
편집 UI에서는
frontend/src/components/Board/PostDetail/PostEditForm.jsx에서 기존 파일을 지울 수 있게 했는데, 여기서 만드는updateData에는newFiles만 들어갑니다. 그래서 저장 후refreshPostAndComments()가 돌면 방금 지운 기존 첨부파일이 다시 나타납니다. 유지할 첨부파일 목록이나deletedAttachmentIds같은 계약을 같이 보내도록 맞춰야 합니다.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@frontend/src/pages/PostDetail.jsx` around lines 223 - 230, The save payload only includes newFiles, so deleted existing attachments are reappearing; modify the updateData sent from PostDetail.jsx to include the attachment-tracking field your edit form uses (e.g., deletedAttachmentIds or retainedAttachmentIds) from PostEditForm.jsx state/props and pass that through to boardApi.updatePost along with title/content/files so the backend can remove the deleted attachments before refreshPostAndComments() runs.
🧹 Nitpick comments (1)
frontend/src/pages/PostDetail.jsx (1)
262-281: 게시판 복귀 경로 계산을 한 곳으로 모으는 편이 안전합니다.여기서는
'root'를/board로 정규화하지만, Line 255의 삭제 후 이동은 아직 rawteam을 그대로 씁니다. 규칙이 두 군데로 갈라져 있어서 전체 게시판 URL 정책이 바뀌면 한쪽만 쉽게 어긋납니다.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@frontend/src/pages/PostDetail.jsx` around lines 262 - 281, The code in handleMoveToBoard duplicates team/root normalization, risking divergence; compute a single normalizedTeamSegment (using location.state?.originTeam || team, then pass through toBoardRouteSegment or normalize 'root' to undefined) and use that single variable for the early navigate('/board') case and for the final navigate call (with encodeURIComponent when non-root). Update references: handleMoveToBoard, location.state?.originTeam, team, toBoardRouteSegment, targetBoardId, and navigate so all routing logic relies on normalizedTeamSegment rather than branching with raw team or separate 'root' checks.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@frontend/src/components/Board/PostDetail/PostEditForm.jsx`:
- Around line 22-55: The form remains interactive while a save is in progress;
add a saving guard to prevent user actions being applied during save. Update
PostEditForm to accept an isSaving prop (or derive from parent) and at the top
of interactive handlers—handleFileButtonClick, handleDragEnter, handleDragOver,
handleDragLeave, handleDrop and any file-delete handler that uses
onAddNewFile—early-return when isSaving is true; additionally bind isSaving to
disable the file input (fileInputRef), disable the add-file button and set
title/body inputs to readOnly/disabled so no edits or file ops can occur until
the save completes.
- Around line 86-91: The hidden file input (referenced by fileInputRef in
PostEditForm.jsx) isn't being cleared, so selecting the same file twice won't
fire onAddNewFile; update the component to reset the input's value (e.g., set
fileInputRef.current.value = '' or null) after handling the file in onAddNewFile
or immediately before programmatically opening the picker so the change event
will fire for the same filename.
In `@frontend/src/utils/boardRoute.js`:
- Around line 19-20: The board route mapping is missing the '트레이딩팀' alias so
toBoardRouteSegment('트레이딩팀') returns null and causes navigation in PostItem.jsx
and PostDetail.jsx to fallback to /board; update the mapping in boardRoute.js to
include the alias (map '트레이딩팀' to 'trading') so toBoardRouteSegment returns the
correct segment and existing navigation logic in PostItem.jsx and PostDetail.jsx
works as intended.
---
Outside diff comments:
In `@frontend/src/pages/PostDetail.jsx`:
- Around line 223-230: The save payload only includes newFiles, so deleted
existing attachments are reappearing; modify the updateData sent from
PostDetail.jsx to include the attachment-tracking field your edit form uses
(e.g., deletedAttachmentIds or retainedAttachmentIds) from PostEditForm.jsx
state/props and pass that through to boardApi.updatePost along with
title/content/files so the backend can remove the deleted attachments before
refreshPostAndComments() runs.
---
Nitpick comments:
In `@frontend/src/pages/PostDetail.jsx`:
- Around line 262-281: The code in handleMoveToBoard duplicates team/root
normalization, risking divergence; compute a single normalizedTeamSegment (using
location.state?.originTeam || team, then pass through toBoardRouteSegment or
normalize 'root' to undefined) and use that single variable for the early
navigate('/board') case and for the final navigate call (with encodeURIComponent
when non-root). Update references: handleMoveToBoard,
location.state?.originTeam, team, toBoardRouteSegment, targetBoardId, and
navigate so all routing logic relies on normalizedTeamSegment rather than
branching with raw team or separate 'root' checks.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 43bf6f34-6ede-468e-9770-3972e2ed9409
📒 Files selected for processing (7)
frontend/src/components/Board/PostDetail/FileAttachmentList.jsxfrontend/src/components/Board/PostDetail/PostEditForm.jsxfrontend/src/components/Board/PostDetail/PostView.jsxfrontend/src/components/Sidebar.module.cssfrontend/src/pages/PostDetail.jsxfrontend/src/utils/boardApi.jsfrontend/src/utils/boardRoute.js
There was a problem hiding this comment.
🧹 Nitpick comments (1)
frontend/src/components/Board/PostDetail/PostEditForm.jsx (1)
118-127: textarea에 드래그 핸들러 중복 설정에 대한 고려사항textarea와 부모 div 모두에 동일한 드래그 핸들러가 설정되어 있습니다.
stopPropagation()으로 이벤트 중복 처리는 방지되지만, textarea에서 부모 div로 드래그 이동 시handleDragLeave의relatedTarget체크로 인해 일시적인 시각적 깜빡임이 발생할 수 있습니다. 실제 사용 환경에서 문제가 확인되면 개선을 고려해주세요.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@frontend/src/components/Board/PostDetail/PostEditForm.jsx` around lines 118 - 127, The textarea and its parent div both attach the same drag handlers (handleDragEnter, handleDragOver, handleDragLeave, handleDrop), which can cause visual flicker when moving the drag between them; either remove the duplicate handlers from the textarea and only handle drag on the parent div (keeping onDrop on the textarea if you need file capture there), or update handleDragLeave to ignore transitions between the textarea and its parent by checking event.relatedTarget (or using contains on event.currentTarget) and returning early when the related element is the parent/child, ensuring stopPropagation is preserved; locate these handlers and the textarea element in PostEditForm.jsx to apply the change.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@frontend/src/components/Board/PostDetail/PostEditForm.jsx`:
- Around line 118-127: The textarea and its parent div both attach the same drag
handlers (handleDragEnter, handleDragOver, handleDragLeave, handleDrop), which
can cause visual flicker when moving the drag between them; either remove the
duplicate handlers from the textarea and only handle drag on the parent div
(keeping onDrop on the textarea if you need file capture there), or update
handleDragLeave to ignore transitions between the textarea and its parent by
checking event.relatedTarget (or using contains on event.currentTarget) and
returning early when the related element is the parent/child, ensuring
stopPropagation is preserved; locate these handlers and the textarea element in
PostEditForm.jsx to apply the change.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 15213a3c-1f30-4fc7-a315-227de5bca19b
📒 Files selected for processing (1)
frontend/src/components/Board/PostDetail/PostEditForm.jsx
사이드바 게시판 메뉴바 수정
게시판 api 연결
게시글 보기 및 댓글, 파일 저장 등
Summary by CodeRabbit
릴리스 노트
새로운 기능
개선사항