[251210] feat: featuredBrandTopBanner API추가 , nbcu bg추가

🕐 커밋 시간: 2025. 12. 10. 13:02:33

📊 변경 통계:
  • 총 파일: 10개
  • 추가: +100줄
  • 삭제: -4줄

📁 추가된 파일:
  + com.twin.app.shoptime/assets/images/bg/nbcu_new.png

📝 수정된 파일:
  ~ com.twin.app.shoptime/src/actions/actionTypes.js
  ~ com.twin.app.shoptime/src/actions/brandActions.js
  ~ com.twin.app.shoptime/src/api/apiConfig.js
  ~ com.twin.app.shoptime/src/reducers/brandReducer.js
  ~ com.twin.app.shoptime/src/views/DetailPanel/components/DetailPanelBackground/DetailPanelBackground.jsx
  ~ com.twin.app.shoptime/src/views/DetailPanel/components/DetailPanelBackground/DetailPanelBackground.v2.jsx
  ~ com.twin.app.shoptime/src/views/FeaturedBrandsPanel/Banner/Banner.jsx
  ~ com.twin.app.shoptime/src/views/FeaturedBrandsPanel/FeaturedBrandsPanel.jsx
  ~ com.twin.app.shoptime/src/views/HomePanel/HomePanel.jsx

🔧 주요 변경 내용:
  • 타입 시스템 안정성 강화
  • 핵심 비즈니스 로직 개선
  • API 서비스 레이어 개선
  • UI 컴포넌트 아키텍처 개선
  • 소규모 기능 개선
  • 모듈 구조 개선
This commit is contained in:
2025-12-10 13:02:34 +09:00
parent db7bc4b2ed
commit d6656848a2
10 changed files with 100 additions and 4 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 MiB

View File

