Skip to content

배너 API 연동#168

Merged
zionhann merged 7 commits intoHandongSF:mainfrom
zionhann:feat/integrate-banners-api
Mar 9, 2026
Merged

배너 API 연동#168
zionhann merged 7 commits intoHandongSF:mainfrom
zionhann:feat/integrate-banners-api

Conversation

@zionhann
Copy link
Copy Markdown
Member

@zionhann zionhann commented Mar 6, 2026

  • 관리자에서 홈 배너를 생성·수정·삭제·정렬할 수 있는 관리 화면을 추가했습니다

    운영자가 코드를 수정하지 않고 홈 배너를 관리할 수 있도록 전용 관리 화면과 API 연결을 붙였습니다. 목록에서 노출 여부를 바로 바꾸고 드래그로 순서를 조정할 수 있게 해 운영 작업 동선을 줄였습니다. 관리자 라우터와 사이드바까지 함께 연결해 실제 사용 흐름에서 바로 접근할 수 있게 했습니다.

  • 홈 캐러셀을 공개 배너 API 기반으로 전환했습니다

    홈 화면의 배너를 하드코딩 데이터가 아니라 서버에서 내려오는 공개 배너 목록으로 렌더링하도록 바꿨습니다. 로딩 중이거나 노출 가능한 배너가 없는 상황도 별도 UI로 처리해 첫 화면이 어색하게 비지 않도록 했습니다. 운영 변경이 배포 없이 즉시 반영되는 구조를 마련하려는 목적입니다.

  • 배너 링크 보안과 관리자 상호작용을 보강했습니다

    배너 이동 URL은 저장 시점과 렌더링 시점 모두에서 http/https만 허용하도록 검증해 잘못된 링크가 노출되지 않게 했습니다. 관리자 목록은 순서 변경 직후 UI가 먼저 반영되고 실패 시 복구되도록 조정해 작업 피드백을 빠르게 확인할 수 있습니다. 삭제 확인은 기본 confirm 대신 모달로 바꾸고 홈 배너 alt 텍스트를 라벨 기반으로 개선해 접근성을 보완했습니다.

@gemini-code-assist
Copy link
Copy Markdown

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

이 PR은 관리자가 홈 배너를 효율적으로 관리할 수 있도록 새로운 배너 관리 시스템을 도입합니다. 관리자는 별도의 코드 배포 없이 배너의 생성, 수정, 삭제, 노출 상태 변경 및 순서 조정을 직접 수행할 수 있습니다. 또한, 홈 화면의 캐러셀은 이제 서버에서 동적으로 배너 데이터를 가져와 표시함으로써 운영 유연성을 크게 향상시킵니다. 이를 통해 운영 변경 사항이 즉시 홈 화면에 반영될 수 있는 구조를 구축했습니다.

Highlights

  • 관리자 배너 관리 페이지 추가: 관리자가 홈 배너를 코드 수정 없이 생성, 수정, 삭제, 노출 전환, 순서 변경할 수 있는 전용 관리 페이지가 추가되었습니다.
  • 홈 캐러셀 API 연동: 기존 하드코딩된 홈 배너 목록을 제거하고 서버에서 제공하는 공개 배너 API를 기반으로 캐러셀이 동적으로 렌더링되도록 변경되었습니다.
  • 라우터 및 사이드바 통합: 새로운 배너 관리 페이지에 대한 라우터 경로와 관리자 사이드바 메뉴가 추가되어 실제 접근 동선이 마련되었습니다.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Changelog
  • src/apis/banner.ts
    • 공개 배너 조회, 관리자 배너 조회, 생성, 수정, 삭제, 순서 변경을 위한 API 함수가 추가되었습니다.
  • src/components/ARouter.tsx
    • 관리자 배너 관리 페이지(ManageBanner)로 연결되는 새로운 라우터 경로가 추가되었습니다.
  • src/components/SideBar.tsx
    • 관리자 사이드바에 '배너 관리' 메뉴 항목이 추가되었습니다.
  • src/const/paths.ts
    • 관리자 배너 관리 페이지의 경로 상수가 정의되었습니다.
  • src/interface/banner.ts
    • 공개 배너, 관리자 배너, 배너 폼 페이로드에 대한 TypeScript 인터페이스가 정의되었습니다.
  • src/pages/Admin/ManageBanner/Page.tsx
    • 관리자 배너 관리 페이지가 추가되었으며, 배너 생성, 수정, 삭제, 노출 상태 변경 및 드래그 앤 드롭 순서 변경 기능을 제공합니다.
  • src/pages/Home/Page.tsx
    • 홈 페이지의 캐러셀이 하드코딩된 슬라이드 대신 공개 배너 API에서 데이터를 가져와 표시하도록 변경되었습니다.
    • 배너 로딩 중 또는 배너가 없는 경우를 처리하는 UI가 추가되었습니다.
  • src/pages/Home/components/EmblaCarousel.tsx
    • 하드코딩된 캐러셀 슬라이드 데이터가 제거되었고, 캐러셀 옵션을 동적으로 전달받을 수 있도록 수정되었습니다.
