detailpanel promotion

This commit is contained in:
고동영
2024-04-23 14:17:52 +09:00
parent 752267cbb3
commit 2b84c5702e
7 changed files with 211 additions and 120 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

View File

@@ -39,6 +39,7 @@ export default function DetailPanel({ panelInfo }) {
const { prdtId, patnrId, curationId, type, bgImgNo } = panelInfo;
console.log("#panelInfo", panelInfo);
useEffect(() => {
if (type === "hotel") {
dispatch(
@@ -140,23 +141,45 @@ export default function DetailPanel({ panelInfo }) {
}, [panelInfo]);
return (
<TPanel isTabActivated={false}>
<THeader
className={css.header}
title={
(prdtId && productData?.prdtNm) ||
(type === "hotel" && hotelData?.hotelInfo.curationNm) ||
(type === "theme" && themeData?.themeInfo[0]?.curationNm)
}
onBackButton
onClick={onClick}
/>
<TBody className={css.tbody} scrollable={false}>
{/* 단일상품 영역 */}
{productData?.pmtSuptYn === "Y" &&
productData?.grPrdtProcYn === "N" &&
prdtId && (
<SingleProduct
<>
<TPanel isTabActivated={false}>
<THeader
className={css.header}
title={
(prdtId && productData?.prdtNm) ||
(type === "hotel" && hotelData?.hotelInfo.curationNm) ||
(type === "theme" && themeData?.themeInfo[0]?.curationNm)
}
onBackButton
onClick={onClick}
/>
<TBody className={css.tbody} scrollable={false}>
{/* 단일상품 영역 */}
{productData?.pmtSuptYn === "Y" &&
productData?.grPrdtProcYn === "N" &&
prdtId && (
<SingleProduct
selectedPatnrId={patnrId}
selectedPrdtId={prdtId}
selectedIndex={selectedIndex}
setSelectedIndex={setSelectedIndex}
launchedFromPlayer={panelInfo.launchedFromPlayer}
/>
)}
{/* 그룹상품 영역 */}
{productData?.pmtSuptYn === "Y" &&
productData?.grPrdtProcYn === "Y" && (
<GroupProduct
selectedPatnrId={patnrId}
selectedPrdtId={prdtId}
selectedIndex={selectedIndex}
setSelectedIndex={setSelectedIndex}
launchedFromPlayer={panelInfo.launchedFromPlayer}
/>
)}
{/* 구매불가상품 영역 */}
{productData?.pmtSuptYn === "N" && prdtId && (
<UnableProduct
selectedPatnrId={patnrId}
selectedPrdtId={prdtId}
selectedIndex={selectedIndex}
@@ -164,39 +187,19 @@ export default function DetailPanel({ panelInfo }) {
launchedFromPlayer={panelInfo.launchedFromPlayer}
/>
)}
{/* 그룹상품 영역 */}
{productData?.pmtSuptYn === "Y" &&
productData?.grPrdtProcYn === "Y" && (
<GroupProduct
selectedPatnrId={patnrId}
selectedPrdtId={prdtId}
{/* 테마그룹상품 영역*/}
{curationId && (hotelInfos || themeData) && (
<ThemeProduct
selectedIndex={selectedIndex}
setSelectedIndex={setSelectedIndex}
selectedCurationId={curationId}
selectedPatnrId={patnrId}
themeType={type}
launchedFromPlayer={panelInfo.launchedFromPlayer}
/>
)}
{/* 구매불가상품 영역 */}
{productData?.pmtSuptYn === "N" && prdtId && (
<UnableProduct
selectedPatnrId={patnrId}
selectedPrdtId={prdtId}
selectedIndex={selectedIndex}
setSelectedIndex={setSelectedIndex}
launchedFromPlayer={panelInfo.launchedFromPlayer}
/>
)}
{/* 테마그룹상품 영역*/}
{curationId && (hotelInfos || themeData) && (
<ThemeProduct
selectedIndex={selectedIndex}
setSelectedIndex={setSelectedIndex}
selectedCurationId={curationId}
selectedPatnrId={patnrId}
themeType={type}
launchedFromPlayer={panelInfo.launchedFromPlayer}
/>
)}
</TBody>
</TBody>
</TPanel>
{lgCatCd && (productData || themeProductInfos) && (
<YouMayLike
isUnable={
@@ -207,6 +210,6 @@ export default function DetailPanel({ panelInfo }) {
lgCatCd={lgCatCd}
/>
)}
</TPanel>
</>
);
}

View File

@@ -72,9 +72,6 @@ export default function UnableOption({
Spotlight.focus("shopbymobile_Btn");
}, [productInfo]);
console.log("#productInfo", productInfo);
console.log("#promotionCode", promotionCode);
const handleSMSClick = useCallback(() => {
dispatch(setShowPopup(Config.ACTIVE_POPUP.smsPopup));
}, [popupVisible]);
@@ -221,11 +218,20 @@ export default function UnableOption({
</div>
)}
</div>
{price5 && installmentMonths && (
{price5 && installmentMonths && promotionCode === 0 && (
<div className={css.installedPrc}>
{$L(`OR ${price5} with ${installmentMonths}-month financing`)}
</div>
)}
{promotionCode !== "0" && (
<div className={css.promotionContainer}>
<span> {$L("input at your checkout")}</span>
<div className={css.promotionContents}>
<div>{promotionCode}</div>
<h3>{$L("SHOPTIMETONE")}</h3>
</div>
</div>
)}
</div>
<div className={css.btnContainer}>

View File

@@ -172,4 +172,31 @@
min-width: 756px;
}
}
.promotionContainer {
.promotionContents {
display: flex;
margin-top: 7px;
> div {
background-color: #ff871d;
border-radius: 8px;
border: solid 0 #25201c;
font-size: 24px;
font-weight: 600;
color: #fff;
padding: 0 9px 0 11px;
}
> h3 {
font-size: 28px;
color: #ff871d;
font-weight: bold;
margin-left: 9px;
}
}
> span {
font-size: 24px;
color: #808080;
}
}
}

View File

@@ -21,11 +21,10 @@ export default function UnableProduct({
selectedPrdtId,
selectedIndex,
setSelectedIndex,
launchedFromPlayer
launchedFromPlayer,
}) {
const productData = useSelector((state) => state.main.productData);
const { promotionCode } = usePriceInfo(productData?.priceInfo) || {};
const isProductSoldOut = () => {
if (productData && productData.length > 0) {
return productData.soldoutFlag === "Y";
@@ -46,7 +45,6 @@ export default function UnableProduct({
setSelectedIndex={setSelectedIndex}
productInfo={productData}
soldoutFlag={soldout}
promotionCode={promotionCode}
launchedFromPlayer={launchedFromPlayer}
/>
<IndicatorOptions

View File

@@ -10,13 +10,15 @@ import Spottable from "@enact/spotlight/Spottable";
import defaultImage from "../../../../../assets/images/img-thumb-empty-144@3x.png";
import { pushPanel } from "../../../../actions/panelActions";
import TVideoPlayer from "../../../../components/TVideoPlayer/TVideoPlayer";
import {
finishVideoPreview,
startVideoPlayer,
} from "../../../../actions/playActions";
import TVirtualGridList from "../../../../components/TVirtualGridList/TVirtualGridList";
import usePriceInfo from "../../../../hooks/usePriceInfo";
import useScrollTo from "../../../../hooks/useScrollTo";
import { panel_names } from "../../../../utils/Config";
import css from "./Indicator.module.less";
import { finishVideoPreview, startVideoPlayer } from "../../../../actions/playActions";
import { scaleW } from "../../../../utils/helperMethods";
import css from "./Indicator.module.less";
const Container = SpotlightContainerDecorator(
{ enterTo: "last-focused", preserveld: true },
@@ -31,28 +33,39 @@ function Indicator({
productInfo,
soldoutFlag,
launchedFromPlayer,
promotionCode,
}) {
const dispatch = useDispatch();
const { cursorVisible } = useSelector((state) => state.common.appStatus);
const { getScrollTo, scrollTop } = useScrollTo();
const [detailVideoPlaying, setDetailVideoPlaying] = useState(!launchedFromPlayer && productInfo.prdtMediaUrl);
const [detailVideoPlaying, setDetailVideoPlaying] = useState(
!launchedFromPlayer && productInfo.prdtMediaUrl
);
let imagePosition = IMAGE_WIDTH * selectedIndex - IMAGE_WIDTH;
const { discountRate, promotionCode } = usePriceInfo(productInfo.priceInfo);
useEffect(() => {
console.log('yhcho productInfo detailVideoPlaying', productInfo, launchedFromPlayer, detailVideoPlaying);
if(detailVideoPlaying && productInfo.prdtMediaUrl){ //auto play
dispatch(startVideoPlayer({
showUrl: productInfo.prdtMediaUrl,
showNm: productInfo.prdtNm,
patnrNm: productInfo.patncNm,
patncLogoPath: productInfo.patncLogoPath,
orderPhnNo: productInfo.orderPhnNo,
shptmBanrTpNm: "MEDIA",
modal: true,
modalContainerId: "indicator_videoContainer", //to calc width, height, left, top
modalClassName: selectedIndex === 0 ? css.videoModal:css.videoModalHide
}));
console.log(
"yhcho productInfo detailVideoPlaying",
productInfo,
launchedFromPlayer,
detailVideoPlaying
);
if (detailVideoPlaying && productInfo.prdtMediaUrl) {
//auto play
dispatch(
startVideoPlayer({
showUrl: productInfo.prdtMediaUrl,
showNm: productInfo.prdtNm,
patnrNm: productInfo.patncNm,
patncLogoPath: productInfo.patncLogoPath,
orderPhnNo: productInfo.orderPhnNo,
shptmBanrTpNm: "MEDIA",
modal: true,
modalContainerId: "indicator_videoContainer", //to calc width, height, left, top
modalClassName:
selectedIndex === 0 ? css.videoModal : css.videoModalHide,
})
);
}
}, [selectedIndex, productInfo, detailVideoPlaying, launchedFromPlayer]);
@@ -79,24 +92,26 @@ function Indicator({
}
}, [selectedIndex, listImages]);
const canPlayVideo = useMemo(()=>{
const canPlayVideo = useMemo(() => {
return productInfo.prdtMediaUrl && selectedIndex === 0;
},[productInfo, selectedIndex]);
}, [productInfo, selectedIndex]);
const handleVideoOnClick = useCallback(() => {
if(canPlayVideo){
dispatch(startVideoPlayer({
showUrl: productInfo.prdtMediaUrl,
showNm: productInfo.prdtNm,
patnrNm: productInfo.patncNm,
patncLogoPath: productInfo.patncLogoPath,
orderPhnNo: productInfo.orderPhnNo,
shptmBanrTpNm: "MEDIA",
modal: !detailVideoPlaying,
modalContainerId: "indicator_videoContainer", //to calc width, height, left, top
modalClassName:css.videoModal
}));
if(!detailVideoPlaying){
if (canPlayVideo) {
dispatch(
startVideoPlayer({
showUrl: productInfo.prdtMediaUrl,
showNm: productInfo.prdtNm,
patnrNm: productInfo.patncNm,
patncLogoPath: productInfo.patncLogoPath,
orderPhnNo: productInfo.orderPhnNo,
shptmBanrTpNm: "MEDIA",
modal: !detailVideoPlaying,
modalContainerId: "indicator_videoContainer", //to calc width, height, left, top
modalClassName: css.videoModal,
})
);
if (!detailVideoPlaying) {
setDetailVideoPlaying(true);
}
}
@@ -111,16 +126,12 @@ function Indicator({
};
}, [selectedIndex]);
const onSpotlightUp = useCallback(() => {
Spotlight.focus("spotlightId_backBtn");
}, []);
const onSpotlightLeft = useCallback(() => {
Spotlight.focus("spotlightId_backBtn");
}, []);
const listImages = useMemo(()=>{
const images = [...productInfo.imgUrls600];
const listImages = useMemo(() => {
const images = [...productInfo.imgUrls600];
if (productInfo?.prdtMediaUrl !== null) {
images.splice(
0,
@@ -131,15 +142,14 @@ function Indicator({
);
}
return images;
},[productInfo]);
}, [productInfo]);
const selectedImage = useMemo(()=>{
const selectedImage = useMemo(() => {
return listImages[selectedIndex];
},[listImages, selectedIndex]);
}, [listImages, selectedIndex]);
const renderItem = useCallback(
({ index, ...rest }) => {
const handleItemClick = () => {
setSelectedIndex(index);
};
@@ -182,18 +192,34 @@ function Indicator({
onClick={handleVideoOnClick}
>
<>
<Image
className={css.image}
src={detailVideoPlaying && canPlayVideo ? "" : selectedImage}
alt=""
></Image>
{soldoutFlag && <h3 className={css.soldoutLabel}>SOLD OUT</h3>}
{!detailVideoPlaying && canPlayVideo && <h3 className={css.soldoutLabel}>Play Button (todo)</h3>}
<Image
className={css.image}
src={detailVideoPlaying && canPlayVideo ? "" : selectedImage}
alt=""
></Image>
{soldoutFlag && <h3 className={css.soldoutLabel}>SOLD OUT</h3>}
{!detailVideoPlaying && canPlayVideo && (
<h3 className={css.soldoutLabel}>Play Button (todo)</h3>
)}
{promotionCode && promotionCode !== "0" && (
<div className={css.promotionImage}>
<div className={css.discountRate}>
<h2>{discountRate}</h2>
<h3>OFF</h3>
</div>
</div>
)}
</>
</SpottableComponent>
</div>
);
}, [productInfo, selectedIndex, selectedImage, soldoutFlag, detailVideoPlaying]);
}, [
productInfo,
selectedIndex,
selectedImage,
soldoutFlag,
detailVideoPlaying,
]);
return (
<Container className={css.indicatorContainer}>
@@ -225,7 +251,7 @@ function Indicator({
spotlightDisabled={!cursorVisible}
className={classNames(
css.downButton,
(listImages.length-1) === selectedIndex && css.disable
listImages.length - 1 === selectedIndex && css.disable
)}
/>
</div>
@@ -233,19 +259,19 @@ function Indicator({
);
}
const propsAreEqual = (prev, next) => {
const keys = Object.keys(prev);
const nextKeys = Object.keys(next);
if(keys.length !== nextKeys.length){
return false;
}
for(let i=0; i<keys.length; i++){
if(prev[keys[i]] !== next[keys[i]]){
const keys = Object.keys(prev);
const nextKeys = Object.keys(next);
if (keys.length !== nextKeys.length) {
return false;
}
for (let i = 0; i < keys.length; i++) {
if (prev[keys[i]] !== next[keys[i]]) {
if (JSON.stringify(prev[keys[i]]) === JSON.stringify(next[keys[i]])) {
continue;
}
return false;
}
}
return true;
}
export default React.memo(Indicator, propsAreEqual);
return false;
}
}
return true;
};
export default React.memo(Indicator, propsAreEqual);

View File

@@ -15,6 +15,7 @@
.thumbnailContainer {
.size(@w: 560px, @h: 560px);
margin-right: 10px;
position: relative;
.player {
.size(@w: 560px, @h: 560px);
margin: 0 10px 10px 0;
@@ -76,7 +77,7 @@
position: relative;
display: flex;
justify-content: center;
.image{
.image {
position: absolute;
width: 100%;
height: 100%;
@@ -153,6 +154,36 @@
}
}
}
.promotionImage {
.size(@w: 158px , @h: 180px);
position: absolute;
top: 0;
left: 0;
background-image: url("../../../../../assets/images/badge/badge-promotion.png");
background-position: center;
background-size: 158px 180px;
.discountRate {
color: #fff;
text-align: center;
font-weight: bold;
line-height: 0.47;
> h2 {
position: absolute;
top: 95px;
right: 54px;
font-size: 38px;
}
> h3 {
position: absolute;
font-size: 15px;
top: 130px;
left: 65px;
}
}
}
}
.tVirtualGridListContainer {