[DetailPanel] 결제가능상품 옵션 선택 시나리오 수정

This commit is contained in:
고동영
2024-06-07 16:39:59 +09:00
parent 990ab6a0ce
commit b333168c7c
6 changed files with 101 additions and 44 deletions

View File

@@ -204,5 +204,7 @@
"Excellent": "Excellent",
"TSV": "TSV",
"Free S&H": "Free S&H",
"Big Sale": "Big Sale"
"Big Sale": "Big Sale",
"SELECT": "SELECT",
"Please select Option": "Please select Option"
}

View File

@@ -44,6 +44,7 @@ function TButtonBase({
ariaLabel,
children,
spotlightId,
spotlightDisabled = false,
className,
onClick,
onBlur,
@@ -112,6 +113,7 @@ function TButtonBase({
onClick={_onClick}
role="button"
aria-label={ariaLabel}
spotlightDisabled={spotlightDisabled}
>
{withMarquee ? (
<Marquee className={css.marquee} marqueeOn="focus">

View File

@@ -56,6 +56,7 @@ export default function TPopUp({
onClose,
hasButton,
hasText,
hasOnClose = false,
hasIndicator,
hasLogo,
hasThumbnail,
@@ -279,7 +280,7 @@ export default function TPopUp({
{button1Text}
</TButton>
)}
{button2Text && (
{button2Text && !hasOnClose && (
<TButton spotlightId="tPopupBtn2" onClick={onClose} role="button">
{button2Text}
</TButton>

View File

@@ -1,4 +1,10 @@
import React, { useCallback, useEffect, useRef, useState } from "react";
import React, {
useCallback,
useEffect,
useMemo,
useRef,
useState,
} from "react";
import classNames from "classnames";
import { useDispatch, useSelector } from "react-redux";
@@ -24,7 +30,6 @@ import TPopUp from "../../../components/TPopUp/TPopUp";
import TQRCode from "../../../components/TQRCode/TQRCode";
import TScroller from "../../../components/TScroller/TScroller";
import TVirtualGridList from "../../../components/TVirtualGridList/TVirtualGridList";
import usePriceInfo from "../../../hooks/usePriceInfo";
import * as Config from "../../../utils/Config";
import { $L } from "../../../utils/helperMethods";
@@ -44,6 +49,8 @@ export default function SingleOption({
isSpotlight,
selectedPatnrId,
selectedPrdtId,
selectedIndex,
type,
}) {
const dispatch = useDispatch();
const productOptionInfos = useSelector((state) => state.product.prdtOptInfo);
@@ -64,8 +71,10 @@ export default function SingleOption({
const [quantity, setQuantity] = useState(1);
const [selectedCouponIndex, setSelectedCouponIndex] = useState(0);
const [selectedCoupon, setSelectedCoupon] = useState();
const [isOptionValue, setIsOptionValue] = useState(false);
const [isOptionSelect, setIsOptionSelect] = useState(false);
const [selectedOptionItemIndex, setSelectedOptionItemIndex] = useState(0);
const [selectedOptions, setSelectedOptions] = useState([]);
const [selectedOptions, setSelectedOptions] = useState();
const [couponTypes, setCouponTypes] = useState(null);
const [couponCodes, setCouponCodes] = useState("");
const [selectedOptionInfo, setSelectedOptionInfo] = useState();
@@ -109,33 +118,49 @@ export default function SingleOption({
);
}, [dispatch, selectedPatnrId, selectedPrdtId, productData]);
useEffect(() => {
if (type !== "theme") {
return;
}
if (selectedOptions) {
setSelectedBtnOptIdx(0);
}
setSelectedOptions();
setIsOptionValue(false);
setSelectedOptionItemIndex(0);
setIsOptionSelect(false);
}, [selectedIndex, type]);
const handleOptionClick = useCallback(
(optionValIdx) => {
setSelectedBtnOptIdx(optionValIdx);
setSelectedOptionItemIndex(0);
setSelectedOptions(productOptionInfos[optionValIdx].prdtOptDtl[0]);
setIsOptionValue(false);
setIsOptionSelect(true);
onClose();
},
[selectedBtnOptIdx]
[productOptionInfos, selectedOptionItemIndex]
);
const handleOptionItemClick = useCallback(
(index) => {
setSelectedOptionItemIndex(index);
setSelectedOptions(
productOptionInfos[selectedBtnOptIdx].prdtOptDtl[index]
);
setIsOptionValue(true);
onClose();
},
[selectedOptionItemIndex]
[productOptionInfos, selectedBtnOptIdx]
);
useEffect(() => {
if (productOptionInfos && productOptionInfos.length > 0) {
setSelectedOptions(
productOptionInfos[selectedBtnOptIdx].prdtOptDtl[
selectedOptionItemIndex
]
);
const loginPopupText = useMemo(() => {
if (!selectedOptions || (!isOptionValue && isOptionSelect)) {
return $L("Please select Option");
}
}, [selectedBtnOptIdx, selectedOptionItemIndex, productOptionInfos]);
return $L("Would you like to sign in?");
}, [selectedOptions]);
const handleIncrement = useCallback(() => {
setQuantity(quantity + 1);
}, [quantity]);
@@ -146,12 +171,26 @@ export default function SingleOption({
}, [quantity]);
const handleOptionPopUpOpen = useCallback(
(OptionInfo, isProductOptionInfoArray) => {
setSelectedOptionInfo(OptionInfo);
(optionInfo, isProductOptionInfoArray) => {
if (
productOptionInfos.length !== 1 &&
!isOptionSelect &&
!isProductOptionInfoArray
) {
return dispatch(setShowPopup(Config.ACTIVE_POPUP.loginPopup));
}
setSelectedOptionInfo(optionInfo);
setHasProductOptionArray(isProductOptionInfoArray);
dispatch(setShowPopup(Config.ACTIVE_POPUP.optionPopup));
},
[dispatch, activePopup, selectedOptionItemIndex]
[
dispatch,
isOptionSelect,
activePopup,
productOptionInfos,
selectedOptionItemIndex,
]
);
const handleQRCodePopUpOpen = useCallback(() => {
@@ -180,6 +219,14 @@ export default function SingleOption({
}, [activePopup, selectedBtnOptIdx, selectedOptionItemIndex]);
const handleLoginPopup = useCallback(() => {
console.log("#selectedOptions", productOptionInfos);
if (productOptionInfos && !isOptionValue && isOptionSelect) {
return dispatch(setShowPopup(Config.ACTIVE_POPUP.loginPopup));
}
if (productOptionInfos && !selectedOptions) {
dispatch(setShowPopup(Config.ACTIVE_POPUP.loginPopup));
return;
}
if (!loginUserData.userNumber) {
dispatch(setShowPopup(Config.ACTIVE_POPUP.loginPopup));
} else {
@@ -190,14 +237,22 @@ export default function SingleOption({
cartList: {
patnrId: selectedPatnrId,
prdtId: selectedPrdtId,
prodOptCdCval: selectedOptions.prodOptCdCval,
prodOptCdCval: selectedOptions?.prodOptCdCval,
prodQty: quantity,
},
},
})
);
}
}, [dispatch, quantity, discountedPrice, selectedBtnOptIdx, selectedOptions]);
}, [
dispatch,
isOptionValue,
isOptionSelect,
quantity,
discountedPrice,
selectedBtnOptIdx,
selectedOptions,
]);
const handleCouponClick = useCallback(
(idx, promotion) => {
@@ -260,17 +315,6 @@ export default function SingleOption({
}
}, [productOptionInfos, productData]);
//옵션이 있을 경우 selectedOption에 첫번째 옵션을 강제로 담음 ( 들어오자마자 BUYNOW 클릭시 체크아웃으로 상품 넘어감 )
useEffect(() => {
if (productOptionInfos && productOptionInfos.length > 0) {
setSelectedOptions(
productOptionInfos[selectedBtnOptIdx].prdtOptDtl[
selectedOptionItemIndex
]
);
}
}, [productOptionInfos]);
const getCouponCode = () => {
const snoArray = [];
@@ -281,24 +325,29 @@ export default function SingleOption({
setCouponCodes(snoArray.join(", "));
};
const renderOptionName = (optionInfo) => {
return optionInfo?.optNm || null;
};
const renderOptionName = useCallback(() => {
if (selectedOptions) {
return productOptionInfos[selectedBtnOptIdx]?.optNm || null;
}
return $L("SELECT");
}, [productOptionInfos, selectedOptions, selectedBtnOptIdx]);
const renderOptionValue = useCallback(
(optionInfo) => {
if (
optionInfo &&
optionInfo.prdtOptDtl &&
optionInfo.prdtOptDtl.length > 0
optionInfo.prdtOptDtl.length > 0 &&
isOptionValue
) {
return (
optionInfo.prdtOptDtl[selectedOptionItemIndex]?.prodOptCval || null
);
}
return null;
return $L("SELECT");
},
[selectedOptionItemIndex]
[selectedOptions, isOptionValue, selectedOptionItemIndex]
);
const renderItem = useCallback(
@@ -406,7 +455,7 @@ export default function SingleOption({
spotlightId={"selectedOptionBox-0"}
>
<span className={css.optionValue}>
{renderOptionName(productOptionInfos[selectedBtnOptIdx])}
{renderOptionName()}
</span>
</TButton>
</div>
@@ -424,6 +473,7 @@ export default function SingleOption({
)
}
spotlightId={"selectedOptionBox-1"}
spotlightDisabled={productOptionInfos.length === 1}
>
<span className={css.optionValue}>
{renderOptionValue(productOptionInfos[selectedBtnOptIdx])}
@@ -532,15 +582,15 @@ export default function SingleOption({
kind="textPopup"
hasText
open={popupVisible}
text={$L("Would you like to sign in?")}
text={loginPopupText}
hasButton
hasOnClose={!selectedOptions || (!isOptionValue && isOptionSelect)}
button1Text={$L("OK")}
button2Text={$L("CANCEL")}
onClick={handleQRCodePopUpOpen}
onClose={onClose}
></TPopUp>
)}
{/* SHOPTIME OPTION POPUP */}
{activePopup === Config.ACTIVE_POPUP.optionPopup && (
<TPopUp

View File

@@ -4,14 +4,14 @@ import { useSelector } from "react-redux";
import SpotlightContainerDecorator from "@enact/spotlight/SpotlightContainerDecorator";
import useLogService from "../../../hooks/useLogService";
import { LOG_MENU, LOG_TP_NO } from "../../../utils/Config";
import { formatGMTString } from "../../../utils/helperMethods";
import Indicator from "../components/indicator/Indicator";
import IndicatorOptions from "../components/indicator/IndicatorOptions";
import ProductOption from "../components/ProductOption";
import SingleOption from "./SingleOption";
import css from "./SingleProduct.module.less";
import useLogService from "../../../hooks/useLogService";
import { LOG_MENU, LOG_TP_NO } from "../../../utils/Config";
import { formatGMTString } from "../../../utils/helperMethods";
const Container = SpotlightContainerDecorator(
{ enterTo: "last-focused", preserveld: true },
@@ -152,6 +152,7 @@ export default function SingleProduct({
productInfo={productData}
selectedPatnrId={selectedPatnrId}
selectedPrdtId={selectedPrdtId}
selectedIndex={selectedIndex}
soldoutFlag={isProductSoldOut}
/>
</ProductOption>

View File

@@ -16,6 +16,7 @@ export default function ThemeSingleOption({
thumbnailUrls={productInfo?.thumbnailUrl}
>
<SingleOption
type="theme"
selectedPatnrId={productData?.themeInfo[0]?.patnrId}
selectedPrdtId={productInfo[selectedIndex]?.prdtId}
productInfo={productInfo[selectedIndex]}