Files
shoptime/com.twin.app.shoptime/src/views/DetailPanel/components/DetailPanelBackground/DetailPanelBackground.v2.jsx
optrader d6656848a2 [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 컴포넌트 아키텍처 개선
  • 소규모 기능 개선
  • 모듈 구조 개선
2025-12-10 13:02:34 +09:00

240 lines
7.5 KiB
JavaScript

// src/views/DetailPanel/components/DetailPanelBackground/DetailPanelBackground.v2.jsx
import React, { useMemo, useCallback } from 'react';
// 이미지 imports
import hsn from '../../../../../assets/images/bg/hsn_new.png';
import koreaKiosk from '../../../../../assets/images/bg/koreaKiosk_new.png';
import lgelectronics from '../../../../../assets/images/bg/lgelectronics_new.png';
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';
// ==================== 로깅 함수들 ====================
/**
* DetailPanelBackgroundV2 초기화 로그
* @param {number} patnrId - 파트너사 ID
* @param {boolean} visible - 표시 여부
* @param {string} imageUrl - 이미지 URL
*/
// const logDetailPanelInit = (patnrId, visible, imageUrl) => {
// console.log(`[DetailPanelBackgroundV2] patnrId: ${patnrId}, visible: ${visible}, imageUrl: ${imageUrl}`);
// };
/**
* 이미지 로드 성공 로그
* @param {number} patnrId - 파트너사 ID
*/
// const logImageLoaded = (patnrId) => {
// console.log(`[DetailPanelBackgroundV2] Image loaded: patnrId=${patnrId}`);
// };
/**
* 이미지 로드 실패 로그
* @param {number} patnrId - 파트너사 ID
* @param {Error} error - 에러 객체
*/
// const logImageError = (patnrId, error) => {
// console.error(`[DetailPanelBackgroundV2] Image load failed: patnrId=${patnrId}`, error);
// };
/**
* 개선된 배경 이미지 컴포넌트 v2
* HomePanel에 미리 로드되어 메모리에 상주하며, visible props로 표시 여부만 제어
*
* @param {Object} props
* @param {number} props.patnrId - 파트너사 ID
* @param {boolean} props.visible - 표시 여부 (HomePanel이 isOnTop일 때 false)
* @param {boolean} props.launchedFromPlayer - PlayerPanel에서 진입했는지 여부
* @param {boolean} props.usePlaceholder - placeholder 표시 여부
*/
export default function DetailPanelBackgroundV2({
patnrId,
visible = true,
launchedFromPlayer = false,
usePlaceholder = false,
}) {
// 파트너사별 배경 이미지 맵
const BG_MAP = useMemo(
() => ({
1: qvc, // QVC
2: hsn, // HSN
4: ontv4u, // ONTV4U
9: lgelectronics, // LG ELECTRONICS
11: shoplc, // SHOPLC
16: koreaKiosk, // KOREA KIOSK
19: Pinkfong, // PINKFONG
21: nbcu, // NBCU
}),
[]
);
const backgroundImageUrl = useMemo(() => {
return BG_MAP[patnrId] || qvc; // 기본값은 QVC
}, [patnrId, BG_MAP]);
// useCallback으로 메모이제이션된 핸들러
const handleImageLoad = useCallback(() => {
logImageLoaded(patnrId);
}, [patnrId]);
const handleImageError = useCallback(
(e) => {
logImageError(patnrId, e);
},
[patnrId]
);
// 개발 환경에서만 로깅
if (process.env.NODE_ENV === 'development') {
// eslint-disable-next-line no-console
logDetailPanelInit(patnrId, visible, backgroundImageUrl);
}
return (
<div
className={css.backgroundContainerV2}
style={{
position: 'fixed',
top: 0,
left: 0,
width: '100vw',
height: '100vh',
zIndex: 50, // HomePanel(z-index: 1)보다 높고, DetailPanel(z-index: 100)보다 낮음
visibility: visible ? 'visible' : 'hidden',
opacity: visible ? 1 : 0,
transition: 'opacity 0.3s ease-in-out, visibility 0.3s ease-in-out',
pointerEvents: 'none',
}}
>
{/* PlayerPanel에서 진입한 경우 이미지를 표시하지 않고 그라데이션만 표시 */}
{launchedFromPlayer ? (
// 그라데이션 레이어들만 표시
<>
{/* 1. 270도 방향 그라데이션 (왼쪽→오른쪽, 투명→불투명) */}
<div
style={{
position: 'absolute',
top: 0,
left: 0,
width: '100%',
height: '100%',
background:
'linear-gradient(270deg, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 0.77) 70%, rgba(0, 0, 0, 1) 100%)',
zIndex: 3,
}}
aria-hidden="true"
/>
{/* 2. 180도 방향 그라데이션 (위→아래, 투명→불투명) */}
<div
style={{
position: 'absolute',
top: 0,
left: 0,
width: '100%',
height: '100%',
background: 'linear-gradient(180deg, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 1) 100%)',
zIndex: 4,
}}
aria-hidden="true"
/>
{/* 3. 투명 그라데이션 */}
<div
style={{
position: 'absolute',
top: 0,
left: 0,
width: '100%',
height: '100%',
background: 'linear-gradient(0deg, rgba(0, 0, 0, 0))',
zIndex: 5,
}}
aria-hidden="true"
/>
</>
) : usePlaceholder ? (
// placeholder 모드
<div
className={css.backgroundPlaceholder}
style={{
position: 'absolute',
top: 0,
left: 0,
width: '100%',
height: '100%',
background: 'linear-gradient(135deg, #1a1a1a 0%, #2d2d2d 50%, #1a1a1a 100%)',
zIndex: 2,
}}
/>
) : (
// 실제 배경 이미지
<img
src={backgroundImageUrl}
alt=""
style={{
position: 'absolute',
top: 0,
left: 0,
width: '100%',
height: '100%',
objectFit: 'cover',
objectPosition: 'center',
zIndex: 2,
}}
aria-hidden="true"
onLoad={handleImageLoad}
onError={handleImageError}
/>
)}
</div>
);
}
/**
* HomePanel에서 사용할 모든 배경 이미지 미리 로딩 컴포넌트
* HomePanel이 렌더링될 때 모든 파트너사 배경 이미지를 미리 로드하여 메모리에 상주시킴
*/
export function PreloadedBackgroundImages({
selectedPatnrId,
isHomePanelOnTop = true,
launchedFromPlayer = false,
}) {
// 모든 파트너사 ID 목록
const allPatnrIds = useMemo(() => [1, 2, 4, 9, 11, 16, 19, 21], []);
// ✅ 원래 로직 복원: HomePanel이 onTop이 아니고 selectedPatnrId가 있을 때만 배경 표시
const shouldShowBackground = !isHomePanelOnTop && selectedPatnrId;
// ✅ 디버깅 로그 추가
useMemo(() => {
console.log('[PreloadedBackgroundImages] Debug info:', {
selectedPatnrId,
isHomePanelOnTop,
launchedFromPlayer,
shouldShowBackground,
allPatnrIds,
});
}, [selectedPatnrId, isHomePanelOnTop, launchedFromPlayer, shouldShowBackground]);
return (
<>
{allPatnrIds.map((patnrId) => {
// ✅ 원래 로직: DetailPanel에서 선택된 patnrId와 일치하는 배경만 표시
const isVisible = shouldShowBackground && patnrId === selectedPatnrId;
console.log(`[PreloadedBackgroundImages] patnrId ${patnrId}, visible: ${isVisible}`);
return (
<DetailPanelBackgroundV2
key={`bg-${patnrId}`}
patnrId={patnrId}
visible={isVisible}
launchedFromPlayer={launchedFromPlayer}
/>
);
})}
</>
);
}