[SHOPTIME-3091] 옵션 상품 정보 변경 대응 기획, Front, 모바일 변경

[수정파일]

  1. actionTypes.js
  2. productActions.js
  3. productReducer.js
  4. ProductOption.jsx
  5. SingleOption.jsx
  6. SingleOption.module.less

[생성파일]

  1. BillingProductPrice.jsx
  2. BillingProductPrice.module.less

[수정내용]

  1. 결제가능한상품에서 옵션이 있을 경우 옵션 선택에 따라 Price값과 Id값이 노출되도록 수정
This commit is contained in:
고동영
2024-09-03 15:36:17 +09:00
parent 45f68969c1
commit 428aef9e29
8 changed files with 155 additions and 93 deletions

View File

@@ -129,7 +129,9 @@ export const types = {
GET_PRODUCT_OPTION: "GET_PRODUCT_OPTION",
GET_PRODUCT_IMAGE_LENGTH: "GET_PRODUCT_IMAGE_LENGTH",
GET_VIDEO_INDECATOR_FOCUS: "GET_VIDEO_INDECATOR_FOCUS",
GET_PRODUCT_OPTION_ID: "GET_PRODUCT_OPTION_ID",
CLEAR_PRODUCT_OPTIONS: "CLEAR_PRODUCT_OPTIONS",
// search actions
GET_SEARCH: "GET_SEARCH",
RESET_SEARCH: "RESET_SEARCH",

View File

@@ -97,7 +97,9 @@ export const getProductOption = (props) => (dispatch, getState) => {
onFail
);
};
export const getProductOptionId = (id) => (dispatch) => {
dispatch({ type: types.GET_PRODUCT_OPTION_ID, payload: id });
};
export const clearProductDetail = () => ({
type: types.CLEAR_PRODUCT_DETAIL,
});

View File

@@ -38,6 +38,11 @@ export const productReducer = (state = initialState, action) => {
...state,
prdtOptInfo: null,
};
case types.GET_PRODUCT_OPTION_ID:
return {
...state,
prodOptCdCval: action.payload,
};
default:
return state;
}

View File

@@ -0,0 +1,55 @@
import React from "react";
import { useSelector } from "react-redux";
import usePriceInfo from "../../../../hooks/usePriceInfo";
import { $L } from "../../../../utils/helperMethods";
import css from "./BillingProductPrice.module.less";
export default function BillingProductPrice({
patncNm,
productInfo,
selectedOptions,
}) {
const productData = useSelector((state) => state.main.productData);
const { shippingCharge } = productInfo || productData;
const { priceInfo } = selectedOptions
? selectedOptions
: productInfo || productData;
const { originalPrice, discountedPrice, discountRate } =
usePriceInfo(priceInfo) || {};
return (
<>
{originalPrice && discountedPrice && (
<div
className={
originalPrice === discountedPrice
? css.notDiscountedPriceLayer
: css.discountedPriceLayer
}
>
<span>
{patncNm} {$L("Price")}
</span>
<div className={css.priceWrapper}>
{discountedPrice !== originalPrice && discountRate >= 5 && (
<span className={css.discountRateTag}>{discountRate}</span>
)}
<span className={css.discountedPrice}>{discountedPrice}</span>
{discountedPrice !== originalPrice && (
<span className={css.originalPrice}>{originalPrice}</span>
)}
</div>
</div>
)}
{shippingCharge && (
<div className={css.shippingLayer}>
<span>{$L("Shipping and Handling")}</span>
<span>{shippingCharge}</span>
</div>
)}
</>
);
}

View File

@@ -0,0 +1,71 @@
@import "../../../../style/CommonStyle.module.less";
@import "../../../../style/utils.module.less";
.discountedPriceLayer {
.flex(@justifyCenter:space-between);
font-weight: bold;
font-size: 36px;
color: @COLOR_GRAY07;
margin-top: 31px;
.priceWrapper {
.flex();
}
.discountRateTag {
padding: 0 12px;
background: #f00;
color: @COLOR_WHITE;
font-weight: bold;
font-size: 24px;
text-align: center;
border-radius: 6px;
height: 42px;
line-height: 42px;
}
.discountedPrice {
font-weight: bold;
font-size: 44px;
line-height: 1.14;
color: @PRIMARY_COLOR_RED;
margin-left: 12px;
}
.originalPrice {
font-size: 24px;
color: @COLOR_GRAY03;
text-decoration: line-through;
margin-left: 9px;
font-weight: normal;
}
}
.notDiscountedPriceLayer {
.flex(@justifyCenter:space-between);
font-weight: bold;
font-size: 36px;
color: @COLOR_GRAY07;
margin-top: 31px;
.priceWrapper {
.flex();
}
.discountedPrice {
font-weight: bold;
font-size: 44px;
line-height: 1.14;
color: @PRIMARY_COLOR_RED;
margin-left: 12px;
}
}
.shippingLayer {
width: 100%;
.flex(@justifyCenter:space-between);
// margin-top: 10px;
> span {
font-size: 24px;
line-height: 1.33;
color: @COLOR_GRAY03;
}
}

View File

