DetailPanel soldout 작업

This commit is contained in:
고동영
2024-04-15 16:10:50 +09:00
parent 32eb7d5a66
commit 6f4007e57e
12 changed files with 143 additions and 62 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

View File

@@ -91,7 +91,7 @@ export default function ItemDetail() {
}) })
); );
} }
}, [dispatch, selectedPatnrId, selectedPrdtId, panels, selectedIndex]); }, [dispatch, selectedPatnrId, selectedPrdtId, panels]);
const onClick = useCallback(() => { const onClick = useCallback(() => {
dispatch(popPanel()); dispatch(popPanel());
@@ -130,8 +130,6 @@ export default function ItemDetail() {
} }
}, [panels, selectedPatnrId, selectedPatnrId, httpHeader]); }, [panels, selectedPatnrId, selectedPatnrId, httpHeader]);
console.log("#productData", productData);
useEffect(() => { useEffect(() => {
if (panels && selectedPatnrId && selectedPrdtId) { if (panels && selectedPatnrId && selectedPrdtId) {
saveToLocalStorage(); saveToLocalStorage();

View File

@@ -15,6 +15,16 @@ export default function GroupProduct({
setSelectedIndex, setSelectedIndex,
}) { }) {
const productData = useSelector((state) => state.main.productData); const productData = useSelector((state) => state.main.productData);
const isProductSoldOut = () => {
if (productData && productData.length > 0) {
return productData.soldoutFlag === "Y";
} else {
return false;
}
};
const isSoldout = isProductSoldOut();
return ( return (
<> <>
<div className={css.container}> <div className={css.container}>
@@ -22,6 +32,7 @@ export default function GroupProduct({
selectedIndex={selectedIndex} selectedIndex={selectedIndex}
setSelectedIndex={setSelectedIndex} setSelectedIndex={setSelectedIndex}
productInfo={productData} productInfo={productData}
soldoutFlag={isSoldout}
/> />
<IndicatorOptions <IndicatorOptions
productInfo={productData} productInfo={productData}

View File

@@ -70,8 +70,8 @@ export default function SingleOption({
setPromotions(newPromotions); setPromotions(newPromotions);
}, [partnerCoupon, shoptiemCoupon]); }, [partnerCoupon, shoptiemCoupon]);
console.log("#coupon ", partnerCoupon, shoptiemCoupon); // console.log("#coupon ", partnerCoupon, shoptiemCoupon);
console.log("#selectedCoupon", selectedCoupon); // console.log("#selectedCoupon", selectedCoupon);
useEffect(() => { useEffect(() => {
dispatch( dispatch(
@@ -178,7 +178,6 @@ export default function SingleOption({
return; return;
} }
if (productOptionInfos && productOptionInfos.length > 0) { if (productOptionInfos && productOptionInfos.length > 0) {
console.log("#일반상품 옵션 포커스");
Spotlight.focus("optionBtn-0"); Spotlight.focus("optionBtn-0");
} else if (productData && productData.soldoutFlag === "Y") { } else if (productData && productData.soldoutFlag === "Y") {
Spotlight.focus("spotlightId_backBtn"); Spotlight.focus("spotlightId_backBtn");

View File

@@ -1,12 +1,12 @@
import React from 'react'; import React from "react";
import { useSelector } from 'react-redux'; import { useSelector } from "react-redux";
import Indicator from '../components/indicator/Indicator'; import Indicator from "../components/indicator/Indicator";
import IndicatorOptions from '../components/indicator/IndicatorOptions'; import IndicatorOptions from "../components/indicator/IndicatorOptions";
import ProductOption from '../components/ProductOption'; import ProductOption from "../components/ProductOption";
import SingleOption from './SingleOption'; import SingleOption from "./SingleOption";
import css from './SingleProduct.module.less'; import css from "./SingleProduct.module.less";
export default function SingleProduct({ export default function SingleProduct({
selectedPatnrId, selectedPatnrId,
@@ -15,7 +15,15 @@ export default function SingleProduct({
setSelectedIndex, setSelectedIndex,
}) { }) {
const productData = useSelector((state) => state.main.productData); const productData = useSelector((state) => state.main.productData);
const isProductSoldOut = () => {
if (productData && productData.length > 0) {
return productData.soldoutFlag === "Y";
} else {
return false;
}
};
const isSoldout = isProductSoldOut();
return ( return (
<> <>
<div className={css.container}> <div className={css.container}>
@@ -23,6 +31,7 @@ export default function SingleProduct({
selectedIndex={selectedIndex} selectedIndex={selectedIndex}
setSelectedIndex={setSelectedIndex} setSelectedIndex={setSelectedIndex}
productInfo={productData} productInfo={productData}
soldoutFlag={isSoldout}
/> />
<IndicatorOptions <IndicatorOptions
productInfo={productData} productInfo={productData}

View File

@@ -102,6 +102,7 @@ export default function HotelOption({
useEffect(() => { useEffect(() => {
Spotlight.focus("seemore_Btn"); Spotlight.focus("seemore_Btn");
}, [hotelInfos]); }, [hotelInfos]);
return ( return (
<> <>
<div> <div>

View File

@@ -14,6 +14,19 @@ export default function ThemeOption({ selectedIndex, setSelectedIndex }) {
); );
const productData = useSelector((state) => state.home.productData); const productData = useSelector((state) => state.home.productData);
const isProductSoldOut = () => {
if (
productInfo &&
productInfo.length > selectedIndex &&
selectedIndex >= 0
) {
return productInfo[selectedIndex]?.soldoutFlag === "Y";
} else {
return false;
}
};
const isSoldout = isProductSoldOut();
return ( return (
<> <>
<div className={css.indicatorContainer}> <div className={css.indicatorContainer}>
@@ -22,6 +35,7 @@ export default function ThemeOption({ selectedIndex, setSelectedIndex }) {
selectedIndex={selectedIndex} selectedIndex={selectedIndex}
setSelectedIndex={setSelectedIndex} setSelectedIndex={setSelectedIndex}
thumbnailUrls={productInfo[selectedIndex]?.imgUrls600} thumbnailUrls={productInfo[selectedIndex]?.imgUrls600}
soldoutFlag={isSoldout}
isSpotlight isSpotlight
/> />
<IndicatorOptions <IndicatorOptions

View File

@@ -17,6 +17,15 @@ export default function UnableProduct({
}) { }) {
const productData = useSelector((state) => state.main.productData); const productData = useSelector((state) => state.main.productData);
const isProductSoldOut = () => {
if (productData && productData.length > 0) {
return productData.soldoutFlag === "Y";
} else {
return false;
}
};
const soldout = isProductSoldOut();
return ( return (
<> <>
<div className={css.container}> <div className={css.container}>
@@ -24,6 +33,7 @@ export default function UnableProduct({
selectedIndex={selectedIndex} selectedIndex={selectedIndex}
setSelectedIndex={setSelectedIndex} setSelectedIndex={setSelectedIndex}
productInfo={productData} productInfo={productData}
soldoutFlag={soldout}
/> />
<IndicatorOptions <IndicatorOptions
productInfo={productData} productInfo={productData}

View File

@@ -1,21 +1,16 @@
import React, { import React, { useCallback, useEffect, useState } from "react";
useCallback,
useEffect,
useState,
} from 'react';
import classNames from 'classnames'; import classNames from "classnames";
import { useSelector } from 'react-redux'; import { useSelector } from "react-redux";
import Image from '@enact/sandstone/Image'; import Image from "@enact/sandstone/Image";
import SpotlightContainerDecorator import SpotlightContainerDecorator from "@enact/spotlight/SpotlightContainerDecorator";
from '@enact/spotlight/SpotlightContainerDecorator'; import Spottable from "@enact/spotlight/Spottable";
import Spottable from '@enact/spotlight/Spottable';
import TVirtualGridList import defaultImage from "../../../../../assets/images/img-thumb-empty-144@3x.png";
from '../../../../components/TVirtualGridList/TVirtualGridList'; import TVirtualGridList from "../../../../components/TVirtualGridList/TVirtualGridList";
import useScrollTo from '../../../../hooks/useScrollTo'; import useScrollTo from "../../../../hooks/useScrollTo";
import css from './Indicator.module.less'; import css from "./Indicator.module.less";
const Container = SpotlightContainerDecorator( const Container = SpotlightContainerDecorator(
{ enterTo: "last-focused", preserveld: true }, { enterTo: "last-focused", preserveld: true },
@@ -28,7 +23,7 @@ export default function Indicator({
selectedIndex, selectedIndex,
setSelectedIndex, setSelectedIndex,
productInfo, productInfo,
thumbnailUrls, soldoutFlag,
}) { }) {
const [selectedImage, setSelectedImage] = useState(null); const [selectedImage, setSelectedImage] = useState(null);
const { cursorVisible } = useSelector((state) => state.common.appStatus); const { cursorVisible } = useSelector((state) => state.common.appStatus);
@@ -74,7 +69,7 @@ export default function Indicator({
return ( return (
<> <>
<SpottableImage <SpottableImage
src={image} src={image ? image : defaultImage}
alt="" alt=""
className={classNames( className={classNames(
css.image, css.image,
@@ -103,8 +98,10 @@ export default function Indicator({
<SpottableImage <SpottableImage
src={selectedImage} src={selectedImage}
alt="" alt=""
className={css.thumbnail} className={classNames(css.thumbnail, soldoutFlag && css.soldout)}
/> >
{soldoutFlag && <h3 className={css.soldoutLabel}>SOLD OUT</h3>}
</SpottableImage>
)} )}
</div> </div>
<div> <div>

View File

@@ -16,12 +16,31 @@
display: flex; display: flex;
justify-content: center; justify-content: center;
> h3 {
font-size: 36px;
font-weight: bold;
color: #ffffff;
margin-top: 256px;
z-index: 3;
}
&:focus { &:focus {
&::after { &::after {
.focused(@boxShadow: 22px, @borderRadius:0px); .focused(@boxShadow: 22px, @borderRadius:0px);
} }
} }
&.soldout {
&:before {
.size(@w: 560px , @h: 560px);
content: "";
position: absolute;
left: 0;
top: 0;
background-color: #7a808d;
opacity: 0.7;
}
}
.thumbnailIndicator { .thumbnailIndicator {
margin-top: auto; margin-top: auto;
position: relative; position: relative;

View File

@@ -8,6 +8,7 @@ import Spotlight from "@enact/spotlight";
import SpotlightContainerDecorator from "@enact/spotlight/SpotlightContainerDecorator"; import SpotlightContainerDecorator from "@enact/spotlight/SpotlightContainerDecorator";
import Spottable from "@enact/spotlight/Spottable"; import Spottable from "@enact/spotlight/Spottable";
import defaultImage from "../../../../../assets/images/img-thumb-empty-144@3x.png";
import TVirtualGridList from "../../../../components/TVirtualGridList/TVirtualGridList"; import TVirtualGridList from "../../../../components/TVirtualGridList/TVirtualGridList";
import useScrollTo from "../../../../hooks/useScrollTo"; import useScrollTo from "../../../../hooks/useScrollTo";
import css from "./ThemeIndicator.module.less"; import css from "./ThemeIndicator.module.less";
@@ -27,6 +28,7 @@ export default function ThemeIndicator({
productInfo, productInfo,
thumbnailUrls, thumbnailUrls,
isSpotlight, isSpotlight,
soldoutFlag,
}) { }) {
const [selectedImage, setSelectedImage] = useState(null); const [selectedImage, setSelectedImage] = useState(null);
@@ -43,6 +45,7 @@ export default function ThemeIndicator({
useEffect(() => { useEffect(() => {
if (thumbnailUrls) { if (thumbnailUrls) {
const image = thumbnailUrls[imageSelectedIndex]; const image = thumbnailUrls[imageSelectedIndex];
setSelectedImage(image); setSelectedImage(image);
} }
}, [thumbnailUrls, imageSelectedIndex]); }, [thumbnailUrls, imageSelectedIndex]);
@@ -93,12 +96,10 @@ export default function ThemeIndicator({
setImageSelectedIndex(0); setImageSelectedIndex(0);
}; };
console.log("#productInfo", productInfo[index]);
return ( return (
<> <>
<SpottableImage <SpottableImage
src={thumbnailUrl || hotelImgUrl} src={thumbnailUrl ? thumbnailUrl : defaultImage || hotelImgUrl}
alt="" alt=""
className={classNames( className={classNames(
css.image, css.image,
@@ -121,16 +122,11 @@ export default function ThemeIndicator({
); );
useEffect(() => { useEffect(() => {
if ( if (soldoutFlag) {
productInfo &&
productInfo.length &&
productInfo[selectedIndex].soldoutFlag === "Y"
) {
Spotlight.focus("spotlightId_backBtn"); Spotlight.focus("spotlightId_backBtn");
return; return;
} }
if (productInfo && productInfo.length > 0 && isSpotlight) { if (productInfo && productInfo.length > 0 && isSpotlight) {
console.log("#isSpotlight", isSpotlight);
Spotlight.focus("IndicatorGridlistContainer"); Spotlight.focus("IndicatorGridlistContainer");
Spotlight.focus("indicator-image-0"); Spotlight.focus("indicator-image-0");
} }
@@ -140,8 +136,16 @@ export default function ThemeIndicator({
<Container className={css.indicatorContainer}> <Container className={css.indicatorContainer}>
<div> <div>
{productInfo && ( {productInfo && (
<SpottableImage src={selectedImage} alt="" className={css.thumbnail}> <SpottableImage
src={selectedImage}
alt=""
className={classNames(css.thumbnail, soldoutFlag && css.soldout)}
>
<Container className={css.thumbnailIndicator}> <Container className={css.thumbnailIndicator}>
{soldoutFlag ? (
<h3>SOLD OUT</h3>
) : (
<>
<SpottableComponent <SpottableComponent
className={classNames( className={classNames(
css.prevButton, css.prevButton,
@@ -162,8 +166,9 @@ export default function ThemeIndicator({
onClick={handleNextClick} onClick={handleNextClick}
spotlightDisabled={imageLength - 1 === imageSelectedIndex} spotlightDisabled={imageLength - 1 === imageSelectedIndex}
/> />
</>
)}
</Container> </Container>
)
</SpottableImage> </SpottableImage>
)} )}
</div> </div>

View File

@@ -21,6 +21,17 @@
.focused(@boxShadow: 22px, @borderRadius:0px); .focused(@boxShadow: 22px, @borderRadius:0px);
} }
} }
&.soldout {
&:before {
.size(@w: 560px , @h: 560px);
content: "";
position: absolute;
left: 0;
top: 0;
background-color: #7a808d;
opacity: 0.7;
}
}
.thumbnailIndicator { .thumbnailIndicator {
margin-top: auto; margin-top: auto;
@@ -59,6 +70,13 @@
background-image: url("../../../../../assets/images/btn/btn-next-thumb-nor.svg"); background-image: url("../../../../../assets/images/btn/btn-next-thumb-nor.svg");
} }
} }
//soldout
> h3 {
font-size: 36px;
font-weight: bold;
color: #ffffff;
margin-bottom: 237px;
}
> span { > span {
// .size(@w: 51px , @h: 21px); // .size(@w: 51px , @h: 21px);
-webkit-text-stroke: 1px rgba(255, 255, 255, 0.7); -webkit-text-stroke: 1px rgba(255, 255, 255, 0.7);