Skip to content

[feature] 메인 배너 클릭, 페이지네이션 추가 및 Swiper 마이그레이션#788

Merged
oesnuj merged 10 commits intodevelop-fefrom
feat/#782-mainpage-banner-click-MOA-287
Nov 8, 2025
Merged

[feature] 메인 배너 클릭, 페이지네이션 추가 및 Swiper 마이그레이션#788
oesnuj merged 10 commits intodevelop-fefrom
feat/#782-mainpage-banner-click-MOA-287

Conversation

@oesnuj
Copy link
Member

@oesnuj oesnuj commented Oct 12, 2025

#️⃣연관된 이슈

#777

📝작업 내용

이번 PR에서 작업한 내용을 간략히 설명해주세요(이미지/동영상 첨부 가능)

👉 Preview 배포 확인하기

1️⃣ Swiper 라이브러리로 배너 마이그레이션 cfd9018

  • 브라우저 창 크기 조절 시 배너가 부자연스럽게 움직임
  • 무한 반복, 자동재생, 화면 계산등의 코드가 복잡해 직관적 이해가 어려움
  • 모바일 슬라이드 필요
  • 위 부분들에 추가로 커스텀 구현으로 추가 기능 개발에 불필요하게 시간이 많이 들것이라 판단했다.

해결 방법

  • React에 최적화되어 있는 Swiper 라이브러리를 선택
  • 무한 루프, 자동 재생, 부드러운 전환 애니메이션을 훨씬 쉽게 적용할 수 있음
image

추가 개선

  • 기존 isMobile 판단 로직을 useDevice 훅으로 통일

2️⃣ useNavigator 커스텀 훅 추가 bbaa725

