Skip to content

Comments

[release] FE v1.1.8#939

Merged
seongwon030 merged 18 commits intomainfrom
develop-fe
Dec 19, 2025
Merged

[release] FE v1.1.8#939
seongwon030 merged 18 commits intomainfrom
develop-fe

Conversation

@seongwon030
Copy link
Member

@seongwon030 seongwon030 commented Dec 17, 2025

#️⃣연관된 이슈

ex) #이슈번호, #이슈번호

📝작업 내용

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

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

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

ex) 메서드 XXX의 이름을 더 잘 짓고 싶은데 혹시 좋은 명칭이 있을까요?

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

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

🫡 참고사항

Summary by CodeRabbit

릴리스 노트

  • 버그 수정

    • 계정 관리 탭에서 회원탈퇴 메뉴 항목이 제거되었습니다.
  • UI 개선

    • 중앙동아리 탭 레이블이 "부경대학교 중앙동아리"로 업데이트되었습니다.
  • 신규 기능

    • 앱 출시 배너가 메인에 추가되어 앱 다운로드 링크(기기별 스토어로 이동)를 제공합니다.
    • 배너 클릭 시 관련 이벤트가 기록됩니다.
  • 동작 변경

    • 외부 링크는 새 탭 대신 현재 창에서 이동하며, 위험한 프로토콜은 차단됩니다.

✏️ Tip: You can customize this high-level summary in your review settings.

- useIsMobile 훅 삭제 (useDevice와 중복)
- 동일한 브레이크포인트(500px) 사용으로 기능 동일
- 회원탈퇴 탭 항목 삭제
- 관련 미구현 alert 로직 제거
…tion-MOA-414

[refactor] 중복된 디바이스 감지 훅을 통합한다
…tion-MOA-416

[feature] 회원 탈퇴 기능을 제거한다
[feature] 중앙동아리 문구에 학교명 추가
- 패치노트 배너 제거
- APP_STORE_LINKS 상수 추가 (iOS, Android, default)
- getAppStoreLink 함수로 user-agent 기반 OS 판별
- iOS: itms-apps 스키마로 App Store 연결
- Android/기타: Google Play Store 연결
- javascript, data, vbscript 프로토콜 차단으로 XSS 방지
- 허용 프로토콜 화이트리스트 방식으로 변경
- 빈 URL 처리 테스트
- 악성 프로토콜 차단 테스트 (javascript, data, vbscript)
- 외부 URL 이동 테스트 (https, http, itms-apps)
- 내부 페이지 이동 테스트
- Given-When-Then 패턴 주석 추가
- renderHook을 beforeEach로 공통화하여 중복 제거
- eventName에 BANNER_CLICKED, APP_DOWNLOAD_BANNER_CLICKED 이벤트 추가
- 배너 클릭 시 bannerId, bannerName, linkTo/platform 로깅
- user-agent 기반 iOS/Android 스토어 링크 분기
- 앱 다운로드 배너 데이터 추가
- 악성 링크 테스트 4개 → 1개 (parameterized)
- 외부 링크 테스트 3개 → 1개 (parameterized)
@seongwon030 seongwon030 self-assigned this Dec 17, 2025
@seongwon030 seongwon030 added 💻 FE Frontend 📈 release 릴리즈 배포 labels Dec 17, 2025
@vercel
Copy link

vercel bot commented Dec 17, 2025

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

Project Deployment Review Updated (UTC)
moadong Ready Ready Preview, Comment Dec 17, 2025 0:59am

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 17, 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

모바일 감지 훅을 useIsMobile에서 useDevice로 교체하고 관련 파일 삭제, 사이드바의 "회원탈퇴" 항목 제거, 메인 페이지 탭 레이블 교체, 배너 클릭 추적 및 앱스토어 리다이렉트 로직과 외부 링크 내비게이션 보안 강화가 추가되었습니다.

Changes

