[251124] fix: App.js 로그 정리 및 최적화-2

🕐 커밋 시간: 2025. 11. 24. 09:24:08

📊 변경 통계:
  • 총 파일: 5개
  • 추가: +156줄
  • 삭제: -111줄

📝 수정된 파일:
  ~ com.twin.app.shoptime/src/actions/empActions.js
  ~ com.twin.app.shoptime/src/hooks/useFocusHistory/useFocusHistory.js
  ~ com.twin.app.shoptime/src/lunaSend/common.js
  ~ com.twin.app.shoptime/src/views/CheckOutPanel/CheckOutPanel.jsx
  ~ com.twin.app.shoptime/src/views/HomePanel/HomePanel.jsx

🔧 함수 변경 내용:
  📄 com.twin.app.shoptime/src/hooks/useFocusHistory/useFocusHistory.js (javascript):
     Added: dwarn(), derror()
    🔄 Modified: getOrCreateGlobalBuffer()
  📄 com.twin.app.shoptime/src/lunaSend/common.js (javascript):
     Added: dwarn(), derror()
  📄 com.twin.app.shoptime/src/views/HomePanel/HomePanel.jsx (javascript):
     Added: dwarn(), derror()

🔧 주요 변경 내용:
  • 핵심 비즈니스 로직 개선
This commit is contained in:
2025-11-24 09:24:08 +09:00
parent 6d0cf78534
commit e2a50b62ab
5 changed files with 479 additions and 360 deletions

View File

