detailpanel promotion
This commit is contained in:
BIN
com.twin.app.shoptime/assets/images/badge/badge-promotion.png
Normal file
BIN
com.twin.app.shoptime/assets/images/badge/badge-promotion.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 20 KiB |
@@ -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>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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}>
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user