@@ -27,7 +27,10 @@ import {
} from "../../../actions/couponActions";
import { sendLogPaymentEntry } from "../../../actions/logActions";
import { pushPanel } from "../../../actions/panelActions";
import { getProductOption } from "../../../actions/productActions";
import {
getProductOption,
getProductOptionId,
} from "../../../actions/productActions";
import TButton from "../../../components/TButton/TButton";
import TPopUp from "../../../components/TPopUp/TPopUp";
import TQRCode from "../../../components/TQRCode/TQRCode";
@@ -38,6 +41,7 @@ import * as Config from "../../../utils/Config";
import { $L, getQRCodeUrl } from "../../../utils/helperMethods";
import { SpotlightIds } from "../../../utils/SpotlightIds";
import FavoriteBtn from "../components/FavoriteBtn";
import BillingProductPrice from "./BillingProductPrice/BillingProductPrice";
import css from "./SingleOption.module.less";
const Container = SpotlightContainerDecorator(
@@ -88,9 +92,6 @@ export default function SingleOption({
const [selectedOptionInfo, setSelectedOptionInfo] = useState();
const [downloadCouponArr, setDownloadCouponArr] = useState([]);
const [focused, setFocused] = useState(false);
const { priceInfo, shippingCharge } = productInfo || productData;
const { originalPrice, discountedPrice, discountRate } =
usePriceInfo(priceInfo) || {};
const webOSVersion = useSelector(
(state) => state.common.appStatus.webOSVersion
@@ -230,6 +231,12 @@ export default function SingleOption({
setSelectedOptions(
productOptionInfos[selectedBtnOptIdx]?.prdtOptDtl[index]
);
dispatch(
getProductOptionId(
productOptionInfos[selectedBtnOptIdx]?.prdtOptDtl[index]
?.prodOptCdCval
)
);
setIsOptionValue(true);
onClose();
},
@@ -715,34 +722,11 @@ export default function SingleOption({
</div>
{/* Price */}
{originalPrice && discountedPrice && (
<div
className={
originalPrice === discountedPrice
? css.notDiscountedPriceLayer
: css.discountedPriceLayer
}
>
<span>
{patncNm || productData.patncNm} {$L("Price")}
</span>
<div className={css.priceWrapper}>
{discountedPrice !== originalPrice && discountRate >= 5 && (
<span className={css.discountRateTag}>{discountRate}</span>
)}
<span className={css.discountedPrice}>{discountedPrice}</span>
{discountedPrice !== originalPrice && (
<span className={css.originalPrice}>{originalPrice}</span>
)}
</div>
</div>
)}
{shippingCharge && (
<div className={css.shippingLayer}>
<span>{$L("Shipping and Handling")}</span>
<span>{shippingCharge}</span>
</div>
)}
<BillingProductPrice
productInfo={productInfo}
selectedOptions={selectedOptions}
patncNm={patncNm || productData?.patncNm}
/>
</div>
{/* BYU NOW & FAVORITE */}
<div>

View File

@@ -154,63 +154,6 @@
}
}
}
.discountedPriceLayer {
.flex(@justifyCenter:space-between);
font-weight: bold;
font-size: 36px;
color: @COLOR_GRAY07;
margin-top: 31px;
.priceWrapper {
.flex();
}
.discountRateTag {
padding: 0 12px;
background: #f00;
color: @COLOR_WHITE;
font-weight: bold;
font-size: 24px;
text-align: center;
border-radius: 6px;
height: 42px;
line-height: 42px;
}
.discountedPrice {
font-weight: bold;
font-size: 44px;
line-height: 1.14;
color: @PRIMARY_COLOR_RED;
margin-left: 12px;
}
.originalPrice {
font-size: 24px;
color: @COLOR_GRAY03;
text-decoration: line-through;
margin-left: 9px;
font-weight: normal;
}
}
.notDiscountedPriceLayer {
.flex(@justifyCenter:space-between);
font-weight: bold;
font-size: 36px;
color: @COLOR_GRAY07;
margin-top: 31px;
.priceWrapper {
.flex();
}
.discountedPrice {
font-weight: bold;
font-size: 44px;
line-height: 1.14;
color: @PRIMARY_COLOR_RED;
margin-left: 12px;
}
}
.shippingLayer {
width: 100%;

View File

@@ -18,7 +18,7 @@ const Container = SpotlightContainerDecorator(
export default function ProductOption({ children, productInfo }) {
const { patncLogoPath, prdtId, prdtNm, revwGrd, expsPrdtNo } = productInfo;
const productOptionId = useSelector((state) => state.product.prodOptCdCval);
const productNameDangerousHTML = useMemo(() => {
const sanitizedString = removeSpecificTags(prdtNm);
@@ -38,9 +38,9 @@ export default function ProductOption({ children, productInfo }) {
fallbackSrc={defaultLogoImg}
/>
{expsPrdtNo && (
{(expsPrdtNo || productOptionId) && (
<div aria-label={productInfo.patnrNm + ", ID :" + expsPrdtNo}>
{$L("ID")} : {expsPrdtNo}
{$L("ID")} : {productOptionId ? productOptionId : expsPrdtNo}
</div>
)}
</div>