[선택약관] 선택약관 저장값변경.

- 홈배너에서 agree시 선택약관 값 Y로 변경되도록 변경.
 - 텀즈오브서비스에서도 선택약관 버튼눌렀을시에 맞춰 작동하도록 변경
This commit is contained in:
junghoon86.park
2025-09-23 14:32:22 +09:00
parent 794c91c909
commit 3d47774646
2 changed files with 91 additions and 37 deletions

View File

@@ -18,6 +18,7 @@ import {
} from '@enact/spotlight/SpotlightContainerDecorator';
import Spottable from '@enact/spotlight/Spottable';
import { types } from '../../../actions/actionTypes';
import {
changeAppStatus,
handleOptionalTermsAgree as handleOptionalTermsAgreeAction,
@@ -190,6 +191,7 @@ export default function HomeBanner({
});
const termsLoading = useSelector((state) => state.common.termsLoading);
const isGnbOpened = useSelector((state) => state.common.isGnbOpened);
const currentTermsFlag = useSelector((state) => state.common.termsFlag);
// 선택약관 동의여부
const introTermsAgree = useSelector(
(state) => state.common.termsFlag.optionalTerms
@@ -345,6 +347,13 @@ export default function HomeBanner({
const handleOptionalAgreeClick = useCallback(() => {
handleOptionalAgree();
setIsOptionalConfirmVisible(false);
dispatch({
type: types.GET_TERMS_AGREE_YN_SUCCESS,
payload: {
...currentTermsFlag,
optionalTerms: "Y",
},
});
}, [handleOptionalAgree]);
const handleOptionalDeclineClick = useCallback(() => {

View File

@@ -4,38 +4,49 @@ import React, {
useMemo,
useRef,
useState,
} from "react";
} from 'react';
import { useDispatch, useSelector } from "react-redux";
import classnames from 'classnames';
import {
useDispatch,
useSelector,
} from 'react-redux';
import Spotlight from "@enact/spotlight";
import { Job } from "@enact/core/util";
import classnames from "classnames";
import { Job } from '@enact/core/util';
import Spotlight from '@enact/spotlight';
import { types } from '../../../../actions/actionTypes';
import {
changeLocalSettings,
getTermsAgreeYn,
launchMembershipApp,
setExitApp,
setHidePopup,
setShowPopup,
getTermsAgreeYn,
updateOptionalTermsAgreement,
} from "../../../../actions/commonActions";
} from '../../../../actions/commonActions';
import {
setMyTermsWithdraw,
setMyPageTermsAgree,
} from "../../../../actions/myPageActions";
import TBody from "../../../../components/TBody/TBody";
import TButton, { TYPES } from "../../../../components/TButton/TButton";
import TButtonScroller from "../../../../components/TButtonScroller/TButtonScroller";
import TButtonTab from "../../../../components/TButtonTab/TButtonTab";
import THeader from "../../../../components/THeader/THeader";
import TPopUp from "../../../../components/TPopUp/TPopUp";
import { initialLocalSettings } from "../../../../reducers/localSettingsReducer";
import * as Config from "../../../../utils/Config";
import { $L, scaleH, scaleW } from "../../../../utils/helperMethods";
import css from "./TermsOfService.module.less";
import TCheckBoxSquare from "../../../../components/TCheckBox/TCheckBoxSquare";
setMyTermsWithdraw,
} from '../../../../actions/myPageActions';
import TBody from '../../../../components/TBody/TBody';
import TButton, { TYPES } from '../../../../components/TButton/TButton';
import TButtonScroller
from '../../../../components/TButtonScroller/TButtonScroller';
import TButtonTab from '../../../../components/TButtonTab/TButtonTab';
import TCheckBoxSquare from '../../../../components/TCheckBox/TCheckBoxSquare';
import THeader from '../../../../components/THeader/THeader';
import TPopUp from '../../../../components/TPopUp/TPopUp';
import {
initialLocalSettings,
} from '../../../../reducers/localSettingsReducer';
import * as Config from '../../../../utils/Config';
import {
$L,
scaleH,
scaleW,
} from '../../../../utils/helperMethods';
import css from './TermsOfService.module.less';
export default function TermsOfService({ title, cbScrollTo }) {
const [selectedTab, setSelectedTab] = useState(0);
@@ -45,7 +56,8 @@ export default function TermsOfService({ title, cbScrollTo }) {
const [closePopUp, setClosePopUp] = useState(false);
const [resetScroll, setResetScroll] = useState(false);
const [agreePopup, setAgreePopup] = useState(false);
const [isOptionalChecked, setIsOptionalChecked] = useState(optionalTermsAgree);
const [isOptionalChecked, setIsOptionalChecked] =
useState(optionalTermsAgree);
const [optionalDisagreePopupOpen, setOptionalDisagreePopupOpen] =
useState(false);
const [showCheckboxAlert, setShowCheckboxAlert] = useState(false);
@@ -53,12 +65,16 @@ export default function TermsOfService({ title, cbScrollTo }) {
const { popupVisible } = useSelector((state) => state.common?.popup);
const { optionalTermsAgree } = useSelector((state) => state.common);
console.log("[TermsOfService] 현재 optionalTermsAgree 상태:", optionalTermsAgree);
console.log(
"[TermsOfService] 현재 optionalTermsAgree 상태:",
optionalTermsAgree
);
const termsData = useSelector((state) => state.home.termsData);
const empTermsData = useSelector((state) => state.emp.empTermsData);
const webOSVersion = useSelector(
(state) => state.common.appStatus.webOSVersion
);
const currentTermsFlag = useSelector((state) => state.common.termsFlag);
const [spotlightDisabled, setSpotlightDisabled] = useState(true);
const [termsList, setTermsList] = useState([]);
const termsListRef = useRef(termsList);
@@ -79,7 +95,10 @@ export default function TermsOfService({ title, cbScrollTo }) {
// ✅ fetchCurrentUserHomeTerms 호출 제거 - TV 환경에서 서버 동기화 지연 방지
useEffect(() => {
console.log("[TermsOfService] optionalTermsAgree 상태 변경:", optionalTermsAgree);
console.log(
"[TermsOfService] optionalTermsAgree 상태 변경:",
optionalTermsAgree
);
setLocalOptionalTermsAgree(optionalTermsAgree);
setIsOptionalChecked(optionalTermsAgree);
}, [optionalTermsAgree]);
@@ -162,7 +181,7 @@ export default function TermsOfService({ title, cbScrollTo }) {
const getOptionalTermsFocusTarget = useCallback(() => {
console.log("[TermsOfService] 포커스 대상 결정:", {
optionalTermsAgree,
isOptionalChecked
isOptionalChecked,
});
if (optionalTermsAgree) {
@@ -175,7 +194,9 @@ export default function TermsOfService({ title, cbScrollTo }) {
console.log("[TermsOfService] → optional-agree-button (체크박스 선택됨)");
return "optional-agree-button"; // 체크박스 선택됨 → Agree 버튼으로
} else {
console.log("[TermsOfService] → optional-agree-checkbox (체크박스 미선택)");
console.log(
"[TermsOfService] → optional-agree-checkbox (체크박스 미선택)"
);
return "optional-agree-checkbox"; // 체크박스 미선택 → 체크박스로
}
}, [optionalTermsAgree, isOptionalChecked]);
@@ -212,13 +233,19 @@ export default function TermsOfService({ title, cbScrollTo }) {
return () => {
if (focusJob.current) {
focusJob.current.stop();
};
}
// if (timeoutRef.current) {
// clearTimeout(timeoutRef.current);
// timeoutRef.current = null;
// }
};
}, [selectedTab, termsList, optionalTermsAgree, isOptionalChecked, getOptionalTermsFocusTarget]); // 3단계: 의존성 배열 업데이트
}, [
selectedTab,
termsList,
optionalTermsAgree,
isOptionalChecked,
getOptionalTermsFocusTarget,
]); // 3단계: 의존성 배열 업데이트
useEffect(() => {
if (!spotlightDisabled) {
@@ -309,7 +336,13 @@ export default function TermsOfService({ title, cbScrollTo }) {
// ✅ IntroPanel과 동일한 방식으로 Redux 상태 직접 업데이트 (API 호출 없이)
dispatch(updateOptionalTermsAgreement(true));
dispatch({
type: types.GET_TERMS_AGREE_YN_SUCCESS,
payload: {
...currentTermsFlag,
optionalTerms: "Y",
},
});
setAgreePopup(true);
if (agreePopupTimeoutRef.current) {
@@ -334,8 +367,10 @@ export default function TermsOfService({ title, cbScrollTo }) {
}, [dispatch, termsList, isOptionalChecked]);
const handleOptionalDisagree = useCallback(() => {
setOptionalDisagreePopupOpen(true);
}, []);
if (agreePopup === false) {
setOptionalDisagreePopupOpen(true);
}
}, [agreePopup]);
const confirmOptionalDisagree = useCallback(() => {
const currentTermsList = termsListRef.current;
@@ -365,6 +400,13 @@ export default function TermsOfService({ title, cbScrollTo }) {
dispatch(updateOptionalTermsAgreement(false));
setLocalOptionalTermsAgree(false);
setIsOptionalChecked(false);
dispatch({
type: types.GET_TERMS_AGREE_YN_SUCCESS,
payload: {
...currentTermsFlag,
optionalTerms: "N",
},
});
} else {
console.error("Optional terms withdrawal failed:", response);
}
@@ -402,7 +444,11 @@ export default function TermsOfService({ title, cbScrollTo }) {
<THeader title={title} ariaLabel={$L("TERMS OF SERVICE, heading 1")} />
<TBody cbScrollTo={cbScrollTo} className={css.tBody}>
<div className={css.termsContainer}>
<div className={classnames(css.contentsBox, { [css.optionalTabActive]: isOptionalTab })}>
<div
className={classnames(css.contentsBox, {
[css.optionalTabActive]: isOptionalTab,
})}
>
<TButtonTab
contents={tabList}
className={css.tTab}
@@ -415,7 +461,8 @@ export default function TermsOfService({ title, cbScrollTo }) {
<div
className={css.text}
dangerouslySetInnerHTML={{
__html: termsList && termsList[selectedTab]?.termsContents,
__html:
termsList && termsList[selectedTab]?.termsContents,
}}
/>
</div>
@@ -429,7 +476,8 @@ export default function TermsOfService({ title, cbScrollTo }) {
<div
className={css.text}
dangerouslySetInnerHTML={{
__html: termsList && termsList[selectedTab]?.termsContents,
__html:
termsList && termsList[selectedTab]?.termsContents,
}}
/>
</div>
@@ -462,9 +510,7 @@ export default function TermsOfService({ title, cbScrollTo }) {
onClick={handleOptionalAgree}
className={css.agreeButton}
spotlightId="optional-agree-button"
spotlightDisabled={
spotlightDisabled || optionalTermsAgree
}
spotlightDisabled={spotlightDisabled || optionalTermsAgree}
disabled={localOptionalTermsAgree}
>
{$L("Agree")}
@@ -595,4 +641,3 @@ export default function TermsOfService({ title, cbScrollTo }) {
</>
);
}