[포유 작업]#1

- action, reducer 에 recommendProduct 관련 추가.
 - 로그 관련으로 Config에 pickedforyou추가
 - homepanel pickforyou노출 건으로 추가.
 - homepanel getSubCategory에 파라미터 추가.
 - bestseller,pickedforyou노출 변경.(foru api에서 내려주는걸로)
 - subCategory 노출 변경. foru api에서 내려주는 아이템 2개 추가및 기존 데이터 중복시 제거.
This commit is contained in:
junghoon86.park
2025-11-10 16:17:51 +09:00
parent 3e547df1a4
commit 11582840b8
7 changed files with 156 additions and 67 deletions

View File

@@ -1,10 +1,18 @@
import { URLS } from '../api/apiConfig';
import { TAxios } from '../api/TAxios';
import { convertUtcToLocal } from '../components/MediaPlayer/util';
import { CATEGORY_DATA_MAX_RESULTS_LIMIT, LOG_CONTEXT_NAME, LOG_MESSAGE_ID } from '../utils/Config';
import {
CATEGORY_DATA_MAX_RESULTS_LIMIT,
LOG_CONTEXT_NAME,
LOG_MESSAGE_ID,
} from '../utils/Config';
import * as HelperMethods from '../utils/helperMethods';
import { types } from './actionTypes';
import { addReservation, changeAppStatus, deleteReservation } from './commonActions';
import {
addReservation,
changeAppStatus,
deleteReservation,
} from './commonActions';
//IF-LGSP-007
export const getMainLiveShow = (props) => (dispatch, getState) => {
@@ -155,7 +163,7 @@ let lastSubCategoryParams = {};
export const getSubCategory =
(params, pageNo = 1, key = null, clear = false) =>
(dispatch, getState) => {
const { lgCatCd, patnrIdList, tabType, filterType } = params;
const { lgCatCd, patnrIdList, tabType, filterType, recommendIncFlag } = params;
let pageSize = params.pageSize || CATEGORY_DATA_MAX_RESULTS_LIMIT;
if (pageNo === 1) {
@@ -179,21 +187,34 @@ export const getSubCategory =
if (pageNo === 1) {
getSubCategoryKey = new Date();
currentKey = getSubCategoryKey;
// ✅ recommendProduct 분리
const { recommendProduct, ...restData } = response.data.data;
dispatch({
type: types.GET_SUB_CATEGORY,
payload: response.data.data,
payload: {
...restData,
recommendProduct,
},
categoryParams: {
lgCatCd,
patnrIdList,
tabType,
filterType,
recommendIncFlag,
pageSize,
},
});
} else if (getSubCategoryKey === currentKey) {
const { recommendProduct, ...restData } = response.data.data;
dispatch({
type: types.GET_SUB_CATEGORY,
payload: response.data.data,
payload: {
...restData,
recommendProduct,
},
append: true,
startIndex: (pageNo - 1) * pageSize,
});
@@ -212,7 +233,7 @@ export const getSubCategory =
getState,
'get',
URLS.GET_SUB_CATEGORY,
{ lgCatCd, patnrIdList, pageSize, pageNo, tabType, filterType },
{ lgCatCd, patnrIdList, pageSize, pageNo, tabType, filterType,recommendIncFlag },
{},
onSuccess,
onFail

View File

@@ -10,11 +10,13 @@ const initialState = {
showDetailInfo: [],
showNowInfo: null,
featuredShowsInfos: {},
recommendProduct: null,
categoryParams: {
lgCatCd: null,
patnrIdList: null,
tabType: null,
filterType: null,
recommendIncFlag: null,
pageSize: CATEGORY_DATA_MAX_RESULTS_LIMIT,
},
};
@@ -39,6 +41,7 @@ export const mainReducer = (state = initialState, action) => {
categoryFilterCd: action.payload.categoryFilterCd,
topShowInfo: action.payload.topShowInfo,
partnerInfos: action.payload.partnerInfos,
recommendProduct: action.payload.recommendProduct,
categoryParams: action.categoryParams,
};
}
@@ -63,6 +66,7 @@ export const mainReducer = (state = initialState, action) => {
categoryFilterCd: action.payload.categoryFilterCd,
topShowInfo: action.payload.topShowInfo,
partnerInfos: action.payload.partnerInfos,
recommendProduct: action.payload.recommendProduct,
categoryParams: action.categoryParams,
};
}
@@ -93,6 +97,7 @@ export const mainReducer = (state = initialState, action) => {
categoryFilterCd: action.payload.categoryFilterCd,
topShowInfo: action.payload.topShowInfo,
partnerInfos: action.payload.partnerInfos,
recommendProduct: action.payload.recommendProduct,
};
} else {
return {
@@ -107,6 +112,7 @@ export const mainReducer = (state = initialState, action) => {
categoryFilterCd: action.payload.categoryFilterCd,
topShowInfo: action.payload.topShowInfo,
partnerInfos: action.payload.partnerInfos,
recommendProduct: action.payload.recommendProduct,
categoryParams: action.categoryParams,
};
}
@@ -206,6 +212,7 @@ export const mainReducer = (state = initialState, action) => {
return {
...state,
subCategoryData: {},
recommendProduct: null,
};
default:

View File

@@ -292,6 +292,7 @@ export const LOG_MENU = {
HOME_ON_SALE: 'Home/On Sale',
HOME_POPULAR_SHOWS: 'Home/Popular Shows',
HOME_BEST_SELLER: 'Home/Best Sellers',
HOME_PICKED_FOR_YOU: 'Home/Picked For You',
TRENDING_NOW_POPULAR_SHOWS: 'Trending Now/Popular Shows',
TRENDING_NOW_BEST_SELLER: 'Trending Now/Best Sellers',

View File

@@ -67,18 +67,33 @@ const BestSeller = ({
const { cursorVisible } = useSelector((state) => state.common.appStatus);
const bestSellerDatas = useSelector(
(state) => state.product.bestSellerData?.bestSeller
const bestSellerNewDatas = useSelector(
(state) =>
state.foryou?.justForYouInfo?.shelfInfos
);
const [drawChk, setDrawChk] = useState(false);
const [firstChk, setFirstChk] = useState(0);
const [bestInfos, setBestInfos] = useState(null);
useEffect(()=>{
setBestInfos(
bestSellerNewDatas?.filter(
(item) => item.recommendTpCd === "BESTSELLER"
)
)
},[bestSellerNewDatas])
const orderStyle = useMemo(() => ({ order: order }), [order]);
useEffect(() => {
setDrawChk(true);
}, [bestSellerDatas]);
}, [bestSellerNewDatas]);
const handleCardClick = useCallback(
(patnrId, prdtId) => () => {
@@ -177,21 +192,6 @@ const BestSeller = ({
}
}, [handleShelfFocus]);
const [bestSellerNewData, setBestSellerNewData] = useState([]);
const _randomProduct = useCallback(() => {
const randomChk = Math.round(Math.random()) === 0 ? false : true;
return randomChk;
}, []);
useEffect(() => {
setBestSellerNewData(
bestSellerDatas?.map((item) => ({
...item,
// foryou: _randomProduct(),
}))
);
}, [bestSellerDatas]);
return (
<Container
@@ -213,8 +213,8 @@ const BestSeller = ({
cbScrollTo={getScrollTo}
noScrollByWheel
>
{bestSellerNewData &&
bestSellerNewData.map(
{bestInfos &&
bestInfos?.[0].productInfos.map(
(
{
prdtId,
@@ -226,7 +226,7 @@ const BestSeller = ({
offerInfo,
brndNm,
patncNm,
catNm,
//catNm, 없음
//foryou,
euEnrgLblInfos,
},
@@ -251,7 +251,7 @@ const BestSeller = ({
shelfTitle={shelfTitle}
patnerName={patncNm}
brandName={brndNm}
catNm={catNm}
// catNm={catNm}
imageAlt={prdtId}
imageSource={imgUrl}
priceInfo={priceInfo}
@@ -265,7 +265,7 @@ const BestSeller = ({
offerInfo={offerInfo}
spotlightId={"bestsellerItem" + itemIndex}
firstLabel={rankText}
label={itemIndex * 1 + 1 + " of " + bestSellerNewData.length}
label={itemIndex * 1 + 1 + " of " + bestInfos?.[0].productInfos.length}
lastLabel=" go to detail, button"
euEnrgLblInfos={euEnrgLblInfos}
>

View File

@@ -1,7 +1,17 @@
import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import React, {
useCallback,
useEffect,
useMemo,
useRef,
useState,
} from 'react';
import classNames from 'classnames';
import { useDispatch, useSelector } from 'react-redux';
import {
useDispatch,
useSelector,
} from 'react-redux';
import { applyMiddleware } from 'redux';
import Spotlight from '@enact/spotlight';
import {
@@ -23,20 +33,31 @@ import {
getHomeMainContents,
updateHomeInfo,
} from '../../actions/homeActions';
import { sendLogGNB, sendLogTotalRecommend } from '../../actions/logActions';
import { getSubCategory, getTop20Show } from '../../actions/mainActions';
import {
sendLogGNB,
sendLogTotalRecommend,
} from '../../actions/logActions';
import {
getSubCategory,
getTop20Show,
} from '../../actions/mainActions';
import { getHomeOnSaleInfo } from '../../actions/onSaleActions';
import { finishVideoPreview, shrinkVideoTo1px, expandVideoFrom1px } from '../../actions/playActions';
import { updatePanel } from '../../actions/panelActions';
import {
expandVideoFrom1px,
finishVideoPreview,
shrinkVideoTo1px,
} from '../../actions/playActions';
import { getBestSeller } from '../../actions/productActions';
import TBody from '../../components/TBody/TBody';
import TButton, { TYPES } from '../../components/TButton/TButton';
import TPanel from '../../components/TPanel/TPanel';
import TPopUp from '../../components/TPopUp/TPopUp';
import TVerticalPagenator from '../../components/TVerticalPagenator/TVerticalPagenator';
import TVerticalPagenator
from '../../components/TVerticalPagenator/TVerticalPagenator';
import useDebugKey from '../../hooks/useDebugKey';
import usePrevious from '../../hooks/usePrevious';
import { useFocusHistory } from '../../hooks/useFocusHistory/useFocusHistory';
import usePrevious from '../../hooks/usePrevious';
import { useVideoPlay } from '../../hooks/useVideoPlay/useVideoPlay';
import { useVideoMove } from '../../hooks/useVideoTransition/useVideoMove';
import {
@@ -55,7 +76,7 @@ import css from '../HomePanel/HomePanel.module.less';
import PopularShow from '../HomePanel/PopularShow/PopularShow';
import SubCategory from '../HomePanel/SubCategory/SubCategory';
import EventPopUpBanner from './EventPopUpBanner/EventPopUpBanner';
import { applyMiddleware } from 'redux';
import PickedForYou from './PickedForYou/PickedForYou';
export const TEMPLATE_CODE_CONF = {
TOP: 'DSP00101',
@@ -63,6 +84,7 @@ export const TEMPLATE_CODE_CONF = {
ON_SALE: 'DSP00103',
POPULAR_SHOW: 'DSP00104',
BEST_SELLER: 'DSP00105',
PICK_FOR_YOU: 'DSP00106',
};
const HomePanel = ({ isOnTop }) => {
@@ -251,6 +273,9 @@ const HomePanel = ({ isOnTop }) => {
case TEMPLATE_CODE_CONF.BEST_SELLER:
nowMenu = LOG_MENU.HOME_BEST_SELLER;
break;
case TEMPLATE_CODE_CONF.PICK_FOR_YOU:
nowMenu = LOG_MENU.HOME_PICKED_FOR_YOU;
break;
default:
nowMenu = LOG_MENU.HOME_TOP;
break;
@@ -384,6 +409,24 @@ const HomePanel = ({ isOnTop }) => {
);
} else break;
}
case TEMPLATE_CODE_CONF.PICK_FOR_YOU: {
if (bestSellerDatas && bestSellerDatas.length > 0) {
return (
<PickedForYou
key={el.shptmApphmDspyOptCd}
spotlightId={el.shptmApphmDspyOptCd}
handleShelfFocus={handleItemFocus(
el.shptmApphmDspyOptCd,
el.expsOrd,
el.shptmApphmDspyOptNm
)}
handleItemFocus={handleItemFocus(el.shptmApphmDspyOptCd)}
shelfLocation={el.expsOrd}
shelfTitle={el.shptmApphmDspyOptNm}
/>
);
} else break;
}
}
})}
{loadingComplete && sortedHomeLayoutInfo && sortedHomeLayoutInfo.length > 0 && (
@@ -593,6 +636,7 @@ const HomePanel = ({ isOnTop }) => {
pageSize: 10,
tabType: 'CAT00102',
filterType: 'CAT00202',
recommendIncFlag: 'Y',
},
1
)

View File

@@ -52,7 +52,7 @@ const PickedForYou = ({
shelfLocation,
shelfTitle,
}) => {
console.log("###Test pjh 여기지 ?");
const { getScrollTo, scrollLeft } = useScrollTo();
const { handleScrollReset, handleStopScrolling } = useScrollReset(
scrollLeft,
@@ -67,10 +67,25 @@ const PickedForYou = ({
(state) => state.product.bestSellerData?.bestSeller
);
const justForYouDatasNew = useSelector(
(state) => state.foryou?.justForYouInfo?.shelfInfos
)
const [drawChk, setDrawChk] = useState(false);
const [firstChk, setFirstChk] = useState(0);
const [pickedForYou, setPickedForYou] = useState(null);
const orderStyle = useMemo(() => ({ order: order }), [order]);
useEffect(()=>{
setPickedForYou(
justForYouDatasNew?.filter(
(item) => item.recommendTpCd === "PICKEDFORYOU"
)
)
},[justForYouDatasNew])
useEffect(() => {
setDrawChk(true);
@@ -193,8 +208,8 @@ const PickedForYou = ({
cbScrollTo={getScrollTo}
noScrollByWheel
>
{justForYouDatas &&
justForYouDatas.map(
{pickedForYou &&
pickedForYou?.[0].productInfos.map(
(
{
prdtId,
@@ -233,7 +248,7 @@ const PickedForYou = ({
onClick={handleCardClick(patnrId, prdtId)}
offerInfo={offerInfo}
spotlightId={"bestsellerItem" + itemIndex}
label={itemIndex * 1 + 1 + " of " + justForYouDatas.length}
label={itemIndex * 1 + 1 + " of " + pickedForYou?.[0].productInfos.length}
lastLabel=" go to detail, button"
/>
);

View File

@@ -71,6 +71,10 @@ export default memo(function SubCategory({
(state) => state.main.subCategoryData?.categoryItemInfos
);
const foruItemInfos = useSelector(
(state) => state.main.recommendProduct[0]?.productInfos
);
const nowMenu = useSelector((state) => state.common.menu.nowMenu);
const [currentLgCatCd, setCurrentLgCatCd] = useState(catCd ? catCd : null);
@@ -110,6 +114,7 @@ export default memo(function SubCategory({
pageSize: "10",
tabType: "CAT00102",
filterType: "CAT00202",
recommendIncFlag: 'Y',
},
1
)
@@ -222,27 +227,23 @@ export default memo(function SubCategory({
}
}, [handleShelfFocus]);
const _randomProduct = useCallback(() => {
const randomChk = Math.round(Math.random()) === 0 ? false : true;
return randomChk;
}, []);
useEffect(() => {
setCategoryItemNewData(
categoryItemInfos?.subCatItemList?.map((item) => ({
const recommendedData = foruItemInfos?.slice(0, 2).map((item) => ({
...item,
foryou: _randomProduct(),
}))
);
}, [categoryItemInfos?.subCatItemList]);
foryou: true,
})) || [];
useEffect(() => {
dispatch(
getRecentlySawItem(
categoryItemNewData.filter((item) => item.foryou === true)
)
);
}, [categoryItemNewData, dispatch]);
const recommendedPrdtIds = new Set(recommendedData.map(item => item.prdtId));
const baseData = categoryItemInfos?.subCatItemList?.filter(
(item) => !recommendedPrdtIds.has(item.prdtId)
).map((item) => ({
...item,
foryou: false,
})) || [];
setCategoryItemNewData([...recommendedData, ...baseData]);
}, [categoryItemInfos?.subCatItemList, foruItemInfos]);
return (
<Container
@@ -321,7 +322,7 @@ export default memo(function SubCategory({
}
)} 원본 보관*/}
{categoryItemNewData &&
categoryItemNewData.map(
categoryItemNewData.slice(0, 10).map(
(
{
prdtId,
@@ -332,7 +333,7 @@ export default memo(function SubCategory({
offerInfo,
brndNm,
patncNm,
//foryou,
foryou,
},
itemIndex
) => {
@@ -367,7 +368,7 @@ export default memo(function SubCategory({
}
lastLabel=" go to detail, button"
>
{/* {foryou === true && <Tag text={"For You"} />} */}
{foryou === true && <Tag text={"For You"} />}
</TItemCardNew>
);
}