diff --git a/com.twin.app.shoptime/src/actions/appDataActions.js b/com.twin.app.shoptime/src/actions/appDataActions.js index 3c21616f..fb4f73f8 100644 --- a/com.twin.app.shoptime/src/actions/appDataActions.js +++ b/com.twin.app.shoptime/src/actions/appDataActions.js @@ -1,6 +1,11 @@ -import { URLS } from "../api/apiConfig"; -import { TAxios } from "../api/TAxios"; -import { types } from "./actionTypes"; +import { URLS } from '../api/apiConfig'; +import { TAxios } from '../api/TAxios'; +import { types } from './actionTypes'; +import { createDebugHelpers } from '../utils/debug'; + +// 디버그 헬퍼 설정 +const DEBUG_MODE = false; +const { dlog, dwarn, derror } = createDebugHelpers(DEBUG_MODE); export const addMainIndex = (index) => ({ type: types.ADD_MAIN_INDEX, @@ -25,7 +30,7 @@ export const sendSms = (params) => (dispatch, getState) => { } = params; const onSuccess = (response) => { - console.log("sendSms onSuccess ", response.data); + dlog('sendSms onSuccess ', response.data); dispatch({ type: types.SEND_SMS, payload: response.data.data, @@ -34,13 +39,13 @@ export const sendSms = (params) => (dispatch, getState) => { }; const onFail = (error) => { - console.error("sendSms onFail ", error); + derror('sendSms onFail ', error); }; TAxios( dispatch, getState, - "post", + 'post', URLS.SEND_SMS, {}, { diff --git a/com.twin.app.shoptime/src/actions/billingActions.js b/com.twin.app.shoptime/src/actions/billingActions.js index e8399980..486b307c 100644 --- a/com.twin.app.shoptime/src/actions/billingActions.js +++ b/com.twin.app.shoptime/src/actions/billingActions.js @@ -1,13 +1,18 @@ -import { URLS } from "../api/apiConfig"; -import { TAxios } from "../api/TAxios"; -import { types } from "./actionTypes"; +import { URLS } from '../api/apiConfig'; +import { TAxios } from '../api/TAxios'; +import { types } from './actionTypes'; +import { createDebugHelpers } from '../utils/debug'; + +// 디버그 헬퍼 설정 +const DEBUG_MODE = false; +const { dlog, dwarn, derror } = createDebugHelpers(DEBUG_MODE); // IF-LGSP-328 : 회원 Billing Address 조회 export const getMyInfoBillingSearch = (props) => (dispatch, getState) => { const { mbrNo } = props; const onSuccess = (response) => { - console.log("getMyInfoBillingSearch onSuccess: ", response.data); + dlog('getMyInfoBillingSearch onSuccess: ', response.data); dispatch({ type: types.GET_MY_INFO_BILLING_SEARCH, @@ -16,13 +21,13 @@ export const getMyInfoBillingSearch = (props) => (dispatch, getState) => { }; const onFail = (error) => { - console.error("getMyInfoBillingSearch onFail: ", error); + derror('getMyInfoBillingSearch onFail: ', error); }; TAxios( dispatch, getState, - "get", + 'get', URLS.GET_MY_INFO_BILLING_SEARCH, { mbrNo }, {}, diff --git a/com.twin.app.shoptime/src/actions/brandActions.js b/com.twin.app.shoptime/src/actions/brandActions.js index a4a83225..4927a1ae 100644 --- a/com.twin.app.shoptime/src/actions/brandActions.js +++ b/com.twin.app.shoptime/src/actions/brandActions.js @@ -1,14 +1,19 @@ -import { URLS } from "../api/apiConfig"; -import { TAxios } from "../api/TAxios"; -import { types } from "./actionTypes"; -import { changeAppStatus } from "./commonActions"; +import { URLS } from '../api/apiConfig'; +import { TAxios } from '../api/TAxios'; +import { types } from './actionTypes'; +import { changeAppStatus } from './commonActions'; +import { createDebugHelpers } from '../utils/debug'; + +// 디버그 헬퍼 설정 +const DEBUG_MODE = false; +const { dlog, dwarn, derror } = createDebugHelpers(DEBUG_MODE); // Featured Brands 정보 조회 IF-LGSP-304 export const getBrandList = () => (dispatch, getState) => { - dispatch(changeAppStatus({ showLoadingPanel: { show: true, type: "wait" } })); + dispatch(changeAppStatus({ showLoadingPanel: { show: true, type: 'wait' } })); const onSuccess = (response) => { - // console.log("getBrandList onSuccess ", response.data); + // dlog("getBrandList onSuccess ", response.data); dispatch({ type: types.GET_BRAND_LIST, @@ -21,30 +26,21 @@ export const getBrandList = () => (dispatch, getState) => { }; const onFail = (error) => { - console.error("getBrandList onFail", error); + derror('getBrandList onFail', error); dispatch(changeAppStatus({ showLoadingPanel: { show: false } })); }; - TAxios( - dispatch, - getState, - "get", - URLS.GET_BRAND_LIST, - {}, - {}, - onSuccess, - onFail - ); + TAxios(dispatch, getState, 'get', URLS.GET_BRAND_LIST, {}, {}, onSuccess, onFail); }; // Featured Brands LAYOUT (shelf) 정보 조회 IF-LGSP-305 export const getBrandLayoutInfo = (props) => (dispatch, getState) => { const { patnrId } = props; - dispatch(changeAppStatus({ showLoadingPanel: { show: true, type: "wait" } })); + dispatch(changeAppStatus({ showLoadingPanel: { show: true, type: 'wait' } })); const onSuccess = (response) => { - // console.log("getBrandLayoutInfo onSuccess ", response.data); + // dlog("getBrandLayoutInfo onSuccess ", response.data); dispatch({ type: types.GET_BRAND_LAYOUT_INFO, @@ -57,30 +53,21 @@ export const getBrandLayoutInfo = (props) => (dispatch, getState) => { }; const onFail = (error) => { - console.error("getBrandLayoutInfo onFail ", error); + derror('getBrandLayoutInfo onFail ', error); dispatch(changeAppStatus({ showLoadingPanel: { show: false } })); }; - TAxios( - dispatch, - getState, - "get", - URLS.GET_BRAND_LAYOUT_INFO, - { patnrId }, - {}, - onSuccess, - onFail - ); + TAxios(dispatch, getState, 'get', URLS.GET_BRAND_LAYOUT_INFO, { patnrId }, {}, onSuccess, onFail); }; // Featured Brands Live 채널 정보 조회 IF-LGSP-306 export const getBrandLiveChannelInfo = (props) => (dispatch, getState) => { const { patnrId } = props; - dispatch(changeAppStatus({ showLoadingPanel: { show: true, type: "wait" } })); + dispatch(changeAppStatus({ showLoadingPanel: { show: true, type: 'wait' } })); const onSuccess = (response) => { - // console.log("getBrandLiveChannelInfo onSuccess ", response.data); + // dlog("getBrandLiveChannelInfo onSuccess ", response.data); dispatch({ type: types.GET_BRAND_LIVE_CHANNEL_INFO, @@ -93,14 +80,14 @@ export const getBrandLiveChannelInfo = (props) => (dispatch, getState) => { }; const onFail = (error) => { - console.error("getBrandLiveChannelInfo onFail ", error); + derror('getBrandLiveChannelInfo onFail ', error); dispatch(changeAppStatus({ showLoadingPanel: { show: false } })); }; TAxios( dispatch, getState, - "get", + 'get', URLS.GET_BRAND_LIVE_CHANNEL_INFO, { patnrId }, {}, @@ -113,7 +100,7 @@ export const getBrandChanInfo = (props) => (dispatch, getState) => { const { patnrId } = props; const onSuccess = (response) => { - // console.log("getBrandChanInfo onSuccess ", response.data); + // dlog("getBrandChanInfo onSuccess ", response.data); dispatch({ type: types.GET_BRAND_CHAN_INFO, @@ -124,13 +111,13 @@ export const getBrandChanInfo = (props) => (dispatch, getState) => { }; const onFail = (error) => { - console.error("getBrandChanInfo onFail ", error); + derror('getBrandChanInfo onFail ', error); }; TAxios( dispatch, getState, - "get", + 'get', URLS.GET_BRAND_LIVE_CHANNEL_INFO, { patnrId }, {}, @@ -143,10 +130,10 @@ export const getBrandChanInfo = (props) => (dispatch, getState) => { export const getBrandTSVInfo = (props) => (dispatch, getState) => { const { patnrId } = props; - dispatch(changeAppStatus({ showLoadingPanel: { show: true, type: "wait" } })); + dispatch(changeAppStatus({ showLoadingPanel: { show: true, type: 'wait' } })); const onSuccess = (response) => { - // console.log("getBrandTSVInfo onSuccess ", response.data); + // dlog("getBrandTSVInfo onSuccess ", response.data); dispatch({ type: types.GET_BRAND_TSV_INFO, @@ -159,30 +146,21 @@ export const getBrandTSVInfo = (props) => (dispatch, getState) => { }; const onFail = (error) => { - console.error("getBrandTSVInfo onFail ", error); + derror('getBrandTSVInfo onFail ', error); dispatch(changeAppStatus({ showLoadingPanel: { show: false } })); }; - TAxios( - dispatch, - getState, - "get", - URLS.GET_BRAND_TSV_INFO, - { patnrId }, - {}, - onSuccess, - onFail - ); + TAxios(dispatch, getState, 'get', URLS.GET_BRAND_TSV_INFO, { patnrId }, {}, onSuccess, onFail); }; // Featured Brand Recommended Show 정보 조회 IF-LGSP-308 export const getBrandRecommendedShowInfo = (props) => (dispatch, getState) => { const { catCd, patnrId } = props; - dispatch(changeAppStatus({ showLoadingPanel: { show: true, type: "wait" } })); + dispatch(changeAppStatus({ showLoadingPanel: { show: true, type: 'wait' } })); const onSuccess = (response) => { - // console.log("getBrandRecommendedShowInfo onSuccess", response.data); + // dlog("getBrandRecommendedShowInfo onSuccess", response.data); dispatch({ type: types.GET_BRAND_RECOMMENDED_SHOW_INFO, @@ -195,14 +173,14 @@ export const getBrandRecommendedShowInfo = (props) => (dispatch, getState) => { }; const onFail = (error) => { - console.error("getBrandRecommendedShowInfo onFail", error); + derror('getBrandRecommendedShowInfo onFail', error); dispatch(changeAppStatus({ showLoadingPanel: { show: false } })); }; TAxios( dispatch, getState, - "get", + 'get', URLS.GET_BRAND_RECOMMENDED_SHOW_INFO, { catCd, patnrId }, {}, @@ -215,10 +193,10 @@ export const getBrandRecommendedShowInfo = (props) => (dispatch, getState) => { export const getBrandCreatorsInfo = (props) => (dispatch, getState) => { const { hstNm, patnrId } = props; - dispatch(changeAppStatus({ showLoadingPanel: { show: true, type: "wait" } })); + dispatch(changeAppStatus({ showLoadingPanel: { show: true, type: 'wait' } })); const onSuccess = (response) => { - // console.log("getBrandCreatorsInfo onSuccess ", response.data); + // dlog("getBrandCreatorsInfo onSuccess ", response.data); dispatch({ type: types.GET_BRAND_CREATORS_INFO, @@ -231,14 +209,14 @@ export const getBrandCreatorsInfo = (props) => (dispatch, getState) => { }; const onFail = (error) => { - console.error("getBrandCreatorsInfo onFail ", error); + derror('getBrandCreatorsInfo onFail ', error); dispatch(changeAppStatus({ showLoadingPanel: { show: false } })); }; TAxios( dispatch, getState, - "get", + 'get', URLS.GET_BRAND_CREATORS_INFO, { hstNm, patnrId }, {}, @@ -251,10 +229,10 @@ export const getBrandCreatorsInfo = (props) => (dispatch, getState) => { export const getBrandSeriesInfo = (props) => (dispatch, getState) => { const { patnrId, seriesId } = props; - dispatch(changeAppStatus({ showLoadingPanel: { show: true, type: "wait" } })); + dispatch(changeAppStatus({ showLoadingPanel: { show: true, type: 'wait' } })); const onSuccess = (response) => { - // console.log("getBrandSeriesInfo onSuccess ", response.data); + // dlog("getBrandSeriesInfo onSuccess ", response.data); dispatch({ type: types.GET_BRAND_SERIES_INFO, @@ -267,14 +245,14 @@ export const getBrandSeriesInfo = (props) => (dispatch, getState) => { }; const onFail = (error) => { - console.error("getBrandSeriesInfo onFail ", error); + derror('getBrandSeriesInfo onFail ', error); dispatch(changeAppStatus({ showLoadingPanel: { show: false } })); }; TAxios( dispatch, getState, - "get", + 'get', URLS.GET_BRAND_SERIES_INFO, { patnrId, seriesId }, {}, @@ -287,10 +265,10 @@ export const getBrandSeriesInfo = (props) => (dispatch, getState) => { export const getBrandCategoryInfo = (props) => (dispatch, getState) => { const { catCdLv1, catCdLv2, patnrId } = props; - dispatch(changeAppStatus({ showLoadingPanel: { show: true, type: "wait" } })); + dispatch(changeAppStatus({ showLoadingPanel: { show: true, type: 'wait' } })); const onSuccess = (response) => { - // console.log("getBrandCategoryInfo onSuccess ", response.data); + // dlog("getBrandCategoryInfo onSuccess ", response.data); dispatch({ type: types.GET_BRAND_CATEGORY_INFO, @@ -304,13 +282,13 @@ export const getBrandCategoryInfo = (props) => (dispatch, getState) => { const onFail = (error) => { dispatch(changeAppStatus({ showLoadingPanel: { show: false } })); - console.error("getBrandCategoryInfo onFail ", error); + derror('getBrandCategoryInfo onFail ', error); }; TAxios( dispatch, getState, - "get", + 'get', URLS.GET_BRAND_CATEGORY_INFO, { catCdLv1, catCdLv2, patnrId }, {}, @@ -322,10 +300,10 @@ export const getBrandCategoryInfo = (props) => (dispatch, getState) => { export const getBrandCategoryProductInfo = (props) => (dispatch, getState) => { const { catCdLv1, catCdLv2, patnrId } = props; - dispatch(changeAppStatus({ showLoadingPanel: { show: true, type: "wait" } })); + dispatch(changeAppStatus({ showLoadingPanel: { show: true, type: 'wait' } })); const onSuccess = (response) => { - // console.log("getBrandCategoryProductInfo onSuccess ", response.data); + // dlog("getBrandCategoryProductInfo onSuccess ", response.data); dispatch({ type: types.GET_BRAND_CATEGORY_PRODUCT_INFO, @@ -338,14 +316,14 @@ export const getBrandCategoryProductInfo = (props) => (dispatch, getState) => { }; const onFail = (error) => { - console.error("getBrandCategoryProductInfo onFail ", error); + derror('getBrandCategoryProductInfo onFail ', error); dispatch(changeAppStatus({ showLoadingPanel: { show: false } })); }; TAxios( dispatch, getState, - "get", + 'get', URLS.GET_BRAND_CATEGORY_INFO, { catCdLv1, catCdLv2, patnrId }, {}, @@ -358,10 +336,10 @@ export const getBrandCategoryProductInfo = (props) => (dispatch, getState) => { export const getBrandBestSeller = (props) => (dispatch, getState) => { const { patnrId } = props; - dispatch(changeAppStatus({ showLoadingPanel: { show: true, type: "wait" } })); + dispatch(changeAppStatus({ showLoadingPanel: { show: true, type: 'wait' } })); const onSuccess = (response) => { - // console.log("getBrandBestSeller onSuccess ", response.data); + // dlog("getBrandBestSeller onSuccess ", response.data); dispatch({ type: types.GET_BRAND_BEST_SELLER, @@ -374,30 +352,21 @@ export const getBrandBestSeller = (props) => (dispatch, getState) => { }; const onFail = (error) => { - console.error("getBrandBestSeller onFail ", error); + derror('getBrandBestSeller onFail ', error); dispatch(changeAppStatus({ showLoadingPanel: { show: false } })); }; - TAxios( - dispatch, - getState, - "get", - URLS.GET_BRAND_BEST_SELLER, - { patnrId }, - {}, - onSuccess, - onFail - ); + TAxios(dispatch, getState, 'get', URLS.GET_BRAND_BEST_SELLER, { patnrId }, {}, onSuccess, onFail); }; // Featured Brands Showroom 조회 IF-LGSP-372 export const getBrandShowroom = (props) => (dispatch, getState) => { const { patnrId } = props; - dispatch(changeAppStatus({ showLoadingPanel: { show: true, type: "wait" } })); + dispatch(changeAppStatus({ showLoadingPanel: { show: true, type: 'wait' } })); const onSuccess = (response) => { - // console.log("getBrandShowroom onSuccess ", response.data); + // dlog("getBrandShowroom onSuccess ", response.data); dispatch({ type: types.GET_BRAND_SHOWROOM, @@ -410,20 +379,11 @@ export const getBrandShowroom = (props) => (dispatch, getState) => { }; const onFail = (error) => { - console.error("getBrandShowroom onFail ", error); + derror('getBrandShowroom onFail ', error); dispatch(changeAppStatus({ showLoadingPanel: { show: false } })); }; - TAxios( - dispatch, - getState, - "get", - URLS.GET_BRAND_SHOWROOM, - { patnrId }, - {}, - onSuccess, - onFail - ); + TAxios(dispatch, getState, 'get', URLS.GET_BRAND_SHOWROOM, { patnrId }, {}, onSuccess, onFail); }; // Featured Brands Recently Aired 조회 IF-LGSP-373 @@ -431,7 +391,7 @@ export const getBrandRecentlyAired = (props) => (dispatch, getState) => { const { patnrId } = props; const onSuccess = (response) => { - // console.log("getBrandRecentlyAired onSuccess ", response.data); + // dlog("getBrandRecentlyAired onSuccess ", response.data); dispatch({ type: types.GET_BRAND_RECENTLY_AIRED, @@ -442,14 +402,14 @@ export const getBrandRecentlyAired = (props) => (dispatch, getState) => { }; const onFail = (error) => { - console.error("getBrandRecentlyAired onFail ", error); + derror('getBrandRecentlyAired onFail ', error); // dispatch(changeAppStatus({ showLoadingPanel: { show: false } })); }; TAxios( dispatch, getState, - "get", + 'get', URLS.GET_BRAND_RECENTLY_AIRED, { patnrId }, {}, @@ -467,7 +427,7 @@ export const setBrandLiveChannelUpcoming = (props) => (dispatch, getState) => { const brandLiveChannelUpcoming = storedBrandLiveChannelUpcoming // .map((item) => { if (item.showId === showId && item.strtDt === strtDt) { - item.alamDispFlag = item.alamDispFlag === "Y" ? "N" : "Y"; + item.alamDispFlag = item.alamDispFlag === 'Y' ? 'N' : 'Y'; } return item; @@ -488,12 +448,11 @@ export const setBrandLiveChannelUpcoming = (props) => (dispatch, getState) => { export const setBrandChanInfo = (props) => (dispatch, getState) => { const { showId, strtDt } = props; - const storedBrandLiveChanInfo = - getState().brand.brandLiveChannelInfoData.data.brandChanInfo; + const storedBrandLiveChanInfo = getState().brand.brandLiveChannelInfoData.data.brandChanInfo; const brandChanInfo = storedBrandLiveChanInfo.map((item) => { if (item.showId === showId && item.strtDt === strtDt) { - item.alamDispFlag = item.alamDispFlag === "Y" ? "N" : "Y"; + item.alamDispFlag = item.alamDispFlag === 'Y' ? 'N' : 'Y'; } return item; diff --git a/com.twin.app.shoptime/src/actions/cancelActions.js b/com.twin.app.shoptime/src/actions/cancelActions.js index cb6a7a01..c0c58d92 100644 --- a/com.twin.app.shoptime/src/actions/cancelActions.js +++ b/com.twin.app.shoptime/src/actions/cancelActions.js @@ -1,60 +1,56 @@ -import { URLS } from "../api/apiConfig"; -import { TAxios } from "../api/TAxios"; -import { types } from "./actionTypes"; -import { changeAppStatus, showError } from "./commonActions"; +import { URLS } from '../api/apiConfig'; +import { TAxios } from '../api/TAxios'; +import { types } from './actionTypes'; +import { changeAppStatus, showError } from './commonActions'; +import { createDebugHelpers } from '../utils/debug'; + +// 디버그 헬퍼 설정 +const DEBUG_MODE = false; +const { dlog, dwarn, derror } = createDebugHelpers(DEBUG_MODE); // 회원 주문 취소/반품/교환 사유 조회 (IF-LGSP-347) -export const getMyinfoOrderCancelColumnsSearch = - (params, callback) => (dispatch, getState) => { - const { reasonTpCd } = params; +export const getMyinfoOrderCancelColumnsSearch = (params, callback) => (dispatch, getState) => { + const { reasonTpCd } = params; - const onSuccess = (response) => { - console.log( - "getMyinfoOrderCancelColumnsSearch onSuccess ", - response.data + const onSuccess = (response) => { + dlog('getMyinfoOrderCancelColumnsSearch onSuccess ', response.data); + + if (response.data.retCode === 0) { + dispatch({ + type: types.GET_MY_INFO_ORDER_CANCEL_COLUMNS_SEARCH, + payload: response.data.data, + }); + + if (callback) callback(); + } else { + dispatch( + showError(response.data.retCode, response.data.retMsg, false, response.data.retDetailCode) ); - - if (response.data.retCode === 0) { - dispatch({ - type: types.GET_MY_INFO_ORDER_CANCEL_COLUMNS_SEARCH, - payload: response.data.data, - }); - - if (callback) callback(); - } else { - dispatch( - showError( - response.data.retCode, - response.data.retMsg, - false, - response.data.retDetailCode - ) - ); - } - }; - - const onFail = (error) => { - console.error("getMyinfoOrderCancelColumnsSearch onFail ", error); - }; - - TAxios( - dispatch, - getState, - "get", - URLS.GET_MY_INFO_ORDER_CANCEL_COLUMNS_SEARCH, - { reasonTpCd }, - {}, - onSuccess, - onFail - ); + } }; + const onFail = (error) => { + derror('getMyinfoOrderCancelColumnsSearch onFail ', error); + }; + + TAxios( + dispatch, + getState, + 'get', + URLS.GET_MY_INFO_ORDER_CANCEL_COLUMNS_SEARCH, + { reasonTpCd }, + {}, + onSuccess, + onFail + ); +}; + // 회원 주문 취소/반품/교환 조회 (IF-LGSP-366) export const getMyinfoOrderCancelSearch = (params) => (dispatch, getState) => { const { mbrNo, ordNo, patnrId, prdtId, prodSno, shptmChngRsnCd } = params; const onSuccess = (response) => { - console.log("getMyinfoOrderCancelSearch onSuccess ", response.data); + dlog('getMyinfoOrderCancelSearch onSuccess ', response.data); dispatch({ type: types.GET_MY_INFO_ORDER_CANCEL_SEARCH, @@ -63,13 +59,13 @@ export const getMyinfoOrderCancelSearch = (params) => (dispatch, getState) => { }; const onFail = (error) => { - console.error("getMyinfoOrderCancelSearch onFail ", error); + derror('getMyinfoOrderCancelSearch onFail ', error); }; TAxios( dispatch, getState, - "get", + 'get', URLS.GET_MY_INFO_ORDER_CANCEL_SEARCH, { mbrNo, ordNo, patnrId, prdtId, prodSno, shptmChngRsnCd }, {}, @@ -80,18 +76,10 @@ export const getMyinfoOrderCancelSearch = (params) => (dispatch, getState) => { // 주문 부분 결제 취소 (IF-LGSP-351) export const updateOrderPartialCancel = (params) => (dispatch, getState) => { - const { - mbrNo, - ordNo, - prodSno, - reqChngRsn, - reqChngRsnCd, - reqMbrId, - reqMbrNo, - } = params; + const { mbrNo, ordNo, prodSno, reqChngRsn, reqChngRsnCd, reqMbrId, reqMbrNo } = params; const onSuccess = (response) => { - console.log("updateOrderPartialCancel onSuccess ", response.data); + dlog('updateOrderPartialCancel onSuccess ', response.data); if (response.data.retCode === 0) { dispatch({ @@ -100,24 +88,19 @@ export const updateOrderPartialCancel = (params) => (dispatch, getState) => { }); } else { dispatch( - showError( - response.data.retCode, - response.data.retMsg, - false, - response.data.retDetailCode - ) + showError(response.data.retCode, response.data.retMsg, false, response.data.retDetailCode) ); } }; const onFail = (error) => { - console.error("updateOrderPartialCancel onFail ", error); + derror('updateOrderPartialCancel onFail ', error); }; TAxios( dispatch, getState, - "post", + 'post', URLS.UPDATE_ORDER_PARTIAL_CANCEL, { mbrNo, ordNo, prodSno, reqChngRsn, reqChngRsnCd, reqMbrId, reqMbrNo }, {}, @@ -127,51 +110,43 @@ export const updateOrderPartialCancel = (params) => (dispatch, getState) => { }; // 결제전체취소 (IF-LGSP-367) -export const paymentTotalCancel = - (params, callback) => (dispatch, getState) => { - const { mbrNo, ordNo, reqChngRsn, reqChngRsnCd } = params; +export const paymentTotalCancel = (params, callback) => (dispatch, getState) => { + const { mbrNo, ordNo, reqChngRsn, reqChngRsnCd } = params; - dispatch( - changeAppStatus({ showLoadingPanel: { show: true, type: "wait" } }) - ); + dispatch(changeAppStatus({ showLoadingPanel: { show: true, type: 'wait' } })); - const onSuccess = (response) => { - console.log("paymentTotalCancel onSuccess ", response.data); + const onSuccess = (response) => { + dlog('paymentTotalCancel onSuccess ', response.data); - if (response.data.retCode === 0) { - dispatch({ - type: types.PAYMENT_TOTAL_CANCEL, - payload: response.data.data, - }); + if (response.data.retCode === 0) { + dispatch({ + type: types.PAYMENT_TOTAL_CANCEL, + payload: response.data.data, + }); - if (callback) callback(response.data); - } else { - dispatch( - showError( - response.data.retCode, - response.data.retMsg, - false, - response.data.retDetailCode - ) - ); - } + if (callback) callback(response.data); + } else { + dispatch( + showError(response.data.retCode, response.data.retMsg, false, response.data.retDetailCode) + ); + } - dispatch(changeAppStatus({ showLoadingPanel: { show: false } })); - }; - - const onFail = (error) => { - console.error("paymentTotalCancel onFail ", error); - dispatch(changeAppStatus({ showLoadingPanel: { show: false } })); - }; - - TAxios( - dispatch, - getState, - "post", - URLS.PAYMENT_TOTAL_CANCEL, - {}, - { mbrNo, ordNo, reqChngRsn, reqChngRsnCd }, - onSuccess, - onFail - ); + dispatch(changeAppStatus({ showLoadingPanel: { show: false } })); }; + + const onFail = (error) => { + derror('paymentTotalCancel onFail ', error); + dispatch(changeAppStatus({ showLoadingPanel: { show: false } })); + }; + + TAxios( + dispatch, + getState, + 'post', + URLS.PAYMENT_TOTAL_CANCEL, + {}, + { mbrNo, ordNo, reqChngRsn, reqChngRsnCd }, + onSuccess, + onFail + ); +}; diff --git a/com.twin.app.shoptime/src/actions/cardActions.js b/com.twin.app.shoptime/src/actions/cardActions.js index 1a16f033..0226c7c5 100644 --- a/com.twin.app.shoptime/src/actions/cardActions.js +++ b/com.twin.app.shoptime/src/actions/cardActions.js @@ -1,13 +1,18 @@ -import { URLS } from "../api/apiConfig"; -import { TAxios } from "../api/TAxios"; -import { types } from "./actionTypes"; +import { URLS } from '../api/apiConfig'; +import { TAxios } from '../api/TAxios'; +import { types } from './actionTypes'; +import { createDebugHelpers } from '../utils/debug'; + +// 디버그 헬퍼 설정 +const DEBUG_MODE = false; +const { dlog, dwarn, derror } = createDebugHelpers(DEBUG_MODE); // 회원의 등록 카드 정보 조회 IF-LGSP-332 export const getMyInfoCardSearch = (props) => (dispatch, getState) => { const { mbrNo } = props; const onSuccess = (response) => { - console.log("getMyInfoCardSearch onSuccess: ", response.data); + dlog('getMyInfoCardSearch onSuccess: ', response.data); dispatch({ type: types.GET_MY_INFO_CARD_SEARCH, @@ -16,17 +21,8 @@ export const getMyInfoCardSearch = (props) => (dispatch, getState) => { }; const onFail = (error) => { - console.error("getMyInfoCardSearch OnFail: ", error); + derror('getMyInfoCardSearch OnFail: ', error); }; - TAxios( - dispatch, - getState, - "get", - URLS.GET_MY_INFO_CARD_SEARCH, - { mbrNo }, - {}, - onSuccess, - onFail - ); + TAxios(dispatch, getState, 'get', URLS.GET_MY_INFO_CARD_SEARCH, { mbrNo }, {}, onSuccess, onFail); }; diff --git a/com.twin.app.shoptime/src/actions/cartActions.js b/com.twin.app.shoptime/src/actions/cartActions.js index dd1d2386..0c926abc 100644 --- a/com.twin.app.shoptime/src/actions/cartActions.js +++ b/com.twin.app.shoptime/src/actions/cartActions.js @@ -2,6 +2,11 @@ import { URLS } from '../api/apiConfig'; import { TAxios } from '../api/TAxios'; import { types } from './actionTypes'; import { showError } from './commonActions'; +import { createDebugHelpers } from '../utils/debug'; + +// 디버그 헬퍼 설정 +const DEBUG_MODE = false; +const { dlog, dwarn, derror } = createDebugHelpers(DEBUG_MODE); /** * 회원 장바구니 정보 조회 @@ -11,7 +16,7 @@ export const getMyInfoCartSearch = (props) => (dispatch, getState) => { const { mbrNo } = props; const onSuccess = (response) => { - console.log("getMyInfoCartSearch onSuccess: ", response.data); + dlog('getMyInfoCartSearch onSuccess: ', response.data); dispatch({ type: types.GET_MY_INFO_CART_SEARCH, @@ -20,8 +25,8 @@ export const getMyInfoCartSearch = (props) => (dispatch, getState) => { }; const onFail = (error) => { - console.error("getMyInfoCartSearch OnFail: ", error); - + derror('getMyInfoCartSearch OnFail: ', error); + // 실패 시에도 빈 데이터로 초기화 dispatch({ type: types.GET_MY_INFO_CART_SEARCH, @@ -31,7 +36,7 @@ export const getMyInfoCartSearch = (props) => (dispatch, getState) => { // API URL이 정의되어 있지 않은 경우 임시로 빈 데이터 반환 if (!URLS.GET_MY_INFO_CART_SEARCH) { - console.warn("GET_MY_INFO_CART_SEARCH URL이 정의되지 않았습니다."); + dwarn('GET_MY_INFO_CART_SEARCH URL이 정의되지 않았습니다.'); dispatch({ type: types.GET_MY_INFO_CART_SEARCH, payload: { cartList: [] }, @@ -39,16 +44,7 @@ export const getMyInfoCartSearch = (props) => (dispatch, getState) => { return; } - TAxios( - dispatch, - getState, - "get", - URLS.GET_MY_INFO_CART_SEARCH, - { mbrNo }, - {}, - onSuccess, - onFail - ); + TAxios(dispatch, getState, 'get', URLS.GET_MY_INFO_CART_SEARCH, { mbrNo }, {}, onSuccess, onFail); }; /** @@ -58,43 +54,35 @@ export const insertMyinfoCart = (props) => (dispatch, getState) => { const { mbrNo, patnrId, prdtId, prdtOpt, prodQty } = props; const onSuccess = (response) => { - console.log("✅ insertMyinfoCart API 성공:", response.data.retCode); + dlog('✅ insertMyinfoCart API 성공:', response.data.retCode); // if (response.data?.retCode !== '0' && response.data.retCode !== 0) { - // console.error("❌ retCode 에러:", response.data.retCode); - // console.error("에러 메시지:", response.data.retMsg); - + // derror("❌ retCode 에러:", response.data.retCode); + // derror("에러 메시지:", response.data.retMsg); + // return; // } - + if (response.data.retCode === 0) { dispatch({ type: types.INSERT_MY_INFO_CART, payload: response.data.data, - }); - dispatch(getMyInfoCartSearch({ mbrNo })); - } else { - dispatch( - showError( - response.data.retCode, - response.data.retMsg, - false, - null, - null - ) - ); - console.error("❌ retCode 에러:", response.data.retCode); - console.error("에러 메시지:", response.data.retMsg); - } + }); + dispatch(getMyInfoCartSearch({ mbrNo })); + } else { + dispatch(showError(response.data.retCode, response.data.retMsg, false, null, null)); + derror('❌ retCode 에러:', response.data.retCode); + derror('에러 메시지:', response.data.retMsg); + } }; const onFail = (error) => { - console.error("insertMyinfoCart OnFail: ", error); + derror('insertMyinfoCart OnFail: ', error); }; TAxios( - dispatch, + dispatch, getState, - "post", + 'post', URLS.INSERT_MY_INFO_CART, {}, { mbrNo, patnrId, prdtId, prdtOpt, prodQty }, @@ -110,7 +98,7 @@ export const deleteMyinfoCart = (props) => (dispatch, getState) => { const { mbrNo, patnrId, prdtId, prodSno } = props; const onSuccess = (response) => { - console.log("deleteMyinfoCart onSuccess: ", response.data); + dlog('deleteMyinfoCart onSuccess: ', response.data); dispatch({ type: types.DELETE_MY_INFO_CART, @@ -122,13 +110,13 @@ export const deleteMyinfoCart = (props) => (dispatch, getState) => { }; const onFail = (error) => { - console.error("deleteMyinfoCart OnFail: ", error); + derror('deleteMyinfoCart OnFail: ', error); }; TAxios( dispatch, getState, - "post", + 'post', URLS.DELETE_MY_INFO_CART, {}, { mbrNo, patnrId, prdtId, prodSno }, @@ -144,7 +132,7 @@ export const deleteAllMyinfoCart = (props) => (dispatch, getState) => { const { mbrNo } = props; const onSuccess = (response) => { - console.log("deleteAllMyinfoCart onSuccess: ", response.data); + dlog('deleteAllMyinfoCart onSuccess: ', response.data); dispatch({ type: types.DELETE_ALL_MY_INFO_CART, @@ -156,13 +144,13 @@ export const deleteAllMyinfoCart = (props) => (dispatch, getState) => { }; const onFail = (error) => { - console.error("deleteAllMyinfoCart OnFail: ", error); + derror('deleteAllMyinfoCart OnFail: ', error); }; TAxios( dispatch, getState, - "post", + 'post', URLS.DELETE_ALL_MY_INFO_CART, {}, { mbrNo }, @@ -194,7 +182,7 @@ export const updateMyinfoCart = (props) => (dispatch, getState) => { const { mbrNo, patnrId, prdtId, prodQty, prodSno } = props; const onSuccess = (response) => { - console.log("updateMyinfoCart onSuccess: ", response.data); + dlog('updateMyinfoCart onSuccess: ', response.data); dispatch({ type: types.UPDATE_MY_INFO_CART, @@ -206,13 +194,13 @@ export const updateMyinfoCart = (props) => (dispatch, getState) => { }; const onFail = (error) => { - console.error("updateMyinfoCart OnFail: ", error); + derror('updateMyinfoCart OnFail: ', error); }; TAxios( dispatch, getState, - "post", + 'post', URLS.UPDATE_MY_INFO_CART, {}, { mbrNo, patnrId, prdtId, prodQty, prodSno }, @@ -229,7 +217,7 @@ export const addToCart = (props) => (dispatch, getState) => { const { mbrNo, patnrId, prdtId, prodOptCdCval, prodQty, prdtOpt } = props; const onSuccess = (response) => { - console.log("addToCart onSuccess: ", response.data); + dlog('addToCart onSuccess: ', response.data); dispatch({ type: types.ADD_TO_CART, @@ -241,12 +229,12 @@ export const addToCart = (props) => (dispatch, getState) => { }; const onFail = (error) => { - console.error("addToCart OnFail: ", error); + derror('addToCart OnFail: ', error); }; // API URL이 정의되어 있지 않은 경우 로컬 상태만 업데이트 if (!URLS.ADD_TO_CART) { - console.warn("ADD_TO_CART URL이 정의되지 않았습니다."); + dwarn('ADD_TO_CART URL이 정의되지 않았습니다.'); dispatch({ type: types.ADD_TO_CART, payload: { patnrId, prdtId, prodOptCdCval, prodQty, prdtOpt }, @@ -257,7 +245,7 @@ export const addToCart = (props) => (dispatch, getState) => { TAxios( dispatch, getState, - "post", + 'post', URLS.ADD_TO_CART, {}, { mbrNo, patnrId, prdtId, prodOptCdCval, prodQty, prdtOpt }, @@ -274,7 +262,7 @@ export const removeFromCart = (props) => (dispatch, getState) => { const { mbrNo, cartSno } = props; const onSuccess = (response) => { - console.log("removeFromCart onSuccess: ", response.data); + dlog('removeFromCart onSuccess: ', response.data); dispatch({ type: types.REMOVE_FROM_CART, @@ -286,11 +274,11 @@ export const removeFromCart = (props) => (dispatch, getState) => { }; const onFail = (error) => { - console.error("removeFromCart OnFail: ", error); + derror('removeFromCart OnFail: ', error); }; if (!URLS.REMOVE_FROM_CART) { - console.warn("REMOVE_FROM_CART URL이 정의되지 않았습니다."); + dwarn('REMOVE_FROM_CART URL이 정의되지 않았습니다.'); dispatch({ type: types.REMOVE_FROM_CART, payload: { cartSno }, @@ -301,7 +289,7 @@ export const removeFromCart = (props) => (dispatch, getState) => { TAxios( dispatch, getState, - "delete", + 'delete', URLS.REMOVE_FROM_CART, { mbrNo, cartSno }, {}, @@ -318,7 +306,7 @@ export const updateCartItem = (props) => (dispatch, getState) => { const { mbrNo, cartSno, prodQty } = props; const onSuccess = (response) => { - console.log("updateCartItem onSuccess: ", response.data); + dlog('updateCartItem onSuccess: ', response.data); dispatch({ type: types.UPDATE_CART_ITEM, @@ -330,11 +318,11 @@ export const updateCartItem = (props) => (dispatch, getState) => { }; const onFail = (error) => { - console.error("updateCartItem OnFail: ", error); + derror('updateCartItem OnFail: ', error); }; if (!URLS.UPDATE_CART_ITEM) { - console.warn("UPDATE_CART_ITEM URL이 정의되지 않았습니다."); + dwarn('UPDATE_CART_ITEM URL이 정의되지 않았습니다.'); dispatch({ type: types.UPDATE_CART_ITEM, payload: { cartSno, prodQty }, @@ -345,7 +333,7 @@ export const updateCartItem = (props) => (dispatch, getState) => { TAxios( dispatch, getState, - "put", + 'put', URLS.UPDATE_CART_ITEM, {}, { mbrNo, cartSno, prodQty }, diff --git a/com.twin.app.shoptime/src/actions/checkoutActions.js b/com.twin.app.shoptime/src/actions/checkoutActions.js index 8705f22d..2b989481 100644 --- a/com.twin.app.shoptime/src/actions/checkoutActions.js +++ b/com.twin.app.shoptime/src/actions/checkoutActions.js @@ -1,210 +1,189 @@ import { URLS } from '../api/apiConfig'; import { TAxios } from '../api/TAxios'; import { types } from './actionTypes'; -import { - changeAppStatus, - showError, -} from './commonActions'; +import { changeAppStatus, showError } from './commonActions'; +import { createDebugHelpers } from '../utils/debug'; + +// 디버그 헬퍼 설정 +const DEBUG_MODE = false; +const { dlog, dwarn, derror } = createDebugHelpers(DEBUG_MODE); // 회원 체크아웃 정보 조회 IF-LGSP-345 -export const getMyInfoCheckoutInfo = - (props, callback) => (dispatch, getState) => { - const { mbrNo, dirPurcSelYn, cartList } = props; +export const getMyInfoCheckoutInfo = (props, callback) => (dispatch, getState) => { + const { mbrNo, dirPurcSelYn, cartList } = props; + + dispatch( + // changeAppStatus({ showLoadingPanel: { show: true, type: "wait" } }) + changeAppStatus({ isLoading: true }) + ); + + const onSuccess = (response) => { + dlog('getMyInfoCheckoutInfo onSuccess: ', response.data); + + // 🔍 API 응답 구조 분석 + const checkoutData = response.data.data || response.data; + const defaultAddrSno = + checkoutData?.shippingAddressList?.[0]?.dlvrAddrSno || + checkoutData?.shippingAddressList?.[0]?.addrSno; + const defaultBilAddrSno = + checkoutData?.billingAddressList?.[0]?.bilAddrSno || + checkoutData?.billingAddressList?.[0]?.addrSno; + + dlog('[checkoutActions] 🔍 Checkout data structure:', { + hasResponseDataData: !!response.data.data, + directData: !!response.data, + defaultAddrSno, + defaultBilAddrSno, + shippingAddressCount: checkoutData?.shippingAddressList?.length, + billingAddressCount: checkoutData?.billingAddressList?.length, + }); + + // 🔴 billingAddressList 상세 분석 + dlog('[checkoutActions] 🔴 billingAddressList analysis:', { + billingAddressList: checkoutData?.billingAddressList, + firstBillingAddress: checkoutData?.billingAddressList?.[0], + firstBillingAddressKeys: Object.keys(checkoutData?.billingAddressList?.[0] || {}), + }); + + // 기본 주소 선택 (첫 번째 주소 사용) + const infoForCheckoutData = { + dlvrAddrSno: defaultAddrSno, + bilAddrSno: defaultBilAddrSno, + }; + + dlog('[checkoutActions] 📦 Dispatching GET_CHECKOUT_INFO with:', { + infoForCheckoutData, + checkoutData, + }); + + dispatch({ + type: types.GET_CHECKOUT_INFO, + payload: { + ...checkoutData, + ...infoForCheckoutData, // 기본 주소 정보 추가 + }, + }); + + if (callback) callback(response.data); + }; + + const onFail = (error) => { + derror('getMyInfoCheckoutInfo OnFail: ', error); + }; + + TAxios( + dispatch, + getState, + 'post', + URLS.GET_CHECKOUT_INFO, + {}, + { mbrNo, dirPurcSelYn, cartList }, + onSuccess, + onFail + ); +}; + +// 회원 CheckOut 상품 주문 IF-LGSP-346 +export const insertMyInfoCheckoutOrder = (props, callback) => (dispatch, getState) => { + const { mbrNo, bilAddrSno, dlvrAddrSno, pinCd, orderProductCoupontUse, orderProductQtyInfo } = + props; + + const onSuccess = (response) => { + dlog('insertMyInfoCheckoutOrder onSuccess: ', response.data); + + if (response.data.retCode === 0) { + dispatch({ + type: types.INSERT_MY_INFO_CHECKOUT_ORDER, + payload: response.data.data, + }); + + if (callback) callback(response); + } else { + dispatch( + showError(response.data.retCode, response.data.retMsg, true, response.data.retDetailCode) + ); + } dispatch( - // changeAppStatus({ showLoadingPanel: { show: true, type: "wait" } }) - changeAppStatus({ isLoading: true }) - ); - - const onSuccess = (response) => { - console.log("getMyInfoCheckoutInfo onSuccess: ", response.data); - - // 🔍 API 응답 구조 분석 - const checkoutData = response.data.data || response.data; - const defaultAddrSno = checkoutData?.shippingAddressList?.[0]?.dlvrAddrSno || checkoutData?.shippingAddressList?.[0]?.addrSno; - const defaultBilAddrSno = checkoutData?.billingAddressList?.[0]?.bilAddrSno || checkoutData?.billingAddressList?.[0]?.addrSno; - - console.log('[checkoutActions] 🔍 Checkout data structure:', { - hasResponseDataData: !!response.data.data, - directData: !!response.data, - defaultAddrSno, - defaultBilAddrSno, - shippingAddressCount: checkoutData?.shippingAddressList?.length, - billingAddressCount: checkoutData?.billingAddressList?.length, - }); - - // 🔴 billingAddressList 상세 분석 - console.log('[checkoutActions] 🔴 billingAddressList analysis:', { - billingAddressList: checkoutData?.billingAddressList, - firstBillingAddress: checkoutData?.billingAddressList?.[0], - firstBillingAddressKeys: Object.keys(checkoutData?.billingAddressList?.[0] || {}), - }); - - // 기본 주소 선택 (첫 번째 주소 사용) - const infoForCheckoutData = { - dlvrAddrSno: defaultAddrSno, - bilAddrSno: defaultBilAddrSno, - }; - - console.log('[checkoutActions] 📦 Dispatching GET_CHECKOUT_INFO with:', { - infoForCheckoutData, - checkoutData, - }); - - dispatch({ - type: types.GET_CHECKOUT_INFO, - payload: { - ...checkoutData, - ...infoForCheckoutData, // 기본 주소 정보 추가 - }, - }); - - if (callback) callback(response.data); - }; - - const onFail = (error) => { - console.error("getMyInfoCheckoutInfo OnFail: ", error); - }; - - TAxios( - dispatch, - getState, - "post", - URLS.GET_CHECKOUT_INFO, - {}, - { mbrNo, dirPurcSelYn, cartList }, - onSuccess, - onFail + changeAppStatus({ + showLoadingPanel: { show: false, showMessage: false }, + }) ); }; -// 회원 CheckOut 상품 주문 IF-LGSP-346 -export const insertMyInfoCheckoutOrder = - (props, callback) => (dispatch, getState) => { - const { + const onFail = (error) => { + derror('insertMyInfoCheckoutOrder onFail: ', error); + dispatch( + changeAppStatus({ + showLoadingPanel: { show: false, showMessage: false }, + }) + ); + }; + + TAxios( + dispatch, + getState, + 'post', + URLS.INSERT_MY_INFO_CHECKOUT_ORDER, + {}, + { mbrNo, bilAddrSno, dlvrAddrSno, pinCd, orderProductCoupontUse, orderProductQtyInfo, - } = props; + }, + onSuccess, + onFail + ); +}; - const onSuccess = (response) => { - console.log("insertMyInfoCheckoutOrder onSuccess: ", response.data); +export const getCheckoutTotalAmt = (params, callback) => (dispatch, getState) => { + const { mbrNo, dirPurcSelYn, bilAddrSno, dlvrAddrSno, isPageLoading, orderProductCoupontUse } = + params; - if (response.data.retCode === 0) { - dispatch({ - type: types.INSERT_MY_INFO_CHECKOUT_ORDER, - payload: response.data.data, - }); + dispatch(changeAppStatus({ isLoading: false })); - if (callback) callback(response); - } else { - dispatch( - showError( - response.data.retCode, - response.data.retMsg, - true, - response.data.retDetailCode - ) - ); - } + dispatch(changeAppStatus({ showLoadingPanel: { show: true, type: 'wait' } })); + const onSuccess = (response) => { + dlog('getCheckoutTotalAmt onSuccess: ', response.data); + + if (response.data.retCode === 0) { + dispatch({ + type: types.GET_CHECKOUT_TOTAL_AMT, + payload: response.data.data, + }); + + if (callback) callback(response.data); + } else { dispatch( - changeAppStatus({ - showLoadingPanel: { show: false, showMessage: false }, - }) + showError(response.data.retCode, response.data.retMsg, true, response.data.retDetailCode) ); - }; + } - const onFail = (error) => { - console.error("insertMyInfoCheckoutOrder onFail: ", error); - dispatch( - changeAppStatus({ - showLoadingPanel: { show: false, showMessage: false }, - }) - ); - }; - - TAxios( - dispatch, - getState, - "post", - URLS.INSERT_MY_INFO_CHECKOUT_ORDER, - {}, - { - mbrNo, - bilAddrSno, - dlvrAddrSno, - pinCd, - orderProductCoupontUse, - orderProductQtyInfo, - }, - onSuccess, - onFail - ); + dispatch(changeAppStatus({ showLoadingPanel: { show: false } })); }; -export const getCheckoutTotalAmt = - (params, callback) => (dispatch, getState) => { - const { - mbrNo, - dirPurcSelYn, - bilAddrSno, - dlvrAddrSno, - isPageLoading, - orderProductCoupontUse, - } = params; + const onFail = (error) => { + derror('getCheckoutTotalAmt onFail: ', error); - dispatch(changeAppStatus({ isLoading: false })); - - dispatch( - changeAppStatus({ showLoadingPanel: { show: true, type: "wait" } }) - ); - - const onSuccess = (response) => { - console.log("getCheckoutTotalAmt onSuccess: ", response.data); - - if (response.data.retCode === 0) { - dispatch({ - type: types.GET_CHECKOUT_TOTAL_AMT, - payload: response.data.data, - }); - - if (callback) callback(response.data); - } else { - dispatch( - showError( - response.data.retCode, - response.data.retMsg, - true, - response.data.retDetailCode - ) - ); - } - - dispatch(changeAppStatus({ showLoadingPanel: { show: false } })); - }; - - const onFail = (error) => { - console.error("getCheckoutTotalAmt onFail: ", error); - - dispatch(changeAppStatus({ showLoadingPanel: { show: false } })); - }; - - TAxios( - dispatch, - getState, - "post", - URLS.GET_CHECKOUT_TOTAL_AMT, - {}, - { mbrNo, dirPurcSelYn, bilAddrSno, dlvrAddrSno, isPageLoading, orderProductCoupontUse }, - onSuccess, - onFail - ); + dispatch(changeAppStatus({ showLoadingPanel: { show: false } })); }; + TAxios( + dispatch, + getState, + 'post', + URLS.GET_CHECKOUT_TOTAL_AMT, + {}, + { mbrNo, dirPurcSelYn, bilAddrSno, dlvrAddrSno, isPageLoading, orderProductCoupontUse }, + onSuccess, + onFail + ); +}; + export const updateSelectedShippingAddr = (dlvrAddrSno) => ({ type: types.UPDATE_SELECTED_SHIPPING_ADDR, payload: dlvrAddrSno, diff --git a/com.twin.app.shoptime/src/actions/commonActions.js b/com.twin.app.shoptime/src/actions/commonActions.js index 0e7dcc34..4523b080 100644 --- a/com.twin.app.shoptime/src/actions/commonActions.js +++ b/com.twin.app.shoptime/src/actions/commonActions.js @@ -13,6 +13,11 @@ import { initialLocalSettings } from '../reducers/localSettingsReducer'; import * as Config from '../utils/Config'; import * as HelperMethods from '../utils/helperMethods'; import { types } from './actionTypes'; +import { createDebugHelpers } from '../utils/debug'; + +// 디버그 헬퍼 설정 +const DEBUG_MODE = false; +const { dlog, dwarn, derror } = createDebugHelpers(DEBUG_MODE); // ======= // import appinfo from "../../webos-meta/appinfo.json"; // import appinfo35 from "../../webos-meta/appinfo35.json"; @@ -53,10 +58,10 @@ export const setShowPopup = (config, addPayload = {}) => { payload = config; } -// ======= -// export const setShowPopup = (config) => { -// const payload = typeof config === "string" ? { activePopup: config } : config; -// >>>>>>> gitlab/develop + // ======= + // export const setShowPopup = (config) => { + // const payload = typeof config === "string" ? { activePopup: config } : config; + // >>>>>>> gitlab/develop return { type: types.SET_SHOW_POPUP, payload, @@ -92,9 +97,9 @@ export const toggleOptionalTermsConfirm = (selected) => ({ export const setExitApp = () => (dispatch, getState) => { dispatch({ type: types.SET_EXIT_APP }); - console.log("Exiting App..."); + dlog('Exiting App...'); - if (typeof window === "object") { + if (typeof window === 'object') { window.close(); } else { window.location.reload(); @@ -107,12 +112,12 @@ export const getLoginUserData = (userData) => ({ }); export const loadingComplete = (status) => ({ - type: "loadingComplete", + type: 'loadingComplete', payload: status, }); export const alertToast = (payload) => (dispatch, getState) => { - if (typeof window === "object" && !window.PalmSystem) { + if (typeof window === 'object' && !window.PalmSystem) { dispatch(changeAppStatus({ toast: true, toastText: payload })); } else { lunaSend.createToast(payload); @@ -120,21 +125,20 @@ export const alertToast = (payload) => (dispatch, getState) => { }; export const getSystemSettings = () => (dispatch, getState) => { - console.log("getSystemSettings "); + dlog('getSystemSettings '); lunaSend.getSystemSettings( - { category: "caption", keys: ["captionEnable"] }, + { category: 'caption', keys: ['captionEnable'] }, { onSuccess: (res) => {}, onFailure: (err) => {}, onComplete: (res) => { - console.log("getSystemSettings onComplete", res); + dlog('getSystemSettings onComplete', res); if (res && res.settings) { - if (typeof res.settings.captionEnable !== "undefined") { + if (typeof res.settings.captionEnable !== 'undefined') { dispatch( changeAppStatus({ captionEnable: - res.settings.captionEnable === "on" || - res.settings.captionEnable === true, + res.settings.captionEnable === 'on' || res.settings.captionEnable === true, }) ); } @@ -144,167 +148,162 @@ export const getSystemSettings = () => (dispatch, getState) => { ); }; -export const getHttpHeaderForServiceRequest = - (onComplete) => (dispatch, getState) => { - console.log("getHttpHeaderForServiceRequest "); - const { serverType, ricCodeSetting, languageSetting } = - getState().localSettings; - lunaSend.getHttpHeaderForServiceRequest({ - onSuccess: (res) => { - const version = res["X-Device-Netcast-Platform-Version"] || ""; - const webOSVersion = Number( - version.substring(0, version.lastIndexOf(".")) - ); +export const getHttpHeaderForServiceRequest = (onComplete) => (dispatch, getState) => { + dlog('getHttpHeaderForServiceRequest '); + const { serverType, ricCodeSetting, languageSetting } = getState().localSettings; + lunaSend.getHttpHeaderForServiceRequest({ + onSuccess: (res) => { + const version = res['X-Device-Netcast-Platform-Version'] || ''; + const webOSVersion = Number(version.substring(0, version.lastIndexOf('.'))); - // 4버전 미만인 경우 다른 처리 없이 버전 정보만 저장 - if (webOSVersion < 4) { - dispatch( - changeAppStatus({ - webOSVersion, - showLoadingPanel: { show: false }, - }) - ); - return; - } - - // 4버전 이상인 경우 기존 로직 수행 - console.log("getHttpHeaderForServiceRequest", res); - const convertedRes = { - Authorization: res["Authorization"], - "X-Authentication": res["X-Authentication"], - "X-Device-ID": res["X-Device-ID"], - "X-Device-Product": res["X-Device-Product"], - "X-Device-Platform": res["X-Device-Platform"], - "X-Device-Model": res["X-Device-Model"], - "X-Device-Eco-Info": res["X-Device-Eco-Info"], - "X-Device-Country": res["X-Device-Country"], - "X-Device-Language": res["X-Device-Language"], - "X-Device-Netcast-Platform-Version": - res["X-Device-Netcast-Platform-Version"], - "X-Device-Publish-Flag": res["X-Device-Publish-Flag"], - "X-Device-Fck": res["X-Device-Fck"], - "X-Device-Eula": res["X-Device-Eula"], - "X-Device-SDK-VERSION": res["X-Device-SDK-VERSION"], - }; - convertedRes["X-Device-Personalization"] = "Y"; - - if ( - typeof window === "object" && - window.PalmSystem && - window.PalmSystem.identifier && - process.env.REACT_APP_MODE !== "DEBUG" - ) { - convertedRes["app_id"] = window.PalmSystem.identifier ?? appinfo.id; - } else { - if (ricCodeSetting === "aic") { - convertedRes["app_id"] = appinfo.id; - } else if (ricCodeSetting === "eic") { - convertedRes["app_id"] = appinfo35.id; - } else if (ricCodeSetting === "ruc") { - convertedRes["app_id"] = appinfo79.id; - } else { - convertedRes["app_id"] = appinfo.id; - } - } - - convertedRes["app_ver"] = "1.0.0"; - convertedRes["cntry_cd"] = res["X-Device-Country"]; - convertedRes["prod_cd"] = res["X-Device-Product"]; - convertedRes["plat_cd"] = res["X-Device-Platform"]; - convertedRes["lang_cd"] = res["X-Device-Language"]; - convertedRes["sdk_ver"] = res["X-Device-SDK-VERSION"]; - convertedRes["publish_flag"] = res["X-Device-Publish-Flag"]; - convertedRes["os_ver"] = version; - convertedRes["dvc_auth"] = res["X-Authentication"]; - - if (serverType !== "system") { - if (ricCodeSetting === "eic") { - if (languageSetting === "GB") { - convertedRes["cntry_cd"] = "GB"; - convertedRes["X-Device-Country"] = "GB"; - res["HOST"] = "GB.nextlgsdp.com"; - } - if (languageSetting === "DE") { - convertedRes["cntry_cd"] = "DE"; - convertedRes["X-Device-Country"] = "DE"; - res["HOST"] = "DE.nextlgsdp.com"; - } - } - if (ricCodeSetting === "aic") { - convertedRes["cntry_cd"] = "US"; - convertedRes["X-Device-Country"] = "US"; - res["HOST"] = "US.nextlgsdp.com"; - } - if (ricCodeSetting === "ruc") { - convertedRes["cntry_cd"] = "RU"; - convertedRes["X-Device-Country"] = "RU"; - res["HOST"] = "RU.nextlgsdp.com"; - } - } - - if (convertedRes["cntry_cd"] === "US") { - convertedRes["lang_cd"] = "en-US"; - } - if (convertedRes["cntry_cd"] === "DE") { - convertedRes["lang_cd"] = "de-DE"; - } - if (convertedRes["cntry_cd"] === "GB") { - convertedRes["lang_cd"] = "en-GB"; - } - if (convertedRes["cntry_cd"] === "RU") { - convertedRes["lang_cd"] = "ru-RU"; - } - - dispatch({ type: types.GET_HTTP_HEADER, payload: convertedRes }); + // 4버전 미만인 경우 다른 처리 없이 버전 정보만 저장 + if (webOSVersion < 4) { dispatch( changeAppStatus({ webOSVersion, - serverHOST: res["HOST"], - mbr_no: res["X-User-Number"], + showLoadingPanel: { show: false }, }) ); + return; + } - const parameters = { serviceName: "LGE" }; - const mbrNo = res["X-User-Number"]; + // 4버전 이상인 경우 기존 로직 수행 + dlog('getHttpHeaderForServiceRequest', res); + const convertedRes = { + Authorization: res['Authorization'], + 'X-Authentication': res['X-Authentication'], + 'X-Device-ID': res['X-Device-ID'], + 'X-Device-Product': res['X-Device-Product'], + 'X-Device-Platform': res['X-Device-Platform'], + 'X-Device-Model': res['X-Device-Model'], + 'X-Device-Eco-Info': res['X-Device-Eco-Info'], + 'X-Device-Country': res['X-Device-Country'], + 'X-Device-Language': res['X-Device-Language'], + 'X-Device-Netcast-Platform-Version': res['X-Device-Netcast-Platform-Version'], + 'X-Device-Publish-Flag': res['X-Device-Publish-Flag'], + 'X-Device-Fck': res['X-Device-Fck'], + 'X-Device-Eula': res['X-Device-Eula'], + 'X-Device-SDK-VERSION': res['X-Device-SDK-VERSION'], + }; + convertedRes['X-Device-Personalization'] = 'Y'; - lunaSend.getLoginUserData(parameters, { - onSuccess: (res) => { - const userId = res.id ?? ""; - const userNumber = res.lastSignInUserNo; - const profileNick = res.profileNick || userId.split("@")[0]; - dispatch( - getLoginUserData({ - userId, - userNumber: mbrNo, - profileNick, - }) - ); - }, - onFailure: (err) => console.error("LoginData fetch failed ", err), - }); - }, - onFailure: (err) => { - console.log("getHttpHeaderForServiceRequest fail", err); - }, - }); - }; + if ( + typeof window === 'object' && + window.PalmSystem && + window.PalmSystem.identifier && + process.env.REACT_APP_MODE !== 'DEBUG' + ) { + convertedRes['app_id'] = window.PalmSystem.identifier ?? appinfo.id; + } else { + if (ricCodeSetting === 'aic') { + convertedRes['app_id'] = appinfo.id; + } else if (ricCodeSetting === 'eic') { + convertedRes['app_id'] = appinfo35.id; + } else if (ricCodeSetting === 'ruc') { + convertedRes['app_id'] = appinfo79.id; + } else { + convertedRes['app_id'] = appinfo.id; + } + } + + convertedRes['app_ver'] = '1.0.0'; + convertedRes['cntry_cd'] = res['X-Device-Country']; + convertedRes['prod_cd'] = res['X-Device-Product']; + convertedRes['plat_cd'] = res['X-Device-Platform']; + convertedRes['lang_cd'] = res['X-Device-Language']; + convertedRes['sdk_ver'] = res['X-Device-SDK-VERSION']; + convertedRes['publish_flag'] = res['X-Device-Publish-Flag']; + convertedRes['os_ver'] = version; + convertedRes['dvc_auth'] = res['X-Authentication']; + + if (serverType !== 'system') { + if (ricCodeSetting === 'eic') { + if (languageSetting === 'GB') { + convertedRes['cntry_cd'] = 'GB'; + convertedRes['X-Device-Country'] = 'GB'; + res['HOST'] = 'GB.nextlgsdp.com'; + } + if (languageSetting === 'DE') { + convertedRes['cntry_cd'] = 'DE'; + convertedRes['X-Device-Country'] = 'DE'; + res['HOST'] = 'DE.nextlgsdp.com'; + } + } + if (ricCodeSetting === 'aic') { + convertedRes['cntry_cd'] = 'US'; + convertedRes['X-Device-Country'] = 'US'; + res['HOST'] = 'US.nextlgsdp.com'; + } + if (ricCodeSetting === 'ruc') { + convertedRes['cntry_cd'] = 'RU'; + convertedRes['X-Device-Country'] = 'RU'; + res['HOST'] = 'RU.nextlgsdp.com'; + } + } + + if (convertedRes['cntry_cd'] === 'US') { + convertedRes['lang_cd'] = 'en-US'; + } + if (convertedRes['cntry_cd'] === 'DE') { + convertedRes['lang_cd'] = 'de-DE'; + } + if (convertedRes['cntry_cd'] === 'GB') { + convertedRes['lang_cd'] = 'en-GB'; + } + if (convertedRes['cntry_cd'] === 'RU') { + convertedRes['lang_cd'] = 'ru-RU'; + } + + dispatch({ type: types.GET_HTTP_HEADER, payload: convertedRes }); + dispatch( + changeAppStatus({ + webOSVersion, + serverHOST: res['HOST'], + mbr_no: res['X-User-Number'], + }) + ); + + const parameters = { serviceName: 'LGE' }; + const mbrNo = res['X-User-Number']; + + lunaSend.getLoginUserData(parameters, { + onSuccess: (res) => { + const userId = res.id ?? ''; + const userNumber = res.lastSignInUserNo; + const profileNick = res.profileNick || userId.split('@')[0]; + dispatch( + getLoginUserData({ + userId, + userNumber: mbrNo, + profileNick, + }) + ); + }, + onFailure: (err) => derror('LoginData fetch failed ', err), + }); + }, + onFailure: (err) => { + dlog('getHttpHeaderForServiceRequest fail', err); + }, + }); +}; export const getDeviceId = (onComplete) => (dispatch, getState) => { lunaSend.getDeviceId( - { idType: ["LGUDID"] }, + { idType: ['LGUDID'] }, { onSuccess: (res) => { - console.log("getDeviceId ", res); + dlog('getDeviceId ', res); if (res.returnValue) { const deviceId = res.idList[0].idValue; dispatch(changeAppStatus({ deviceId: deviceId })); } }, onFailure: (err) => { - console.log(err); + dlog(err); }, onComplete: () => { - console.log("getDeviceId done"); + dlog('getDeviceId done'); if (onComplete) onComplete(); }, } @@ -317,8 +316,8 @@ export const getTermsAgreeYn = () => (dispatch, getState) => { try { const { terms } = getState().home.termsData.data; - console.log( - "getTermsAgreeYn", + dlog( + 'getTermsAgreeYn', terms.map((term) => ({ trmsId: term.trmsId, trmsTpCd: term.trmsTpCd, @@ -328,33 +327,33 @@ export const getTermsAgreeYn = () => (dispatch, getState) => { ); // MST00405 선택약관 정보만 따로 출력 - const optionalTerm = terms.find((term) => term.trmsTpCd === "MST00405"); + const optionalTerm = terms.find((term) => term.trmsTpCd === 'MST00405'); if (optionalTerm) { - console.log("getTermsAgreeYn MST00405 선택약관:", { + dlog('getTermsAgreeYn MST00405 선택약관:', { trmsId: optionalTerm.trmsId, trmsTpCd: optionalTerm.trmsTpCd, trmsAgrFlag: optionalTerm.trmsAgrFlag, trmsPopFlag: optionalTerm.trmsPopFlag, }); } else { - console.log("getTermsAgreeYn MST00405 선택약관을 찾을 수 없습니다."); + dlog('getTermsAgreeYn MST00405 선택약관을 찾을 수 없습니다.'); } const termsAgreeFlag = terms.reduce((acc, term) => { switch (term.trmsTpCd) { - case "MST00401": + case 'MST00401': acc.privacyTerms = term.trmsAgrFlag; break; - case "MST00402": + case 'MST00402': acc.serviceTerms = term.trmsAgrFlag; break; - case "MST00403": + case 'MST00403': acc.purchaseTerms = term.trmsAgrFlag; break; - case "MST00404": + case 'MST00404': acc.paymentTerms = term.trmsAgrFlag; break; - case "MST00405": + case 'MST00405': acc.optionalTerms = term.trmsAgrFlag; break; default: @@ -368,7 +367,7 @@ export const getTermsAgreeYn = () => (dispatch, getState) => { payload: termsAgreeFlag, }); } catch (error) { - console.error("getTermsAgreeYn error:", error); + derror('getTermsAgreeYn error:', error); dispatch({ type: types.GET_TERMS_AGREE_YN_FAILURE }); } }; @@ -376,8 +375,8 @@ export const getTermsAgreeYn = () => (dispatch, getState) => { // export const getTermsAgreeYn = () => (dispatch, getState) => { // const { terms } = getState().home.termsData.data; -// // console.log("getTermsAgreeYn", terms); -// console.log("getTermsAgreeYn", terms.map(term => ({ +// // dlog("getTermsAgreeYn", terms); +// dlog("getTermsAgreeYn", terms.map(term => ({ // trmsId: term.trmsId, // trmsTpCd: term.trmsTpCd, // trmsAgrFlag: term.trmsAgrFlag, @@ -429,7 +428,7 @@ export const launchMembershipApp = () => (dispatch, getState) => { panelInfo: currentPanel.panelInfo || {}, }); - if (typeof window === "object" && !window.PalmSystem) { + if (typeof window === 'object' && !window.PalmSystem) { // const testBypass = { // name: Config.panel_names.CATEGORY_PANEL, // panelInfo: { @@ -444,7 +443,7 @@ export const launchMembershipApp = () => (dispatch, getState) => { // }, // }; - console.log("returnPath", returnPath); + dlog('returnPath', returnPath); // setTimeout(() => { // dispatch(handleBypassLink(JSON.stringify(testBypass))); // }, 1000); @@ -453,10 +452,10 @@ export const launchMembershipApp = () => (dispatch, getState) => { lunaSend.launchMembershipApp(returnPath, { onSuccess: (res) => { - console.log("membership launch success: ", res); + dlog('membership launch success: ', res); }, onFailure: (err) => { - console.log("membership launch failed:", err); + dlog('membership launch failed:', err); }, }); }; @@ -470,7 +469,7 @@ export const setFocus = (spotlightId) => ({ export const focusElement = (spotlightId) => (dispatch, getState) => { dispatch(setFocus(spotlightId)); - if (typeof window === "object") { + if (typeof window === 'object') { rafId = window.requestAnimationFrame(() => { Spotlight.focus(spotlightId); }); @@ -479,7 +478,7 @@ export const focusElement = (spotlightId) => (dispatch, getState) => { export const cancelFocusElement = () => () => { if (rafId !== null) { - if (typeof window === "object") { + if (typeof window === 'object') { window.cancelAnimationFrame(rafId); rafId = null; } @@ -506,20 +505,20 @@ export const requestLiveSubtitle = if (Number(webOSVersion) <= 4.5) { lunaSend.setSubtitleEnable(mediaId, enable, { onSuccess: (res) => { - console.log(res); + dlog(res); }, onFailure: (err) => { - console.log(err); + dlog(err); }, }); return; } else { lunaSend.setSubtitleEnableOver5(mediaId, enable, { onSuccess: (res) => { - console.log(res); + dlog(res); }, onFailure: (err) => { - console.log(err); + dlog(err); }, }); } @@ -528,20 +527,20 @@ export const requestLiveSubtitle = export const addReservation = (data) => (dispatch) => { lunaSend.addReservation(data, { onSuccess: (res) => { - console.log("addReservation success:", res); + dlog('addReservation success:', res); // Optionally show success toast if (res && res.returnValue) { - dispatch(alertToast("Reminder set successfully")); + dispatch(alertToast('Reminder set successfully')); } }, onFailure: (err) => { - console.error("addReservation failed:", err); + derror('addReservation failed:', err); // Use the helper function for better error handling const errorMessage = HelperMethods.getReservationErrorMessage(err); dispatch(alertToast(errorMessage)); }, onComplete: () => { - console.log("addReservation completed"); + dlog('addReservation completed'); }, }); }; @@ -579,7 +578,7 @@ export const deleteReservation = (showId) => (dispatch) => { } }, onFailure: (err) => { - console.log(err); + dlog(err); }, }); }; @@ -618,13 +617,7 @@ export const clearErrorMessage = () => ({ }); export const showError = - ( - errorCode, - errorMsg, - shouldPopPanel = false, - retDetailCode = null, - returnBindStrings = null - ) => + (errorCode, errorMsg, shouldPopPanel = false, retDetailCode = null, returnBindStrings = null) => (dispatch) => { dispatch( setShowPopup(Config.ACTIVE_POPUP.errorPopup, { @@ -654,34 +647,34 @@ export const checkFirstLaunch = () => (dispatch) => { lunaSend.checkFirstLaunch({ onSuccess: (res) => { if (!res.returnValue) { - console.error("Failed to check first launch status"); + derror('Failed to check first launch status'); return; } if (res.results.length === 0) { - console.log("First launch detected - initializing localStorage"); + dlog('First launch detected - initializing localStorage'); - if (typeof window === "object") { + if (typeof window === 'object') { dispatch(changeLocalSettings({ phoneNumbers: {}, recentItems: [] })); } lunaSend.saveFirstLaunchInfo({ onSuccess: (saveRes) => { - console.log("First launch info saved to DB8:", saveRes); + dlog('First launch info saved to DB8:', saveRes); dispatch(changeAppStatus({ isFirstLaunch: true })); }, onFailure: (err) => { - console.error("Failed to save first launch info:", err); + derror('Failed to save first launch info:', err); }, }); } else { - console.log("Not first launch - keeping existing settings"); + dlog('Not first launch - keeping existing settings'); dispatch(changeAppStatus({ isFirstLaunch: false })); } }, onFailure: (err) => { - console.error("Failed to check first launch:", err); + derror('Failed to check first launch:', err); }, }); }; @@ -693,36 +686,27 @@ let updateNetworkStateJob = new Job((dispatch, connected) => { export const getConnectionStatus = () => (dispatch, getState) => { lunaSend.getConnectionStatus({ onSuccess: (res) => { - console.log("lunasend getConnectionStatus", res); + dlog('lunasend getConnectionStatus', res); if (res.returnValue) { const isInternet = - (res.wifi && res.wifi.onInternet === "yes") || - (res.wired && res.wired.onInternet === "yes"); + (res.wifi && res.wifi.onInternet === 'yes') || + (res.wired && res.wired.onInternet === 'yes'); const isInternetConnected = - (res.wifi && res.wifi.state === "connected") || - (res.wired && res.wired.state === "connected"); + (res.wifi && res.wifi.state === 'connected') || + (res.wired && res.wired.state === 'connected'); - console.log( - "internetconnected.............", - isInternet, - isInternetConnected, - res - ); + dlog('internetconnected.............', isInternet, isInternetConnected, res); const connected = isInternet && isInternetConnected; - updateNetworkStateJob.startAfter( - connected ? 100 : 3000, - dispatch, - connected - ); + updateNetworkStateJob.startAfter(connected ? 100 : 3000, dispatch, connected); } }, onFailure: (err) => { - console.log(err); + dlog(err); }, onComplete: (res) => { - console.log("getConnectionStatus done", res); + dlog('getConnectionStatus done', res); }, }); }; @@ -731,17 +715,17 @@ export const getConnectionStatus = () => (dispatch, getState) => { export const getConnectionInfo = () => (dispatch, getState) => { lunaSend.getConnectionInfo({ onSuccess: (res) => { - console.log("lunasend getConnectionStatus", res); + dlog('lunasend getConnectionStatus', res); if (res && res.returnValue) { const macAddress = res?.wiredInfo?.macAddress; - console.log("macAddress...........", macAddress, res); + dlog('macAddress...........', macAddress, res); } }, onFailure: (err) => { - console.log("getConnentionInfo", err); + dlog('getConnentionInfo', err); }, onComplete: (res) => { - console.log("getConnentionInfo done", res); + dlog('getConnentionInfo done', res); dispatch({ type: types.GET_DEVICE_MACADDRESS, payload: res, @@ -753,13 +737,13 @@ export const getConnectionInfo = () => (dispatch, getState) => { export const disableNotification = () => (dispatch, getState) => { lunaSend.disableNotification({ onSuccess: (res) => { - console.log("lunasend disable notification success", res); + dlog('lunasend disable notification success', res); }, onFailure: (err) => { - console.log("lunasend disable notification failure", err); + dlog('lunasend disable notification failure', err); }, onComplete: (res) => { - console.log("lunasend disable notification complete", res); + dlog('lunasend disable notification complete', res); }, }); }; @@ -767,13 +751,13 @@ export const disableNotification = () => (dispatch, getState) => { export const enableNotification = () => (dispatch, getState) => { lunaSend.enableNotification({ onSuccess: (res) => { - console.log("lunasend enable notification success", res); + dlog('lunasend enable notification success', res); }, onFailure: (err) => { - console.log("lunasend enable notification failure", err); + dlog('lunasend enable notification failure', err); }, onComplete: (res) => { - console.log("lunasend enable notification complete", res); + dlog('lunasend enable notification complete', res); }, }); }; @@ -795,15 +779,15 @@ export const resetOptionalTermsSession = () => ({ // 선택약관 동의 처리를 위한 헬퍼 함수 export const handleOptionalTermsAgree = () => (dispatch) => { - console.log("[CommonActions] 선택약관 동의 처리"); - dispatch(setOptionalTermsUserDecision("agreed")); + dlog('[CommonActions] 선택약관 동의 처리'); + dispatch(setOptionalTermsUserDecision('agreed')); dispatch(setOptionalTermsPopupShown(true)); }; // 선택약관 거절 처리를 위한 헬퍼 함수 export const handleOptionalTermsDecline = () => (dispatch) => { - console.log("[CommonActions] 선택약관 거절 처리"); - dispatch(setOptionalTermsUserDecision("declined")); + dlog('[CommonActions] 선택약관 거절 처리'); + dispatch(setOptionalTermsUserDecision('declined')); dispatch(setOptionalTermsPopupShown(true)); }; @@ -811,10 +795,10 @@ export const handleOptionalTermsDecline = () => (dispatch) => { export const updateOptionalTermsAgreement = (agreed = true) => (dispatch) => { - console.log(`[CommonActions] 선택약관 통합 상태 업데이트: ${agreed}`); + dlog(`[CommonActions] 선택약관 통합 상태 업데이트: ${agreed}`); // 1. optionalTermsPopupFlow 업데이트 (TV 환경용) - dispatch(setOptionalTermsUserDecision(agreed ? "agreed" : "declined")); + dispatch(setOptionalTermsUserDecision(agreed ? 'agreed' : 'declined')); dispatch(setOptionalTermsPopupShown(true)); // 2. 기본 optionalTermsAgree 상태 직접 업데이트 (API 호출 없이) diff --git a/com.twin.app.shoptime/src/actions/convertActions.js b/com.twin.app.shoptime/src/actions/convertActions.js index 9b12062a..ee3563ea 100644 --- a/com.twin.app.shoptime/src/actions/convertActions.js +++ b/com.twin.app.shoptime/src/actions/convertActions.js @@ -2,6 +2,11 @@ import { URLS } from '../api/apiConfig'; import { TAxios } from '../api/TAxios'; import { types } from './actionTypes'; import { getReAuthenticationCode } from './deviceActions'; +import { createDebugHelpers } from '../utils/debug'; + +// 디버그 헬퍼 설정 +const DEBUG_MODE = false; +const { dlog, dwarn, derror } = createDebugHelpers(DEBUG_MODE); /** * PDF를 이미지로 변환 (재시도 로직 포함) @@ -18,7 +23,7 @@ export const convertPdfToImage = const attemptConversion = () => { attempts++; - // console.log(`🔄 [EnergyLabel] Converting PDF attempt ${attempts}/${maxRetries + 1}:`, pdfUrl); + // dlog(`🔄 [EnergyLabel] Converting PDF attempt ${attempts}/${maxRetries + 1}:`, pdfUrl); // 타임아웃 설정 timeoutId = setTimeout(() => { @@ -26,15 +31,15 @@ export const convertPdfToImage = const timeoutError = new Error( `Conversion timeout after ${timeout}ms (attempt ${attempts})` ); - console.warn(`⏱️ [EnergyLabel] Timeout on attempt ${attempts}:`, timeoutError.message); + dwarn(`⏱️ [EnergyLabel] Timeout on attempt ${attempts}:`, timeoutError.message); // 재시도 가능한 경우 if (attempts < maxRetries + 1) { - // console.log(`🔄 [EnergyLabel] Retrying... (${attempts}/${maxRetries + 1})`); + // dlog(`🔄 [EnergyLabel] Retrying... (${attempts}/${maxRetries + 1})`); attemptConversion(); } else { // 최종 실패 - console.error(`❌ [EnergyLabel] Final failure after ${attempts} attempts:`, pdfUrl); + derror(`❌ [EnergyLabel] Final failure after ${attempts} attempts:`, pdfUrl); dispatch({ type: types.CONVERT_PDF_TO_IMAGE_FAILURE, payload: { pdfUrl, error: timeoutError }, @@ -53,22 +58,20 @@ export const convertPdfToImage = clearTimeout(timeoutId); timeoutId = null; } - + // retCode 체크 (프로젝트 API 규약: 200이어도 retCode로 성공/실패 구분) const retCode = response.headers?.retcode || response.headers?.retCode; - + if (retCode !== undefined && retCode !== 0 && retCode !== '0') { const error = new Error(`API Error: retCode=${retCode}`); - console.warn(`⚠️ [EnergyLabel] API returned error on attempt ${attempts}:`, retCode); + dwarn(`⚠️ [EnergyLabel] API returned error on attempt ${attempts}:`, retCode); // retCode 에러도 재시도 if (attempts < maxRetries + 1) { - console.log( - `🔄 [EnergyLabel] Retrying due to API error... (${attempts}/${maxRetries + 1})` - ); + dlog(`🔄 [EnergyLabel] Retrying due to API error... (${attempts}/${maxRetries + 1})`); attemptConversion(); } else { - console.error( + derror( `❌ [EnergyLabel] Final failure after ${attempts} attempts (API error):`, pdfUrl ); @@ -80,62 +83,62 @@ export const convertPdfToImage = } return; } - - if(response.data.type !== "image/png"){ - dispatch(getReAuthenticationCode()); + + if (response.data.type !== 'image/png') { + dispatch(getReAuthenticationCode()); + attemptConversion(); + return; + } + + let imageUrl; + try { + if (response.data instanceof Blob) { + if (response.data.size === 0) { + throw new Error('Invalid image data (empty blob)'); + } + imageUrl = URL.createObjectURL(response.data); + } else if (response.data instanceof ArrayBuffer) { + if (response.data.byteLength === 0) { + throw new Error('Invalid image data (empty buffer)'); + } + const blob = new Blob([response.data], { type: 'image/png' }); + imageUrl = URL.createObjectURL(blob); + } else { + const blob = new Blob([response.data], { type: 'image/png' }); + if (blob.size === 0) { + throw new Error('Invalid image data (empty blob)'); + } + imageUrl = URL.createObjectURL(blob); + } + + dlog(`✅ [EnergyLabel] Conversion successful on attempt ${attempts}:`, pdfUrl); + dispatch({ + type: types.CONVERT_PDF_TO_IMAGE_SUCCESS, + payload: { pdfUrl, imageUrl }, + }); + + callback && callback(null, imageUrl); + } catch (error) { + derror(`❌ [EnergyLabel] Image creation failed on attempt ${attempts}:`, error); + + // 이미지 생성 실패도 재시도 + if (attempts < maxRetries + 1) { + dlog( + `🔄 [EnergyLabel] Retrying due to image creation error... (${attempts}/${maxRetries + 1})` + ); attemptConversion(); - return; - } - - let imageUrl; - try { - if (response.data instanceof Blob) { - if (response.data.size === 0) { - throw new Error('Invalid image data (empty blob)'); - } - imageUrl = URL.createObjectURL(response.data); - } else if (response.data instanceof ArrayBuffer) { - if (response.data.byteLength === 0) { - throw new Error('Invalid image data (empty buffer)'); - } - const blob = new Blob([response.data], { type: 'image/png' }); - imageUrl = URL.createObjectURL(blob); - } else { - const blob = new Blob([response.data], { type: 'image/png' }); - if (blob.size === 0) { - throw new Error('Invalid image data (empty blob)'); - } - imageUrl = URL.createObjectURL(blob); - } - - console.log(`✅ [EnergyLabel] Conversion successful on attempt ${attempts}:`, pdfUrl); + } else { + derror( + `❌ [EnergyLabel] Final failure after ${attempts} attempts (image error):`, + pdfUrl + ); dispatch({ - type: types.CONVERT_PDF_TO_IMAGE_SUCCESS, - payload: { pdfUrl, imageUrl }, + type: types.CONVERT_PDF_TO_IMAGE_FAILURE, + payload: { pdfUrl, error }, }); - - callback && callback(null, imageUrl); - } catch (error) { - console.error(`❌ [EnergyLabel] Image creation failed on attempt ${attempts}:`, error); - - // 이미지 생성 실패도 재시도 - if (attempts < maxRetries + 1) { - console.log( - `🔄 [EnergyLabel] Retrying due to image creation error... (${attempts}/${maxRetries + 1})` - ); - attemptConversion(); - } else { - console.error( - `❌ [EnergyLabel] Final failure after ${attempts} attempts (image error):`, - pdfUrl - ); - dispatch({ - type: types.CONVERT_PDF_TO_IMAGE_FAILURE, - payload: { pdfUrl, error }, - }); - callback && callback(error, null); - } + callback && callback(error, null); } + } }; const onFail = (error) => { @@ -144,16 +147,14 @@ export const convertPdfToImage = timeoutId = null; } - console.warn(`⚠️ [EnergyLabel] Network error on attempt ${attempts}:`, error.message); + dwarn(`⚠️ [EnergyLabel] Network error on attempt ${attempts}:`, error.message); // 네트워크 에러도 재시도 if (attempts < maxRetries + 1) { - console.log( - `🔄 [EnergyLabel] Retrying due to network error... (${attempts}/${maxRetries + 1})` - ); + dlog(`🔄 [EnergyLabel] Retrying due to network error... (${attempts}/${maxRetries + 1})`); attemptConversion(); } else { - console.error( + derror( `❌ [EnergyLabel] Final failure after ${attempts} attempts (network error):`, pdfUrl ); diff --git a/com.twin.app.shoptime/src/actions/couponActions.js b/com.twin.app.shoptime/src/actions/couponActions.js index 03b0410c..8cd4e483 100644 --- a/com.twin.app.shoptime/src/actions/couponActions.js +++ b/com.twin.app.shoptime/src/actions/couponActions.js @@ -2,13 +2,18 @@ import { URLS } from '../api/apiConfig'; import { TAxios } from '../api/TAxios'; import { types } from './actionTypes'; import { showError } from './commonActions'; +import { createDebugHelpers } from '../utils/debug'; + +// 디버그 헬퍼 설정 +const DEBUG_MODE = false; +const { dlog, dwarn, derror } = createDebugHelpers(DEBUG_MODE); // IF-LGSP-339 : 회원 다운로드 쿠폰 정보 조회 export const getProductCouponInfo = (props) => (dispatch, getState) => { const { mbrNo, patnrId, prdtId } = props; const onSuccess = (response) => { - console.log("getProductCouponInfo onSuccess ", response.data); + dlog('getProductCouponInfo onSuccess ', response.data); dispatch({ type: types.GET_PRODUCT_COUPON_INFO, @@ -17,13 +22,13 @@ export const getProductCouponInfo = (props) => (dispatch, getState) => { }; const onFail = (error) => { - console.error("getProductCouponInfo onFail", error); + derror('getProductCouponInfo onFail', error); }; TAxios( dispatch, getState, - "get", + 'get', URLS.GET_PRODUCT_COUPON_INFO, { mbrNo, patnrId, prdtId }, {}, @@ -37,32 +42,27 @@ export const getProductCouponTotDownload = (props) => (dispatch, getState) => { const { mbrNo, cpnSnoAll } = props; const onSuccess = (response) => { - console.log("getProductCouponTotDownload onSuccess ", response.data); - if(response.data.retCode === 0){ + dlog('getProductCouponTotDownload onSuccess ', response.data); + if (response.data.retCode === 0) { dispatch({ type: types.GET_PRODUCT_COUPON_TOTDOWNLOAD, payload: response.data.data, }); } else { dispatch( - showError( - response.data.retCode, - response.data.retMsg, - false, - response.data.retDetailCode - ) + showError(response.data.retCode, response.data.retMsg, false, response.data.retDetailCode) ); } }; const onFail = (error) => { - console.error("getProductCouponTotDownload onFail", error); + derror('getProductCouponTotDownload onFail', error); }; TAxios( dispatch, getState, - "post", + 'post', URLS.GET_PRODUCT_COUPON_TOTDOWNLOAD, {}, { mbrNo, cpnSnoAll }, @@ -73,10 +73,10 @@ export const getProductCouponTotDownload = (props) => (dispatch, getState) => { // IF-LGSP-318 : 상품 쿠폰 다운로드 export const getProductCouponDownload = (props) => (dispatch, getState) => { const { mbrNo, cpnSno } = props; - + const onSuccess = (response) => { - console.log("getProductCouponDownload onSuccess ", response.data); - if(response.data.retCode === 0){ + dlog('getProductCouponDownload onSuccess ', response.data); + if (response.data.retCode === 0) { dispatch({ type: types.GET_PRODUCT_COUPON_DOWNLOAD, payload: response.data.data, @@ -84,24 +84,19 @@ export const getProductCouponDownload = (props) => (dispatch, getState) => { }); } else { dispatch( - showError( - response.data.retCode, - response.data.retMsg, - false, - response.data.retDetailCode - ) + showError(response.data.retCode, response.data.retMsg, false, response.data.retDetailCode) ); } }; const onFail = (error) => { - console.error("getProductCouponDownload onFail", error); + derror('getProductCouponDownload onFail', error); }; TAxios( dispatch, getState, - "post", + 'post', URLS.GET_PRODUCT_COUPON_DOWNLOAD, {}, { mbrNo, cpnSno }, @@ -114,7 +109,7 @@ export const getProductCouponSearch = (props) => (dispatch, getState) => { const { mbrNo, patnrId, prdtId, catCd } = props; const onSuccess = (response) => { - console.log("getProductCouponSearch onSuccess ", response.data); + dlog('getProductCouponSearch onSuccess ', response.data); dispatch({ type: types.GET_PRODUCT_COUPON_SEARCH, @@ -123,13 +118,13 @@ export const getProductCouponSearch = (props) => (dispatch, getState) => { }; const onFail = (error) => { - console.error("getProductCouponSearch onFail", error); + derror('getProductCouponSearch onFail', error); }; TAxios( dispatch, getState, - "get", + 'get', URLS.GET_PRODUCT_COUPON_SEARCH, { mbrNo, patnrId, prdtId, catCd }, {}, diff --git a/com.twin.app.shoptime/src/actions/deviceActions.js b/com.twin.app.shoptime/src/actions/deviceActions.js index 2c997a64..478a54d8 100644 --- a/com.twin.app.shoptime/src/actions/deviceActions.js +++ b/com.twin.app.shoptime/src/actions/deviceActions.js @@ -4,6 +4,11 @@ import * as lunaSend from '../lunaSend'; import { types } from './actionTypes'; import { changeLocalSettings } from './commonActions'; import { fetchCurrentUserHomeTerms } from './homeActions'; +import { createDebugHelpers } from '../utils/debug'; + +// 디버그 헬퍼 설정 +const DEBUG_MODE = false; +const { dlog, dwarn, derror } = createDebugHelpers(DEBUG_MODE); const MAX_RETRY_COUNT = 3; const RETRY_DELAY = 2000; // 2 seconds @@ -12,7 +17,7 @@ const RETRY_DELAY = 2000; // 2 seconds export const getAuthenticationCode = () => (dispatch, getState) => { setTokenRefreshing(true); const onSuccess = (response) => { - console.log('getAuthenticationCode onSuccess: ', response.data); + dlog('getAuthenticationCode onSuccess: ', response.data); const accessToken = response.data.data.accessToken; const refreshToken = response.data.data.refreshToken ?? null; @@ -22,7 +27,7 @@ export const getAuthenticationCode = () => (dispatch, getState) => { }; const onFail = (error) => { - console.error('getAuthenticationCode onFail: ', error); + derror('getAuthenticationCode onFail: ', error); setTokenRefreshing(false); }; @@ -35,7 +40,7 @@ export const registerDevice = const { agreeTerms } = params; const onSuccess = (response) => { - console.log('registerDevice onSuccess: ', response.data); + dlog('registerDevice onSuccess: ', response.data); dispatch({ type: types.REGISTER_DEVICE, @@ -50,7 +55,7 @@ export const registerDevice = }; const onFail = (error) => { - console.error('registerDevice onFail: ', error); + derror('registerDevice onFail: ', error); if (onFailCallback) { onFailCallback(error); } @@ -74,7 +79,7 @@ export const registerDeviceInfo = (params) => (dispatch, getState) => { const { evntTpCd, evntId, evntApplcnFlag, entryMenu, mbphNo } = params; const onSuccess = (response) => { - console.log('registerDeviceInfo onSuccess: ', response.data); + dlog('registerDeviceInfo onSuccess: ', response.data); dispatch({ type: types.REGISTER_DEVICE_INFO, @@ -84,7 +89,7 @@ export const registerDeviceInfo = (params) => (dispatch, getState) => { }; const onFail = (error) => { - console.error('registerDeviceInfo onFail: ', error); + derror('registerDeviceInfo onFail: ', error); }; TAxios( @@ -102,7 +107,7 @@ export const registerDeviceInfo = (params) => (dispatch, getState) => { // 디바이스 부가 정보 조회 IF-LGSP-003 export const getDeviceAdditionInfo = () => (dispatch, getState) => { const onSuccess = (response) => { - console.log('getDeviceAdditionInfo onSuccess: ', response.data); + dlog('getDeviceAdditionInfo onSuccess: ', response.data); dispatch({ type: types.GET_DEVICE_INFO, @@ -111,7 +116,7 @@ export const getDeviceAdditionInfo = () => (dispatch, getState) => { }; const onFail = (error) => { - console.error('getDeviceAdditionInfo onFail: ', error); + derror('getDeviceAdditionInfo onFail: ', error); }; TAxios(dispatch, getState, 'get', URLS.GET_DEVICE_INFO, {}, {}, onSuccess, onFail); @@ -121,7 +126,7 @@ export const getDeviceAdditionInfo = () => (dispatch, getState) => { export const getReAuthenticationCode = () => (dispatch, getState) => { setTokenRefreshing(true); const onSuccess = (response) => { - // console.log("getReAuthenticationCode onSuccess: ", response.data); + // dlog("getReAuthenticationCode onSuccess: ", response.data); const accessToken = response.data.data.accessToken; dispatch(changeLocalSettings({ accessToken })); setTokenRefreshing(false); @@ -129,7 +134,7 @@ export const getReAuthenticationCode = () => (dispatch, getState) => { }; const onFail = (error) => { - console.error('getReAuthenticationCode onFail: ', error); + derror('getReAuthenticationCode onFail: ', error); setTokenRefreshing(false); }; diff --git a/com.twin.app.shoptime/src/actions/empActions.js b/com.twin.app.shoptime/src/actions/empActions.js index a7ebb3ea..96eb295e 100644 --- a/com.twin.app.shoptime/src/actions/empActions.js +++ b/com.twin.app.shoptime/src/actions/empActions.js @@ -1,11 +1,16 @@ import { URLS } from '../api/apiConfig'; import { TAxios } from '../api/TAxios'; import { types } from './actionTypes'; +import { createDebugHelpers } from '../utils/debug'; + +// 디버그 헬퍼 설정 +const DEBUG_MODE = false; +const { dlog, dwarn, derror } = createDebugHelpers(DEBUG_MODE); // IF-LGSPM-373 EMP Shoptime 선택 약관 조회 export const getShoptimeTerms = () => (dispatch, getState) => { const onSuccess = (response) => { - // console.log("getShoptimeTerms onSuccess ", response.data); + // dlog("getShoptimeTerms onSuccess ", response.data); dispatch({ type: types.GET_SHOPTIME_TERMS, @@ -14,7 +19,7 @@ export const getShoptimeTerms = () => (dispatch, getState) => { }; const onFail = (error) => { - console.error('getShoptimeTerms onFail ', error); + derror('getShoptimeTerms onFail ', error); }; TAxios(dispatch, getState, 'get', URLS.GET_SHOPTIME_TERMS, {}, {}, onSuccess, onFail); diff --git a/com.twin.app.shoptime/src/actions/eventActions.js b/com.twin.app.shoptime/src/actions/eventActions.js index da2801d8..639b56b6 100644 --- a/com.twin.app.shoptime/src/actions/eventActions.js +++ b/com.twin.app.shoptime/src/actions/eventActions.js @@ -1,48 +1,43 @@ -import { URLS } from "../api/apiConfig"; -import { TAxios } from "../api/TAxios"; -import { types } from "./actionTypes"; +import { URLS } from '../api/apiConfig'; +import { TAxios } from '../api/TAxios'; +import { types } from './actionTypes'; +import { createDebugHelpers } from '../utils/debug'; + +// 디버그 헬퍼 설정 +const DEBUG_MODE = false; +const { dlog, dwarn, derror } = createDebugHelpers(DEBUG_MODE); // 이벤트 정보 조회 IF-LGSP-070 -export const getWelcomeEventInfo = - (onSuccessCallback, onFailCallback) => (dispatch, getState) => { - const onSuccess = (response) => { - console.log("getWelcomeEventInfo onSuccess ", response.data); +export const getWelcomeEventInfo = (onSuccessCallback, onFailCallback) => (dispatch, getState) => { + const onSuccess = (response) => { + dlog('getWelcomeEventInfo onSuccess ', response.data); - dispatch({ - type: types.GET_WELCOME_EVENT_INFO, - payload: response.data.data, - retCode: response.data.retCode, - }); + dispatch({ + type: types.GET_WELCOME_EVENT_INFO, + payload: response.data.data, + retCode: response.data.retCode, + }); - if (onSuccessCallback) { - onSuccessCallback(response.data); - } - }; - - const onFail = (error) => { - console.error("getWelcomeEventInfo onFail ", error); - if (onFailCallback) { - onFailCallback(error); - } - }; - - TAxios( - dispatch, - getState, - "get", - URLS.GET_WELCOME_EVENT_INFO, - {}, - {}, - onSuccess, - onFail - ); + if (onSuccessCallback) { + onSuccessCallback(response.data); + } }; + const onFail = (error) => { + derror('getWelcomeEventInfo onFail ', error); + if (onFailCallback) { + onFailCallback(error); + } + }; + + TAxios(dispatch, getState, 'get', URLS.GET_WELCOME_EVENT_INFO, {}, {}, onSuccess, onFail); +}; + // 이벤트(쿠폰) 지급 요청 (IF-LGSP-071) export const setEventIssueReq = (params) => (dispatch, getState) => { const { evntTpCd, evntId, mbphNo, cntryCd } = params; const onSuccess = (response) => { - console.log("setEventIssueReq onSuccess ", response.data); + dlog('setEventIssueReq onSuccess ', response.data); dispatch({ type: types.SET_EVENT_ISSUE_REQ, @@ -52,13 +47,13 @@ export const setEventIssueReq = (params) => (dispatch, getState) => { }; const onFail = (error) => { - console.error("setEventIssueReq onFail ", error); + derror('setEventIssueReq onFail ', error); }; TAxios( dispatch, getState, - "post", + 'post', URLS.SET_EVENT_ISSUE_REQ, {}, { evntTpCd, evntId, mbphNo, cntryCd }, @@ -71,7 +66,7 @@ export const setEventIssueReq = (params) => (dispatch, getState) => { export const getEventIssuedStaus = (params) => (dispatch, getState) => { const { evntTpCd, evntId } = params; const onSuccess = (response) => { - console.log("getEventIssuedStaus onSuccess ", response.data); + dlog('getEventIssuedStaus onSuccess ', response.data); dispatch({ type: types.GET_EVENT_ISSUED_STATUS, @@ -81,13 +76,13 @@ export const getEventIssuedStaus = (params) => (dispatch, getState) => { }; const onFail = (error) => { - console.error("getEventIssuedStaus onFail ", error); + derror('getEventIssuedStaus onFail ', error); }; TAxios( dispatch, getState, - "get", + 'get', URLS.GET_EVENT_ISSUED_STATUS, { evntTpCd, evntId }, {}, @@ -101,7 +96,7 @@ export const setEventPopClickInfo = (params) => (dispatch, getState) => { const { evntApplcnFlag, evntId } = params; const onSuccess = (response) => { - console.log("setEventPopClickInfo onSuccess ", response.data); + dlog('setEventPopClickInfo onSuccess ', response.data); dispatch({ type: types.SET_EVENT_POP_CLICK_INFO, @@ -113,13 +108,13 @@ export const setEventPopClickInfo = (params) => (dispatch, getState) => { }; const onFail = (error) => { - console.error("setEventPopClickInfo onFail ", error); + derror('setEventPopClickInfo onFail ', error); }; TAxios( dispatch, getState, - "post", + 'post', URLS.SET_EVENT_POP_CLICK_INFO, {}, { evntApplcnFlag, evntId }, diff --git a/com.twin.app.shoptime/src/actions/forYouActions.js b/com.twin.app.shoptime/src/actions/forYouActions.js index 18445341..a7628f45 100644 --- a/com.twin.app.shoptime/src/actions/forYouActions.js +++ b/com.twin.app.shoptime/src/actions/forYouActions.js @@ -3,34 +3,30 @@ import { TAxios } from '../api/TAxios'; import { get } from '../utils/fp'; import { types } from './actionTypes'; import { changeAppStatus } from './commonActions'; +import { createDebugHelpers } from '../utils/debug'; + +// 디버그 헬퍼 설정 +const DEBUG_MODE = false; +const { dlog, dwarn, derror } = createDebugHelpers(DEBUG_MODE); export const justForYou = (callback) => (dispatch, getState) => { const macAddress = getState().common.macAddress; - const macAddr = macAddress?.wired || macAddress?.wifi || "00:1A:2B:3C:4D:5E"; + const macAddr = macAddress?.wired || macAddress?.wifi || '00:1A:2B:3C:4D:5E'; const onSuccess = (response) => { - console.log("JustForYou onSuccess", response.data); + dlog('JustForYou onSuccess', response.data); dispatch({ type: types.JUSTFORYOU, - payload: get("data.data", response), + payload: get('data.data', response), }); dispatch(changeAppStatus({ showLoadingPanel: { show: false } })); callback && callback(); }; const onFail = (error) => { - console.error("JustForYou onFail", error); + derror('JustForYou onFail', error); dispatch(changeAppStatus({ showLoadingPanel: { show: false } })); callback && callback(); }; - TAxios( - dispatch, - getState, - "post", - URLS.JUSTFORYOU, - {}, - {macAddr}, - onSuccess, - onFail - ); + TAxios(dispatch, getState, 'post', URLS.JUSTFORYOU, {}, { macAddr }, onSuccess, onFail); }; diff --git a/com.twin.app.shoptime/src/actions/homeActions.js b/com.twin.app.shoptime/src/actions/homeActions.js index 3c546c30..cc328bfb 100644 --- a/com.twin.app.shoptime/src/actions/homeActions.js +++ b/com.twin.app.shoptime/src/actions/homeActions.js @@ -3,13 +3,18 @@ import { TAxios, TAxiosPromise } from '../api/TAxios'; import { types } from './actionTypes'; import { changeAppStatus, getTermsAgreeYn } from './commonActions'; import { collectBannerPositions } from '../utils/domUtils'; +import { createDebugHelpers } from '../utils/debug'; + +// 디버그 헬퍼 설정 +const DEBUG_MODE = false; +const { dlog, dwarn, derror } = createDebugHelpers(DEBUG_MODE); // 약관 정보 조회 IF-LGSP-005 export const getHomeTerms = (props) => (dispatch, getState) => { const { trmsTpCdList, mbrNo } = props; const onSuccess = (response) => { - console.log('getHomeTerms onSuccess ', response.data); + dlog('getHomeTerms onSuccess ', response.data); if (response.data.retCode === 0) { dispatch({ @@ -49,7 +54,7 @@ export const getHomeTerms = (props) => (dispatch, getState) => { payload: finalOptionalTermsValue, }); - console.log( + dlog( '[optionalTermsAvailable] 실제값:', hasOptionalTerms, '강제설정값:', @@ -57,8 +62,8 @@ export const getHomeTerms = (props) => (dispatch, getState) => { ); if (process.env.NODE_ENV === 'development') { - console.log('약관 ID 매핑 생성:', termsIdMap); - console.log('선택약관 존재 여부:', hasOptionalTerms); + dlog('약관 ID 매핑 생성:', termsIdMap); + dlog('선택약관 존재 여부:', hasOptionalTerms); } } @@ -69,7 +74,7 @@ export const getHomeTerms = (props) => (dispatch, getState) => { }; const onFail = (error) => { - console.error('getHomeTerms onFail ', error); + derror('getHomeTerms onFail ', error); }; TAxios( @@ -89,7 +94,7 @@ export const fetchCurrentUserHomeTerms = () => (dispatch, getState) => { const loginUserData = getState().common.appStatus.loginUserData; if (!loginUserData || !loginUserData.userNumber) { - console.error( + derror( 'fetchCurrentUserHomeTerms: userNumber (mbrNo) is not available. User might not be logged in.' ); dispatch({ type: types.GET_TERMS_AGREE_YN_FAILURE }); @@ -100,7 +105,7 @@ export const fetchCurrentUserHomeTerms = () => (dispatch, getState) => { const trmsTpCdList = 'MST00401, MST00402, MST00405'; // 기본 약관 코드 리스트 const onSuccess = (response) => { - console.log('fetchCurrentUserHomeTerms onSuccess ', response.data); + dlog('fetchCurrentUserHomeTerms onSuccess ', response.data); if (response.data.retCode === 0) { dispatch({ @@ -139,7 +144,7 @@ export const fetchCurrentUserHomeTerms = () => (dispatch, getState) => { type: types.SET_OPTIONAL_TERMS_AVAILABILITY, payload: finalOptionalTermsValue, }); - console.log( + dlog( '[optionalTermsAvailable] 실제값:', hasOptionalTerms, '강제설정값:', @@ -147,8 +152,8 @@ export const fetchCurrentUserHomeTerms = () => (dispatch, getState) => { ); if (process.env.NODE_ENV === 'development') { - console.log('약관 ID 매핑 생성:', termsIdMap); - console.log('선택약관 존재 여부:', hasOptionalTerms); + dlog('약관 ID 매핑 생성:', termsIdMap); + dlog('선택약관 존재 여부:', hasOptionalTerms); } } @@ -163,7 +168,7 @@ export const fetchCurrentUserHomeTerms = () => (dispatch, getState) => { }; const onFail = (error) => { - console.error('fetchCurrentUserHomeTerms onFail ', error); + derror('fetchCurrentUserHomeTerms onFail ', error); dispatch({ type: types.GET_TERMS_AGREE_YN_FAILURE }); }; @@ -184,7 +189,7 @@ export const fetchCurrentUserHomeTermsSafe = () => async (dispatch, getState) => const loginUserData = getState().common.appStatus.loginUserData; if (!loginUserData || !loginUserData.userNumber) { - console.error('fetchCurrentUserHomeTerms: userNumber is not available'); + derror('fetchCurrentUserHomeTerms: userNumber is not available'); dispatch({ type: types.GET_TERMS_AGREE_YN_FAILURE }); return { success: false, message: '사용자 정보가 없습니다.' }; } @@ -192,7 +197,7 @@ export const fetchCurrentUserHomeTermsSafe = () => async (dispatch, getState) => const mbrNo = loginUserData.userNumber; const trmsTpCdList = 'MST00401, MST00402, MST00405'; - console.log('Fetching home terms for user:', mbrNo); + dlog('Fetching home terms for user:', mbrNo); // 안전한 API 호출 (기존 TAxios 패턴과 동일) const result = await TAxiosPromise(dispatch, getState, 'get', URLS.GET_HOME_TERMS, { @@ -202,7 +207,7 @@ export const fetchCurrentUserHomeTermsSafe = () => async (dispatch, getState) => // 네트워크 에러인 경우 if (!result.success) { - console.error('fetchCurrentUserHomeTerms network error:', result.error); + derror('fetchCurrentUserHomeTerms network error:', result.error); dispatch({ type: types.GET_TERMS_AGREE_YN_FAILURE }); return { success: false, message: '네트워크 오류가 발생했습니다.' }; } @@ -210,7 +215,7 @@ export const fetchCurrentUserHomeTermsSafe = () => async (dispatch, getState) => // 기존 TAxios처럼 특별한 retCode들은 TAxios 내부에서 이미 처리됨 // (401, 402, 501, 602, 603, 604 등은 TAxios에서 알아서 처리하고 onSuccess가 호출되지 않음) - console.log('fetchCurrentUserHomeTerms response:', result.data); + dlog('fetchCurrentUserHomeTerms response:', result.data); // 정상적으로 onSuccess가 호출된 경우에만 여기까지 옴 if (result.data && result.data.retCode === 0) { @@ -252,8 +257,8 @@ export const fetchCurrentUserHomeTermsSafe = () => async (dispatch, getState) => }); if (process.env.NODE_ENV === 'development') { - console.log('약관 ID 매핑 생성:', termsIdMap); - console.log( + dlog('약관 ID 매핑 생성:', termsIdMap); + dlog( '선택약관 존재 여부 - 실제값:', hasOptionalTerms, '강제설정값:', @@ -271,7 +276,7 @@ export const fetchCurrentUserHomeTermsSafe = () => async (dispatch, getState) => } else { // retCode가 0이 아닌 일반적인 API 에러 // Chromium68 호환성을 위해 Optional Chaining 제거 - console.error('API returned non-zero retCode:', result.data && result.data.retCode); + derror('API returned non-zero retCode:', result.data && result.data.retCode); dispatch({ type: types.GET_TERMS_AGREE_YN_FAILURE }); return { success: false, @@ -283,7 +288,7 @@ export const fetchCurrentUserHomeTermsSafe = () => async (dispatch, getState) => // 메뉴 목록 조회 IF-LGSP-044 export const getHomeMenu = () => (dispatch, getState) => { const onSuccess = (response) => { - // console.log("getHomeMenu onSuccess ", response.data); + // dlog("getHomeMenu onSuccess ", response.data); dispatch({ type: types.GET_HOME_MENU, @@ -292,7 +297,7 @@ export const getHomeMenu = () => (dispatch, getState) => { }; const onFail = (error) => { - console.error('getHomeMenu onFail ', error); + derror('getHomeMenu onFail ', error); }; TAxios(dispatch, getState, 'get', URLS.GET_HOME_MENU, {}, {}, onSuccess, onFail); @@ -305,7 +310,7 @@ export const getThemeCurationDetailInfo = (params) => (dispatch, getState) => { dispatch(changeAppStatus({ showLoadingPanel: { show: true, type: 'wait' } })); const onSuccess = (response) => { - console.log('getThemeCurationDetailInfo onSuccess', response.data); + dlog('getThemeCurationDetailInfo onSuccess', response.data); dispatch({ type: types.GET_THEME_CURATION_DETAIL_INFO, @@ -316,7 +321,7 @@ export const getThemeCurationDetailInfo = (params) => (dispatch, getState) => { }; const onFail = (error) => { - console.error('getThemeCurationDetailInfo onFail', error); + derror('getThemeCurationDetailInfo onFail', error); dispatch(changeAppStatus({ showLoadingPanel: { show: false } })); }; @@ -338,7 +343,7 @@ export const getThemeHotelDetailInfo = (params) => (dispatch, getState) => { dispatch(changeAppStatus({ showLoadingPanel: { show: true, type: 'wait' } })); const onSuccess = (response) => { - console.log('getThemeHotelDetailInfo onSuccess', response.data); + dlog('getThemeHotelDetailInfo onSuccess', response.data); dispatch({ type: types.GET_THEME_HOTEL_DETAIL_INFO, @@ -349,7 +354,7 @@ export const getThemeHotelDetailInfo = (params) => (dispatch, getState) => { }; const onFail = (error) => { - console.error('getThemeHotelDetailInfo onFail', error); + derror('getThemeHotelDetailInfo onFail', error); dispatch(changeAppStatus({ showLoadingPanel: { show: false } })); }; @@ -367,7 +372,7 @@ export const getThemeHotelDetailInfo = (params) => (dispatch, getState) => { // HOME LAYOUT 정보 조회 IF-LGSP-300 export const getHomeLayout = () => (dispatch, getState) => { const onSuccess = (response) => { - console.log('getHomeLayout onSuccess', response.data); + dlog('getHomeLayout onSuccess', response.data); dispatch({ type: types.GET_HOME_LAYOUT, @@ -377,7 +382,7 @@ export const getHomeLayout = () => (dispatch, getState) => { }; const onFail = (error) => { - console.error('getHomeLayout onFail', error); + derror('getHomeLayout onFail', error); dispatch(changeAppStatus({ showLoadingPanel: { show: false } })); }; @@ -387,7 +392,7 @@ export const getHomeLayout = () => (dispatch, getState) => { // HOME Main Contents Banner 정보 조회 IF-LGSP-301 export const getHomeMainContents = () => (dispatch, getState) => { const onSuccess = (response) => { - console.log('getHomeMainContents onSuccess', response.data); + dlog('getHomeMainContents onSuccess', response.data); dispatch({ type: types.GET_HOME_MAIN_CONTENTS, @@ -399,7 +404,7 @@ export const getHomeMainContents = () => (dispatch, getState) => { }; const onFail = (error) => { - console.error('getHomeMainContents onFail', error); + derror('getHomeMainContents onFail', error); dispatch(changeAppStatus({ showLoadingPanel: { show: false } })); }; @@ -409,7 +414,7 @@ export const getHomeMainContents = () => (dispatch, getState) => { // Theme 전시 정보 조회 : IF-LGSP-045 export const getThemeCurationInfo = () => (dispatch, getState) => { const onSuccess = (response) => { - console.log('getThemeCurationInfo onSuccess', response.data); + dlog('getThemeCurationInfo onSuccess', response.data); dispatch({ type: types.GET_THEME_CURATION_INFO, @@ -420,7 +425,7 @@ export const getThemeCurationInfo = () => (dispatch, getState) => { }; const onFail = (error) => { - console.error('getThemeCurationInfo onFail', error); + derror('getThemeCurationInfo onFail', error); dispatch(changeAppStatus({ showLoadingPanel: { show: false } })); }; @@ -434,7 +439,7 @@ export const getThemeMenuShelfInfo = (props) => (dispatch, getState) => { dispatch(changeAppStatus({ showLoadingPanel: { show: true, type: 'wait' } })); const onSuccess = (response) => { - console.log('getThemeMenuShelfInfo onSuccess', response.data); + dlog('getThemeMenuShelfInfo onSuccess', response.data); dispatch(changeAppStatus({ showLoadingPanel: { show: false } })); dispatch({ type: types.GET_THEME_MENU_SHELF_INFO, @@ -443,7 +448,7 @@ export const getThemeMenuShelfInfo = (props) => (dispatch, getState) => { }; const onFail = (error) => { - console.error('getThemeMenuShelfInfo onFail', error); + derror('getThemeMenuShelfInfo onFail', error); dispatch(changeAppStatus({ showLoadingPanel: { show: false } })); }; @@ -495,7 +500,7 @@ export const checkEnterThroughGNB = (boolean) => ({ export const setBannerIndex = (bannerId, index) => { if (!bannerId) { - console.warn('setBannerIndex called with undefined bannerId'); + dwarn('setBannerIndex called with undefined bannerId'); return { type: 'NO_OP' }; } return { @@ -551,9 +556,9 @@ export const collectAndSaveBannerPositions = (bannerIds) => async (dispatch) => dispatch(setBannerPositions(positions)); if (process.env.NODE_ENV === 'development') { - console.log('[homeActions] 배너 위치 수집 완료:', positions); + dlog('[homeActions] 배너 위치 수집 완료:', positions); } } catch (error) { - console.error('[homeActions] 배너 위치 수집 실패:', error); + derror('[homeActions] 배너 위치 수집 실패:', error); } }; diff --git a/com.twin.app.shoptime/src/actions/logActions.js b/com.twin.app.shoptime/src/actions/logActions.js index 9c91d1a2..949c5abc 100644 --- a/com.twin.app.shoptime/src/actions/logActions.js +++ b/com.twin.app.shoptime/src/actions/logActions.js @@ -1,11 +1,13 @@ -import { countryCode, URLS } from "../api/apiConfig"; -import { TLogEvent } from "../api/TLogEvent"; -import { LOG_MENU, LOG_TP_NO } from "../utils/Config"; -import { - formatGMTString, - getTimeDifferenceByMilliseconds, -} from "../utils/helperMethods"; -import { setGNBMenu, setSecondLayerInfo } from "./commonActions"; +import { countryCode, URLS } from '../api/apiConfig'; +import { TLogEvent } from '../api/TLogEvent'; +import { LOG_MENU, LOG_TP_NO } from '../utils/Config'; +import { formatGMTString, getTimeDifferenceByMilliseconds } from '../utils/helperMethods'; +import { setGNBMenu, setSecondLayerInfo } from './commonActions'; +import { createDebugHelpers } from '../utils/debug'; + +// 디버그 헬퍼 설정 +const DEBUG_MODE = false; +const { dlog, dwarn, derror } = createDebugHelpers(DEBUG_MODE); export const getUrlByLogTpNo = (logTpNo) => { switch (logTpNo) { @@ -157,17 +159,17 @@ export const getUrlByLogTpNo = (logTpNo) => { export const postTotalLog = (params, url) => (dispatch, getState) => { const onSuccess = (response) => { - // console.log("#Total Log onSuccess.....", response); + // dlog("#Total Log onSuccess.....", response); }; const onFail = (error) => { - // console.error("totalLog onFail...", error); + // derror("totalLog onFail...", error); }; TLogEvent( dispatch, getState, - "post", + 'post', URLS.LOG_TOTAL_RECOMMEND, {}, params, @@ -181,20 +183,20 @@ export const postLog = (params, url) => (dispatch, getState) => { const { logTpNo } = params; const onSuccess = (response) => { - // console.log( + // dlog( // `postLog onSuccess logTpNo ${logTpNo}`, // JSON.parse(response.config.data) // ); }; const onFail = (error) => { - console.error("postLog onFail", error); + derror('postLog onFail', error); }; TLogEvent( dispatch, getState, - "post", + 'post', url ?? getUrlByLogTpNo(logTpNo), {}, params, @@ -249,7 +251,7 @@ export const sendLogLive = (params, callback) => (dispatch, getState) => { const { entryMenu, nowMenu } = getState().common.menu; if (!logTpNo || !patncNm || !patnrId || !showId || !watchStrtDt) { - console.log("[sendLogLive] invalid params", params); + dlog('[sendLogLive] invalid params', params); return; } @@ -303,7 +305,7 @@ export const sendLogVOD = (params, callback) => (dispatch, getState) => { const { entryMenu, nowMenu } = getState().common.menu; if (!logTpNo || !watchStrtDt) { - console.log("[sendLogLive] invalid params", params); + dlog('[sendLogLive] invalid params', params); return; } @@ -368,24 +370,24 @@ export const sendLogCuration = (params) => (dispatch, getState) => { const { entryMenu, nowMenu } = getState().common.menu; if (!logTpNo) { - console.log("[sendLogCuration] invalid params", params); + dlog('[sendLogCuration] invalid params', params); return; } const newParams = { - cnttTpNm: params.cnttTpNm ?? "", - curationId: params.curationId ?? "", - curationNm: params.curationNm ?? "", + cnttTpNm: params.cnttTpNm ?? '', + curationId: params.curationId ?? '', + curationNm: params.curationNm ?? '', entryMenu: entryMenu, - expsOrd: params.expsOrd ?? "", - lgCatCd: params.lgCatCd ?? "", - lgCatNm: params.lgCatNm ?? "", - logTpNo: params.logTpNo ?? "", - linkTpCd: params.linkTpCd ?? "", + expsOrd: params.expsOrd ?? '', + lgCatCd: params.lgCatCd ?? '', + lgCatNm: params.lgCatNm ?? '', + logTpNo: params.logTpNo ?? '', + linkTpCd: params.linkTpCd ?? '', nowMenu: nowMenu, - patncNm: params.patncNm ?? "", - patnrId: params.patnrId ?? "", - sortTpNm: params.sortTpNm ?? "", + patncNm: params.patncNm ?? '', + patnrId: params.patnrId ?? '', + sortTpNm: params.sortTpNm ?? '', }; dispatch(postLog(newParams)); @@ -438,16 +440,12 @@ export const sendLogGNB = (menu) => (dispatch, getState) => { const secondLayerInfo = getState().common.secondLayerInfo; if (!menu) { - console.log("[sendLogGNB] invalid params", menu); + dlog('[sendLogGNB] invalid params', menu); return; } if ( - ![ - LOG_MENU.SEARCH_SEARCH, - LOG_MENU.SEARCH_RESULT, - LOG_MENU.SEARCH_BEST_SELLER, - ].includes(menu) + ![LOG_MENU.SEARCH_SEARCH, LOG_MENU.SEARCH_RESULT, LOG_MENU.SEARCH_BEST_SELLER].includes(menu) ) { if (menu === nowMenu || !menuMovSno) { return; @@ -460,17 +458,13 @@ export const sendLogGNB = (menu) => (dispatch, getState) => { logTpNo: LOG_TP_NO.GNB, menuMovSno: `${menuMovSno}`, nowMenu: menu, - outDt: "", + outDt: '', }; dispatch(setGNBMenu(menu)); dispatch(postLog(newParams)); - if ( - [1].includes(menuMovSno) && - secondLayerInfo && - Object.keys(secondLayerInfo).length > 0 - ) { + if ([1].includes(menuMovSno) && secondLayerInfo && Object.keys(secondLayerInfo).length > 0) { dispatch( sendLogSecondLayer({ ...secondLayerInfo, @@ -481,7 +475,7 @@ export const sendLogGNB = (menu) => (dispatch, getState) => { dispatch( sendLogDeepLinkFlag({ deeplinkId: secondLayerInfo.deeplinkId, - flag: secondLayerInfo.deeplinkId ? "Y" : "N", + flag: secondLayerInfo.deeplinkId ? 'Y' : 'N', }) ); } @@ -534,15 +528,10 @@ export const sendLogProductDetail = (params) => (dispatch, getState) => { const { logTpNo } = params; const { entryMenu, nowMenu } = getState().common.menu; - const menu = - logTpNo === LOG_TP_NO.PRODUCT.PRODUCT_DETAIL_IMAGE - ? entryMenu - : params?.entryMenu; + const menu = logTpNo === LOG_TP_NO.PRODUCT.PRODUCT_DETAIL_IMAGE ? entryMenu : params?.entryMenu; const outDt = - logTpNo === LOG_TP_NO.PRODUCT.PRODUCT_DETAIL_IMAGE - ? "" - : formatGMTString(new Date()); + logTpNo === LOG_TP_NO.PRODUCT.PRODUCT_DETAIL_IMAGE ? '' : formatGMTString(new Date()); const newParams = { ...params, @@ -582,14 +571,11 @@ export const sendLogDetail = (params) => (dispatch, getState) => { const { entryMenu, nowMenu } = getState().common.menu; if (!logTpNo || !patncNm || !patnrId) { - console.log("[sendLogDetail] invalid params", params); + dlog('[sendLogDetail] invalid params', params); return; } - const outDt = - logTpNo === LOG_TP_NO.DETAIL.DETAIL_BUTTON_CLICK - ? "" - : formatGMTString(new Date()); + const outDt = logTpNo === LOG_TP_NO.DETAIL.DETAIL_BUTTON_CLICK ? '' : formatGMTString(new Date()); const newParams = { ...params, @@ -688,7 +674,7 @@ export const sendLogPartners = (params) => (dispatch, getState) => { const { entryMenu, nowMenu } = getState().common.menu; if (!patncNm || !patnrId) { - console.log("[sendLogPartners] invalid params", params); + dlog('[sendLogPartners] invalid params', params); return; } @@ -719,7 +705,7 @@ export const sendLogMyPageAlertFlag = (params) => (dispatch, getState) => { const { entryMenu, nowMenu } = getState().common.menu; if (!alertFlag) { - console.log("[sendLogMyPageAlertFlag] invalid params", params); + dlog('[sendLogMyPageAlertFlag] invalid params', params); return; } @@ -749,7 +735,7 @@ export const sendLogMyPageMyDelete = (params) => (dispatch, getState) => { const { entryMenu, nowMenu } = getState().common.menu; if (!cnt) { - console.log("[sendLogMyPageMyDelete] invalid params", params); + dlog('[sendLogMyPageMyDelete] invalid params', params); return; } @@ -781,7 +767,7 @@ export const sendLogMyPageNotice = (params) => (dispatch, getState) => { const { entryMenu, nowMenu } = getState().common.menu; if (!itemId || !title) { - console.log("[sendLogNoticeView] invalid params", params); + dlog('[sendLogNoticeView] invalid params', params); return; } @@ -819,7 +805,7 @@ export const sendLogSearch = (params) => (dispatch, getState) => { const { entryMenu, nowMenu } = getState().common.menu; if (!inputFlag || !itemCnt || !keyword || !showCnt || !themeCnt) { - console.log("[sendLogSearch] invalid params", params); + dlog('[sendLogSearch] invalid params', params); return; } @@ -869,25 +855,25 @@ export const sendLogSearchClick = (params) => (dispatch, getState) => { const { entryMenu, nowMenu } = getState().common.menu; if (!keyword || !patncNm || !patnrId) { - console.log("[sendLogSearchClick] invalid params", params); + dlog('[sendLogSearchClick] invalid params', params); return; } const newParams = { - curationId: params?.curationId ?? "", - curationNm: params?.curationNm ?? "", - dcAfPrice: params?.dcAfPrice ?? "", + curationId: params?.curationId ?? '', + curationNm: params?.curationNm ?? '', + dcAfPrice: params?.dcAfPrice ?? '', entryMenu: entryMenu, keyword, - lgCatNm: params?.lgCatNm ?? "", + lgCatNm: params?.lgCatNm ?? '', logTpNo: LOG_TP_NO.SEARCH_CLICK, nowMenu: nowMenu, patncNm, patnrId, - prdtId: params?.prdtId ?? "", - prdtNm: params?.prdtNm ?? "", - showId: params?.showId ?? "", - showNm: params?.showNm ?? "", + prdtId: params?.prdtId ?? '', + prdtNm: params?.prdtNm ?? '', + showId: params?.showId ?? '', + showNm: params?.showNm ?? '', }; dispatch(postLog(newParams)); @@ -925,7 +911,7 @@ export const sendLogUpcomingFlag = (params) => (dispatch, getState) => { const { entryMenu, nowMenu } = getState().common.menu; if (!items) { - console.log("[sendLogUpcomingFlag] invalid params", params); + dlog('[sendLogUpcomingFlag] invalid params', params); return; } @@ -972,25 +958,17 @@ export const sendLogAlarmPop = (params) => (dispatch, getState) => { const { alarmDt, alarmType, cnt, patncNm, patnrId, showId, showNm } = params; const { entryMenu, nowMenu } = getState().common.menu; - if ( - !alarmDt || - !alarmType || - !cnt || - !patncNm || - !patnrId || - !showId || - !showNm - ) { - console.log("[sendLogAlarmPop] invalid params", params); + if (!alarmDt || !alarmType || !cnt || !patncNm || !patnrId || !showId || !showNm) { + dlog('[sendLogAlarmPop] invalid params', params); return; } const newParams = { ...params, entryMenu: entryMenu, - hstNm: params?.hstNm ?? "", - lgCatCd: params?.lgCatCd ?? "", - lgCatNm: params?.lgCatNm ?? "", + hstNm: params?.hstNm ?? '', + lgCatCd: params?.lgCatCd ?? '', + lgCatNm: params?.lgCatNm ?? '', logTpNo: LOG_TP_NO.ALARM_POP, nowMenu: nowMenu, }; @@ -1032,29 +1010,20 @@ export const sendLogAlarmPop = (params) => (dispatch, getState) => { * (M) showNm 방송 이름 */ export const sendLogAlarmClick = (params) => (dispatch, getState) => { - const { alarmDt, alarmType, clickFlag, cnt, logTpNo, patnrId, showId } = - params; + const { alarmDt, alarmType, clickFlag, cnt, logTpNo, patnrId, showId } = params; const { entryMenu, nowMenu } = getState().common.menu; - if ( - !alarmDt || - !alarmType || - !clickFlag || - !cnt || - !logTpNo || - !patnrId || - !showId - ) { - console.log("[sendLogAlarmClick] invalid params", params); + if (!alarmDt || !alarmType || !clickFlag || !cnt || !logTpNo || !patnrId || !showId) { + dlog('[sendLogAlarmClick] invalid params', params); return; } const newParams = { ...params, entryMenu: entryMenu, - hstNm: params?.hstNm ?? "", - lgCatCd: params?.lgCatCd ?? "", - lgCatNm: params?.lgCatNm ?? "", + hstNm: params?.hstNm ?? '', + lgCatCd: params?.lgCatCd ?? '', + lgCatNm: params?.lgCatNm ?? '', nowMenu: nowMenu, }; @@ -1177,7 +1146,7 @@ export const sendLogTerms = (params) => (dispatch, getState) => { const { entryMenu, nowMenu } = getState().common.menu; if (!logTpNo) { - console.log("[sendLogTerms] invalid params", params); + dlog('[sendLogTerms] invalid params', params); return; } @@ -1208,7 +1177,7 @@ export const sendLogLgAccountLogin = (params) => (dispatch, getState) => { const { entryMenu, nowMenu } = getState().common.menu; if (!lginTpNm || !usrNo) { - console.log("[sendLogLgAccountLogin] invalid params", params); + dlog('[sendLogLgAccountLogin] invalid params', params); return; } @@ -1239,7 +1208,7 @@ export const sendLogOrderBtnClick = (params) => (dispatch, getState) => { const { entryMenu, nowMenu } = getState().common.menu; if (!btnNm) { - console.log("[sendLogOrderBtnClick] invalid params", params); + dlog('[sendLogOrderBtnClick] invalid params', params); return; } @@ -1272,7 +1241,7 @@ export const sendLogOrderChange = (params) => (dispatch, getState) => { const { entryMenu, nowMenu } = getState().common.menu; if (!reqRsn || !reqTpNm) { - console.log("[sendLogOrderChange] invalid params", params); + dlog('[sendLogOrderChange] invalid params', params); return; } @@ -1315,7 +1284,7 @@ export const sendLogCouponUse = (params) => (dispatch, getState) => { // const {} = params const { entryMenu, nowMenu } = getState().common.menu; // if() { - // console.log('[sendLogCouponUse] invalid params', params) + // dlog('[sendLogCouponUse] invalid params', params) // } const newParams = { @@ -1364,29 +1333,11 @@ export const sendLogCouponUse = (params) => (dispatch, getState) => { * (M) qty 수량 */ export const sendLogPaymentEntry = (params) => (dispatch, getState) => { - const { - cartTpSno, - dcAftrPrc, - dcBefPrc, - patncNm, - patnrId, - prodId, - prodNm, - qty, - } = params; + const { cartTpSno, dcAftrPrc, dcBefPrc, patncNm, patnrId, prodId, prodNm, qty } = params; const { entryMenu, nowMenu } = getState().common.menu; - if ( - !cartTpSno || - !dcAftrPrc || - !dcBefPrc || - !patncNm || - !patnrId || - !prodId || - !prodNm || - !qty - ) { - console.log("[sendLogPaymentEntry] invalid params", params); + if (!cartTpSno || !dcAftrPrc || !dcBefPrc || !patncNm || !patnrId || !prodId || !prodNm || !qty) { + dlog('[sendLogPaymentEntry] invalid params', params); return; } @@ -1438,17 +1389,7 @@ export const sendLogPaymentEntry = (params) => (dispatch, getState) => { * (M) usrNo 사용자 번호 */ export const sendLogPaymentComplete = (params) => (dispatch, getState) => { - const { - cartTpSno, - dcAftrPrc, - dcBefPrc, - patncNm, - patnrId, - prodId, - prodNm, - qty, - usrNo, - } = params; + const { cartTpSno, dcAftrPrc, dcBefPrc, patncNm, patnrId, prodId, prodNm, qty, usrNo } = params; const { entryMenu, nowMenu } = getState().common.menu; if ( @@ -1462,7 +1403,7 @@ export const sendLogPaymentComplete = (params) => (dispatch, getState) => { !qty || !usrNo ) { - console.log("[sendLogPaymentComplete] invalid params", params); + dlog('[sendLogPaymentComplete] invalid params', params); return; } @@ -1506,22 +1447,22 @@ export const sendLogFeaturedBrands = (params) => (dispatch, getState) => { const { entryMenu, nowMenu } = getState().common.menu; if (!patncNm || !patnrId) { - console.log("[sendLogFeaturedBrands] invalid params", params); + dlog('[sendLogFeaturedBrands] invalid params', params); return; } const newParams = { - catCd: params.catCd ?? "", - catNm: params.catNm ?? "", - crtrId: params.crtrId ?? "", - crtrNm: params.crtrNm ?? "", + catCd: params.catCd ?? '', + catNm: params.catNm ?? '', + crtrId: params.crtrId ?? '', + crtrNm: params.crtrNm ?? '', entryMenu: entryMenu, logTpNo: LOG_TP_NO.BRANDS, nowMenu: nowMenu, patncNm, patnrId, - srsId: params.srsId ?? "", - srsNm: params.srsNm ?? "", + srsId: params.srsId ?? '', + srsNm: params.srsNm ?? '', }; dispatch(postLog(newParams)); @@ -1543,7 +1484,7 @@ export const sendLogMyInfoEdit = (params) => (dispatch, getState) => { const { entryMenu, nowMenu } = getState().common.menu; if (!btnNm) { - console.log("[sendLogMyInfoEdit] invalid params", params); + dlog('[sendLogMyInfoEdit] invalid params', params); return; } @@ -1572,7 +1513,7 @@ export const sendLogCheckOutBtnClick = (params) => (dispatch, getState) => { const { entryMenu, nowMenu } = getState().common.menu; if (!btnNm) { - console.log("[sendLogCheckOutBtnClick] invalid params", params); + dlog('[sendLogCheckOutBtnClick] invalid params', params); return; } @@ -1597,19 +1538,19 @@ export const sendLogTotalRecommend = (params) => (dispatch, getState) => { const macAddr = macAddress?.wired ? macAddress?.wired : macAddress?.wifi; - if (typeof window === "object" && !window.PalmSystem) { - localMacAddress = "00:1A:2B:3C:4D:5E"; + if (typeof window === 'object' && !window.PalmSystem) { + localMacAddress = '00:1A:2B:3C:4D:5E'; } const logCreateTime = new Date().toISOString(); - // console.log("#params", params); + // dlog("#params", params); const newParams = { ...params, userNumber: userNumber, macAddr: macAddr ? macAddr : localMacAddress, - entryMenu: entryMenu ? entryMenu : "APP", + entryMenu: entryMenu ? entryMenu : 'APP', logCreateTime, }; diff --git a/com.twin.app.shoptime/src/actions/mediaActions.js b/com.twin.app.shoptime/src/actions/mediaActions.js index 12c135fb..5759c020 100644 --- a/com.twin.app.shoptime/src/actions/mediaActions.js +++ b/com.twin.app.shoptime/src/actions/mediaActions.js @@ -2,6 +2,11 @@ import Spotlight from '@enact/spotlight'; import { panel_names } from '../utils/Config'; import { popPanel, pushPanel, updatePanel } from './panelActions'; +import { createDebugHelpers } from '../utils/debug'; + +// 디버그 헬퍼 설정 +const DEBUG_MODE = false; +const { dlog, dwarn, derror } = createDebugHelpers(DEBUG_MODE); let startMediaFocusTimer = null; @@ -23,7 +28,7 @@ export const startMediaPlayer = const topPanel = panels[panels.length - 1]; let panelWorkingAction = pushPanel; - console.log('[startMediaPlayer]-LoadingVideo 🚀 시작:', { + dlog('[startMediaPlayer]-LoadingVideo 🚀 시작:', { showUrl: rest?.showUrl?.substring(0, 50), showNm: rest?.showNm, prdtId: rest?.prdtId, @@ -53,7 +58,7 @@ export const startMediaPlayer = ) ); - console.log('[startMediaPlayer]-LoadingVideo ✅ MediaPanel dispatch 완료'); + dlog('[startMediaPlayer]-LoadingVideo ✅ MediaPanel dispatch 완료'); if (modal && modalContainerId && !spotlightDisable) { Spotlight.setPointerMode(false); @@ -70,21 +75,21 @@ export const finishMediaPreview = () => (dispatch, getState) => { const panels = getState().panels.panels; const topPanel = panels[panels.length - 1]; - // console.log('[finishMediaPreview] ========== Called =========='); - // console.log('[finishMediaPreview] Current panels:', JSON.stringify(panels, null, 2)); - // console.log('[finishMediaPreview] topPanel:', JSON.stringify(topPanel, null, 2)); + // dlog('[finishMediaPreview] ========== Called =========='); + // dlog('[finishMediaPreview] Current panels:', JSON.stringify(panels, null, 2)); + // dlog('[finishMediaPreview] topPanel:', JSON.stringify(topPanel, null, 2)); if (topPanel && topPanel.name === panel_names.MEDIA_PANEL && topPanel.panelInfo.modal) { - // console.log('[finishMediaPreview] Closing modal MediaPanel'); + // dlog('[finishMediaPreview] Closing modal MediaPanel'); if (startMediaFocusTimer) { clearTimeout(startMediaFocusTimer); startMediaFocusTimer = null; } dispatch(popPanel()); - // console.log('[finishMediaPreview] popPanel dispatched'); + // dlog('[finishMediaPreview] popPanel dispatched'); } else { - // console.log('[finishMediaPreview] Not closing - no modal MediaPanel on top'); + // dlog('[finishMediaPreview] Not closing - no modal MediaPanel on top'); } }; @@ -120,7 +125,7 @@ export const pauseModalMedia = () => (dispatch, getState) => { ); if (modalMediaPanel) { - // console.log('[pauseModalMedia] Pausing modal MediaPanel'); + // dlog('[pauseModalMedia] Pausing modal MediaPanel'); dispatch( updatePanel({ name: panel_names.MEDIA_PANEL, @@ -144,7 +149,7 @@ export const resumeModalMedia = () => (dispatch, getState) => { ); if (modalMediaPanel && modalMediaPanel.panelInfo?.isPaused) { - // console.log('[resumeModalMedia] Resuming modal MediaPanel'); + // dlog('[resumeModalMedia] Resuming modal MediaPanel'); dispatch( updatePanel({ name: panel_names.MEDIA_PANEL, @@ -163,21 +168,21 @@ export const resumeModalMedia = () => (dispatch, getState) => { export const switchMediaToFullscreen = () => (dispatch, getState) => { const panels = getState().panels.panels; - // console.log('[switchMediaToFullscreen] ========== Called =========='); - // console.log('[switchMediaToFullscreen] Current panels:', JSON.stringify(panels, null, 2)); + // dlog('[switchMediaToFullscreen] ========== Called =========='); + // dlog('[switchMediaToFullscreen] Current panels:', JSON.stringify(panels, null, 2)); const modalMediaPanel = panels.find( (panel) => panel.name === panel_names.MEDIA_PANEL && panel.panelInfo?.modal ); - // console.log( + // dlog( // '[switchMediaToFullscreen] modalMediaPanel found:', // JSON.stringify(modalMediaPanel, null, 2) // ); if (modalMediaPanel) { - // console.log('[switchMediaToFullscreen] Switching to fullscreen - updating modal to false'); - // console.log( + // dlog('[switchMediaToFullscreen] Switching to fullscreen - updating modal to false'); + // dlog( // '[switchMediaToFullscreen] Existing panelInfo:', // JSON.stringify(modalMediaPanel.panelInfo, null, 2) // ); @@ -187,7 +192,7 @@ export const switchMediaToFullscreen = () => (dispatch, getState) => { modal: false, }; - // console.log( + // dlog( // '[switchMediaToFullscreen] New panelInfo to dispatch:', // JSON.stringify(newPanelInfo, null, 2) // ); @@ -198,9 +203,9 @@ export const switchMediaToFullscreen = () => (dispatch, getState) => { panelInfo: newPanelInfo, }) ); - // console.log('[switchMediaToFullscreen] updatePanel dispatched'); + // dlog('[switchMediaToFullscreen] updatePanel dispatched'); } else { - // console.log( + // dlog( // '[switchMediaToFullscreen] No modal MediaPanel found - cannot switch to fullscreen' // ); } @@ -215,7 +220,7 @@ export const switchMediaToModal = (modalContainerId, modalClassName) => (dispatc const mediaPanel = panels.find((panel) => panel.name === panel_names.MEDIA_PANEL); if (mediaPanel && !mediaPanel.panelInfo?.modal) { - // console.log('[switchMediaToModal] Switching to modal'); + // dlog('[switchMediaToModal] Switching to modal'); dispatch( updatePanel({ name: panel_names.MEDIA_PANEL, @@ -237,10 +242,11 @@ export const switchMediaToModal = (modalContainerId, modalClassName) => (dispatc export const minimizeModalMedia = () => (dispatch, getState) => { const panels = getState().panels.panels; - console.log('[Minimize] ========== Called =========='); - console.log('[Minimize] Total panels:', panels.length); - console.log( - '[Minimize] All panels:',panels + dlog('[Minimize] ========== Called =========='); + dlog('[Minimize] Total panels:', panels.length); + dlog( + '[Minimize] All panels:', + panels // JSON.stringify( // panels.map((p) => ({ name: p.name, modal: p.panelInfo?.modal })), // null, @@ -252,13 +258,13 @@ export const minimizeModalMedia = () => (dispatch, getState) => { (panel) => panel.name === panel_names.MEDIA_PANEL && panel.panelInfo?.modal ); - // console.log('[Minimize] Found modalMediaPanel:', !!modalMediaPanel); + // dlog('[Minimize] Found modalMediaPanel:', !!modalMediaPanel); if (modalMediaPanel) { - console.log( + dlog( '[Minimize] modalMediaPanel.panelInfo:', JSON.stringify(modalMediaPanel.panelInfo, null, 2) ); - // console.log('[Minimize] ✅ Minimizing modal MediaPanel (modal=false, isMinimized=true)'); + // dlog('[Minimize] ✅ Minimizing modal MediaPanel (modal=false, isMinimized=true)'); dispatch( updatePanel({ name: panel_names.MEDIA_PANEL, @@ -273,7 +279,7 @@ export const minimizeModalMedia = () => (dispatch, getState) => { }) ); } else { - console.log('[Minimize] ❌ No modal MediaPanel found - cannot minimize'); + dlog('[Minimize] ❌ No modal MediaPanel found - cannot minimize'); } }; @@ -285,16 +291,16 @@ export const restoreModalMedia = () => (dispatch, getState) => { const panels = getState().panels.panels; if (typeof window !== 'undefined' && window.detailPanelScrollTop !== 0) { - console.log( + dlog( '[restoreModalMedia] Blocked restore because detail panel scroll not zero:', window.detailPanelScrollTop ); return; } - // console.log('[Restore]] ========== Called =========='); - // console.log('[Restore] Total panels:', panels.length); - // console.log( + // dlog('[Restore]] ========== Called =========='); + // dlog('[Restore] Total panels:', panels.length); + // dlog( // '[Restore] All panels:', // JSON.stringify( // panels.map((p) => ({ @@ -315,13 +321,13 @@ export const restoreModalMedia = () => (dispatch, getState) => { panel.panelInfo?.isMinimized ); - // console.log('[restoreModalMedia] Found minimizedMediaPanel:', !!minimizedMediaPanel); + // dlog('[restoreModalMedia] Found minimizedMediaPanel:', !!minimizedMediaPanel); if (minimizedMediaPanel) { - // console.log( + // dlog( // '[restoreModalMedia] minimizedMediaPanel.panelInfo:', // JSON.stringify(minimizedMediaPanel.panelInfo, null, 2) // ); - // console.log( + // dlog( // '[restoreModalMedia] ✅ Restoring modal MediaPanel (modal=true, isMinimized=false)' // ); dispatch( @@ -336,6 +342,6 @@ export const restoreModalMedia = () => (dispatch, getState) => { }) ); } else { - // console.log('[restoreModalMedia] ❌ No minimized MediaPanel found - cannot restore'); + // dlog('[restoreModalMedia] ❌ No minimized MediaPanel found - cannot restore'); } }; diff --git a/com.twin.app.shoptime/src/actions/mockCartActions.js b/com.twin.app.shoptime/src/actions/mockCartActions.js index a1cf4200..d695101a 100644 --- a/com.twin.app.shoptime/src/actions/mockCartActions.js +++ b/com.twin.app.shoptime/src/actions/mockCartActions.js @@ -1,5 +1,16 @@ import { BUYNOW_CONFIG } from '../utils/BuyNowConfig'; -import { createMockCartListData, createMockCartData, addMockCartItem, removeMockCartItem, updateMockCartItemQuantity } from '../utils/BuyNowDataManipulator'; +import { + createMockCartListData, + createMockCartData, + addMockCartItem, + removeMockCartItem, + updateMockCartItemQuantity, +} from '../utils/BuyNowDataManipulator'; +import { createDebugHelpers } from '../utils/debug'; + +// 디버그 헬퍼 설정 +const DEBUG_MODE = false; +const { dlog, dwarn, derror } = createDebugHelpers(DEBUG_MODE); // Mock Cart Action Types export const MOCK_CART_TYPES = { @@ -16,27 +27,29 @@ export const MOCK_CART_TYPES = { * Mock 장바구니 초기화 * BuyOption에서 ADD TO CART 시 호출 - 기존 장바구니에 상품 추가 */ -export const initializeMockCart = (productData, optionInfo = {}, quantity = 1) => (dispatch, getState) => { - if (!BUYNOW_CONFIG.isMockMode()) { - return; - } +export const initializeMockCart = + (productData, optionInfo = {}, quantity = 1) => + (dispatch, getState) => { + if (!BUYNOW_CONFIG.isMockMode()) { + return; + } - console.log('[MockCartActions] initializeMockCart - productData:', productData); + dlog('[MockCartActions] initializeMockCart - productData:', productData); - // 기존 장바구니 데이터 확인 - const currentCart = getState().mockCart.cartInfo || []; - console.log('[MockCartActions] initializeMockCart - current cart items:', currentCart.length); + // 기존 장바구니 데이터 확인 + const currentCart = getState().mockCart.cartInfo || []; + dlog('[MockCartActions] initializeMockCart - current cart items:', currentCart.length); - // 새 상품 데이터 생성 - const newCartItem = createMockCartData(productData, optionInfo, quantity); + // 새 상품 데이터 생성 + const newCartItem = createMockCartData(productData, optionInfo, quantity); - if (newCartItem) { - // addToMockCart를 사용하여 기존 장바구니에 상품 추가 (덮어쓰기 방지) - dispatch(addToMockCart(productData, optionInfo, quantity)); - } else { - console.log('[MockCartActions] initializeMockCart - Failed to create cart item'); - } -}; + if (newCartItem) { + // addToMockCart를 사용하여 기존 장바구니에 상품 추가 (덮어쓰기 방지) + dispatch(addToMockCart(productData, optionInfo, quantity)); + } else { + dlog('[MockCartActions] initializeMockCart - Failed to create cart item'); + } + }; /** * Mock 장바구니에 상품 추가 @@ -44,28 +57,30 @@ export const initializeMockCart = (productData, optionInfo = {}, quantity = 1) = * @param {Object} optionInfo - 옵션 정보 * @param {number} quantity - 수량 */ -export const addToMockCart = (productData, optionInfo = {}, quantity = 1) => (dispatch, getState) => { - if (!BUYNOW_CONFIG.isMockMode()) { - return; - } +export const addToMockCart = + (productData, optionInfo = {}, quantity = 1) => + (dispatch, getState) => { + if (!BUYNOW_CONFIG.isMockMode()) { + return; + } - console.log('[MockCartActions] addToMockCart - productData:', productData); + dlog('[MockCartActions] addToMockCart - productData:', productData); - // Mock 장바구니 데이터 생성 - const newCartItem = addMockCartItem(productData, optionInfo, quantity); + // Mock 장바구니 데이터 생성 + const newCartItem = addMockCartItem(productData, optionInfo, quantity); - dispatch({ - type: MOCK_CART_TYPES.ADD_TO_MOCK_CART, - payload: { - item: newCartItem, - lastAction: { - type: 'add', - data: newCartItem, - timestamp: Date.now(), + dispatch({ + type: MOCK_CART_TYPES.ADD_TO_MOCK_CART, + payload: { + item: newCartItem, + lastAction: { + type: 'add', + data: newCartItem, + timestamp: Date.now(), + }, }, - }, - }); -}; + }); + }; /** * Mock 장바구니에서 상품 제거 @@ -76,7 +91,7 @@ export const removeFromMockCart = (prodSno) => (dispatch, getState) => { return; } - console.log('[MockCartActions] removeFromMockCart - prodSno:', prodSno); + dlog('[MockCartActions] removeFromMockCart - prodSno:', prodSno); dispatch({ type: MOCK_CART_TYPES.REMOVE_FROM_MOCK_CART, @@ -101,7 +116,7 @@ export const updateMockCartItem = (prodSno, quantity) => (dispatch, getState) => return; } - console.log('[MockCartActions] updateMockCartItem - prodSno:', prodSno, 'quantity:', quantity); + dlog('[MockCartActions] updateMockCartItem - prodSno:', prodSno, 'quantity:', quantity); const updatedItem = updateMockCartItemQuantity(prodSno, quantity); @@ -136,7 +151,7 @@ export const setMockCartItemQuantity = (prodSno, quantity) => (dispatch, getStat return; } - console.log('[MockCartActions] setMockCartItemQuantity - prodSno:', prodSno, 'quantity:', quantity); + dlog('[MockCartActions] setMockCartItemQuantity - prodSno:', prodSno, 'quantity:', quantity); const updatedItem = updateMockCartItemQuantity(prodSno, quantity); @@ -163,7 +178,7 @@ export const clearMockCart = () => (dispatch, getState) => { return; } - console.log('[MockCartActions] clearMockCart'); + dlog('[MockCartActions] clearMockCart'); dispatch({ type: MOCK_CART_TYPES.CLEAR_MOCK_CART, @@ -184,7 +199,7 @@ export const resetMockCart = () => (dispatch, getState) => { return; } - console.log('[MockCartActions] resetMockCart - Clearing cart to empty'); + dlog('[MockCartActions] resetMockCart - Clearing cart to empty'); // 빈 장바구니로 재설정 (기본 Mock 상품 없음) dispatch({ @@ -208,7 +223,7 @@ export const updateSelectedItems = (selectedItems) => (dispatch, getState) => { return; } - console.log('[MockCartActions] updateSelectedItems - selectedItems:', selectedItems); + dlog('[MockCartActions] updateSelectedItems - selectedItems:', selectedItems); dispatch({ type: MOCK_CART_TYPES.UPDATE_SELECTED_ITEMS, @@ -220,4 +235,4 @@ export const updateSelectedItems = (selectedItems) => (dispatch, getState) => { }, }, }); -}; \ No newline at end of file +}; diff --git a/com.twin.app.shoptime/src/actions/myPageActions.js b/com.twin.app.shoptime/src/actions/myPageActions.js index dcfe3ffb..d56abe84 100644 --- a/com.twin.app.shoptime/src/actions/myPageActions.js +++ b/com.twin.app.shoptime/src/actions/myPageActions.js @@ -1,17 +1,22 @@ -import { URLS } from "../api/apiConfig"; -import { TAxios } from "../api/TAxios"; -import { types } from "./actionTypes"; +import { URLS } from '../api/apiConfig'; +import { TAxios } from '../api/TAxios'; +import { types } from './actionTypes'; import { changeAppStatus, deleteReservation, disableNotification, enableNotification, -} from "./commonActions"; +} from './commonActions'; +import { createDebugHelpers } from '../utils/debug'; + +// 디버그 헬퍼 설정 +const DEBUG_MODE = false; +const { dlog, dwarn, derror } = createDebugHelpers(DEBUG_MODE); // 추천 Keyword 목록 조회 IF-LGSP-055 export const getMyRecommandedKeyword = () => (dispatch, getState) => { const onSuccess = (response) => { - console.log("getMyRecommandedKeyword onSuccess ", response.data); + dlog('getMyRecommandedKeyword onSuccess ', response.data); dispatch({ type: types.GET_MY_RECOMMANDED_KEYWORD, @@ -20,25 +25,16 @@ export const getMyRecommandedKeyword = () => (dispatch, getState) => { }; const onFail = (error) => { - console.error("getMyRecommandedKeyword onFail ", error); + derror('getMyRecommandedKeyword onFail ', error); }; - TAxios( - dispatch, - getState, - "get", - URLS.GET_MY_RECOMMANDED_KEYWORD, - {}, - {}, - onSuccess, - onFail - ); + TAxios(dispatch, getState, 'get', URLS.GET_MY_RECOMMANDED_KEYWORD, {}, {}, onSuccess, onFail); }; // FAQ 조회 (IF-LGSP-048) export const getMyFaqInfo = () => (dispatch, getState) => { const onSuccess = (response) => { - console.log("getMyFaqInfo onSuccess ", response.data); + dlog('getMyFaqInfo onSuccess ', response.data); dispatch({ type: types.GET_MY_FAQ_INFO, payload: response.data.data, @@ -46,25 +42,16 @@ export const getMyFaqInfo = () => (dispatch, getState) => { }; const onFail = (error) => { - console.error("getMyFaqInfo onFail ", error); + derror('getMyFaqInfo onFail ', error); }; - TAxios( - dispatch, - getState, - "get", - URLS.GET_MY_FAQ_INFO, - {}, - {}, - onSuccess, - onFail - ); + TAxios(dispatch, getState, 'get', URLS.GET_MY_FAQ_INFO, {}, {}, onSuccess, onFail); }; // Notice 조회 (IF-LGSP-049) export const getNotice = () => (dispatch, getState) => { const onSuccess = (response) => { - console.log("getMyNotice onSuccess ", response.data); + dlog('getMyNotice onSuccess ', response.data); dispatch({ type: types.GET_NOTICE, payload: response.data.data, @@ -72,16 +59,16 @@ export const getNotice = () => (dispatch, getState) => { }; const onFail = (error) => { - console.error("getMyNotice onFail ", error); + derror('getMyNotice onFail ', error); }; - TAxios(dispatch, getState, "get", URLS.GET_NOTICE, {}, {}, onSuccess, onFail); + TAxios(dispatch, getState, 'get', URLS.GET_NOTICE, {}, {}, onSuccess, onFail); }; // MyPage 파트너사 Contact 정보 조회 (IF-LGSP-033) export const getMyCustomers = () => (dispatch, getState) => { const onSuccess = (response) => { - console.log("getMyCustomers onSuccess ", response.data); + dlog('getMyCustomers onSuccess ', response.data); dispatch({ type: types.GET_MY_CUSTOMERS, payload: response.data.data, @@ -89,27 +76,18 @@ export const getMyCustomers = () => (dispatch, getState) => { }; const onFail = (error) => { - console.error("getMyCustomers onFail ", error); + derror('getMyCustomers onFail ', error); }; - TAxios( - dispatch, - getState, - "get", - URLS.GET_MY_CUSTOMERS, - {}, - {}, - onSuccess, - onFail - ); + TAxios(dispatch, getState, 'get', URLS.GET_MY_CUSTOMERS, {}, {}, onSuccess, onFail); }; // MyPage 찜 목록 IF-LGSP-052 export const getMyFavorite = () => (dispatch, getState) => { - dispatch(changeAppStatus({ showLoadingPanel: { show: true, type: "wait" } })); + dispatch(changeAppStatus({ showLoadingPanel: { show: true, type: 'wait' } })); const onSuccess = (response) => { - console.log("getmyFavorite onSuccess ", response.data); + dlog('getmyFavorite onSuccess ', response.data); dispatch({ type: types.GET_MY_FAVORITE, @@ -120,20 +98,11 @@ export const getMyFavorite = () => (dispatch, getState) => { }; const onFail = (error) => { - console.error("getMyFavorite onFail ", error); + derror('getMyFavorite onFail ', error); dispatch(changeAppStatus({ showLoadingPanel: { show: false } })); }; - TAxios( - dispatch, - getState, - "get", - URLS.GET_MY_FAVORITE, - {}, - {}, - onSuccess, - onFail - ); + TAxios(dispatch, getState, 'get', URLS.GET_MY_FAVORITE, {}, {}, onSuccess, onFail); }; // MyPage 찜 삭제 IF-LGSP-053 @@ -141,7 +110,7 @@ export const deleteMyFavorite = (params) => (dispatch, getState) => { const { productList, showList } = params; const onSuccess = (response) => { - console.log("deleteMyFavorite onSuccess ", response.data); + dlog('deleteMyFavorite onSuccess ', response.data); const { favoriteData } = getState().myPage; const currentFavorites = favoriteData.favorites; @@ -152,8 +121,7 @@ export const deleteMyFavorite = (params) => (dispatch, getState) => { const updatedFavorites = currentFavorites.filter( (item) => - !productIdsToDelete.includes(item.prdtId) && - !showIdsToDelete.includes(item.showId) + !productIdsToDelete.includes(item.prdtId) && !showIdsToDelete.includes(item.showId) ); dispatch({ @@ -164,13 +132,13 @@ export const deleteMyFavorite = (params) => (dispatch, getState) => { }; const onFail = (error) => { - console.error("deleteMyFavorite onFail ", error); + derror('deleteMyFavorite onFail ', error); }; TAxios( dispatch, getState, - "post", + 'post', URLS.DELETE_MY_FAVORITE, {}, { productList, showList }, @@ -180,121 +148,114 @@ export const deleteMyFavorite = (params) => (dispatch, getState) => { }; // MyPage 약관 철회 (IF-LGSP-032) -export const setMyTermsWithdraw = - (params, callback) => (dispatch, getState) => { - let localMacAddress; - const { mandatoryIncludeYn, termsList } = params; +export const setMyTermsWithdraw = (params, callback) => (dispatch, getState) => { + let localMacAddress; + const { mandatoryIncludeYn, termsList } = params; - // 약관철회 파라미터 추가 로그 요청 - const httpHeader = getState().common.httpHeader; - const macAddress = getState().common.macAddress; - const userNumber = getState().common.appStatus.loginUserData?.userNumber; + // 약관철회 파라미터 추가 로그 요청 + const httpHeader = getState().common.httpHeader; + const macAddress = getState().common.macAddress; + const userNumber = getState().common.appStatus.loginUserData?.userNumber; - const macAddr = macAddress?.wired || macAddress?.wifi || macAddress?.p2p; + const macAddr = macAddress?.wired || macAddress?.wifi || macAddress?.p2p; - if (typeof window === "object" && !window.PalmSystem) { - localMacAddress = "00:1A:2B:3C:4D:5E"; - } - const logCreateTime = new Date().toISOString(); - const xDeviceProduct = httpHeader["X-Device-Product"] || httpHeader.prod_cd; + if (typeof window === 'object' && !window.PalmSystem) { + localMacAddress = '00:1A:2B:3C:4D:5E'; + } + const logCreateTime = new Date().toISOString(); + const xDeviceProduct = httpHeader['X-Device-Product'] || httpHeader.prod_cd; - const onSuccess = (response) => { - console.log("setMyTermsWithdraw onSuccess ", response.data); + const onSuccess = (response) => { + dlog('setMyTermsWithdraw onSuccess ', response.data); - dispatch({ - type: types.SET_MY_TERMS_WITHDRAW, - payload: response.data, - }); + dispatch({ + type: types.SET_MY_TERMS_WITHDRAW, + payload: response.data, + }); - if (callback) callback(response.data); - }; - - const onFail = (error) => { - console.error("setMyTermsWithdraw onFail ", error); - }; - - const requestData = { - mandatoryIncludeYn, - termsList, - xDeviceProduct, - macAddr: macAddr ? macAddr : localMacAddress, - userNumber: userNumber || "", - requestTime: logCreateTime, - }; - - TAxios( - dispatch, - getState, - "post", - URLS.SET_MY_TERMS_WITHDRAW, - {}, - requestData, - onSuccess, - onFail - ); + if (callback) callback(response.data); }; + const onFail = (error) => { + derror('setMyTermsWithdraw onFail ', error); + }; + + const requestData = { + mandatoryIncludeYn, + termsList, + xDeviceProduct, + macAddr: macAddr ? macAddr : localMacAddress, + userNumber: userNumber || '', + requestTime: logCreateTime, + }; + + TAxios( + dispatch, + getState, + 'post', + URLS.SET_MY_TERMS_WITHDRAW, + {}, + requestData, + onSuccess, + onFail + ); +}; + // MyPage 약관 동의 (IF-LGSP-031) -export const setMyPageTermsAgree = - (params, callback) => (dispatch, getState) => { - const { termsList, notTermsList } = params; +export const setMyPageTermsAgree = (params, callback) => (dispatch, getState) => { + const { termsList, notTermsList } = params; - dispatch({ type: types.GET_TERMS_AGREE_YN_START }); + dispatch({ type: types.GET_TERMS_AGREE_YN_START }); - const onSuccess = (response) => { - console.log("setMyPageTermsAgree onSuccess ", response.data); + const onSuccess = (response) => { + dlog('setMyPageTermsAgree onSuccess ', response.data); - // 약관 ID를 약관 코드로 변환하기 위해 state에서 termsIdMap 조회 - const termsIdMap = getState().home.termsIdMap || {}; - const idToCodeMap = Object.entries(termsIdMap).reduce( - (acc, [code, id]) => { - acc[id] = code; - return acc; - }, - {} - ); + // 약관 ID를 약관 코드로 변환하기 위해 state에서 termsIdMap 조회 + const termsIdMap = getState().home.termsIdMap || {}; + const idToCodeMap = Object.entries(termsIdMap).reduce((acc, [code, id]) => { + acc[id] = code; + return acc; + }, {}); - // 동의한 약관 ID 목록을 약관 코드로 변환 - const agreedTermCodes = termsList - .map((id) => idToCodeMap[id]) - .filter(Boolean); + // 동의한 약관 ID 목록을 약관 코드로 변환 + const agreedTermCodes = termsList.map((id) => idToCodeMap[id]).filter(Boolean); - dispatch({ - type: types.SET_MYPAGE_TERMS_AGREE_SUCCESS, - payload: { - ...response.data, - agreedTermCodes: agreedTermCodes, // 변환된 약관 코드 리스트를 payload에 추가 - }, - retCode: response.data.retCode, - }); + dispatch({ + type: types.SET_MYPAGE_TERMS_AGREE_SUCCESS, + payload: { + ...response.data, + agreedTermCodes: agreedTermCodes, // 변환된 약관 코드 리스트를 payload에 추가 + }, + retCode: response.data.retCode, + }); - if (callback) callback(response.data); - }; - - const onFail = (error) => { - console.error("setMyPageTermsAgree onFail ", error); - dispatch({ - type: types.SET_MYPAGE_TERMS_AGREE_FAIL, - payload: error, - }); - }; - - TAxios( - dispatch, - getState, - "post", - URLS.SET_MYPAGE_TERMS_AGREE, - {}, - { termsList, notTermsList }, - onSuccess, - onFail - ); + if (callback) callback(response.data); }; + const onFail = (error) => { + derror('setMyPageTermsAgree onFail ', error); + dispatch({ + type: types.SET_MYPAGE_TERMS_AGREE_FAIL, + payload: error, + }); + }; + + TAxios( + dispatch, + getState, + 'post', + URLS.SET_MYPAGE_TERMS_AGREE, + {}, + { termsList, notTermsList }, + onSuccess, + onFail + ); +}; + // MyPage Upcoming Alert 정보 변경 조회 (IF-LGSP-050) export const getMyUpcomingChangeInfo = () => (dispatch, getState) => { const onSuccess = (response) => { - console.log("getMyUpcomingChangeInfo onSuccess ", response.data); + dlog('getMyUpcomingChangeInfo onSuccess ', response.data); dispatch({ type: types.GET_MY_UPCOMING_CHANGE_INFO, @@ -303,25 +264,16 @@ export const getMyUpcomingChangeInfo = () => (dispatch, getState) => { }; const onFail = (error) => { - console.error("getMyUpcomingChangeInfo onFail ", error); + derror('getMyUpcomingChangeInfo onFail ', error); }; - TAxios( - dispatch, - getState, - "get", - URLS.GET_MY_UPCOMING_CHANGE_INFO, - {}, - {}, - onSuccess, - onFail - ); + TAxios(dispatch, getState, 'get', URLS.GET_MY_UPCOMING_CHANGE_INFO, {}, {}, onSuccess, onFail); }; // MyPage Upcoming Alert Show 목록 (IF-LGSP-025) export const getMyUpcomingAlertShow = () => (dispatch, getState) => { const onSuccess = (response) => { - console.log("getMyUpcomingAlertShow onSuccess ", response.data); + dlog('getMyUpcomingAlertShow onSuccess ', response.data); dispatch({ type: types.GET_MY_UPCOMING_ALERT_SHOW, @@ -330,19 +282,10 @@ export const getMyUpcomingAlertShow = () => (dispatch, getState) => { }; const onFail = (error) => { - console.error("getMyUpcomingAlertShow onFail ", error); + derror('getMyUpcomingAlertShow onFail ', error); }; - TAxios( - dispatch, - getState, - "get", - URLS.GET_MY_UPCOMING_ALERT_SHOW, - {}, - {}, - onSuccess, - onFail - ); + TAxios(dispatch, getState, 'get', URLS.GET_MY_UPCOMING_ALERT_SHOW, {}, {}, onSuccess, onFail); }; // MyPage UpComing Alert Show 삭제 (IF-LGSP-042) @@ -350,7 +293,7 @@ export const deleteMyUpcomingAlertShow = (params) => (dispatch, getState) => { const { showList } = params; const onSuccess = (response) => { - console.log("deleteMyUpcomingAlertShow onSuccess ", response.data); + dlog('deleteMyUpcomingAlertShow onSuccess ', response.data); dispatch({ type: types.DELETE_MY_UPCOMING_ALERT_SHOW, @@ -363,13 +306,13 @@ export const deleteMyUpcomingAlertShow = (params) => (dispatch, getState) => { }; const onFail = (error) => { - console.error("deleteMyUpcomingAlertShow onFail ", error); + derror('deleteMyUpcomingAlertShow onFail ', error); }; TAxios( dispatch, getState, - "post", + 'post', URLS.DELETE_MY_UPCOMING_ALERT_SHOW, {}, { showList }, @@ -381,7 +324,7 @@ export const deleteMyUpcomingAlertShow = (params) => (dispatch, getState) => { // MyPage Upcoming Alert Show - Key 목록 (IF-LGSP-076) export const getMyUpcomingAlertShowKeys = () => (dispatch, getState) => { const onSuccess = (response) => { - console.log("getMyUpcomingAlertShowKeys onSuccess ", response.data); + dlog('getMyUpcomingAlertShowKeys onSuccess ', response.data); dispatch({ type: types.GET_MY_UPCOMING_ALERT_SHOW_KEYS, @@ -390,13 +333,13 @@ export const getMyUpcomingAlertShowKeys = () => (dispatch, getState) => { }; const onFail = (error) => { - console.error("getMyUpcomingAlertShowKeys onFail ", error); + derror('getMyUpcomingAlertShowKeys onFail ', error); }; TAxios( dispatch, getState, - "get", + 'get', URLS.GET_MY_UPCOMING_ALERT_SHOW_KEYS, {}, {}, @@ -410,9 +353,9 @@ export const setMyUpcomingUseAlert = (params) => (dispatch, getState) => { const { upcomingAlamUseFlag } = params; const onSuccess = (response) => { - console.log("setMyUpcomingUseAlert onSuccess ", response.data); + dlog('setMyUpcomingUseAlert onSuccess ', response.data); - if (upcomingAlamUseFlag === "Y") { + if (upcomingAlamUseFlag === 'Y') { dispatch(enableNotification()); } else { dispatch(disableNotification()); @@ -425,9 +368,9 @@ export const setMyUpcomingUseAlert = (params) => (dispatch, getState) => { }; const onFail = (error) => { - console.error("setMyUpcomingUseAlert onFail ", error); + derror('setMyUpcomingUseAlert onFail ', error); - if (upcomingAlamUseFlag === "Y") { + if (upcomingAlamUseFlag === 'Y') { dispatch(disableNotification()); } else { dispatch(enableNotification()); @@ -437,7 +380,7 @@ export const setMyUpcomingUseAlert = (params) => (dispatch, getState) => { TAxios( dispatch, getState, - "post", + 'post', URLS.SET_MY_UPCOMING_USE_ALERT, {}, { upcomingAlamUseFlag }, @@ -449,7 +392,7 @@ export const setMyUpcomingUseAlert = (params) => (dispatch, getState) => { // UpComing Alert 방송 변경 정보 조회 (IF-LGSP-068) export const getUpcomingAlertShowChangeInfo = () => (dispatch, getState) => { const onSuccess = (response) => { - console.log("getUpcomingAlertShowChangeInfo onSuccess ", response.data); + dlog('getUpcomingAlertShowChangeInfo onSuccess ', response.data); dispatch({ type: types.GET_UPCOMING_ALERT_SHOW_CHANGE_INFO, @@ -458,13 +401,13 @@ export const getUpcomingAlertShowChangeInfo = () => (dispatch, getState) => { }; const onFail = (error) => { - console.error("getUpcomingAlertShowChangeInfo onFail ", error); + derror('getUpcomingAlertShowChangeInfo onFail ', error); }; TAxios( dispatch, getState, - "get", + 'get', URLS.GET_UPCOMING_ALERT_SHOW_CHANGE_INFO, {}, {}, @@ -478,7 +421,7 @@ export const getMyRecentlyViewedInfo = (params) => (dispatch, getState) => { const { showList, productList } = params; const onSuccess = (response) => { - console.log("getMyRecentlyViewedInfo onSuccess ", response.data); + dlog('getMyRecentlyViewedInfo onSuccess ', response.data); dispatch({ type: types.GET_MY_RECENTLY_VIEWED_INFO, @@ -488,13 +431,13 @@ export const getMyRecentlyViewedInfo = (params) => (dispatch, getState) => { }; const onFail = (error) => { - console.error("getMyRecentlyViewedInfo onFail ", error); + derror('getMyRecentlyViewedInfo onFail ', error); }; TAxios( dispatch, getState, - "post", + 'post', URLS.GET_MY_RECENTLY_VIEWED_INFO, {}, { showList, productList }, diff --git a/com.twin.app.shoptime/src/actions/onSaleActions.js b/com.twin.app.shoptime/src/actions/onSaleActions.js index 7f0a2caa..99c44d90 100644 --- a/com.twin.app.shoptime/src/actions/onSaleActions.js +++ b/com.twin.app.shoptime/src/actions/onSaleActions.js @@ -1,15 +1,19 @@ -import { URLS } from "../api/apiConfig"; -import { TAxios } from "../api/TAxios"; -import { types } from "./actionTypes"; -import { changeAppStatus } from "./commonActions"; +import { URLS } from '../api/apiConfig'; +import { TAxios } from '../api/TAxios'; +import { types } from './actionTypes'; +import { changeAppStatus } from './commonActions'; +import { createDebugHelpers } from '../utils/debug'; + +// 디버그 헬퍼 설정 +const DEBUG_MODE = false; +const { dlog, dwarn, derror } = createDebugHelpers(DEBUG_MODE); // On Sale 조회 IF-LGSP-086 (Home) export const getHomeOnSaleInfo = (props) => (dispatch, getState) => { - const { categoryIncFlag, homeSaleInfosIncFlag, lgCatCd, saleInfosIncFlag } = - props; + const { categoryIncFlag, homeSaleInfosIncFlag, lgCatCd, saleInfosIncFlag } = props; const onSuccess = (response) => { - console.log("getHomeOnSaleInfo onSuccess ", response.data); + dlog('getHomeOnSaleInfo onSuccess ', response.data); dispatch({ type: types.GET_HOME_ON_SALE_INFO, @@ -21,14 +25,14 @@ export const getHomeOnSaleInfo = (props) => (dispatch, getState) => { }; const onFail = (error) => { - console.error("getHomeOnSaleInfo onFail", error); + derror('getHomeOnSaleInfo onFail', error); dispatch(changeAppStatus({ showLoadingPanel: { show: false } })); }; TAxios( dispatch, getState, - "get", + 'get', URLS.GET_ON_SALE_INFO, { categoryIncFlag, homeSaleInfosIncFlag, lgCatCd, saleInfosIncFlag }, {}, @@ -41,10 +45,10 @@ export const getHomeOnSaleInfo = (props) => (dispatch, getState) => { export const getOnSaleInfo = (props) => (dispatch, getState) => { const { categoryIncFlag, lgCatCd, saleInfosIncFlag } = props; - dispatch(changeAppStatus({ showLoadingPanel: { show: true, type: "wait" } })); + dispatch(changeAppStatus({ showLoadingPanel: { show: true, type: 'wait' } })); const onSuccess = (response) => { - console.log("getOnSaleInfo onSuccess ", response.data); + dlog('getOnSaleInfo onSuccess ', response.data); dispatch(changeAppStatus({ showLoadingPanel: { show: false } })); dispatch({ type: types.GET_ON_SALE_INFO, @@ -55,14 +59,14 @@ export const getOnSaleInfo = (props) => (dispatch, getState) => { }; const onFail = (error) => { - console.error("getOnSaleInfo onFail", error); + derror('getOnSaleInfo onFail', error); dispatch(changeAppStatus({ showLoadingPanel: { show: false } })); }; TAxios( dispatch, getState, - "get", + 'get', URLS.GET_ON_SALE_INFO, { categoryIncFlag, lgCatCd, saleInfosIncFlag }, {}, diff --git a/com.twin.app.shoptime/src/actions/orderActions.js b/com.twin.app.shoptime/src/actions/orderActions.js index 0476f1e1..6439ef5c 100644 --- a/com.twin.app.shoptime/src/actions/orderActions.js +++ b/com.twin.app.shoptime/src/actions/orderActions.js @@ -1,10 +1,15 @@ -import axios from "axios"; +import axios from 'axios'; -import { URLS } from "../api/apiConfig"; -import { TAxios } from "../api/TAxios"; -import { GET_MY_INFO_ORDER_SEARCH_LIMIT } from "../utils/Config"; -import { types } from "./actionTypes"; -import { changeAppStatus, getTermsAgreeYn } from "./commonActions"; +import { URLS } from '../api/apiConfig'; +import { TAxios } from '../api/TAxios'; +import { GET_MY_INFO_ORDER_SEARCH_LIMIT } from '../utils/Config'; +import { types } from './actionTypes'; +import { changeAppStatus, getTermsAgreeYn } from './commonActions'; +import { createDebugHelpers } from '../utils/debug'; + +// 디버그 헬퍼 설정 +const DEBUG_MODE = false; +const { dlog, dwarn, derror } = createDebugHelpers(DEBUG_MODE); // 회원 주문 정보 조회 (IF-LGSP-340) let getMyinfoOrderSearchKey = null; @@ -30,14 +35,12 @@ export const getMyinfoOrderSearch = } if (loading) { - dispatch( - changeAppStatus({ showLoadingPanel: { show: true, type: "wait" } }) - ); + dispatch(changeAppStatus({ showLoadingPanel: { show: true, type: 'wait' } })); } let currentKey = key; const onSuccess = (response) => { - console.log("getMyinfoOrderSearch onSuccess ", response.data); + dlog('getMyinfoOrderSearch onSuccess ', response.data); if (orderInfoDataIdx === 1) { getMyinfoOrderSearchKey = new Date(); @@ -69,7 +72,7 @@ export const getMyinfoOrderSearch = }; const onFail = (error) => { - console.error("getMyinfoOrderSearch onFail ", error); + derror('getMyinfoOrderSearch onFail ', error); if (loading) { dispatch(changeAppStatus({ showLoadingPanel: { show: false } })); } @@ -81,7 +84,7 @@ export const getMyinfoOrderSearch = TAxios( dispatch, getState, - "get", + 'get', URLS.GET_MY_INFO_ORDER_SEARCH, { mbrNo, @@ -101,7 +104,7 @@ export const continueGetMyinfoOrderSearch = (dispatch, getState) => { const state = getState(); const orderSearchParams = state.order.orderSearchParams; - const isCancelOrder = orderSearchParams.cancelOrderYn === "Y"; + const isCancelOrder = orderSearchParams.cancelOrderYn === 'Y'; const orderInfoData = isCancelOrder ? state.order.cancelOrderInfoData : state.order.orderInfoData; @@ -133,74 +136,72 @@ const clearMyinfoOrderSearch = () => ({ }); // 회원 주문 상세 정보 조회 (IF-LGSP-341) -export const getMyinfoOrderDetailSearch = - (params, callback) => (dispatch, getState) => { - const { mbrNo, ordNo, prdtId } = params; +export const getMyinfoOrderDetailSearch = (params, callback) => (dispatch, getState) => { + const { mbrNo, ordNo, prdtId } = params; - const onSuccess = (response) => { - console.log("getMyinfoOrderDetailSearch onSuccess ", response.data); + const onSuccess = (response) => { + dlog('getMyinfoOrderDetailSearch onSuccess ', response.data); - dispatch({ - type: types.GET_MY_INFO_ORDER_DETAIL_SEARCH, - payload: response.data.data, - }); + dispatch({ + type: types.GET_MY_INFO_ORDER_DETAIL_SEARCH, + payload: response.data.data, + }); - if (callback) callback(response.data); - }; - - const onFail = (error) => { - console.error("getMyinfoOrderDetailSearch onFail ", error); - }; - - TAxios( - dispatch, - getState, - "get", - URLS.GET_MY_INFO_ORDER_DETAIL_SEARCH, - { mbrNo, ordNo, prdtId }, - {}, - onSuccess, - onFail - ); + if (callback) callback(response.data); }; -export const getMyinfoOrderShippingSearch = - (params, callback) => (dispatch, getState) => { - const { mbrNo, ordNo, patnrId, prdtId, prodSno } = params; - - const onSuccess = (response) => { - console.log("getMyinfoOrderShippingSearch onSuccess ", response.data); - - dispatch({ - type: types.GET_MY_INFO_ORDER_SHIPPING_SEARCH, - payload: response.data.data, - }); - - if (callback) callback(response.data); - }; - - const onFail = (error) => { - console.error("getMyinfoOrderShippingSearch onFail ", error); - }; - - TAxios( - dispatch, - getState, - "get", - URLS.GET_MY_INFO_ORDER_SHIPPING_SEARCH, - { mbrNo, ordNo, patnrId, prdtId, prodSno }, - {}, - onSuccess, - onFail - ); + const onFail = (error) => { + derror('getMyinfoOrderDetailSearch onFail ', error); }; + TAxios( + dispatch, + getState, + 'get', + URLS.GET_MY_INFO_ORDER_DETAIL_SEARCH, + { mbrNo, ordNo, prdtId }, + {}, + onSuccess, + onFail + ); +}; + +export const getMyinfoOrderShippingSearch = (params, callback) => (dispatch, getState) => { + const { mbrNo, ordNo, patnrId, prdtId, prodSno } = params; + + const onSuccess = (response) => { + dlog('getMyinfoOrderShippingSearch onSuccess ', response.data); + + dispatch({ + type: types.GET_MY_INFO_ORDER_SHIPPING_SEARCH, + payload: response.data.data, + }); + + if (callback) callback(response.data); + }; + + const onFail = (error) => { + derror('getMyinfoOrderShippingSearch onFail ', error); + }; + + TAxios( + dispatch, + getState, + 'get', + URLS.GET_MY_INFO_ORDER_SHIPPING_SEARCH, + { mbrNo, ordNo, patnrId, prdtId, prodSno }, + {}, + onSuccess, + onFail + ); +}; + // 구매 약관 동의 (IF-LGSP-360) export const setPurchaseTermsAgree = (params) => (dispatch, getState) => { const { mbrNo, termsList } = params; const onSuccess = (response) => { - console.log("setPurchaseTermsAgree onSuccess ", response.data); + dlog('setPurchaseTermsAgree onSuccess ', response.data); dispatch({ type: types.SET_PURCHASE_TERMS_AGREE, @@ -212,13 +213,13 @@ export const setPurchaseTermsAgree = (params) => (dispatch, getState) => { }; const onFail = (error) => { - console.error("setPurchaseTermsAgree onFail ", error); + derror('setPurchaseTermsAgree onFail ', error); }; TAxios( dispatch, getState, - "post", + 'post', URLS.SET_PURCHASE_TERMS_AGREE, {}, { mbrNo, termsList }, @@ -232,7 +233,7 @@ export const setPurchasetermsWithdraw = (params) => (dispatch, getState) => { const { mbrNo, termsList } = params; const onSuccess = (response) => { - console.log("setPurchasetermsWithdraw onSuccess ", response.data); + dlog('setPurchasetermsWithdraw onSuccess ', response.data); dispatch({ type: types.SET_PURCHASE_TERMS_WITHDRAW, @@ -244,13 +245,13 @@ export const setPurchasetermsWithdraw = (params) => (dispatch, getState) => { }; const onFail = (error) => { - console.error("setPurchasetermsWithdraw onFail ", error); + derror('setPurchasetermsWithdraw onFail ', error); }; TAxios( dispatch, getState, - "post", + 'post', URLS.SET_PURCHASE_TERMS_WITHDRAW, {}, { mbrNo, termsList }, diff --git a/com.twin.app.shoptime/src/actions/panelActions.js b/com.twin.app.shoptime/src/actions/panelActions.js index 3cc765ad..03ba8237 100644 --- a/com.twin.app.shoptime/src/actions/panelActions.js +++ b/com.twin.app.shoptime/src/actions/panelActions.js @@ -3,6 +3,11 @@ import Spotlight from '@enact/spotlight'; import { getContainerId } from '@enact/spotlight/src/container'; import { panel_names } from '../utils/Config'; import { updateHomeInfo } from './homeActions'; +import { createDebugHelpers } from '../utils/debug'; + +// 디버그 헬퍼 설정 +const DEBUG_MODE = false; +const { dlog, dwarn, derror } = createDebugHelpers(DEBUG_MODE); // 시작 메뉴 추적을 위한 상수 export const SOURCE_MENUS = { @@ -95,7 +100,7 @@ export const navigateToDetail = ({ if (sourceMenu) panelInfo.sourceMenu = sourceMenu; // 로깅 - console.log(`[navigateToDetail] ${sourceMenu || 'unknown'} → DetailPanel`, { + dlog(`[navigateToDetail] ${sourceMenu || 'unknown'} → DetailPanel`, { patnrId, prdtId, curationId, @@ -128,11 +133,9 @@ export const navigateToDetail = ({ }, }) ); - // console.log('[TRACE-GRADIENT] 🟢 navigateToDetail set showGradientBackground: true - source:', sourceMenu); + // dlog('[TRACE-GRADIENT] 🟢 navigateToDetail set showGradientBackground: true - source:', sourceMenu); } else { - console.log( - '[TRACE-GRADIENT] 🔵 navigateToDetail skipped gradient - launchedFromPlayer: true' - ); + dlog('[TRACE-GRADIENT] 🔵 navigateToDetail skipped gradient - launchedFromPlayer: true'); } // HomePanel Redux 상태에 포커스 스냅샷 저장 (Detail→Home 복귀 시 사용) @@ -542,7 +545,7 @@ export const focusPanel = (panelName, focusTarget) => { const state = getState(); const panels = state.panels.panels; - console.log('[focusPanel] 포커스 이동 시도', { + dlog('[focusPanel] 포커스 이동 시도', { panelName, focusTarget, currentPanels: panels.map((p) => p.name), @@ -555,7 +558,7 @@ export const focusPanel = (panelName, focusTarget) => { const topPanel = panels[panels.length - 1]; if (!targetPanel) { - console.warn(`[focusPanel] ❌ Panel을 찾을 수 없음: ${panelName}`); + dwarn(`[focusPanel] ❌ Panel을 찾을 수 없음: ${panelName}`); return; } @@ -568,7 +571,7 @@ export const focusPanel = (panelName, focusTarget) => { if (hasBlockingModalAbove) { const blockingModal = panelsAboveTarget.find((panel) => panel?.panelInfo?.modal === true); - console.warn( + dwarn( `[focusPanel] ⚠️ 상위에 Modal이 있음. ` + `${panelName}(${targetPanelIndex}층)에 포커스할 수 없음. ` + `상단 Modal: ${blockingModal?.name}(${panelsAboveTarget.indexOf(blockingModal) + targetPanelIndex + 1}층)` @@ -576,7 +579,7 @@ export const focusPanel = (panelName, focusTarget) => { return; } - console.log( + dlog( `[focusPanel] ✅ Panel 위치 확인: ${panelName}(${targetPanelIndex}층), ` + `전체 Panel: ${panels.length}층` ); @@ -586,18 +589,18 @@ export const focusPanel = (panelName, focusTarget) => { const element = document.getElementById(focusTarget); if (!element) { - console.warn(`[focusPanel] ❌ 요소를 찾을 수 없음: ${focusTarget}`); + dwarn(`[focusPanel] ❌ 요소를 찾을 수 없음: ${focusTarget}`); return; } if (element.offsetParent === null) { - console.warn(`[focusPanel] ⚠️ 요소가 숨겨져있음: ${focusTarget}`); + dwarn(`[focusPanel] ⚠️ 요소가 숨겨져있음: ${focusTarget}`); return; } // ✅ 포커스 이동 Spotlight.focus(focusTarget); - console.log(`[focusPanel] ✅ 포커스 이동 성공: ${panelName} → ${focusTarget}`); + dlog(`[focusPanel] ✅ 포커스 이동 성공: ${panelName} → ${focusTarget}`); // Reducer에 반영 dispatch({ diff --git a/com.twin.app.shoptime/src/actions/panelNavigationActions.js b/com.twin.app.shoptime/src/actions/panelNavigationActions.js index a1ea29fe..83622935 100644 --- a/com.twin.app.shoptime/src/actions/panelNavigationActions.js +++ b/com.twin.app.shoptime/src/actions/panelNavigationActions.js @@ -1,266 +1,283 @@ -/** - * src/actions/panelNavigationActions.js - * Panel navigation 순차 처리를 위한 액션 크리에이터 - * - * Chrome 68 호환성을 위한 callback-free 순차 네비게이션 - */ - -import { pushPanel, updatePanel } from './panelActions'; -import { panel_names } from '../utils/Config'; - -/** - * 상품 클릭 시 순차 네비게이션 (Search → Detail) - * @param {string} patnrId - 파트너 ID - * @param {string} prdtId - 상품 ID - * @param {string} searchQuery - 검색어 - * @param {string} currentSpot - 현재 spotlight ID - * @param {Object} additionalInfo - 추가 패널 정보 - * @returns {Function} Redux thunk function - */ -export const navigateToDetailPanel = ( - patnrId, - prdtId, - searchQuery, - currentSpot, - additionalInfo = {} -) => (dispatch, getState) => { - // 현재 상태에서 lastPanelAction 카운트 저장 - const currentActionCount = getState().panels.lastPanelAction || 0; - - console.log('[PanelNavigation] Starting navigation to detail:', { - patnrId, - prdtId, - searchQuery, - currentSpot, - currentActionCount - }); - - // 1. 먼저 현재 패널(예: SearchPanel) 업데이트 - dispatch(updatePanel({ - name: panel_names.SEARCH_PANEL, - panelInfo: { - searchVal: searchQuery, - currentSpot, - tab: 0, - ...additionalInfo - } - })); - - // 2. Redux store 구독하여 상태 변화 감지 - // 직접 store 접근 대신 타이머 기반 방식 사용 (Chrome 68 호환) - const storeUnsubscribe = (() => { - let isUnsubscribed = false; - - const checkStateChange = () => { - if (isUnsubscribed) return; - - const newState = getState(); - const newActionCount = newState.panels.lastPanelAction || 0; - - // updatePanel이 완료되면 (action count가 변경되면) - if (newActionCount !== currentActionCount) { - console.log('[PanelNavigation] UpdatePanel completed, pushing DetailPanel'); - - // 구독 해제 - isUnsubscribed = true; - - // 3. DetailPanel push - dispatch(pushPanel({ - name: panel_names.DETAIL_PANEL, - panelInfo: { - patnrId, - prdtId, - fromSearch: true, - searchQuery, - ...additionalInfo - } - })); - } - }; - - // 즉시 한번 확인하고, 그 후 주기적으로 확인 - setTimeout(checkStateChange, 0); - const intervalId = setInterval(checkStateChange, 16); // 60fps - - return () => { - isUnsubscribed = true; - clearInterval(intervalId); - }; - })(); - - // 타임아웃 방어 (최대 1초 대기) - setTimeout(() => { - storeUnsubscribe(); - console.log('[PanelNavigation] Timeout fallback, pushing DetailPanel'); - - dispatch(pushPanel({ - name: panel_names.DETAIL_PANEL, - panelInfo: { - patnrId, - prdtId, - fromSearch: true, - searchQuery, - ...additionalInfo - } - })); - }, 1000); -}; - -/** - * HomePanel에서 상품 클릭 시 순차 네비게이션 - * @param {string} patnrId - 파트너 ID - * @param {string} prdtId - 상품 ID - * @param {Object} additionalInfo - 추가 패널 정보 - * @returns {Function} Redux thunk function - */ -export const navigateToDetailFromHome = ( - patnrId, - prdtId, - additionalInfo = {} -) => (dispatch, getState) => { - const currentActionCount = getState().panels.lastPanelAction || 0; - - console.log('[PanelNavigation] Starting navigation from home:', { - patnrId, - prdtId, - currentActionCount - }); - - dispatch(updatePanel({ - name: panel_names.HOME_PANEL, - panelInfo: { - lastSelectedProduct: { patnrId, prdtId }, - ...additionalInfo - } - })); - - const storeUnsubscribe = (() => { - let isUnsubscribed = false; - - const checkStateChange = () => { - if (isUnsubscribed) return; - - const newState = getState(); - const newActionCount = newState.panels.lastPanelAction || 0; - - if (newActionCount !== currentActionCount) { - console.log('[PanelNavigation] HomePanel update completed, pushing DetailPanel'); - isUnsubscribed = true; - - dispatch(pushPanel({ - name: panel_names.DETAIL_PANEL, - panelInfo: { - patnrId, - prdtId, - fromHome: true, - ...additionalInfo - } - })); - } - }; - - setTimeout(checkStateChange, 0); - const intervalId = setInterval(checkStateChange, 16); - - return () => { - isUnsubscribed = true; - clearInterval(intervalId); - }; - })(); - - setTimeout(() => { - storeUnsubscribe(); - console.log('[PanelNavigation] Timeout fallback from home'); - - dispatch(pushPanel({ - name: panel_names.DETAIL_PANEL, - panelInfo: { - patnrId, - prdtId, - fromHome: true, - ...additionalInfo - } - })); - }, 1000); -}; - -/** - * JustForYouBanner 클릭 시 순차 네비게이션 (PlayerPanel 제거 → JustForYouTestPanel push) - * @returns {Function} Redux thunk function - */ -export const navigateToJustForYouTestPanel = () => (dispatch, getState) => { - const currentActionCount = getState().panels.lastPanelAction || 0; - - console.log('[PanelNavigation] Starting navigation to JustForYouTestPanel:', { - currentActionCount - }); - - // 1. 먼저 HomePanel 상태 저장 (필요시) - dispatch(updatePanel({ - name: panel_names.HOME_PANEL, - panelInfo: { - fromJustForYouBanner: true, - timestamp: Date.now() - } - })); - - const storeUnsubscribe = (() => { - let isUnsubscribed = false; - - const checkStateChange = () => { - if (isUnsubscribed) return; - - const newState = getState(); - const newActionCount = newState.panels.lastPanelAction || 0; - - // updatePanel이 완료되면 - if (newActionCount !== currentActionCount) { - console.log('[PanelNavigation] HomePanel update completed, pushing JustForYouTestPanel'); - isUnsubscribed = true; - - // 2. JustForYouTestPanel push - dispatch(pushPanel({ - name: panel_names.JUST_FOR_YOU_TEST_PANEL, - panelInfo: { - fromJustForYouBanner: true - } - })); - - // 3. JustForYouTestPanel이 렌더링된 후 PlayerPanel 제거 - setTimeout(() => { - console.log('[PanelNavigation] Removing PlayerPanel after JustForYouTestPanel render'); - const { finishAllVideoForce } = require('./playActions'); - dispatch(finishAllVideoForce()); - }, 200); - } - }; - - setTimeout(checkStateChange, 0); - const intervalId = setInterval(checkStateChange, 16); - - return () => { - isUnsubscribed = true; - clearInterval(intervalId); - }; - })(); - - // 타임아웃 방어 (최대 1초 대기) - setTimeout(() => { - storeUnsubscribe(); - console.log('[PanelNavigation] Timeout fallback, pushing JustForYouTestPanel'); - - dispatch(pushPanel({ - name: panel_names.JUST_FOR_YOU_TEST_PANEL, - panelInfo: { - fromJustForYouBanner: true - } - })); - - // fallback으로도 PlayerPanel 제거 - setTimeout(() => { - console.log('[PanelNavigation] Fallback: removing PlayerPanel'); - const { finishAllVideoForce } = require('./playActions'); - dispatch(finishAllVideoForce()); - }, 200); - }, 1000); -}; \ No newline at end of file +/** + * src/actions/panelNavigationActions.js + * Panel navigation 순차 처리를 위한 액션 크리에이터 + * + * Chrome 68 호환성을 위한 callback-free 순차 네비게이션 + */ + +import { pushPanel, updatePanel } from './panelActions'; +import { panel_names } from '../utils/Config'; +import { createDebugHelpers } from '../utils/debug'; + +// 디버그 헬퍼 설정 +const DEBUG_MODE = false; +const { dlog, dwarn, derror } = createDebugHelpers(DEBUG_MODE); + +/** + * 상품 클릭 시 순차 네비게이션 (Search → Detail) + * @param {string} patnrId - 파트너 ID + * @param {string} prdtId - 상품 ID + * @param {string} searchQuery - 검색어 + * @param {string} currentSpot - 현재 spotlight ID + * @param {Object} additionalInfo - 추가 패널 정보 + * @returns {Function} Redux thunk function + */ +export const navigateToDetailPanel = + (patnrId, prdtId, searchQuery, currentSpot, additionalInfo = {}) => + (dispatch, getState) => { + // 현재 상태에서 lastPanelAction 카운트 저장 + const currentActionCount = getState().panels.lastPanelAction || 0; + + dlog('[PanelNavigation] Starting navigation to detail:', { + patnrId, + prdtId, + searchQuery, + currentSpot, + currentActionCount, + }); + + // 1. 먼저 현재 패널(예: SearchPanel) 업데이트 + dispatch( + updatePanel({ + name: panel_names.SEARCH_PANEL, + panelInfo: { + searchVal: searchQuery, + currentSpot, + tab: 0, + ...additionalInfo, + }, + }) + ); + + // 2. Redux store 구독하여 상태 변화 감지 + // 직접 store 접근 대신 타이머 기반 방식 사용 (Chrome 68 호환) + const storeUnsubscribe = (() => { + let isUnsubscribed = false; + + const checkStateChange = () => { + if (isUnsubscribed) return; + + const newState = getState(); + const newActionCount = newState.panels.lastPanelAction || 0; + + // updatePanel이 완료되면 (action count가 변경되면) + if (newActionCount !== currentActionCount) { + dlog('[PanelNavigation] UpdatePanel completed, pushing DetailPanel'); + + // 구독 해제 + isUnsubscribed = true; + + // 3. DetailPanel push + dispatch( + pushPanel({ + name: panel_names.DETAIL_PANEL, + panelInfo: { + patnrId, + prdtId, + fromSearch: true, + searchQuery, + ...additionalInfo, + }, + }) + ); + } + }; + + // 즉시 한번 확인하고, 그 후 주기적으로 확인 + setTimeout(checkStateChange, 0); + const intervalId = setInterval(checkStateChange, 16); // 60fps + + return () => { + isUnsubscribed = true; + clearInterval(intervalId); + }; + })(); + + // 타임아웃 방어 (최대 1초 대기) + setTimeout(() => { + storeUnsubscribe(); + dlog('[PanelNavigation] Timeout fallback, pushing DetailPanel'); + + dispatch( + pushPanel({ + name: panel_names.DETAIL_PANEL, + panelInfo: { + patnrId, + prdtId, + fromSearch: true, + searchQuery, + ...additionalInfo, + }, + }) + ); + }, 1000); + }; + +/** + * HomePanel에서 상품 클릭 시 순차 네비게이션 + * @param {string} patnrId - 파트너 ID + * @param {string} prdtId - 상품 ID + * @param {Object} additionalInfo - 추가 패널 정보 + * @returns {Function} Redux thunk function + */ +export const navigateToDetailFromHome = + (patnrId, prdtId, additionalInfo = {}) => + (dispatch, getState) => { + const currentActionCount = getState().panels.lastPanelAction || 0; + + dlog('[PanelNavigation] Starting navigation from home:', { + patnrId, + prdtId, + currentActionCount, + }); + + dispatch( + updatePanel({ + name: panel_names.HOME_PANEL, + panelInfo: { + lastSelectedProduct: { patnrId, prdtId }, + ...additionalInfo, + }, + }) + ); + + const storeUnsubscribe = (() => { + let isUnsubscribed = false; + + const checkStateChange = () => { + if (isUnsubscribed) return; + + const newState = getState(); + const newActionCount = newState.panels.lastPanelAction || 0; + + if (newActionCount !== currentActionCount) { + dlog('[PanelNavigation] HomePanel update completed, pushing DetailPanel'); + isUnsubscribed = true; + + dispatch( + pushPanel({ + name: panel_names.DETAIL_PANEL, + panelInfo: { + patnrId, + prdtId, + fromHome: true, + ...additionalInfo, + }, + }) + ); + } + }; + + setTimeout(checkStateChange, 0); + const intervalId = setInterval(checkStateChange, 16); + + return () => { + isUnsubscribed = true; + clearInterval(intervalId); + }; + })(); + + setTimeout(() => { + storeUnsubscribe(); + dlog('[PanelNavigation] Timeout fallback from home'); + + dispatch( + pushPanel({ + name: panel_names.DETAIL_PANEL, + panelInfo: { + patnrId, + prdtId, + fromHome: true, + ...additionalInfo, + }, + }) + ); + }, 1000); + }; + +/** + * JustForYouBanner 클릭 시 순차 네비게이션 (PlayerPanel 제거 → JustForYouTestPanel push) + * @returns {Function} Redux thunk function + */ +export const navigateToJustForYouTestPanel = () => (dispatch, getState) => { + const currentActionCount = getState().panels.lastPanelAction || 0; + + dlog('[PanelNavigation] Starting navigation to JustForYouTestPanel:', { + currentActionCount, + }); + + // 1. 먼저 HomePanel 상태 저장 (필요시) + dispatch( + updatePanel({ + name: panel_names.HOME_PANEL, + panelInfo: { + fromJustForYouBanner: true, + timestamp: Date.now(), + }, + }) + ); + + const storeUnsubscribe = (() => { + let isUnsubscribed = false; + + const checkStateChange = () => { + if (isUnsubscribed) return; + + const newState = getState(); + const newActionCount = newState.panels.lastPanelAction || 0; + + // updatePanel이 완료되면 + if (newActionCount !== currentActionCount) { + dlog('[PanelNavigation] HomePanel update completed, pushing JustForYouTestPanel'); + isUnsubscribed = true; + + // 2. JustForYouTestPanel push + dispatch( + pushPanel({ + name: panel_names.JUST_FOR_YOU_TEST_PANEL, + panelInfo: { + fromJustForYouBanner: true, + }, + }) + ); + + // 3. JustForYouTestPanel이 렌더링된 후 PlayerPanel 제거 + setTimeout(() => { + dlog('[PanelNavigation] Removing PlayerPanel after JustForYouTestPanel render'); + const { finishAllVideoForce } = require('./playActions'); + dispatch(finishAllVideoForce()); + }, 200); + } + }; + + setTimeout(checkStateChange, 0); + const intervalId = setInterval(checkStateChange, 16); + + return () => { + isUnsubscribed = true; + clearInterval(intervalId); + }; + })(); + + // 타임아웃 방어 (최대 1초 대기) + setTimeout(() => { + storeUnsubscribe(); + dlog('[PanelNavigation] Timeout fallback, pushing JustForYouTestPanel'); + + dispatch( + pushPanel({ + name: panel_names.JUST_FOR_YOU_TEST_PANEL, + panelInfo: { + fromJustForYouBanner: true, + }, + }) + ); + + // fallback으로도 PlayerPanel 제거 + setTimeout(() => { + dlog('[PanelNavigation] Fallback: removing PlayerPanel'); + const { finishAllVideoForce } = require('./playActions'); + dispatch(finishAllVideoForce()); + }, 200); + }, 1000); +}; diff --git a/com.twin.app.shoptime/src/actions/pinCodeActions.js b/com.twin.app.shoptime/src/actions/pinCodeActions.js index 22cff540..5c4c02ac 100644 --- a/com.twin.app.shoptime/src/actions/pinCodeActions.js +++ b/com.twin.app.shoptime/src/actions/pinCodeActions.js @@ -1,57 +1,61 @@ -import { URLS } from "../api/apiConfig"; -import { TAxios } from "../api/TAxios"; -import { types } from "./actionTypes"; -import { changeAppStatus } from "./commonActions"; +import { URLS } from '../api/apiConfig'; +import { TAxios } from '../api/TAxios'; +import { types } from './actionTypes'; +import { changeAppStatus } from './commonActions'; +import { createDebugHelpers } from '../utils/debug'; + +// 디버그 헬퍼 설정 +const DEBUG_MODE = false; +const { dlog, dwarn, derror } = createDebugHelpers(DEBUG_MODE); // 회원 등록카드 PIN CODE 입력 체크 IF-LGSP-336 -export const getMyInfoCardPincodeCheck = - (params, callback) => (dispatch, getState) => { - const { mbrNo, pinCd } = params; +export const getMyInfoCardPincodeCheck = (params, callback) => (dispatch, getState) => { + const { mbrNo, pinCd } = params; - dispatch( - changeAppStatus({ - showLoadingPanel: { show: true, type: "wait", showMessage: true }, - }) - ); + dispatch( + changeAppStatus({ + showLoadingPanel: { show: true, type: 'wait', showMessage: true }, + }) + ); - const onSuccess = (response) => { - console.log("getMyInfoCardPincodeCheck onSuccess ", response); + const onSuccess = (response) => { + dlog('getMyInfoCardPincodeCheck onSuccess ', response); - dispatch({ - type: types.GET_MY_INFO_CARD_PINCODE_CHECK, - payload: response.data, - }); + dispatch({ + type: types.GET_MY_INFO_CARD_PINCODE_CHECK, + payload: response.data, + }); - if (response.data.retCode !== 0) { - dispatch( - changeAppStatus({ - showLoadingPanel: { show: false, showMessage: false }, - }) - ); - } - - if (callback) { - callback(response.data); - } - }; - - const onFail = (error) => { - console.error("getMyInfoCardPincodeCheck onFail ", error); + if (response.data.retCode !== 0) { dispatch( changeAppStatus({ showLoadingPanel: { show: false, showMessage: false }, }) ); - }; + } - TAxios( - dispatch, - getState, - "get", - URLS.GET_MY_INFO_CARD_PINCODE_CHECK, - { mbrNo, pinCd }, - {}, - onSuccess, - onFail + if (callback) { + callback(response.data); + } + }; + + const onFail = (error) => { + derror('getMyInfoCardPincodeCheck onFail ', error); + dispatch( + changeAppStatus({ + showLoadingPanel: { show: false, showMessage: false }, + }) ); }; + + TAxios( + dispatch, + getState, + 'get', + URLS.GET_MY_INFO_CARD_PINCODE_CHECK, + { mbrNo, pinCd }, + {}, + onSuccess, + onFail + ); +}; diff --git a/com.twin.app.shoptime/src/actions/productActions.js b/com.twin.app.shoptime/src/actions/productActions.js index 62c1d926..17754db9 100644 --- a/com.twin.app.shoptime/src/actions/productActions.js +++ b/com.twin.app.shoptime/src/actions/productActions.js @@ -5,15 +5,13 @@ import { changeAppStatus } from './commonActions'; import { reduce, set, get } from '../utils/fp'; import { createDebugHelpers } from '../utils/debug'; +// 디버그 헬퍼 설정 +const DEBUG_MODE = false; +const { dlog, dwarn, derror } = createDebugHelpers(DEBUG_MODE); + // CustomerImages용 리뷰 이미지 import import reviewSampleImage from '../../assets/images/image-review-sample-1.png'; -// DEBUG_MODE - true인 경우에만 로그 출력 -const DEBUG_MODE = false; - -// 이 파일의 DEBUG_MODE를 사용하여 헬퍼 생성 -const { dlog, dwarn, derror } = createDebugHelpers(DEBUG_MODE); - // Best Seller 상품 목록 조회 IF-LGSP-303 // FP helpers const pickParams = (keys) => (src) => @@ -167,7 +165,7 @@ export const getProductOption = createGetThunk({ // // return apiData; // } catch (error) { -// console.error('[UserReviews] ❌ extractReviewApiData 에러:', error); +// derror('[UserReviews] ❌ extractReviewApiData 에러:', error); // return null; // } // }; @@ -176,11 +174,11 @@ export const getProductOption = createGetThunk({ // IF-LGSP-101용 API 응답에서 reviewList + reviewDetail 추출 const extractReviewListApiData = (apiResponse) => { try { - // console.log('[UserReviewList] 📥 extractReviewListApiData 호출 - 원본 응답:', apiResponse); + // dlog('[UserReviewList] 📥 extractReviewListApiData 호출 - 원본 응답:', apiResponse); // ⭐ 핵심: retCode가 0인지 먼저 확인 (HTTP 200이어도 API 에러일 수 있음) if (apiResponse && apiResponse.retCode !== 0) { - // console.error('[UserReviewList] ❌ API 에러 - retCode !== 0:', { + // derror('[UserReviewList] ❌ API 에러 - retCode !== 0:', { // retCode: apiResponse.retCode, // retMsg: apiResponse.retMsg, // fullResponse: apiResponse @@ -206,7 +204,7 @@ const extractReviewListApiData = (apiResponse) => { reviewList.length === 0 ) { reviewList = reviewDetail.reviewList; - // console.log('[UserReviewList] 🔄 reviewDetail.reviewList에서 데이터 추출됨'); + // dlog('[UserReviewList] 🔄 reviewDetail.reviewList에서 데이터 추출됨'); } data = { @@ -214,7 +212,7 @@ const extractReviewListApiData = (apiResponse) => { reviewDetail: reviewDetail, }; - // console.log('[UserReviewList] 📊 apiResponse.data 경로에서 추출:', { + // dlog('[UserReviewList] 📊 apiResponse.data 경로에서 추출:', { // reviewListLength: data.reviewList.length, // reviewDetailKeys: Object.keys(data.reviewDetail), // reviewDetail: data.reviewDetail, @@ -232,7 +230,7 @@ const extractReviewListApiData = (apiResponse) => { reviewList.length === 0 ) { reviewList = reviewDetail.reviewList; - // console.log('[UserReviewList] 🔄 reviewDetail.reviewList에서 데이터 추출됨'); + // dlog('[UserReviewList] 🔄 reviewDetail.reviewList에서 데이터 추출됨'); } data = { @@ -240,7 +238,7 @@ const extractReviewListApiData = (apiResponse) => { reviewDetail: reviewDetail, }; - // console.log('[UserReviewList] 📊 직접 경로에서 추출:', { + // dlog('[UserReviewList] 📊 직접 경로에서 추출:', { // reviewListLength: data.reviewList.length, // reviewDetailKeys: Object.keys(data.reviewDetail), // reviewDetail: data.reviewDetail, @@ -249,18 +247,18 @@ const extractReviewListApiData = (apiResponse) => { } if (!data || (!data.reviewList && !data.reviewDetail)) { - // console.warn('[UserReviewList] ⚠️ reviewList와 reviewDetail 모두 없음:', apiResponse); + // dwarn('[UserReviewList] ⚠️ reviewList와 reviewDetail 모두 없음:', apiResponse); return null; } - // console.log('[UserReviewList] ✅ 추출 완료:', { + // dlog('[UserReviewList] ✅ 추출 완료:', { // reviewListLength: data.reviewList.length, // reviewDetail: data.reviewDetail // }); return data; } catch (error) { - // console.error('[UserReviewList] ❌ extractReviewListApiData 에러:', error); + // derror('[UserReviewList] ❌ extractReviewListApiData 에러:', error); return null; } }; @@ -397,7 +395,7 @@ const fetchAllReviewsWithSequentialPaging = async ( pageSize = 100, // 최대값으로 설정하여 페이징 횟수 최소화 } = requestParams; - // console.log('[UserReviewList] 🚀 순차 페이징 시작:', { + // dlog('[UserReviewList] 🚀 순차 페이징 시작:', { // prdtId, // patnrId, // filterTpCd, @@ -427,7 +425,7 @@ const fetchAllReviewsWithSequentialPaging = async ( // filterTpCd가 'ALL'이 아니면 filterTpVal 추가 if (filterTpCd !== 'ALL') { if (!filterTpVal) { - // console.warn('[UserReviewList] ⚠️ filterTpCd가 ALL이 아니면 filterTpVal은 필수입니다'); + // dwarn('[UserReviewList] ⚠️ filterTpCd가 ALL이 아니면 filterTpVal은 필수입니다'); } params.filterTpVal = filterTpVal; } @@ -436,7 +434,7 @@ const fetchAllReviewsWithSequentialPaging = async ( // ⭐ 타임아웃 추가: TAxios의 콜백이 호출되지 않는 경우를 대비 (모든 오류 상황 처리) const REQUEST_TIMEOUT = 5000; // 5초 타임아웃 (재인증, 팝업 등 오류 상황 처리 포함) - // console.log(`[UserReviewList] 🔄 API 요청 시작 (page ${pageNo}):`, { + // dlog(`[UserReviewList] 🔄 API 요청 시작 (page ${pageNo}):`, { // prdtId, // patnrId, // filterTpCd, @@ -450,12 +448,12 @@ const fetchAllReviewsWithSequentialPaging = async ( const onSuccess = (res) => { if (callbackCalled) { - // console.warn(`[UserReviewList] ⚠️ onSuccess 중복 호출 (page ${pageNo})`); + // dwarn(`[UserReviewList] ⚠️ onSuccess 중복 호출 (page ${pageNo})`); return; } callbackCalled = true; - // console.log(`[UserReviewList] ✅ API 응답 수신 (page ${pageNo}):`, { + // dlog(`[UserReviewList] ✅ API 응답 수신 (page ${pageNo}):`, { // status: res?.status, // statusText: res?.statusText, // retCode: res?.data?.retCode, @@ -467,12 +465,12 @@ const fetchAllReviewsWithSequentialPaging = async ( const onFail = (err) => { if (callbackCalled) { - // console.warn(`[UserReviewList] ⚠️ onFail 중복 호출 (page ${pageNo})`); + // dwarn(`[UserReviewList] ⚠️ onFail 중복 호출 (page ${pageNo})`); return; } callbackCalled = true; - // console.error(`[UserReviewList] ❌ API 콜백 에러 발생 (page ${pageNo}):`, { + // derror(`[UserReviewList] ❌ API 콜백 에러 발생 (page ${pageNo}):`, { // errorMessage: err?.message, // errorStatus: err?.response?.status, // errorStatusText: err?.response?.statusText, @@ -484,7 +482,7 @@ const fetchAllReviewsWithSequentialPaging = async ( }; // API 호출 - // console.log(`[UserReviewList] 📡 TAxios 호출 (page ${pageNo})`); + // dlog(`[UserReviewList] 📡 TAxios 호출 (page ${pageNo})`); TAxios( dispatch, getState, @@ -500,7 +498,7 @@ const fetchAllReviewsWithSequentialPaging = async ( new Promise((_, reject) => setTimeout(() => { const timeoutError = new Error(`API request timeout without callback (page ${pageNo})`); - // console.error(`[UserReviewList] ⏱️ API 응답 타임아웃 (page ${pageNo}):`, { + // derror(`[UserReviewList] ⏱️ API 응답 타임아웃 (page ${pageNo}):`, { // timeout: REQUEST_TIMEOUT, // prdtId, // patnrId, @@ -515,7 +513,7 @@ const fetchAllReviewsWithSequentialPaging = async ( // ⭐ 핵심: HTTP 200이어도 response.data.retCode를 반드시 확인해야 함 const retCode = response?.data?.retCode; - // console.log(`[UserReviewList] 📄 페이지 ${pageNo} 응답 상태 확인:`, { + // dlog(`[UserReviewList] 📄 페이지 ${pageNo} 응답 상태 확인:`, { // pageNo, // httpStatus: response?.status, // retCode: retCode, @@ -526,7 +524,7 @@ const fetchAllReviewsWithSequentialPaging = async ( // retCode가 0이 아니면 API 에러 (HTTP 200이어도 실제 데이터 없을 수 있음) if (retCode !== 0) { - // console.error(`[UserReviewList] ❌ API 에러 - retCode !== 0 (page ${pageNo}):`, { + // derror(`[UserReviewList] ❌ API 에러 - retCode !== 0 (page ${pageNo}):`, { // retCode, // retMsg: response?.data?.retMsg, // pageNo, @@ -540,7 +538,7 @@ const fetchAllReviewsWithSequentialPaging = async ( const reviewData = extractReviewListApiData(response.data); if (!reviewData || !reviewData.reviewList) { - // console.warn('[UserReviewList] ⚠️ 리뷰 데이터 추출 실패, 페이징 종료'); + // dwarn('[UserReviewList] ⚠️ 리뷰 데이터 추출 실패, 페이징 종료'); break; } @@ -552,7 +550,7 @@ const fetchAllReviewsWithSequentialPaging = async ( // 5. 현재 페이지의 리뷰들을 전체 리스트에 추가 allReviews = allReviews.concat(reviewData.reviewList); - // console.log(`[UserReviewList] ✅ 페이지 ${pageNo} 수집 완료:`, { + // dlog(`[UserReviewList] ✅ 페이지 ${pageNo} 수집 완료:`, { // pageNo, // currentPageCount: reviewData.reviewList.length, // totalCollected: allReviews.length, @@ -567,7 +565,7 @@ const fetchAllReviewsWithSequentialPaging = async ( if (receivedCount < pageSize || allReviews.length >= totalReviews) { hasMore = false; - // console.log('[UserReviewList] 📊 페이징 종료:', { + // dlog('[UserReviewList] 📊 페이징 종료:', { // reason: receivedCount < pageSize ? '받은 개수 < pageSize' : '수집된 개수 >= 총 개수', // receivedCount, // pageSize, @@ -580,7 +578,7 @@ const fetchAllReviewsWithSequentialPaging = async ( } // 7. 모든 리뷰 수집 완료, Redux에 디스패치 - // console.log('[UserReviewList] 🎉 모든 리뷰 수집 완료:', { + // dlog('[UserReviewList] 🎉 모든 리뷰 수집 완료:', { // totalCollected: allReviews.length, // totRvwCnt: currentReviewDetail?.totRvwCnt, // pages: pageNo - 1 @@ -602,7 +600,7 @@ const fetchAllReviewsWithSequentialPaging = async ( payload: finalPayload, }; - // console.log('[UserReviewList] 📦 Redux 디스패치:', { + // dlog('[UserReviewList] 📦 Redux 디스패치:', { // actionType, // totalReviews: allReviews.length, // totRvwCnt: currentReviewDetail?.totRvwCnt, @@ -620,7 +618,7 @@ const fetchAllReviewsWithSequentialPaging = async ( const apiRetCode = error?.response?.data?.retCode; const apiRetMsg = error?.response?.data?.retMsg; - // console.error('[fetchAllReviewsWithSequentialPaging] ❌ 에러 발생:', { + // derror('[fetchAllReviewsWithSequentialPaging] ❌ 에러 발생:', { // errorMessage: errorMessage, // errorType: typeof error, // httpStatus: httpStatus, @@ -638,7 +636,7 @@ const fetchAllReviewsWithSequentialPaging = async ( const isTimeoutError = errorMessage.includes('timeout') || errorMessage.includes('without callback'); if (isTimeoutError && retryCount < MAX_RETRIES) { - // console.log(`[fetchAllReviewsWithSequentialPaging] 🔄 타임아웃으로 인한 재시도 (${retryCount + 1}/${MAX_RETRIES}):`, { + // dlog(`[fetchAllReviewsWithSequentialPaging] 🔄 타임아웃으로 인한 재시도 (${retryCount + 1}/${MAX_RETRIES}):`, { // prdtId, // patnrId, // pageNo, @@ -663,7 +661,7 @@ const fetchAllReviewsWithSequentialPaging = async ( export const getUserReviewList = (requestParams) => async (dispatch, getState) => { const { prdtId, patnrId, filterTpCd = 'ALL', filterTpVal } = requestParams; - // console.log('[getUserReviewList] 🚀 getUserReviewList 호출됨 (순차 페이징 사용):', { + // dlog('[getUserReviewList] 🚀 getUserReviewList 호출됨 (순차 페이징 사용):', { // prdtId, // patnrId, // filterTpCd, @@ -675,7 +673,7 @@ export const getUserReviewList = (requestParams) => async (dispatch, getState) = // fetchAllReviewsWithSequentialPaging 함수를 호출하여 모든 리뷰 수집 const result = await fetchAllReviewsWithSequentialPaging(dispatch, getState, requestParams); - // console.log('[getUserReviewList] ✅ 모든 리뷰 수집 완료:', { + // dlog('[getUserReviewList] ✅ 모든 리뷰 수집 완료:', { // totalReviews: result.reviewList.length, // totRvwCnt: result.reviewDetail?.totRvwCnt, // prdtId, @@ -690,7 +688,7 @@ export const getUserReviewList = (requestParams) => async (dispatch, getState) = const apiRetCode = error?.response?.data?.retCode; const apiRetMsg = error?.response?.data?.retMsg; - // console.error('[getUserReviewList] ❌ 순차 페이징 중 에러 발생:', { + // derror('[getUserReviewList] ❌ 순차 페이징 중 에러 발생:', { // errorMessage: errorMessage, // errorType: typeof error, // httpStatus: httpStatus, diff --git a/com.twin.app.shoptime/src/actions/queuedPanelActions.js b/com.twin.app.shoptime/src/actions/queuedPanelActions.js index e0cabb27..bd13d008 100644 --- a/com.twin.app.shoptime/src/actions/queuedPanelActions.js +++ b/com.twin.app.shoptime/src/actions/queuedPanelActions.js @@ -1,4 +1,9 @@ -import { types } from "./actionTypes"; +import { types } from './actionTypes'; +import { createDebugHelpers } from '../utils/debug'; + +// 디버그 헬퍼 설정 +const DEBUG_MODE = false; +const { dlog, dwarn, derror } = createDebugHelpers(DEBUG_MODE); /** * [251106] 큐 기반 패널 액션들 @@ -26,8 +31,8 @@ export const pushPanelQueued = (panel, duplicatable = false) => ({ action: 'PUSH_PANEL', panel, duplicatable, - timestamp: Date.now() - } + timestamp: Date.now(), + }, }); /** @@ -41,8 +46,8 @@ export const popPanelQueued = (panelName = null) => ({ id: `queue_item_${++queueItemId}_${Date.now()}`, action: 'POP_PANEL', panelName, - timestamp: Date.now() - } + timestamp: Date.now(), + }, }); /** @@ -56,8 +61,8 @@ export const updatePanelQueued = (panelInfo) => ({ id: `queue_item_${++queueItemId}_${Date.now()}`, action: 'UPDATE_PANEL', panelInfo, - timestamp: Date.now() - } + timestamp: Date.now(), + }, }); /** @@ -71,8 +76,8 @@ export const resetPanelsQueued = (panels = null) => ({ id: `queue_item_${++queueItemId}_${Date.now()}`, action: 'RESET_PANELS', panels, - timestamp: Date.now() - } + timestamp: Date.now(), + }, }); /** @@ -82,8 +87,8 @@ export const resetPanelsQueued = (panels = null) => ({ export const clearPanelQueue = () => ({ type: types.CLEAR_PANEL_QUEUE, payload: { - timestamp: Date.now() - } + timestamp: Date.now(), + }, }); /** @@ -94,8 +99,8 @@ export const clearPanelQueue = () => ({ export const processPanelQueue = () => ({ type: types.PROCESS_PANEL_QUEUE, payload: { - timestamp: Date.now() - } + timestamp: Date.now(), + }, }); /** @@ -108,8 +113,8 @@ export const setQueueProcessing = (isProcessing) => ({ type: types.SET_QUEUE_PROCESSING, payload: { isProcessing, - timestamp: Date.now() - } + timestamp: Date.now(), + }, }); /** @@ -119,7 +124,7 @@ export const setQueueProcessing = (isProcessing) => ({ */ export const enqueueMultiplePanelActions = (actions) => { return (dispatch) => { - actions.forEach(action => { + actions.forEach((action) => { dispatch(action); }); // 마지막에 큐 처리 시작 @@ -134,20 +139,22 @@ export const enqueueMultiplePanelActions = (actions) => { */ export const createPanelSequence = (sequence) => { return (dispatch) => { - const queuedActions = sequence.map(item => { - switch (item.type) { - case 'push': - return pushPanelQueued(item.panel, item.duplicatable); - case 'pop': - return popPanelQueued(item.panelName); - case 'update': - return updatePanelQueued(item.panelInfo); - case 'reset': - return resetPanelsQueued(item.panels); - default: - return null; - } - }).filter(Boolean); + const queuedActions = sequence + .map((item) => { + switch (item.type) { + case 'push': + return pushPanelQueued(item.panel, item.duplicatable); + case 'pop': + return popPanelQueued(item.panelName); + case 'update': + return updatePanelQueued(item.panelInfo); + case 'reset': + return resetPanelsQueued(item.panels); + default: + return null; + } + }) + .filter(Boolean); dispatch(enqueueMultiplePanelActions(queuedActions)); }; @@ -174,9 +181,9 @@ export const enqueueAsyncPanelAction = (config) => { return (dispatch, getState) => { const actionId = config.id || `async_action_${++queueItemId}_${Date.now()}`; - console.log('[queuedPanelActions] 🔄 ENQUEUE_ASYNC_PANEL_ACTION', { + dlog('[queuedPanelActions] 🔄 ENQUEUE_ASYNC_PANEL_ACTION', { actionId, - timestamp: Date.now() + timestamp: Date.now(), }); dispatch({ @@ -189,8 +196,8 @@ export const enqueueAsyncPanelAction = (config) => { onFinish: config.onFinish, timeout: config.timeout || 10000, timestamp: Date.now(), - status: 'pending' - } + status: 'pending', + }, }); // 비동기 액션 실행 @@ -206,141 +213,142 @@ export const enqueueAsyncPanelAction = (config) => { */ const executeAsyncAction = (dispatch, getState, actionId) => { const state = getState(); - const asyncAction = state.panels?.panelActionQueue?.find(item => item.id === actionId); + const asyncAction = state.panels?.panelActionQueue?.find((item) => item.id === actionId); if (!asyncAction) { - console.warn('[queuedPanelActions] ⚠️ ASYNC_ACTION_NOT_FOUND', actionId); + dwarn('[queuedPanelActions] ⚠️ ASYNC_ACTION_NOT_FOUND', actionId); return; } - console.log('[queuedPanelActions] ⚡ EXECUTING_ASYNC_ACTION', actionId); + dlog('[queuedPanelActions] ⚡ EXECUTING_ASYNC_ACTION', actionId); // 비동기 액션을 Promise로 래핑하여 실행 - import('../utils/asyncActionUtils').then(({ wrapAsyncAction, withTimeout }) => { - const actionPromise = wrapAsyncAction(asyncAction.asyncAction, { dispatch, getState }); - const timeoutPromise = withTimeout(actionPromise, asyncAction.timeout); + import('../utils/asyncActionUtils') + .then(({ wrapAsyncAction, withTimeout }) => { + const actionPromise = wrapAsyncAction(asyncAction.asyncAction, { dispatch, getState }); + const timeoutPromise = withTimeout(actionPromise, asyncAction.timeout); - timeoutPromise - .then(result => { - console.log('[queuedPanelActions] 📊 ASYNC_ACTION_RESULT', { - actionId, - success: result.success, - hasError: !!result.error, - errorCode: result.error?.code - }); - - if (result.success) { - // 성공 처리 - console.log('[queuedPanelActions] ✅ ASYNC_ACTION_SUCCESS', actionId); - - // 사용자 정의 성공 콜백 실행 - if (asyncAction.onSuccess) { - try { - asyncAction.onSuccess(result.data); - } catch (error) { - console.error('[queuedPanelActions] ❌ USER_ON_SUCCESS_ERROR', error); - } - } - - // 완료 콜백 실행 - if (asyncAction.onFinish) { - try { - asyncAction.onFinish(true, result.data); - } catch (error) { - console.error('[queuedPanelActions] ❌ USER_ON_FINISH_ERROR', error); - } - } - - // Redux 상태 업데이트 - dispatch({ - type: types.COMPLETE_ASYNC_PANEL_ACTION, - payload: { - actionId, - result: result.data, - timestamp: Date.now() - } - }); - - } else { - // 실패 처리 - console.error('[queuedPanelActions] ❌ ASYNC_ACTION_FAILED', { + timeoutPromise + .then((result) => { + dlog('[queuedPanelActions] 📊 ASYNC_ACTION_RESULT', { actionId, - error: result.error, - errorCode: result.error?.code + success: result.success, + hasError: !!result.error, + errorCode: result.error?.code, }); - // 사용자 정의 실패 콜백 실행 + if (result.success) { + // 성공 처리 + dlog('[queuedPanelActions] ✅ ASYNC_ACTION_SUCCESS', actionId); + + // 사용자 정의 성공 콜백 실행 + if (asyncAction.onSuccess) { + try { + asyncAction.onSuccess(result.data); + } catch (error) { + derror('[queuedPanelActions] ❌ USER_ON_SUCCESS_ERROR', error); + } + } + + // 완료 콜백 실행 + if (asyncAction.onFinish) { + try { + asyncAction.onFinish(true, result.data); + } catch (error) { + derror('[queuedPanelActions] ❌ USER_ON_FINISH_ERROR', error); + } + } + + // Redux 상태 업데이트 + dispatch({ + type: types.COMPLETE_ASYNC_PANEL_ACTION, + payload: { + actionId, + result: result.data, + timestamp: Date.now(), + }, + }); + } else { + // 실패 처리 + derror('[queuedPanelActions] ❌ ASYNC_ACTION_FAILED', { + actionId, + error: result.error, + errorCode: result.error?.code, + }); + + // 사용자 정의 실패 콜백 실행 + if (asyncAction.onFail) { + try { + asyncAction.onFail(result.error); + } catch (callbackError) { + derror('[queuedPanelActions] ❌ USER_ON_FAIL_ERROR', callbackError); + } + } + + // 완료 콜백 실행 + if (asyncAction.onFinish) { + try { + asyncAction.onFinish(false, result.error); + } catch (callbackError) { + derror('[queuedPanelActions] ❌ USER_ON_FINISH_ERROR', callbackError); + } + } + + // Redux 상태 업데이트 + dispatch({ + type: types.FAIL_ASYNC_PANEL_ACTION, + payload: { + actionId, + error: result.error, + timestamp: Date.now(), + }, + }); + } + }) + .catch((error) => { + derror('[queuedPanelActions] 💥 ASYNC_ACTION_EXECUTION_ERROR', { actionId, error }); + + // 치명적인 에러 처리 if (asyncAction.onFail) { try { - asyncAction.onFail(result.error); + asyncAction.onFail(error); } catch (callbackError) { - console.error('[queuedPanelActions] ❌ USER_ON_FAIL_ERROR', callbackError); + derror('[queuedPanelActions] ❌ USER_ON_FAIL_ERROR', callbackError); } } - // 완료 콜백 실행 if (asyncAction.onFinish) { try { - asyncAction.onFinish(false, result.error); + asyncAction.onFinish(false, error); } catch (callbackError) { - console.error('[queuedPanelActions] ❌ USER_ON_FINISH_ERROR', callbackError); + derror('[queuedPanelActions] ❌ USER_ON_FINISH_ERROR', callbackError); } } - // Redux 상태 업데이트 dispatch({ type: types.FAIL_ASYNC_PANEL_ACTION, payload: { actionId, - error: result.error, - timestamp: Date.now() - } - }); - } - }) - .catch(error => { - console.error('[queuedPanelActions] 💥 ASYNC_ACTION_EXECUTION_ERROR', { actionId, error }); - - // 치명적인 에러 처리 - if (asyncAction.onFail) { - try { - asyncAction.onFail(error); - } catch (callbackError) { - console.error('[queuedPanelActions] ❌ USER_ON_FAIL_ERROR', callbackError); - } - } - - if (asyncAction.onFinish) { - try { - asyncAction.onFinish(false, error); - } catch (callbackError) { - console.error('[queuedPanelActions] ❌ USER_ON_FINISH_ERROR', callbackError); - } - } - - dispatch({ - type: types.FAIL_ASYNC_PANEL_ACTION, - payload: { - actionId, - error: { - code: 'EXECUTION_ERROR', - message: error.message || '비동기 액션 실행 중 치명적인 오류 발생' + error: { + code: 'EXECUTION_ERROR', + message: error.message || '비동기 액션 실행 중 치명적인 오류 발생', + }, + timestamp: Date.now(), }, - timestamp: Date.now() - } + }); }); - }); - }).catch(error => { - console.error('[queuedPanelActions] 💥 ASYNC_UTILS_IMPORT_ERROR', error); + }) + .catch((error) => { + derror('[queuedPanelActions] 💥 ASYNC_UTILS_IMPORT_ERROR', error); - // 유틸리티 import 실패 시 기본 처리 - if (asyncAction.onFail) { - asyncAction.onFail(error); - } - if (asyncAction.onFinish) { - asyncAction.onFinish(false, error); - } - }); + // 유틸리티 import 실패 시 기본 처리 + if (asyncAction.onFail) { + asyncAction.onFail(error); + } + if (asyncAction.onFinish) { + asyncAction.onFinish(false, error); + } + }); }; /** @@ -355,11 +363,11 @@ const executeAsyncAction = (dispatch, getState, actionId) => { export const createApiWithPanelActions = (config) => { return enqueueAsyncPanelAction({ asyncAction: (dispatch, getState, onSuccess, onFail) => { - console.log('[queuedPanelActions] 🌐 API_CALL_START'); + dlog('[queuedPanelActions] 🌐 API_CALL_START'); config.apiCall(dispatch, getState, onSuccess, onFail); }, onSuccess: (response) => { - console.log('[queuedPanelActions] 🎯 API_SUCCESS_EXECUTING_PANELS'); + dlog('[queuedPanelActions] 🎯 API_SUCCESS_EXECUTING_PANELS'); // API 성공 콜백 실행 if (config.onApiSuccess) { @@ -380,7 +388,7 @@ export const createApiWithPanelActions = (config) => { } }, onFail: (error) => { - console.log('[queuedPanelActions] 🚫 API_FAILED', error); + dlog('[queuedPanelActions] 🚫 API_FAILED', error); // API 실패 콜백 실행 if (config.onApiFail) { @@ -388,8 +396,8 @@ export const createApiWithPanelActions = (config) => { } }, onFinish: (isSuccess, result) => { - console.log('[queuedPanelActions] 🏁 API_WITH_PANELS_COMPLETE', { isSuccess }); - } + dlog('[queuedPanelActions] 🏁 API_WITH_PANELS_COMPLETE', { isSuccess }); + }, }); }; @@ -404,14 +412,14 @@ export const createAsyncPanelSequence = (asyncConfigs) => { const executeNext = () => { if (currentIndex >= asyncConfigs.length) { - console.log('[queuedPanelActions] 🎊 ASYNC_SEQUENCE_COMPLETE'); + dlog('[queuedPanelActions] 🎊 ASYNC_SEQUENCE_COMPLETE'); return; } const config = asyncConfigs[currentIndex]; - console.log('[queuedPanelActions] 📋 EXECUTING_ASYNC_SEQUENCE_ITEM', { + dlog('[queuedPanelActions] 📋 EXECUTING_ASYNC_SEQUENCE_ITEM', { index: currentIndex, - total: asyncConfigs.length + total: asyncConfigs.length, }); // 현재 액션에 다음 액션 실행 로직 추가 @@ -428,12 +436,12 @@ export const createAsyncPanelSequence = (asyncConfigs) => { currentIndex++; setTimeout(executeNext, 50); // 50ms 후 다음 액션 실행 } else { - console.error('[queuedPanelActions] ⛔ ASYNC_SEQUENCE_STOPPED_ON_ERROR', { + derror('[queuedPanelActions] ⛔ ASYNC_SEQUENCE_STOPPED_ON_ERROR', { index: currentIndex, - error: result + error: result, }); } - } + }, }; dispatch(enqueueAsyncPanelAction(enhancedConfig)); @@ -442,4 +450,4 @@ export const createAsyncPanelSequence = (asyncConfigs) => { // 첫 번째 액션 실행 executeNext(); }; -}; \ No newline at end of file +}; diff --git a/com.twin.app.shoptime/src/actions/searchActions.js b/com.twin.app.shoptime/src/actions/searchActions.js index 26771087..afb08db7 100644 --- a/com.twin.app.shoptime/src/actions/searchActions.js +++ b/com.twin.app.shoptime/src/actions/searchActions.js @@ -3,6 +3,11 @@ import { TAxios } from '../api/TAxios'; import { SEARCH_DATA_MAX_RESULTS_LIMIT } from '../utils/Config'; import { types } from './actionTypes'; import { changeAppStatus } from './commonActions'; +import { createDebugHelpers } from '../utils/debug'; + +// 디버그 헬퍼 설정 +const DEBUG_MODE = false; +const { dlog, dwarn, derror } = createDebugHelpers(DEBUG_MODE); // Search 통합검색 (IBS) 데이터 조회 IF-LGSP-090 let getSearchKey = null; @@ -19,7 +24,7 @@ export const getSearch = let currentKey = key; const onSuccess = (response) => { - console.log('getSearch onSuccess: ', response.data); + dlog('getSearch onSuccess: ', response.data); if (startIndex === 1) { getSearchKey = new Date(); @@ -42,7 +47,7 @@ export const getSearch = }; const onFail = (error) => { - console.error('getSearch onFail: ', error); + derror('getSearch onFail: ', error); }; TAxios( @@ -101,7 +106,7 @@ export const getShopperHouseSearch = (dispatch, getState) => { // ✅ 빈 query 체크 - API 호출 방지 if (!query || query.trim() === '') { - console.log('[ShopperHouse] ⚠️ 빈 쿼리 - API 호출 건너뜀'); + dlog('[ShopperHouse] ⚠️ 빈 쿼리 - API 호출 건너뜀'); return; } @@ -111,7 +116,7 @@ export const getShopperHouseSearch = const currentKey = currentShopperHouseData?.results?.[0]?.searchId || 'null'; const preKey = preShopperHouseData?.results?.[0]?.searchId || 'null'; - console.log('[ShopperHouse]-DIFF shopperHouseKey:', currentKey, '| preShopperHouseKey:', preKey); + dlog('[ShopperHouse]-DIFF shopperHouseKey:', currentKey, '| preShopperHouseKey:', preKey); if (currentShopperHouseData) { dispatch({ @@ -127,37 +132,29 @@ export const getShopperHouseSearch = const currentSearchKey = new Date().getTime(); getShopperHouseSearchKey = currentSearchKey; - console.log( - '[ShopperHouse] 🔍 [DEBUG] API 호출 시작 - key:', - currentSearchKey, - 'query:', - query - ); + dlog('[ShopperHouse] 🔍 [DEBUG] API 호출 시작 - key:', currentSearchKey, 'query:', query); const onSuccess = (response) => { - console.log('[ShopperHouse] 📥 [DEBUG] API 응답 도착 - key:', currentSearchKey); - console.log('[ShopperHouse] 🔑 [DEBUG] 현재 유효한 key:', getShopperHouseSearchKey); + dlog('[ShopperHouse] 📥 [DEBUG] API 응답 도착 - key:', currentSearchKey); + dlog('[ShopperHouse] 🔑 [DEBUG] 현재 유효한 key:', getShopperHouseSearchKey); // ✨ 현재 요청이 최신 요청인지 확인 if (currentSearchKey === getShopperHouseSearchKey) { - console.log('[ShopperHouse] ✅ [DEBUG] 유효한 응답 - Redux 업데이트'); - console.log( - '[ShopperHouse] getShopperHouseSearch onSuccess: ', - JSON.stringify(response.data) - ); + dlog('[ShopperHouse] ✅ [DEBUG] 유효한 응답 - Redux 업데이트'); + dlog('[ShopperHouse] getShopperHouseSearch onSuccess: ', JSON.stringify(response.data)); // ✅ API 성공 여부 확인 const retCode = response.data?.retCode; if (retCode !== 0) { - console.error( + derror( '[ShopperHouse] ❌ API 실패 - retCode:', retCode, 'retMsg:', response.data?.retMsg ); - console.log('[VoiceInput] 📥 API 응답 실패'); - console.log('[VoiceInput] ├─ retCode:', retCode); - console.log('[VoiceInput] └─ retMsg:', response.data?.retMsg); + dlog('[VoiceInput] 📥 API 응답 실패'); + dlog('[VoiceInput] ├─ retCode:', retCode); + dlog('[VoiceInput] └─ retMsg:', response.data?.retMsg); // ✨ API 실패 응답을 Redux 에러 상태에 저장 dispatch( @@ -179,8 +176,8 @@ export const getShopperHouseSearch = // ✅ result 데이터 존재 확인 if (!response.data?.data?.result) { - console.error('[ShopperHouse] ❌ API 응답에 result 데이터 없음'); - console.log('[VoiceInput] 📥 API 응답 실패 (result 데이터 없음)'); + derror('[ShopperHouse] ❌ API 응답에 result 데이터 없음'); + dlog('[VoiceInput] 📥 API 응답 실패 (result 데이터 없음)'); // ✨ result 데이터 없음 에러를 Redux 에러 상태에 저장 dispatch( @@ -209,15 +206,15 @@ export const getShopperHouseSearch = const elapsedTime = ((new Date().getTime() - currentSearchKey) / 1000).toFixed(2); - console.log('*[ShopperHouseAPI] ✅ onSuccess - API 응답 성공'); - console.log( + dlog('*[ShopperHouseAPI] ✅ onSuccess - API 응답 성공'); + dlog( '*[ShopperHouseAPI] ├─ searchId:', receivedSearchId === null ? '(NULL)' : receivedSearchId ); - console.log('*[ShopperHouseAPI] ├─ 상품 개수:', productCount); - console.log('*[ShopperHouseAPI] ├─ relativeQueries:', relativeQueries || '(없음)'); - console.log('*[ShopperHouseAPI] ├─ 소요 시간:', elapsedTime + '초'); - console.log('*[ShopperHouseAPI] └─ timestamp:', new Date().toISOString()); + dlog('*[ShopperHouseAPI] ├─ 상품 개수:', productCount); + dlog('*[ShopperHouseAPI] ├─ relativeQueries:', relativeQueries || '(없음)'); + dlog('*[ShopperHouseAPI] ├─ 소요 시간:', elapsedTime + '초'); + dlog('*[ShopperHouseAPI] └─ timestamp:', new Date().toISOString()); dispatch({ type: types.GET_SHOPPERHOUSE_SEARCH, @@ -226,16 +223,16 @@ export const getShopperHouseSearch = dispatch(updateSearchTimestamp()); } else { - console.log('[ShopperHouse] ❌ [DEBUG] 오래된 응답 무시 - Redux 업데이트 안함'); + dlog('[ShopperHouse] ❌ [DEBUG] 오래된 응답 무시 - Redux 업데이트 안함'); } }; const onFail = (error) => { - console.error('[ShopperHouse] getShopperHouseSearch onFail: ', JSON.stringify(error)); + derror('[ShopperHouse] getShopperHouseSearch onFail: ', JSON.stringify(error)); // ✨ 현재 요청이 최신 요청인지 확인 if (currentSearchKey === getShopperHouseSearchKey) { - console.log('[ShopperHouse] ❌ [DEBUG] 유효한 에러 응답 - Redux 에러 상태 업데이트'); + dlog('[ShopperHouse] ❌ [DEBUG] 유효한 에러 응답 - Redux 에러 상태 업데이트'); const retCode = error?.data?.retCode; const status = error?.status; @@ -243,15 +240,15 @@ export const getShopperHouseSearch = // ✅ TAxios 재인증 오류 필터링 (기존 방식 그대로 활용) if (retCode === 401) { - console.log('*[ShopperHouseAPI] ⚠️ onFail - Access Token 만료 (401)'); - console.log('*[ShopperHouseAPI] └─ TAxios가 자동으로 재인증하고 재시도합니다'); + dlog('*[ShopperHouseAPI] ⚠️ onFail - Access Token 만료 (401)'); + dlog('*[ShopperHouseAPI] └─ TAxios가 자동으로 재인증하고 재시도합니다'); // 401 에러는 Redux에 저장하지 않음 (TAxios 자동 재시도 대기) return; } if (retCode === 402 || retCode === 501) { - console.log('*[ShopperHouseAPI] ⚠️ onFail - RefreshToken 만료 (' + retCode + ')'); - console.log('*[ShopperHouseAPI] └─ TAxios가 자동으로 토큰 재발급하고 재시도합니다'); + dlog('*[ShopperHouseAPI] ⚠️ onFail - RefreshToken 만료 (' + retCode + ')'); + dlog('*[ShopperHouseAPI] └─ TAxios가 자동으로 토큰 재발급하고 재시도합니다'); // 402/501 에러는 Redux에 저장하지 않음 (TAxios 자동 재시도 대기) return; } @@ -262,22 +259,22 @@ export const getShopperHouseSearch = errorMessage?.includes('Network Error') || errorMessage?.includes('timeout') ) { - console.log('*[ShopperHouseAPI] ⚠️ onFail - 일시적인 네트워크 오류'); - console.log('*[ShopperHouseAPI] ├─ status:', status); - console.log('*[ShopperHouseAPI] └─ errorMessage:', errorMessage); + dlog('*[ShopperHouseAPI] ⚠️ onFail - 일시적인 네트워크 오류'); + dlog('*[ShopperHouseAPI] ├─ status:', status); + dlog('*[ShopperHouseAPI] └─ errorMessage:', errorMessage); // 일시적인 네트워크 오류는 Redux에 저장하지 않음 return; } // ✨ 그 외의 실제 API 오류들만 Redux에 저장 - console.log('*[ShopperHouseAPI] ❌ onFail - 실제 API 오류 발생'); - console.log('*[ShopperHouseAPI] ├─ retCode:', retCode); - console.log('*[ShopperHouseAPI] ├─ status:', status); - console.log('*[ShopperHouseAPI] ├─ errorMessage:', errorMessage); - console.log('*[ShopperHouseAPI] └─ retMsg:', error?.data?.retMsg || '(없음)'); + dlog('*[ShopperHouseAPI] ❌ onFail - 실제 API 오류 발생'); + dlog('*[ShopperHouseAPI] ├─ retCode:', retCode); + dlog('*[ShopperHouseAPI] ├─ status:', status); + dlog('*[ShopperHouseAPI] ├─ errorMessage:', errorMessage); + dlog('*[ShopperHouseAPI] └─ retMsg:', error?.data?.retMsg || '(없음)'); // ✅ API 실패 시 모든 데이터 정리 - console.log('*[ShopperHouseAPI] 🧹 API 실패 - shopperHouse 데이터 정리'); + dlog('*[ShopperHouseAPI] 🧹 API 실패 - shopperHouse 데이터 정리'); dispatch(clearShopperHouseData()); // ✅ 사용자에게 실패 알림 표시 @@ -310,7 +307,7 @@ export const getShopperHouseSearch = }) ); } else { - console.log('[ShopperHouse] ❌ [DEBUG] 오래된 에러 응답 무시 - Redux 업데이트 안함'); + dlog('[ShopperHouse] ❌ [DEBUG] 오래된 에러 응답 무시 - Redux 업데이트 안함'); } }; @@ -321,17 +318,17 @@ export const getShopperHouseSearch = if (sortingType) { params.sortingType = sortingType; } - console.log('*[ShopperHouseAPI] getShopperHouseSearch params: ', JSON.stringify(params)); - console.log('*[ShopperHouseAPI] ├─ query:', query); - console.log('*[ShopperHouseAPI] ├─ searchId:', searchId === null ? '(NULL)' : searchId); - console.log('*[ShopperHouseAPI] ├─ sortingType:', sortingType === null ? '(NULL)' : sortingType); - console.log('*[ShopperHouseAPI] └─ timestamp:', new Date().toISOString()); + dlog('*[ShopperHouseAPI] getShopperHouseSearch params: ', JSON.stringify(params)); + dlog('*[ShopperHouseAPI] ├─ query:', query); + dlog('*[ShopperHouseAPI] ├─ searchId:', searchId === null ? '(NULL)' : searchId); + dlog('*[ShopperHouseAPI] ├─ sortingType:', sortingType === null ? '(NULL)' : sortingType); + dlog('*[ShopperHouseAPI] └─ timestamp:', new Date().toISOString()); // 🔧 [테스트용] API 실패 시뮬레이션 스위치 const SIMULATE_API_FAILURE = false; // ⭐ 이 값을 true로 변경하면 실패 시뮬레이션 if (SIMULATE_API_FAILURE) { - console.log('🧪 [TEST] API 실패 시뮬레이션 활성화 - 2초 후 실패 응답'); + dlog('🧪 [TEST] API 실패 시뮬레이션 활성화 - 2초 후 실패 응답'); // 2초 후 실패 시뮬레이션 setTimeout(() => { @@ -346,7 +343,7 @@ export const getShopperHouseSearch = }, }; - console.log('🧪 [TEST] 시뮬레이션된 실패 응답 전송'); + dlog('🧪 [TEST] 시뮬레이션된 실패 응답 전송'); onFail(simulatedError); }, 2000); // 2초 딜레이 @@ -358,8 +355,8 @@ export const getShopperHouseSearch = // ShopperHouse API 에러 처리 액션 export const setShopperHouseError = (error) => { - console.log('[ShopperHouse] ❌ [DEBUG] setShopperHouseError - 에러 정보 저장'); - console.log('[ShopperHouse] └─ error:', error); + dlog('[ShopperHouse] ❌ [DEBUG] setShopperHouseError - 에러 정보 저장'); + dlog('[ShopperHouse] └─ error:', error); return { type: types.SET_SHOPPERHOUSE_ERROR, @@ -369,8 +366,8 @@ export const setShopperHouseError = (error) => { // ShopperHouse 에러 표시 액션 (사용자에게 팝업으로 알림) export const showShopperHouseError = (error) => { - console.log('[ShopperHouse] 🔴 [DEBUG] showShopperHouseError - 에러 팝업 표시'); - console.log('[ShopperHouse] └─ error:', error); + dlog('[ShopperHouse] 🔴 [DEBUG] showShopperHouseError - 에러 팝업 표시'); + dlog('[ShopperHouse] └─ error:', error); return { type: types.SHOW_SHOPPERHOUSE_ERROR, @@ -386,7 +383,7 @@ export const showShopperHouseError = (error) => { // ShopperHouse 에러 숨김 액션 (팝업 닫기) export const hideShopperHouseError = () => { - console.log('[ShopperHouse] ✅ [DEBUG] hideShopperHouseError - 에러 팝업 숨김'); + dlog('[ShopperHouse] ✅ [DEBUG] hideShopperHouseError - 에러 팝업 숨김'); return { type: types.HIDE_SHOPPERHOUSE_ERROR, @@ -401,7 +398,12 @@ export const clearShopperHouseData = () => (dispatch, getState) => { const currentKey = currentShopperHouseData?.results?.[0]?.searchId || 'null'; const preKey = preShopperHouseData?.results?.[0]?.searchId || 'null'; - console.log('[ShopperHouse]-DIFF (before clear) shopperHouseKey:', currentKey, '| preShopperHouseKey:', preKey); + dlog( + '[ShopperHouse]-DIFF (before clear) shopperHouseKey:', + currentKey, + '| preShopperHouseKey:', + preKey + ); if (currentShopperHouseData) { dispatch({ @@ -422,7 +424,7 @@ export const clearShopperHouseData = () => (dispatch, getState) => { // Search Main 조회 IF-LGSP-097 export const getSearchMain = () => (dispatch, getState) => { const onSuccess = (response) => { - console.log('getSearchMain onSuccess: ', response.data); + dlog('getSearchMain onSuccess: ', response.data); dispatch({ type: types.GET_SEARCH_MAIN, @@ -431,7 +433,7 @@ export const getSearchMain = () => (dispatch, getState) => { }; const onFail = (error) => { - console.error('getSearchMain onFail: ', error); + derror('getSearchMain onFail: ', error); }; TAxios(dispatch, getState, 'post', URLS.GET_SEARCH_MAIN, {}, {}, onSuccess, onFail); @@ -462,7 +464,7 @@ export const clearSearchMainData = () => ({ * @returns {object} Redux action */ export const switchToSearchInputOverlay = (source = 'VoiceInputOverlay') => { - console.log('[searchActions] 🔄 switchToSearchInputOverlay 명령 발송', { + dlog('[searchActions] 🔄 switchToSearchInputOverlay 명령 발송', { source, timestamp: new Date().toISOString(), }); @@ -483,7 +485,7 @@ export const switchToSearchInputOverlay = (source = 'VoiceInputOverlay') => { * @returns {object} Redux action */ export const clearPanelCommand = () => { - console.log('[searchActions] 🧹 clearPanelCommand 호출 - 명령 초기화'); + dlog('[searchActions] 🧹 clearPanelCommand 호출 - 명령 초기화'); return { type: types.CLEAR_PANEL_COMMAND, @@ -505,31 +507,31 @@ export const clearPanelCommand = () => { export const transitionToSearchInputOverlay = (options) => async (dispatch) => { const { setIsVoiceOverlayVisible, setIsSearchOverlayVisible, Spotlight } = options; - console.log('[searchActions] 🔄 transitionToSearchInputOverlay 시작'); - console.log('[searchActions] ├─ Step 1: VoiceInputOverlay 닫기'); + dlog('[searchActions] 🔄 transitionToSearchInputOverlay 시작'); + dlog('[searchActions] ├─ Step 1: VoiceInputOverlay 닫기'); // Step 1: VoiceInputOverlay 닫기 setIsVoiceOverlayVisible(false); // Step 2: 애니메이션 대기 (300ms - VoiceInputOverlay 닫기 애니메이션) - console.log('[searchActions] ├─ Step 2: 300ms 대기 (VoiceOverlay 애니메이션)'); + dlog('[searchActions] ├─ Step 2: 300ms 대기 (VoiceOverlay 애니메이션)'); await new Promise((resolve) => setTimeout(resolve, 300)); // Step 3: SearchInputOverlay 열기 - console.log('[searchActions] ├─ Step 3: SearchInputOverlay 열기'); + dlog('[searchActions] ├─ Step 3: SearchInputOverlay 열기'); setIsSearchOverlayVisible(true); // Step 4: 렌더링 대기 (100ms - SearchInputOverlay 렌더링 및 마운트) - console.log('[searchActions] ├─ Step 4: 100ms 대기 (SearchInputOverlay 렌더링)'); + dlog('[searchActions] ├─ Step 4: 100ms 대기 (SearchInputOverlay 렌더링)'); await new Promise((resolve) => setTimeout(resolve, 100)); // Step 5: Spotlight 포커스 설정 - console.log('[searchActions] ├─ Step 5: Spotlight 포커스 설정 (search_overlay_input_box)'); + dlog('[searchActions] ├─ Step 5: Spotlight 포커스 설정 (search_overlay_input_box)'); Spotlight.focus('search_overlay_input_box'); // Step 6: 명령 초기화 - console.log('[searchActions] └─ Step 6: panelCommand 초기화'); + dlog('[searchActions] └─ Step 6: panelCommand 초기화'); dispatch(clearPanelCommand()); - console.log('[searchActions] ✅ transitionToSearchInputOverlay 완료'); + dlog('[searchActions] ✅ transitionToSearchInputOverlay 완료'); }; diff --git a/com.twin.app.shoptime/src/actions/shippingActions.js b/com.twin.app.shoptime/src/actions/shippingActions.js index aba1d659..64d543eb 100644 --- a/com.twin.app.shoptime/src/actions/shippingActions.js +++ b/com.twin.app.shoptime/src/actions/shippingActions.js @@ -1,13 +1,18 @@ -import { URLS } from "../api/apiConfig"; -import { TAxios } from "../api/TAxios"; -import { types } from "./actionTypes"; +import { URLS } from '../api/apiConfig'; +import { TAxios } from '../api/TAxios'; +import { types } from './actionTypes'; +import { createDebugHelpers } from '../utils/debug'; + +// 디버그 헬퍼 설정 +const DEBUG_MODE = false; +const { dlog, dwarn, derror } = createDebugHelpers(DEBUG_MODE); // IF-LGSP-324 회원 Shipping Address 조회 export const getMyInfoShippingSearch = (props) => (dispatch, getState) => { const { mbrNo } = props; const onSuccess = (response) => { - console.log("getmyInfoShippingSearch OnSuccess: ", response.data); + dlog('getmyInfoShippingSearch OnSuccess: ', response.data); dispatch({ type: types.GET_MY_INFO_SHIPPING_SEARCH, @@ -16,13 +21,13 @@ export const getMyInfoShippingSearch = (props) => (dispatch, getState) => { }; const onFail = (error) => { - console.error("getmyInfoShippingSearch onFail: ", error); + derror('getmyInfoShippingSearch onFail: ', error); }; TAxios( dispatch, getState, - "get", + 'get', URLS.GET_MY_INFO_SHIPPING_SEARCH, { mbrNo }, {}, diff --git a/com.twin.app.shoptime/src/actions/voiceActions.js b/com.twin.app.shoptime/src/actions/voiceActions.js index 9350d865..521e8335 100644 --- a/com.twin.app.shoptime/src/actions/voiceActions.js +++ b/com.twin.app.shoptime/src/actions/voiceActions.js @@ -3,6 +3,11 @@ import { types } from './actionTypes'; import * as lunaSend from '../lunaSend/voice'; import { FEATURE_FLAGS } from '../constants/featureFlags'; +import { createDebugHelpers } from '../utils/debug'; + +// 디버그 헬퍼 설정 +const DEBUG_MODE = false; +const { dlog, dwarn, derror } = createDebugHelpers(DEBUG_MODE); /** * Helper function to add log entries @@ -27,7 +32,7 @@ const addLog = (type, title, data, success = true) => { export const registerVoiceFramework = () => (dispatch, getState) => { // VUI Feature Flag Check if (!FEATURE_FLAGS.ENABLE_VUI) { - console.log('[Voice] VUI is disabled by feature flag'); + dlog('[Voice] VUI is disabled by feature flag'); dispatch( addLog( 'ACTION', @@ -46,7 +51,7 @@ export const registerVoiceFramework = () => (dispatch, getState) => { const isTV = typeof window === 'object' && window.PalmSystem; if (!isTV) { - console.warn('[Voice] Voice framework is only available on webOS TV platform'); + dwarn('[Voice] Voice framework is only available on webOS TV platform'); dispatch( addLog( 'ERROR', @@ -65,7 +70,7 @@ export const registerVoiceFramework = () => (dispatch, getState) => { return null; } - console.log('[Voice] Registering with voice framework...'); + dlog('[Voice] Registering with voice framework...'); // Log the request dispatch( @@ -83,8 +88,8 @@ export const registerVoiceFramework = () => (dispatch, getState) => { voiceHandler = lunaSend.registerVoiceConductor({ onSuccess: (res) => { - console.log('[Voice] ⭐ Response from voice framework:', res); - console.log('[Voice] Response details:', { + dlog('[Voice] ⭐ Response from voice framework:', res); + dlog('[Voice] Response details:', { subscribed: res.subscribed, returnValue: res.returnValue, command: res.command, @@ -114,7 +119,7 @@ export const registerVoiceFramework = () => (dispatch, getState) => { // Initial registration response if (res.subscribed && res.returnValue && !res.command) { - console.log('[Voice] Registration successful'); + dlog('[Voice] Registration successful'); dispatch( addLog('ACTION', '[Voice] ✅ Registration Successful', { message: 'Successfully registered with voice framework', @@ -130,7 +135,7 @@ export const registerVoiceFramework = () => (dispatch, getState) => { // setContext command received if (res.command === 'setContext' && res.voiceTicket) { - console.log('[Voice] setContext command received, ticket:', res.voiceTicket); + dlog('[Voice] setContext command received, ticket:', res.voiceTicket); dispatch( addLog('COMMAND', '[VoiceConductor] setContext Command Received', { command: res.command, @@ -150,7 +155,7 @@ export const registerVoiceFramework = () => (dispatch, getState) => { // performAction command received if (res.command === 'performAction' && res.action) { - console.log('[Voice] ⭐⭐⭐ performAction command received:', res.action); + dlog('[Voice] ⭐⭐⭐ performAction command received:', res.action); // ⭐ 중요: performAction 수신 성공 로그 (명확하게) dispatch( @@ -171,7 +176,7 @@ export const registerVoiceFramework = () => (dispatch, getState) => { // Get voiceTicket from Redux state (performAction response doesn't include voiceTicket) const { voiceTicket } = getState().voice; - console.log('[Voice] Using voiceTicket from state:', voiceTicket); + dlog('[Voice] Using voiceTicket from state:', voiceTicket); // Process the action and report result dispatch(handleVoiceAction(voiceTicket, res.action)); @@ -179,7 +184,7 @@ export const registerVoiceFramework = () => (dispatch, getState) => { }, onFailure: (err) => { - console.error('[Voice] Registration failed:', err); + derror('[Voice] Registration failed:', err); dispatch( addLog( 'ERROR', @@ -203,7 +208,7 @@ export const registerVoiceFramework = () => (dispatch, getState) => { }, onComplete: (res) => { - console.log('[Voice] Registration completed:', res); + dlog('[Voice] Registration completed:', res); }, }); @@ -217,21 +222,21 @@ export const registerVoiceFramework = () => (dispatch, getState) => { export const sendVoiceIntents = (voiceTicket) => (dispatch, getState) => { // VUI Feature Flag Check if (!FEATURE_FLAGS.ENABLE_VUI) { - console.log('[Voice] VUI is disabled - sendVoiceIntents skipped'); + dlog('[Voice] VUI is disabled - sendVoiceIntents skipped'); return; } - console.log('[Voice] Sending voice intents...'); + dlog('[Voice] Sending voice intents...'); // Define the intents that this app supports // This is a sample configuration - customize based on your app's features // ⭐ 디버깅 팁: UseIME이 안되면 먼저 Select/Scroll 테스트 - console.log('[Voice] ⚠️ DEBUGGING TIP:'); - console.log(' 1. UseIME might not be supported on all webOS versions'); - console.log(' 2. Try saying "Search" or "Home" to test Select intent first'); - console.log(' 3. If Select works but UseIME does not, UseIME is not supported'); - console.log(' 4. Check webOS system logs: journalctl -u voiceconductor'); + dlog('[Voice] ⚠️ DEBUGGING TIP:'); + dlog(' 1. UseIME might not be supported on all webOS versions'); + dlog(' 2. Try saying "Search" or "Home" to test Select intent first'); + dlog(' 3. If Select works but UseIME does not, UseIME is not supported'); + dlog(' 4. Check webOS system logs: journalctl -u voiceconductor'); // VoicePanel UI에도 표시 dispatch( @@ -312,7 +317,7 @@ export const sendVoiceIntents = (voiceTicket) => (dispatch, getState) => { lunaSend.setVoiceContext(voiceTicket, inAppIntents, { onSuccess: (res) => { - console.log('[Voice] Voice context set successfully:', res); + dlog('[Voice] Voice context set successfully:', res); // Log successful context setting dispatch( addLog( @@ -384,7 +389,7 @@ export const sendVoiceIntents = (voiceTicket) => (dispatch, getState) => { healthCheckCount++; const currentState = getState().voice; - console.log(`[Voice] 🏥 Subscription Health Check #${healthCheckCount}:`, { + dlog(`[Voice] 🏥 Subscription Health Check #${healthCheckCount}:`, { isRegistered: currentState.isRegistered, hasVoiceTicket: !!currentState.voiceTicket, voiceTicket: currentState.voiceTicket, @@ -408,13 +413,13 @@ export const sendVoiceIntents = (voiceTicket) => (dispatch, getState) => { // 10번 체크하면 중단 (30초) if (healthCheckCount >= 10 || currentState.lastSTTText) { clearInterval(healthCheckInterval); - console.log('[Voice] Health check completed or STT received'); + dlog('[Voice] Health check completed or STT received'); } }, 3000); }, onFailure: (err) => { - console.error('[Voice] Failed to set voice context:', err); + derror('[Voice] Failed to set voice context:', err); // Log failed context setting dispatch( addLog( @@ -440,7 +445,7 @@ export const sendVoiceIntents = (voiceTicket) => (dispatch, getState) => { }, onComplete: (res) => { - console.log('[Voice] setContext completed'); + dlog('[Voice] setContext completed'); }, }); }; @@ -450,7 +455,7 @@ export const sendVoiceIntents = (voiceTicket) => (dispatch, getState) => { * Process the action and report the result */ export const handleVoiceAction = (voiceTicket, action) => (dispatch, getState) => { - console.log('[Voice] Handling voice action:', action); + dlog('[Voice] Handling voice action:', action); // Log that we're processing the action dispatch( @@ -468,7 +473,7 @@ export const handleVoiceAction = (voiceTicket, action) => (dispatch, getState) = try { // UseIME Intent 처리 - STT 텍스트 수신 if (action.intent === 'UseIME' && action.value) { - console.log('[Voice] ⭐ STT Text received:', action.value); + dlog('[Voice] ⭐ STT Text received:', action.value); // 📝 로그: STT 텍스트 추출 과정 dispatch( @@ -511,7 +516,7 @@ export const handleVoiceAction = (voiceTicket, action) => (dispatch, getState) = } else if (action.intent === 'Scroll' && action.itemId) { result = dispatch(handleScrollIntent(action.itemId)); } else { - console.warn('[Voice] Unknown intent or missing itemId:', action); + dwarn('[Voice] Unknown intent or missing itemId:', action); result = false; feedback = { voiceUi: { @@ -520,7 +525,7 @@ export const handleVoiceAction = (voiceTicket, action) => (dispatch, getState) = }; } } catch (error) { - console.error('[Voice] Error processing action:', error); + derror('[Voice] Error processing action:', error); result = false; feedback = { voiceUi: { @@ -548,32 +553,32 @@ export const handleVoiceAction = (voiceTicket, action) => (dispatch, getState) = * Handle Select intent actions */ const handleSelectIntent = (itemId) => (dispatch, getState) => { - console.log('[Voice] Processing Select intent for:', itemId); + dlog('[Voice] Processing Select intent for:', itemId); // TODO: Implement actual navigation/action logic switch (itemId) { case 'voice-search-button': - console.log('[Voice] Navigate to Search'); + dlog('[Voice] Navigate to Search'); // dispatch(navigateToSearch()); return true; case 'voice-cart-button': - console.log('[Voice] Navigate to Cart'); + dlog('[Voice] Navigate to Cart'); // dispatch(navigateToCart()); return true; case 'voice-home-button': - console.log('[Voice] Navigate to Home'); + dlog('[Voice] Navigate to Home'); // dispatch(navigateToHome()); return true; case 'voice-mypage-button': - console.log('[Voice] Navigate to My Page'); + dlog('[Voice] Navigate to My Page'); // dispatch(navigateToMyPage()); return true; default: - console.warn('[Voice] Unknown Select itemId:', itemId); + dwarn('[Voice] Unknown Select itemId:', itemId); return false; } }; @@ -582,22 +587,22 @@ const handleSelectIntent = (itemId) => (dispatch, getState) => { * Handle Scroll intent actions */ const handleScrollIntent = (itemId) => (dispatch, getState) => { - console.log('[Voice] Processing Scroll intent for:', itemId); + dlog('[Voice] Processing Scroll intent for:', itemId); // TODO: Implement actual scroll logic switch (itemId) { case 'voice-scroll-up': - console.log('[Voice] Scroll Up'); + dlog('[Voice] Scroll Up'); // Implement scroll up logic return true; case 'voice-scroll-down': - console.log('[Voice] Scroll Down'); + dlog('[Voice] Scroll Down'); // Implement scroll down logic return true; default: - console.warn('[Voice] Unknown Scroll itemId:', itemId); + dwarn('[Voice] Unknown Scroll itemId:', itemId); return false; } }; @@ -608,7 +613,7 @@ const handleScrollIntent = (itemId) => (dispatch, getState) => { export const reportActionResult = (voiceTicket, result, feedback = null) => (dispatch, getState) => { - console.log('[Voice] Reporting action result:', { result, feedback }); + dlog('[Voice] Reporting action result:', { result, feedback }); // Log the report request dispatch( @@ -622,7 +627,7 @@ export const reportActionResult = lunaSend.reportVoiceActionResult(voiceTicket, result, feedback, { onSuccess: (res) => { - console.log('[Voice] Action result reported successfully:', res); + dlog('[Voice] Action result reported successfully:', res); // Log successful report dispatch( addLog( @@ -643,7 +648,7 @@ export const reportActionResult = }, onFailure: (err) => { - console.error('[Voice] Failed to report action result:', err); + derror('[Voice] Failed to report action result:', err); // Log failed report dispatch( addLog( @@ -664,7 +669,7 @@ export const reportActionResult = }, onComplete: (res) => { - console.log('[Voice] reportActionResult completed'); + dlog('[Voice] reportActionResult completed'); }, }); }; @@ -676,14 +681,14 @@ export const reportActionResult = export const unregisterVoiceFramework = () => (dispatch, getState) => { // VUI Feature Flag Check if (!FEATURE_FLAGS.ENABLE_VUI) { - console.log('[Voice] VUI is disabled - unregisterVoiceFramework skipped'); + dlog('[Voice] VUI is disabled - unregisterVoiceFramework skipped'); return; } const { voiceHandler } = getState().voice; const isTV = typeof window === 'object' && window.PalmSystem; - console.log('[Voice] Unregistering from voice framework'); + dlog('[Voice] Unregistering from voice framework'); dispatch( addLog('ACTION', '[Voice] 🔌 Unregistering Voice Framework', { diff --git a/com.twin.app.shoptime/src/actions/webSpeechActions.js b/com.twin.app.shoptime/src/actions/webSpeechActions.js index 006d6a0e..c5bfc265 100644 --- a/com.twin.app.shoptime/src/actions/webSpeechActions.js +++ b/com.twin.app.shoptime/src/actions/webSpeechActions.js @@ -2,6 +2,11 @@ import { types } from './actionTypes'; import webSpeechService from '../services/webSpeech/WebSpeechService'; +import { createDebugHelpers } from '../utils/debug'; + +// 디버그 헬퍼 설정 +const DEBUG_MODE = false; +const { dlog, dwarn, derror } = createDebugHelpers(DEBUG_MODE); /** * Web Speech 초기화 및 시작 @@ -10,12 +15,12 @@ import webSpeechService from '../services/webSpeech/WebSpeechService'; export const initializeWebSpeech = (config = {}) => (dispatch) => { - console.log('[VoiceInput]-[WebSpeech] ACTION-INIT: 초기화 시작'); + dlog('[VoiceInput]-[WebSpeech] ACTION-INIT: 초기화 시작'); // 지원 여부 확인 if (!webSpeechService.isSupported) { const error = 'Web Speech API is not supported in this browser'; - console.error('[VoiceInput]-[WebSpeech] ACTION-INIT: ❌ Web Speech API 미지원'); + derror('[VoiceInput]-[WebSpeech] ACTION-INIT: ❌ Web Speech API 미지원'); dispatch({ type: types.WEB_SPEECH_ERROR, payload: { error, message: error }, @@ -32,7 +37,7 @@ export const initializeWebSpeech = }); if (!initialized) { - console.error('[VoiceInput]-[WebSpeech] ACTION-INIT: ❌ 초기화 실패'); + derror('[VoiceInput]-[WebSpeech] ACTION-INIT: ❌ 초기화 실패'); dispatch({ type: types.WEB_SPEECH_ERROR, payload: { error: 'Failed to initialize', message: 'Failed to initialize Web Speech' }, @@ -42,14 +47,14 @@ export const initializeWebSpeech = // 이벤트 핸들러 등록 webSpeechService.on('start', () => { - console.log('[VoiceInput]-[WebSpeech] ACTION-EVENT: WEB_SPEECH_START 디스패치'); + dlog('[VoiceInput]-[WebSpeech] ACTION-EVENT: WEB_SPEECH_START 디스패치'); dispatch({ type: types.WEB_SPEECH_START, }); }); webSpeechService.on('result', (result) => { - console.log( + dlog( `[VoiceInput]-[WebSpeech] ACTION-EVENT: result 수신 - isFinal=${result.isFinal}, text="${result.transcript}"` ); @@ -62,7 +67,7 @@ export const initializeWebSpeech = // ✅ Final 결과 처리 추가 (TV 환경 대응) // TV에서는 final result가 와야 API 호출이 가능할 수 있음 if (result.isFinal) { - console.log( + dlog( `[VoiceInput]-[WebSpeech] ACTION-EVENT: WEB_SPEECH_FINAL_RESULT 디스패치 - finalText="${result.transcript}"` ); dispatch({ @@ -76,7 +81,7 @@ export const initializeWebSpeech = }); webSpeechService.on('error', (errorInfo) => { - console.error( + derror( `[VoiceInput]-[WebSpeech] ACTION-EVENT: WEB_SPEECH_ERROR 디스패치 - error="${errorInfo.error}"` ); dispatch({ @@ -86,13 +91,13 @@ export const initializeWebSpeech = }); webSpeechService.on('end', () => { - console.log('[VoiceInput]-[WebSpeech] ACTION-EVENT: WEB_SPEECH_END 디스패치'); + dlog('[VoiceInput]-[WebSpeech] ACTION-EVENT: WEB_SPEECH_END 디스패치'); dispatch({ type: types.WEB_SPEECH_END, }); }); - console.log('[VoiceInput]-[WebSpeech] ACTION-INIT: ✅ WEB_SPEECH_INITIALIZED 디스패치'); + dlog('[VoiceInput]-[WebSpeech] ACTION-INIT: ✅ WEB_SPEECH_INITIALIZED 디스패치'); dispatch({ type: types.WEB_SPEECH_INITIALIZED, }); @@ -104,11 +109,11 @@ export const initializeWebSpeech = * 음성 인식 시작 */ export const startWebSpeech = () => (dispatch) => { - console.log('[VoiceInput]-[WebSpeech] ACTION-START: 음성 인식 시작 요청'); + dlog('[VoiceInput]-[WebSpeech] ACTION-START: 음성 인식 시작 요청'); const started = webSpeechService.start(); if (!started) { - console.error('[VoiceInput]-[WebSpeech] ACTION-START: ❌ 음성 인식 시작 실패'); + derror('[VoiceInput]-[WebSpeech] ACTION-START: ❌ 음성 인식 시작 실패'); dispatch({ type: types.WEB_SPEECH_ERROR, payload: { error: 'Failed to start', message: 'Failed to start recognition' }, @@ -120,7 +125,7 @@ export const startWebSpeech = () => (dispatch) => { * 음성 인식 중지 */ export const stopWebSpeech = () => (dispatch) => { - console.log('[VoiceInput]-[WebSpeech] ACTION-STOP: 음성 인식 중지 요청'); + dlog('[VoiceInput]-[WebSpeech] ACTION-STOP: 음성 인식 중지 요청'); webSpeechService.stop(); }; @@ -128,7 +133,7 @@ export const stopWebSpeech = () => (dispatch) => { * 음성 인식 중단 */ export const abortWebSpeech = () => (dispatch) => { - console.log('[VoiceInput]-[WebSpeech] ACTION-ABORT: 음성 인식 중단 (즉시) 요청'); + dlog('[VoiceInput]-[WebSpeech] ACTION-ABORT: 음성 인식 중단 (즉시) 요청'); webSpeechService.abort(); }; @@ -136,21 +141,21 @@ export const abortWebSpeech = () => (dispatch) => { * 리소스 정리 */ export const cleanupWebSpeech = () => (dispatch) => { - console.log('[VoiceInput]-[WebSpeech] ACTION-CLEANUP: 리소스 정리 요청'); + dlog('[VoiceInput]-[WebSpeech] ACTION-CLEANUP: 리소스 정리 요청'); webSpeechService.cleanup(); dispatch({ type: types.WEB_SPEECH_CLEANUP, }); - console.log('[VoiceInput]-[WebSpeech] ACTION-CLEANUP: ✅ WEB_SPEECH_CLEANUP 디스패치'); + dlog('[VoiceInput]-[WebSpeech] ACTION-CLEANUP: ✅ WEB_SPEECH_CLEANUP 디스패치'); }; /** * STT 텍스트 초기화 (이전 음성 인식 결과 제거) */ export const clearSTTText = () => (dispatch) => { - console.log('[VoiceInput]-[WebSpeech] ACTION-CLEAR: STT 텍스트 초기화 요청'); + dlog('[VoiceInput]-[WebSpeech] ACTION-CLEAR: STT 텍스트 초기화 요청'); dispatch({ type: types.VOICE_CLEAR_STATE, }); - console.log('[VoiceInput]-[WebSpeech] ACTION-CLEAR: ✅ VOICE_CLEAR_STATE 디스패치'); + dlog('[VoiceInput]-[WebSpeech] ACTION-CLEAR: ✅ VOICE_CLEAR_STATE 디스패치'); }; diff --git a/com.twin.app.shoptime/src/reducers/localSettingsReducer.js b/com.twin.app.shoptime/src/reducers/localSettingsReducer.js index 21be174f..b3f71b9a 100644 --- a/com.twin.app.shoptime/src/reducers/localSettingsReducer.js +++ b/com.twin.app.shoptime/src/reducers/localSettingsReducer.js @@ -1,7 +1,12 @@ -import { types } from "../actions/actionTypes"; -import { SHOPTIME_BASE_URL } from "../api/apiConfig"; -import * as Config from "../utils/Config"; -import { readLocalStorage, writeLocalStorage } from "../utils/helperMethods"; +import { types } from '../actions/actionTypes'; +import { SHOPTIME_BASE_URL } from '../api/apiConfig'; +import * as Config from '../utils/Config'; +import { readLocalStorage, writeLocalStorage } from '../utils/helperMethods'; +import { createDebugHelpers } from '../utils/debug'; + +// 디버그 헬퍼 설정 +const DEBUG_MODE = false; +const { dlog, dwarn, derror } = createDebugHelpers(DEBUG_MODE); export const initialLocalSettings = { version: 1, // if version changed data will be deleted @@ -10,9 +15,9 @@ export const initialLocalSettings = { accessToken: null, refreshToken: null, phoneNumbers: {}, - logEnable: typeof window === "object" && !window.PalmSystem, + logEnable: typeof window === 'object' && !window.PalmSystem, recentItems: [], - languageSetting: "system", //US, GB, DE, RU + languageSetting: 'system', //US, GB, DE, RU watchRecord: {}, oldDb8Deleted: false, skipEndOfServicePopup: false, @@ -23,10 +28,7 @@ const updateAWithBKeys = (A, B) => { for (const key in B) { if (Object.prototype.hasOwnProperty.call(B, key)) { // B에만 존재하는 키를 A에 업데이트 - if ( - !Object.prototype.hasOwnProperty.call(A, key) || - A[key] === undefined - ) { + if (!Object.prototype.hasOwnProperty.call(A, key) || A[key] === undefined) { A[key] = B[key]; } } @@ -34,49 +36,52 @@ const updateAWithBKeys = (A, B) => { return A; }; const updateInitialLocalSettings = () => { - let data = readLocalStorage("localSettings", initialLocalSettings); + let data = readLocalStorage('localSettings', initialLocalSettings); // pc 에서 web hotsting 서버에 접속시 서버 변경을 제한한다. - if( typeof window === "object" && !window.PalmSystem && window.location.href.indexOf(SHOPTIME_BASE_URL) > 0){ + if ( + typeof window === 'object' && + !window.PalmSystem && + window.location.href.indexOf(SHOPTIME_BASE_URL) > 0 + ) { data.preventServerChange = true; - let hrefUrl = window.location.href.split(".")[0]; - if (hrefUrl.indexOf("qt2") >= 0) { + let hrefUrl = window.location.href.split('.')[0]; + if (hrefUrl.indexOf('qt2') >= 0) { data.serverType = 'qt2'; - } else if (hrefUrl.indexOf("qt") >= 0) { + } else if (hrefUrl.indexOf('qt') >= 0) { data.serverType = 'qt'; } else { data.serverType = 'prd'; } - data.ricCodeSetting = hrefUrl.split("-")[1] ?? hrefUrl.split("//")[1]; - if(data.ricCodeSetting === 'aic'){ + data.ricCodeSetting = hrefUrl.split('-')[1] ?? hrefUrl.split('//')[1]; + if (data.ricCodeSetting === 'aic') { data.languageSetting = 'US'; - }else if(data.ricCodeSetting === 'eic' && (data.languageSetting !== 'GB' && data.languageSetting !== 'DE')){ + } else if ( + data.ricCodeSetting === 'eic' && + data.languageSetting !== 'GB' && + data.languageSetting !== 'DE' + ) { data.languageSetting = 'GB'; - }else if(data.ricCodeSetting === 'ruc'){ + } else if (data.ricCodeSetting === 'ruc') { data.languageSetting = 'RU'; } } if (data.version !== initialLocalSettings.version) { - console.log( - "localSettingsReducer version updated. All datas are initialized." - ); + dlog('localSettingsReducer version updated. All datas are initialized.'); data = initialLocalSettings; - writeLocalStorage("localSettings", initialLocalSettings); + writeLocalStorage('localSettings', initialLocalSettings); } else { updateAWithBKeys(data, initialLocalSettings); } return data; }; -export const localSettingsReducer = ( - state = updateInitialLocalSettings(), - action -) => { +export const localSettingsReducer = (state = updateInitialLocalSettings(), action) => { switch (action.type) { case types.CHANGE_LOCAL_SETTINGS: { const newState = Object.assign({}, state, action.payload); - writeLocalStorage("localSettings", newState); + writeLocalStorage('localSettings', newState); return newState; } default: diff --git a/com.twin.app.shoptime/src/reducers/mediaOverlayReducer.js b/com.twin.app.shoptime/src/reducers/mediaOverlayReducer.js index e538ace1..4ff59a0c 100644 --- a/com.twin.app.shoptime/src/reducers/mediaOverlayReducer.js +++ b/com.twin.app.shoptime/src/reducers/mediaOverlayReducer.js @@ -1,5 +1,10 @@ // Media Overlay Reducer - 3 Layer 구조(MediaPanel + MediaPlayer)용 overlay 상태 관리 import { MEDIA_OVERLAY_ACTIONS } from '../actions/mediaOverlayActions'; +import { createDebugHelpers } from '../utils/debug'; + +// 디버그 헬퍼 설정 +const DEBUG_MODE = false; +const { dlog, dwarn, derror } = createDebugHelpers(DEBUG_MODE); export const initialState = { // Media Overlay Controls 상태 @@ -86,10 +91,13 @@ const handlers = { lastAction: MEDIA_OVERLAY_ACTIONS.SET_MEDIA_CONTROLS_TOGGLE, }; - console.log('🔄 [mediaOverlayReducer.SET_MEDIA_CONTROLS_TOGGLE] 상태 변화'); - console.log('🔄 [mediaOverlayReducer.SET_MEDIA_CONTROLS_TOGGLE] 이전 visible:', isCurrentlyVisible); - console.log('🔄 [mediaOverlayReducer.SET_MEDIA_CONTROLS_TOGGLE] 이후 visible:', newState.controls.visible); - console.log('🔄 [mediaOverlayReducer.SET_MEDIA_CONTROLS_TOGGLE] 전체 상태:', newState); + dlog('🔄 [mediaOverlayReducer.SET_MEDIA_CONTROLS_TOGGLE] 상태 변화'); + dlog('🔄 [mediaOverlayReducer.SET_MEDIA_CONTROLS_TOGGLE] 이전 visible:', isCurrentlyVisible); + dlog( + '🔄 [mediaOverlayReducer.SET_MEDIA_CONTROLS_TOGGLE] 이후 visible:', + newState.controls.visible + ); + dlog('🔄 [mediaOverlayReducer.SET_MEDIA_CONTROLS_TOGGLE] 전체 상태:', newState); return newState; }, @@ -165,4 +173,4 @@ export const mediaOverlayReducer = (state = initialState, action = {}) => { } return state; -}; \ No newline at end of file +}; diff --git a/com.twin.app.shoptime/src/reducers/mockCartReducer.js b/com.twin.app.shoptime/src/reducers/mockCartReducer.js index df0b8a96..65ee394a 100644 --- a/com.twin.app.shoptime/src/reducers/mockCartReducer.js +++ b/com.twin.app.shoptime/src/reducers/mockCartReducer.js @@ -1,4 +1,9 @@ import { MOCK_CART_TYPES } from '../actions/mockCartActions'; +import { createDebugHelpers } from '../utils/debug'; + +// 디버그 헬퍼 설정 +const DEBUG_MODE = false; +const { dlog, dwarn, derror } = createDebugHelpers(DEBUG_MODE); // 브라우저 환경 확인 const isBrowser = typeof window !== 'undefined' && typeof window.localStorage !== 'undefined'; @@ -43,7 +48,7 @@ const saveToLocalStorage = (state) => { }; window.localStorage.setItem(MOCK_CART_STORAGE_KEY, JSON.stringify(dataToSave)); } catch (error) { - console.error('[MockCartReducer] localStorage 저장 실패:', error); + derror('[MockCartReducer] localStorage 저장 실패:', error); } }; @@ -67,7 +72,7 @@ const loadFromLocalStorage = () => { }; } } catch (error) { - console.error('[MockCartReducer] localStorage 로드 실패:', error); + derror('[MockCartReducer] localStorage 로드 실패:', error); } return initialState; }; @@ -79,13 +84,12 @@ const loadFromLocalStorage = () => { * @returns {Object} 중복 여부와 기존 아이템 인덱스 */ const findDuplicateItem = (cartItems, newItem) => { - const index = cartItems.findIndex(item => - item.prdtId === newItem.prdtId && - item.optNm === newItem.optNm + const index = cartItems.findIndex( + (item) => item.prdtId === newItem.prdtId && item.optNm === newItem.optNm ); return { isDuplicate: index !== -1, - index + index, }; }; @@ -105,7 +109,7 @@ const calculateTotals = (cartItems) => { return { totalQuantity, - totalPrice: parseFloat(totalPrice.toFixed(2)) + totalPrice: parseFloat(totalPrice.toFixed(2)), }; }; @@ -145,12 +149,12 @@ export const mockCartReducer = (state = loadFromLocalStorage(), action) => { const currentQty = updatedItems[index].prodQty || updatedItems[index].qty || 1; const newQty = item.prodQty || item.qty || 1; - console.log('[MockCartReducer] Quantity update - Current:', currentQty, 'Adding:', newQty); + dlog('[MockCartReducer] Quantity update - Current:', currentQty, 'Adding:', newQty); updatedItems[index] = { ...updatedItems[index], prodQty: currentQty + newQty, - qty: currentQty + newQty // qty 필드도 동기화 + qty: currentQty + newQty, // qty 필드도 동기화 }; } else { // 새 상품 추가 @@ -173,7 +177,7 @@ export const mockCartReducer = (state = loadFromLocalStorage(), action) => { case MOCK_CART_TYPES.REMOVE_FROM_MOCK_CART: { const { prodSno } = action.payload; - const updatedItems = state.cartInfo.filter(item => item.prodSno !== prodSno); + const updatedItems = state.cartInfo.filter((item) => item.prodSno !== prodSno); const newState = { ...state, @@ -191,11 +195,11 @@ export const mockCartReducer = (state = loadFromLocalStorage(), action) => { case MOCK_CART_TYPES.UPDATE_MOCK_CART_ITEM: { const { prodSno, quantity } = action.payload; - const updatedItems = state.cartInfo.map(item => { + const updatedItems = state.cartInfo.map((item) => { if (item.prodSno === prodSno) { return { ...item, - prodQty: Math.max(1, quantity) // 최소 1개 보장 + prodQty: Math.max(1, quantity), // 최소 1개 보장 }; } return item; @@ -220,7 +224,7 @@ export const mockCartReducer = (state = loadFromLocalStorage(), action) => { if (quantity <= 0) { // 수량이 0이면 상품 제거 - const updatedItems = state.cartInfo.filter(item => item.prodSno !== prodSno); + const updatedItems = state.cartInfo.filter((item) => item.prodSno !== prodSno); const newState = { ...state, @@ -236,11 +240,11 @@ export const mockCartReducer = (state = loadFromLocalStorage(), action) => { return newState; } - const updatedItems = state.cartInfo.map(item => { + const updatedItems = state.cartInfo.map((item) => { if (item.prodSno === prodSno) { return { ...item, - prodQty: quantity + prodQty: quantity, }; } return item; @@ -295,4 +299,4 @@ export const mockCartReducer = (state = loadFromLocalStorage(), action) => { default: return state; } -}; \ No newline at end of file +}; diff --git a/com.twin.app.shoptime/src/reducers/playReducer.js b/com.twin.app.shoptime/src/reducers/playReducer.js index 93c6aea7..dbe0a67c 100644 --- a/com.twin.app.shoptime/src/reducers/playReducer.js +++ b/com.twin.app.shoptime/src/reducers/playReducer.js @@ -1,5 +1,10 @@ import { types } from '../actions/actionTypes'; import { PLAYBACK_STATUS, DISPLAY_STATUS } from '../actions/playActions'; +import { createDebugHelpers } from '../utils/debug'; + +// 디버그 헬퍼 설정 +const DEBUG_MODE = false; +const { dlog, dwarn, derror } = createDebugHelpers(DEBUG_MODE); const initialState = { subTitleBlobs: {}, @@ -103,7 +108,7 @@ export const playReducer = (state = initialState, action) => { }); if (hasImportantChange) { - console.log('🔄 [Redux Reducer] VIDEO PLAY STATE CRITICAL CHANGE', { + dlog('🔄 [Redux Reducer] VIDEO PLAY STATE CRITICAL CHANGE', { previousPaused: state.videoPlayState?.isPaused, newPaused: newState.isPaused, previousPlaying: state.videoPlayState?.isPlaying, diff --git a/com.twin.app.shoptime/src/reducers/productReducer.js b/com.twin.app.shoptime/src/reducers/productReducer.js index 9cc69689..b803a33e 100644 --- a/com.twin.app.shoptime/src/reducers/productReducer.js +++ b/com.twin.app.shoptime/src/reducers/productReducer.js @@ -1,5 +1,10 @@ import { types } from '../actions/actionTypes'; import { curry, get, set } from '../utils/fp'; +import { createDebugHelpers } from '../utils/debug'; + +// 디버그 헬퍼 설정 +const DEBUG_MODE = false; +const { dlog, dwarn, derror } = createDebugHelpers(DEBUG_MODE); const initialState = { bestSellerData: {}, @@ -61,11 +66,11 @@ const handleUserReviewList = curry((state, action) => { const reviewListData = get('payload', action); const prdtId = get(['payload', 'prdtId'], action); - console.log('[productReducer_useReviewList] 🟡 handleUserReviewList:', { + dlog('[productReducer_useReviewList] 🟡 handleUserReviewList:', { prdtId, reviewListDataKeys: reviewListData ? Object.keys(reviewListData) : 'null', reviewListLength: reviewListData?.reviewList?.length || 0, - reviewDetail: reviewListData?.reviewDetail + reviewDetail: reviewListData?.reviewDetail, }); return set('reviewListData', reviewListData, set('loadedListPrdtId', prdtId, state)); @@ -89,11 +94,11 @@ const handleReviewFilters = curry((state, action) => { const reviewFiltersData = get('payload', action); const prdtId = get(['payload', 'prdtId'], action); - console.log('[productReducer_reviewFilters] 🟡 handleReviewFilters:', { + dlog('[productReducer_reviewFilters] 🟡 handleReviewFilters:', { prdtId, reviewFiltersDataKeys: reviewFiltersData ? Object.keys(reviewFiltersData) : 'null', filtersLength: reviewFiltersData?.filters?.length || 0, - filters: reviewFiltersData?.filters + filters: reviewFiltersData?.filters, }); return set('reviewFiltersData', reviewFiltersData, set('loadedFiltersPrdtId', prdtId, state)); @@ -105,11 +110,13 @@ const handleFilteredReviewList = curry((state, action) => { const filterTpCd = get(['payload', 'filterTpCd'], action); const filterTpVal = get(['payload', 'filterTpVal'], action); - console.log('[productReducer_filteredReviewList] 🟡 handleFilteredReviewList:', { + dlog('[productReducer_filteredReviewList] 🟡 handleFilteredReviewList:', { filterTpCd, filterTpVal, - filteredReviewListDataKeys: filteredReviewListData ? Object.keys(filteredReviewListData) : 'null', - reviewListLength: filteredReviewListData?.reviewList?.length || 0 + filteredReviewListDataKeys: filteredReviewListData + ? Object.keys(filteredReviewListData) + : 'null', + reviewListLength: filteredReviewListData?.reviewList?.length || 0, }); // filteredReviewListData와 currentReviewFilter 모두 업데이트 @@ -125,7 +132,9 @@ const handleFilteredReviewList = curry((state, action) => { // All Star 필터 해제 핸들러 - 필터 상태와 필터링된 데이터를 초기화 // ✅ CRITICAL FIX: reviewListData도 함께 초기화하여 Back 시 재로드되도록 함 const handleClearReviewFilter = (state, action) => { - console.log('[productReducer_clearReviewFilter] 🟡 handleClearReviewFilter: 필터 해제됨 + 리뷰 데이터 초기화'); + dlog( + '[productReducer_clearReviewFilter] 🟡 handleClearReviewFilter: 필터 해제됨 + 리뷰 데이터 초기화' + ); let newState = state; // 캐시 ID 초기화 (다시 로드되도록) @@ -163,12 +172,12 @@ export const productReducer = (state = initialState, action = {}) => { // v2 디버깅: GET_USER_REVIEW_LIST 액션 확인 if (type === 'GET_USER_REVIEW_LIST') { - console.log('[productReducer_useReviewList] 🟢 GET_USER_REVIEW_LIST 액션 수신:', { + dlog('[productReducer_useReviewList] 🟢 GET_USER_REVIEW_LIST 액션 수신:', { actionType: type, payloadKeys: action.payload ? Object.keys(action.payload) : 'null', reviewListLength: action.payload?.reviewList?.length || 0, prdtId: action.payload?.prdtId, - handler: !!handler + handler: !!handler, }); } @@ -176,11 +185,11 @@ export const productReducer = (state = initialState, action = {}) => { // v2 디버깅: 상태 업데이트 확인 if (type === 'GET_USER_REVIEW_LIST') { - console.log('[productReducer_useReviewList] 🔵 상태 업데이트 완료:', { + dlog('[productReducer_useReviewList] 🔵 상태 업데이트 완료:', { reviewListDataExists: !!newState.reviewListData, reviewListDataKeys: newState.reviewListData ? Object.keys(newState.reviewListData) : 'null', loadedListPrdtId: newState.loadedListPrdtId, - reviewListLength: newState.reviewListData?.reviewList?.length || 0 + reviewListLength: newState.reviewListData?.reviewList?.length || 0, }); } diff --git a/com.twin.app.shoptime/src/reducers/videoOverlayReducer.js b/com.twin.app.shoptime/src/reducers/videoOverlayReducer.js index a9c5c7bf..7a7f3471 100644 --- a/com.twin.app.shoptime/src/reducers/videoOverlayReducer.js +++ b/com.twin.app.shoptime/src/reducers/videoOverlayReducer.js @@ -1,5 +1,10 @@ // Video Overlay Reducer - modal=true 상태에서 비디오 오버레이 제어 import { VIDEO_OVERLAY_ACTIONS } from '../actions/videoOverlayActions'; +import { createDebugHelpers } from '../utils/debug'; + +// 디버그 헬퍼 설정 +const DEBUG_MODE = false; +const { dlog, dwarn, derror } = createDebugHelpers(DEBUG_MODE); export const initialState = { // Modal 상태 @@ -111,10 +116,10 @@ const handlers = { lastAction: VIDEO_OVERLAY_ACTIONS.TOGGLE_CONTROLS, }; - console.log('🔄 [videoOverlayReducer.TOGGLE_CONTROLS] 상태 변화'); - console.log('🔄 [videoOverlayReducer.TOGGLE_CONTROLS] 이전 visible:', isCurrentlyVisible); - console.log('🔄 [videoOverlayReducer.TOGGLE_CONTROLS] 이후 visible:', newState.controls.visible); - console.log('🔄 [videoOverlayReducer.TOGGLE_CONTROLS] 전체 상태:', newState); + dlog('🔄 [videoOverlayReducer.TOGGLE_CONTROLS] 상태 변화'); + dlog('🔄 [videoOverlayReducer.TOGGLE_CONTROLS] 이전 visible:', isCurrentlyVisible); + dlog('🔄 [videoOverlayReducer.TOGGLE_CONTROLS] 이후 visible:', newState.controls.visible); + dlog('🔄 [videoOverlayReducer.TOGGLE_CONTROLS] 전체 상태:', newState); return newState; }, diff --git a/com.twin.app.shoptime/src/views/UserReview/ShowUserReviews.jsx b/com.twin.app.shoptime/src/views/UserReview/ShowUserReviews.jsx index 148656dc..92a6df5e 100644 --- a/com.twin.app.shoptime/src/views/UserReview/ShowUserReviews.jsx +++ b/com.twin.app.shoptime/src/views/UserReview/ShowUserReviews.jsx @@ -1,26 +1,22 @@ -import React, { - useCallback, - useEffect, -} from 'react'; +import React, { useCallback, useEffect } from 'react'; -import { - useDispatch, - useSelector, -} from 'react-redux'; +import { useDispatch, useSelector } from 'react-redux'; import Spotlight from '@enact/spotlight'; import Spottable from '@enact/spotlight/Spottable'; import { finishMediaPreview } from '../../actions/mediaActions'; -import { - popPanel, - pushPanel, -} from '../../actions/panelActions'; +import { popPanel, pushPanel } from '../../actions/panelActions'; import { clearAllVideoTimers } from '../../actions/playActions'; import useReviews, { REVIEW_VERSION } from '../../hooks/useReviews/useReviews'; import { panel_names } from '../../utils/Config'; +import { createDebugHelpers } from '../../utils/debug'; import css from './ShowUserReviews.module.less'; +// 디버그 헬퍼 설정 +const DEBUG_MODE = false; +const { dlog, dwarn, derror } = createDebugHelpers(DEBUG_MODE); + const SpottableComponent = Spottable('div'); const ShowUserReviews = ({ hasVideo, launchedFromPlayer, onFocus, onBlur }) => { @@ -37,14 +33,14 @@ const ShowUserReviews = ({ hasVideo, launchedFromPlayer, onFocus, onBlur }) => { const { stats } = useReviews(productData && productData.prdtId); const handleShowUserReviewsClick = useCallback(() => { - console.log('[ShowUserReviews] 🎯 Show User Reviews 버튼 클릭:', { + dlog('[ShowUserReviews] 🎯 Show User Reviews 버튼 클릭:', { reviewVersion: REVIEW_VERSION, reviewListDataLength: reviewListData?.length || 0, statsAvgRating: stats?.averageRating, - statsTotalReviews: stats?.totalReviews + statsTotalReviews: stats?.totalReviews, }); - - dispatch(popPanel(panel_names.PLAYER_PANEL)); // PlayerPanel 제거 + + dispatch(popPanel(panel_names.PLAYER_PANEL)); // PlayerPanel 제거 dispatch( pushPanel({ @@ -72,7 +68,7 @@ const ShowUserReviews = ({ hasVideo, launchedFromPlayer, onFocus, onBlur }) => { const handleKeyDown = useCallback((event) => { if (event.key === 'ArrowUp') { - console.log('[ShowUserReviews] ArrowUp key pressed - attempting to focus last review'); + dlog('[ShowUserReviews] ArrowUp key pressed - attempting to focus last review'); const container = document.querySelector('[data-spotlight-id="user-reviews-container"]'); const savedScrollTop = container?.scrollTop || 0; @@ -82,17 +78,17 @@ const ShowUserReviews = ({ hasVideo, launchedFromPlayer, onFocus, onBlur }) => { '[data-spotlight-id="user-review-at-last"]' ); if (lastReviewElement) { - console.log('[ShowUserReviews] Found last review element, focusing...'); + dlog('[ShowUserReviews] Found last review element, focusing...'); Spotlight.focus(lastReviewElement); if (container) container.scrollTop = savedScrollTop; } else { - console.log('[ShowUserReviews] Last review element not found, trying alternative...'); + dlog('[ShowUserReviews] Last review element not found, trying alternative...'); const reviewElements = document.querySelectorAll('[data-spotlight-id^="user-review-"]'); if (reviewElements.length > 0) { const lastElement = reviewElements[reviewElements.length - 1]; - console.log('[ShowUserReviews] Focusing last review element (alternative method)'); + dlog('[ShowUserReviews] Focusing last review element (alternative method)'); Spotlight.focus(lastElement); if (container) container.scrollTop = savedScrollTop; @@ -103,7 +99,7 @@ const ShowUserReviews = ({ hasVideo, launchedFromPlayer, onFocus, onBlur }) => { }, []); // useEffect(() => { - // console.log('[ShowUserReviews_v2] 컴포넌트 마운트/업데이트', { + // dlog('[ShowUserReviews_v2] 컴포넌트 마운트/업데이트', { // hasReviewData: !!reviewListData, // reviewCount: reviewListData?.length || 0, // statsTotalReviews: stats?.totalReviews, @@ -115,7 +111,7 @@ const ShowUserReviews = ({ hasVideo, launchedFromPlayer, onFocus, onBlur }) => { // v2 API 데이터로 렌더링 조건 수정: 5개 이상일 때만 보이기 if (!reviewListData || reviewListData.length <= 5) { - // console.log('[ShowUserReviews_v2] ❌ 버튼 숨김:', { + // dlog('[ShowUserReviews_v2] ❌ 버튼 숨김:', { // reason: !reviewListData ? 'reviewListData가 없음' : 'reviewListData.length <= 5', // reviewListLength: reviewListData?.length || 0 // }); @@ -124,7 +120,7 @@ const ShowUserReviews = ({ hasVideo, launchedFromPlayer, onFocus, onBlur }) => { return (
- {/* {console.log('[ShowUserReviews_v2] ✅ 버튼 렌더링 시작:', { + {/* {dlog('[ShowUserReviews_v2] ✅ 버튼 렌더링 시작:', { reviewListLength: reviewListData?.length, version: REVIEW_VERSION })} */} diff --git a/com.twin.app.shoptime/src/views/UserReview/UserReviewPanel.jsx b/com.twin.app.shoptime/src/views/UserReview/UserReviewPanel.jsx index 386d7ccb..f87c182b 100644 --- a/com.twin.app.shoptime/src/views/UserReview/UserReviewPanel.jsx +++ b/com.twin.app.shoptime/src/views/UserReview/UserReviewPanel.jsx @@ -10,6 +10,7 @@ import TPanel from '../../components/TPanel/TPanel'; import useReviews, { REVIEW_VERSION } from '../../hooks/useReviews/useReviews'; import fp from '../../utils/fp'; import { panel_names } from '../../utils/Config'; +import { createDebugHelpers } from '../../utils/debug'; import StarRating from '../DetailPanel/components/StarRating'; import UserReviewsPopup from '../DetailPanel/ProductContentSection/UserReviews/UserReviewsPopup/UserReviewsPopup'; import FilterItemButton from './components/FilterItemButton'; @@ -17,9 +18,13 @@ import UserReviewsList from './components/UserReviewsList'; import UserReviewHeader from './UserReviewHeader'; import css from './UserReviewPanel.module.less'; +// 디버그 헬퍼 설정 +const DEBUG_MODE = false; +const { dlog, dwarn, derror } = createDebugHelpers(DEBUG_MODE); + // 버전에 따른 UI 설정 const VERSION_LABEL = REVIEW_VERSION === 1 ? '[v1 - 기존 API]' : '[v2 - 신 API]'; -console.log('[UserReviewPanel] 🔧 REVIEW_VERSION:', REVIEW_VERSION, VERSION_LABEL); +dlog('[UserReviewPanel] 🔧 REVIEW_VERSION:', REVIEW_VERSION, VERSION_LABEL); const UserReviewPanel = ({ className, panelInfo, spotlightId }) => { const dispatch = useDispatch(); @@ -49,10 +54,10 @@ const UserReviewPanel = ({ className, panelInfo, spotlightId }) => { currentReviewFilter, // 전체 리뷰 데이터 (팝업용) allReviews, - filteredReviews, // ✅ 필터링된 전체 리뷰 (팝업에서 사용) + filteredReviews, // ✅ 필터링된 전체 리뷰 (팝업에서 사용) getReviewsWithImages, extractImagesFromReviews, - } = useReviews(prdtId, patnrId); // REVIEW_VERSION 상수에 따라 자동으로 API 선택 + } = useReviews(prdtId, patnrId); // REVIEW_VERSION 상수에 따라 자동으로 API 선택 const [isPaging, setIsPaging] = useState(false); const [forceScrollToTop, setForceScrollToTop] = useState(false); @@ -119,32 +124,32 @@ const UserReviewPanel = ({ className, panelInfo, spotlightId }) => { const filteredCount = stats.filteredCount || 0; const avgRating = stats.averageRating || 5; - console.log('[UserReviewPanel] 📊 ReviewCount:', { + dlog('[UserReviewPanel] 📊 ReviewCount:', { reviewCount, filteredCount, avgRating, isFilterActive: !!currentReviewFilter, _isFilterActive: stats._isFilterActive, - _activeSource: stats._activeSource + _activeSource: stats._activeSource, }); // API 기반 RATING 필터 데이터 추출 (IF-LGSP-100) // ✅ 필터 버튼의 개수는 초기 IF-LGSP-100 기반으로 절대 변경되지 않음 const ratingFilterData = React.useMemo(() => { if (!filters || !Array.isArray(filters)) { - console.log('[UserReviewPanel] ⚠️ filters 데이터 없음'); + dlog('[UserReviewPanel] ⚠️ filters 데이터 없음'); return {}; } const ratingFilter = filters.find((f) => f.filterTpCd === 'RATING'); if (!ratingFilter) { - console.log('[UserReviewPanel] ⚠️ RATING 필터 데이터 없음'); + dlog('[UserReviewPanel] ⚠️ RATING 필터 데이터 없음'); return {}; } - console.log('[UserReviewPanel] 🎯 RATING 필터 데이터 추출 (IF-LGSP-100 기반):', { + dlog('[UserReviewPanel] 🎯 RATING 필터 데이터 추출 (IF-LGSP-100 기반):', { ratingFilter, - filterItems: ratingFilter.filter + filterItems: ratingFilter.filter, }); // filter 배열을 { filterTpVal: filterNmCnt } 형태로 변환 @@ -167,7 +172,7 @@ const UserReviewPanel = ({ className, panelInfo, spotlightId }) => { } } - console.log('[UserReviewPanel] 📊 RATING 필터 데이터 변환 완료:', ratingMap); + dlog('[UserReviewPanel] 📊 RATING 필터 데이터 변환 완료:', ratingMap); return ratingMap; }, [filters]); @@ -180,13 +185,13 @@ const UserReviewPanel = ({ className, panelInfo, spotlightId }) => { const keywordsFilter = filters.find((f) => f.filterTpCd === 'KEYWORDS'); if (!keywordsFilter) { - console.log('[UserReviewPanel] ⚠️ KEYWORDS 필터 데이터 없음'); + dlog('[UserReviewPanel] ⚠️ KEYWORDS 필터 데이터 없음'); return []; } - console.log('[UserReviewPanel] 🎯 KEYWORDS 필터 데이터 추출:', { + dlog('[UserReviewPanel] 🎯 KEYWORDS 필터 데이터 추출:', { keywordsFilter, - filterItems: keywordsFilter.filter + filterItems: keywordsFilter.filter, }); // filter 배열을 그대로 반환 (filterNm, filterNmCnt, filterTpVal 포함) @@ -201,13 +206,13 @@ const UserReviewPanel = ({ className, panelInfo, spotlightId }) => { const sentimentFilter = filters.find((f) => f.filterTpCd === 'SENTIMENT'); if (!sentimentFilter) { - console.log('[UserReviewPanel] ⚠️ SENTIMENT 필터 데이터 없음'); + dlog('[UserReviewPanel] ⚠️ SENTIMENT 필터 데이터 없음'); return {}; } - console.log('[UserReviewPanel] 🎯 SENTIMENT 필터 데이터 추출:', { + dlog('[UserReviewPanel] 🎯 SENTIMENT 필터 데이터 추출:', { sentimentFilter, - filterItems: sentimentFilter.filter + filterItems: sentimentFilter.filter, }); // filter 배열을 { filterTpVal: filterNmCnt } 형태로 변환 @@ -225,39 +230,43 @@ const UserReviewPanel = ({ className, panelInfo, spotlightId }) => { const handleApiRatingFilter = useCallback( (rating) => { if (!prdtId || !patnrId) { - console.warn('[UserReviewPanel] ⚠️ API 호출 실패: prdtId 또는 patnrId 없음'); + dwarn('[UserReviewPanel] ⚠️ API 호출 실패: prdtId 또는 patnrId 없음'); return; } - console.log('[UserReviewPanel] 🔄 별점 필터 API 호출:', { rating, prdtId, patnrId }); + dlog('[UserReviewPanel] 🔄 별점 필터 API 호출:', { rating, prdtId, patnrId }); setForceScrollToTop(true); if (rating === 'all') { // ALL 필터로 리뷰 재로드 - dispatch(getUserReviewList({ - prdtId, - patnrId, - filterTpCd: 'ALL', - pageSize: 100, - pageNo: 1 - })); + dispatch( + getUserReviewList({ + prdtId, + patnrId, + filterTpCd: 'ALL', + pageSize: 100, + pageNo: 1, + }) + ); } else { // RATING 필터로 리뷰 조회 - dispatch(getUserReviewList({ - prdtId, - patnrId, - filterTpCd: 'RATING', - filterTpVal: String(rating), - pageSize: 100, - pageNo: 1 - })); + dispatch( + getUserReviewList({ + prdtId, + patnrId, + filterTpCd: 'RATING', + filterTpVal: String(rating), + pageSize: 100, + pageNo: 1, + }) + ); } }, [prdtId, patnrId, dispatch] ); const handleAllStarsFilter = useCallback(() => { - console.log('[UserReviewPanel] 🔄 All Star 필터 해제'); + dlog('[UserReviewPanel] 🔄 All Star 필터 해제'); setForceScrollToTop(true); dispatch(clearReviewFilter()); }, [dispatch]); @@ -271,21 +280,23 @@ const UserReviewPanel = ({ className, panelInfo, spotlightId }) => { const handleApiKeywordsFilter = useCallback( (keyword) => { if (!prdtId || !patnrId) { - console.warn('[UserReviewPanel] ⚠️ API 호출 실패: prdtId 또는 patnrId 없음'); + dwarn('[UserReviewPanel] ⚠️ API 호출 실패: prdtId 또는 patnrId 없음'); return; } - console.log('[UserReviewPanel] 🔄 키워드 필터 API 호출:', { keyword, prdtId, patnrId }); + dlog('[UserReviewPanel] 🔄 키워드 필터 API 호출:', { keyword, prdtId, patnrId }); setForceScrollToTop(true); - dispatch(getUserReviewList({ - prdtId, - patnrId, - filterTpCd: 'KEYWORDS', - filterTpVal: keyword, - pageSize: 100, - pageNo: 1 - })); + dispatch( + getUserReviewList({ + prdtId, + patnrId, + filterTpCd: 'KEYWORDS', + filterTpVal: keyword, + pageSize: 100, + pageNo: 1, + }) + ); }, [prdtId, patnrId, dispatch] ); @@ -294,41 +305,57 @@ const UserReviewPanel = ({ className, panelInfo, spotlightId }) => { const handleApiSentimentFilter = useCallback( (sentiment) => { if (!prdtId || !patnrId) { - console.warn('[UserReviewPanel] ⚠️ API 호출 실패: prdtId 또는 patnrId 없음'); + dwarn('[UserReviewPanel] ⚠️ API 호출 실패: prdtId 또는 patnrId 없음'); return; } - console.log('[UserReviewPanel] 🔄 감정 필터 API 호출:', { sentiment, prdtId, patnrId }); + dlog('[UserReviewPanel] 🔄 감정 필터 API 호출:', { sentiment, prdtId, patnrId }); setForceScrollToTop(true); if (sentiment === 'all') { // ALL 필터로 리뷰 재로드 - dispatch(getUserReviewList({ - prdtId, - patnrId, - filterTpCd: 'ALL', - pageSize: 100, - pageNo: 1 - })); + dispatch( + getUserReviewList({ + prdtId, + patnrId, + filterTpCd: 'ALL', + pageSize: 100, + pageNo: 1, + }) + ); } else { // SENTIMENT 필터로 리뷰 조회 - dispatch(getUserReviewList({ - prdtId, - patnrId, - filterTpCd: 'SENTIMENT', - filterTpVal: sentiment, - pageSize: 100, - pageNo: 1 - })); + dispatch( + getUserReviewList({ + prdtId, + patnrId, + filterTpCd: 'SENTIMENT', + filterTpVal: sentiment, + pageSize: 100, + pageNo: 1, + }) + ); } }, [prdtId, patnrId, dispatch] ); - const handleAromaClick = useCallback(() => handleApiKeywordsFilter('Aroma'), [handleApiKeywordsFilter]); - const handleVanillaClick = useCallback(() => handleApiKeywordsFilter('Vanilla'), [handleApiKeywordsFilter]); - const handleCinnamonClick = useCallback(() => handleApiKeywordsFilter('Cinnamon'), [handleApiKeywordsFilter]); - const handleQualityClick = useCallback(() => handleApiKeywordsFilter('Quality'), [handleApiKeywordsFilter]); + const handleAromaClick = useCallback( + () => handleApiKeywordsFilter('Aroma'), + [handleApiKeywordsFilter] + ); + const handleVanillaClick = useCallback( + () => handleApiKeywordsFilter('Vanilla'), + [handleApiKeywordsFilter] + ); + const handleCinnamonClick = useCallback( + () => handleApiKeywordsFilter('Cinnamon'), + [handleApiKeywordsFilter] + ); + const handleQualityClick = useCallback( + () => handleApiKeywordsFilter('Quality'), + [handleApiKeywordsFilter] + ); const handlePositiveClick = useCallback( () => handleApiSentimentFilter('positive'), @@ -343,7 +370,7 @@ const UserReviewPanel = ({ className, panelInfo, spotlightId }) => { useEffect(() => { if (forceScrollToTop) { const timer = setTimeout(() => { - console.log('[UserReviewPanel] ↩️ 스크롤을 상단으로 리셋 완료'); + dlog('[UserReviewPanel] ↩️ 스크롤을 상단으로 리셋 완료'); setForceScrollToTop(false); }, 50); return () => clearTimeout(timer); @@ -353,7 +380,7 @@ const UserReviewPanel = ({ className, panelInfo, spotlightId }) => { // UserReviewPanel 데이터 상태 로깅 useEffect(() => { if (_debug) { - console.log(`[UserReviewPanel] 📊 데이터 상태 ${VERSION_LABEL}:`, { + dlog(`[UserReviewPanel] 📊 데이터 상태 ${VERSION_LABEL}:`, { reviewVersion: _debug.reviewVersion, versionLabel: VERSION_LABEL, totalReviews: stats.totalReviews, @@ -366,7 +393,16 @@ const UserReviewPanel = ({ className, panelInfo, spotlightId }) => { totalPages: userReviewPanelTotalPages, }); } - }, [_debug, stats, currentFilter, userReviewPanelPage, userReviewPanelReviews, userReviewPanelHasNext, userReviewPanelHasPrev, userReviewPanelTotalPages]); + }, [ + _debug, + stats, + currentFilter, + userReviewPanelPage, + userReviewPanelReviews, + userReviewPanelHasNext, + userReviewPanelHasPrev, + userReviewPanelTotalPages, + ]); useEffect(() => { return () => { @@ -377,7 +413,7 @@ const UserReviewPanel = ({ className, panelInfo, spotlightId }) => { const handleBackButton = useCallback(() => { // ✅ CRITICAL FIX: Back 버튼 클릭 시 Redux 필터 상태 초기화 // 필터가 유지되어 ProductAllSection으로 돌아갔을 때 잘못된 리뷰 표시 방지 - console.log('[UserReviewPanel] 🔙 Back 버튼 클릭 - Redux 필터 초기화'); + dlog('[UserReviewPanel] 🔙 Back 버튼 클릭 - Redux 필터 초기화'); dispatch(clearReviewFilter()); if (bgVideoInfo && bgVideoInfo.hasVideo) { @@ -408,7 +444,7 @@ const UserReviewPanel = ({ className, panelInfo, spotlightId }) => { // ✅ filteredReviews 사용: 현재 필터에 적용된 리뷰 목록 내에서 찾기 const handleReviewClick = useCallback( (review, index) => { - console.log('[UserReviewPanel] Review clicked, opening popup:', { + dlog('[UserReviewPanel] Review clicked, opening popup:', { rvwId: review.rvwId, index, currentFilter, @@ -419,7 +455,7 @@ const UserReviewPanel = ({ className, panelInfo, spotlightId }) => { // filteredReviews는 현재 필터에 적용된 전체 리뷰 목록 const realIndex = filteredReviews.findIndex((r) => r.rvwId === review.rvwId); - console.log('[UserReviewPanel] Review index mapping:', { + dlog('[UserReviewPanel] Review index mapping:', { localIndex: index, realIndexInFiltered: realIndex, selectedIndex: realIndex >= 0 ? realIndex : index, @@ -434,7 +470,7 @@ const UserReviewPanel = ({ className, panelInfo, spotlightId }) => { // 팝업 닫기 핸들러 const handleClosePopup = useCallback(() => { - console.log('[UserReviewPanel] Closing popup'); + dlog('[UserReviewPanel] Closing popup'); setIsPopupOpen(false); setPopupMode('user-reviews'); setSelectedImageIndex(0); @@ -442,7 +478,7 @@ const UserReviewPanel = ({ className, panelInfo, spotlightId }) => { // 팝업 모드 변경 핸들러 const handleModeChange = useCallback((newMode, imageIndex = 0) => { - console.log('[UserReviewPanel] Mode change requested:', { newMode, imageIndex }); + dlog('[UserReviewPanel] Mode change requested:', { newMode, imageIndex }); setPopupMode(newMode); if (newMode === 'all-images' || newMode === 'user-reviews') { setSelectedImageIndex(imageIndex); @@ -518,7 +554,10 @@ const UserReviewPanel = ({ className, panelInfo, spotlightId }) => { ariaLabel="Filter by 5 star ratings" dataSpotlightUp="filter-all-stars" dataSpotlightDown="filter-4-stars" - isActive={currentReviewFilter?.filterTpCd === 'RATING' && currentReviewFilter?.filterTpVal === '5'} + isActive={ + currentReviewFilter?.filterTpCd === 'RATING' && + currentReviewFilter?.filterTpVal === '5' + } /> { ariaLabel="Filter by 4 star ratings" dataSpotlightUp="filter-5-stars" dataSpotlightDown="filter-3-stars" - isActive={currentReviewFilter?.filterTpCd === 'RATING' && currentReviewFilter?.filterTpVal === '4'} + isActive={ + currentReviewFilter?.filterTpCd === 'RATING' && + currentReviewFilter?.filterTpVal === '4' + } /> { ariaLabel="Filter by 3 star ratings" dataSpotlightUp="filter-4-stars" dataSpotlightDown="filter-2-stars" - isActive={currentReviewFilter?.filterTpCd === 'RATING' && currentReviewFilter?.filterTpVal === '3'} + isActive={ + currentReviewFilter?.filterTpCd === 'RATING' && + currentReviewFilter?.filterTpVal === '3' + } /> { ariaLabel="Filter by 2 star ratings" dataSpotlightUp="filter-3-stars" dataSpotlightDown="filter-1-stars" - isActive={currentReviewFilter?.filterTpCd === 'RATING' && currentReviewFilter?.filterTpVal === '2'} + isActive={ + currentReviewFilter?.filterTpCd === 'RATING' && + currentReviewFilter?.filterTpVal === '2' + } /> { spotlightId="filter-1-stars" ariaLabel="Filter by 1 star ratings" dataSpotlightUp="filter-2-stars" - isActive={currentReviewFilter?.filterTpCd === 'RATING' && currentReviewFilter?.filterTpVal === '1'} + isActive={ + currentReviewFilter?.filterTpCd === 'RATING' && + currentReviewFilter?.filterTpVal === '1' + } />
@@ -567,17 +618,29 @@ const UserReviewPanel = ({ className, panelInfo, spotlightId }) => { keywordsFilterData .filter((keyword) => parseInt(keyword.filterNmCnt, 10) > 0) .map((keyword, index) => ( - handleApiKeywordsFilter(keyword.filterTpVal)} - spotlightId={`filter-keyword-${index}`} - ariaLabel={`Filter by ${keyword.filterNm} keyword`} - dataSpotlightUp={index === 0 ? 'filter-1-stars' : `filter-keyword-${index - 1}`} - dataSpotlightDown={index === keywordsFilterData.filter((k) => parseInt(k.filterNmCnt, 10) > 0).length - 1 ? 'filter-positive' : `filter-keyword-${index + 1}`} - isActive={currentReviewFilter?.filterTpCd === 'KEYWORDS' && currentReviewFilter?.filterTpVal === keyword.filterTpVal} - /> - )) + handleApiKeywordsFilter(keyword.filterTpVal)} + spotlightId={`filter-keyword-${index}`} + ariaLabel={`Filter by ${keyword.filterNm} keyword`} + dataSpotlightUp={ + index === 0 ? 'filter-1-stars' : `filter-keyword-${index - 1}` + } + dataSpotlightDown={ + index === + keywordsFilterData.filter((k) => parseInt(k.filterNmCnt, 10) > 0) + .length - + 1 + ? 'filter-positive' + : `filter-keyword-${index + 1}` + } + isActive={ + currentReviewFilter?.filterTpCd === 'KEYWORDS' && + currentReviewFilter?.filterTpVal === keyword.filterTpVal + } + /> + )) ) : ( // 폴백: API 데이터 없을 경우 기존 하드코딩된 버튼 표시 <> @@ -627,17 +690,29 @@ const UserReviewPanel = ({ className, panelInfo, spotlightId }) => { Object.entries(sentimentFilterData) .filter(([, count]) => count > 0) .map(([sentiment, count], index) => ( - handleApiSentimentFilter(sentiment)} - spotlightId={`filter-sentiment-${sentiment}`} - ariaLabel={`Filter by ${sentiment} sentiment`} - dataSpotlightUp={index === 0 ? 'filter-quality' : `filter-sentiment-${Object.entries(sentimentFilterData).filter(([, c]) => c > 0)[index - 1][0]}`} - dataSpotlightDown={index === Object.entries(sentimentFilterData).filter(([, c]) => c > 0).length - 1 ? undefined : `filter-sentiment-${Object.entries(sentimentFilterData).filter(([, c]) => c > 0)[index + 1][0]}`} - isActive={currentReviewFilter?.filterTpCd === 'SENTIMENT' && currentReviewFilter?.filterTpVal === sentiment} - /> - )) + handleApiSentimentFilter(sentiment)} + spotlightId={`filter-sentiment-${sentiment}`} + ariaLabel={`Filter by ${sentiment} sentiment`} + dataSpotlightUp={ + index === 0 + ? 'filter-quality' + : `filter-sentiment-${Object.entries(sentimentFilterData).filter(([, c]) => c > 0)[index - 1][0]}` + } + dataSpotlightDown={ + index === + Object.entries(sentimentFilterData).filter(([, c]) => c > 0).length - 1 + ? undefined + : `filter-sentiment-${Object.entries(sentimentFilterData).filter(([, c]) => c > 0)[index + 1][0]}` + } + isActive={ + currentReviewFilter?.filterTpCd === 'SENTIMENT' && + currentReviewFilter?.filterTpVal === sentiment + } + /> + )) ) : ( // 폴백: API 데이터 없을 경우 기존 하드코딩된 버튼 표시 <> @@ -660,7 +735,11 @@ const UserReviewPanel = ({ className, panelInfo, spotlightId }) => { onClick={handleNegativeClick} spotlightId="filter-negative" ariaLabel="Filter by negative sentiment" - dataSpotlightUp={filterCounts?.sentiment?.positive > 0 ? "filter-positive" : "filter-quality"} + dataSpotlightUp={ + filterCounts?.sentiment?.positive > 0 + ? 'filter-positive' + : 'filter-quality' + } isActive={ currentFilter.type === 'sentiment' && currentFilter.value === 'negative' } diff --git a/com.twin.app.shoptime/src/views/UserReview/components/UserReviewsList.jsx b/com.twin.app.shoptime/src/views/UserReview/components/UserReviewsList.jsx index 20512f92..b08d4943 100644 --- a/com.twin.app.shoptime/src/views/UserReview/components/UserReviewsList.jsx +++ b/com.twin.app.shoptime/src/views/UserReview/components/UserReviewsList.jsx @@ -4,8 +4,13 @@ import UserReviewItem from './UserReviewItem'; import UserReviewsScroller from './UserReviewsScroller'; import VirtualScrollBar from './VirtualScrollBar'; import { $L } from '../../../utils/helperMethods'; +import { createDebugHelpers } from '../../../utils/debug'; import css from './UserReviewsList.module.less'; +// 디버그 헬퍼 설정 +const DEBUG_MODE = false; +const { dlog, dwarn, derror } = createDebugHelpers(DEBUG_MODE); + const Container = SpotlightContainerDecorator( { enterTo: 'default-element', @@ -34,18 +39,21 @@ const UserReviewsList = ({ onReviewClick, // 상위에서 전달받은 리뷰 클릭 핸들러 forceScrollToTop = false, // 필터 변경 시 스크롤을 상단으로 리셋 }) => { - const handleReviewClick = useCallback((review, index) => { - console.log('[UserReviewsList] Review item clicked:', { - rvwId: review.rvwId, - index: index, - review: review, - }); + const handleReviewClick = useCallback( + (review, index) => { + dlog('[UserReviewsList] Review item clicked:', { + rvwId: review.rvwId, + index: index, + review: review, + }); - // 상위로 클릭 이벤트 전달 - if (onReviewClick) { - onReviewClick(review, index); - } - }, [onReviewClick]); + // 상위로 클릭 이벤트 전달 + if (onReviewClick) { + onReviewClick(review, index); + } + }, + [onReviewClick] + ); // ✅ API 필터 활성화 여부 확인 // 필터가 활성화되면 filteredReviewCount (필터링된 리뷰 개수) 사용 @@ -53,23 +61,20 @@ const UserReviewsList = ({ const isApiFilterActive = !!currentReviewFilter; const displayCount = isApiFilterActive ? filteredReviewCount : totalReviewCount; - console.log('[UserReviewsList] 📊 리뷰 개수 계산:', { + dlog('[UserReviewsList] 📊 리뷰 개수 계산:', { isApiFilterActive, totalReviewCount, filteredReviewCount, displayCount, currentReviewFilter, - reviewsDataLength: reviewsData?.length || 0 + reviewsDataLength: reviewsData?.length || 0, }); return (
- - {displayCount} - {' '} - Customer Reviews + {displayCount} Customer Reviews
diff --git a/com.twin.app.shoptime/src/views/UserReview/components/VirtualScrollBar.jsx b/com.twin.app.shoptime/src/views/UserReview/components/VirtualScrollBar.jsx index cb711e24..43de2bb1 100644 --- a/com.twin.app.shoptime/src/views/UserReview/components/VirtualScrollBar.jsx +++ b/com.twin.app.shoptime/src/views/UserReview/components/VirtualScrollBar.jsx @@ -1,8 +1,13 @@ import React, { useCallback, useMemo, useEffect, useRef } from 'react'; import Spottable from '@enact/spotlight/Spottable'; import classNames from 'classnames'; +import { createDebugHelpers } from '../../../utils/debug'; import css from './VirtualScrollBar.module.less'; +// 디버그 헬퍼 설정 +const DEBUG_MODE = false; +const { dlog, dwarn, derror } = createDebugHelpers(DEBUG_MODE); + const SpottableDiv = Spottable('div'); const VirtualScrollBar = ({ @@ -36,14 +41,14 @@ const VirtualScrollBar = ({ (event) => { if (event.key === 'ArrowDown') { if (hasNext && onNextPage) { - console.log('[VirtualScrollBar] Arrow Down - Next page'); + dlog('[VirtualScrollBar] Arrow Down - Next page'); onNextPage(); } event.preventDefault(); event.stopPropagation(); } else if (event.key === 'ArrowUp') { if (hasPrev && onPrevPage) { - console.log('[VirtualScrollBar] Arrow Up - Previous page'); + dlog('[VirtualScrollBar] Arrow Up - Previous page'); onPrevPage(); } event.preventDefault(); @@ -57,7 +62,7 @@ const VirtualScrollBar = ({ if (thumbRef.current) { thumbRef.current.style.height = `${thumbHeightPercent}%`; thumbRef.current.style.top = `${thumbTopPercent}%`; - console.log('[VirtualScrollBar] Updated:', { + dlog('[VirtualScrollBar] Updated:', { totalPages, thumbHeightPercent, thumbTopPercent,