🕐 커밋 시간: 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 컴포넌트 아키텍처 개선 • 소규모 기능 개선 • 모듈 구조 개선
240 lines
7.5 KiB
JavaScript
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}
|
|
/>
|
|
);
|
|
})}
|
|
</>
|
|
);
|
|
}
|