@@ -131,6 +131,7 @@ export const types = {
GET_BRAND_SHOWROOM: 'GET_BRAND_SHOWROOM',
GET_BRAND_RECENTLY_AIRED: 'GET_BRAND_RECENTLY_AIRED',
GET_BRAND_SHOP_BY_SHOW: 'GET_BRAND_SHOP_BY_SHOW',
GET_BRAND_TOP_BANNER: 'GET_BRAND_TOP_BANNER',
SET_BRAND_LIVE_CHANNEL_UPCOMING: 'SET_BRAND_LIVE_CHANNEL_UPCOMING',
SET_BRAND_CHAN_INFO: 'SET_BRAND_CHAN_INFO',
RESET_BRAND_STATE: 'RESET_BRAND_STATE',

View File

@@ -428,6 +428,43 @@ export const getBrandShopByShow = (props) => (dispatch, getState) => {
TAxios(dispatch, getState, 'get', URLS.GET_BRAND_SHOP_BY_SHOW, params, {}, onSuccess, onFail);
};
// Featured Brands Top Banner 정보 조회 IF-LGSP-377 (NBCU 전용)
export const getBrandTopBanner = (props) => (dispatch, getState) => {
const { patnrId } = props;
console.log("[getBrandTopBanner] Called - patnrId:", patnrId);
// NBCU(patnrId: 21)가 아니면 호출하지 않음
if (patnrId !== 21) {
console.log("[getBrandTopBanner] Skip - patnrId is not 21 (NBCU)");
return;
}
dispatch(changeAppStatus({ showLoadingPanel: { show: true, type: 'wait' } }));
const onSuccess = (response) => {
console.log("[getBrandTopBanner] onSuccess - patnrId:", patnrId, "data:", response.data.data);
console.log("[getBrandTopBanner] brandTopBannerInfo:", response.data.data.brandTopBannerInfo);
dispatch({
type: types.GET_BRAND_TOP_BANNER,
payload: {
data: response.data.data,
},
});
dispatch(changeAppStatus({ showLoadingPanel: { show: false } }));
};
const onFail = (error) => {
console.log("[getBrandTopBanner] onFail - patnrId:", patnrId, "error:", error);
derror('getBrandTopBanner onFail ', error);
dispatch(changeAppStatus({ showLoadingPanel: { show: false } }));
};
TAxios(dispatch, getState, 'get', URLS.GET_BRAND_TOP_BANNER, { patnrId }, {}, onSuccess, onFail);
};
// Featured Brands Recently Aired 조회 IF-LGSP-373
export const getBrandRecentlyAired = (props) => (dispatch, getState) => {
const { patnrId } = props;

View File

@@ -56,6 +56,7 @@ export const URLS = {
GET_BRAND_SHOWROOM: "/lgsp/v1/brand/showroom.lge",
GET_BRAND_RECENTLY_AIRED: "/lgsp/v1/brand/recently/aired.lge",
GET_BRAND_SHOP_BY_SHOW: "/lgsp/v1/brand/shopByShow.lge",
GET_BRAND_TOP_BANNER: "/lgsp/v1/brand/top/banner.lge",
//on-sale controller
GET_ON_SALE_INFO: "/lgsp/v1/onsale/onsale.lge",

View File

@@ -48,6 +48,10 @@ const initialState = {
brandShopByShowData: {
data: {},
},
brandTopBannerData: {
data: {},
},
};
export const brandReducer = (state = initialState, action) => {
@@ -179,6 +183,12 @@ export const brandReducer = (state = initialState, action) => {
};
}
case types.GET_BRAND_TOP_BANNER:
return {
...state,
brandTopBannerData: action.payload,
};
case types.SET_BRAND_LIVE_CHANNEL_UPCOMING:
return {
...state,

View File

@@ -10,6 +10,7 @@ import ontv4u from '../../../../../assets/images/bg/ontv4u_new.png';
import Pinkfong from '../../../../../assets/images/bg/Pinkfong_new.png';
import qvc from '../../../../../assets/images/bg/qvc_new.png';
import shoplc from '../../../../../assets/images/bg/shoplc_new.png';
import nbcu from '../../../../../assets/images/bg/nbcu_new.png';
import css from './DetailPanelBackground.module.less';
/**
@@ -38,6 +39,7 @@ export default function DetailPanelBackground({
11: shoplc,
16: koreaKiosk,
19: Pinkfong,
21: nbcu,
};
const detailPanelBg = useMemo(() => {

View File

@@ -9,6 +9,7 @@ import ontv4u from '../../../../../assets/images/bg/ontv4u_new.png';
import Pinkfong from '../../../../../assets/images/bg/Pinkfong_new.png';
import qvc from '../../../../../assets/images/bg/qvc_new.png';
import shoplc from '../../../../../assets/images/bg/shoplc_new.png';
import nbcu from '../../../../../assets/images/bg/nbcu_new.png';
import css from './DetailPanelBackground.module.less';
// ==================== 로깅 함수들 ====================
@@ -65,6 +66,7 @@ export default function DetailPanelBackgroundV2({
11: shoplc, // SHOPLC
16: koreaKiosk, // KOREA KIOSK
19: Pinkfong, // PINKFONG
21: nbcu, // NBCU
}),
[]
);
@@ -200,7 +202,7 @@ export function PreloadedBackgroundImages({
launchedFromPlayer = false,
}) {
// 모든 파트너사 ID 목록
const allPatnrIds = useMemo(() => [1, 2, 4, 9, 11, 16, 19], []);
const allPatnrIds = useMemo(() => [1, 2, 4, 9, 11, 16, 19, 21], []);
// ✅ 원래 로직 복원: HomePanel이 onTop이 아니고 selectedPatnrId가 있을 때만 배경 표시
const shouldShowBackground = !isHomePanelOnTop && selectedPatnrId;

View File

@@ -7,13 +7,36 @@ import css from "./Banner.module.less";
export default memo(function Banner({
brandInfo,
brandTopImgInfo,
brandTopBannerInfo,
panelPatnrId,
selectedPatnrId,
}) {
const selectedBrandInfo =
brandInfo?.find(({ patnrId }) => panelPatnrId === patnrId) || {};
const { patncLogoPath, patncNm } = selectedBrandInfo;
const { topImgAlt, topImgPath } = brandTopImgInfo;
const { topImgAlt, topImgPath } = brandTopImgInfo || {};
// NBCU(patnrId: 21)인 경우 Top Banner 정보 사용
const isNBCU = selectedPatnrId === 21;
console.log("[Banner] isNBCU:", isNBCU);
console.log("[Banner] brandTopBannerInfo:", brandTopBannerInfo);
// Top Banner 정보에서 필요한 필드 추출
const {
banrImgUrl, // 배너 이미지 URL
banrImgNm, // 배너 이미지 이름
pupBanrImgUrl, // 팝업 배너 이미지 URL
pupBanrTtl, // 팝업 배너 타이틀
banrNm // 배너 이름
} = brandTopBannerInfo || {};
// NBCU인 경우 Top Banner 이미지를, 아니면 기존 Top 이미지 사용
const bannerImageSrc = isNBCU ? banrImgUrl : topImgPath;
const bannerImageAlt = isNBCU ? banrImgNm || banrNm : topImgAlt;
console.log("[Banner] bannerImageSrc:", bannerImageSrc);
console.log("[Banner] bannerImageAlt:", bannerImageAlt);
return (
<div className={css.container}>
@@ -26,7 +49,13 @@ export default memo(function Banner({
/>
<figcaption>{patncNm}</figcaption>
</figure>
<CustomImage src={topImgPath} alt={topImgAlt} ariaLabel={topImgAlt} />
{bannerImageSrc && (
<CustomImage
src={bannerImageSrc}
alt={bannerImageAlt}
ariaLabel={bannerImageAlt}
/>
)}
</div>
);
});

View File

@@ -26,6 +26,7 @@ import {
getBrandShopByShow,
getBrandShowroom,
getBrandTSVInfo,
getBrandTopBanner,
} from "../../actions/brandActions";
import { changeAppStatus, setHidePopup } from "../../actions/commonActions";
import {
@@ -276,6 +277,9 @@ const FeaturedBrandsPanel = ({ isOnTop, panelInfo, spotlightId }) => {
const brandShopByShowContsInfo = useSelector(
(state) => state.brand.brandShopByShowData.data.brandShopByShowContsInfo
);
const brandTopBannerInfo = useSelector(
(state) => state.brand.brandTopBannerData.data.brandTopBannerInfo
);
const [displayTopButton, setDisplayTopButton] = useState(false);
const [focusedContainerId, setFocusedContainerId] = useState(null);
@@ -816,6 +820,12 @@ const FeaturedBrandsPanel = ({ isOnTop, panelInfo, spotlightId }) => {
}
});
// NBCU(patnrId: 21)인 경우 Top Banner API 호출
if (selectedPatnrId === 21) {
console.log("[FeaturedBrandsPanel] NBCU detected - calling Top Banner API");
dispatch(getBrandTopBanner({ patnrId: selectedPatnrId }));
}
resetStates();
}
}, [sortedBrandLayoutInfo, selectedPatnrId]);
@@ -1035,11 +1045,13 @@ const FeaturedBrandsPanel = ({ isOnTop, panelInfo, spotlightId }) => {
/>
)}
{brandInfo && brandTopImgInfo && (
{brandInfo && (brandTopImgInfo || (selectedPatnrId === 21 && brandTopBannerInfo)) && (
<Banner
brandInfo={brandInfo}
brandTopImgInfo={brandTopImgInfo}
brandTopBannerInfo={brandTopBannerInfo}
panelPatnrId={panelInfo?.patnrId}
selectedPatnrId={selectedPatnrId}
/>
)}

View File

@@ -27,6 +27,7 @@ import ontv4u from '../../../assets/images/bg/ontv4u_new.png';
import Pinkfong from '../../../assets/images/bg/Pinkfong_new.png';
import qvc from '../../../assets/images/bg/qvc_new.png';
import shoplc from '../../../assets/images/bg/shoplc_new.png';
import nbcu from '../../../assets/images/bg/nbcu_new.png';
import { types } from '../../actions/actionTypes';
import {
changeAppStatus,
@@ -123,6 +124,7 @@ const BACKGROUND_IMAGES = {
11: shoplc, // SHOPLC
16: koreaKiosk, // KOREA KIOSK
19: Pinkfong, // PINKFONG
21: nbcu, // NBCU
};
export const TEMPLATE_CODE_CONF = {