diff --git a/com.twin.app.shoptime/src/components/Optional/OptionalTermsConfirm.jsx b/com.twin.app.shoptime/src/components/Optional/OptionalTermsConfirm.jsx index 46d7eefe..99e1be5f 100644 --- a/com.twin.app.shoptime/src/components/Optional/OptionalTermsConfirm.jsx +++ b/com.twin.app.shoptime/src/components/Optional/OptionalTermsConfirm.jsx @@ -1,106 +1,204 @@ // src/components/Optional/OptionalTermsConfirm.jsx -import React, { useEffect, useCallback } from "react"; -import { useDispatch, useSelector } from "react-redux"; -import classNames from "classnames"; +import React, { useEffect, useCallback, useState } from 'react'; +import { useDispatch, useSelector } from 'react-redux'; +import TPopUp from '../TPopUp/TPopUp'; +import TButton from '../TButton/TButton'; +import TCheckBoxSquare from '../TCheckBox/TCheckBoxSquare'; +import TButtonScroller from '../TButtonScroller/TButtonScroller'; +import { $L, scaleH, scaleW } from '../../utils/helperMethods'; +import { setHidePopup } from '../../actions/commonActions'; +import { setMyPageTermsAgree } from '../../actions/myPageActions'; +import css from './OptionalTermsConfirm.module.less'; -import TPopUp from "../TPopUp/TPopUp"; -import TCheckBoxSquare from "../TCheckBox/TCheckBoxSquare"; -import TButton from "../TButton/TButton"; -import { $L } from "../../utils/helperMethods"; -import css from "./OptionalTermsConfirm.module.less"; +const OptionalTermsConfirm = ({ open }) => { + const dispatch = useDispatch(); -export default function OptionalTermsConfirm({ - className, - open = false, - onAgree, - onNotNow, - onToggleOptionalTerms, - optionalTermsSelected = false, - spotlightId = "optional-terms-confirm", - onClose, - ...rest -}) { + const [isChecked, setIsChecked] = useState(false); + const [isTermsPopupVisible, setIsTermsPopupVisible] = useState(false); + const [isWarningPopupVisible, setIsWarningPopupVisible] = useState(false); useEffect(() => { - console.log("OptionalTermsConfirm", optionalTermsSelected); - }, [optionalTermsSelected]); + console.log("OptionalTermsTest - in Component Rendered"); + }, []); + + const optionalTermsData = useSelector((state) => + state.home.termsData?.data?.terms.find(term => term.trmsTpCd === "MST00405") + ); + + const handleMainPopupClose = useCallback(() => { + dispatch(setHidePopup()); + }, [dispatch]); + + const handleCheckboxToggle = useCallback(({ selected }) => { + setIsChecked(selected); + }, []); + + const handleViewTermsClick = useCallback(() => { + setIsTermsPopupVisible(true); + }, []); + + const handleCloseTermsPopup = useCallback((e) => { + if (e) { + e.stopPropagation(); + } + setIsTermsPopupVisible(false); + }, []); const handleAgree = useCallback(() => { - if (onAgree) { - onAgree(); - } - }, [onAgree]); + if (isChecked) { + // 약관 동의할 항목들 (string array) + const termsList = ["TID0000222", "TID0000223", "TID0000232"]; + + // 동의하지 않을 항목들 (빈 배열) + const notTermsList = []; - const handleNotNow = useCallback(() => { - if (onNotNow) { - onNotNow(); - } - }, [onNotNow]); + console.log('약관 동의 API 호출 파라미터:', { termsList, notTermsList }); - const handleTermsToggle = useCallback(({ selected }) => { - if (onToggleOptionalTerms) { - onToggleOptionalTerms(selected); + const callback = (response) => { + if (response.retCode === "000" || response.retCode === 0) { + console.log('약관 동의 성공:', response); + } else { + console.error('약관 동의 실패:', response); + } + }; + + dispatch(setMyPageTermsAgree({ termsList, notTermsList }, callback)); + dispatch(setHidePopup()); + } else { + setIsWarningPopupVisible(true); } - }, [onToggleOptionalTerms]); + }, [isChecked, dispatch]); + + const handleCloseWarningPopup = useCallback(() => { + setIsWarningPopupVisible(false); + }, []); + + const handleDontAskAgain = () => { + console.log("Don't Ask Again 처리 필요"); + dispatch(setHidePopup()); + }; + + if (isTermsPopupVisible) { + return ( + + {optionalTermsData && ( +
+
{$L("Optional Terms")}
+ +
+ +
+ )} + + ); + } + + if (isWarningPopupVisible) { + return ( + + ); + } + return ( -
-
- {$L("Get recommendations, special offers, and ads tailored just for you.")} -
- -
-
-
- +
+
+
+ -
- {$L("Optional Terms")} -
+ +
Optional Terms
+
- + +
+
+ Get recommendations, special offers, and ads tailored just for you. +
+
+
- - {$L("Agree")} - - - - {$L("Not Now")} - +
+ + {$L('Agree')} + + + {$L('Not Now')} + + + {$L("Don't Ask Again")} + +
); -} \ No newline at end of file +}; + +export default OptionalTermsConfirm; \ No newline at end of file diff --git a/com.twin.app.shoptime/src/components/Optional/OptionalTermsConfirm.module.less b/com.twin.app.shoptime/src/components/Optional/OptionalTermsConfirm.module.less index b68edf6b..de35cd42 100644 --- a/com.twin.app.shoptime/src/components/Optional/OptionalTermsConfirm.module.less +++ b/com.twin.app.shoptime/src/components/Optional/OptionalTermsConfirm.module.less @@ -1,236 +1,191 @@ -@import "../../style/CommonStyle.module.less"; -@import "../../style/utils.module.less"; +// src/components/Optional/OptionalTermsConfirm.module.less +.testPopup { + width: 958px; + height: 300px; + background-color: white !important; + border-radius: 12px; + box-shadow: 0 20px 70px rgba(2, 3, 3, 0.7) !important; + position: absolute !important; + top: 45% !important; + left: 450px !important; -// Optional Terms Confirm 팝업 전용 전역 스타일 - 화면 하단 위치 조정 -:global { - // 팝업이 화면 하단에 나타나도록 조정 - .src_components_Optional_OptionalTermsConfirm_optionalTermsPopup { - position: fixed !important; - left: 120px !important; // GNB 너비만큼 오른쪽으로 이동 - bottom: 0 !important; - top: auto !important; - right: auto !important; - width: calc(100vw - 120px) !important; // GNB 너비를 제외한 나머지 영역 - height: auto !important; - transform: none !important; - margin: 0 !important; - border-radius: 0 !important; - background: #E6EBF0; - box-shadow: 0px 20px 12px rgba(0, 0, 0, 0.30); } - // 팝업 컨테이너들의 위치 조정 - .enact_ui_Transition_Transition_transition.enact_sandstone_Popup_Popup_popupTransitionContainer { - align-items: flex-end !important; - justify-content: flex-start !important; - padding-left: 120px !important; // GNB 너비만큼 패딩 - } -} - -.optionalTermsPopup { - background: #E6EBF0; - box-shadow: 0px 20px 12px rgba(0, 0, 0, 0.30); - // TPopUp의 기본 스타일을 하단 팝업으로 오버라이드 - .popupContent { - width: 100%; - height: 140px; - padding: 25px 140px; - .flex(@alignCenter: center, @justifyCenter: flex-start); - gap: 20px; - - .description { - .flex(@alignCenter: center, @justifyCenter: flex-end); - color: black; - font-size: 26px; - font-family: 'LG Smart UI', sans-serif; - font-weight: 400; - word-wrap: break-word; - line-height: 1.3; - flex: 0 0 auto; - } - - .rightSection { + + .contentContainer { + // width: 958px; + // height: 310px; + padding: 60px 57px 40px 57px; + background: #E6EBF0; + box-shadow: 0px 20px 12px rgba(0, 0, 0, 0.30); + border-radius: 4px; + display: inline-flex; + justify-content: flex-start; + align-items: flex-start; + box-sizing: border-box; + + .mainContent { flex: 1 1 0; - .flex(@alignCenter: center, @justifyCenter: space-between); - - .termsSection { - .flex(@direction: column, @alignCenter: center, @justifyCenter: flex-start); + display: inline-flex; + flex-direction: column; + justify-content: center; + align-items: flex-start; + gap: 30px; + + .checkboxSection { + align-self: stretch; + display: flex; + flex-direction: column; + justify-content: flex-start; + align-items: center; gap: 10px; - - .termsButton { - .flex(@alignCenter: center, @justifyCenter: space-between); - width: 320px; - height: 60px; - padding: 0 30px; - background: white; - border-radius: 6px; - border: 1px solid #CFCFCF; - + + .checkboxArea { + min-height: 120px; + display: inline-flex; + justify-content: flex-start; + align-items: center; + gap: 20px; + .checkbox { - width: 27px; - height: 27px; - border-radius: 50%; - border: 1.82px solid black; + min-width: 45px; + min-height: 45px; + flex-shrink: 0; } - - .termsText { - color: #1A1A1A; - font-size: 22px; - font-family: 'LG Smart UI', sans-serif; - font-weight: 700; - line-height: 35px; - word-wrap: break-word; - flex: 1; - margin-left: 10px; + + // TButton으로 변경되어 포커스 가능 + .termBox { + min-width: 530px; + min-height: 120px; + padding-left: 50px !important; + padding-right: 50px !important; + background: white !important; + box-shadow: 0px 0px 30px rgba(0, 0, 0, 0.20); + border-radius: 6px; + outline: 1px #CFCFCF solid; + outline-offset: -1px; + display: flex !important; + justify-content: space-between !important; + align-items: center !important; + border: none !important; + + // 포커스 스타일 추가 + &:focus { + outline: 3px solid #C70850 !important; + outline-offset: 2px !important; + } + + .termTitle { + color: #1A1A1A; + font-size: 35px; + font-family: 'LG Smart UI'; + font-weight: 700; + line-height: 35px; + } + + .expandIcon { + min-width: 37px; + min-height: 37px; + position: relative; + border-radius: 100px; + outline: 2.5px black solid; + outline-offset: -2.5px; + flex-shrink: 0; + + .arrow { + width: 14.66px; + height: 6.99px; + left: 16.01px; + top: 25.83px; + position: absolute; + transform: rotate(-90deg); + transform-origin: top left; + outline: 2.5px black solid; + outline-offset: -1.25px; + } + } } } } - + + .descriptionSection { + align-self: stretch; + padding-top: 20px; + border-top: 1px #C5C6C9 solid; + display: inline-flex; + justify-content: center; + align-items: center; + + .description { + display: flex; + justify-content: center; + flex-direction: column; + color: black; + font-size: 26px; + font-family: 'LG Smart UI'; + font-weight: 400; + } + } + .buttonSection { - .flex(@alignCenter: center, @justifyCenter: center); - gap: 12px; - - .agreeButton { - width: 160px; - height: 50px; - max-width: 450px; - min-width: 150px; - background: #C70850; - box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.50); - border-radius: 12px; - - > div { - text-align: center; - color: white; - font-size: 20px; - font-family: 'LG Smart UI', sans-serif; - font-weight: 700; - word-wrap: break-word; + align-self: stretch; + display: flex; + flex-direction: column; + justify-content: flex-start; + align-items: flex-start; + gap: 10px; + + .buttonGroup { + align-self: stretch; + display: inline-flex; + justify-content: center; + align-items: center; + gap: 12px; + + .agreeButton, .notNowButton, .dontAskButton { + min-width: 300px; + min-height: 80px; + max-width: 450px; + flex: 1; + border-radius: 12px; + display: flex; + justify-content: center; + align-items: center; + + > div { + text-align: center; + font-size: 30px; + font-family: 'LG Smart UI'; + font-weight: 700; + } } - - &:disabled { - background: #777D8A; - box-shadow: none; - + + .agreeButton { + background: #C70850 !important; + box-shadow: 0px 0px 50px rgba(0, 0, 0, 0.50); + + > div { + color: white; + } + } + + .notNowButton { + background: #777D8A !important; + > div { color: #E6E6E6; } } - } - - .notNowButton { - width: 160px; - height: 50px; - max-width: 450px; - min-width: 150px; - background: #777D8A; - border-radius: 12px; - - > div { - text-align: center; - color: #E6E6E6; - font-size: 20px; - font-family: 'LG Smart UI', sans-serif; - font-weight: 700; - word-wrap: break-word; - } - - &:hover { - background: #8A8F9C; - } - - &:focus { - background: #8A8F9C; - box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.30); - } - } - } - } - } -} - -// 반응형 대응 -@media (max-width: 1366px) { - .optionalTermsPopup { - .popupContent { - padding: 20px 100px; - - .description { - font-size: 24px; - } - - .rightSection { - .termsSection { - .termsButton { - width: 280px; - height: 55px; - - .termsText { - font-size: 20px; - } - } - } - - .buttonSection { - .agreeButton, - .notNowButton { - width: 140px; - height: 45px; - + + .dontAskButton { + background: rgba(122, 128, 141, 0.30) !important; + > div { - font-size: 18px; + opacity: 0.30; + color: #E6E6E6; } } } } } - } -} - -@media (max-width: 1024px) { - .optionalTermsPopup { - .popupContent { - height: 120px; - padding: 15px 60px; - gap: 15px; - - .description { - font-size: 22px; - } - - .rightSection { - .termsSection { - .termsButton { - width: 250px; - height: 50px; - padding: 0 20px; - - .checkbox { - width: 24px; - height: 24px; - } - - .termsText { - font-size: 18px; - line-height: 30px; - } - } - } - - .buttonSection { - gap: 8px; - - .agreeButton, - .notNowButton { - width: 120px; - height: 40px; - - > div { - font-size: 16px; - } - } - } - } - } - } -} \ No newline at end of file + } \ No newline at end of file diff --git a/com.twin.app.shoptime/src/components/TPopUp/TNewPopUp.jsx b/com.twin.app.shoptime/src/components/TPopUp/TNewPopUp.jsx new file mode 100644 index 00000000..401de234 --- /dev/null +++ b/com.twin.app.shoptime/src/components/TPopUp/TNewPopUp.jsx @@ -0,0 +1,531 @@ +import React, { useCallback, useEffect, useMemo, useState } from "react"; + +import classNames from "classnames"; +import { useDispatch, useSelector } from "react-redux"; + +import Alert from "@enact/sandstone/Alert"; +import Spotlight from "@enact/spotlight"; +import SpotlightContainerDecorator from "@enact/spotlight/SpotlightContainerDecorator"; +import Spottable from "@enact/spotlight/Spottable"; + +import defaultImageItem from "../../../assets/images/img-thumb-empty-product@3x.png"; +import { cancelFocusElement, focusElement } from "../../actions/commonActions"; +import { SpotlightIds } from "../../utils/SpotlightIds"; +import CustomImage from "../CustomImage/CustomImage"; +import TButton from "../TButton/TButton"; +import css from "./TNewPopUp.module.less"; +import { $L } from "../../utils/helperMethods"; + +const Container = SpotlightContainerDecorator( + { enterTo: "default-element" }, + Spottable("div") +); + +const OptionContainer = SpotlightContainerDecorator( + { enterTo: "last-focused" }, + Spottable("ul") +); + +const ButtonContainer = SpotlightContainerDecorator("div"); +const ButtonContainerNegative = SpotlightContainerDecorator( + { defaultElement: `[data-spotlight-id="${"tPopupBtn2"}"]` }, + "div" +); +const SpottableComponent = Spottable("li"); +const SpottableDiv = Spottable("div"); + +const KINDS = [ + "textPopup", + "termsPopup", + "introTermsPopup", + "optionPopup", + "eventBannerPopup", + "supportPopup", + "exitPopup", + "couponPopup", + "mobileSendPopup", + "qrPopup", + "checkoutTermsPopup", + "scrollPopup", + "watchPopup", + "setPinCodePopup", + "descriptionPopup", + "errorPopup", + "orderDetailPopup", + "returnExchangePopup", + "orderCancelPopup", + "cancelConfirmPopup", + "trackPackagePopup", + "optionalAgreement", + "normal", +]; + +// 각 kind별 클래스명 매핑 +const CLASS_MAPPINGS = { + introTermsPopup: { + info: "introTermsInfo", + textLayer: "commonTextLayer", + title: "commonTitle", + text: "commonText", + buttonContainer: "introTermsButtonContainer" + }, + descriptionPopup: { + info: "descriptionInfo", + textLayer: "commonTextLayer", + title: "commonTitle", + text: "commonText", + buttonContainer: "descriptionButtonContainer", + img: "descriptionImg" + }, + textPopup: { + info: "textExitInfo", + textLayer: "commonTextLayer", + title: "commonTitle", + text: "textExitText", + buttonContainer: "textExitButtonContainer" + }, + exitPopup: { + info: "textExitInfo", + textLayer: "commonTextLayer", + title: "commonTitle", + text: "textExitText", + buttonContainer: "textExitButtonContainer" + }, + optionPopup: { + info: "optionInfo", + textLayer: "commonTextLayer", + title: "commonTitle", + text: "commonText", + buttonContainer: "optionButtonContainer", + optionLayer: "optionLayer", + option: "optionChoice", + img: "optionImg" + }, + eventBannerPopup: { + info: "eventBannerInfo", + textLayer: "commonTextLayer", + title: "commonTitle", + text: "commonText", + buttonContainer: "eventBannerButtonContainer" + }, + supportPopup: { + info: "supportInfo", + textLayer: "commonTextLayer", + title: "commonTitle", + text: "commonText", + buttonContainer: "supportButtonContainer" + }, + couponPopup: { + info: "couponInfo", + textLayer: "commonTextLayer", + title: "commonTitle", + text: "commonText", + buttonContainer: "couponButtonContainer" + }, + mobileSendPopup: { + info: "mobileSendInfo", + textLayer: "commonTextLayer", + title: "commonTitle", + text: "commonText", + buttonContainer: "mobileSendButtonContainer" + }, + qrPopup: { + info: "qrInfo", + textLayer: "commonTextLayer", + title: "commonTitle", + text: "commonText", + buttonContainer: "qrButtonContainer" + }, + checkoutTermsPopup: { + info: "checkoutTermsInfo", + textLayer: "commonTextLayer", + title: "checkoutTermsTitle", + text: "checkoutTermsText", + buttonContainer: "checkoutTermsButtonContainer" + }, + scrollPopup: { + info: "scrollInfo", + textLayer: "commonTextLayer", + title: "commonTitle", + text: "commonText", + buttonContainer: "scrollButtonContainer" + }, + watchPopup: { + info: "watchInfo", + textLayer: "watchTextLayer", + title: "watchTitle", + text: "watchText", + buttonContainer: "watchButtonContainer", + thumbnail: "watchThumbnail" + }, + setPinCodePopup: { + info: "setPinCodeInfo", + textLayer: "commonTextLayer", + title: "commonTitle", + text: "setPinCodeText", + buttonContainer: "setPinCodeButtonContainer" + }, + errorPopup: { + info: "errorInfo", + textLayer: "commonTextLayer", + title: "commonTitle", + text: "errorText", + buttonContainer: "errorButtonContainer" + }, + orderCancelPopup: { + info: "orderCancelInfo", + textLayer: "commonTextLayer", + title: "commonTitle", + text: "orderCancelText", + buttonContainer: "orderCancelButtonContainer" + }, + returnExchangePopup: { + info: "returnExchangeInfo", + textLayer: "commonTextLayer", + title: "commonTitle", + text: "returnExchangeText", + buttonContainer: "returnExchangeButtonContainer" + }, + trackPackagePopup: { + info: "trackPackageInfo", + textLayer: "commonTextLayer", + title: "commonTitle", + text: "trackPackageText", + buttonContainer: "trackPackageButtonContainer" + }, + cancelConfirmPopup: { + info: "cancelConfirmInfo", + textLayer: "commonTextLayer", + title: "commonTitle", + text: "cancelConfirmText", + buttonContainer: "cancelConfirmButtonContainer" + }, + optionalAgreement: { + info: "optionalAgreementInfo", + textLayer: "optionalAgreementTextLayer", + title: "commonTitle", + text: "optionalAgreementText", + buttonContainer: "optionalAgreementButtonContainer", + contentContainer: "optionalAgreementContentContainer" + } +}; + +// 기본값 설정 +const getClassName = (kind, element) => { + const mapping = CLASS_MAPPINGS[kind]; + if (mapping && mapping[element]) { + return css[mapping[element]]; + } + // 기본값 반환 (기존 클래스명) + return css[element]; +}; + +export default function TNewPopUp({ + kind, + children, + onExit, + onClick, + currentPage, + onRightClick, + onLeftClick, + itemLength, + onClose, + hasButton, + hasText, + hasOnClose = false, + hasIndicator, + hasLogo, + hasThumbnail, + thumbnail, + logo, + className, + button1Text, + button2Text, + open, + title, + text, + type = "overlay", + options, + optionClick, + selectedIndex, + spotlightId, + onSpotlightRight, + ...rest +}) { + const dispatch = useDispatch(); + const popupVisible = useSelector((state) => state.common.popup.popupVisible); + const httpHeader = useSelector((state) => state.common.httpHeader); + + useEffect(() => { + if (popupVisible) { + if (spotlightId) { + const timerId = setTimeout(() => { + Spotlight.focus(spotlightId); + }, 0); + + return () => { + clearTimeout(timerId); + }; + } + const timerId = setTimeout(() => { + Spotlight.focus(SpotlightIds.TPOPUP); + }, 0); + + return () => { + clearTimeout(timerId); + }; + } + }, [spotlightId, popupVisible]); + + useEffect(() => { + if (KINDS.indexOf(kind) < 0) { + console.error("TNewPopUp kind error"); + } + }, [kind]); + + const ButtonContainerComp = useMemo(() => { + return kind === "exitPopup" ? ButtonContainerNegative : ButtonContainer; + }, [kind]); + + // optionalAgreement + // 자동으로 Yes/No 버튼 텍스트 설정 + + const finalButton1Text = useMemo(() => { + if (kind === "optionalAgreement" && !button1Text) { + return "Yes"; + } + return button1Text; + }, [kind, button1Text]); + + const finalButton2Text = useMemo(() => { + if (kind === "optionalAgreement" && !button2Text) { + return "No"; + } + return button2Text; + }, [kind, button2Text]); + + // optionalAgreement일 경우 항상 버튼 표시 + const shouldShowButtons = useMemo(() => { + return hasButton || kind === "optionalAgreement"; + }, [hasButton, kind]); + + //------------------------------------------------------- + + const _onClick = useCallback( + (e) => { + if (onClick) { + onClick(e); + } else if (kind === "exitPopup") _onExit(); + else _onClose(); + }, + [kind, onClick, _onClose, _onExit] + ); + + const _onClose = useCallback(() => { + if (onClose) { + onClose(); + } + }, [onClose]); + + const _onExit = useCallback(() => { + if (onExit) { + onExit(); + } + }, [onExit]); + + const _onRightClick = useCallback(() => { + if (onRightClick) { + onRightClick(); + } + }, [onRightClick]); + + const _onLeftClick = useCallback(() => { + if (onLeftClick) { + onLeftClick(); + } + }, [onLeftClick]); + + const selectedOptClick = useCallback( + (index, stock) => () => { + if (stock > 0) { + optionClick(index); + } + }, + [optionClick] + ); + + const _onSpotlightRight = useCallback( + (e) => { + if (onSpotlightRight) onSpotlightRight(e); + }, + [onSpotlightRight] + ); + + if (!open) { + return null; + } + + return ( + + + {hasOnClose && ( + + )} + {hasThumbnail && ( +
+ +
+ )} + {hasText && ( +
+ {title && ( +
+ {title} +
+ )} + {hasLogo && logo !== null && ( + + + + )} + {text && ( +
+ {text} +
+ )} +
+ )} + {options && ( + = 5 ? css.optionScroll : null + )} + > + {options.map((option, index) => { + const { prodOptCval, optImgUrl, optPrc, optStkQty, optNm } = + option; + const optStock = Number(optStkQty); + + return ( + 0 && + index === selectedIndex && + css.selectedOption, + + index == selectedIndex && css.focused, + optStkQty <= 0 && css.optionSoldOut + )} + spotlightId={`selectedOptionBtn-${index}`} + onClick={selectedOptClick(index, optStkQty)} + key={`option: ${index}`} + aria-label={optNm ? optNm : prodOptCval} + spotlightDisabled={optStkQty && optStkQty <= 0} + > + {optImgUrl && ( + + )} +
+ {optNm ? optNm : prodOptCval} + {optStkQty && optStkQty <= 0 && ( + {$L("SOLD OUT")} + )} +
+ + {optPrc && optStock !== 0 && `($${optPrc})`} +
+ ); + })} +
+ )} + + {/* optionalAgreement의 특별한 구조 처리 */} + {kind === "optionalAgreement" && ( +
+ {children} +
+ )} + + {/* 다른 종류들의 children */} + {kind !== "optionalAgreement" && children} + + {hasIndicator && ( + <> + {currentPage !== 0 && ( + + )} + {currentPage !== itemLength - 1 && ( + + )} + + )} + {shouldShowButtons && ( + + {finalButton1Text && ( + + {finalButton1Text} + + )} + {finalButton2Text && ( + + {finalButton2Text} + + )} + + )} +
+
+ ); +} \ No newline at end of file diff --git a/com.twin.app.shoptime/src/components/TPopUp/TNewPopUp.module.less b/com.twin.app.shoptime/src/components/TPopUp/TNewPopUp.module.less new file mode 100644 index 00000000..78d9bdbe --- /dev/null +++ b/com.twin.app.shoptime/src/components/TPopUp/TNewPopUp.module.less @@ -0,0 +1,862 @@ +@import "../../style/CommonStyle.module.less"; +@import "../../style/utils.module.less"; + +.tNewPopUp { + //enact popup reset + margin: 0 auto !important; + background: transparent !important; + > div { + padding: 0 !important; + > div > div { + width: unset !important; + margin: 0 !important; + > div { + font-family: @baseFont; + } + } + } + box-shadow: 0 20px 70px rgba(2, 3, 3, 0.7) !important; + + .default-style(@width: 780px) { + .commonInfo { + width: @width; + background-color: @BG_COLOR_01; + color: @COLOR_GRAY03; + display: flex; + flex-direction: column; + font-weight: normal; + box-sizing: border-box; + border-radius: 4px; + } + + .commonTextLayer { + width: 100%; + + .commonTitle { + text-align: left; + font-size: 36px; + font-weight: bold; + line-height: normal; + color: @COLOR_BLACK; + background-color: @COLOR_SKYBLUE; + padding: 30px 60px; + } + + .commonText { + min-height: 180px; + color: @COLOR_GRAY03; + font-size: 30px; + line-height: 38px; + text-align: center; + .flex(); + } + } + } + + // kind + + &.introTermsPopup { + .default-style(); + + .introTermsInfo { + .size(@w: 1100px , @h: 564px); + padding: 60px 42px 30px 60px; + background-color: @BG_COLOR_01; + color: @COLOR_GRAY03; + display: flex; + flex-direction: column; + font-weight: normal; + box-sizing: border-box; + border-radius: 4px; + + .introTermsButtonContainer { + margin-top: 30px; + display: flex; + justify-content: center; + > div { + min-width: 300px; + height: 78px; + } + } + } + } + + &.descriptionPopup { + .default-style(); + + .descriptionInfo { + .size(@w: 1100px , @h: 824px); + padding: 60px 42px 30px 60px; + background-color: @BG_COLOR_01; + color: @COLOR_GRAY03; + display: flex; + flex-direction: column; + font-weight: normal; + box-sizing: border-box; + border-radius: 4px; + } + + .descriptionImg { + .size(@w: 200px, @h: 200px); + } + + .descriptionButtonContainer { + display: flex; + justify-content: center; + margin-top: 30px; + } + } + + &.textPopup, + &.exitPopup { + .default-style(); + + .textExitInfo { + width: 780px; + background-color: @BG_COLOR_01; + color: @COLOR_GRAY03; + display: flex; + flex-direction: column; + font-weight: normal; + box-sizing: border-box; + border-radius: 4px; + + .textExitText { + padding: 0 60px; + min-height: 180px; + margin: 30px 0; + color: @COLOR_GRAY03; + font-size: 30px; + line-height: 38px; + text-align: center; + .flex(); + } + + .textExitButtonContainer { + margin: 0 0 30px 0; + display: flex; + justify-content: center; + > div { + min-width: 240px; + height: 78px; + margin: 0 6px; + } + } + } + } + + &.optionPopup { + .default-style(); + + .optionInfo { + width: 820px; + background-color: @BG_COLOR_01; + color: @COLOR_GRAY03; + display: flex; + flex-direction: column; + font-weight: normal; + box-sizing: border-box; + border-radius: 4px; + } + + .optionItem { + width: 100%; + display: flex; + justify-content: space-between; + } + + .optionLayer { + margin: 0 auto; + width: 700px; + max-height: 410px; + margin-top: 31px; + + .optionChoice { + box-sizing: border-box; + border: 1px solid @COLOR_GRAY02; + background: @COLOR_WHITE; + font-size: 24px; + font-weight: bold; + color: @COLOR_GRAY03; + padding: 30px; + height: 90px; + line-height: normal; + align-items: center; + display: flex; + + &:focus { + background: @PRIMARY_COLOR_RED; + color: @COLOR_WHITE; + } + + .optionImg { + width: 60px; + height: 60px; + margin: 0 12px 0 0; + } + + &.optionSoldOut { + background: @BG_COLOR_02; + > * { + opacity: 0.4; + } + } + + &.optionItem { + display: flex; + color: red; + } + } + + &.optionScroll { + overflow-y: auto; + } + + .selectedOption { + box-sizing: border-box; + background: @COLOR_WHITE; + color: @PRIMARY_COLOR_RED; + border: 4px solid @PRIMARY_COLOR_RED; + } + } + + .optionButtonContainer { + margin: 30px 0 30px 0; + display: flex; + justify-content: center; + } + } + + &.eventBannerPopup { + .default-style(); + + .eventBannerInfo { + width: 600px; + height: 510px; + background-color: @BG_COLOR_01; + color: @COLOR_GRAY03; + display: flex; + flex-direction: column; + font-weight: normal; + box-sizing: border-box; + border-radius: 4px; + + > p > img { + width: 600px; + height: 510px; + } + } + + .eventBannerButtonContainer { + display: flex; + justify-content: center; + position: absolute; + left: 0; + right: 0; + bottom: 50px; + + > div { + margin: 0 6px; + min-width: 240px; + height: 78px; + } + } + } + + &.supportPopup { + .default-style(); + + .supportInfo { + width: 960px; + height: 640px; + background-color: @BG_COLOR_01; + color: @COLOR_GRAY03; + display: flex; + flex-direction: column; + font-weight: normal; + box-sizing: border-box; + border-radius: 4px; + + .supportButtonContainer { + position: absolute; + right: 0; + left: 0; + bottom: 0; + margin-bottom: 30px; + display: flex; + justify-content: center; + > div { + min-width: 300px; + height: 78px; + } + } + } + } + + &.couponPopup { + .default-style(); + + .couponInfo { + width: 960px; + height: 640px; + background-color: @BG_COLOR_01; + color: @COLOR_GRAY03; + display: flex; + flex-direction: column; + font-weight: normal; + box-sizing: border-box; + border-radius: 4px; + + .couponButtonContainer { + position: absolute; + right: 0; + left: 0; + bottom: 0; + margin-bottom: 30px; + display: flex; + justify-content: center; + > div { + min-width: 300px; + height: 78px; + } + } + } + } + + &.mobileSendPopup { + .default-style(); + + .mobileSendInfo { + width: 960px; + height: 640px; + background-color: @BG_COLOR_01; + color: @COLOR_GRAY03; + display: flex; + flex-direction: column; + font-weight: normal; + box-sizing: border-box; + border-radius: 4px; + + .mobileSendButtonContainer { + position: absolute; + right: 0; + left: 0; + bottom: 0; + margin-bottom: 30px; + display: flex; + justify-content: center; + > div { + min-width: 300px; + height: 78px; + } + } + } + } + + &.qrPopup { + .default-style(); + + .qrInfo { + width: 960px; + height: 640px; + background-color: @BG_COLOR_01; + color: @COLOR_GRAY03; + display: flex; + flex-direction: column; + font-weight: normal; + box-sizing: border-box; + border-radius: 4px; + } + + .qrButtonContainer { + display: flex; + justify-content: center; + padding: 30px 0; + + > div { + margin-top: 2; + min-width: 340px; + height: 80px; + margin: 0 10px; + background: @COLOR_GRAY09; + } + } + } + + &.checkoutTermsPopup { + .checkoutTermsInfo { + .size(@w: 1100px , @h: 750px); + padding: 60px 60px 30px 60px; + background-color: @BG_COLOR_01; + color: @COLOR_GRAY03; + display: flex; + flex-direction: column; + font-weight: normal; + + .checkoutTermsTitle { + text-align: left; + font-size: 36px; + font-weight: bold; + line-height: normal; + color: @COLOR_BLACK; + padding: 0 0 30px 0; + } + + .checkoutTermsText { + height: 480px; + overflow-y: auto; + font-size: 24px; + line-height: 36px; + padding-right: 20px; + + &::-webkit-scrollbar { + width: 8px; + height: 300px; + } + &::-webkit-scrollbar-track-piece { + background-color: #fff; + } + &::-webkit-scrollbar-thumb { + background-color: #7a808d; + } + } + } + + .checkoutTermsButtonContainer { + display: flex; + justify-content: center; + padding: 30px 0; + + > div { + min-width: 300px; + height: 78px; + margin: 0 10px; + background: @COLOR_GRAY09; + font-size: 30px; + &:focus { + box-shadow: 0px 18px 28.2px 1.8px rgba(62, 59, 59, 0.4); + background-color: @PRIMARY_COLOR_RED; + color: @COLOR_WHITE; + } + } + } + } + + &.scrollPopup { + .default-style(); + + .scrollInfo { + width: 900px; + background-color: @BG_COLOR_01; + color: @COLOR_GRAY03; + display: flex; + flex-direction: column; + font-weight: normal; + box-sizing: border-box; + border-radius: 4px; + } + + .scrollButtonContainer { + display: flex; + justify-content: center; + padding: 30px 0; + + > div { + min-width: 300px; + height: 78px; + margin: 0 10px; + background: @COLOR_GRAY09; + font-size: 30px; + &:focus { + box-shadow: 0px 18px 28.2px 1.8px rgba(62, 59, 59, 0.4); + background-color: @PRIMARY_COLOR_RED; + color: @COLOR_WHITE; + } + } + } + } + + &.watchPopup { + position: absolute; + right: 42px; + bottom: -330px; + + .watchInfo { + width: 1038px; + height: 168px; + background-color: @BG_COLOR_01; + color: @COLOR_GRAY03; + display: flex; + flex-wrap: wrap; + flex-direction: column; + + .watchThumbnail { + width: 300px; + height: 168px; + img { + width: 100%; + height: 100%; + } + } + + .watchTextLayer { + width: 552px; + height: 168px; + padding: 30px; + box-sizing: border-box; + } + + .watchTitle { + color: @COLOR_BLACK; + font-size: 30px; + text-align: left; + font-weight: bold; + width: 552px; + height: 36px; + .elip(@clamp:1); + img { + width: 100%; + height: 100%; + } + } + + .watchText { + color: #1a1a1a; + font-size: 24px; + text-align: left; + font-weight: normal; + width: 552px; + height: 30px; + .elip(@clamp:1); + } + } + + .watchButtonContainer { + display: flex; + flex-wrap: wrap; + justify-content: center; + padding: 18px 30px; + width: 180px; + > div { + min-width: 180px; + height: 60px; + margin: 0 0 12px 0; + background: @COLOR_GRAY09; + font-size: 24px; + line-height: 60px; + &:focus { + box-shadow: 0px 18px 28.2px 1.8px rgba(62, 59, 59, 0.4); + background-color: @PRIMARY_COLOR_RED; + color: @COLOR_WHITE; + } + } + } + } + + &.setPinCodePopup { + .default-style(); + + .setPinCodeInfo { + width: 780px; + background-color: @BG_COLOR_01; + color: @COLOR_GRAY03; + display: flex; + flex-direction: column; + font-weight: normal; + box-sizing: border-box; + border-radius: 4px; + + .setPinCodeText { + padding: 0 60px; + min-height: 180px; + margin: 30px 0; + color: @COLOR_GRAY03; + font-size: 30px; + line-height: 38px; + text-align: center; + .flex(); + } + + .setPinCodeButtonContainer { + margin: 0 0 30px 0; + display: flex; + justify-content: center; + > div { + min-width: 240px; + height: 78px; + margin: 0 6px; + } + } + } + } + + &.errorPopup { + .default-style(); + + .errorInfo { + width: 780px; + background-color: @BG_COLOR_01; + color: @COLOR_GRAY03; + display: flex; + flex-direction: column; + font-weight: normal; + box-sizing: border-box; + border-radius: 4px; + + .errorText { + padding: 0 60px; + min-height: 180px; + margin: 30px 0; + color: @COLOR_GRAY03; + font-size: 30px; + line-height: 38px; + text-align: center; + .flex(); + } + + .errorButtonContainer { + margin: 0 0 30px 0; + display: flex; + justify-content: center; + > div { + min-width: 240px; + height: 78px; + margin: 0 6px; + } + } + } + } + + &.orderDetailPopup { + .default-style(); + width: 900px; + background-color: @BG_COLOR_01; + } + + &.orderCancelPopup { + > div > div > div { + box-shadow: 0 20px 70px rgba(2, 3, 3, 0.7) !important; + border-radius: 6px !important; + } + .default-style(); + position: relative; + + .orderCancelInfo { + width: 780px; + background-color: @BG_COLOR_01; + color: @COLOR_GRAY03; + display: flex; + flex-direction: column; + font-weight: normal; + box-sizing: border-box; + border-radius: 4px; + + .orderCancelText { + padding: 0 60px; + min-height: 180px; + margin: 30px 0; + color: @COLOR_GRAY03; + font-size: 30px; + line-height: 38px; + text-align: center; + .flex(); + } + + .orderCancelButtonContainer { + margin: 0 0 30px 0; + display: flex; + justify-content: center; + > div { + min-width: 240px; + height: 78px; + margin: 0 6px; + } + } + } + } + + &.returnExchangePopup { + .default-style(); + + .returnExchangeInfo { + width: 780px; + background-color: @BG_COLOR_01; + color: @COLOR_GRAY03; + display: flex; + flex-direction: column; + font-weight: normal; + box-sizing: border-box; + border-radius: 4px; + + .returnExchangeText { + padding: 0 60px; + min-height: 180px; + margin: 30px 0; + color: @COLOR_GRAY03; + font-size: 30px; + line-height: 38px; + text-align: center; + .flex(); + } + + .returnExchangeButtonContainer { + margin: 0 0 30px 0; + display: flex; + justify-content: center; + > div { + min-width: 240px; + height: 78px; + margin: 0 6px; + } + } + } + } + + &.trackPackagePopup { + .default-style(@width: 860px); + + .trackPackageInfo { + width: 860px; + background-color: @BG_COLOR_01; + color: @COLOR_GRAY03; + display: flex; + flex-direction: column; + font-weight: normal; + box-sizing: border-box; + border-radius: 4px; + + .trackPackageText { + padding: 0 60px; + min-height: 180px; + margin: 30px 0; + color: @COLOR_GRAY03; + font-size: 30px; + line-height: 38px; + text-align: center; + .flex(); + } + + .trackPackageButtonContainer { + margin: 0 0 30px 0; + display: flex; + justify-content: center; + > div { + min-width: 240px; + height: 78px; + margin: 0 6px; + } + } + } + } + + &.cancelConfirmPopup { + .default-style(); + position: absolute; + left: 50%; + transform: translateX(-50%); + width: 100%; + height: 100%; + + > div > div > div { + box-shadow: 0 20px 70px rgba(2, 3, 3, 0.7) !important; + border-radius: 6px !important; + } + + .cancelConfirmInfo { + width: 780px; + background-color: @BG_COLOR_01; + color: @COLOR_GRAY03; + display: flex; + flex-direction: column; + font-weight: normal; + box-sizing: border-box; + border-radius: 4px; + + .cancelConfirmText { + padding: 0 60px; + min-height: 180px; + margin: 30px 0; + color: @COLOR_GRAY03; + font-size: 30px; + line-height: 38px; + text-align: center; + .flex(); + } + + .cancelConfirmButtonContainer { + margin: 0 0 30px 0; + display: flex; + justify-content: center; + > div { + min-width: 240px; + height: 78px; + margin: 0 6px; + } + } + } + } + + /* 👇 새로운 팝업 스타일 */ + &.optionalAgreement { + .default-style(); + + // 팝업 위치를 정중앙보다 아래로 명시적으로 지정 + position: absolute !important; + top: 80% !important; // 50%가 정중앙, 값을 키우면 아래로 이동 + left: 50% !important; + transform: translate(-50%, -50%) !important; + margin: 0 !important; + + .optionalAgreementInfo { + .size(@w: 1064px, @h: 240px); + padding: 60px 57px 40px; // 상단 60px, 좌우 57px, 하단 40px 패딩 적용 + box-sizing: border-box; // 패딩이 너비/높이에 포함되도록 설정 + background-color: @BG_COLOR_01; + color: @COLOR_GRAY03; + display: flex; + flex-direction: column; + font-weight: normal; + border-radius: 4px; + + // 컨텐츠 영역 + .optionalAgreementContentContainer { + width: 100%; + height: 100%; + display: flex; + flex-direction: column; + } + + // 텍스트 영역 스타일 + .optionalAgreementTextLayer { + flex: 1; // 남은 공간을 모두 차지하도록 설정 + min-height: 0; // flex item이 부모를 넘어 수축할 수 있도록 허용 + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + overflow: hidden; // 내용이 넘칠 경우 숨김 + + .optionalAgreementText { + font-size: 30px; + line-height: 38px; + text-align: center; + color: @COLOR_GRAY03; + } + } + + // 버튼 컨테이너 스타일 + .optionalAgreementButtonContainer { + margin-top: 3%; // gap 대신 margin 사용 + display: flex; + justify-content: center; + gap: 12px; // 버튼 간 간격 + flex-shrink: 0; // 컨테이너가 줄어들지 않도록 설정 + + > div { + min-width: 300px; + height: 80px; // 높이 80px로 수정 + } + } + } + } +} \ No newline at end of file diff --git a/com.twin.app.shoptime/src/components/TabLayout/TabItem.module.less b/com.twin.app.shoptime/src/components/TabLayout/TabItem.module.less index 973d0fea..859dbc90 100644 --- a/com.twin.app.shoptime/src/components/TabLayout/TabItem.module.less +++ b/com.twin.app.shoptime/src/components/TabLayout/TabItem.module.less @@ -11,8 +11,14 @@ height: 84px; position: relative; margin-left: 36px; + border: none !important; // ✅ 모든 테두리 제거 + outline: none !important; // ✅ 포커스 아웃라인 제거 + box-shadow: none !important; // ✅ 그림자 제거 + &.focused { color: #eee; + border: none !important; // ✅ focused 상태에서도 테두리 제거 + outline: none !important; // ✅ focused 상태에서도 포커스 아웃라인 제거 &::before { background: linear-gradient(to right, #cb1253, #e15ba1); border-radius: 42px; diff --git a/com.twin.app.shoptime/src/views/IntroPanel/IntroPanel.new.module.less b/com.twin.app.shoptime/src/views/IntroPanel/IntroPanel.new.module.less index a738716d..368ee9d1 100644 --- a/com.twin.app.shoptime/src/views/IntroPanel/IntroPanel.new.module.less +++ b/com.twin.app.shoptime/src/views/IntroPanel/IntroPanel.new.module.less @@ -146,8 +146,8 @@ transition: color 0.3s ease; } - // 포커스 상태 - &:global(.spottable):global(.focus) { + 포커스 상태 + &.focused { outline: 2px #C91D53 solid !important; outline-offset: 2px !important; background-color: rgba(201, 29, 83, 0.1) !important; @@ -250,7 +250,7 @@ transition: all 0.3s ease; // 포커스 상태 - &:global(.spottable):global(.focus) { + &.focused { background-color: #a40640 !important; border-color: #a40640 !important; color: white !important; @@ -289,7 +289,7 @@ transition: all 0.3s ease; // 포커스 상태 - &:global(.spottable):global(.focus) { + &.focused { background-color: #7a7a7a !important; border-color: #7a7a7a !important; color: white !important; @@ -337,12 +337,12 @@ } } -// 체크박스 커스텀 스타일 -:global(.tCheckBoxSquare) { +// ✅ 로컬 체크박스 스타일로 변경 +.customCheckbox { width: 45px; height: 45px; + position: relative; - // 기본 상태 &:before { content: ''; width: 42px; @@ -371,8 +371,7 @@ transform: translate(-50%, -50%); } - // 포커스 상태 - &.focus:before { + &.focused:before { border-color: #C91D53; box-shadow: 0 0 10px rgba(199, 8, 80, 0.3); } diff --git a/com.twin.app.shoptime/src/views/MainView/MainView.jsx b/com.twin.app.shoptime/src/views/MainView/MainView.jsx index 6088f3e7..4acfe04f 100644 --- a/com.twin.app.shoptime/src/views/MainView/MainView.jsx +++ b/com.twin.app.shoptime/src/views/MainView/MainView.jsx @@ -81,7 +81,7 @@ import TrendingNowPanel from "../TrendingNowPanel/TrendingNowPanel"; import VideoTestPanel from "../VideoTestPanel/VideoTestPanel"; import WelcomeEventPanel from "../WelcomeEventPanel/WelcomeEventPanel"; import TermsOfOptional from "../MyPagePanel/MyPageSub/TermsOfService/TermsOfOptionalSimple"; // 선택약관 반영 인트로 -import OptionalTermsConfirmTest from "../../components/Optional/OptionalTermsConfirmTest"; +import OptionalTermsConfirm from "../../components/Optional/OptionalTermsConfirm"; import css from "./MainView.module.less"; const preloadImages = [ @@ -171,7 +171,7 @@ export default function MainView({ className, initService }) { const [showEndOfServicePopup, setShowEndOfServicePopup] = useState(false); const topPanel = panels[panels.length - 1]; - // OptionalTermsConfirm 팝업 상태 디버깅 + useEffect(() => { console.log('🔍 MainView 팝업 상태 변경:', { popupVisible, @@ -780,22 +780,7 @@ export default function MainView({ className, initService }) { /> ) : null} - {/* {activePopup === "optionalTermsTest" && ( - - )} */} - - {/* OptionalTermsConfirmPopup */} - {activePopup === Config.ACTIVE_POPUP.optionalTermsConfirmPopup && ( - - )} + {loadingComplete && @@ -814,8 +799,9 @@ export default function MainView({ className, initService }) { button2Text={$L("OK")} /> )} + {/* OptionalTermsConfirmPopup */} {activePopup === Config.ACTIVE_POPUP.optionalTermsTest && ( - + )}
);