diff --git a/com.twin.app.shoptime/src/components/GlobalPopup/GlobalPopup.jsx b/com.twin.app.shoptime/src/components/GlobalPopup/GlobalPopup.jsx
index e9627f02..96dc3849 100644
--- a/com.twin.app.shoptime/src/components/GlobalPopup/GlobalPopup.jsx
+++ b/com.twin.app.shoptime/src/components/GlobalPopup/GlobalPopup.jsx
@@ -18,6 +18,7 @@ import { setHidePopup } from '../../actions/commonActions';
import { getPopupConfig } from '../../constants/popupConfig';
import usePrevious from '../../hooks/usePrevious';
import TPopUp from '../TPopUp/TPopUp';
+import TopBannerPopup from '../../views/FeaturedBrandsPanel/TopBannerImage/TopBannerPopup';
// 커스텀 훅: 팝업 상태 관리
const useGlobalPopupState = () => {
@@ -128,9 +129,16 @@ const GlobalPopup = () => {
secondaryData
} = useGlobalPopupState();
+ const [imageDimensions, setImageDimensions] = React.useState({ width: 0, height: 0 });
+
const handlers = usePopupCloseHandlers();
const previousPopupVisible = usePrevious(popupVisible);
+ const handleImageLoad = useCallback((dimensions) => {
+ console.log("[GLOBAL-POPUP] Image dimensions received:", dimensions);
+ setImageDimensions(dimensions);
+ }, []);
+
// 현재 팝업 설정
const currentConfig = useMemo(() => {
if (!activePopup) return null;
@@ -214,6 +222,47 @@ const GlobalPopup = () => {
return null;
}
+ // TopBannerImagePopup 특수 처리
+ if (activePopup === 'topBannerImagePopup') {
+ // Figma 디자인 기반 고정 크기
+ // 너비: 1060px
+ // 높이: 헤더(110px) + 이미지(556px) + 푸터(138px) = 804px
+ const popupWidth = '1060px';
+ const popupHeight = '804px';
+
+ return (
+
+ );
+ }
+
// 설정이 없으면 기본 팝업도 렌더링하지 않음
if (!currentConfig) {
console.warn(`No configuration found for popup type: ${activePopup}`);
diff --git a/com.twin.app.shoptime/src/views/FeaturedBrandsPanel/Banner/Banner.jsx b/com.twin.app.shoptime/src/views/FeaturedBrandsPanel/Banner/Banner.jsx
index 66f5bc42..dfe9f9aa 100644
--- a/com.twin.app.shoptime/src/views/FeaturedBrandsPanel/Banner/Banner.jsx
+++ b/com.twin.app.shoptime/src/views/FeaturedBrandsPanel/Banner/Banner.jsx
@@ -26,11 +26,12 @@ export default memo(function Banner({
console.log("[FB-BANNER-COMP] isNBCU:", isNBCU);
console.log("[FB-BANNER-COMP] brandTopBannerInfo:", brandTopBannerInfo);
- // Top Banner 정보에서 필요한 필드 추출 (현재는 사용하지 않음)
+ // Top Banner 정보에서 필요한 필드 추출
const {
banrImgUrl, // 배너 이미지 URL
banrImgNm, // 배너 이미지 이름
pupBanrImgUrl, // 팝업 배너 이미지 URL
+ pupBanrImgNm, // 팝업 배너 이미지 이름
pupBanrTtl, // 팝업 배너 타이틀
banrNm // 배너 이름
} = brandTopBannerInfo || {};
@@ -76,6 +77,8 @@ export default memo(function Banner({
banrImgUrl={banrImgUrl}
banrImgNm={banrImgNm}
banrNm={banrNm}
+ pupBanrImgUrl={pupBanrImgUrl}
+ pupBanrImgNm={pupBanrImgNm}
spotlightId="nbcu-top-banner-image"
/>
)}
diff --git a/com.twin.app.shoptime/src/views/FeaturedBrandsPanel/TopBannerImage/TopBannerImage.jsx b/com.twin.app.shoptime/src/views/FeaturedBrandsPanel/TopBannerImage/TopBannerImage.jsx
index 742f4b52..af115f70 100644
--- a/com.twin.app.shoptime/src/views/FeaturedBrandsPanel/TopBannerImage/TopBannerImage.jsx
+++ b/com.twin.app.shoptime/src/views/FeaturedBrandsPanel/TopBannerImage/TopBannerImage.jsx
@@ -1,4 +1,6 @@
import React, { memo, useCallback, useState } from "react";
+import { useDispatch } from "react-redux";
+import { setShowPopup } from "../../../actions/commonActions";
import CustomImage from "../../../components/CustomImage/CustomImage";
import SpotlightContainerDecorator from "@enact/spotlight/SpotlightContainerDecorator";
import css from "./TopBannerImage.module.less";
@@ -8,16 +10,26 @@ const Container = SpotlightContainerDecorator(
"div"
);
-const TopBannerImage = memo(({ banrImgUrl, banrImgNm, banrNm, spotlightId }) => {
+const TopBannerImage = memo(({ banrImgUrl, banrImgNm, banrNm, pupBanrImgUrl, pupBanrImgNm, spotlightId }) => {
console.log("[TOP-BANNER-IMG] Rendering with URL:", banrImgUrl);
console.log("[TOP-BANNER-IMG] spotlightId:", spotlightId);
+ const dispatch = useDispatch();
const [imageDimensions, setImageDimensions] = useState({ width: 0, height: 0 });
const handleClick = useCallback(() => {
- console.log("[TOP-BANNER-IMG] Clicked");
- // 필요시 클릭 핸들러 로직 추가
- }, []);
+ console.log("[TOP-BANNER-IMG] Clicked - Opening popup");
+ if (pupBanrImgUrl) {
+ console.log("[TOP-BANNER-IMG] Dispatching topBannerImagePopup");
+ dispatch(setShowPopup({
+ activePopup: 'topBannerImagePopup',
+ data: {
+ pupBanrImgUrl,
+ pupBanrImgNm: pupBanrImgNm || banrImgNm || banrNm
+ }
+ }));
+ }
+ }, [dispatch, pupBanrImgUrl, pupBanrImgNm, banrImgNm, banrNm]);
const handleImageLoad = useCallback((e) => {
const img = e.target;
diff --git a/com.twin.app.shoptime/src/views/FeaturedBrandsPanel/TopBannerImage/TopBannerPopup.figma.jsx b/com.twin.app.shoptime/src/views/FeaturedBrandsPanel/TopBannerImage/TopBannerPopup.figma.jsx
new file mode 100644
index 00000000..f3f203eb
--- /dev/null
+++ b/com.twin.app.shoptime/src/views/FeaturedBrandsPanel/TopBannerImage/TopBannerPopup.figma.jsx
@@ -0,0 +1,13 @@
+
+
+
Wells Fargo Active Cash Credit Card
+
+
+

+
+
+
\ No newline at end of file
diff --git a/com.twin.app.shoptime/src/views/FeaturedBrandsPanel/TopBannerImage/TopBannerPopup.jsx b/com.twin.app.shoptime/src/views/FeaturedBrandsPanel/TopBannerImage/TopBannerPopup.jsx
new file mode 100644
index 00000000..ac228719
--- /dev/null
+++ b/com.twin.app.shoptime/src/views/FeaturedBrandsPanel/TopBannerImage/TopBannerPopup.jsx
@@ -0,0 +1,61 @@
+import React, { memo, useCallback, useState } from "react";
+import { useDispatch } from "react-redux";
+import { setHidePopup } from "../../../actions/commonActions";
+import css from "./TopBannerPopup.module.less";
+
+const TopBannerPopup = memo(({ title, imageUrl, imageAlt, onImageLoad }) => {
+ const dispatch = useDispatch();
+ const [imageDimensions, setImageDimensions] = useState({ width: 0, height: 0 });
+
+ const handleImageLoad = useCallback((e) => {
+ const img = e.target;
+ console.log("[TOP-BANNER-POPUP] Image loaded - dimensions:", img.naturalWidth, "x", img.naturalHeight);
+
+ const dimensions = {
+ width: img.naturalWidth,
+ height: img.naturalHeight
+ };
+
+ setImageDimensions(dimensions);
+
+ // 부모 컴포넌트에 크기 전달
+ if (onImageLoad) {
+ onImageLoad(dimensions);
+ }
+ }, [onImageLoad]);
+
+ const handleClose = useCallback(() => {
+ console.log("[TOP-BANNER-POPUP] Closing popup");
+ dispatch(setHidePopup());
+ }, [dispatch]);
+
+ return (
+
+ {/* Title Section */}
+
+
+ {/* Image Section */}
+
+

+
+
+ {/* Button Section */}
+
+
+
+
+ );
+});
+
+TopBannerPopup.displayName = "TopBannerPopup";
+
+export default TopBannerPopup;
diff --git a/com.twin.app.shoptime/src/views/FeaturedBrandsPanel/TopBannerImage/TopBannerPopup.module.less b/com.twin.app.shoptime/src/views/FeaturedBrandsPanel/TopBannerImage/TopBannerPopup.module.less
new file mode 100644
index 00000000..bc108b95
--- /dev/null
+++ b/com.twin.app.shoptime/src/views/FeaturedBrandsPanel/TopBannerImage/TopBannerPopup.module.less
@@ -0,0 +1,100 @@
+.container {
+ width: 100%;
+ height: 100%;
+ background: white;
+ overflow: hidden;
+ border-radius: 12px;
+ flex-direction: column;
+ justify-content: flex-start;
+ align-items: stretch;
+ display: flex;
+}
+
+// 헤더: 높이 110px (상단 마진 30 + 내용 50 + 하단 마진 30)
+.titleSection {
+ flex: 0 0 110px;
+ background: #E7EBEF;
+ padding-top: 30px;
+ padding-bottom: 30px;
+ padding-left: 30px;
+ padding-right: 30px;
+ justify-content: flex-start;
+ align-items: center;
+ gap: 15px;
+ display: flex;
+}
+
+.titleText {
+ flex: 1;
+ text-align: center;
+ color: black;
+ font-size: 42px;
+ font-family: 'LG Smart UI', sans-serif;
+ font-weight: 700;
+ line-height: 42px;
+ word-wrap: break-word;
+ word-break: break-word;
+}
+
+// 이미지: 높이 556px
+.imageSection {
+ flex: 0 0 556px;
+ justify-content: center;
+ align-items: center;
+ display: flex;
+ background: white;
+ overflow: hidden;
+}
+
+.popupImage {
+ width: 100%;
+ height: 100%;
+ object-fit: contain;
+}
+
+// 푸터: 높이 138px (상단 마진 30 + 버튼 78 + 하단 마진 30)
+.buttonSection {
+ flex: 0 0 138px;
+ padding-left: 60px;
+ padding-right: 60px;
+ padding-top: 30px;
+ padding-bottom: 30px;
+ justify-content: center;
+ align-items: center;
+ gap: 10px;
+ display: flex;
+}
+
+.closeButton {
+ width: 300px;
+ height: 78px;
+ background: #7A808D;
+ border-radius: 12px;
+ border: none;
+ justify-content: center;
+ align-items: center;
+ gap: 10px;
+ display: flex;
+ cursor: pointer;
+ transition: background-color 0.2s ease;
+
+ color: white;
+ font-size: 30px;
+ font-family: 'LG Smart UI', sans-serif;
+ font-weight: 700;
+ line-height: 30px;
+ text-align: center;
+
+ &:hover {
+ background: #6a7278;
+ }
+
+ &:focus {
+ outline: 2px solid #fff;
+ outline-offset: 2px;
+ }
+
+ &:active {
+ background: #5a6268;
+ }
+}