[feature] 메인페이지 동아리/홍보 필터 컴포넌트를 제작한다#1129
Conversation
- styled(Button)으로 스타일 확장 시 className 전달이 필요하여 추가
동아리/홍보 탭 전환 UI 및 알림 dot 컴포넌트 추가 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Warning
|
| Cohort / File(s) | Summary |
|---|---|
Button 컴포넌트 확장 frontend/src/components/common/Button/Button.tsx |
ButtonProps에 className?: string 추가. Button이 className을 받아 StyledButton으로 전달하도록 변경. |
Filter 컴포넌트 (로직 · 스타일 · 스토리북) frontend/src/pages/MainPage/components/Filter/Filter.tsx, frontend/src/pages/MainPage/components/Filter/Filter.styles.ts, frontend/src/pages/MainPage/components/Filter/Filter.stories.tsx |
모바일 전용 필터 컴포넌트 신규 추가. useDevice, useLocation, useNavigate로 경로 기반 활성화 및 내비게이션 처리. 스타일(FilterListContainer, FilterButton, NotificationDot, FilterButtonWrapper) 및 Storybook 스토리 3개 추가. |
MainPage 및 Banner 스타일 조정 frontend/src/pages/MainPage/MainPage.tsx, frontend/src/pages/MainPage/components/Banner/Banner.styles.ts |
MainPage에 Filter 컴포넌트를 Header와 Banner 사이에 렌더링하도록 추가. BannerContainer의 모바일 margin-top을 56px에서 0px로 변경. |
Estimated code review effort
🎯 3 (Moderate) | ⏱️ ~20 minutes
Possibly related PRs
- [feature] 모집 상태 보기 기능을 제거하고 중앙동아리 태그를 이동한다 #759: MainPage의 필터/탭 UI를 조정하는 PR로, 본 PR의 Filter 추가와 동일 영역 변경 관련성이 높음.
- [feature] 메인페이지 새로운 카드 디자인을 적용한다 #773: 동일한
Banner.styles.ts파일의 모바일/반응형 스타일을 조정하는 PR이라 스타일 충돌 가능성이 있음. - [release] FE v1.1.8 #939: 모바일 감지 훅(
useDevice/ 유사 훅) 사용 변경 관련 PR로, 본 PR의 Filter가 해당 훅을 사용함에 따라 연관됨.
Suggested reviewers
- lepitaaar
- oesnuj
- suhyun113
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
| Check name | Status | Explanation |
|---|---|---|
| Description Check | ✅ Passed | Check skipped - CodeRabbit’s high-level summary is enabled. |
| Title check | ✅ Passed | PR 제목이 변경사항의 주요 목표를 명확하게 설명합니다. 메인페이지에 동아리/홍보 필터 컴포넌트를 제작한다는 내용이 실제 변경사항과 일치합니다. |
| Linked Issues check | ✅ Passed | PR의 코드 변경사항이 MOA-587 이슈의 요구사항을 충족합니다. 동아리/홍보 칩 필터 버튼이 추가되었으며, 필터 컴포넌트 구현, 스타일링, 스토리북 문서화가 모두 완료되었습니다. |
| Out of Scope Changes check | ✅ Passed | 모든 변경사항이 필터 컴포넌트 구현 범위 내입니다. Button 컴포넌트의 className prop 추가, 배너 마진 조정, Filter 컴포넌트 전체 구현이 모두 필터 기능 추가와 직접 관련됩니다. |
| Docstring Coverage | ✅ Passed | No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. |
✏️ Tip: You can configure your own custom pre-merge checks in the settings.
✨ Finishing touches
- 📝 Generate docstrings
🧪 Generate unit tests (beta)
- Create PR with unit tests
- Post copyable unit tests in a comment
- Commit unit tests in branch
feature/#1123-main-filter-btn-MOA-587
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.
suhyun113
left a comment
There was a problem hiding this comment.
수고하셨습니당! 지금처럼 프리뷰로 확인이 어려울 때 스토리북으로 보니 좋네요~
| ], | ||
| }; | ||
|
|
||
| export const WithNotificationDot: Story = { |
There was a problem hiding this comment.
알림 스토리북까지 추가해주니 확인하기 편하네요!!
추가로 알림이 있는 홍보 버튼을 클릭하면 탭 전환과 동시에 알림 표시가 제거되는 인터랙션을 보여주는 스토리도 있으면 컴포넌트 흐름을 이해하는데 더 좋을 것 같아요!
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In `@frontend/src/pages/MainPage/components/Filter/Filter.stories.tsx`:
- Around line 7-10: Replace the manual viewport manipulation by removing the
setViewportWidth helper and instead configure Storybook's built‑in viewport
addon via each story's parameters.viewport; specifically delete the
setViewportWidth function and any calls to it in this file and update the
PromotionTab and WithNotificationDot stories to set their responsive width using
their stories' parameters.viewport configuration so Storybook's viewport addon
(not window.innerWidth) drives CSS media queries and responsive behaviour.
🧹 Nitpick comments (1)
frontend/src/pages/MainPage/components/Filter/Filter.stories.tsx (1)
55-83:InteractiveNotificationFilter가 실제Filter컴포넌트를 사용하지 않고 내부 구조를 재구현하고 있습니다.
Filter컴포넌트의 내부 구조가 변경되면 이 스토리는 실제 동작과 괴리가 생깁니다. 가능하다면 실제Filter컴포넌트를 합성하거나,Filter에showNotification같은 prop을 추가하여 스토리에서 활용하는 방식을 고려해 주세요.
| const setViewportWidth = (width: number) => { | ||
| window.innerWidth = width; | ||
| window.dispatchEvent(new Event('resize')); | ||
| }; |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
find . -name "Filter.stories.tsx" -type f | head -5Repository: Moadong/moadong
Length of output: 125
🌐 Web query:
Storybook 10 viewport addon parameters configuration CSS media queries
💡 Result:
In Storybook 10.x, the Viewport feature is configured via:
parameters.viewport.options(the list of available viewports)initialGlobals.viewport(the initially-selected viewport) (storybook.js.org)
Global config (.storybook/preview.ts)
import type { Preview } from '@storybook/your-framework';
import { MINIMAL_VIEWPORTS, INITIAL_VIEWPORTS } from 'storybook/viewport';
const preview: Preview = {
parameters: {
viewport: {
options: {
...MINIMAL_VIEWPORTS,
...INITIAL_VIEWPORTS,
// Custom “CSS breakpoint” viewports (use px values that match your `@media` rules)
sm: { name: 'sm (≥640)', styles: { width: '640px', height: '800px' }, type: 'mobile' },
md: { name: 'md (≥768)', styles: { width: '768px', height: '900px' }, type: 'tablet' },
lg: { name: 'lg (≥1024)', styles: { width: '1024px', height: '900px' }, type: 'desktop' },
},
},
},
initialGlobals: {
viewport: { value: 'md', isRotated: false },
},
};
export default preview;options entries are keyed objects like { name, styles: { width, height }, type }, and width/height must include units (e.g. "320px"). (storybook.js.org)
How this relates to CSS media queries
The viewport tool does not configure CSS @media queries directly—it simply changes the iframe size, and your existing CSS @media (min-width: ...) rules will apply automatically at those widths. (storybook.js.org)
Citations:
- 1: https://storybook.js.org/docs/essentials/viewport
- 2: https://storybook.js.org/docs/essentials/viewport
- 3: https://storybook.js.org/docs/essentials/viewport
🏁 Script executed:
cat -n "./frontend/src/pages/MainPage/components/Filter/Filter.stories.tsx"Repository: Moadong/moadong
Length of output: 3020
Storybook viewport 파라미터를 사용하여 반응형 동작을 올바르게 테스트하세요.
window.innerWidth 직접 변경은 CSS 미디어 쿼리를 트리거하지 않으며, Storybook의 viewport 애드온을 우회합니다. 현재 방식으로는 반응형 스타일이 제대로 적용되지 않습니다.
권장 수정 방법
setViewportWidth 함수를 제거하고, parameters.viewport를 사용하세요:
-const setViewportWidth = (width: number) => {
- window.innerWidth = width;
- window.dispatchEvent(new Event('resize'));
-};
export const ClubTab: Story = {
+ parameters: {
+ viewport: {
+ defaultViewport: 'iphone12',
+ },
+ },
decorators: [
(Story) => {
return (
<MemoryRouter initialEntries={['/']}>
<Story />
</MemoryRouter>
);
},
],
};PromotionTab과 WithNotificationDot 스토리에도 동일하게 적용하세요.
📝 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.
| const setViewportWidth = (width: number) => { | |
| window.innerWidth = width; | |
| window.dispatchEvent(new Event('resize')); | |
| }; | |
| export const ClubTab: Story = { | |
| parameters: { | |
| viewport: { | |
| defaultViewport: 'iphone12', | |
| }, | |
| }, | |
| decorators: [ | |
| (Story) => { | |
| return ( | |
| <MemoryRouter initialEntries={['/']}> | |
| <Story /> | |
| </MemoryRouter> | |
| ); | |
| }, | |
| ], | |
| }; |
🤖 Prompt for AI Agents
In `@frontend/src/pages/MainPage/components/Filter/Filter.stories.tsx` around
lines 7 - 10, Replace the manual viewport manipulation by removing the
setViewportWidth helper and instead configure Storybook's built‑in viewport
addon via each story's parameters.viewport; specifically delete the
setViewportWidth function and any calls to it in this file and update the
PromotionTab and WithNotificationDot stories to set their responsive width using
their stories' parameters.viewport configuration so Storybook's viewport addon
(not window.innerWidth) drives CSS media queries and responsive behaviour.
#️⃣연관된 이슈
📝작업 내용
중점적으로 리뷰받고 싶은 부분(선택)
논의하고 싶은 부분(선택)
🫡 참고사항
Summary by CodeRabbit
릴리스 노트
New Features
Style
Documentation