diff --git a/com.twin.app.shoptime/src/actions/mainActions.js b/com.twin.app.shoptime/src/actions/mainActions.js index e1469564..448b4f1d 100644 --- a/com.twin.app.shoptime/src/actions/mainActions.js +++ b/com.twin.app.shoptime/src/actions/mainActions.js @@ -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 diff --git a/com.twin.app.shoptime/src/reducers/mainReducer.js b/com.twin.app.shoptime/src/reducers/mainReducer.js index a66815c7..8143b9f5 100644 --- a/com.twin.app.shoptime/src/reducers/mainReducer.js +++ b/com.twin.app.shoptime/src/reducers/mainReducer.js @@ -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: diff --git a/com.twin.app.shoptime/src/utils/Config.js b/com.twin.app.shoptime/src/utils/Config.js index 9be17c52..9a7d1fb7 100644 --- a/com.twin.app.shoptime/src/utils/Config.js +++ b/com.twin.app.shoptime/src/utils/Config.js @@ -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', diff --git a/com.twin.app.shoptime/src/views/HomePanel/BestSeller/BestSeller.jsx b/com.twin.app.shoptime/src/views/HomePanel/BestSeller/BestSeller.jsx index 7b224278..6640e283 100644 --- a/com.twin.app.shoptime/src/views/HomePanel/BestSeller/BestSeller.jsx +++ b/com.twin.app.shoptime/src/views/HomePanel/BestSeller/BestSeller.jsx @@ -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(() => { + useEffect(() => { setDrawChk(true); - }, [bestSellerDatas]); + }, [bestSellerNewDatas]); const handleCardClick = useCallback( (patnrId, prdtId) => () => { @@ -176,22 +191,7 @@ const BestSeller = ({ handleShelfFocus(); } }, [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 ( - {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} > diff --git a/com.twin.app.shoptime/src/views/HomePanel/HomePanel.jsx b/com.twin.app.shoptime/src/views/HomePanel/HomePanel.jsx index 091e5598..123fdc68 100644 --- a/com.twin.app.shoptime/src/views/HomePanel/HomePanel.jsx +++ b/com.twin.app.shoptime/src/views/HomePanel/HomePanel.jsx @@ -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 ( + + ); + } else break; + } } })} {loadingComplete && sortedHomeLayoutInfo && sortedHomeLayoutInfo.length > 0 && ( @@ -593,6 +636,7 @@ const HomePanel = ({ isOnTop }) => { pageSize: 10, tabType: 'CAT00102', filterType: 'CAT00202', + recommendIncFlag: 'Y', }, 1 ) diff --git a/com.twin.app.shoptime/src/views/HomePanel/PickedForYou/PickedForYou.jsx b/com.twin.app.shoptime/src/views/HomePanel/PickedForYou/PickedForYou.jsx index 9dbb6e57..f53a0f0a 100644 --- a/com.twin.app.shoptime/src/views/HomePanel/PickedForYou/PickedForYou.jsx +++ b/com.twin.app.shoptime/src/views/HomePanel/PickedForYou/PickedForYou.jsx @@ -52,7 +52,7 @@ const PickedForYou = ({ shelfLocation, shelfTitle, }) => { - console.log("###Test pjh 여기지 ?"); + const { getScrollTo, scrollLeft } = useScrollTo(); const { handleScrollReset, handleStopScrolling } = useScrollReset( scrollLeft, @@ -67,11 +67,26 @@ 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); }, [justForYouDatas]); @@ -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" /> ); diff --git a/com.twin.app.shoptime/src/views/HomePanel/SubCategory/SubCategory.jsx b/com.twin.app.shoptime/src/views/HomePanel/SubCategory/SubCategory.jsx index f366aac2..16d31437 100644 --- a/com.twin.app.shoptime/src/views/HomePanel/SubCategory/SubCategory.jsx +++ b/com.twin.app.shoptime/src/views/HomePanel/SubCategory/SubCategory.jsx @@ -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) => ({ - ...item, - foryou: _randomProduct(), - })) - ); - }, [categoryItemInfos?.subCatItemList]); - - useEffect(() => { - dispatch( - getRecentlySawItem( - categoryItemNewData.filter((item) => item.foryou === true) - ) - ); - }, [categoryItemNewData, dispatch]); + const recommendedData = foruItemInfos?.slice(0, 2).map((item) => ({ + ...item, + foryou: true, + })) || []; + + 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 ( { @@ -367,7 +368,7 @@ export default memo(function SubCategory({ } lastLabel=" go to detail, button" > - {/* {foryou === true && } */} + {foryou === true && } ); }