Cohort / File(s) 요약
훅 변경 및 삭제
frontend/src/hooks/useIsMobile.ts, frontend/src/hooks/useNavigator.ts, frontend/src/hooks/__tests__/useNavigator.test.ts
useIsMobile 파일 삭제. useNavigator 외부 링크 판정 및 리다이렉트를 window.location.href 사용으로 변경하고 javascript:, data:, vbscript: 프로토콜 차단 추가. useNavigator용 테스트 추가.
컴포넌트 - QuestionTitle
frontend/src/components/application/QuestionTitle/QuestionTitle.tsx
useIsMobile 사용을 useDevice로 교체; React 임포트에서 useEffect 제거(대신 useLayoutEffect, useRef 유지).
페이지 - AdminPage 사이드바
frontend/src/pages/AdminPage/components/SideBar/SideBar.tsx
"회원탈퇴" 메뉴 항목 및 관련 클릭 처리(alert 등) 제거.
페이지 - MainPage 탭 레이블
frontend/src/pages/MainPage/MainPage.tsx
탭 레이블 및 초기 활성 탭 값을 '중앙동아리'에서 '부경대학교 중앙동아리'로 변경.
배너 관련 변경
frontend/src/pages/MainPage/components/Banner/Banner.tsx, frontend/src/pages/MainPage/components/Banner/bannerData.ts
앱 다운로드 배너(이미지 및 id 추가) 삽입, 배너 클릭 핸들러 확장(배너 id/이름 파라미터, 앱스토어 링크 결정), 플랫폼 감지 및 Mixpanel 이벤트(APP_DOWNLOAD_BANNER_CLICKED, BANNER_CLICKED) 추적 추가. 기존 패치노트 배너 제거.
상수 - 이벤트명 추가
frontend/src/constants/eventName.ts
USER_EVENT에 BANNER_CLICKEDAPP_DOWNLOAD_BANNER_CLICKED 이벤트 키 추가.

Sequence Diagram(s)

mermaid
sequenceDiagram
autonumber
participant User as 사용자
participant Banner as Banner 컴포넌트
participant Track as Mixpanel (trackEvent)
participant NavHook as useNavigator
participant Browser as 브라우저 (window.location / 내비게이트)

User->>Banner: 배너 클릭 (bannerId, alt, linkTo)
Banner->>Track: trackEvent(BANNER_CLICKED or APP_DOWNLOAD_BANNER_CLICKED, meta)
alt linkTo == APP_STORE_LINK
    Banner->>Banner: getAppStoreLink() (UA 기반)
    Banner->>NavHook: navigateTo(storeLink)
else 외부 URL (http/https/itms-apps)
    Banner->>NavHook: navigateTo(externalUrl)
else 내부 경로
    Banner->>NavHook: navigateTo(internalPath)
end

NavHook->>NavHook: 검사 (차단 프로토콜? external?)
alt 차단 프로토콜 (javascript:, data:, vbscript:)
    NavHook-->>Browser: 아무 동작 안함 (차단)
else 외부 URL
    NavHook-->>Browser: window.location.href = url
else 내부 경로
    NavHook-->>Browser: useNavigate(path)
end

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25분

  • 혼합된 변경(훅 제거·대체, 내비게이션 보안 로직 변경, 분석 이벤트 추가, UI 레이블/아이템 변경, 테스트 추가)
  • 리뷰 시 집중할 점:
    • useDevice의 isMobile 동작이 기존 useIsMobile과 호환되는지 검증
    • useNavigator의 외부 URL 판정 및 프로토콜 차단이 모든 보안 케이스를 커버하는지 확인
    • Banner의 APP_STORE_LINK 처리 및 플랫폼 감지 로직(UA 기반)이 올바른지 검토
    • useNavigator 테스트가 브라우저 전역(window.location) 복원/모킹을 안전하게 수행하는지 확인

Possibly related PRs

Suggested reviewers

  • lepitaaar
  • Zepelown
  • suhyun113

Pre-merge checks and finishing touches

❌ Failed checks (1 inconclusive)
Check name Status Explanation Resolution
Title check ❓ Inconclusive PR 제목 '[release] FE v1.1.8'은 버전 릴리스를 나타내지만, 변경 내용의 구체적인 주요 기능을 설명하지 않습니다. 제목을 더 구체적으로 수정하여 주요 변경 사항을 명확히 하세요. 예: '[release] FE v1.1.8: useDevice 훅 전환 및 배너 기능 개선'
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
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 develop-fe

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.

@seongwon030 seongwon030 changed the title [release] v1.1.8 [release] FE v1.1.8 Dec 17, 2025
[feature] 앱 출시 배너를 추가한다
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

🧹 Nitpick comments (2)
frontend/src/pages/MainPage/components/Banner/bannerData.ts (1)

17-23: 매직 스트링 'APP_STORE_LINK' 사용 개선 제안

linkTo: 'APP_STORE_LINK'는 실제 URL이 아닌 특수 식별자로 사용되고 있어 혼란을 줄 수 있습니다. 타입 안정성과 명확성을 위해 별도 필드나 타입 유니온 사용을 고려해 주세요.

 interface BannerItem {
   id: string;
   desktopImage: string;
   mobileImage: string;
-  linkTo?: string;
+  linkTo?: string;
+  isAppStoreLink?: boolean;
   alt: string;
 }

 const BANNERS: BannerItem[] = [
   {
     id: 'app-release-december-2025',
     desktopImage: AppReleaseDesktopImage,
     mobileImage: AppReleaseMobileImage,
-    linkTo: 'APP_STORE_LINK',
+    isAppStoreLink: true,
     alt: '앱 다운로드 배너',
   },

코딩 가이드라인에 따라 매직 값 대신 명시적인 상수나 타입을 사용하는 것이 좋습니다.

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

48-64: 플랫폼 감지 로직 중복 - 리팩토링 권장

플랫폼 감지 로직이 getAppStoreLink() (Line 24-30)와 handleBannerClick (Line 56)에서 중복됩니다. 단일 함수로 추출하여 일관성을 유지하세요.

+const getPlatform = (): 'ios' | 'android' => {
+  const userAgent = navigator.userAgent.toLowerCase();
+  if (/iphone|ipad|ipod|macintosh/.test(userAgent)) {
+    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;
+  const platform = getPlatform();
+  return APP_STORE_LINKS[platform] ?? APP_STORE_LINKS.default;
 };

그리고 handleBannerClick에서:

       trackEvent(USER_EVENT.APP_DOWNLOAD_BANNER_CLICKED, {
         bannerId,
         bannerName,
-        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.

📥 Commits

Reviewing files that changed from the base of the PR and between 2978c99 and d14a323.

⛔ Files ignored due to path filters (2)
  • frontend/src/assets/images/banners/banner_desktop4.png is excluded by !**/*.png
  • frontend/src/assets/images/banners/banner_mobile4.png is excluded by !**/*.png
📒 Files selected for processing (5)
  • frontend/src/constants/eventName.ts (1 hunks)
  • frontend/src/hooks/__tests__/useNavigator.test.ts (1 hunks)
  • frontend/src/hooks/useNavigator.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 with if/else or 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.ts
  • frontend/src/hooks/__tests__/useNavigator.test.ts
  • frontend/src/hooks/useNavigator.ts
  • frontend/src/pages/MainPage/components/Banner/bannerData.ts
  • 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/constants/eventName.ts
  • frontend/src/hooks/__tests__/useNavigator.test.ts
  • frontend/src/hooks/useNavigator.ts
  • frontend/src/pages/MainPage/components/Banner/bannerData.ts
  • frontend/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
🧠 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
🧬 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 (6)
frontend/src/constants/eventName.ts (1)

5-9: LGTM!

새로운 배너 이벤트 상수들이 기존 컨벤션을 잘 따르고 있습니다. Line 8-9에 불필요한 빈 줄이 있지만 사소한 부분입니다.

frontend/src/hooks/useNavigator.ts (2)

12-13: 보안 강화 - 잘 구현되었습니다.

javascript:, data:, vbscript: 프로토콜을 대소문자 구분 없이 차단하여 XSS 공격 벡터를 효과적으로 방지합니다.


15-18: 외부 링크 동작 변경 확인 필요

window.open 대신 window.location.href를 사용하여 외부 링크가 새 탭이 아닌 현재 탭에서 열리도록 변경되었습니다. 앱스토어 링크(itms-apps)의 경우 이 동작이 적합하지만, http/https 외부 링크도 동일하게 현재 탭에서 열리게 됩니다.

이것이 의도된 UX 변경인지 확인해 주세요. 만약 일반 외부 링크는 새 탭에서 열어야 한다면 프로토콜별로 분기 처리가 필요합니다.

frontend/src/hooks/__tests__/useNavigator.test.ts (1)

1-104: LGTM! - 포괄적인 테스트 커버리지

테스트가 useNavigator 훅의 주요 시나리오를 잘 커버하고 있습니다:

  • 빈/공백 링크 처리
  • 악성 프로토콜 차단 (대소문자 포함)
  • 외부 URL 네비게이션 (http, https, itms-apps)
  • 내부 라우팅

window.location 모킹과 복원이 적절하게 처리되었습니다.

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

21-31: macintosh 사용자를 iOS 앱스토어로 리다이렉트하는 것이 적절한지 확인 필요

Mac 사용자(macintosh)를 iOS 앱스토어(itms-apps)로 리다이렉트합니다. Mac에서는 itms-apps 프로토콜이 제대로 동작하지 않을 수 있으며, 사용자 경험이 저하될 수 있습니다.

Mac 사용자에게는 웹 앱스토어 링크나 별도의 안내를 제공하는 것이 더 적절할 수 있습니다.


33-64: 배너 클릭 추적 및 앱스토어 링크 처리 - 잘 구현되었습니다.

Mixpanel 이벤트 추적과 플랫폼별 앱스토어 링크 처리가 적절하게 구현되었습니다. handleBannerClick이 배너 메타데이터(bannerId, bannerName)를 받아 추적에 활용하는 패턴이 좋습니다.

Copy link
Contributor

@lepitaaar lepitaaar 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
Member

@oesnuj oesnuj left a comment

Choose a reason for hiding this comment

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

🚀

@seongwon030 seongwon030 merged commit 34692b5 into main Dec 19, 2025
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

💻 FE Frontend 📈 release 릴리즈 배포

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants