[선택약관 관련수정]

1. TButtonScroller.jsx
    1. Props 추가 및 kind로 구분하여 spotlight.focus변경.
2. TNewPopUp.jsx
    1.  758줄의 kind 추가하여 전달.
3. IntroPanel.new.jsx
    1.  자동팝업 종료후 체크박스에 포커스 이동처리
    2. selectAll에서 포커스 올렸을때 처리변경.
    3. Optional term 체크박스에서 하단으로 이동시 로직에 따른 체크박스 이동.
    4. 팝업에 agree버튼 및 실제 작동 함수 추가.
4.  TermsOfService.jsx
    1. 체크박스 및 문구 주석처리(추후 제거처리 필요, 완료 이후)
This commit is contained in:
junghoon86.park
2025-09-03 17:51:29 +09:00
parent bad391e73c
commit 1a42261b57
4 changed files with 101 additions and 55 deletions

View File

@@ -28,6 +28,7 @@ export default function TButtonScroller({
className,
resetScrollPosition,
forcedFocus = true,
kind,
}) {
const { getScrollTo, scrollTop } = useScrollTo();
@@ -90,9 +91,17 @@ export default function TButtonScroller({
if (!forcedFocus) return;
if (checkScrollPosition === "top") {
Spotlight.focus("spotlightId_TbuttonScrollerDown");
if (kind === "figmaTermsPopup") {
Spotlight.focus("figma-terms-agree");
} else {
Spotlight.focus("spotlightId_TbuttonScrollerDown");
}
} else if (checkScrollPosition === "bottom") {
Spotlight.focus("spotlightId_TbuttonScrollerUp");
if (kind === "figmaTermsPopup") {
Spotlight.focus("figma-terms-agree");
} else {
Spotlight.focus("spotlightId_TbuttonScrollerUp");
}
}
}, [checkScrollPosition, forcedFocus]);
return (

View File

@@ -222,7 +222,7 @@ const CLASS_MAPPINGS = {
optionalConfirm: {
info: "optionalConfirmInfo",
textLayer: "optionalConfirmTextLayer",
title: "optionalConfirmTitle",
title: "optionalConfirmTitle",
text: "optionalConfirmText",
buttonContainer: "optionalConfirmButtonContainer",
contentContainer: "optionalConfirmContentContainer" // 👈 추가
@@ -283,7 +283,7 @@ export default function TNewPopUp({
customPosition = false,
position = {},
onOptionalTermsClick, // Optional Terms 버튼용
onOptionalAgreeClick, // Agree 버튼용
onOptionalAgreeClick, // Agree 버튼용
onOptionalDeclineClick, // Not Now 버튼용
onIntroTermsAgreeClick, // introTerms Agree 버튼용
showAgreeButton = false,
@@ -327,14 +327,14 @@ export default function TNewPopUp({
let focusTarget = SpotlightIds.TPOPUP;
if (kind === 'introTermsPopup') {
focusTarget = 'introTermsAgreeBtn';
} else if (kind === 'optionalConfirm') {
} else if (kind === 'optionalConfirm') {
focusTarget = 'optionalConfirmAgreeBtn';
} else if (kind === 'figmaTermsPopup') {
focusTarget = 'figma-terms-close';
} else if (spotlightId) {
focusTarget = spotlightId;
}
const timerId = setTimeout(() => {
console.log("focusTarget is ", focusTarget);
Spotlight.focus(focusTarget);
@@ -359,10 +359,10 @@ export default function TNewPopUp({
// }
// }, [open, spotlightId]);
// 커스텀 스타일 생성
const customStyle = useMemo(() => {
// 커스텀 스타일 생성
const customStyle = useMemo(() => {
if (!customPosition) return {};
return {
position: position.position || 'fixed',
top: position.top,
@@ -487,23 +487,23 @@ export default function TNewPopUp({
}, [onIntroTermsAgreeClick]);
const _onSpotlightRight = useCallback(
(e) => {
if (onSpotlightRight) onSpotlightRight(e);
},
[onSpotlightRight]
);
const alertStyle = useMemo(() => {
if (kind === 'optionalConfirm') {
return {
bottom: 'unset',
transform: 'none'
};
}
return {};
}, [kind]);
(e) => {
if (onSpotlightRight) onSpotlightRight(e);
},
[onSpotlightRight]
);
const alertStyle = useMemo(() => {
if (kind === 'optionalConfirm') {
return {
bottom: 'unset',
transform: 'none'
};
}
return {};
}, [kind]);
if (!open) {
return null;
if (!open) {
return null;
}
@@ -514,7 +514,7 @@ export default function TNewPopUp({
type={type}
open={open}
className={classNames(css.tNewPopUp, css[kind], className)}
onClose={onClose}
onClose={onClose}
style={alertStyle}
>
<Container
@@ -614,7 +614,7 @@ export default function TNewPopUp({
})}
</OptionContainer>
)}
{/* optionalAgreement의 특별한 구조 처리 */}
{kind === "optionalAgreement" && (
<div className={getClassName(kind, "contentContainer")}>
@@ -622,11 +622,11 @@ export default function TNewPopUp({
</div>
)}
{/* 다른 종류들의 children */}
{kind !== "optionalAgreement" && kind !== "optionalConfirm" && kind !== "figmaTermsPopup" && children}
{hasIndicator && (
<>
{currentPage !== 0 && (
@@ -682,7 +682,7 @@ export default function TNewPopUp({
</TButton>
)}
</ButtonContainerComp>
)}
)}
{kind === "optionalConfirm" && (
<div className={getClassName(kind, "optionalConfirmContentContainer")}>
@@ -692,18 +692,18 @@ export default function TNewPopUp({
<OptionalConfirmButtonSection className={getClassName(kind, "optionalConfirmButtonSection")}>
<div className={getClassName(kind, "optionalConfirmLeftButtonSection")}>
<TButton
className={css.optionalTermsButton}
onClick={_onOptionalTermsClick}
className={css.optionalTermsButton}
onClick={_onOptionalTermsClick}
spotlightId="optionalConfirmTermsBtn"
type="terms"
ariaLabel={$L("Optional Terms")}
size="small"
>
<div className={css.optionalTermsTitle}>{$L("Optional Terms")}</div>
<div className={css.optionalTermsTitle}>{$L("Optional Terms")}</div>
</TButton>
</div>
<div className={getClassName(kind, "optionalConfirmRightButtonSection")}>
<TButton
<TButton
className={getClassName(kind, "optionalConfirmButton")}
onClick={_onOptionalAgreeClick}
role="button"
@@ -723,8 +723,8 @@ export default function TNewPopUp({
>
{$L("Not Now")}
</TButton>
</div>
</div>
</OptionalConfirmButtonSection>
</div>
)}
@@ -739,9 +739,10 @@ export default function TNewPopUp({
</div>
</div>
<div className={getClassName(kind, "contentBody")}>
<TButtonScroller
boxHeight={460}
width={844}
<TButtonScroller
boxHeight={460}
width={844}
kind={kind}
>
<div
className={getClassName(kind, "scrollerContent")}
@@ -775,4 +776,4 @@ export default function TNewPopUp({
</Container>
</Alert>
);
}
}

View File

@@ -79,7 +79,7 @@ export default function IntroPanel(props) {
"[IntroPanel.new] optionalTermsAvailable = true, 고급 IntroPanel 사용",
);
return <IntroPanelWithOptional {...props} />;
}
}
// 선택약관 포함 고급 IntroPanel 컴포넌트
function IntroPanelWithOptional({
@@ -608,6 +608,11 @@ function IntroPanelWithOptional({
// 3초 후 자동 닫기
popupTimeoutRef.current = setTimeout(() => {
setRequiredAgreePopup(false);
if (!termsChecked) {
Spotlight.focus("termsCheckbox");
} else if (!privacyChecked) {
Spotlight.focus("privacyCheckbox");
}
}, 3000);
return;
@@ -837,6 +842,31 @@ function IntroPanelWithOptional({
Spotlight.focus();
}, [popupVisible]);
//20250903 pjh
//selectAll에서 포커스 올렸을때 처리 변경.
const onSelectAllSpotlightUp = () => {
const focusTimer = setTimeout(() => {
Spotlight.focus("optionalCheckbox");
}, 100);
return () => {
clearTimeout(focusTimer);
};
};
//Optional terms 체크박스가 체크가 되어있을때 아래로 내리면(3개전부 체크기준) agree로 가고, 아닐경우 select all로 포커스이동해야함.
const onOptionalTermSpotlightDown = () => {
const focusTimer = setTimeout(() => {
if (termsChecked && privacyChecked && optionalChecked) {
Spotlight.focus("agreeButton");
} else {
Spotlight.focus("selectAllCheckbox");
}
}, 100);
return () => {
clearTimeout(focusTimer);
};
};
// useEffect(() => {
// if (regDeviceInfoData && regDeviceInfoData.retCode === 0) {
// dispatch(setHidePopup());
@@ -944,6 +974,7 @@ function IntroPanelWithOptional({
className={css.customeCheckbox}
selected={optionalChecked}
onToggle={handleOptionalToggle}
onSpotlightDown={onOptionalTermSpotlightDown}
spotlightId="optionalCheckbox"
ariaLabel={$L("Optional Terms checkbox")}
/>
@@ -968,6 +999,7 @@ function IntroPanelWithOptional({
className={css.selectAllCheckbox}
selected={selectAllChecked}
onToggle={handleSelectAllToggle}
onSpotlightUp={onSelectAllSpotlightUp}
spotlightId="selectAllCheckbox"
ariaLabel={$L("Select All checkbox")}
/>
@@ -1033,6 +1065,8 @@ function IntroPanelWithOptional({
open={popupVisible}
kind="figmaTermsPopup"
title={getTermsPopupTitle(currentTerms)}
showAgreeButton
onAgreeClick={handleTermsAgree}
text={currentTerms?.trmsCntt || ""}
onClose={onClose} // Close 버튼 핸들러 연결
/>
@@ -1095,3 +1129,4 @@ function IntroPanelWithOptional({
</Region>
);
}

View File

@@ -164,12 +164,12 @@ export default function TermsOfService({ title, cbScrollTo }) {
optionalTermsAgree,
isOptionalChecked
});
if (optionalTermsAgree) {
console.log("[TermsOfService] → optional-disagree-button (이미 동의함)");
return "optional-disagree-button"; // 이미 동의한 경우
}
}
//미동의 상태에서 체크박스 선택 여부에 따라 결정
if (isOptionalChecked) {
console.log("[TermsOfService] → optional-agree-button (체크박스 선택됨)");
@@ -198,7 +198,7 @@ export default function TermsOfService({ title, cbScrollTo }) {
// 초기 포커스: 체크박스로 이동
const initialFocusTarget = getOptionalTermsFocusTarget();
Spotlight.focus(initialFocusTarget);
// 0.5초 후 Agree 버튼으로 포커스 이동 (미동의 상태이고 체크박스 미선택인 경우)
if (!optionalTermsAgree && !isOptionalChecked) {
setTimeout(() => {
@@ -258,7 +258,7 @@ export default function TermsOfService({ title, cbScrollTo }) {
}
// 약관 철회
const onExit = useCallback(() => {
const onExit = useCallback(() => {
dispatch(setHidePopup());
dispatch(
setMyTermsWithdraw(
@@ -306,10 +306,10 @@ export default function TermsOfService({ title, cbScrollTo }) {
setLocalOptionalTermsAgree(true);
setIsOptionalChecked(true);
console.log("Optional terms agreement successful.");
// ✅ IntroPanel과 동일한 방식으로 Redux 상태 직접 업데이트 (API 호출 없이)
dispatch(updateOptionalTermsAgreement(true));
setAgreePopup(true);
if (agreePopupTimeoutRef.current) {
@@ -439,7 +439,7 @@ export default function TermsOfService({ title, cbScrollTo }) {
{termsList[selectedTab]?.trmsTpCd === "MST00405" ? (
<div className={css.optionalContainer}>
<div className={css.checkboxContainer}>
{/* <div className={css.checkboxContainer}>
<TCheckBoxSquare
selected={optionalTermsAgree || isOptionalChecked}
onToggle={handleOptionalCheckboxToggle}
@@ -456,7 +456,7 @@ export default function TermsOfService({ title, cbScrollTo }) {
"I agree to receive Personalized Recommendations and Advertisements"
)}
</div>
</div>
</div> */}
<div className={css.buttonContainer}>
<TButton
onClick={handleOptionalAgree}
@@ -489,10 +489,10 @@ export default function TermsOfService({ title, cbScrollTo }) {
"You can change your agreement to the terms and conditions in your LG Account."
)
: termsList[selectedTab]?.termsId === "20230908001_US"
? $L(
"If you do not wish to agree to these terms, please proceed to the following link."
)
: null}
? $L(
"If you do not wish to agree to these terms, please proceed to the following link."
)
: null}
</div>
)}
<TButton
@@ -595,3 +595,4 @@ export default function TermsOfService({ title, cbScrollTo }) {
</>
);
}