Conversation
[feat] 앱은 부스클릭시 이동되지않게 변경
[feature] 배너 api 연동
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Warning
|
| 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
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.
Comment @coderabbitai help to get the list of available commands and usage tips.
✅ UI 변경사항 없음
전체 56개 스토리 · 22개 컴포넌트 |
There was a problem hiding this comment.
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:16과frontend/src/apis/club.ts:24는new 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
📒 Files selected for processing (7)
.gitignorefrontend/src/apis/banner.tsfrontend/src/constants/queryKeys.tsfrontend/src/hooks/Queries/useBanner.tsfrontend/src/pages/FestivalPage/components/BoothMapSection/BoothMapSection.tsxfrontend/src/pages/MainPage/components/Banner/Banner.stories.tsxfrontend/src/pages/MainPage/components/Banner/Banner.tsx
💤 Files with no reviewable changes (1)
- frontend/src/pages/MainPage/components/Banner/Banner.stories.tsx
| 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}`); | ||
| } |
There was a problem hiding this comment.
인앱 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.
| 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.
🚀 릴리즈 PR
📦 버전 정보
💾 BE/💻 FE🚨 MAJOR/➕ MINOR/🔧 PATCHvX.Y.Z📖 버전 라벨 선택 가이드 (Semantic Versioning)
🚨 MAJORv1.0.0→v2.0.0➕ MINORv1.0.0→v1.1.0🔧 PATCHv1.0.0→v1.0.1📋 포함된 변경사항
Summary by CodeRabbit
릴리스 노트
새로운 기능
개선사항