[250930] feat: YouMayLikeData관련 수정 및 배경이미지 개선

This commit is contained in:
2025-09-30 10:37:59 +09:00
parent 29859514a8
commit 1f387f9327
9 changed files with 231 additions and 126 deletions

View File

@@ -308,24 +308,43 @@ export const getTop20Show = () => (dispatch, getState) => {
// 유메이라이크 아이템 리스트 IF-LGSP-201 // 유메이라이크 아이템 리스트 IF-LGSP-201
export const getMainYouMayLike = export const getMainYouMayLike =
({ lgCatCd, exclCurationId, exclPatnrId, exclPrdtId }) => ({ lgCatCd, exclCurationId, exclPatnrId, exclPrdtId, catDpTh3, catDpTh4 }) =>
(dispatch, getState) => { (dispatch, getState) => {
// console.log('[YouMayLike] API 요청 시작:', {
// lgCatCd,
// exclCurationId,
// exclPatnrId,
// exclPrdtId,
// catDpTh3,
// catDpTh4
// });
const onSuccess = (response) => { const onSuccess = (response) => {
console.log("getMainYouMayLike onSuccess ", response.data); // console.log('[YouMayLike] API 응답 성공 (onSuccess):', {
console.log('[YouMayLike] API 응답 구조:', { // fullResponse: response.data,
fullResponse: response.data, // dataField: response.data.data,
dataField: response.data.data, // hasYoumaylike: !!(response.data.data && response.data.data.youmaylike),
hasYoumaylike: !!(response.data.data && response.data.data.youmaylike), // youmaylikeLength: response.data.data?.youmaylike?.length || 0,
youmaylikeLength: response.data.data?.youmaylike?.length || 0 // youmaylikeData: response.data.data?.youmaylike
}); // });
// console.log('[YouMayLike] Redux dispatch 전 - payload:', response.data.data);
dispatch({ dispatch({
type: types.GET_YOUMAYLIKE, type: types.GET_YOUMAYLIKE,
payload: response.data.data, payload: response.data.data,
}); });
// console.log('[YouMayLike] Redux dispatch 완료');
}; };
const onFail = (error) => { const onFail = (error) => {
// console.error('[YouMayLike] API 요청 실패 (onFail):', {
// error: error,
// errorMessage: error?.message,
// errorResponse: error?.response,
// errorData: error?.response?.data
// });
console.error("getMainYouMayLike onFail", error); console.error("getMainYouMayLike onFail", error);
}; };
@@ -334,7 +353,7 @@ export const getMainYouMayLike =
getState, getState,
"get", "get",
URLS.GET_YOUMAYLIKE, URLS.GET_YOUMAYLIKE,
{ lgCatCd, exclCurationId, exclPatnrId, exclPrdtId }, { lgCatCd, exclCurationId, exclPatnrId, exclPrdtId, catDpTh3, catDpTh4 },
{}, {},
onSuccess, onSuccess,
onFail onFail

View File

@@ -137,6 +137,13 @@ export const mainReducer = (state = initialState, action) => {
} }
case types.GET_YOUMAYLIKE: { case types.GET_YOUMAYLIKE: {
const data = action.payload; const data = action.payload;
// console.log('[YouMayLike] Reducer - GET_YOUMAYLIKE 액션 처리:', {
// actionPayload: action.payload,
// youmaylikeFromPayload: data.youmaylike,
// youmaylikeLength: data.youmaylike?.length || 0,
// prevState: state.youmaylikeData,
// newState: data.youmaylike
// });
return { return {
...state, ...state,
youmaylikeData: data.youmaylike, youmaylikeData: data.youmaylike,

View File

@@ -18,8 +18,6 @@ import DetailPanelSkeleton from './DetailPanelSkeleton/DetailPanelSkeleton';
import Spotlight from '@enact/spotlight'; import Spotlight from '@enact/spotlight';
import { setContainerLastFocusedElement } from '@enact/spotlight/src/container'; import { setContainerLastFocusedElement } from '@enact/spotlight/src/container';
import detailPanelBg
from '../../../assets/images/detailpanel/detailpanel-bg-1.png';
import indicatorDefaultImage import indicatorDefaultImage
from '../../../assets/images/img-thumb-empty-144@3x.png'; from '../../../assets/images/img-thumb-empty-144@3x.png';
import { getDeviceAdditionInfo } from '../../actions/deviceActions'; import { getDeviceAdditionInfo } from '../../actions/deviceActions';
@@ -47,6 +45,7 @@ import {
} from '../../utils/helperMethods'; } from '../../utils/helperMethods';
import { SpotlightIds } from '../../utils/SpotlightIds'; import { SpotlightIds } from '../../utils/SpotlightIds';
import THeaderCustom from './components/THeaderCustom'; import THeaderCustom from './components/THeaderCustom';
import DetailPanelBackground from './components/DetailPanelBackground';
import css from './DetailPanel.module.less'; import css from './DetailPanel.module.less';
import ProductAllSection from './ProductAllSection/ProductAllSection'; import ProductAllSection from './ProductAllSection/ProductAllSection';
import ThemeItemListOverlay from './ThemeItemListOverlay/ThemeItemListOverlay'; import ThemeItemListOverlay from './ThemeItemListOverlay/ThemeItemListOverlay';
@@ -232,24 +231,8 @@ export default function DetailPanel({ panelInfo, isOnTop, spotlightId }) {
[scrollToSection] [scrollToSection]
); );
// ===== 고정 배경 이미지 설정 (detailPanelBg만 사용) ===== // ===== 배경 이미지 설정 (컴포넌트로 구현되어 useEffect 불필요) =====
// 모든 DetailPanel에서 동일한 배경 이미지(detailpanel-bg-1.png) 사용 // DetailPanelBackground 컴포넌트로 배경 렌더링
useEffect(() => {
console.log("[PartnerId] Partner background info:", {
panelPatnrId: panelPatnrId,
productDataPatnrId: productData?.patnrId,
productDataPatncNm: productData?.patncNm,
productDataThumbnailUrl960: productData?.thumbnailUrl960,
imageUrl: imageUrl,
detailPanelBg: detailPanelBg,
});
// 고정 배경 이미지만 설정 (파트너사별 변경 없이)
document.documentElement.style.setProperty(
"--bg-url",
`url(${detailPanelBg})`
);
}, [panelPatnrId, productData, imageUrl]);
// FP 방식으로 pending scroll 처리 (메모리 누수 방지) // FP 방식으로 pending scroll 처리 (메모리 누수 방지)
useEffect(() => { useEffect(() => {
@@ -338,43 +321,25 @@ export default function DetailPanel({ panelInfo, isOnTop, spotlightId }) {
useEffect(() => { useEffect(() => {
const shouldLoadRecommendations = fp.pipe(() => lgCatCd, fp.isNotEmpty)(); const shouldLoadRecommendations = fp.pipe(() => lgCatCd, fp.isNotEmpty)();
console.log('[YouMayLike] API 호출 체크:', {
lgCatCd,
shouldLoadRecommendations,
panelInfo_curationId: panelInfo?.curationId,
panelInfo_patnrId: panelInfo?.patnrId,
panelInfo_prdtId: panelInfo?.prdtId,
// 비교용 - 제거 예정
old_panelCurationId: panelCurationId,
old_panelPatnrId: panelPatnrId,
old_panelPrdtId: panelPrdtId
});
if (shouldLoadRecommendations) { if (shouldLoadRecommendations) {
const apiParams = { const youMayLikeParams = {
lgCatCd: lgCatCd, lgCatCd: lgCatCd,
exclCurationId: panelInfo?.curationId, exclCurationId: panelInfo?.curationId,
exclPatnrId: panelInfo?.patnrId, exclPatnrId: panelInfo?.patnrId,
exclPrdtId: panelInfo?.prdtId, exclPrdtId: panelInfo?.prdtId,
catDpTh3: productData?.catDpTh3,
catDpTh4: productData?.catDpTh4,
}; };
console.log('[YouMayLike] getMainYouMayLike API 호출 중...', {
apiParams, // console.log('[YouMayLike]-youmaylikeData 요청 파라미터:', youMayLikeParams);
currentProduct: { dispatch(getMainYouMayLike(youMayLikeParams));
patnrId: panelInfo?.patnrId,
prdtId: panelInfo?.prdtId,
curationId: panelInfo?.curationId
}
});
dispatch(getMainYouMayLike(apiParams));
} else {
console.log('[YouMayLike] API 호출하지 않음 - lgCatCd가 비어있음');
} }
}, [panelInfo?.curationId, panelInfo?.patnrId, panelInfo?.prdtId, lgCatCd]); }, [panelInfo?.curationId, panelInfo?.patnrId, panelInfo?.prdtId, lgCatCd]);
const getlgCatCd = useCallback(() => { const getlgCatCd = useCallback(() => {
// DetailPanel.backup.jsx와 완전히 동일한 로직 // DetailPanel.backup.jsx와 완전히 동일한 로직
if (productData && !panelInfo?.curationId) { if (productData && !panelInfo?.curationId) {
console.log('[YouMayLike] lgCatCd 설정 (일반상품):', productData.catCd); // console.log('[YouMayLike] lgCatCd 설정 (일반상품):', productData.catCd);
setLgCatCd(productData.catCd); setLgCatCd(productData.catCd);
} else if ( } else if (
themeProductInfos && themeProductInfos &&
@@ -382,16 +347,16 @@ export default function DetailPanel({ panelInfo, isOnTop, spotlightId }) {
panelInfo?.curationId panelInfo?.curationId
) { ) {
const themeCatCd = themeProductInfos[selectedIndex]?.catCd; const themeCatCd = themeProductInfos[selectedIndex]?.catCd;
console.log('[YouMayLike] lgCatCd 설정 (테마상품):', themeCatCd); // console.log('[YouMayLike] lgCatCd 설정 (테마상품):', themeCatCd);
setLgCatCd(themeCatCd); setLgCatCd(themeCatCd);
} else { } else {
console.log('[YouMayLike] lgCatCd 설정 (빈값):', { // console.log('[YouMayLike] lgCatCd 설정 (빈값):', {
hasProductData: !!productData, // hasProductData: !!productData,
panelCurationId: panelInfo?.curationId, // panelCurationId: panelInfo?.curationId,
hasThemeProductInfos: !!themeProductInfos, // hasThemeProductInfos: !!themeProductInfos,
selectedIndex, // selectedIndex,
themeProductPmtSuptYn: themeProductInfos?.[selectedIndex]?.pmtSuptYn // themeProductPmtSuptYn: themeProductInfos?.[selectedIndex]?.pmtSuptYn
}); // });
setLgCatCd(""); setLgCatCd("");
} }
}, [productData, themeProductInfos, selectedIndex, panelInfo?.curationId]); }, [productData, themeProductInfos, selectedIndex, panelInfo?.curationId]);
@@ -402,21 +367,21 @@ export default function DetailPanel({ panelInfo, isOnTop, spotlightId }) {
}, [themeProductInfos, productData, panelInfo, selectedIndex, getlgCatCd]); }, [themeProductInfos, productData, panelInfo, selectedIndex, getlgCatCd]);
// lgCatCd 변경 추적 로그 // lgCatCd 변경 추적 로그
useEffect(() => { // useEffect(() => {
console.log('[YouMayLike] lgCatCd 변경됨:', { // console.log('[YouMayLike] lgCatCd 변경됨:', {
lgCatCd, // lgCatCd,
willTriggerYouMayLike: !!lgCatCd // willTriggerYouMayLike: !!lgCatCd
}); // });
}, [lgCatCd]); // }, [lgCatCd]);
// youmaylikeData 변경 추적 로그 // youmaylikeData 변경 추적 로그
useEffect(() => { // useEffect(() => {
console.log('[YouMayLike] DetailPanel - youmaylikeData 변경됨:', { // console.log('[YouMayLike] DetailPanel - youmaylikeData 변경됨:', {
youmaylikeData, // youmaylikeData,
hasData: !!(youmaylikeData && youmaylikeData.length > 0), // hasData: !!(youmaylikeData && youmaylikeData.length > 0),
dataLength: youmaylikeData?.length || 0 // dataLength: youmaylikeData?.length || 0
}); // });
}, [youmaylikeData]); // }, [youmaylikeData]);
// 최근 본 상품 저장이 필요하면: // 최근 본 상품 저장이 필요하면:
// - 순수 유틸로 빌드/업서트 함수 작성 후, 적절한 useEffect에서 호출하세요. // - 순수 유틸로 빌드/업서트 함수 작성 후, 적절한 useEffect에서 호출하세요.
@@ -729,7 +694,10 @@ export default function DetailPanel({ panelInfo, isOnTop, spotlightId }) {
}, []); }, []);
return ( return (
<div ref={containerRef}> <div ref={containerRef} style={{ position: 'relative', width: '100%', height: '100%' }}>
{/* 배경 이미지 및 그라데이션 컴포넌트 - 모든 콘텐츠 뒤에 렌더링 */}
<DetailPanelBackground />
<TPanel <TPanel
isTabActivated={false} isTabActivated={false}
className={css.detailPanelWrap} className={css.detailPanelWrap}
@@ -791,7 +759,6 @@ export default function DetailPanel({ panelInfo, isOnTop, spotlightId }) {
themeProductInfo={themeProductInfo} themeProductInfo={themeProductInfo}
onReady={handleProductAllSectionReady} onReady={handleProductAllSectionReady}
isOnRender={renderStates.canRender} isOnRender={renderStates.canRender}
youmaylikeData={youmaylikeData}
/> />
); );
} }

View File

@@ -2,18 +2,16 @@
@import "../../style/utils.module.less"; @import "../../style/utils.module.less";
.detailPanelWrap { .detailPanelWrap {
background-size: cover; // 배경 이미지와 그라데이션은 DetailPanelBackground 컴포넌트로 구현
background-position: center; // CSS 변수 대신 실제 DOM 요소 사용하여 webOS TV 호환성 확보
background-image: position: relative;
linear-gradient(0deg, rgba(0, 0, 0, 0)), z-index: 1; // 배경 컴포넌트(z-index: 0) 위에 표시
linear-gradient(180deg, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 1) 100%), background: transparent !important; // 투명 배경으로 설정하여 뒤의 배경 컴포넌트가 보이도록
linear-gradient(
270deg, // 하위 요소들도 투명 배경 (detailPanelWrap 스코프 내에서만 적용)
rgba(0, 0, 0, 0) 0%, > * {
rgba(0, 0, 0, 0.77) 70%, background: transparent !important;
rgba(0, 0, 0, 1) 100% }
),
var(--bg-url);
} }
.header { .header {
@@ -52,6 +50,7 @@
position: relative; position: relative;
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
background: transparent; // 투명 배경으로 설정
// padding-left: 120px; // padding-left: 120px;

View File

@@ -145,14 +145,16 @@ export default function ProductAllSection({
themeProductInfo, themeProductInfo,
onReady, onReady,
isOnRender, isOnRender,
youmaylikeData,
}) { }) {
const dispatch = useDispatch(); const dispatch = useDispatch();
// Redux 상태 추가 - DetailPanel.backup.jsx와 동일하게 // Redux 상태
const webOSVersion = useSelector((state) => state.common.appStatus.webOSVersion); const webOSVersion = useSelector((state) => state.common.appStatus.webOSVersion);
const groupInfos = useSelector((state) => state.product.groupInfo); const groupInfos = useSelector((state) => state.product.groupInfo);
// YouMayLike 데이터는 API 응답 시간이 걸리므로 직접 구독
const youmaylikeData = useSelector((state) => state.main.youmaylikeData);
const [currentHeight, setCurrentHeight] = useState(0); const [currentHeight, setCurrentHeight] = useState(0);
//하단부분까지 갔을때 체크용 //하단부분까지 갔을때 체크용
const [documentHeight, setDocumentHeight] = useState(0); const [documentHeight, setDocumentHeight] = useState(0);
@@ -212,19 +214,18 @@ export default function ProductAllSection({
hasReviews, // 리뷰 존재 여부 플래그 추가 hasReviews, // 리뷰 존재 여부 플래그 추가
} = useReviews(productData.prdtId, panelInfo && panelInfo.patnrId); } = useReviews(productData.prdtId, panelInfo && panelInfo.patnrId);
// YouMayAlsoLike 데이터 확인 - props로 받은 데이터 사용 // YouMayAlsoLike 데이터 확인
const youmaylikeProductData = youmaylikeData; const hasYouMayAlsoLike = youmaylikeData && youmaylikeData.length > 0;
const hasYouMayAlsoLike = youmaylikeProductData && youmaylikeProductData.length > 0;
// YouMayLike 데이터 디버깅 // YouMayLike 데이터 디버깅
useEffect(() => { // useEffect(() => {
console.log('[YouMayLike] ProductAllSection - 데이터 상태 (Props):', { // console.log('[YouMayLike] ProductAllSection - 데이터 상태:', {
youmaylikeProductData, // youmaylikeData,
hasYouMayAlsoLike, // hasYouMayAlsoLike,
dataLength: youmaylikeProductData?.length || 0, // dataLength: youmaylikeData?.length || 0,
productDataPrdtId: productData?.prdtId // productDataPrdtId: productData?.prdtId
}); // });
}, [youmaylikeProductData, hasYouMayAlsoLike, productData]); // }, [youmaylikeData, hasYouMayAlsoLike, productData]);
// ProductAllSection 마운트 시 showAllReviews 초기화 // ProductAllSection 마운트 시 showAllReviews 초기화
useEffect(() => { useEffect(() => {
@@ -619,14 +620,14 @@ export default function ProductAllSection({
</TButton> </TButton>
)} )}
{/* YouMayLike 버튼 렌더링 상태 로그 */} {/* YouMayLike 버튼 렌더링 상태 로그 */}
{(() => { {/* {(() => {
console.log('[YouMayLike] 버튼 렌더링 체크:', { console.log('[YouMayLike] 버튼 렌더링 체크:', {
hasYouMayAlsoLike, hasYouMayAlsoLike,
shouldRenderButton: hasYouMayAlsoLike, shouldRenderButton: hasYouMayAlsoLike,
youmaylikeDataLength: youmaylikeProductData?.length || 0 youmaylikeDataLength: youmaylikeData?.length || 0
}); });
return null; return null;
})()} })()} */}
</Container> </Container>
{panelInfo && panelInfo && panelInfo.type === 'theme' && !openThemeItemOverlay && ( {panelInfo && panelInfo && panelInfo.type === 'theme' && !openThemeItemOverlay && (
@@ -734,19 +735,20 @@ export default function ProductAllSection({
<div ref={youMayAlsoLikelRef}> <div ref={youMayAlsoLikelRef}>
<div id="scroll-marker-you-may-also-like" className={css.scrollMarker}></div> <div id="scroll-marker-you-may-also-like" className={css.scrollMarker}></div>
<div id="you-may-also-like-section"> <div id="you-may-also-like-section">
{(() => { {/* {(() => {
console.log('[YouMayLike] YouMayAlsoLike 컴포넌트 렌더링:', { console.log('[YouMayLike] YouMayAlsoLike 컴포넌트 렌더링:', {
productInfo: productData, productInfo: productData,
panelInfo, panelInfo,
hasData: !!youmaylikeProductData hasData: !!youmaylikeData
}); });
return null; return null;
})()} })()} */}
<YouMayAlsoLike <YouMayAlsoLike
productInfo={productData} productInfo={productData}
panelInfo={panelInfo} panelInfo={panelInfo}
onFocus={youmaylikeFocus} onFocus={youmaylikeFocus}
onBlur={_onBlur} onBlur={_onBlur}
youmaylikeData={youmaylikeData}
/> />
</div> </div>
</div> </div>

View File

@@ -31,32 +31,36 @@ const Container = SpotlightContainerDecorator(
"div" "div"
); );
export default function YouMayAlsoLike({ productInfo, panelInfo, onFocus, onBlur }) { export default function YouMayAlsoLike({ productInfo, panelInfo, onFocus, onBlur, youmaylikeData }) {
const { getScrollTo, scrollLeft } = useScrollTo(); const { getScrollTo, scrollLeft } = useScrollTo();
const [newYoumaylikeProductData, setNewYoumaylikeProductData] = useState([]); const [newYoumaylikeProductData, setNewYoumaylikeProductData] = useState([]);
const dispatch = useDispatch(); const dispatch = useDispatch();
const focusedContainerIdRef = useRef(null); const focusedContainerIdRef = useRef(null);
const youmaylikeProductData = useSelector( // Redux에서 데이터 조회
const reduxYoumaylikeData = useSelector(
(state) => state.main.youmaylikeData (state) => state.main.youmaylikeData
); );
// props로 받은 데이터 우선 사용, 없으면 Redux 데이터 사용
const youmaylikeProductData = youmaylikeData || reduxYoumaylikeData;
//노출 9개로 변경위한 처리건. //노출 9개로 변경위한 처리건.
useEffect(() => { useEffect(() => {
console.log('[YouMayLike] YouMayAlsoLike 컴포넌트 - 데이터 처리:', { // console.log('[YouMayLike] YouMayAlsoLike 컴포넌트 - 데이터 처리:', {
originalData: youmaylikeProductData, // originalData: youmaylikeProductData,
originalLength: youmaylikeProductData?.length || 0, // originalLength: youmaylikeProductData?.length || 0,
hasData: !!(youmaylikeProductData && youmaylikeProductData.length > 0) // hasData: !!(youmaylikeProductData && youmaylikeProductData.length > 0)
}); // });
if (youmaylikeProductData && youmaylikeProductData.length > 0) { if (youmaylikeProductData && youmaylikeProductData.length > 0) {
const processedData = youmaylikeProductData.slice(0, youmaylikeProductData.length - 1); const processedData = youmaylikeProductData.slice(0, youmaylikeProductData.length - 1);
console.log('[YouMayLike] 처리된 데이터 설정:', { // console.log('[YouMayLike] 처리된 데이터 설정:', {
processedLength: processedData.length, // processedLength: processedData.length,
processedData // processedData
}); // });
setNewYoumaylikeProductData(processedData); setNewYoumaylikeProductData(processedData);
} else { } else {
console.log('[YouMayLike] 데이터 없음 - 빈 배열 설정'); // console.log('[YouMayLike] 데이터 없음 - 빈 배열 설정');
setNewYoumaylikeProductData([]); setNewYoumaylikeProductData([]);
} }
}, [youmaylikeProductData]); }, [youmaylikeProductData]);
@@ -98,12 +102,12 @@ export default function YouMayAlsoLike({ productInfo, panelInfo, onFocus, onBlur
}, [onBlur]); }, [onBlur]);
// 렌더링 시점 로그 // 렌더링 시점 로그
console.log('[YouMayLike] YouMayAlsoLike 렌더링:', { // console.log('[YouMayLike] YouMayAlsoLike 렌더링:', {
newYoumaylikeProductData, // newYoumaylikeProductData,
hasData: !!(newYoumaylikeProductData && newYoumaylikeProductData.length > 0), // hasData: !!(newYoumaylikeProductData && newYoumaylikeProductData.length > 0),
dataLength: newYoumaylikeProductData?.length || 0, // dataLength: newYoumaylikeProductData?.length || 0,
willRender: !!(newYoumaylikeProductData && newYoumaylikeProductData.length > 0) // willRender: !!(newYoumaylikeProductData && newYoumaylikeProductData.length > 0)
}); // });
return ( return (
<div> <div>

View File

@@ -0,0 +1,38 @@
// src/views/DetailPanel/components/DetailPanelBackground/DetailPanelBackground.jsx
import React, { useEffect } from 'react';
import css from './DetailPanelBackground.module.less';
import detailPanelBg from '../../../../../assets/images/detailpanel/detailpanel-bg-1.png';
/**
* DetailPanel의 배경 이미지와 그라데이션을 렌더링하는 컴포넌트
* CSS 변수 대신 실제 DOM 요소로 구현하여 webOS TV 호환성 확보
*/
export default function DetailPanelBackground() {
useEffect(() => {
console.log('[DetailPanelBackground] 배경 이미지 경로:', detailPanelBg);
}, []);
return (
<div className={css.backgroundContainer}>
{/* 실제 배경 이미지 */}
<img
src={detailPanelBg}
alt=""
className={css.backgroundImage}
aria-hidden="true"
onLoad={() => console.log('[DetailPanelBackground] 이미지 로드 완료')}
onError={(e) => console.error('[DetailPanelBackground] 이미지 로드 실패:', e)}
/>
{/* 그라데이션 레이어들 - CSS의 linear-gradient를 div로 구현 */}
{/* 1. 270도 방향 그라데이션 (왼쪽→오른쪽, 투명→불투명) */}
<div className={css.gradientLayer1} aria-hidden="true" />
{/* 2. 180도 방향 그라데이션 (위→아래, 투명→불투명) */}
<div className={css.gradientLayer2} aria-hidden="true" />
{/* 3. 투명 그라데이션 */}
<div className={css.gradientLayer3} aria-hidden="true" />
</div>
);
}

View File

@@ -0,0 +1,67 @@
@import "../../../../style/CommonStyle.module.less";
@import "../../../../style/utils.module.less";
// 배경 컨테이너 - 전체 화면을 덮으며 최하단에 위치
.backgroundContainer {
position: absolute; // 부모 기준 절대 위치
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 0; // z-index: -1 대신 0 사용
overflow: hidden;
pointer-events: none; // 클릭 이벤트가 아래로 통과하도록
}
// 실제 배경 이미지
.backgroundImage {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
object-fit: cover; // 화면 크기에 맞춰 이미지 조정
object-position: center;
z-index: 1; // 맨 아래 레이어
}
// 그라데이션 레이어 1: 270도 방향 (왼쪽→오른쪽, 투명→불투명)
// linear-gradient(270deg, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 0.77) 70%, rgba(0, 0, 0, 1) 100%)
.gradientLayer1 {
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%
);
z-index: 2;
}
// 그라데이션 레이어 2: 180도 방향 (위→아래, 투명→불투명)
// linear-gradient(180deg, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 1) 100%)
.gradientLayer2 {
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%);
z-index: 3;
}
// 그라데이션 레이어 3: 투명 그라데이션
// linear-gradient(0deg, rgba(0, 0, 0, 0))
.gradientLayer3 {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: linear-gradient(0deg, rgba(0, 0, 0, 0));
z-index: 4;
}

View File

@@ -0,0 +1,2 @@
// Barrel export for DetailPanelBackground
export { default } from './DetailPanelBackground';