-
Notifications
You must be signed in to change notification settings - Fork 2
[feature] 앱 출시 배너를 추가한다 #938
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
- 패치노트 배너 제거
- APP_STORE_LINKS 상수 추가 (iOS, Android, default) - getAppStoreLink 함수로 user-agent 기반 OS 판별 - iOS: itms-apps 스키마로 App Store 연결 - Android/기타: Google Play Store 연결
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Warning
|
| Cohort / File(s) | Summary |
|---|---|
외부 URL 탐지 및 네비게이션 훅 frontend/src/hooks/useNavigator.ts |
위험한 프로토콜(javascript:, data:, vbscript:) 차단; 외부 링크 판별을 http/https/itms-apps 등으로 확장; 외부 링크는 내부 라우터 대신 window.location.href로 이동하도록 변경. |
훅 단위테스트 추가 frontend/src/hooks/__tests__/useNavigator.test.ts |
빈/공백 링크, 위험 스킴(대소문자 포함), 외부 링크(itms-apps 포함), 내부 절대/상대 경로 시나리오를 검증하는 테스트 추가. useNavigate 및 window.location 모킹/복원 포함. |
배너 클릭 처리 및 앱스토어 토큰 해석 frontend/src/pages/MainPage/components/Banner/Banner.tsx |
APP_STORE_LINKS 맵과 getAppStoreLink() 추가. handleBannerClick이 APP_STORE_LINK일 때 플랫폼별 스토어 URL을 해석해 트래킹(APP_DOWNLOAD_BANNER_CLICKED) 후 이동; 일반 링크는 BANNER_CLICKED 트래킹 후 이동. |
배너 데이터 업데이트(콘텐츠 전환) frontend/src/pages/MainPage/components/Banner/bannerData.ts |
PatchNote 배너 항목 제거, 앱 출시 배너(app-release-december-2025)로 교체(데스크톱/모바일 이미지 및 linkTo: APP_STORE_LINK). |
이벤트 상수 추가 frontend/src/constants/eventName.ts |
USER_EVENT에 BANNER_CLICKED 및 APP_DOWNLOAD_BANNER_CLICKED 키 추가. |
Sequence Diagram(s)
sequenceDiagram
participant User
participant Banner
participant useNavigator
participant Router as React-Router
participant Window as window.location
User->>Banner: 배너 클릭 (bannerId, bannerName, linkTo)
Banner->>useNavigator: handleBannerClick(linkTo, bannerId, bannerName)
alt linkTo == APP_STORE_LINK
useNavigator->>useNavigator: getAppStoreLink(userAgent)
useNavigator->>Window: window.location.href = appStoreUrl
useNavigator->>Banner: track(APP_DOWNLOAD_BANNER_CLICKED, ...)
else linkTo matches external (http/https/itms-apps)
useNavigator->>Window: window.location.href = url
useNavigator->>Banner: track(BANNER_CLICKED, ...)
else internal path
useNavigator->>Router: navigate(path)
useNavigator->>Banner: (no window.location change)
end
Estimated code review effort
🎯 3 (Moderate) | ⏱️ ~20 분
- 주의할 파일/영역:
useNavigator.ts의 스킴 차단 정규식(대소문자 및 인코딩 엣지케이스)getAppStoreLink()의 userAgent 기반 플랫폼 판별 정확성- Banner의 트래킹 호출 인자와 이벤트 이름(
USER_EVENT) 사용 일관성 - 테스트에서
window.location모킹/복원으로 인한 사이드 이펙트
Possibly related issues
- MOA-427: 패치노트 배너를 앱 출시 배너로 변경한다 — 패치노트 제거 및 앱 출시 배너 추가 구현과 직접 연관.
- [feature] MOA-427 패치노트 배너를 앱 출시 배너로 변경한다 #937 — MainPage 배너 교체(패치노트→앱 출시)와 기능적으로 일치.
Possibly related PRs
- [feature] 11월 패치노트 배너 추가 및 Banner 컴포넌트 구조 개선 #858 — Banner 컴포넌트 및 bannerData 관련 변경 이력과 직접적 코드 레벨 연관.
- [refactor] 믹스패널 이벤트 이름을 통일한다 #856 —
USER_EVENT상수 변경/확장과 이벤트 네이밍 정합성 관련 연관. - [feature] 메인 배너 클릭, 페이지네이션 추가 및 Swiper 마이그레이션 #788 —
useNavigator외부 링크 처리/네비게이션 흐름 관련 변경 이력과 연관.
Suggested reviewers
- oesnuj
- lepitaaar
- seongje973
Pre-merge checks and finishing touches
✅ Passed checks (5 passed)
| Check name | Status | Explanation |
|---|---|---|
| Title check | ✅ Passed | The PR title '[feature] 앱 출시 배너를 추가한다' clearly summarizes the main objective: adding an app release banner feature. |
| Linked Issues check | ✅ Passed | All coding requirements from MOA-427 are met: patch note banner removed, app release banner added with platform-specific store links, security enhancements to useNavigator implemented, and comprehensive tests added. |
| Out of Scope Changes check | ✅ Passed | All changes directly support the linked issue objectives: banner replacement, app store navigation, security improvements, and test coverage are all within scope. |
| Docstring Coverage | ✅ Passed | No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. |
| Description Check | ✅ Passed | Check skipped - CodeRabbit’s high-level summary is enabled. |
✨ 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/#937-add-app-banner-MOA-427
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 3
📜 Review details
Configuration used: Organization 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.
⛔ Files ignored due to path filters (2)
frontend/src/assets/images/banners/banner_desktop4.pngis excluded by!**/*.pngfrontend/src/assets/images/banners/banner_mobile4.pngis excluded by!**/*.png
📒 Files selected for processing (3)
frontend/src/hooks/useNavigator.ts(1 hunks)frontend/src/pages/MainPage/components/Banner/Banner.tsx(2 hunks)frontend/src/pages/MainPage/components/Banner/bannerData.ts(2 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
frontend/**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (frontend/.cursorrules)
frontend/**/*.{ts,tsx,js,jsx}: Replace magic numbers with named constants for clarity
Replace complex/nested ternaries withif/elseor IIFEs for readability
Assign complex boolean conditions to named variables for explicit meaning
Avoid hidden side effects; functions should only perform actions implied by their signature (Single Responsibility Principle)
Use unique and descriptive names for custom wrappers/functions to avoid ambiguity
Define constants near related logic or ensure names link them clearly to avoid silent failures
Break down broad state management into smaller, focused hooks/contexts to reduce coupling
Files:
frontend/src/pages/MainPage/components/Banner/Banner.tsxfrontend/src/pages/MainPage/components/Banner/bannerData.tsfrontend/src/hooks/useNavigator.ts
frontend/**/*.{tsx,jsx}
📄 CodeRabbit inference engine (frontend/.cursorrules)
frontend/**/*.{tsx,jsx}: Abstract complex logic/interactions into dedicated 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 when using form libraries like react-hook-form
Use Component Composition instead of Props Drilling to reduce coupling
Files:
frontend/src/pages/MainPage/components/Banner/Banner.tsx
frontend/**/*.{ts,tsx}
📄 CodeRabbit inference engine (frontend/.cursorrules)
Use consistent return types for similar functions/hooks
Files:
frontend/src/pages/MainPage/components/Banner/Banner.tsxfrontend/src/pages/MainPage/components/Banner/bannerData.tsfrontend/src/hooks/useNavigator.ts
🔇 Additional comments (2)
frontend/src/pages/MainPage/components/Banner/bannerData.ts (1)
5-6: LGTM!앱 출시 배너로의 전환이 올바르게 구현되었습니다. 이미지 임포트와 배너 데이터 구조가 기존 패턴을 잘 따르고 있으며,
APP_STORE_LINK토큰은 Banner 컴포넌트에서 플랫폼별 스토어 링크로 적절히 해석됩니다.Also applies to: 32-36
frontend/src/pages/MainPage/components/Banner/Banner.tsx (1)
48-57: LGTM!
handleBannerClick함수는 undefined URL에 대한 적절한 가드를 포함하고 있으며,APP_STORE_LINK토큰을 플랫폼별 스토어 링크로 올바르게 해석한 후 네비게이션을 수행합니다. 로직이 명확하고 안전합니다.
- javascript, data, vbscript 프로토콜 차단으로 XSS 방지 - 허용 프로토콜 화이트리스트 방식으로 변경
- 빈 URL 처리 테스트 - 악성 프로토콜 차단 테스트 (javascript, data, vbscript) - 외부 URL 이동 테스트 (https, http, itms-apps) - 내부 페이지 이동 테스트
There was a problem hiding this 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
🧹 Nitpick comments (1)
frontend/src/hooks/useNavigator.ts (1)
12-13: 위험 프로토콜 목록에 추가 프로토콜을 포함하는 것을 권장합니다.현재
javascript:,data:,vbscript:프로토콜만 차단하고 있습니다.file:및blob:프로토콜도 보안 위험이 될 수 있으므로 차단 목록에 추가하는 것이 좋습니다.다음 diff를 적용하여 차단 목록을 확장하세요:
-const isDangerousProtocol = /^(javascript|data|vbscript):/i.test(trimmedUrl); +const isDangerousProtocol = /^(javascript|data|vbscript|file|blob):/i.test(trimmedUrl);
📜 Review details
Configuration used: Organization 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.
📒 Files selected for processing (2)
frontend/src/hooks/__tests__/useNavigator.test.ts(1 hunks)frontend/src/hooks/useNavigator.ts(1 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
frontend/**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (frontend/.cursorrules)
frontend/**/*.{ts,tsx,js,jsx}: Replace magic numbers with named constants for clarity
Replace complex/nested ternaries withif/elseor IIFEs for readability
Assign complex boolean conditions to named variables for explicit meaning
Avoid hidden side effects; functions should only perform actions implied by their signature (Single Responsibility Principle)
Use unique and descriptive names for custom wrappers/functions to avoid ambiguity
Define constants near related logic or ensure names link them clearly to avoid silent failures
Break down broad state management into smaller, focused hooks/contexts to reduce coupling
Files:
frontend/src/hooks/useNavigator.tsfrontend/src/hooks/__tests__/useNavigator.test.ts
frontend/**/*.{ts,tsx}
📄 CodeRabbit inference engine (frontend/.cursorrules)
Use consistent return types for similar functions/hooks
Files:
frontend/src/hooks/useNavigator.tsfrontend/src/hooks/__tests__/useNavigator.test.ts
🧠 Learnings (1)
📚 Learning: 2025-07-20T11:48:50.207Z
Learnt from: seongwon030
Repo: Moadong/moadong PR: 541
File: frontend/src/pages/ClubDetailPage/components/ClubDetailHeader/ClubDetailHeader.tsx:41-43
Timestamp: 2025-07-20T11:48:50.207Z
Learning: moadong 프로젝트는 Next.js가 아닌 순수 React + react-router-dom 기반의 CSR(Client-Side Rendering) SPA이므로, window 객체 사용에 대한 SSR 호환성 문제를 제기하지 않아야 합니다.
Applied to files:
frontend/src/hooks/__tests__/useNavigator.test.ts
🔇 Additional comments (3)
frontend/src/hooks/useNavigator.ts (2)
15-15: LGTM! 이전 리뷰의 보안 우려사항이 해결되었습니다.외부 URL 탐지 로직이 올바르게 구현되었으며, 위험한 프로토콜 차단(12-13줄)이 추가되어 이전 리뷰에서 제기된 보안 문제가 해결되었습니다.
18-18: 외부 링크 탐색 방식 변경을 확인해주세요.외부 URL 탐색 방식이
window.open(trimmedUrl, '_blank', 'noopener,noreferrer')에서window.location.href = trimmedUrl로 변경되었습니다. 이는 외부 링크가 새 탭이 아닌 현재 탭에서 열리도록 변경하는 것으로, 사용자 경험에 큰 영향을 미칩니다.
- 이전: 외부 링크를 새 탭에서 열어 현재 페이지 유지
- 현재: 외부 링크로 현재 탭에서 이동하여 현재 페이지 이탈
앱 스토어 링크의 경우 의도적인 변경일 수 있으나, 다른 외부 링크의 경우 사용자가 새 탭에서 열리기를 기대할 수 있습니다. 이 변경이 의도된 것인지 확인해주세요.
필요한 경우 다음과 같이 URL 유형에 따라 다르게 처리할 수 있습니다:
if (isExternalUrl) { // 앱 스토어 링크는 현재 탭에서, 다른 외부 링크는 새 탭에서 if (/^itms-apps:/.test(trimmedUrl)) { window.location.href = trimmedUrl; } else { window.open(trimmedUrl, '_blank', 'noopener,noreferrer'); } } else { navigate(trimmedUrl); }frontend/src/hooks/__tests__/useNavigator.test.ts (1)
1-126: LGTM! 포괄적이고 잘 구성된 테스트 스uite입니다.테스트가 다음을 철저하게 검증합니다:
- 빈 링크 및 공백 처리
- 위험한 프로토콜 차단 (대소문자 변형 포함)
- 외부 URL 탐색 (https, http, itms-apps)
- 내부 경로 탐색 (절대/상대 경로)
테스트 구조가 명확하고, mock 관리가 적절하며, 구현과 완벽하게 일치합니다.
Based on learnings, moadong 프로젝트는 CSR SPA이므로
window객체 사용에 대한 SSR 호환성 문제가 없습니다.
- Given-When-Then 패턴 주석 추가 - renderHook을 beforeEach로 공통화하여 중복 제거
There was a problem hiding this 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
🧹 Nitpick comments (1)
frontend/src/hooks/__tests__/useNavigator.test.ts (1)
54-90: 악성 링크 차단 테스트가 잘 구현되어 있습니다.
javascript:,data:,vbscript:스킴에 대한 차단과 대소문자 구분 없는 검증이 포함되어 있어 일반적인 XSS 공격 벡터를 효과적으로 커버하고 있습니다.선택적 개선 사항: 추가 보안 테스트 케이스를 고려해볼 수 있습니다:
- URL 인코딩된 스킴 (
javascript%3Aalert)- 공백이 포함된 스킴 우회 시도
- 다른 잠재적 위험 스킴 (
file:,blob:)현재 구현으로도 주요 공격 벡터는 충분히 방어됩니다.
📜 Review details
Configuration used: Organization 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.
📒 Files selected for processing (1)
frontend/src/hooks/__tests__/useNavigator.test.ts(1 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
frontend/**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (frontend/.cursorrules)
frontend/**/*.{ts,tsx,js,jsx}: Replace magic numbers with named constants for clarity
Replace complex/nested ternaries withif/elseor IIFEs for readability
Assign complex boolean conditions to named variables for explicit meaning
Avoid hidden side effects; functions should only perform actions implied by their signature (Single Responsibility Principle)
Use unique and descriptive names for custom wrappers/functions to avoid ambiguity
Define constants near related logic or ensure names link them clearly to avoid silent failures
Break down broad state management into smaller, focused hooks/contexts to reduce coupling
Files:
frontend/src/hooks/__tests__/useNavigator.test.ts
frontend/**/*.{ts,tsx}
📄 CodeRabbit inference engine (frontend/.cursorrules)
Use consistent return types for similar functions/hooks
Files:
frontend/src/hooks/__tests__/useNavigator.test.ts
🧠 Learnings (1)
📚 Learning: 2025-07-20T11:48:50.207Z
Learnt from: seongwon030
Repo: Moadong/moadong PR: 541
File: frontend/src/pages/ClubDetailPage/components/ClubDetailHeader/ClubDetailHeader.tsx:41-43
Timestamp: 2025-07-20T11:48:50.207Z
Learning: moadong 프로젝트는 Next.js가 아닌 순수 React + react-router-dom 기반의 CSR(Client-Side Rendering) SPA이므로, window 객체 사용에 대한 SSR 호환성 문제를 제기하지 않아야 합니다.
Applied to files:
frontend/src/hooks/__tests__/useNavigator.test.ts
🔇 Additional comments (4)
frontend/src/hooks/__tests__/useNavigator.test.ts (4)
1-32: 테스트 설정이 올바르게 구성되어 있습니다.Mock 설정,
window.location백업/복원, 그리고 각 테스트 간 초기화 로직이 적절하게 구현되었습니다.Object.defineProperty를 사용한window.location모킹은 Jest에서 표준적인 패턴입니다.
34-52: 빈 링크 처리 테스트가 올바릅니다.빈 문자열과 공백만 있는 경우 모두 내비게이션이 발생하지 않음을 검증하고 있습니다. 적절한 경계값 테스트입니다.
92-119: 외부 링크 처리 테스트가 정확합니다.
https,http,itms-apps프로토콜에 대해window.location.href를 통한 이동과useNavigate가 호출되지 않음을 모두 검증하고 있습니다. 앱 스토어 딥링크 지원이라는 PR 목표와도 일치합니다.
121-139: 내부 페이지 내비게이션 테스트가 올바릅니다.절대 경로와 상대 경로 모두
useNavigate를 통해 처리되고window.location.href가 변경되지 않음을 검증하여 SPA 내비게이션 동작이 올바르게 유지됨을 보장합니다.
lepitaaar
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
빠른추가 수고하셨습니다~
- eventName에 BANNER_CLICKED, APP_DOWNLOAD_BANNER_CLICKED 이벤트 추가 - 배너 클릭 시 bannerId, bannerName, linkTo/platform 로깅 - user-agent 기반 iOS/Android 스토어 링크 분기 - 앱 다운로드 배너 데이터 추가
There was a problem hiding this 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 (1)
frontend/src/pages/MainPage/components/Banner/Banner.tsx (1)
21-31: iPadOS 감지 로직에 잠재적 문제가 있습니다.이전 리뷰에서 언급된 것처럼, 최신 iPadOS는 데스크탑 모드에서 macOS와 동일한 user-agent를 전송합니다.
macintosh매칭만으로는 Mac과 iPad를 구분할 수 없어 Mac 사용자가 iOS 앱스토어로 리다이렉트될 수 있습니다.
navigator.maxTouchPoints를 활용하여 개선할 수 있습니다:const getAppStoreLink = (): string => { const userAgent = navigator.userAgent.toLowerCase(); - if (/iphone|ipad|ipod|macintosh/.test(userAgent)) { + // iPad/iPhone/iPod 명시적 감지 + if (/iphone|ipad|ipod/.test(userAgent)) { + return APP_STORE_LINKS.ios; + } + // macOS Safari에서 iPadOS 감지 (maxTouchPoints > 1) + if (/macintosh/.test(userAgent) && navigator.maxTouchPoints > 1) { return APP_STORE_LINKS.ios; } if (/android/.test(userAgent)) { return APP_STORE_LINKS.android; } return APP_STORE_LINKS.default; };
🧹 Nitpick comments (2)
frontend/src/pages/MainPage/components/Banner/bannerData.ts (1)
17-23: 매직 스트링'APP_STORE_LINK'를 상수로 추출하는 것을 권장합니다.
linkTo: 'APP_STORE_LINK'가 Banner.tsx에서 특별히 처리되는 매직 스트링입니다. 명시적인 상수로 추출하면 유지보수성이 향상됩니다.+// 상수 파일 또는 이 파일 상단에 추가 +export const APP_STORE_LINK_TOKEN = 'APP_STORE_LINK'; // bannerData.ts에서 - linkTo: 'APP_STORE_LINK', + linkTo: APP_STORE_LINK_TOKEN,frontend/src/pages/MainPage/components/Banner/Banner.tsx (1)
51-59: 플랫폼 감지 로직이 중복되어 있습니다.라인 24와 56에서 동일한 iOS 감지 로직이 반복됩니다. 또한
getAppStoreLink()와 플랫폼 추적의 로직이 분리되어 있어 향후 불일치가 발생할 수 있습니다.플랫폼 감지를 통합하는 것을 권장합니다:
+const getPlatform = (): 'ios' | 'android' => { + const userAgent = navigator.userAgent.toLowerCase(); + if (/iphone|ipad|ipod/.test(userAgent)) return 'ios'; + if (/macintosh/.test(userAgent) && navigator.maxTouchPoints > 1) return 'ios'; + return 'android'; +}; + const getAppStoreLink = (): string => { - const userAgent = navigator.userAgent.toLowerCase(); - - if (/iphone|ipad|ipod|macintosh/.test(userAgent)) { - return APP_STORE_LINKS.ios; - } - if (/android/.test(userAgent)) { - return APP_STORE_LINKS.android; - } - return APP_STORE_LINKS.default; + return APP_STORE_LINKS[getPlatform()]; }; // handleBannerClick 내부 - platform: /iphone|ipad|ipod|macintosh/.test(navigator.userAgent.toLowerCase()) ? 'ios' : 'android', + platform: getPlatform(),
📜 Review details
Configuration used: Organization 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.
📒 Files selected for processing (3)
frontend/src/constants/eventName.ts(1 hunks)frontend/src/pages/MainPage/components/Banner/Banner.tsx(3 hunks)frontend/src/pages/MainPage/components/Banner/bannerData.ts(2 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
frontend/**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (frontend/.cursorrules)
frontend/**/*.{ts,tsx,js,jsx}: Replace magic numbers with named constants for clarity
Replace complex/nested ternaries withif/elseor IIFEs for readability
Assign complex boolean conditions to named variables for explicit meaning
Avoid hidden side effects; functions should only perform actions implied by their signature (Single Responsibility Principle)
Use unique and descriptive names for custom wrappers/functions to avoid ambiguity
Define constants near related logic or ensure names link them clearly to avoid silent failures
Break down broad state management into smaller, focused hooks/contexts to reduce coupling
Files:
frontend/src/constants/eventName.tsfrontend/src/pages/MainPage/components/Banner/bannerData.tsfrontend/src/pages/MainPage/components/Banner/Banner.tsx
frontend/**/*.{ts,tsx}
📄 CodeRabbit inference engine (frontend/.cursorrules)
Use consistent return types for similar functions/hooks
Files:
frontend/src/constants/eventName.tsfrontend/src/pages/MainPage/components/Banner/bannerData.tsfrontend/src/pages/MainPage/components/Banner/Banner.tsx
frontend/**/*.{tsx,jsx}
📄 CodeRabbit inference engine (frontend/.cursorrules)
frontend/**/*.{tsx,jsx}: Abstract complex logic/interactions into dedicated 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 when using form libraries like react-hook-form
Use Component Composition instead of Props Drilling to reduce coupling
Files:
frontend/src/pages/MainPage/components/Banner/Banner.tsx
🧬 Code graph analysis (1)
frontend/src/pages/MainPage/components/Banner/Banner.tsx (1)
frontend/src/constants/eventName.ts (1)
USER_EVENT(1-36)
🔇 Additional comments (2)
frontend/src/pages/MainPage/components/Banner/Banner.tsx (1)
89-101: 배너 클릭 핸들러 통합이 잘 되어 있습니다.
handleBannerClick에 배너 메타데이터(bannerId,bannerName,linkTo)를 전달하는 방식이 깔끔하고, 이벤트 추적과 내비게이션 로직이 적절히 분리되어 있습니다.frontend/src/constants/eventName.ts (1)
5-9: 새 배너 이벤트 상수가 적절하게 추가되었습니다.새 이벤트 상수들(
BANNER_CLICKED,APP_DOWNLOAD_BANNER_CLICKED)이 기존 네이밍 컨벤션을 잘 따르고 있습니다.참고: 라인 8-9의 불필요한 공백을 정리할 수 있습니다.
- 악성 링크 테스트 4개 → 1개 (parameterized) - 외부 링크 테스트 3개 → 1개 (parameterized)
#️⃣연관된 이슈
📝작업 내용
앱 릴리즈 배너 클릭 시 사용자의 OS에 따라 적절한 스토어로 이동하도록 구현했습니다.
1. 앱 릴리즈 배너 추가
2. OS별 스토어 분기 처리
user-agent기반으로 iOS/Android 판별하는 유틸함수 추가Banner.tsx내부에 두었습니다.3. useNavigator 보안 강화
javascript://, data://등 위험한 프로토콜 차단http://, https://, itms-apps://4. 테스트 추가
5. 로깅 추가
중점적으로 리뷰받고 싶은 부분(선택)
논의하고 싶은 부분(선택)
🫡 참고사항
Summary by CodeRabbit
새로운 기능
개선사항
업데이트
테스트
✏️ Tip: You can customize this high-level summary in your review settings.