diff --git a/com.twin.app.shoptime/src/actions/actionTypes.js b/com.twin.app.shoptime/src/actions/actionTypes.js index 595b6408..899acac2 100644 --- a/com.twin.app.shoptime/src/actions/actionTypes.js +++ b/com.twin.app.shoptime/src/actions/actionTypes.js @@ -137,6 +137,9 @@ export const types = { RESET_BRAND_STATE: 'RESET_BRAND_STATE', RESET_BRAND_STATE_EXCEPT_BRAND_INFO: 'RESET_BRAND_STATE_EXCEPT_BRAND_INFO', RESET_BRAND_LAYOUT_INFO: 'RESET_BRAND_LAYOUT_INFO', + // 🆕 [251210] patnrId=21 카테고리 그룹 데이터 관리 + SET_BRAND_SHOP_BY_SHOW_CATEGORY_GROUPS: 'SET_BRAND_SHOP_BY_SHOW_CATEGORY_GROUPS', + RESET_BRAND_SHOP_BY_SHOW_CATEGORY_GROUPS: 'RESET_BRAND_SHOP_BY_SHOW_CATEGORY_GROUPS', // main actions GET_SUB_CATEGORY: 'GET_SUB_CATEGORY', diff --git a/com.twin.app.shoptime/src/actions/brandActions.js b/com.twin.app.shoptime/src/actions/brandActions.js index 713472f0..7b835478 100644 --- a/com.twin.app.shoptime/src/actions/brandActions.js +++ b/com.twin.app.shoptime/src/actions/brandActions.js @@ -410,6 +410,8 @@ export const getBrandShopByShow = (props) => (dispatch, getState) => { type: types.GET_BRAND_SHOP_BY_SHOW, payload: { data: response.data.data, + patnrId, + contsId, }, }); diff --git a/com.twin.app.shoptime/src/reducers/brandReducer.js b/com.twin.app.shoptime/src/reducers/brandReducer.js index 96c76408..7eb92d6d 100644 --- a/com.twin.app.shoptime/src/reducers/brandReducer.js +++ b/com.twin.app.shoptime/src/reducers/brandReducer.js @@ -52,6 +52,9 @@ const initialState = { brandTopBannerData: { data: {}, }, + + // 🆕 [251210] patnrId=21 카테고리 그룹 데이터 저장소 + brandShopByShowCategoryGroups: {}, }; export const brandReducer = (state = initialState, action) => { @@ -174,12 +177,31 @@ export const brandReducer = (state = initialState, action) => { ? nextData : { ...prevData, ...nextData, brandShopByShowContsList: prevData.brandShopByShowContsList }; + // 🆕 [251210] patnrId=21인 경우 그룹 데이터 별도 저장 + const updatedCategoryGroups = { ...state.brandShopByShowCategoryGroups }; + + if (action.payload?.patnrId === 21 || action.payload?.patnrId === "21") { + const patnrId = String(action.payload.patnrId); + + // patnrId별 그룹 데이터가 없으면 초기화 + if (!updatedCategoryGroups[patnrId]) { + updatedCategoryGroups[patnrId] = {}; + } + + // 현재 contsId에 대한 그룹 정보 저장 + if (nextData.brandShopByShowContsInfo?.contsId) { + const contsId = nextData.brandShopByShowContsInfo.contsId; + updatedCategoryGroups[patnrId][contsId] = nextData.brandShopByShowContsInfo; + } + } + return { ...state, brandShopByShowData: { ...action.payload, data: mergedData, }, + brandShopByShowCategoryGroups: updatedCategoryGroups, }; } @@ -218,6 +240,25 @@ export const brandReducer = (state = initialState, action) => { }; } + // 🆕 [251210] patnrId=21 카테고리 그룹 데이터 설정 + case types.SET_BRAND_SHOP_BY_SHOW_CATEGORY_GROUPS: { + return { + ...state, + brandShopByShowCategoryGroups: { + ...state.brandShopByShowCategoryGroups, + ...action.payload, + }, + }; + } + + // 🆕 [251210] patnrId=21 카테고리 그룹 데이터 초기화 + case types.RESET_BRAND_SHOP_BY_SHOW_CATEGORY_GROUPS: { + return { + ...state, + brandShopByShowCategoryGroups: {}, + }; + } + default: return state; } diff --git a/com.twin.app.shoptime/src/views/DetailPanel/ProductAllSection/ProductAllSection.jsx b/com.twin.app.shoptime/src/views/DetailPanel/ProductAllSection/ProductAllSection.jsx index 92008749..87c4fa64 100644 --- a/com.twin.app.shoptime/src/views/DetailPanel/ProductAllSection/ProductAllSection.jsx +++ b/com.twin.app.shoptime/src/views/DetailPanel/ProductAllSection/ProductAllSection.jsx @@ -1108,6 +1108,7 @@ export default function ProductAllSection({ const descriptionRef = useRef(null); const reviewRef = useRef(null); const youMayAlsoLikelRef = useRef(null); + const seeMoreProductsRef = useRef(null); const prevMediaPanelModalStateRef = useRef(null); // MediaPanel의 이전 modal 상태 추적 // 동영상과 이미지를 통합한 렌더링 아이템 리스트 생성 (Indicator.jsx 로직 기반) @@ -1264,6 +1265,15 @@ export default function ProductAllSection({ Spotlight.focus("detail_youMayAlsoLike_area") },100); }, [scrollToSection, dispatch]); + + const handleSeeMoreProductsClick = useCallback(() => { + console.log('[SEE MORE PRODUCTS] Button clicked - currently no action'); + // TODO: 나중에 그룹 상품 표시 로직 추가 + scrollToSection('scroll-marker-see-more-products'); + setTimeout(() => { + Spotlight.focus("see-more-products-area"); + }, 100); + }, [scrollToSection]); // 헤더 Back 아이콘에서 아래로 내려올 때 첫 번째 버튼을 바라보도록 설정 useEffect(() => { const firstId = stackOrder[0]; @@ -1751,10 +1761,27 @@ export default function ProductAllSection({ activeButton === 'youmaylike' ? css.active : '' )} onClick={handleYouMayAlsoLikeClick} + onFocus={() => handleButtonFocus('youmaylike')} + onBlur={handleButtonBlur} > {$L('YOU MAY ALSO LIKE')} )} + {/* 🆕 [251210] patnrId=21인 경우 SEE MORE PRODUCTS 버튼 */} + {(panelInfo?.patnrId === 21 || panelInfo?.patnrId === "21") && ( + handleButtonFocus('seemoreproducts')} + onBlur={handleButtonBlur} + spotlightId="see-more-products-button" + > + {$L('SEE MORE PRODUCTS')} + + )} {/* YouMayLike 버튼 렌더링 상태 로그 */} {/* {(() => { console.log('[YouMayLike] 버튼 렌더링 체크:', { @@ -1938,6 +1965,20 @@ export default function ProductAllSection({ )} + + {/* 🆕 [251210] patnrId=21인 경우 SEE MORE PRODUCTS 섹션 */} + {(panelInfo?.patnrId === 21 || panelInfo?.patnrId === "21") && ( +
+
+
+ {/* TODO: 나중에 그룹 상품 표시 컴포넌트 추가 */} +
+

SEE MORE PRODUCTS

+

그룹 상품이 여기에 표시될 예정입니다

+
+
+
+ )}
{ const brandTopBannerInfo = useSelector( (state) => state.brand.brandTopBannerData.data.brandTopBannerInfo ); + // 🆕 [251210] patnrId=21 카테고리 그룹 데이터 + const brandShopByShowCategoryGroups = useSelector( + (state) => state.brand.brandShopByShowCategoryGroups + ); const [displayTopButton, setDisplayTopButton] = useState(false); const [focusedContainerId, setFocusedContainerId] = useState(null); @@ -310,6 +314,9 @@ const FeaturedBrandsPanel = ({ isOnTop, panelInfo, spotlightId }) => { }); const renderedShelfCountRef = useRef(0); + // 🆕 [251210] patnrId=21 카테고리 그룹 조회 상태 추적 + const fetchedCategoryGroupsRef = useRef(new Set()); + const fromDetail = panelInfo?.from && panelInfo.from === "detail"; const fromGNB = panelInfo?.from && panelInfo.from === "gnb"; const fromUpcoming = panelInfo?.from && panelInfo.from === "upcoming"; @@ -803,6 +810,18 @@ const FeaturedBrandsPanel = ({ isOnTop, panelInfo, spotlightId }) => { console.log("[FB-PANEL-DATA-FETCH] sortedBrandLayoutInfo:", sortedBrandLayoutInfo); console.log("[FB-PANEL-DATA-FETCH] selectedPatnrId:", selectedPatnrId); + // 🆕 [251210] patnrId 변경 시 조회 상태 초기화 + if (selectedPatnrId) { + const patnrIdString = String(selectedPatnrId); + // 이전 patnrId와 다르면 ref 초기화 + const currentFetchKeys = Array.from(fetchedCategoryGroupsRef.current).filter(key => key.startsWith(patnrIdString)); + if (currentFetchKeys.length === 0) { + console.log("[FB-PANEL-DATA-FETCH] patnrId changed, clearing category group fetch status"); + // 다른 patnrId로 전환 시 ref 초기화 + fetchedCategoryGroupsRef.current.clear(); + } + } + if (sortedBrandLayoutInfo && selectedPatnrId) { console.log("[FB-PANEL-DATA-FETCH] Fetching data - patnrId:", selectedPatnrId); Object.entries(DISPATCH_MAP) // @@ -835,6 +854,33 @@ const FeaturedBrandsPanel = ({ isOnTop, panelInfo, spotlightId }) => { } }, [sortedBrandLayoutInfo, selectedPatnrId]); + // 🆕 [251210] patnrId=21인 경우 모든 카테고리 그룹 데이터 미리 조회 + useEffect(() => { + if (selectedPatnrId === 21 || selectedPatnrId === "21") { + console.log("[FB-PANEL-CATEGORY-GROUPS] patnrId=21 detected - fetching all category group data"); + console.log("[FB-PANEL-CATEGORY-GROUPS] brandShopByShowContsList:", brandShopByShowContsList); + + // 각 카테고리(contsId)별 그룹 데이터 조회 + if (brandShopByShowContsList && brandShopByShowContsList.length > 0) { + brandShopByShowContsList.forEach((conts) => { + const fetchKey = `${selectedPatnrId}-${conts.contsId}`; + + // useRef로 이미 조회된 contsId 추적 (무한루프 방지) + if (!fetchedCategoryGroupsRef.current.has(fetchKey)) { + console.log("[FB-PANEL-CATEGORY-GROUPS] Fetching category group for contsId:", conts.contsId); + fetchedCategoryGroupsRef.current.add(fetchKey); // 조회 상태 기록 + dispatch(getBrandShopByShow({ + patnrId: selectedPatnrId, + contsId: conts.contsId + })); + } else { + console.log("[FB-PANEL-CATEGORY-GROUPS] Category group already fetched for contsId:", conts.contsId); + } + }); + } + } + }, [selectedPatnrId, brandShopByShowContsList, dispatch]); // brandShopByShowCategoryGroups 제거 + useEffect(() => { if (selectedCatCd) { dispatch(