도입 배경

  • 헤더 링크, 지원서 버튼 등등 하나의 버튼에서 내부 링크(/introduce)와 외부 링크(https://...)를 구분해서 처리하는 로직이 필요한 경우가 많음
  • 매번 링크 타입을 판단하는 코드 작성 필요

해결 방법

const handleLink = useNavigator();

// 외부 링크 → 새 탭에서 열기
handleLink('https://example.com');

// 내부 링크 → React Router로 이동
handleLink('/introduce');

장점

  • 링크 타입 자동 판별 및 적절한 방식으로 처리
  • 코드 중복 제거 및 일관성 확보
  • react-router-domnavigate 직접 사용 불필요

💡💡 앞으로 내외부 링크 처리가 필요한 경우 이 훅을 사용해주세요!💡💡


3️⃣ 이전 / 다음 버튼 아이콘을 변경 0c02310


4️⃣ 배너 클릭 기능 추가 3e1c7d7

  • 배너 클릭 시 배너 상수파일에 설정된 외부 링크 or 내부 링크로 페이지 이동

5️⃣ 페이지네이션 추가 ed50294

모바일

  • 숫자형 표시 (1 / 3)
  • 우측 하단 배치
image

데스크톱

  • Dot 형태 표시
  • 중앙 하단 배치
image

중점적으로 리뷰받고 싶은 부분(선택)

리뷰어가 특별히 봐주었으면 하는 부분이 있다면 작성해주세요

피드백, 궁금증, 칭찬 환영합니다~

  1. useNavigator 훅 네이밍 괜찮나요?

논의하고 싶은 부분(선택)

논의하고 싶은 부분이 있다면 작성해주세요.

라이브러리 도입 기준에 대해

처음에는 직접 구현했는데 요구사항(무한 루프, 자동 재생, 모바일 스와이프, 페이지네이션 등)이 추가되면서 코드가 너어무 복잡해졌습니다. 물론 극한의 추상화를 진행하면 어느정도 해결할 수 있을 것 같긴해요
Swiper는 loop={true} 한 줄로 무한 루프가 해결되는 걸 보고... 지금까지 작업한 게 아깝기도 했지만 도입했습니다.

선택 이유

  • 개발 속도와 안정성 측면에서 검증된 라이브러리가 유리
  • 단순 배너에 너무 많은 시간이 소요된다... 그냥 라이브러리 쓰고 다른 비즈니스 로직에 더 집중 하자
  • 모바일 지원과 접근성이 기본 제공

다른 분들의 의견이 듣고 싶습니다.

  1. 이번 케이스에서 Swiper 사용 어떤가요?
  2. 팀 차원의 라이브러리 도입 기준을 정하면 어떨까요?
    생각나는 게 있으면 가볍게 남겨주세요~ 안 남겨도 괜찮습니다! 👍

Summary by CodeRabbit

릴리스 노트

  • 새로운 기능

    • 배너에 클릭 네비게이션 기능 추가
    • 모바일과 데스크톱에서 다른 형식의 페이지 표시기 추가
  • 개선 사항

    • 배너 회전 및 전환 메커니즘 개선
    • 모바일과 데스크톱 환경에 맞춘 반응형 디자인 최적화
    • 내부 및 외부 링크 네비게이션 로직 개선

원인: setIsReady(false) 호출 직후에도 isReady는 여전히 true
결과: 복구 로직(if (!isReady)) 실행 안 됨 → 배너 멈춤
해결: 리사이즈는 단순히 레이아웃 변경이므로 상태 리셋 불필요
- 커스텀 슬라이더 로직을 Swiper로 교체
- 복잡한 상태 관리 및 애니메이션 로직 제거
- 기존 기능(무한 루프, 자동재생, 네비게이션) 동일하게 유지
- useDevice 커스텀 훅을 적용하여 Banner 컴포넌트 내의 화면 크기 감지 로직 제거
- 내부 경로는 React Router navigate로 라우팅
- 외부 HTTPS 링크는 새 탭에서 안전하게 열기 (noopener, noreferrer)
배너 이미지 리스트에 linkTo 속성을 추가하여 클릭 시 이동할 경로 지정
- useNavigator 훅 import 및 적용
- handleBannerClick 함수 구현 (linkTo 기반 페이지 이동)
- BannerItem에 onClick 이벤트 및 isClickable prop 추가
- linkTo 존재 여부에 따른 조건부 클릭 처리
- 데스크탑: dot 형태 페이지네이션
- 모바일: 숫자형 페이지네이션 (1/5)
@oesnuj oesnuj self-assigned this Oct 12, 2025
@oesnuj oesnuj added ✨ Feature 기능 개발 💻 FE Frontend labels Oct 12, 2025
@vercel
Copy link

vercel bot commented Oct 12, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Preview Comments Updated (UTC)
moadong Ready Ready Preview Comment Nov 8, 2025 9:41am

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Oct 12, 2025

Warning

.coderabbit.yaml has a parsing error

The CodeRabbit configuration file in this repository has a parsing error and default settings were used instead. Please fix the error(s) in the configuration file. You can initialize chat with CodeRabbit to get help with the configuration file.

💥 Parsing errors (1)
Validation error: Invalid regex pattern for base branch. Received: "**" at "reviews.auto_review.base_branches[0]"
⚙️ Configuration instructions
  • Please see the configuration documentation for more information.
  • You can also validate your configuration using the online YAML validator.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Walkthrough

메인페이지 배너를 Swiper 기반 캐러셀로 전환하고 배너 클릭 시 내부/외부 이동을 처리하는 useNavigator 훅을 도입했다. 배너 데이터에 linkTo 필드를 추가하고 스타일을 미디어 유틸로 정리하여 페이지네이션(숫자/도트) 및 클릭 가능성 표시를 추가했다.

Changes

Cohort / File(s) Change summary
배너 데이터: 링크 필드 추가
frontend/src/constants/banners.ts
데스크톱/모바일 배너 아이템에 linkTo: '/introduce' 필드 추가.
네비게이션 훅 도입
frontend/src/hooks/useNavigator.ts
useNavigator 훅 추가. handleLink로 공백 제거·빈 값 무시, https:// 외부 URL은 window.open, 그 외는 useNavigate로 내부 라우팅. (default export)
배너 컴포넌트 — Swiper 전환 및 클릭 처리
frontend/src/pages/MainPage/components/Banner/Banner.tsx, frontend/src/pages/MainPage/components/Banner/Banner.styles.ts
커스텀 슬라이드 로직 제거 후 Swiper(Autoplay, Navigation) 사용으로 전환. BannerProps에 선택적 linkTo 추가, 배너 클릭 시 useNavigator 사용. 모바일은 숫자 페이지네이션, 데스크톱은 도트 페이지네이션으로 렌더. 스타일은 media 유틸 적용, BannerItemisClickable prop 추가, NumericPagination, DotPagination, Dot 컴포넌트 추가 및 SlideButton/버튼 포인터 이벤트 조정.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor U as 사용자
  participant B as Banner (SwiperSlide)
  participant H as useNavigator.handleLink
  participant R as React Router (navigate)
  participant W as window.open

  U->>B: 배너 클릭
  B->>H: handleLink(linkTo)
  alt 외부 URL (https://...)
    H->>W: window.open(url, "_blank")
  else 내부 경로
    H->>R: navigate(url)
  end
Loading
sequenceDiagram
  autonumber
  actor U as 사용자
  participant BtnP as Prev 버튼
  participant BtnN as Next 버튼
  participant S as Swiper 인스턴스

  U->>BtnP: 클릭
  BtnP->>S: slidePrev()

  U->>BtnN: 클릭
  BtnN->>S: slideNext()

  S-->>S: onSlideChange -> currentIndex 갱신
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • 주의할 파일/영역:
    • Banner.tsx — Swiper 이벤트(onSwiper, onSlideChange) 및 swiperInstance 관리
    • useNavigator.ts — 외부/내부 링크 판별 로직
    • Banner.styles.ts — media 유틸 적용, 포인터 이벤트/페이지네이션 새 컴포넌트 확인

Possibly related PRs

Suggested reviewers

  • lepitaaar
  • seongje973
  • seongwon030

Pre-merge checks and finishing touches

✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed PR 제목은 주요 변경사항을 명확하게 요약하고 있습니다: 배너 클릭 기능 추가, 페이지네이션 추가, Swiper 마이그레이션이라는 핵심 내용을 간결하게 표현했습니다.
Linked Issues check ✅ Passed 변경사항이 MOA-287 요구사항을 완전히 충족합니다: 배너 클릭 기능이 구현되었고, useNavigator 훅으로 내부/외부 링크를 자동 판별하여 처리하며, banners.ts에 linkTo 필드를 추가하여 배너별 링크 설정이 가능합니다.
Out of Scope Changes check ✅ Passed 모든 변경사항이 MOA-287의 배너 클릭 기능 구현 범위 내에 있습니다. Swiper 마이그레이션, 페이지네이션, useNavigator 훅 등은 모두 배너 기능 개선을 위한 필수 지원 작업입니다.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ 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 feat/#782-mainpage-banner-click-MOA-287

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🧹 Nitpick comments (5)
frontend/src/constants/banners.ts (1)

31-31: 이름 혼동 가능: SlideButton(상수) vs Styled.SlideButton(컴포넌트).

가독성/오해 방지를 위해 상수명을 변경하는 것을 권장합니다.

-export const SlideButton = [PrevButton, NextButton];
+export const SlideButtonIcons = [PrevButton, NextButton];

Banner.tsx의 import도 함께 변경 필요:

-import { SlideButton } from '@/constants/banners';
+import { SlideButtonIcons as SlideButton } from '@/constants/banners';
frontend/src/hooks/useNavigator.ts (1)

2-2: React Router v7 가이드에 맞춘 import 정리(선택).

v7에서는 react-router로의 직접 import를 권장합니다. 현재는 re-export라 동작하나, 점진적 이전을 고려해보세요.

Based on learnings

frontend/src/pages/MainPage/components/Banner/Banner.tsx (3)

59-64: 매직 넘버 상수화.

autoplay delay(3000), speed(500)을 명명 상수로 추출하세요.

As per coding guidelines

-          autoplay={{
-            delay: 3000,
-            disableOnInteraction: false,
-          }}
-          speed={500}
+          autoplay={{
+            delay: AUTOPLAY_DELAY_MS,
+            disableOnInteraction: false,
+          }}
+          speed={SLIDE_SPEED_MS}

파일 상단(컴포넌트 위) 등에 추가:

const AUTOPLAY_DELAY_MS = 3000;
const SLIDE_SPEED_MS = 500;

3-3: 불필요한 Swiper 모듈 제거(선택).

기본 네비게이션 UI는 사용하지 않고 인스턴스 메서드로 제어하므로 Navigation 모듈이 불필요해 보입니다. 번들 최적화를 위해 제거를 고려하세요.

-import { Navigation, Autoplay } from 'swiper/modules';
+import { Autoplay } from 'swiper/modules';
-          modules={[Navigation, Autoplay]}
+          modules={[Autoplay]}

Also applies to: 55-55


71-71: 배너 이미지 대체 텍스트 구체화(선택).

banner-{index}는 정보가 부족합니다. 배너 목적(예: "서비스 소개 페이지 이동")에 맞게 alt를 구체화하거나 장식적 이미지면 빈 문자열로 처리하세요.

📜 Review details

Configuration used: CodeRabbit 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.

📥 Commits

Reviewing files that changed from the base of the PR and between 393ab43 and ed50294.

⛔ Files ignored due to path filters (2)
  • frontend/src/assets/images/icons/next_button_icon.svg is excluded by !**/*.svg
  • frontend/src/assets/images/icons/prev_button_icon.svg is excluded by !**/*.svg
📒 Files selected for processing (4)
  • frontend/src/constants/banners.ts (1 hunks)
  • frontend/src/hooks/useNavigator.ts (1 hunks)
  • frontend/src/pages/MainPage/components/Banner/Banner.styles.ts (5 hunks)
  • frontend/src/pages/MainPage/components/Banner/Banner.tsx (2 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
frontend/**/*.{ts,tsx}

📄 CodeRabbit inference engine (frontend/.cursorrules)

frontend/**/*.{ts,tsx}: Replace magic numbers with named constants for clarity.
Replace complex or nested ternary operators with if/else statements or IIFEs for readability.
Assign complex boolean conditions to named variables.
Use consistent return types for similar functions and hooks.
Avoid hidden side effects; functions should only perform actions implied by their signature (Single Responsibility Principle).
Use unique, descriptive names for custom wrappers and functions to avoid ambiguity.
Define constants near related logic or ensure names link them clearly.

Files:

  • frontend/src/hooks/useNavigator.ts
  • frontend/src/pages/MainPage/components/Banner/Banner.styles.ts
  • frontend/src/constants/banners.ts
  • frontend/src/pages/MainPage/components/Banner/Banner.tsx
frontend/**/*.tsx

📄 CodeRabbit inference engine (frontend/.cursorrules)

frontend/**/*.tsx: Abstract complex logic/interactions into dedicated components or higher-order 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.
Break down broad state management into smaller, focused hooks or contexts.
Use component composition instead of props drilling.

Files:

  • frontend/src/pages/MainPage/components/Banner/Banner.tsx
🧬 Code graph analysis (2)
frontend/src/pages/MainPage/components/Banner/Banner.styles.ts (1)
frontend/src/styles/mediaQuery.ts (1)
  • media (8-14)
frontend/src/pages/MainPage/components/Banner/Banner.tsx (2)
frontend/src/pages/MainPage/components/Banner/Banner.styles.ts (1)
  • SlideButton (63-85)
frontend/src/constants/banners.ts (1)
  • SlideButton (31-31)
🔇 Additional comments (1)
frontend/src/pages/MainPage/components/Banner/Banner.tsx (1)

2-4: Swiper CSS import 확인 필요.

전역 또는 이 컴포넌트에서 import 'swiper/css'가 누락되면 기본 스타일이 적용되지 않습니다. 프로젝트 내 어디엔가 포함되어 있는지 확인 부탁드립니다.

Copy link
Member

@seongwon030 seongwon030 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

와 확실히 라이브러리를 사용하니까 코드양이 많이 줄어드네요. 라이브러리를 사용했을때의 성능 최적화는 어떤 방식으로 할 수 있을지 생각해봐도 좋을 것 같습니다.

초반 캐러셀 구현할 때 직접 구현해보고 싶은 마음에 코드가 길어져도 감수했던 것 같습니다.
지금 저희는 비즈니스적인 문제도 고려할 필요가 있는 것 같아요. 스프린트를 정하고 그 안에 수행해야 하는 일이 있는데 개인적인 기술적 성장보단 팀 자체의 능률이 중요해진 것 같네요. 역량이 부족하다면 작업단위를 줄이는 방향이 더 맞는 것 같습니다..!

Copy link
Collaborator

@suhyun113 suhyun113 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

헉 배너 도트 추가되면 좋겠다고 생각하고 있었는데! 좋아요!
너무 수고하셨습니다ㅏ

저는 Swiper를 사용한거 좋다고 생각해요. 준서님께서 충분히 고민해보고 코드 복잡도를 해결하기 위해 도입하신거 같아서 좋은 것 같습니다ㅏ 안그래도 배너에서 자잘한 오류들이 있었는데, 클릭 이벤트까지 추가해야하니 적절한 선택인 것 같습니다!

라이브러리 도입 기준이 있다면 좋을 것 같네요! 저는 음... 준서님처럼 타당한 이유를 이야기하고 사용한다면 좋을 것 같아요! PR을 읽으면서 이해도 되고, 좋은 것 같아요.
아 단지, 팀 차원의 기준을 정하기로 한다면 라이브러리 도입 전에 같이 이야기해봐도 좋을 것 같아요!
Discussions을 활용한다면 라이브러리 도입 기준 관련된 곳에서 토의하는 것은 어떨까요?

@oesnuj
Copy link
Member Author

oesnuj commented Nov 8, 2025

헉 배너 도트 추가되면 좋겠다고 생각하고 있었는데! 좋아요! 너무 수고하셨습니다ㅏ

저는 Swiper를 사용한거 좋다고 생각해요. 준서님께서 충분히 고민해보고 코드 복잡도를 해결하기 위해 도입하신거 같아서 좋은 것 같습니다ㅏ 안그래도 배너에서 자잘한 오류들이 있었는데, 클릭 이벤트까지 추가해야하니 적절한 선택인 것 같습니다!

라이브러리 도입 기준이 있다면 좋을 것 같네요! 저는 음... 준서님처럼 타당한 이유를 이야기하고 사용한다면 좋을 것 같아요! PR을 읽으면서 이해도 되고, 좋은 것 같아요. 아 단지, 팀 차원의 기준을 정하기로 한다면 라이브러리 도입 전에 같이 이야기해봐도 좋을 것 같아요! Discussions을 활용한다면 라이브러리 도입 기준 관련된 곳에서 토의하는 것은 어떨까요?

수현님
논의하고 싶은 부분에 대해서 같이 답변 남겨주셔서 감사합니다!
라이브러리없이 직접 구현하는 것이 학습에는 도움되지만 서비스를 운영함에 있어서는 라이브러리를 잘 활용하는 것도 능력이라는 생각이 드네요
라이브러리 도입 기준에 대해서 Discussions에 정리해서 한번 남겨보겠습니다 😊

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

♻️ Duplicate comments (2)
frontend/src/pages/MainPage/components/Banner/Banner.styles.ts (2)

2-2: 순환 의존성 여전히 존재.

이전 리뷰에서 지적된 순환 의존성 문제가 해결되지 않았습니다. BannerProps를 런타임 임포트하면 Banner.tsx와 순환 참조가 발생합니다.

해결 방법:

-import { BannerProps } from './Banner';
+import type { BannerProps } from './Banner';

또는 Line 21의 BannerWrapper에서 실제로 props를 사용하지 않으므로 제네릭 제거:

-export const BannerWrapper = styled.div<BannerProps>`
+export const BannerWrapper = styled.div`

96-96: 잘못된 CSS 값: font-weight: medium.

이전 리뷰에서 지적된 이슈가 수정되지 않았습니다. font-weight: medium은 유효하지 않은 CSS 값입니다.

-  font-size: 11px;
-  font-weight: medium;
+  font-size: 11px;
+  font-weight: 500;
🧹 Nitpick comments (1)
frontend/src/pages/MainPage/components/Banner/Banner.styles.ts (1)

86-116: 매직 넘버를 상수로 추출하는 것을 고려해보세요.

페이지네이션 컴포넌트들에 여러 매직 넘버가 사용되고 있습니다(예: bottom: 17px, right: -10px, gap: 6px, width: 8px 등). 코딩 가이드라인에 따라 이러한 값들을 명명된 상수로 추출하면 유지보수성이 향상됩니다.

예시:

const PAGINATION_SPACING = {
  NUMERIC_BOTTOM: 17,
  NUMERIC_RIGHT: -10,
  DOT_BOTTOM: 20,
  DOT_GAP: 6,
  DOT_SIZE: 8,
} as const;

적용:

export const NumericPagination = styled.div`
  bottom: ${PAGINATION_SPACING.NUMERIC_BOTTOM}px;
  right: ${PAGINATION_SPACING.NUMERIC_RIGHT}px;
  // ...
`;
📜 Review details

Configuration used: CodeRabbit 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.

📥 Commits

Reviewing files that changed from the base of the PR and between ed50294 and 63cc3e7.

📒 Files selected for processing (1)
  • frontend/src/pages/MainPage/components/Banner/Banner.styles.ts (5 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
frontend/**/*.{ts,tsx}

📄 CodeRabbit inference engine (frontend/.cursorrules)

frontend/**/*.{ts,tsx}: Replace magic numbers with named constants for clarity.
Replace complex or nested ternary operators with if/else statements or IIFEs for readability.
Assign complex boolean conditions to named variables.
Use consistent return types for similar functions and hooks.
Avoid hidden side effects; functions should only perform actions implied by their signature (Single Responsibility Principle).
Use unique, descriptive names for custom wrappers and functions to avoid ambiguity.
Define constants near related logic or ensure names link them clearly.

Files:

  • frontend/src/pages/MainPage/components/Banner/Banner.styles.ts
🧠 Learnings (1)
📚 Learning: 2025-07-19T05:09:10.702Z
Learnt from: CR
Repo: Moadong/moadong PR: 0
File: frontend/.cursorrules:0-0
Timestamp: 2025-07-19T05:09:10.702Z
Learning: Applies to frontend/**/*.{ts,tsx} : Replace magic numbers with named constants for clarity.

Applied to files:

  • frontend/src/pages/MainPage/components/Banner/Banner.styles.ts
🧬 Code graph analysis (1)
frontend/src/pages/MainPage/components/Banner/Banner.styles.ts (1)
frontend/src/styles/mediaQuery.ts (1)
  • media (8-14)
🔇 Additional comments (4)
frontend/src/pages/MainPage/components/Banner/Banner.styles.ts (4)

3-3: 미디어 쿼리 유틸리티 도입 잘 했습니다.

중앙화된 mediaQuery 유틸리티를 사용하여 하드코딩된 브레이크포인트를 제거한 점이 좋습니다. 유지보수성이 향상되고 일관성 있는 반응형 디자인을 보장합니다.

Also applies to: 15-18, 31-35, 77-83


38-48: 클릭 가능 상태 표시가 올바르게 구현되었습니다.

isClickable prop을 통해 커서 스타일을 조건부로 적용하여 사용자에게 명확한 인터랙션 피드백을 제공합니다.


58-59: 포인터 이벤트 처리가 적절합니다.

컨테이너에서 pointer-events: none을 설정하고 버튼에서 pointer-events: auto를 활성화하여 중첩된 인터랙티브 요소의 이벤트 전파를 올바르게 제어했습니다. 반응형 스타일 조정도 적절합니다.

Also applies to: 62-84


100-116: 페이지네이션 컴포넌트 구현이 깔끔합니다.

데스크톱용 도트 페이지네이션과 모바일용 숫자 페이지네이션을 명확하게 분리하여 구현했습니다. 활성 상태 전환 애니메이션도 부드럽게 적용되어 좋은 사용자 경험을 제공합니다.

@oesnuj oesnuj merged commit c5fae9d into develop-fe Nov 8, 2025
5 checks passed
@oesnuj oesnuj deleted the feat/#782-mainpage-banner-click-MOA-287 branch November 11, 2025 04:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

💻 FE Frontend ✨ Feature 기능 개발

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants