[Feat] WTH-398 : 게시판 반응형 적용#122
Hidden character warning
Conversation
📝 Walkthrough요약보드 네비게이션을 반응형으로 재구성하여 모바일/태블릿+ 레이아웃을 분기하고, 변경사항보드 네비게이션 반응형 아키텍처
모바일 쓰기 액션 및 헤더 분기
상수 및 포맷 정리
관련 PR
추천 라벨
추천 리뷰어
🎯 3 (Moderate) | ⏱️ ~25 minutes
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 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 |
PR 테스트 결과✅ Jest: 통과 🎉 모든 테스트를 통과했습니다! |
PR 검증 결과✅ TypeScript: 통과 🎉 모든 검증을 통과했습니다! |
|
구현한 기능 Preview: https://weeth-1kwyjo667-weethsite-4975s-projects.vercel.app |
There was a problem hiding this comment.
Actionable comments posted: 5
🧹 Nitpick comments (2)
src/components/layout/header/MobileNavSheet.tsx (1)
29-29: ⚡ Quick win
isPostingPage로직이 중복됩니다.이 로직이
Header.tsx(line 34)에도 동일하게 정의되어 있습니다. 공통 유틸리티 함수나 커스텀 훅으로 추출하는 것을 권장합니다.♻️ 제안: 공통 로직 추출
src/utils/route.ts파일을 생성하여 중복을 제거할 수 있습니다:// src/utils/route.ts export function isPostingPage(pathname: string): boolean { return pathname.includes('/write') || /\/board\/edit\/\d+$/.test(pathname); }그런 다음 두 파일에서 이 함수를 import하여 사용합니다.
🤖 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/components/layout/header/MobileNavSheet.tsx` at line 29, The isPostingPage logic is duplicated between MobileNavSheet.tsx and Header.tsx; extract it into a shared utility and import it from both places. Create a function named isPostingPage(pathname: string): boolean (for example in src/utils/route.ts) that returns pathname.includes('/write') || /\/board\/edit\/\d+$/.test(pathname), then replace the inline expressions in MobileNavSheet.tsx and Header.tsx with calls to isPostingPage(pathname). Ensure both files import the new function and remove the duplicated regex/include logic.src/components/layout/header/Header.tsx (1)
34-34: ⚡ Quick win
isPostingPage로직이 중복됩니다.이 로직이
MobileNavSheet.tsx(line 29)에도 동일하게 정의되어 있습니다. 공통 유틸리티 함수나 커스텀 훅으로 추출하는 것을 권장합니다.♻️ 제안: 공통 로직 추출
src/utils/route.ts또는src/hooks/useIsPostingPage.ts파일을 생성하여 중복을 제거할 수 있습니다:// src/utils/route.ts export function isPostingPage(pathname: string): boolean { return pathname.includes('/write') || /\/board\/edit\/\d+$/.test(pathname); }그런 다음 두 파일에서 이 함수를 import하여 사용합니다.
🤖 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/components/layout/header/Header.tsx` at line 34, The isPostingPage check (used in Header.tsx as the isPostingPage const and duplicated in MobileNavSheet.tsx) should be extracted to a single shared utility or hook to remove duplication; create a small exported function (e.g., isPostingPage(pathname: string)) or a hook (e.g., useIsPostingPage) that implements the logic pathname.includes('/write') || /\/board\/edit\/\d+$/.test(pathname), replace the local const in Header.tsx and the duplicate in MobileNavSheet.tsx with an import of that shared function/hook, and update imports accordingly.
🤖 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/app/`(private)/[clubId]/(main)/board/(with-nav)/BoardNavClient.tsx:
- Line 119: The component BoardNavClient.tsx contains a hardcoded Tailwind
shadow class "shadow-[0_5px_20px_rgba(17,33,49,0.2)]"; replace this with the
project's shadow design token class (e.g., the appropriate shadow token used
across the app) by updating the className on the BoardNavClient element or the
related cva variant in this file to use that token instead, and if no suitable
token exists, ask before adding a new design token so we stay compliant with the
Tailwind v4 + cva styling guideline.
In `@src/components/board/BoardNavSkeleton.tsx`:
- Line 10: The div in BoardNavSkeleton.tsx uses a hardcoded width class
"w-[304px]"; replace it with the appropriate design token or responsive utility
instead: look for an existing sidebar width token (e.g., a class like w-sidebar
or a token in your tailwind/design-tokens) and swap "w-[304px]" to that token;
if no token exists, use a responsive utility such as w-auto or w-fit where
suitable, and if a new design token is required, confirm with the
product/designer before adding it and then update the class accordingly in
BoardNavSkeleton.
In `@src/components/board/CategorySelector.tsx`:
- Line 56: Replace the hardcoded height class "h-[40px]" in the CategorySelector
component's container class string with an approved design-token utility (e.g.,
use Tailwind's h-10 or your project's height token) by updating the class list
in the JSX where the string contains 'bg-container-neutral flex h-[40px] w-full
items-center rounded-lg py-200 pr-200 pl-300'; if no existing token fits, ask
the product/design owner before adding a new token and then use that new token
class instead of a raw pixel value.
In `@src/components/layout/header/Header.tsx`:
- Line 92: The element in Header.tsx currently uses a raw utility class "p-2"
which violates spacing token rules; update the className on the header element
(the JSX element that contains className="text-icon-normal p-2") to use the
approved spacing token (p-100 through p-500) that matches the intended visual
spacing (e.g., p-100/p-200/etc.), and if any gaps are used elsewhere in the same
component replace raw gap classes with gap-100~400 accordingly to conform with
the design token guidelines.
In `@src/components/layout/header/PostingActions.tsx`:
- Line 33: The class string in PostingActions.tsx uses a raw spacing utility
`tablet:px-4` which violates the design token rule; locate the className on the
element inside the PostingActions component and replace `tablet:px-4` with the
appropriate design-token spacing class (e.g., use the token form from
p-100..p-500 or the horizontal padding token if your token naming is
px-100/px-200, etc.) so all spacing uses the defined tokens (also consider
gap-100..gap-400 where applicable); keep other classes like `tablet:typo-button1
tablet:rounded-md text-text-strong whitespace-nowrap` unchanged.
---
Nitpick comments:
In `@src/components/layout/header/Header.tsx`:
- Line 34: The isPostingPage check (used in Header.tsx as the isPostingPage
const and duplicated in MobileNavSheet.tsx) should be extracted to a single
shared utility or hook to remove duplication; create a small exported function
(e.g., isPostingPage(pathname: string)) or a hook (e.g., useIsPostingPage) that
implements the logic pathname.includes('/write') ||
/\/board\/edit\/\d+$/.test(pathname), replace the local const in Header.tsx and
the duplicate in MobileNavSheet.tsx with an import of that shared function/hook,
and update imports accordingly.
In `@src/components/layout/header/MobileNavSheet.tsx`:
- Line 29: The isPostingPage logic is duplicated between MobileNavSheet.tsx and
Header.tsx; extract it into a shared utility and import it from both places.
Create a function named isPostingPage(pathname: string): boolean (for example in
src/utils/route.ts) that returns pathname.includes('/write') ||
/\/board\/edit\/\d+$/.test(pathname), then replace the inline expressions in
MobileNavSheet.tsx and Header.tsx with calls to isPostingPage(pathname). Ensure
both files import the new function and remove the duplicated regex/include
logic.
🪄 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: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 7a7ec501-8209-4de6-bfc8-3a31bcc26471
📒 Files selected for processing (11)
src/app/(private)/[clubId]/(main)/board/(with-nav)/BoardNavClient.tsxsrc/app/(private)/[clubId]/(main)/board/(with-nav)/layout.tsxsrc/app/(private)/[clubId]/(main)/board/layout.tsxsrc/components/board/BoardNavSkeleton.tsxsrc/components/board/CategorySelector.tsxsrc/components/layout/header/Header.tsxsrc/components/layout/header/MobileNavSheet.tsxsrc/components/layout/header/MobileWriteButton.tsxsrc/components/layout/header/PostingActions.tsxsrc/constants/board/type.tssrc/hooks/attendance/useAttendanceSSE.ts
| {/* Mobile: CategorySelector 드롭다운 (tablet 이상에서 숨김) */} | ||
| <div className="tablet:hidden"> | ||
| <CategorySelector | ||
| className="shadow-[0_5px_20px_rgba(17,33,49,0.2)]" |
There was a problem hiding this comment.
🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win
하드코딩된 shadow 값을 디자인 토큰으로 교체하세요.
shadow-[0_5px_20px_rgba(17,33,49,0.2)]는 하드코딩된 값입니다. 코딩 가이드라인에 따라 디자인 토큰 클래스를 우선 사용해야 하며, 하드코딩된 값은 사용하지 않아야 합니다. 프로젝트의 shadow 디자인 토큰을 확인하여 적절한 토큰 클래스로 교체하거나, 필요한 경우 새로운 토큰 추가에 대해 사용자에게 문의하세요.
As per coding guidelines: "Use Tailwind CSS v4 with class-variance-authority (cva) for styling. Always use design token classes first; no hardcoded values. Ask user before adding new tokens"
🤖 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/app/`(private)/[clubId]/(main)/board/(with-nav)/BoardNavClient.tsx at
line 119, The component BoardNavClient.tsx contains a hardcoded Tailwind shadow
class "shadow-[0_5px_20px_rgba(17,33,49,0.2)]"; replace this with the project's
shadow design token class (e.g., the appropriate shadow token used across the
app) by updating the className on the BoardNavClient element or the related cva
variant in this file to use that token instead, and if no suitable token exists,
ask before adding a new design token so we stay compliant with the Tailwind v4 +
cva styling guideline.
| <Skeleton key={i} className="h-10 w-full rounded-md" /> | ||
| ))} | ||
| {/* Tablet+: 사이드바 형태의 스켈레톤 */} | ||
| <div className="bg-container-neutral tablet:flex hidden w-[304px] flex-col items-start rounded-lg"> |
There was a problem hiding this comment.
🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win
하드코딩된 너비 값을 디자인 토큰이나 반응형 단위로 교체하세요.
w-[304px]는 하드코딩된 픽셀 값입니다. 코딩 가이드라인에 따라 디자인 토큰 클래스를 사용해야 합니다. 사이드바 너비에 대한 디자인 토큰이 정의되어 있는지 확인하거나, 필요한 경우 w-fit, w-auto 등의 반응형 유틸리티 또는 새로운 토큰 추가에 대해 검토하세요.
As per coding guidelines: "Always use design token classes first; no hardcoded values. Ask user before adding new tokens"
🤖 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/components/board/BoardNavSkeleton.tsx` at line 10, The div in
BoardNavSkeleton.tsx uses a hardcoded width class "w-[304px]"; replace it with
the appropriate design token or responsive utility instead: look for an existing
sidebar width token (e.g., a class like w-sidebar or a token in your
tailwind/design-tokens) and swap "w-[304px]" to that token; if no token exists,
use a responsive utility such as w-auto or w-fit where suitable, and if a new
design token is required, confirm with the product/designer before adding it and
then update the class accordingly in BoardNavSkeleton.
| <DropdownMenuTrigger | ||
| className={cn( | ||
| 'bg-container-neutral flex h-[40px] items-center self-stretch rounded-lg py-200 pr-200 pl-300', | ||
| 'bg-container-neutral flex h-[40px] w-full items-center rounded-lg py-200 pr-200 pl-300', |
There was a problem hiding this comment.
🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win
하드코딩된 높이 값을 디자인 토큰으로 교체하세요.
h-[40px]는 하드코딩된 픽셀 값입니다. 코딩 가이드라인에 따라 디자인 토큰 클래스를 사용해야 합니다. 버튼이나 인터랙티브 요소의 높이에 대한 디자인 토큰을 확인하거나, 필요한 경우 h-10(Tailwind 기본 유틸리티) 또는 새로운 토큰 추가에 대해 사용자에게 문의하세요.
As per coding guidelines: "Always use design token classes first; no hardcoded values. Ask user before adding new tokens"
🤖 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/components/board/CategorySelector.tsx` at line 56, Replace the hardcoded
height class "h-[40px]" in the CategorySelector component's container class
string with an approved design-token utility (e.g., use Tailwind's h-10 or your
project's height token) by updating the class list in the JSX where the string
contains 'bg-container-neutral flex h-[40px] w-full items-center rounded-lg
py-200 pr-200 pl-300'; if no existing token fits, ask the product/design owner
before adding a new token and then use that new token class instead of a raw
pixel value.
| src={ExitToAppIcon} | ||
| alt="avatar" | ||
| size={40} | ||
| className="text-icon-normal p-2" |
There was a problem hiding this comment.
디자인 토큰 클래스를 사용해야 합니다.
p-2는 코딩 가이드라인에 명시된 p-100~500 범위에 속하지 않습니다. 정의된 spacing token 클래스를 사용해주세요.
🎨 제안: 토큰 클래스 사용
- className="text-icon-normal p-2"
+ className="text-icon-normal p-200"As per coding guidelines: Use spacing token classes: p-100~500, gap-100~400.
📝 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.
| className="text-icon-normal p-2" | |
| className="text-icon-normal p-200" |
🤖 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/components/layout/header/Header.tsx` at line 92, The element in
Header.tsx currently uses a raw utility class "p-2" which violates spacing token
rules; update the className on the header element (the JSX element that contains
className="text-icon-normal p-2") to use the approved spacing token (p-100
through p-500) that matches the intended visual spacing (e.g.,
p-100/p-200/etc.), and if any gaps are used elsewhere in the same component
replace raw gap classes with gap-100~400 accordingly to conform with the design
token guidelines.
| size="md" | ||
| className="typo-button1 text-text-strong px-4" | ||
| size="sm" | ||
| className="tablet:typo-button1 tablet:rounded-md tablet:px-4 text-text-strong whitespace-nowrap" |
There was a problem hiding this comment.
디자인 토큰 클래스를 사용해야 합니다.
tablet:px-4는 코딩 가이드라인에 명시된 p-100~500 범위에 속하지 않습니다. 정의된 spacing token 클래스를 사용해주세요.
🎨 제안: 토큰 클래스 사용
- className="tablet:typo-button1 tablet:rounded-md tablet:px-4 text-text-strong whitespace-nowrap"
+ className="tablet:typo-button1 tablet:rounded-md tablet:px-400 text-text-strong whitespace-nowrap"As per coding guidelines: Use spacing token classes: p-100~500, gap-100~400.
📝 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.
| className="tablet:typo-button1 tablet:rounded-md tablet:px-4 text-text-strong whitespace-nowrap" | |
| className="tablet:typo-button1 tablet:rounded-md tablet:px-400 text-text-strong whitespace-nowrap" |
🤖 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/components/layout/header/PostingActions.tsx` at line 33, The class string
in PostingActions.tsx uses a raw spacing utility `tablet:px-4` which violates
the design token rule; locate the className on the element inside the
PostingActions component and replace `tablet:px-4` with the appropriate
design-token spacing class (e.g., use the token form from p-100..p-500 or the
horizontal padding token if your token naming is px-100/px-200, etc.) so all
spacing uses the defined tokens (also consider gap-100..gap-400 where
applicable); keep other classes like `tablet:typo-button1 tablet:rounded-md
text-text-strong whitespace-nowrap` unchanged.
JIN921
left a comment
There was a problem hiding this comment.
반응형 야르 하네요... 부드럽고 좋다... 어드민도 모바일은 걍 LNB 없애고 하단 푸터나 헤더에 넣어 버릴까 고민이 되네요...
✅ PR 유형
어떤 변경 사항이 있었나요?
📌 관련 이슈번호
✅ Key Changes
게시판 레이아웃 반응형 전환
board/layout.tsx: 모바일 접근을 막던 MobileBlocker 제거 — 모바일에서도 게시판 접근 가능board/(with-nav)/layout.tsx: 레이아웃을 모바일 flex-col → 태블릿 이상 flex-row로 전환, 패딩도 반응형 적용게시판 내비게이션 반응형 분기
BoardNavClient.tsx: footer prop 추가CategorySelector드롭다운 (태블릿 이상 숨김)BoardNavSkeleton.tsx: 모바일(드롭다운 형태) / 태블릿+(사이드바 형태) 스켈레톤 분리헤더 반응형 개선
Header.tsx: 게시물 작성 페이지가 아닐 때 MobileWriteButton을 함께 노출하도록 조건 분기 리팩토링MobileWriteButton.tsx: 모바일 게시판 페이지에서 글쓰기 버튼 표시PostingActions.tsx: 모바일에서는 sm 크기 버튼 + 전송 아이콘 숨김, 태블릿 이상에서 기존 md 스타일 복원MobileNavSheet게시판 목록 표시게시판 타입 정렬 순서 수정
BOARD_TYPE_ORDER: ALL → NOTICE → GENERAL 순으로 변경 (기존: NOTICE → ALL → GENERAL)📸 스크린샷 or 실행영상
게시판
2026-05-27.172625.mp4
게시글 작성
🎸 기타 사항 or 추가 코멘트
반응형 적용하면서 보니까,, 게시판 목록 정렬이 공지사항부터 되어 잇길래... ㅠ.ㅜ
겸사겸사 같이 수정해두엇습니당
Summary by CodeRabbit
릴리스 노트
New Features
Refactor