@@ -1,27 +1,12 @@
import React, {
useCallback,
useEffect,
useMemo,
useRef,
useState,
} from 'react';
import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import {
useDispatch,
useSelector,
} from 'react-redux';
import { useDispatch, useSelector } from 'react-redux';
import { Job } from '@enact/core/util';
import Spotlight from '@enact/spotlight';
import {
getCheckoutTotalAmt,
resetCheckoutData,
} from '../../actions/checkoutActions';
import {
setHidePopup,
setShowPopup,
} from '../../actions/commonActions';
import { getCheckoutTotalAmt, resetCheckoutData } from '../../actions/checkoutActions';
import { setHidePopup, setShowPopup } from '../../actions/commonActions';
import { getShoptimeTerms } from '../../actions/empActions';
import {
sendLogCheckOutBtnClick,
@@ -30,10 +15,7 @@ import {
sendLogPaymentEntry,
sendLogTotalRecommend,
} from '../../actions/logActions';
import {
popPanel,
updatePanel,
} from '../../actions/panelActions';
import { popPanel, updatePanel } from '../../actions/panelActions';
import TBody from '../../components/TBody/TBody';
import TButton from '../../components/TButton/TButton';
import TButtonScroller from '../../components/TButtonScroller/TButtonScroller';
@@ -46,11 +28,7 @@ import TQRCode from '../../components/TQRCode/TQRCode';
import useScrollTo from '../../hooks/useScrollTo';
import { BUYNOW_CONFIG } from '../../utils/BuyNowConfig';
import * as Config from '../../utils/Config';
import {
$L,
scaleH,
scaleW,
} from '../../utils/helperMethods';
import { $L, scaleH, scaleW } from '../../utils/helperMethods';
import {
getSafeCurrencyInfo,
getSafeFirstProduct,
@@ -68,7 +46,7 @@ import SummaryContainer from './container/SummaryCotainer';
export default function CheckOutPanel({ panelInfo }) {
// DEBUG_LOG 설정 - 이 값이 true일 때만 console.log가 실행됨
const DEBUG_LOG = true; // 계속 활성화하여 디버깅
const DEBUG_LOG = false; // 계속 활성화하여 디버깅
// console.log 오버라이드를 위한 ref
const originalConsoleLog = useRef();
@@ -85,32 +63,75 @@ export default function CheckOutPanel({ panelInfo }) {
}
};
console.log('%c[BuyOption][CheckOutPanel] ▶️ Component mounted START', 'background: blue; color: white; font-weight: bold; padding: 5px;');
console.log('%c🚨🚨🚨 CHECKOUT PANEL PANELINFO ANALYSIS 🚨🚨🚨', 'background: yellow; color: black; font-weight: bold; font-size: 14px; padding: 5px;');
console.log(
'%c[BuyOption][CheckOutPanel] ▶️ Component mounted START',
'background: blue; color: white; font-weight: bold; padding: 5px;'
);
console.log(
'%c🚨🚨🚨 CHECKOUT PANEL PANELINFO ANALYSIS 🚨🚨🚨',
'background: yellow; color: black; font-weight: bold; font-size: 14px; padding: 5px;'
);
console.log('%cpanelInfo:', 'background: yellow; color: black; padding: 3px;', panelInfo);
console.log('%cpanelInfo.isFromCart:', 'background: yellow; color: black; padding: 3px;', panelInfo?.isFromCart);
console.log('%cpanelInfo.fromCartPanel:', 'background: yellow; color: black; padding: 3px;', panelInfo?.fromCartPanel);
console.log('%cpanelInfo.cartItems:', 'background: yellow; color: black; padding: 3px;', panelInfo?.cartItems);
console.log('%cpanelInfo.cartItems type:', 'background: yellow; color: black; padding: 3px;', typeof panelInfo?.cartItems);
console.log('%cpanelInfo.cartItems length:', 'background: yellow; color: black; padding: 3px;', panelInfo?.cartItems?.length);
console.log('%cpanelInfo.productInfo:', 'background: yellow; color: black; padding: 3px;', panelInfo?.productInfo);
console.log('%cpanelInfo.logInfo:', 'background: yellow; color: black; padding: 3px;', panelInfo?.logInfo);
console.log('[BuyOption][CheckOutPanel] Current panels:', panels?.map((p) => ({ name: p.name, hasModal: !!p.panelInfo?.modal })));
console.log(
'%cpanelInfo.isFromCart:',
'background: yellow; color: black; padding: 3px;',
panelInfo?.isFromCart
);
console.log(
'%cpanelInfo.fromCartPanel:',
'background: yellow; color: black; padding: 3px;',
panelInfo?.fromCartPanel
);
console.log(
'%cpanelInfo.cartItems:',
'background: yellow; color: black; padding: 3px;',
panelInfo?.cartItems
);
console.log(
'%cpanelInfo.cartItems type:',
'background: yellow; color: black; padding: 3px;',
typeof panelInfo?.cartItems
);
console.log(
'%cpanelInfo.cartItems length:',
'background: yellow; color: black; padding: 3px;',
panelInfo?.cartItems?.length
);
console.log(
'%cpanelInfo.productInfo:',
'background: yellow; color: black; padding: 3px;',
panelInfo?.productInfo
);
console.log(
'%cpanelInfo.logInfo:',
'background: yellow; color: black; padding: 3px;',
panelInfo?.logInfo
);
console.log(
'[BuyOption][CheckOutPanel] Current panels:',
panels?.map((p) => ({ name: p.name, hasModal: !!p.panelInfo?.modal }))
);
// PlayerPanel 충돌 방지: PlayerPanel이 있고 modal 상태면 비활성화
const playerPanelIndex = panels?.findIndex(p =>
p.name === Config.panel_names.PLAYER_PANEL ||
p.name === Config.panel_names.PLAYER_PANEL_NEW ||
p.name === Config.panel_names.MEDIA_PANEL
const playerPanelIndex = panels?.findIndex(
(p) =>
p.name === Config.panel_names.PLAYER_PANEL ||
p.name === Config.panel_names.PLAYER_PANEL_NEW ||
p.name === Config.panel_names.MEDIA_PANEL
);
if (playerPanelIndex >= 0) {
console.log('[BuyOption][CheckOutPanel] 🚨 PlayerPanel/MediaPanel detected at index:', playerPanelIndex);
console.log(
'[BuyOption][CheckOutPanel] 🚨 PlayerPanel/MediaPanel detected at index:',
playerPanelIndex
);
console.log('[BuyOption][CheckOutPanel] PlayerPanel info:', panels[playerPanelIndex]);
// PlayerPanel/MediaPanel 상태를 비활성화하여 CheckOutPanel과의 충돌 방지
if (panels[playerPanelIndex].panelInfo?.modal) {
console.log('[BuyOption][CheckOutPanel] 🔄 Disabling modal PlayerPanel to prevent conflicts');
console.log(
'[BuyOption][CheckOutPanel] 🔄 Disabling modal PlayerPanel to prevent conflicts'
);
// 필요하다면 여기서 PlayerPanel 상태를 비활성화하는 액션을 디스패치할 수 있음
// dispatch(updatePanel({
// name: panels[playerPanelIndex].name,
@@ -143,38 +164,97 @@ export default function CheckOutPanel({ panelInfo }) {
// Mock Mode: panelInfo.productInfo 또는 Redux에서 상품 데이터 사용
const productData = BUYNOW_CONFIG.isMockMode()
? (() => {
console.log('%c🚨🚨🚨 MOCK MODE DATA SELECTION START 🚨🚨🚨', 'background: yellow; color: black; font-weight: bold; font-size: 14px; padding: 5px;');
console.log('%cisFromCart condition check:', 'background: yellow; color: black; padding: 3px;');
console.log('%c - panelInfo?.isFromCart:', 'background: yellow; color: black; padding: 3px;', panelInfo?.isFromCart);
console.log('%c - panelInfo?.cartItems exists:', 'background: yellow; color: black; padding: 3px;', !!panelInfo?.cartItems);
console.log('%c - Array.isArray(panelInfo?.cartItems):', 'background: yellow; color: black; padding: 3px;', Array.isArray(panelInfo?.cartItems));
console.log('%c - panelInfo?.cartItems.length > 0:', 'background: yellow; color: black; padding: 3px;', panelInfo?.cartItems?.length > 0);
console.log(
'%c🚨🚨🚨 MOCK MODE DATA SELECTION START 🚨🚨🚨',
'background: yellow; color: black; font-weight: bold; font-size: 14px; padding: 5px;'
);
console.log(
'%cisFromCart condition check:',
'background: yellow; color: black; padding: 3px;'
);
console.log(
'%c - panelInfo?.isFromCart:',
'background: yellow; color: black; padding: 3px;',
panelInfo?.isFromCart
);
console.log(
'%c - panelInfo?.cartItems exists:',
'background: yellow; color: black; padding: 3px;',
!!panelInfo?.cartItems
);
console.log(
'%c - Array.isArray(panelInfo?.cartItems):',
'background: yellow; color: black; padding: 3px;',
Array.isArray(panelInfo?.cartItems)
);
console.log(
'%c - panelInfo?.cartItems.length > 0:',
'background: yellow; color: black; padding: 3px;',
panelInfo?.cartItems?.length > 0
);
// ✅ 1순위: CartPanel에서 전달된 cartItems (전체 카트 데이터)
if (panelInfo?.isFromCart && panelInfo?.cartItems && Array.isArray(panelInfo.cartItems) && panelInfo.cartItems.length > 0) {
console.log('%c✅ SUCCESS! Using cartItems from CartPanel (multi-product) ✅', 'background: green; color: white; font-weight: bold; font-size: 14px; padding: 5px;');
console.log('%ccartItems:', 'background: green; color: white; padding: 3px;', panelInfo.cartItems);
console.log('%ccartItems count:', 'background: green; color: white; padding: 3px;', panelInfo.cartItems.length);
if (
panelInfo?.isFromCart &&
panelInfo?.cartItems &&
Array.isArray(panelInfo.cartItems) &&
panelInfo.cartItems.length > 0
) {
console.log(
'%c✅ SUCCESS! Using cartItems from CartPanel (multi-product) ✅',
'background: green; color: white; font-weight: bold; font-size: 14px; padding: 5px;'
);
console.log(
'%ccartItems:',
'background: green; color: white; padding: 3px;',
panelInfo.cartItems
);
console.log(
'%ccartItems count:',
'background: green; color: white; padding: 3px;',
panelInfo.cartItems.length
);
return panelInfo.cartItems;
}
console.log('%c❌ FAILED! isFromCart condition FAILED ❌', 'background: red; color: white; font-weight: bold; font-size: 14px; padding: 5px;');
console.log('%cTrying next condition - productInfo check...', 'background: red; color: white; padding: 3px;');
console.log(
'%c❌ FAILED! isFromCart condition FAILED ❌',
'background: red; color: white; font-weight: bold; font-size: 14px; padding: 5px;'
);
console.log(
'%cTrying next condition - productInfo check...',
'background: red; color: white; padding: 3px;'
);
// 2순위: BuyOption에서 전달된 productInfo (단일 상품)
if (panelInfo?.productInfo) {
console.log('%c[BuyOption][CheckOutPanel] ✅ Mock Mode - Using panelInfo.productInfo (single product):', 'background: green; color: white; font-weight: bold; padding: 5px;', panelInfo.productInfo);
console.log(
'%c[BuyOption][CheckOutPanel] ✅ Mock Mode - Using panelInfo.productInfo (single product):',
'background: green; color: white; font-weight: bold; padding: 5px;',
panelInfo.productInfo
);
return [panelInfo.productInfo];
}
// 3순위: Redux에서 가져온 상품 데이터
if (reduxProductData && Array.isArray(reduxProductData) && reduxProductData.length > 0) {
console.log('%c[BuyOption][CheckOutPanel] ✅ Mock Mode - Using reduxProductData:', 'background: green; color: white; font-weight: bold; padding: 5px;', 'count=' + reduxProductData.length);
console.log(
'%c[BuyOption][CheckOutPanel] ✅ Mock Mode - Using reduxProductData:',
'background: green; color: white; font-weight: bold; padding: 5px;',
'count=' + reduxProductData.length
);
return reduxProductData;
}
// 4순위: 기본 Hardcoded Mock 데이터 (최후의 fallback)
console.error('%c[BuyOption][CheckOutPanel] ⚠️ Mock Mode - Using fallback mock data:', 'background: orange; color: white; font-weight: bold; padding: 5px;', 'panelInfo=', panelInfo, 'reduxProductData=', reduxProductData);
console.error(
'%c[BuyOption][CheckOutPanel] ⚠️ Mock Mode - Using fallback mock data:',
'background: orange; color: white; font-weight: bold; padding: 5px;',
'panelInfo=',
panelInfo,
'reduxProductData=',
reduxProductData
);
return [
{
prdtId: 'MOCK_PRODUCT_1',
@@ -192,16 +272,37 @@ export default function CheckOutPanel({ panelInfo }) {
})()
: reduxProductData;
console.log('%c🚨🚨🚨 FINAL PRODUCT DATA RESULT 🚨🚨🚨', 'background: yellow; color: black; font-weight: bold; font-size: 14px; padding: 5px;');
console.log('%cisMockMode:', 'background: yellow; color: black; padding: 3px;', BUYNOW_CONFIG.isMockMode());
console.log('%cproductData loaded:', 'background: yellow; color: black; padding: 3px;', productData && productData.length, 'items');
console.log('%cproductData[0].prdtId:', 'background: yellow; color: black; padding: 3px;', productData?.[0]?.prdtId);
console.log('%cproductData length:', 'background: yellow; color: black; padding: 3px;', productData?.length || 0);
console.log(
'%c🚨🚨🚨 FINAL PRODUCT DATA RESULT 🚨🚨🚨',
'background: yellow; color: black; font-weight: bold; font-size: 14px; padding: 5px;'
);
console.log(
'%cisMockMode:',
'background: yellow; color: black; padding: 3px;',
BUYNOW_CONFIG.isMockMode()
);
console.log(
'%cproductData loaded:',
'background: yellow; color: black; padding: 3px;',
productData && productData.length,
'items'
);
console.log(
'%cproductData[0].prdtId:',
'background: yellow; color: black; padding: 3px;',
productData?.[0]?.prdtId
);
console.log(
'%cproductData length:',
'background: yellow; color: black; padding: 3px;',
productData?.length || 0
);
console.log('%cproductData:', 'background: yellow; color: black; padding: 3px;', productData);
// 표시용으로 모든 상품 데이터 정규화 (없는 필드는 안전한 기본값으로)
// Mock 모드에서는 항상 정규화, API 모드에서는 그대로 사용
const normalizedProductData = productData?.map((prod) => normalizeProductDataForDisplay(prod)) || [];
const normalizedProductData =
productData?.map((prod) => normalizeProductDataForDisplay(prod)) || [];
const safeProductData = BUYNOW_CONFIG.isMockMode() ? normalizedProductData : productData;
console.log('[BuyOption][CheckOutPanel] productData (normalized):', normalizedProductData);
@@ -259,7 +360,10 @@ export default function CheckOutPanel({ panelInfo }) {
const spotJob = useRef(new Job((func) => func(), 0));
useEffect(() => {
console.log('[BuyOption][CheckOutPanel] sendLogGNB useEffect - isOrderSuccessful:', isOrderSuccessful);
console.log(
'[BuyOption][CheckOutPanel] sendLogGNB useEffect - isOrderSuccessful:',
isOrderSuccessful
);
let nowMenu;
if (isOrderSuccessful) {
@@ -321,7 +425,9 @@ export default function CheckOutPanel({ panelInfo }) {
// Mock Mode: API 호출 스킵
if (BUYNOW_CONFIG.isMockMode()) {
console.log('[BuyOption][CheckOutPanel] Mock Mode - Skipping checkout total amount calculation');
console.log(
'[BuyOption][CheckOutPanel] Mock Mode - Skipping checkout total amount calculation'
);
return;
}
@@ -356,7 +462,9 @@ export default function CheckOutPanel({ panelInfo }) {
infoForCheckoutData.dlvrAddrSno &&
infoForCheckoutData.bilAddrSno
) {
console.log('[BuyOption][CheckOutPanel] ✅ All conditions met - Calling getCheckoutTotalAmt');
console.log(
'[BuyOption][CheckOutPanel] ✅ All conditions met - Calling getCheckoutTotalAmt'
);
dispatch(
getCheckoutTotalAmt(
{
@@ -364,7 +472,7 @@ export default function CheckOutPanel({ panelInfo }) {
dirPurcSelYn: cartSelectInfo.length > 0 ? 'N' : 'Y',
bilAddrSno: infoForCheckoutData.bilAddrSno,
dlvrAddrSno: infoForCheckoutData.dlvrAddrSno,
isPageLoading: "Y",
isPageLoading: 'Y',
orderProductCoupontUse,
},
totalAmtValidate
@@ -428,12 +536,14 @@ export default function CheckOutPanel({ panelInfo }) {
console.log('[CheckOutPanel] onBackClick - Sending reload signal to DetailPanel');
// DetailPanel에 재시작 신호 전달
dispatch(updatePanel({
name: Config.panel_names.DETAIL_PANEL,
panelInfo: {
shouldReload: true,
}
}));
dispatch(
updatePanel({
name: Config.panel_names.DETAIL_PANEL,
panelInfo: {
shouldReload: true,
},
})
);
// CheckOutPanel 제거
dispatch(popPanel(Config.panel_names.CHECKOUT_PANEL));
@@ -442,7 +552,10 @@ export default function CheckOutPanel({ panelInfo }) {
}, [dispatch, panels]);
const toggleOrderSideBar = useCallback(() => {
console.log('[BuyOption][CheckOutPanel] toggleOrderSideBar called - current state:', orderSideBarOpen);
console.log(
'[BuyOption][CheckOutPanel] toggleOrderSideBar called - current state:',
orderSideBarOpen
);
if (!orderSideBarOpen) {
dispatch(sendLogCheckOutBtnClick({ btnNm: 'ORDER ITEMS' }));
dispatch(
@@ -460,7 +573,10 @@ export default function CheckOutPanel({ panelInfo }) {
}, [orderSideBarOpen, dispatch]);
const toggleOfferSideBar = useCallback(() => {
console.log('[BuyOption][CheckOutPanel] toggleOfferSideBar called - current state:', offerSideBarOpen);
console.log(
'[BuyOption][CheckOutPanel] toggleOfferSideBar called - current state:',
offerSideBarOpen
);
if (!offerSideBarOpen) {
dispatch(sendLogCheckOutBtnClick({ btnNm: 'OFFERS & PROMOTION' }));
dispatch(
@@ -489,7 +605,9 @@ export default function CheckOutPanel({ panelInfo }) {
}, [dispatch]);
const handlePopPanel = useCallback(() => {
console.log('[BuyOption][CheckOutPanel] handlePopPanel called - dispatching setHidePopup and popPanel');
console.log(
'[BuyOption][CheckOutPanel] handlePopPanel called - dispatching setHidePopup and popPanel'
);
dispatch(setHidePopup());
dispatch(popPanel());
}, [dispatch]);
@@ -564,12 +682,14 @@ export default function CheckOutPanel({ panelInfo }) {
console.log('[CheckOutPanel] onCancelCheckoutPanel - Sending reload signal to DetailPanel');
// DetailPanel에 재시작 신호 전달
dispatch(updatePanel({
name: Config.panel_names.DETAIL_PANEL,
panelInfo: {
shouldReload: true,
}
}));
dispatch(
updatePanel({
name: Config.panel_names.DETAIL_PANEL,
panelInfo: {
shouldReload: true,
},
})
);
// CheckOutPanel 제거
dispatch(popPanel(Config.panel_names.CHECKOUT_PANEL));
@@ -591,9 +711,7 @@ export default function CheckOutPanel({ panelInfo }) {
dispatch(sendLogMyInfoEdit({ btnNm }));
}, []);
const checkOutPanelInfo = panels.find(
(panel) => panel.name === "checkoutpanel"
)?.panelInfo;
const checkOutPanelInfo = panels.find((panel) => panel.name === 'checkoutpanel')?.panelInfo;
console.log(
'[CheckOutPanel] Rendering - orderSideBarOpen:',
@@ -635,14 +753,14 @@ export default function CheckOutPanel({ panelInfo }) {
fromCartPanel={panelInfo?.fromCartPanel}
/>
) : ( */}
<SummaryContainer
setPlaceOrderPopup={setPlaceOrderPopup}
empTermsData={empTermsData}
handleTermsClick={handleTermsClick}
currSign={currSign}
currSignLoc={currSignLoc}
doSendLogPaymentEntry={doSendLogPaymentEntry}
/>
<SummaryContainer
setPlaceOrderPopup={setPlaceOrderPopup}
empTermsData={empTermsData}
handleTermsClick={handleTermsClick}
currSign={currSign}
currSignLoc={currSignLoc}
doSendLogPaymentEntry={doSendLogPaymentEntry}
/>
{/* )} */}
{/* {BUYNOW_CONFIG.isMockMode() ? (
<InformationContainerMock
@@ -653,12 +771,12 @@ export default function CheckOutPanel({ panelInfo }) {
orderItemsCount={orderItemsCount}
/>
) : ( */}
<InformationContainer
toggleOrderSideBar={toggleOrderSideBar}
toggleOfferSideBar={toggleOfferSideBar}
scrollTopBody={scrollTopBody}
doSendLogMyInfoEdit={doSendLogMyInfoEdit}
/>
<InformationContainer
toggleOrderSideBar={toggleOrderSideBar}
toggleOfferSideBar={toggleOfferSideBar}
scrollTopBody={scrollTopBody}
doSendLogMyInfoEdit={doSendLogMyInfoEdit}
/>
{/* )} */}
</div>
</TBody>
@@ -740,8 +858,11 @@ export default function CheckOutPanel({ panelInfo }) {
lastTotalPrice={checkOutPanelInfo?.estimatedTotal}
/>
</TFullPopup>
<div style={{display: 'none'}}>
{console.log('%c[BuyOption][CheckOutPanel] ✅ Component rendering COMPLETE', 'background: lightgreen; color: black; font-weight: bold; padding: 5px;')}
<div style={{ display: 'none' }}>
{console.log(
'%c[BuyOption][CheckOutPanel] ✅ Component rendering COMPLETE',
'background: lightgreen; color: black; font-weight: bold; padding: 5px;'
)}
</div>
</>
);