Activity
  • 이 PR에는 아직 인간 활동(댓글, 리뷰 등)이 없습니다.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 3bef495b98

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/pages/Home/Page.tsx Outdated
Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces banner management functionality to the admin page and integrates home screen banners with the API. While the overall implementation is solid, particularly the clean use of react-query and dnd-kit for complex UI elements like drag-and-drop reordering and inline editing on the admin page, a critical security vulnerability was identified. The application is susceptible to Stored Cross-Site Scripting (XSS) because banner redirect URLs from the API are rendered directly into the href attribute of anchor tags without proper protocol validation. This could allow a malicious or compromised administrator to execute arbitrary JavaScript in users' browsers. I've also left specific review comments regarding UX improvements and accessibility enhancements.

Comment thread src/pages/Admin/ManageBanner/Page.tsx
Comment thread src/pages/Home/Page.tsx Outdated
Comment thread src/pages/Admin/ManageBanner/Page.tsx Outdated
Comment thread src/pages/Home/Page.tsx Outdated
Address PR review feedback so banner links only use safe external URLs and the banner admin flow feels more responsive and consistent for operators.
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Mar 9, 2026

📝 Walkthrough

Walkthrough

This PR introduces a banner management system with API clients, TypeScript types, an admin page for CRUD and reordering operations, integration with the home page to display public banners, and supporting utilities for URL validation and alt text generation.

Changes

Cohort / File(s) Summary
Banner Types & Interfaces
src/interface/banner.ts
Introduces three new TypeScript interfaces: PublicBanner with id, imageUrl, and optional label/redirectUrl; AdminBanner extending PublicBanner with required label, active, and displayOrder; BannerFormPayload for form submission with optional fields.
Banner API Module
src/apis/banner.ts
Adds six API methods for banner operations: getPublicBanners, getAdminBanners, createAdminBanner, updateAdminBanner, deleteAdminBanner, and reorderAdminBanners. Includes internal buildBannerFormData helper for multipart form data construction.
Banner Utilities
src/utils/banner.ts
Introduces getSafeExternalUrl for validating and parsing redirect URLs with protocol validation, and getBannerAltText for generating accessible alt text from banner label or redirect URL hostname.
Admin Banner Management Page
src/pages/Admin/ManageBanner/Page.tsx
Comprehensive new admin page implementing draggable banner list, inline editor forms for create/edit operations with image upload, active state toggling, deletion confirmation, and real-time API integration via react-query.
Home Page Banner Integration
src/pages/Home/Page.tsx
Integrates dynamic public banner fetching via useQuery, renders banners with safe external links and accessible alt text, includes loading and empty states, removes reliance on static carousel slides.
Carousel Component Update
src/pages/Home/components/EmblaCarousel.tsx
Removes exported CAROUSEL_SLIDES constant and simplifies hook usage to rely solely on passed-in children props and options parameter for dynamic content rendering.
Navigation & Routing
src/components/ARouter.tsx, src/components/SideBar.tsx, src/const/paths.ts
Adds lazy-loaded admin route for manageBanner, new sidebar navigation item "배너 관리" with Image icon restricted to ADMIN role, and new paths.admin.manageBanner route path constant.
🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title '배너 API 연동' accurately summarizes the main objective of integrating the banners API across the application.
Description check ✅ Passed The description clearly relates to the changeset, detailing banner management features, home carousel conversion, security improvements, and admin interactions.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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.

