Skip to content

[release] FE#1332

Merged
seongwon030 merged 12 commits intomainfrom
develop-fe
Mar 11, 2026
Merged

[release] FE#1332
seongwon030 merged 12 commits intomainfrom
develop-fe

Conversation

@seongwon030
Copy link
Copy Markdown
Member

@seongwon030 seongwon030 commented Mar 11, 2026

🚀 릴리즈 PR

📦 버전 정보

항목 내용
서비스 💾 BE / 💻 FE
Bump 타입 🚨 MAJOR / ➕ MINOR / 🔧 PATCH
예상 버전 vX.Y.Z

⚠️ 반드시 라벨을 지정해주세요: 서비스 라벨(💾 BE, 💻 FE)과 버전 라벨(🚨 MAJOR, ➕ MINOR, 🔧 PATCH)이 없으면 태그가 생성되지 않습니다.

📖 버전 라벨 선택 가이드 (Semantic Versioning)
라벨 버전 변화 선택 기준 예시
🚨 MAJOR v1.0.0v2.0.0 기존 API/기능이 호환되지 않는 변경 API 엔드포인트 삭제/변경, 요청/응답 스펙 변경, DB 스키마 대규모 변경
➕ MINOR v1.0.0v1.1.0 기존 기능은 유지하면서 새 기능 추가 새 API 엔드포인트 추가, 새 기능 도입, 기존 API에 선택적 필드 추가
🔧 PATCH v1.0.0v1.0.1 기능 변경 없이 버그 수정/내부 개선 버그 수정, 성능 개선, 리팩토링, 문서 수정

📋 포함된 변경사항

이번 릴리즈에 포함된 주요 변경사항을 요약합니다.

Summary by CodeRabbit

릴리스 노트

  • 새로운 기능

    • 배너 컴포넌트가 이제 API에서 동적으로 배너 데이터를 가져옵니다. 기기 유형(웹/모바일)에 따라 최적화된 배너가 표시됩니다.
  • 개선사항

    • 배너 로딩 실패 시 로컬 데이터를 대체로 사용하여 안정성을 향상시켰습니다.
    • 부스 맵에서의 링크 네비게이션 로직을 개선했습니다.

@seongwon030 seongwon030 self-assigned this Mar 11, 2026
@seongwon030 seongwon030 added 💻 FE Frontend 📈 release 릴리즈 배포 🔧 PATCH Patch 릴리즈 labels Mar 11, 2026
@vercel
Copy link
Copy Markdown

vercel bot commented Mar 11, 2026

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

Project Deployment Actions Updated (UTC)
moadong Ready Ready Preview, Comment Mar 11, 2026 1:01am

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 11, 2026

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

배너 데이터를 API로부터 동적으로 가져오는 새로운 시스템을 도입합니다. 배너 타입별 API 엔드포인트, React Query 훅, 쿼리 키를 추가하고 기존 정적 배너 컴포넌트를 API 기반으로 리팩토링합니다. BoothMapSection의 네비게이션 로직도 수정합니다.

Changes

Cohort / File(s) Summary
Banner API Layer
frontend/src/apis/banner.ts, frontend/src/constants/queryKeys.ts, frontend/src/hooks/Queries/useBanner.ts
신규 배너 API 모듈 추가: BannerType('WEB' | 'APP_HOME' | 'WEB_MOBILE'), Banner 인터페이스, getBanners API 함수, 쿼리 키 정의, 24시간 캐싱 설정의 useGetBanners 훅.
Banner Component
frontend/src/pages/MainPage/components/Banner/Banner.tsx
배너 데이터 소스를 정적 데이터에서 useGetBanners API로 변경. 로딩/폴백 로직 추가. 새로운 배너 데이터 형식(imageUrl, linkTo, alt) 적용. Swiper 슬라이드, 클릭 핸들링, 페이지네이션을 동적 배너로 업데이트.
Storybook 제거
frontend/src/pages/MainPage/components/Banner/Banner.stories.tsx
배너 컴포넌트 스토리북 파일 삭제 (Desktop/Mobile 스토리 제거).
Navigation Logic
frontend/src/pages/FestivalPage/components/BoothMapSection/BoothMapSection.tsx
WebView 내부 조건 확인 후 부스 링크가 있으면 /clubDetail/{link}로 일관되게 네비게이션하도록 수정.
Configuration
.gitignore
dailyNote/ 디렉토리 추가.

Sequence Diagram(s)

