From 3c3662f791846af202a05a1084e5b0b1ddf12cea Mon Sep 17 00:00:00 2001 From: optrader Date: Wed, 26 Nov 2025 13:17:14 +0900 Subject: [PATCH] [251126] fix: Log Migration - DetailPanel sendLogDetail MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 🕐 커밋 시간: 2025. 11. 26. 13:17:14 📊 변경 통계: • 총 파일: 1개 • 추가: +107줄 • 삭제: -3줄 📝 수정된 파일: ~ com.twin.app.shoptime/src/views/DetailPanel/ProductAllSection/ProductAllSection.jsx 🔧 주요 변경 내용: • 중간 규모 기능 개선 --- .../ProductAllSection/ProductAllSection.jsx | 110 +++++++++++++++++- 1 file changed, 107 insertions(+), 3 deletions(-) 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 bf264351..6bd0822b 100644 --- a/com.twin.app.shoptime/src/views/DetailPanel/ProductAllSection/ProductAllSection.jsx +++ b/com.twin.app.shoptime/src/views/DetailPanel/ProductAllSection/ProductAllSection.jsx @@ -35,9 +35,13 @@ import { } from '../../../actions/commonActions.js'; import { sendLogGNB, + sendLogDetail, + sendLogTotalRecommend, + sendLogProductDetail, + sendLogShopByMobile, } from '../../../actions/logActions'; import { updatePanel } from '../../../actions/panelActions'; -import { panel_names } from '../../../utils/Config'; +import { panel_names, LOG_CONTEXT_NAME, LOG_MESSAGE_ID, LOG_TP_NO } from '../../../utils/Config'; import { getProductCouponDownload, getProductCouponSearch, @@ -63,6 +67,7 @@ import TVirtualGridList from '../../../components/TVirtualGridList/TVirtualGridList.jsx'; import useReviews from '../../../hooks/useReviews/useReviews'; import useScrollTo from '../../../hooks/useScrollTo'; +import { formatGMTString } from '../../../../utils/helperMethods'; import { BUYNOW_CONFIG } from '../../../utils/BuyNowConfig'; import * as Config from '../../../utils/Config.js'; import { @@ -669,6 +674,43 @@ export default function ProductAllSection({ dispatch(resetShowAllReviews()); }, []); // 빈 dependency array = 마운트 시에만 실행 + // 제품 상세 버튼 클릭 핸들러 - Source의 handleIndicatorOptions와 동일한 기능 + const handleIndicatorOptions = useCallback(() => { + if (productData && Object.keys(productData).length > 0) { + // sendLogDetail - 제품 상세 버튼 클릭 로깅 (Source와 동일) + const detailLogParams = { + curationId: productData?.curationId ?? "", + curationNm: productData?.curationNm ?? "", + inDt: "", + linkTpCd: panelInfo?.linkTpCd ?? "", + logTpNo: LOG_TP_NO.DETAIL.DETAIL_BUTTON_CLICK, + patncNm: productData?.patncNm ?? "", + patnrId: productData?.patnrId ?? "", + }; + + dispatch(sendLogDetail(detailLogParams)); + + // sendLogTotalRecommend - 추천 버튼 클릭 로깅 (Source와 동일) + let menuType; + if (isTravelProductVisible) { + menuType = Config.LOG_MENU.DETAIL_PAGE_TRAVEL_THEME_DETAIL; + } else if (isGroupProductVisible) { + menuType = Config.LOG_MENU.DETAIL_PAGE_GROUP_DETAIL; + } else if (isBillingProductVisible) { + menuType = Config.LOG_MENU.DETAIL_PAGE_BILLING_PRODUCT_DETAIL; + } else { + menuType = Config.LOG_MENU.DETAIL_PAGE_PRODUCT_DETAIL; + } + + dispatch(sendLogTotalRecommend({ + menu: menuType, + buttonTitle: "DESCRIPTION", + contextName: LOG_CONTEXT_NAME.DETAILPAGE, + messageId: LOG_MESSAGE_ID.BUTTONCLICK, + })); + } + }, [productData, panelInfo, isBillingProductVisible, isGroupProductVisible, isTravelProductVisible]); + // sendLogGNB 로깅 - Source의 DetailPanel 컴포넌트들과 동일한 패턴 useEffect(() => { if (!entryMenuRef.current) entryMenuRef.current = nowMenu; @@ -708,6 +750,40 @@ export default function ProductAllSection({ } }, [fromPanel?.fromYouMayLike, isBillingProductVisible, isUnavailableProductVisible, isGroupProductVisible, isTravelProductVisible]); // BUY NOW 상태 변경 시 재실행 + // sendLogProductDetail 로깅 - Source의 productData 변경 감지와 동일한 패턴 + useEffect(() => { + if (productData && Object.keys(productData).length > 0) { + const params = { + befPrice: productData?.priceInfo?.split("|")[0], + curationId: productData?.curationId ?? "", + curationNm: productData?.curationNm ?? "", + entryMenu: entryMenuRef.current, + expsOrd: "1", + inDt: formatGMTString(new Date()), + lastPrice: productData?.priceInfo?.split("|")[1], + lgCatCd: productData?.catCd ?? "", + lgCatNm: productData?.catNm ?? "", + linkTpCd: panelInfo?.linkTpCd ?? "", + logTpNo: isTravelProductVisible + ? Config.LOG_TP_NO.PRODUCT.TRAVEL_DETAIL + : isGroupProductVisible + ? Config.LOG_TP_NO.PRODUCT.GROUP_DETAIL + : isBillingProductVisible + ? Config.LOG_TP_NO.PRODUCT.BILLING_PRODUCT_DETAIL + : Config.LOG_TP_NO.PRODUCT.PRODUCT_DETAIL, + patncNm: productData?.patncNm ?? "", + patnrId: productData?.patnrId ?? "", + prdtId: productData?.prdtId ?? "", + prdtNm: productData?.prdtNm ?? "", + revwGrd: productData?.revwGrd ?? "", + rewdAplyFlag: productData.priceInfo?.split("|")[2], + tsvFlag: productData?.todaySpclFlag ?? "", + }; + + return () => dispatch(sendLogProductDetail(params)); + } + }, [productData, entryMenuRef.current, panelInfo?.linkTpCd, isBillingProductVisible, isGroupProductVisible, isTravelProductVisible]); // productData 변경 시 재실행 + // [251115] 주석 처리: MediaPanel에서 이미 포커스 이동을 처리하므로 // ProductAllSection의 자동 포커스는 포커스 탈취를 일으킬 수 있음 // useEffect(() => { @@ -982,7 +1058,32 @@ export default function ProductAllSection({ }, [hasVideo, productVideoVersion]); const handleShopByMobileOpen = useCallback( - pipe(() => true, setMobileSendPopupOpen), + pipe(() => { + // sendLogShopByMobile - Source와 동일한 로깅 추가 + if (productData && Object.keys(productData).length > 0) { + const { priceInfo, patncNm, prdtId, prdtNm, brndNm, catNm } = productData; + const regularPrice = priceInfo?.split("|")[0]; + const discountPrice = priceInfo?.split("|")[1]; + const discountRate = priceInfo?.split("|")[4]; + + const logParams = { + prdtId, + patnrId, + prdtNm, + patncNm, + brndNm, + catNm, + regularPrice, + discountPrice, + discountRate, + shopByMobileTime: new Date().toISOString(), + }; + + dispatch(sendLogShopByMobile(logParams)); + } + + setMobileSendPopupOpen(true); // 팝업 열기 + }, setMobileSendPopupOpen), [] ); @@ -1054,7 +1155,10 @@ export default function ProductAllSection({ const handleProductDetailsClick = useCallback(() => { dispatch(minimizeModalMedia()); scrollToSection('scroll-marker-product-details'); - }, [scrollToSection, dispatch]); + + // Source의 handleIndicatorOptions와 동일한 로깅 기능 추가 + handleIndicatorOptions(); + }, [scrollToSection, dispatch, handleIndicatorOptions]); const handleYouMayAlsoLikeClick = useCallback(() => { dispatch(minimizeModalMedia());