@zionhann zionhann changed the title 배너 관리 페이지와 홈 배너 API 연동 배너 관리 화면과 홈 배너 API 연동 및 안정화 Mar 9, 2026
zionhann added 3 commits March 9, 2026 11:52
Keep browser and Playwright Node contexts aligned so CI can boot the app and tests even when workflow-level VITE variables are unset or blank.
Ensure Playwright setup workers populate base URL variables before importing user login helpers so CI auth bootstrap does not fail with empty workflow env values.
Provide a safe default backend base URL so Playwright auth setup can reach the API even when workflow-level VITE variables are blank in CI.
Copy link
Copy Markdown

@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: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/components/ARouter.tsx`:
- Around line 115-120: The admin route registration for paths.admin.manageBanner
in ARouter.tsx currently exposes the page directly; wrap the lazy-loaded
Component with the existing PrivateRoute (or an Admin-only gate) so only
authenticated/admin users can access it: import and use PrivateRoute (or
AdminRoute) to guard the Component returned in the lazy loader (the Module
default exported Component) for the manageBanner route; ensure the guard checks
admin role/permissions consistent with PrivateRoute's API and mirrors how other
admin routes are protected.

In `@src/pages/Admin/ManageBanner/Page.tsx`:
- Around line 571-579: The UI currently treats a failed getAdminBanners fetch as
an empty list because the render branch checks only displayBanners.length and
editingRowId, causing the NoData component to show on load errors; add an
explicit fetch/error state (e.g., isLoading and loadError) driven by
getAdminBanners in the component that populates displayBanners, and change the
conditional around the NoData render to only show when loadError is falsy and
displayBanners.length === 0 (otherwise render an error message or retry action
when loadError is truthy). Update the data-loading code path that calls
getAdminBanners to set loadError on failure and ensure startCreate remains
available as the action for real empty lists while an error UI offers retry that
re-invokes getAdminBanners.

In `@src/pages/Home/Page.tsx`:
- Around line 51-93: The current JSX treats any non-loading falsy banners as an
empty-state, which hides load failures; update the render logic in Page.tsx to
distinguish an explicit banner load error from a true empty array by introducing
or using an existing error flag (e.g., bannerError) alongside isBannerLoading
and banners, and change the conditional that now uses "isBannerLoading ? ... :
banners && banners.length > 0 ? ..." so that when bannerError is truthy you
render an error state (or a retry UI) instead of NoData; ensure components
referenced (WaveLoading, EmblaCarousel, NoData) and helpers (getSafeExternalUrl,
getBannerAltText) remain unchanged and keep key usage on banner.id.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 49a1faaf-3f64-441e-b234-0805a019bfb9

📥 Commits

Reviewing files that changed from the base of the PR and between 33ed485 and 67ac532.

📒 Files selected for processing (9)
  • src/apis/banner.ts
  • src/components/ARouter.tsx
  • src/components/SideBar.tsx
  • src/const/paths.ts
  • src/interface/banner.ts
  • src/pages/Admin/ManageBanner/Page.tsx
  • src/pages/Home/Page.tsx
  • src/pages/Home/components/EmblaCarousel.tsx
  • src/utils/banner.ts

Comment thread src/components/ARouter.tsx
Comment thread src/pages/Admin/ManageBanner/Page.tsx Outdated
Comment thread src/pages/Home/Page.tsx
zionhann added 2 commits March 9, 2026 12:01
Keep the banner review fixes intact while dropping the follow-up changes that were added only to chase the unrelated E2E workflow failures.
Keep the new banner surfaces safe for operators and users by protecting the admin route and separating true empty states from failed banner fetches.
@zionhann zionhann changed the title 배너 관리 화면과 홈 배너 API 연동 및 안정화 배너 API 연동 Mar 9, 2026
@zionhann zionhann merged commit 511d5ec into HandongSF:main Mar 9, 2026
1 of 2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants