fix: IntroPanel수정 , webOSVersion처리 수정,UI 수정
This commit is contained in:
@@ -146,6 +146,7 @@ function AppBase(props) {
|
||||
(state) => state.common.appStatus.cursorVisible
|
||||
);
|
||||
const introTermsAgree = useSelector((state) => state.common.introTermsAgree);
|
||||
const deviceRegistered = useSelector((state) => state.common.deviceRegistered);
|
||||
// const optionalTermsAgree = useSelector((state) => state.common.optionalTermsAgree);
|
||||
const termsLoading = useSelector((state) => state.common.termsLoading);
|
||||
// termsFlag 전체 상태 확인
|
||||
@@ -418,8 +419,8 @@ function AppBase(props) {
|
||||
// 약관 동의 여부 확인 전에는 아무것도 하지 않음
|
||||
return;
|
||||
}
|
||||
|
||||
if (introTermsAgree) {
|
||||
console.log("[App.js] deviceRegistered", deviceRegistered);
|
||||
if (introTermsAgree || deviceRegistered) {
|
||||
initService(true);
|
||||
} else {
|
||||
// 필수 약관에 동의하지 않은 경우
|
||||
@@ -428,7 +429,7 @@ function AppBase(props) {
|
||||
);
|
||||
dispatch(changeAppStatus({ showLoadingPanel: { show: false } }));
|
||||
}
|
||||
}, [introTermsAgree, dispatch, initService, termsLoading]);
|
||||
}, [introTermsAgree, deviceRegistered, dispatch, initService, termsLoading]);
|
||||
|
||||
useEffect(() => {
|
||||
const launchParmas = getLaunchParams();
|
||||
|
||||
@@ -40,6 +40,7 @@ export const types = {
|
||||
SET_ERROR_MESSAGE: "SET_ERROR_MESSAGE",
|
||||
CLEAR_ERROR_MESSAGE: "CLEAR_ERROR_MESSAGE",
|
||||
GET_DEVICE_MACADDRESS: "GET_DEVICE_MACADDRESS",
|
||||
SET_DEVICE_REGISTERED: "SET_DEVICE_REGISTERED",
|
||||
|
||||
// billing actions
|
||||
GET_MY_INFO_BILLING_SEARCH: "GET_MY_INFO_BILLING_SEARCH",
|
||||
|
||||
@@ -566,9 +566,14 @@ export const setSecondLayerInfo = (secondLayerInfo) => ({
|
||||
payload: secondLayerInfo,
|
||||
});
|
||||
|
||||
export const setGNBMenu = (menu) => ({
|
||||
export const setGNBMenu = (gnbMenu) => ({
|
||||
type: types.SET_GNB_MENU,
|
||||
payload: menu,
|
||||
payload: gnbMenu,
|
||||
});
|
||||
|
||||
export const setDeviceRegistered = (isRegistered) => ({
|
||||
type: types.SET_DEVICE_REGISTERED,
|
||||
payload: isRegistered,
|
||||
});
|
||||
|
||||
export const clearErrorMessage = () => ({
|
||||
|
||||
@@ -1,10 +1,18 @@
|
||||
import { URLS } from "../api/apiConfig";
|
||||
import { runDelayedAction, setTokenRefreshing, TAxios } from "../api/TAxios";
|
||||
import {
|
||||
runDelayedAction,
|
||||
setTokenRefreshing,
|
||||
TAxios,
|
||||
TAxiosAdvancedPromise,
|
||||
} from "../api/TAxios";
|
||||
import * as lunaSend from "../lunaSend";
|
||||
import { types } from "./actionTypes";
|
||||
import { changeLocalSettings } from "./commonActions";
|
||||
import { fetchCurrentUserHomeTerms } from "./homeActions";
|
||||
|
||||
const MAX_RETRY_COUNT = 3;
|
||||
const RETRY_DELAY = 2000; // 2 seconds
|
||||
|
||||
// IF-LGSP-000 인증코드 요청
|
||||
export const getAuthenticationCode = () => (dispatch, getState) => {
|
||||
setTokenRefreshing(true);
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
import axios from 'axios';
|
||||
|
||||
import Spotlight from '@enact/spotlight';
|
||||
import { useDispatch } from 'react-redux';
|
||||
import { useState } from 'react';
|
||||
import { fetchCurrentUserHomeTermsSafe } from '../actions/homeActions';
|
||||
|
||||
import { types } from '../actions/actionTypes';
|
||||
import {
|
||||
@@ -187,10 +190,11 @@ export const TAxios = (
|
||||
dispatch(getReAuthenticationCode());
|
||||
}
|
||||
pushQueue();
|
||||
if (onFail) onFail(res);
|
||||
return;
|
||||
}
|
||||
|
||||
//RefreshToken 만료
|
||||
// RefreshToken 만료
|
||||
if (res?.data?.retCode === 402 || res?.data?.retCode === 501) {
|
||||
if (baseUrl === URLS.GET_RE_AUTHENTICATION_CODE) {
|
||||
dispatch(getAuthenticationCode());
|
||||
@@ -200,6 +204,7 @@ export const TAxios = (
|
||||
}
|
||||
pushQueue();
|
||||
}
|
||||
if (onFail) onFail(res);
|
||||
return;
|
||||
}
|
||||
// 602 요청 국가 불일치
|
||||
@@ -246,3 +251,330 @@ export const TAxios = (
|
||||
pushQueue();
|
||||
}
|
||||
};
|
||||
|
||||
// 안전한 에러 처리를 위한 TAxiosPromise
|
||||
export const TAxiosPromise = (
|
||||
dispatch,
|
||||
getState,
|
||||
type,
|
||||
baseUrl,
|
||||
urlParams = {},
|
||||
params = {},
|
||||
noTokenRefresh = false
|
||||
) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
TAxios(
|
||||
dispatch,
|
||||
getState,
|
||||
type,
|
||||
baseUrl,
|
||||
urlParams,
|
||||
params,
|
||||
// onSuccess - 항상 성공 객체로 반환
|
||||
(response) => {
|
||||
resolve({
|
||||
success: true,
|
||||
data: response.data,
|
||||
response: response,
|
||||
error: null
|
||||
});
|
||||
},
|
||||
// onFail - 에러도 resolve로 처리하여 throw 방지
|
||||
(error) => {
|
||||
console.error(`TAxiosPromise failed for ${baseUrl}:`, error);
|
||||
resolve({
|
||||
success: false,
|
||||
data: null,
|
||||
response: null,
|
||||
error: error
|
||||
});
|
||||
},
|
||||
noTokenRefresh
|
||||
);
|
||||
});
|
||||
};
|
||||
|
||||
// 더 세밀한 제어를 위한 확장된 Promise 버전
|
||||
export const TAxiosAdvancedPromise = (
|
||||
dispatch,
|
||||
getState,
|
||||
type,
|
||||
baseUrl,
|
||||
urlParams = {},
|
||||
params = {},
|
||||
options = {}
|
||||
) => {
|
||||
const {
|
||||
noTokenRefresh = false,
|
||||
timeout = 30000,
|
||||
retries = 0,
|
||||
retryDelay = 1000,
|
||||
throwOnError = false, // 개발자가 명시적으로 원할 때만 throw
|
||||
} = options;
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
let attempts = 0;
|
||||
const maxAttempts = retries + 1;
|
||||
|
||||
const attemptRequest = () => {
|
||||
attempts++;
|
||||
console.log(`TAxiosPromise attempt ${attempts}/${maxAttempts} for ${baseUrl}`);
|
||||
|
||||
const timeoutId = setTimeout(() => {
|
||||
const timeoutError = new Error(`Request timeout after ${timeout}ms for ${baseUrl}`);
|
||||
if (throwOnError) {
|
||||
reject(timeoutError);
|
||||
} else {
|
||||
resolve({
|
||||
success: false,
|
||||
data: null,
|
||||
response: null,
|
||||
error: timeoutError
|
||||
});
|
||||
}
|
||||
}, timeout);
|
||||
|
||||
TAxios(
|
||||
dispatch,
|
||||
getState,
|
||||
type,
|
||||
baseUrl,
|
||||
urlParams,
|
||||
params,
|
||||
// onSuccess
|
||||
(response) => {
|
||||
clearTimeout(timeoutId);
|
||||
console.log(`TAxiosPromise success on attempt ${attempts} for ${baseUrl}`);
|
||||
resolve({
|
||||
success: true,
|
||||
data: response.data,
|
||||
response: response,
|
||||
error: null
|
||||
});
|
||||
},
|
||||
// onFail
|
||||
(error) => {
|
||||
clearTimeout(timeoutId);
|
||||
console.error(`TAxiosPromise error on attempt ${attempts} for ${baseUrl}:`, error);
|
||||
|
||||
// 재시도 로직
|
||||
if (attempts < maxAttempts) {
|
||||
console.log(`Retrying in ${retryDelay}ms... (${attempts}/${maxAttempts})`);
|
||||
setTimeout(() => {
|
||||
attemptRequest();
|
||||
}, retryDelay);
|
||||
} else {
|
||||
// 최종 실패 시에도 resolve로 처리 (throwOnError가 false인 경우)
|
||||
if (throwOnError) {
|
||||
reject(error);
|
||||
} else {
|
||||
resolve({
|
||||
success: false,
|
||||
data: null,
|
||||
response: null,
|
||||
error: error
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
noTokenRefresh
|
||||
);
|
||||
};
|
||||
|
||||
attemptRequest();
|
||||
});
|
||||
};
|
||||
|
||||
// HTTP 메소드별 편의 함수들 (안전한 버전)
|
||||
export const TAxiosGet = async (dispatch, getState, baseUrl, urlParams = {}, options = {}) => {
|
||||
return await TAxiosPromise(dispatch, getState, 'get', baseUrl, urlParams, {}, options.noTokenRefresh);
|
||||
};
|
||||
|
||||
export const TAxiosPost = async (dispatch, getState, baseUrl, params = {}, options = {}) => {
|
||||
return await TAxiosPromise(dispatch, getState, 'post', baseUrl, {}, params, options.noTokenRefresh);
|
||||
};
|
||||
|
||||
// 안전한 다중 요청 처리
|
||||
export const TAxiosAll = async (requests) => {
|
||||
try {
|
||||
const results = await Promise.all(requests);
|
||||
|
||||
// 모든 결과를 안전하게 처리
|
||||
const successResults = [];
|
||||
const failedResults = [];
|
||||
|
||||
results.forEach((result, index) => {
|
||||
if (result.success) {
|
||||
successResults.push({ index, result: result.data });
|
||||
} else {
|
||||
failedResults.push({ index, error: result.error });
|
||||
}
|
||||
});
|
||||
|
||||
return {
|
||||
success: failedResults.length === 0,
|
||||
successResults,
|
||||
failedResults,
|
||||
allResults: results
|
||||
};
|
||||
} catch (error) {
|
||||
console.error('TAxiosAll unexpected error:', error);
|
||||
return {
|
||||
success: false,
|
||||
successResults: [],
|
||||
failedResults: [{ index: -1, error }],
|
||||
allResults: []
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
// 순차 요청 처리 (안전 버전)
|
||||
export const TAxiosSequential = async (requests) => {
|
||||
const results = [];
|
||||
const errors = [];
|
||||
|
||||
for (let i = 0; i < requests.length; i++) {
|
||||
try {
|
||||
const result = await requests[i];
|
||||
if (result.success) {
|
||||
results.push({ index: i, data: result.data });
|
||||
} else {
|
||||
errors.push({ index: i, error: result.error });
|
||||
console.error(`TAxiosSequential failed at request ${i}:`, result.error);
|
||||
}
|
||||
} catch (error) {
|
||||
errors.push({ index: i, error });
|
||||
console.error(`TAxiosSequential unexpected error at request ${i}:`, error);
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
success: errors.length === 0,
|
||||
results,
|
||||
errors
|
||||
};
|
||||
};
|
||||
|
||||
// 안전한 Redux Thunk 헬퍼
|
||||
export const createSafeApiThunk = (apiCall) => {
|
||||
return (...args) => async (dispatch, getState) => {
|
||||
try {
|
||||
const result = await apiCall(dispatch, getState, ...args);
|
||||
return result; // 이미 안전한 형태로 반환됨
|
||||
} catch (error) {
|
||||
console.error('API thunk unexpected error:', error);
|
||||
return {
|
||||
success: false,
|
||||
data: null,
|
||||
response: null,
|
||||
error
|
||||
};
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
// 실제 사용 예시들 (안전한 버전)
|
||||
export const safeUsageExamples = {
|
||||
// 1. 기본 안전한 사용법
|
||||
basicSafeUsage: async (dispatch, getState) => {
|
||||
const result = await TAxiosPromise(
|
||||
dispatch,
|
||||
getState,
|
||||
'get',
|
||||
URLS.GET_HOME_TERMS,
|
||||
{ trmsTpCdList: "MST00401, MST00402", mbrNo: "12345" }
|
||||
);
|
||||
|
||||
if (result.success) {
|
||||
console.log('Success:', result.data);
|
||||
return result.data;
|
||||
} else {
|
||||
console.error('API call failed:', result.error);
|
||||
// 에러를 throw하지 않고 기본값 반환하거나 사용자에게 안내
|
||||
return null;
|
||||
}
|
||||
},
|
||||
|
||||
// 2. retCode 체크를 포함한 안전한 처리
|
||||
safeWithRetCodeCheck: async (dispatch, getState) => {
|
||||
const result = await TAxiosGet(
|
||||
dispatch,
|
||||
getState,
|
||||
URLS.GET_HOME_TERMS,
|
||||
{ trmsTpCdList: "MST00401, MST00402", mbrNo: "12345" }
|
||||
);
|
||||
|
||||
if (!result.success) {
|
||||
console.error('Network error:', result.error);
|
||||
return { success: false, message: '네트워크 오류가 발생했습니다.' };
|
||||
}
|
||||
|
||||
if (result.data.retCode !== 0) {
|
||||
console.error('API error:', result.data.retCode, result.data.retMsg);
|
||||
return {
|
||||
success: false,
|
||||
message: result.data.retMsg || 'API 오류가 발생했습니다.'
|
||||
};
|
||||
}
|
||||
|
||||
return { success: true, data: result.data };
|
||||
},
|
||||
|
||||
// 3. 여러 요청의 안전한 처리
|
||||
safeParallelRequests: async (dispatch, getState) => {
|
||||
const requests = [
|
||||
TAxiosGet(dispatch, getState, URLS.GET_HOME_TERMS, { mbrNo: "12345" }),
|
||||
TAxiosGet(dispatch, getState, URLS.GET_USER_INFO, { mbrNo: "12345" }),
|
||||
TAxiosPost(dispatch, getState, URLS.UPDATE_SETTINGS, { setting: "value" })
|
||||
];
|
||||
|
||||
const result = await TAxiosAll(requests);
|
||||
|
||||
if (result.success) {
|
||||
console.log('All requests succeeded');
|
||||
return result.successResults.map(item => item.result);
|
||||
} else {
|
||||
console.error('Some requests failed:', result.failedResults);
|
||||
// 부분적 성공도 처리 가능
|
||||
return {
|
||||
successData: result.successResults.map(item => item.result),
|
||||
errors: result.failedResults
|
||||
};
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// 컴포넌트에서의 안전한 사용법
|
||||
export const ComponentUsageExample = () => {
|
||||
const dispatch = useDispatch();
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [error, setError] = useState(null);
|
||||
|
||||
const handleFetchTerms = async () => {
|
||||
setLoading(true);
|
||||
setError(null);
|
||||
|
||||
const result = await dispatch(fetchCurrentUserHomeTermsSafe());
|
||||
|
||||
setLoading(false);
|
||||
|
||||
if (result.success) {
|
||||
console.log("Terms fetched successfully");
|
||||
// 성공 처리 (예: 성공 토스트 표시)
|
||||
} else {
|
||||
console.error("Failed to fetch terms:", result.message);
|
||||
setError(result.message);
|
||||
// 에러 처리 (예: 에러 토스트 표시)
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div>
|
||||
<button onClick={handleFetchTerms} disabled={loading}>
|
||||
{loading ? '로딩 중...' : '약관 정보 가져오기'}
|
||||
</button>
|
||||
{error && <div className="error-message">{error}</div>}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -1045,7 +1045,7 @@
|
||||
.figmaTermsContentContainer {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 40px;
|
||||
// gap: 40px;
|
||||
}
|
||||
|
||||
.figmaTermsCard {
|
||||
@@ -1073,6 +1073,7 @@
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
// margin-bottom: 40px;
|
||||
|
||||
.scrollerContent {
|
||||
padding: 31px;
|
||||
@@ -1085,6 +1086,7 @@
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center; // 버튼 수직 정렬을 위해 추가
|
||||
margin-top: 40px;
|
||||
// gap: 15px; // 버튼 사이 간격
|
||||
}
|
||||
|
||||
|
||||
@@ -75,6 +75,8 @@ const initialState = {
|
||||
macAddress: { wifi: "", wired: "", p2p: "" },
|
||||
connectionFailed: false,
|
||||
|
||||
deviceRegistered: false,
|
||||
|
||||
termsAgreementStatus: {
|
||||
MST00401: false, // 개인정보처리방침 (필수)
|
||||
MST00402: false, // 이용약관 (필수)
|
||||
@@ -84,6 +86,11 @@ const initialState = {
|
||||
|
||||
export const commonReducer = (state = initialState, action) => {
|
||||
switch (action.type) {
|
||||
case types.SET_DEVICE_REGISTERED:
|
||||
return {
|
||||
...state,
|
||||
deviceRegistered: action.payload,
|
||||
};
|
||||
case types.CHANGE_APP_STATUS: {
|
||||
let isUpdated = false;
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@ import {
|
||||
setExitApp,
|
||||
setHidePopup,
|
||||
setShowPopup,
|
||||
setDeviceRegistered,
|
||||
// setTermsAgreeYn,
|
||||
} from "../../actions/commonActions";
|
||||
import { registerDevice } from "../../actions/deviceActions";
|
||||
@@ -50,6 +51,9 @@ const Container = SpotlightContainerDecorator(
|
||||
"div",
|
||||
);
|
||||
|
||||
const MAX_RETRY_ATTEMPTS = 3;
|
||||
const RETRY_DELAY_MS = 1500; // 1.5 seconds
|
||||
|
||||
export default function IntroPanel({
|
||||
// children,
|
||||
// isTabActivated,
|
||||
@@ -70,6 +74,7 @@ export default function IntroPanel({
|
||||
);
|
||||
// const eventInfos = useSelector((state) => state.event.eventData);
|
||||
const regDeviceData = useSelector((state) => state.device.regDeviceData);
|
||||
const deviceRegistered = useSelector((state) => state.common.deviceRegistered);
|
||||
// const regDeviceInfoData = useSelector(
|
||||
// (state) => state.device.regDeviceInfoData
|
||||
// );
|
||||
@@ -114,26 +119,28 @@ export default function IntroPanel({
|
||||
const webOSVersion = useSelector(
|
||||
(state) => state.common.appStatus?.webOSVersion,
|
||||
);
|
||||
|
||||
// const webOSVersion = 4.5;
|
||||
// WebOS 버전별 UI 표시 모드 결정
|
||||
// 이미지 표시: 4.0, 5.0, 23, 24
|
||||
// 텍스트 표시: 4.5, 6.0, 22
|
||||
const shouldShowBenefitsView = useMemo(() => {
|
||||
if (!webOSVersion) return false;
|
||||
|
||||
const version = String(webOSVersion);
|
||||
const versionNum = Number.parseFloat(String(webOSVersion));
|
||||
|
||||
// 텍스트 표시 버전들
|
||||
const textVersions = ["4.5", "6.0", "22"];
|
||||
// 텍스트 표시 버전들 (숫자로 비교)
|
||||
const textVersions = [4.5, 6.0, 22];
|
||||
|
||||
// 이미지 표시 버전들
|
||||
const imageVersions = ["4.0", "5.0", "23", "24"];
|
||||
const imageVersions = [4.0, 5.0, 23, 24];
|
||||
|
||||
// 텍스트 버전인지 확인
|
||||
const shouldShowText = textVersions.includes(version);
|
||||
const shouldShowText = textVersions.includes(versionNum);
|
||||
|
||||
if (process.env.NODE_ENV === "development") {
|
||||
console.log("🔍 WebOS 버전별 UI 모드:");
|
||||
console.log(" - webOSVersion:", version);
|
||||
console.log(" - webOSVersion:", versionNum);
|
||||
console.log(" - shouldShowText (텍스트 모드):", shouldShowText);
|
||||
console.log(" - 텍스트 버전들:", textVersions);
|
||||
console.log(" - 이미지 버전들:", imageVersions);
|
||||
@@ -202,6 +209,14 @@ export default function IntroPanel({
|
||||
}
|
||||
}, [termsError, dispatch]);
|
||||
|
||||
useEffect(() => {
|
||||
console.log("[IntroPanel] deviceRegistered", deviceRegistered);
|
||||
if (deviceRegistered) {
|
||||
console.log("[IntroPanel] deviceRegistered 팝업 닫기");
|
||||
dispatch(popPanel(panel_names.INTRO_PANEL));
|
||||
}
|
||||
}, [deviceRegistered, dispatch]);
|
||||
|
||||
// 약관 팝업 동의여부에 따른 이벤트 핸들러
|
||||
const handleTermsAgree = useCallback(() => {
|
||||
if (!currentTerms) {
|
||||
@@ -287,114 +302,122 @@ export default function IntroPanel({
|
||||
}, [regDeviceData, dispatch, isProcessing]); // isProcessing 의존성 추가
|
||||
|
||||
// [추가] 실제 처리 로직 분리
|
||||
const executeAgree = useCallback(() => {
|
||||
console.log("[IntroPanel] executeAgree 실행 시작");
|
||||
const executeAgree = useCallback(
|
||||
(retryCount = 0) => {
|
||||
console.log(`[IntroPanel] executeAgree 실행 시작 (시도: ${retryCount + 1})`);
|
||||
|
||||
setIsProcessing(true);
|
||||
// Redux에서 가져온 termsIdMap을 사용하여 동적으로 약관 ID 매핑
|
||||
const agreeTerms = [];
|
||||
|
||||
// 기존 타임아웃을 5초로 단축
|
||||
processingTimeoutRef.current = setTimeout(() => {
|
||||
console.warn(
|
||||
"[IntroPanel] executeAgree 타임아웃 - isProcessing 강제 해제",
|
||||
);
|
||||
setIsProcessing(false);
|
||||
}, 5000);
|
||||
if (termsChecked && termsIdMap["MST00402"]) {
|
||||
agreeTerms.push(termsIdMap["MST00402"]); // 이용약관
|
||||
}
|
||||
if (privacyChecked && termsIdMap["MST00401"]) {
|
||||
agreeTerms.push(termsIdMap["MST00401"]); // 개인정보처리방침
|
||||
}
|
||||
if (optionalChecked && termsIdMap["MST00405"]) {
|
||||
agreeTerms.push(termsIdMap["MST00405"]); // 선택약관
|
||||
}
|
||||
|
||||
// 약관 동의 처리 시작 시 로딩 상태로 설정
|
||||
dispatch({ type: types.GET_TERMS_AGREE_YN_START });
|
||||
|
||||
// Redux에서 가져온 termsIdMap을 사용하여 동적으로 약관 ID 매핑
|
||||
const agreeTerms = [];
|
||||
|
||||
if (termsChecked && termsIdMap["MST00402"]) {
|
||||
agreeTerms.push(termsIdMap["MST00402"]); // 이용약관
|
||||
}
|
||||
if (privacyChecked && termsIdMap["MST00401"]) {
|
||||
agreeTerms.push(termsIdMap["MST00401"]); // 개인정보처리방침
|
||||
}
|
||||
if (optionalChecked && termsIdMap["MST00405"]) {
|
||||
agreeTerms.push(termsIdMap["MST00405"]); // 선택약관
|
||||
}
|
||||
|
||||
if (process.env.NODE_ENV === "development") {
|
||||
console.log("[IntroPanel] 현재 termsIdMap:", termsIdMap);
|
||||
console.log("[IntroPanel] 최종 전송될 agreeTerms:", agreeTerms);
|
||||
}
|
||||
console.log("[IntroPanel] agreeTerms!!", agreeTerms);
|
||||
|
||||
dispatch(
|
||||
registerDevice(
|
||||
{ agreeTerms: agreeTerms },
|
||||
(newRegDeviceData) => {
|
||||
if (newRegDeviceData && newRegDeviceData.retCode === 0) {
|
||||
dispatch(
|
||||
getWelcomeEventInfo((eventInfos) => {
|
||||
if (
|
||||
eventInfos &&
|
||||
Object.keys(eventInfos.data).length > 0 &&
|
||||
webOSVersion
|
||||
) {
|
||||
let displayWelcomeEventPanel = false;
|
||||
if (process.env.NODE_ENV === "development") {
|
||||
console.log("[IntroPanel] 현재 termsIdMap:", termsIdMap);
|
||||
console.log("[IntroPanel] 최종 전송될 agreeTerms:", agreeTerms);
|
||||
}
|
||||
console.log("[IntroPanel] agreeTerms!!", agreeTerms);
|
||||
|
||||
dispatch(
|
||||
registerDevice(
|
||||
{ agreeTerms: agreeTerms },
|
||||
(newRegDeviceData) => {
|
||||
// ================== SUCCESS ==================
|
||||
if (newRegDeviceData && newRegDeviceData.retCode === 0) {
|
||||
dispatch(setDeviceRegistered(true));
|
||||
dispatch(
|
||||
getWelcomeEventInfo((eventInfos) => {
|
||||
if (
|
||||
eventInfos.data?.welcomeEventFlag === "Y" ||
|
||||
(eventInfos.data?.welcomeBillCpnEventFlag === "Y" &&
|
||||
Number(webOSVersion) >= 6)
|
||||
eventInfos &&
|
||||
Object.keys(eventInfos.data).length > 0 &&
|
||||
webOSVersion
|
||||
) {
|
||||
displayWelcomeEventPanel = true;
|
||||
}
|
||||
let displayWelcomeEventPanel = false;
|
||||
|
||||
dispatch(
|
||||
sendLogTerms({ logTpNo: Config.LOG_TP_NO.TERMS.AGREE }),
|
||||
);
|
||||
if (
|
||||
eventInfos.data?.welcomeEventFlag === "Y" ||
|
||||
(eventInfos.data?.welcomeBillCpnEventFlag === "Y" &&
|
||||
Number(webOSVersion) >= 6)
|
||||
) {
|
||||
displayWelcomeEventPanel = true;
|
||||
}
|
||||
|
||||
if (displayWelcomeEventPanel) {
|
||||
dispatch(
|
||||
pushPanel({
|
||||
name: panel_names.WELCOME_EVENT_PANEL,
|
||||
panelInfo: { eventInfos: eventInfos.data },
|
||||
}),
|
||||
sendLogTerms({ logTpNo: Config.LOG_TP_NO.TERMS.AGREE })
|
||||
);
|
||||
|
||||
if (displayWelcomeEventPanel) {
|
||||
dispatch(
|
||||
pushPanel({
|
||||
name: panel_names.WELCOME_EVENT_PANEL,
|
||||
panelInfo: { eventInfos: eventInfos.data },
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
dispatch(popPanel(panel_names.INTRO_PANEL));
|
||||
setIsProcessing(false);
|
||||
})
|
||||
);
|
||||
} else {
|
||||
// retCode가 0이 아닌 경우도 실패로 간주하고 재시도
|
||||
if (retryCount < MAX_RETRY_ATTEMPTS - 1) {
|
||||
setTimeout(() => {
|
||||
executeAgree(retryCount + 1);
|
||||
}, RETRY_DELAY_MS);
|
||||
} else {
|
||||
dispatch(
|
||||
setShowPopup(Config.ACTIVE_POPUP.alertPopup, {
|
||||
title: $L("Error"),
|
||||
text: $L(
|
||||
"A temporary network error occurred. Please try again in a moment."
|
||||
),
|
||||
button1Text: $L("OK"),
|
||||
})
|
||||
);
|
||||
setIsProcessing(false);
|
||||
clearTimeout(processingTimeoutRef.current); // 타임아웃 정리
|
||||
}),
|
||||
);
|
||||
} else {
|
||||
dispatch(
|
||||
setShowPopup(Config.ACTIVE_POPUP.alertPopup, {
|
||||
title: $L("Error"),
|
||||
text: $L("Device registration failed. Please try again."),
|
||||
button1Text: $L("OK"),
|
||||
}),
|
||||
);
|
||||
setIsProcessing(false);
|
||||
clearTimeout(processingTimeoutRef.current); // 타임아웃 정리
|
||||
}
|
||||
}
|
||||
},
|
||||
() => {
|
||||
// ================== FAIL ==================
|
||||
console.error(`[IntroPanel] registerDevice 실패 (시도: ${retryCount + 1})`);
|
||||
if (retryCount < MAX_RETRY_ATTEMPTS - 1) {
|
||||
setTimeout(() => {
|
||||
executeAgree(retryCount + 1);
|
||||
}, RETRY_DELAY_MS);
|
||||
} else {
|
||||
console.error("[IntroPanel] 최대 재시도 횟수 초과.");
|
||||
dispatch(
|
||||
setShowPopup(Config.ACTIVE_POPUP.alertPopup, {
|
||||
title: $L("Error"),
|
||||
text: $L(
|
||||
"A temporary network error occurred. Please try again in a moment."
|
||||
),
|
||||
button1Text: $L("OK"),
|
||||
})
|
||||
);
|
||||
setIsProcessing(false);
|
||||
}
|
||||
}
|
||||
},
|
||||
() => {
|
||||
dispatch(
|
||||
setShowPopup(Config.ACTIVE_POPUP.alertPopup, {
|
||||
title: $L("Error"),
|
||||
text: $L("Device registration failed. Please try again."),
|
||||
button1Text: $L("OK"),
|
||||
}),
|
||||
);
|
||||
setIsProcessing(false);
|
||||
clearTimeout(processingTimeoutRef.current); // 타임아웃 정리
|
||||
},
|
||||
),
|
||||
);
|
||||
}, [
|
||||
termsChecked,
|
||||
privacyChecked,
|
||||
optionalChecked,
|
||||
dispatch,
|
||||
webOSVersion,
|
||||
termsIdMap,
|
||||
]);
|
||||
)
|
||||
);
|
||||
},
|
||||
[
|
||||
termsChecked,
|
||||
privacyChecked,
|
||||
optionalChecked,
|
||||
dispatch,
|
||||
webOSVersion,
|
||||
termsIdMap,
|
||||
]
|
||||
);
|
||||
|
||||
// [추가] 재시도 메커니즘 시작
|
||||
const startRetryMechanism = useCallback(() => {
|
||||
@@ -451,6 +474,7 @@ export default function IntroPanel({
|
||||
}
|
||||
|
||||
// 실제 처리 실행
|
||||
setIsProcessing(true);
|
||||
executeAgree();
|
||||
}, [
|
||||
termsChecked,
|
||||
@@ -661,6 +685,8 @@ export default function IntroPanel({
|
||||
const title = "welcome to shoptime!";
|
||||
delete rest.isOnTop;
|
||||
|
||||
const uiMode = shouldShowBenefitsView ? "Text Mode" : "Image Mode";
|
||||
|
||||
// [추가] 약관 종류에 따라 팝업 제목을 반환하는 헬퍼 함수
|
||||
const getTermsPopupTitle = (terms) => {
|
||||
if (!terms) return "";
|
||||
@@ -823,6 +849,13 @@ export default function IntroPanel({
|
||||
{$L("Do Not Agree")}
|
||||
</TButton>
|
||||
</div>
|
||||
|
||||
{/* --- DEBUG INFO [START] --- */}
|
||||
<div className={css.debugInfo}>
|
||||
<div>WebOS: {webOSVersion}</div>
|
||||
<div>Mode: {uiMode}</div>
|
||||
</div>
|
||||
{/* --- DEBUG INFO [END] --- */}
|
||||
</Container>
|
||||
</TPanel>
|
||||
|
||||
|
||||
@@ -148,6 +148,7 @@
|
||||
transition: all 0.3s ease;
|
||||
will-change: transform;
|
||||
margin-bottom: 20px;
|
||||
margin-left: 10px;
|
||||
|
||||
.termsText {
|
||||
color: black;
|
||||
@@ -416,3 +417,24 @@
|
||||
line-height: 43px;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
|
||||
.termsButton {
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
.debugInfo {
|
||||
position: absolute;
|
||||
bottom: 20px;
|
||||
right: 20px;
|
||||
padding: 10px;
|
||||
background-color: rgba(0, 0, 0, 0.6);
|
||||
color: white;
|
||||
font-size: 18px;
|
||||
font-weight: bold;
|
||||
z-index: 999;
|
||||
border-radius: 8px;
|
||||
opacity: 0.8;
|
||||
text-align: right;
|
||||
line-height: 1.4;
|
||||
pointer-events: none; /* Make it non-interactive */
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user