sequenceDiagram
    participant Component as Banner Component
    participant Hook as useGetBanners Hook
    participant API as bannerApi
    participant Cache as React Query Cache
    participant Server as Backend API

    Component->>Hook: useGetBanners(bannerType)
    Hook->>Cache: Check queryKey<br/>(banner.list[type])
    
    alt Cache Miss or Stale
        Cache-->>Hook: No cached data
        Hook->>API: getBanners(type)
        API->>Server: GET /api/banner?type={type}
        Server-->>API: { statuscode, message,<br/>images: Banner[] }
        API-->>Hook: images array
        Hook->>Cache: Store with 24h staleTime
    else Cache Hit
        Cache-->>Hook: Return cached banners
    end
    
    Hook-->>Component: UseQuery result<br/>(data, loading, error)
    Component->>Component: Render with displayBanners<br/>or fallback BANNERS
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~35 minutes

Possibly related PRs

  • PR #1331: 동일한 배너 API 모듈(banner.ts, queryKeys.banner, useGetBanners 훅) 추가 및 Banner.tsx 리팩토링과 스토리 제거 작업이 정확히 일치합니다.
  • PR #1316: BoothMapSection.tsx의 동일한 onClick 로직에서 WebView 내부 조건 확인 및 /clubDetail/{link} 네비게이션 통일화 작업이 일치합니다.
  • PR #858: 배너 컴포넌트(Banner.tsx) 및 배너 데이터 소스 변경이 직접 관련됩니다.

Suggested reviewers

  • lepitaaar
  • oesnuj
  • suhyun113
🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Title check ❓ Inconclusive PR 제목 '[release] FE'는 매우 일반적이고 모호하며, 실제 변경 사항의 핵심을 명확하게 설명하지 못합니다. 배너 API 통합 및 UI 개선 등 주요 변경 사항을 구체적으로 반영하는 더 명확한 제목으로 변경하십시오. 예: '[release] Banner API integration and refactoring (FE)'
✅ 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.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 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.

@github-actions
Copy link
Copy Markdown

✅ UI 변경사항 없음

구분 링크
📖 Storybook https://67904e61c16daa99a63b44a7-ppyrjzobqx.chromatic.com/

전체 56개 스토리 · 22개 컴포넌트

Copy link
Copy Markdown
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: 1

🧹 Nitpick comments (1)
frontend/src/apis/banner.ts (1)

15-19: 런타임 일관성을 위해 문자열 기반 URL 구성으로 변경을 검토해 주세요.

new URL() 생성자는 절대 URL을 필수로 요구하므로, API_BASE_URL이 환경에 따라 상대 경로나 빈 문자열인 경우 런타임 에러가 발생합니다. 현재 frontend/src/apis/banner.ts:16frontend/src/apis/club.ts:24new URL()을 사용하고 있으나, frontend/src/apis/promotion.ts, image.ts, auth.ts, application.ts 등 대부분의 API 모듈들은 문자열 템플릿 방식(\${API_BASE_URL}/api/...``)으로 구성되어 있습니다. 일관성과 안정성을 위해 이 두 파일을 다른 API 모듈들과 동일한 문자열 기반 방식으로 통일하는 것을 권장합니다.

🔧 권장 형태
   getBanners: async (type: BannerType = 'WEB'): Promise<Banner[]> => {
-    const url = new URL(`${API_BASE_URL}/api/banner`);
-    url.searchParams.set('type', type);
-
-    const response = await fetch(url);
+    const response = await fetch(
+      `${API_BASE_URL}/api/banner?type=${encodeURIComponent(type)}`,
+    );
     const data = await handleResponse<{
       statuscode: string;
       message: string;
       images: Banner[];
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@frontend/src/apis/banner.ts` around lines 15 - 19, Replace the use of new
URL() in getBanners (and the similar function in club.ts) with a string-based
URL to avoid runtime errors when API_BASE_URL is relative or empty: build the
request URL using a template literal combining API_BASE_URL and the path (e.g.,
`${API_BASE_URL}/api/banner`) and append the type as a query parameter using
encodeURIComponent(BannerType) (e.g., `...?type=${encodeURIComponent(type)}`),
then call fetch with that string; update references to url.searchParams.set and
url.toString() accordingly so getBanners, API_BASE_URL and BannerType are used
consistently.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In
`@frontend/src/pages/FestivalPage/components/BoothMapSection/BoothMapSection.tsx`:
- Around line 667-674: The click handler currently bails out on in-app WebView
(isInAppWebView()) causing clicks to be no-ops; change it to route WebView users
to the WebView-specific club route instead of returning. In the BoothMapSection
onClick handler, when isInAppWebView() is true, call navigate to the WebView
route (e.g. `/webview/club/${booth.link}` or `/webview/club/@${booth.name}`
depending on whether booth.link is the id or you need the `@name` variant), and
still fire the USER_EVENT.FESTIVAL_BOOTH_CLICKED tracking before navigating.
Ensure booth.link/name existence is checked before building the WebView path.

---

Nitpick comments:
In `@frontend/src/apis/banner.ts`:
- Around line 15-19: Replace the use of new URL() in getBanners (and the similar
function in club.ts) with a string-based URL to avoid runtime errors when
API_BASE_URL is relative or empty: build the request URL using a template
literal combining API_BASE_URL and the path (e.g., `${API_BASE_URL}/api/banner`)
and append the type as a query parameter using encodeURIComponent(BannerType)
(e.g., `...?type=${encodeURIComponent(type)}`), then call fetch with that
string; update references to url.searchParams.set and url.toString() accordingly
so getBanners, API_BASE_URL and BannerType are used consistently.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: a59a8878-86c0-4905-bc2d-76f63b2150c5

📥 Commits

Reviewing files that changed from the base of the PR and between ab6ef67 and b77407b.

📒 Files selected for processing (7)
  • .gitignore
  • frontend/src/apis/banner.ts
  • frontend/src/constants/queryKeys.ts
  • frontend/src/hooks/Queries/useBanner.ts
  • frontend/src/pages/FestivalPage/components/BoothMapSection/BoothMapSection.tsx
  • frontend/src/pages/MainPage/components/Banner/Banner.stories.tsx
  • frontend/src/pages/MainPage/components/Banner/Banner.tsx
💤 Files with no reviewable changes (1)
  • frontend/src/pages/MainPage/components/Banner/Banner.stories.tsx

Comment on lines 667 to 674
onClick={() => {
if (isInAppWebView()) return;
if (booth.link) {
trackEvent(USER_EVENT.FESTIVAL_BOOTH_CLICKED, {
booth: booth.name,
});
if (isInAppWebView()) {
navigate(`/webview/club/${booth.link}`);
} else {
navigate(`/clubDetail/${booth.link}`);
}
navigate(`/clubDetail/${booth.link}`);
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

인앱 WebView에서 동아리 상세 진입이 완전히 막힙니다.

Line 668에서 바로 return 하면서 앱 사용자는 부스 클릭이 전부 no-op이 됩니다. frontend/src/App.tsx:88-102에는 아직 /webview/club/:clubId/webview/club/@:clubName 라우트가 살아 있어서, 여기서는 차단보다 WebView 전용 경로로 보내는 쪽이 맞아 보입니다.

🔧 제안 수정안
                     onClick={() => {
-                      if (isInAppWebView()) return;
                       if (booth.link) {
                         trackEvent(USER_EVENT.FESTIVAL_BOOTH_CLICKED, {
                           booth: booth.name,
                         });
-                        navigate(`/clubDetail/${booth.link}`);
+                        navigate(
+                          isInAppWebView()
+                            ? `/webview/club/${booth.link}`
+                            : `/clubDetail/${booth.link}`,
+                        );
                       }
                     }}
📝 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.

Suggested change
onClick={() => {
if (isInAppWebView()) return;
if (booth.link) {
trackEvent(USER_EVENT.FESTIVAL_BOOTH_CLICKED, {
booth: booth.name,
});
if (isInAppWebView()) {
navigate(`/webview/club/${booth.link}`);
} else {
navigate(`/clubDetail/${booth.link}`);
}
navigate(`/clubDetail/${booth.link}`);
}
onClick={() => {
if (booth.link) {
trackEvent(USER_EVENT.FESTIVAL_BOOTH_CLICKED, {
booth: booth.name,
});
navigate(
isInAppWebView()
? `/webview/club/${booth.link}`
: `/clubDetail/${booth.link}`,
);
}
}}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@frontend/src/pages/FestivalPage/components/BoothMapSection/BoothMapSection.tsx`
around lines 667 - 674, The click handler currently bails out on in-app WebView
(isInAppWebView()) causing clicks to be no-ops; change it to route WebView users
to the WebView-specific club route instead of returning. In the BoothMapSection
onClick handler, when isInAppWebView() is true, call navigate to the WebView
route (e.g. `/webview/club/${booth.link}` or `/webview/club/@${booth.name}`
depending on whether booth.link is the id or you need the `@name` variant), and
still fire the USER_EVENT.FESTIVAL_BOOTH_CLICKED tracking before navigating.
Ensure booth.link/name existence is checked before building the WebView path.

Copy link
Copy Markdown
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.

수고하셧읍니다

@seongwon030 seongwon030 merged commit 1e2b61f into main Mar 11, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

💻 FE Frontend 🔧 PATCH Patch 릴리즈 📈 release 릴리즈 배포

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants