디테일패널 폴더구조 변경 및 인디게이터 구현

This commit is contained in:
고동영
2024-03-19 10:04:02 +09:00
parent c027053982
commit 70c7548898
27 changed files with 487 additions and 250 deletions

View File

@@ -1,32 +1,42 @@
import React, { useEffect, useState } from "react";
import React, {
useEffect,
useState,
} from 'react';
import { useDispatch, useSelector } from "react-redux";
import {
useDispatch,
useSelector,
} from 'react-redux';
import {
getThemeCurationDetailInfo,
getThemeHotelDetailInfo,
} from "../../actions/homeActions";
import { getMainCategoryDetail } from "../../actions/mainActions";
import { popPanel } from "../../actions/panelActions";
import { getProductGroup } from "../../actions/productActions";
import TBody from "../../components/TBody/TBody";
import THeader from "../../components/THeader/THeader";
import TPanel from "../../components/TPanel/TPanel";
import GroupProduct from "./container/GroupProduct";
import SingleProduct from "./container/SingleProduct";
import ThemeProduct from "./container/ThemeProduct";
import UnableProduct from "./container/UnableProduct";
import YouMayLike from "./container/YouMayLike";
import css from "./DetailPanel.module.less";
} from '../../actions/homeActions';
import { getMainCategoryDetail } from '../../actions/mainActions';
import { popPanel } from '../../actions/panelActions';
import { getProductGroup } from '../../actions/productActions';
import TBody from '../../components/TBody/TBody';
import THeader from '../../components/THeader/THeader';
import TPanel from '../../components/TPanel/TPanel';
import css from './DetailPanel.module.less';
import GroupProduct from './GroupProduct/GroupProduct';
import SingleProduct from './SingleProduct/SingleProduct';
import ThemeProduct from './ThemeProduct/ThemeProduct';
import UnableProduct from './UnableProduct/UnableProduct';
import YouMayLike from './YouMayLike/YouMayLike';
export default function ItemDetail() {
const [selectedPatnrId, setSelectedPatnrId] = useState("");
const [selectedPrdtId, setSelectedPrtdId] = useState("");
const [selectedCurationId, setSelectedCurationId] = useState("");
const [selectedIndex, setSelectedIndex] = useState(0);
const productData = useSelector((state) => state.main.productData);
const panels = useSelector((state) => state.panels.panels);
const groupInfos = useSelector((state) => state.product.groupInfo);
const hotelInfos = useSelector(
(state) => state.home.themeCurationHotelDetailData
);
const dispatch = useDispatch();
@@ -48,33 +58,37 @@ export default function ItemDetail() {
useEffect(() => {
getPanelInfo();
dispatch(
getThemeCurationDetailInfo({
patnrId: selectedPatnrId,
curationId: selectedCurationId,
})
);
dispatch(
getThemeHotelDetailInfo({
patnrId: selectedPatnrId,
curationId: selectedCurationId,
})
);
if (selectedCurationId) {
dispatch(
getThemeCurationDetailInfo({
patnrId: selectedPatnrId,
curationId: selectedCurationId,
})
);
dispatch(
getThemeHotelDetailInfo({
patnrId: selectedPatnrId,
curationId: selectedCurationId,
})
);
}
dispatch(
getMainCategoryDetail({
patnrId: selectedPatnrId,
prdtId: selectedPrdtId,
})
);
if (selectedPrdtId) {
dispatch(
getMainCategoryDetail({
patnrId: selectedPatnrId,
prdtId: selectedPrdtId,
})
);
dispatch(
getProductGroup({
patnrId: selectedPatnrId,
prdtId: selectedPrdtId,
})
);
}, [dispatch, panels, selectedPatnrId, selectedPrdtId]);
dispatch(
getProductGroup({
patnrId: selectedPatnrId,
prdtId: selectedPrdtId,
})
);
}
}, [dispatch, panels, selectedPatnrId, selectedPrdtId, selectedCurationId]);
const onClick = () => {
dispatch(popPanel());
@@ -83,18 +97,32 @@ export default function ItemDetail() {
<TPanel isTabActivated={false}>
<THeader
className={css.header}
title={productData?.prdtNm}
title={
(selectedPrdtId && productData?.prdtNm) ||
(selectedCurationId && hotelInfos[selectedIndex]?.hotelNm)
}
onBackButton
onClick={onClick}
/>
<TBody className={css.container} scrollable={false}>
<TBody className={css.tbody} scrollable={false}>
{/* 단일상품 영역 */}
{productData?.pmtSuptYn === "Y" && selectedPrdtId && (
<SingleProduct
selectedPatnrId={selectedPatnrId}
selectedPrdtId={selectedPrdtId}
/>
)}
{productData?.pmtSuptYn === "Y" &&
productData?.grPrdtProcFlag === "N" &&
selectedPrdtId && (
<SingleProduct
selectedPatnrId={selectedPatnrId}
selectedPrdtId={selectedPrdtId}
/>
)}
{/* 그룹상품 영역 */}
{productData?.pmtSuptYn === "Y" &&
productData?.grPrdtProcFlag === "Y " &&
selectedPrdtId && (
<GroupProduct
selectedPatnrId={selectedPatnrId}
selectedPrdtId={selectedPrdtId}
/>
)}
{/* 구매불가상품 영역 */}
{productData?.pmtSuptYn === "N" && selectedPrdtId && (
<UnableProduct
@@ -102,18 +130,16 @@ export default function ItemDetail() {
selectedPrdtId={selectedPrdtId}
/>
)}
{/* 그룹상품 영역 */}
{groupInfos && selectedPrdtId && (
<GroupProduct
selectedPatnrId={selectedPatnrId}
selectedPrdtId={selectedPrdtId}
/>
)}
{/* 테마그룹상품 영역*/}
{!selectedPrdtId && <ThemeProduct />}
{selectedCurationId && (
<ThemeProduct
selectedIndex={selectedIndex}
setSelectedIndex={setSelectedIndex}
/>
)}
</TBody>
<YouMayLike />
{selectedPrdtId && <YouMayLike />}
</TPanel>
);
}

View File

@@ -25,7 +25,7 @@
// }
}
.container {
.tbody {
position: relative;
display: flex;
justify-content: space-between;

View File

@@ -1,16 +1,20 @@
import React, { useEffect } from "react";
import React, { useEffect } from 'react';
import { useDispatch, useSelector } from "react-redux";
import {
useDispatch,
useSelector,
} from 'react-redux';
import SpotlightContainerDecorator from "@enact/spotlight/SpotlightContainerDecorator";
import Spottable from "@enact/spotlight/Spottable";
import SpotlightContainerDecorator
from '@enact/spotlight/SpotlightContainerDecorator';
import Spottable from '@enact/spotlight/Spottable';
import noGroupImg from "../../../../../assets/images/img-my-info-billing@3x.png";
import { getMainCategoryDetail } from "../../../../actions/mainActions";
import { getProductGroup } from "../../../../actions/productActions";
import TScroller from "../../../../components/TScroller/TScroller";
import { $L } from "../../../../utils/helperMethods";
import css from "./GroupOption.module.less";
import noGroupImg from '../../../../assets/images/img-my-info-billing@3x.png';
import { getMainCategoryDetail } from '../../../actions/mainActions';
import { getProductGroup } from '../../../actions/productActions';
import TScroller from '../../../components/TScroller/TScroller';
import { $L } from '../../../utils/helperMethods';
import css from './GroupOption.module.less';
const Container = SpotlightContainerDecorator(
{ enterTo: "last-focused", continue5WayHold: true },

View File

@@ -1,5 +1,5 @@
@import "../../../../style/CommonStyle.module.less";
@import "../../../../style/utils.module.less";
@import "../../../style/CommonStyle.module.less";
@import "../../../style/utils.module.less";
.optionGroupScroll {
width: 846px;

View File

@@ -1,9 +1,9 @@
import React from "react";
import React from 'react';
import GroupOption from "../components/optionTypes/GroupOption";
import ProductOption from "../components/ProductOption";
import ProductThumbnail from "../components/ProductThumbnail";
import css from "./GroupProduct.module.less";
import ProductOption from '../components/ProductOption';
import ProductThumbnail from '../components/ProductThumbnail';
import GroupOption from './GroupOption';
import css from './GroupProduct.module.less';
export default function GroupProduct({ selectedPatnrId, selectedPrdtId }) {
return (

View File

@@ -1,26 +1,38 @@
import React, { useCallback, useEffect, useState } from "react";
import React, {
useCallback,
useEffect,
useState,
} from 'react';
import classNames from "classnames";
import { useDispatch, useSelector } from "react-redux";
import classNames from 'classnames';
import {
useDispatch,
useSelector,
} from 'react-redux';
import Spotlight from "@enact/spotlight";
import SpotlightContainerDecorator from "@enact/spotlight/SpotlightContainerDecorator";
import Spottable from "@enact/spotlight/Spottable";
import Spotlight from '@enact/spotlight';
import SpotlightContainerDecorator
from '@enact/spotlight/SpotlightContainerDecorator';
import Spottable from '@enact/spotlight/Spottable';
import { setHidePopup, setShowPopup } from "../../../../actions/commonActions";
import { getProductCouponSearch } from "../../../../actions/couponActions";
import { pushPanel } from "../../../../actions/panelActions";
import { getProductOption } from "../../../../actions/productActions";
import TButton from "../../../../components/TButton/TButton";
import TPopUp from "../../../../components/TPopUp/TPopUp";
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";
import { SpotlightIds } from "../../../../utils/SpotlightIds";
import FavoriteBtn from "../common/FavoriteBtn";
import css from "./SingleOption.module.less";
import {
setHidePopup,
setShowPopup,
} from '../../../actions/commonActions';
import { getProductCouponSearch } from '../../../actions/couponActions';
import { pushPanel } from '../../../actions/panelActions';
import { getProductOption } from '../../../actions/productActions';
import TButton from '../../../components/TButton/TButton';
import TPopUp from '../../../components/TPopUp/TPopUp';
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';
import { SpotlightIds } from '../../../utils/SpotlightIds';
import FavoriteBtn from '../components/common/FavoriteBtn';
import css from './SingleOption.module.less';
const Container = SpotlightContainerDecorator(
{ enterTo: "default-element", preserveId: true },

View File

@@ -1,5 +1,5 @@
@import "../../../../style/CommonStyle.module.less";
@import "../../../../style/utils.module.less";
@import "../../../style/CommonStyle.module.less";
@import "../../../style/utils.module.less";
.detailContainer {
width: 846px;
@@ -38,7 +38,7 @@
min-width: 560px;
background-color: @COLOR_WHITE;
color: @COLOR_GRAY03;
background-image: url(../../../../../assets/images/btn/btn-dropdown-nor@3x.png);
background-image: url(../../../../assets/images/btn/btn-dropdown-nor@3x.png);
.imgElement(42px, 42px, right 30px, center);
position: relative;
@@ -46,7 +46,7 @@
color: @PRIMARY_COLOR_RED;
&::after {
.focused(@boxShadow: 22px, @borderRadius: 12px);
background-image: url(../../../../../assets/images/btn/btn-dropdown-foc@3x.png);
background-image: url(../../../../assets/images/btn/btn-dropdown-foc@3x.png);
.imgElement(42px, 42px, right 26px, center);
}
}
@@ -92,25 +92,25 @@
}
&.increaseBtn {
background-image: url(../../../../../assets/images/btn/btn-quantity-increase-nor@3x.png);
background-image: url(../../../../assets/images/btn/btn-quantity-increase-nor@3x.png);
.imgElement(90px, 90px, center, center);
&:focus {
background-image: url(../../../../../assets/images/btn/btn-quantity-increase-foc@3x.png);
background-image: url(../../../../assets/images/btn/btn-quantity-increase-foc@3x.png);
.imgElement(90px, 90px, center, center);
}
}
&.decreaseBtn {
background-image: url(../../../../../assets/images/btn/btn-quantity-decrease-nor@3x.png);
background-image: url(../../../../assets/images/btn/btn-quantity-decrease-nor@3x.png);
.imgElement(90px, 90px, center, center);
&:focus {
background-image: url(../../../../../assets/images/btn/btn-quantity-decrease-foc@3x.png);
background-image: url(../../../../assets/images/btn/btn-quantity-decrease-foc@3x.png);
.imgElement(90px, 90px, center, center);
}
}
&.decreaseDimBtn {
background-image: url(../../../../../assets/images/btn/btn-quantity-decrease-dim@3x.png);
background-image: url(../../../../assets/images/btn/btn-quantity-decrease-dim@3x.png);
.imgElement(90px, 90px, center, center);
}
}
@@ -228,7 +228,7 @@
.favoriteBtn {
min-width: 78px;
height: 78px;
background-image: url(../../../../../assets/images/icons/ic-heart-nor@3x.png);
background-image: url(../../../../assets/images/icons/ic-heart-nor@3x.png);
.imgElement(54px, 54px, center, center);
}
}

View File

@@ -1,9 +1,9 @@
import React from "react";
import React from 'react';
import SingleOption from "../components/optionTypes/SingleOption";
import ProductOption from "../components/ProductOption";
import ProductThumbnail from "../components/ProductThumbnail";
import css from "./SingleProduct.module.less";
import ProductOption from '../components/ProductOption';
import ProductThumbnail from '../components/ProductThumbnail';
import SingleOption from './SingleOption';
import css from './SingleProduct.module.less';
export default function SingleProduct({ selectedPatnrId, selectedPrdtId }) {
return (

View File

@@ -0,0 +1,88 @@
import React, {
useCallback,
useEffect,
useRef,
useState,
} from 'react';
import { useSelector } from 'react-redux';
import logo from '../../../../assets/images/icons/ic-partners-netflix@3x.png';
import TButton from '../../../components/TButton/TButton';
import TQRCode from '../../../components/TQRCode/TQRCode';
import { $L } from '../../../utils/helperMethods';
import StarRating from '../components/common/StarRating';
import css from './HotelOption.module.less';
export default function HotelOption({ selectedIndex, setSelectedIndex }) {
const tooltipDes = $L(
` Please check for more detailed\ninformation about the product.`
);
const [label, setLabel] = useState("");
const hotelInfos = useSelector(
(state) => state.home.themeCurationHotelDetailData
);
console.log("#hotelInfos", hotelInfos);
useEffect(() => {
let label = "";
let rating = hotelInfos[selectedIndex]?.hotelDetailInfo.revwGrd;
if (rating !== undefined) {
if (rating <= 2.4) {
label = "Fair";
} else if (rating >= 2.5 && rating <= 3.4) {
label = "Good";
} else if (rating >= 3.5 && rating <= 4.4) {
label = "Very Good";
} else if (rating >= 4.5 && rating <= 5) {
label = "Excellent";
}
}
setLabel(label);
}, [selectedIndex, hotelInfos]);
return (
<div className={css.optionContainer}>
<div className={css.topLayer}>
<img src={logo} alt="patncLogoPath" />
<div className={css.rating}>
<StarRating
rating={hotelInfos[selectedIndex]?.hotelDetailInfo.revwGrd}
/>
<span className={css.line} /> <div>{label}</div>
</div>
</div>
<div className={css.title}>{hotelInfos[selectedIndex]?.hotelNm}</div>
<div className={css.amenities}></div>
<div className={css.bottomLayer}>
<div>
<div className={css.today}>{$L("Today, 1 Night(s) 2 Adult(s)")}</div>
<div className={css.roomType}>
{hotelInfos[selectedIndex]?.hotelDetailInfo.roomType}
</div>
<div className={css.price}>
<div>{$L("Price From")}</div>
<p>
{hotelInfos[selectedIndex]?.hotelDetailInfo.currencySign}
{hotelInfos[selectedIndex]?.hotelDetailInfo.price}
</p>
</div>
</div>
<div className={css.qrcodeContainer}>
<TQRCode
text={hotelInfos[selectedIndex]?.qrcodeUrl}
width="160"
height="160"
/>
<div className={css.tooltip}>
<div className={css.tooltipBody}>{tooltipDes}</div>
</div>
</div>
</div>
<TButton className={css.tbutton}>SEE MORE</TButton>
</div>
);
}

View File

@@ -0,0 +1,130 @@
@import "../../../style/CommonStyle.module.less";
@import "../../../style/utils.module.less";
.optionContainer {
.flex(@direction:column ,@justifyCenter:flex-start,@alignCenter:flex-start);
.size(@w: 1026px, @h: 930px);
background-color: @BG_COLOR_01;
padding: 30px 120px 60px 60px;
.topLayer {
width: 100%;
.flex(@direction:row ,@justifyCenter:flex-start);
text-align: left;
color: @COLOR_GRAY03;
font-weight: bold;
font-size: 30px;
justify-content: space-between;
img {
width: 42px;
height: 42px;
margin-right: 11px;
}
.rating {
display: flex;
font-size: 30px;
font-weight: bold;
color: #c70850;
// margin-bottom: 3px;
.line {
.size(@w: 1px , @h: 24px);
background-color: #808080;
margin: 5px 9px 0 10px;
}
}
}
.title {
.elip(@clamp:2);
font-weight: bold;
font-size: 36px;
color: @COLOR_GRAY08;
width: 100%;
margin-top: 20px;
}
.amenities {
.size(@w: 846px , @h: 234px);
background-color: #f2f2f2;
margin: 32px 0 20px 0;
}
.bottomLayer {
display: flex;
.today {
font-size: 24px;
font-weight: bold;
color: #222;
margin-bottom: 13px;
}
.roomType {
width: 654px;
.elip(@clamp:3);
font-size: 24px;
color: #808080;
margin-bottom: 36px;
}
.price {
> div {
font-size: 36px;
font-weight: bold;
color: #222;
margin-bottom: 22px;
}
> p {
font-size: 44px;
font-weight: bold;
color: #c70850;
}
}
.qrcodeContainer {
.size(@w: 192px , @h: 192px);
.flex(@display: flex, @justifyCenter: center, @alignCenter: center, @direction: column);
margin-top: 35px;
div:first-child {
.size(@w: 192px, @h: 192px);
box-shadow: 0px 3px 6px 0 rgba(2, 3, 3, 0.1);
border-radius: 6px;
border: solid 1px #dadada;
background-image: linear-gradient(to top, #f5f5f5, #fff);
margin: 10px 0 0 6px;
padding: 16px 16px 16px 16px;
}
.tooltip {
.tooltipBody {
position: relative;
width: 340px;
height: 80px;
padding: 15px 26px 16px 26px;
text-align: center;
background: @COLOR_GRAY07;
border-radius: 10px;
line-height: 1.27;
color: @COLOR_WHITE;
font-size: 22px;
&::before {
content: "";
position: absolute;
z-index: 1;
top: -28px;
left: calc(50% - 15px);
border: 15px solid #222222;
border-top-color: transparent;
border-right-color: transparent;
border-left-color: transparent;
}
}
}
}
}
.tbutton {
.size(@w: 846px , @h:78px);
margin-top: 103px;
}
}

View File

@@ -1,5 +1,5 @@
@import "../../../../style/CommonStyle.module.less";
@import "../../../../style/utils.module.less";
@import "../../../style/CommonStyle.module.less";
@import "../../../style/utils.module.less";
.optionContainer {
.flex(@direction:column ,@justifyCenter:flex-start,@alignCenter:flex-start);

View File

@@ -0,0 +1,32 @@
import React, { useState } from 'react';
import { useSelector } from 'react-redux';
import ThemeHotelIndicator from '../components/indicator/ThemeHotelIndicator';
import HotelOption from './HotelOption';
import ThemeOption from './ThemeOption';
import css from './ThemeProduct.module.less';
export default function ThemeProduct({ selectedIndex, setSelectedIndex }) {
const productInfos = useSelector(
(state) => state.home.themeCurationDetailInfoData
);
return (
<div className={css.container}>
<ThemeHotelIndicator
selectedIndex={selectedIndex}
setSelectedIndex={setSelectedIndex}
/>
{productInfos.themeInfo?.length > 0 ? (
<ThemeOption />
) : (
<HotelOption
selectedIndex={selectedIndex}
setSelectedIndex={setSelectedIndex}
/>
)}
</div>
);
}

View File

@@ -1,14 +1,14 @@
import React, { useCallback } from "react";
import React, { useCallback } from 'react';
import classNames from "classnames";
import { useSelector } from "react-redux";
import classNames from 'classnames';
import { useSelector } from 'react-redux';
import TButton from "../../../../components/TButton/TButton";
import TQRCode from "../../../../components/TQRCode/TQRCode";
import usePriceInfo from "../../../../hooks/usePriceInfo";
import { $L } from "../../../../utils/helperMethods";
import FavoriteBtn from "../common/FavoriteBtn";
import css from "./UnableOption.module.less";
import TButton from '../../../components/TButton/TButton';
import TQRCode from '../../../components/TQRCode/TQRCode';
import usePriceInfo from '../../../hooks/usePriceInfo';
import { $L } from '../../../utils/helperMethods';
import FavoriteBtn from '../components/common/FavoriteBtn';
import css from './UnableOption.module.less';
export default function OptionPartnerPrice({
selectedPatnrId,

View File

@@ -1,5 +1,5 @@
@import "../../../../style/CommonStyle.module.less";
@import "../../../../style/utils.module.less";
@import "../../../style/CommonStyle.module.less";
@import "../../../style/utils.module.less";
.priceContainer {
height: 536px;

View File

@@ -1,9 +1,9 @@
import React from "react";
import React from 'react';
import UnableOption from "../components/optionTypes/UnableOption";
import ProductOption from "../components/ProductOption";
import ProductThumbnail from "../components/ProductThumbnail";
import css from "./UnableProduct.module.less";
import ProductOption from '../components/ProductOption';
import ProductThumbnail from '../components/ProductThumbnail';
import UnableOption from './UnableOption';
import css from './UnableProduct.module.less';
export default function UnableProduct({ selectedPatnrId, selectedPrdtId }) {
return (

View File

@@ -1,17 +1,23 @@
import React, { useCallback, useEffect, useState } from "react";
import React, {
useCallback,
useEffect,
useRef,
useState,
} from 'react';
import classNames from "classnames";
import { useSelector } from "react-redux";
import classNames from 'classnames';
import { useSelector } from 'react-redux';
import Image from "@enact/sandstone/Image";
import Spotlight from "@enact/spotlight";
import SpotlightContainerDecorator from "@enact/spotlight/SpotlightContainerDecorator";
import Spottable from "@enact/spotlight/Spottable";
import Image from '@enact/sandstone/Image';
import Spotlight from '@enact/spotlight';
import SpotlightContainerDecorator
from '@enact/spotlight/SpotlightContainerDecorator';
import Spottable from '@enact/spotlight/Spottable';
import CustomImage from "../../../../components/CustomImage/CustomImage";
import TItemCard from "../../../../components/TItemCard/TItemCard";
import TVirtualGridList from "../../../../components/TVirtualGridList/TVirtualGridList";
import css from "./ThemeHotelIndicator.module.less";
import TVirtualGridList
from '../../../../components/TVirtualGridList/TVirtualGridList';
import useScrollTo from '../../../../hooks/useScrollTo';
import css from './ThemeHotelIndicator.module.less';
const Container = SpotlightContainerDecorator(
{ enterTo: "last-focused", preserveld: true },
@@ -20,17 +26,16 @@ const Container = SpotlightContainerDecorator(
const SpottableComponent = Spottable("div");
const SpottableImage = Spottable(Image);
export default function ThemeHotelIndicator() {
const [selectedIndex, setSelectedIndex] = useState(0);
export default function ThemeHotelIndicator({
selectedIndex,
setSelectedIndex,
}) {
const [selectedImage, setSelectedImage] = useState(null);
const [imageSelectedIndex, setImageSelectedIndex] = useState(0);
const hotelInfos = useSelector(
(state) => state.home.themeCurationHotelDetailData
);
const HotelData = useSelector((state) => state.home.HotelData);
console.log("#hotelInfos", hotelInfos);
console.log("#HotelData", HotelData);
const { cursorVisible } = useSelector((state) => state.common.appStatus);
const imageLength = hotelInfos[selectedIndex]?.hotelDetailInfo.imgUrls.length;
@@ -51,6 +56,19 @@ export default function ThemeHotelIndicator() {
setImageSelectedIndex((prev) => prev + 1);
}
};
const handleUpClick = () => {
if (selectedIndex > 0) {
setSelectedIndex((prev) => prev - 1);
}
};
const handleDownClick = useCallback(() => {
if (hotelInfos.length - 1 !== selectedIndex) {
setSelectedIndex((prev) => prev + 1);
}
}, [selectedIndex]);
const renderItem = useCallback(
({ index, ...rest }) => {
const { hotelImgUrl } = hotelInfos[index];
@@ -70,6 +88,7 @@ export default function ThemeHotelIndicator() {
selectedIndex === index && css.selected
)}
onClick={handleItemClick}
spotlightId={`indicator-image-${index}`}
{...rest}
>
<span
@@ -103,7 +122,7 @@ export default function ThemeHotelIndicator() {
spotlightDisabled={imageSelectedIndex === 0}
/>
<span>
{imageSelectedIndex + 1} /{imageLength}
{imageSelectedIndex + 1} / {imageLength}
</span>
<SpottableComponent
className={classNames(
@@ -122,8 +141,15 @@ export default function ThemeHotelIndicator() {
</div>
</div>
<div>
<SpottableComponent spotlightDisabled className={css.upButton} />
<div className={css.tVirtualGridListContainer}>
<SpottableComponent
onClick={handleUpClick}
spotlightDisabled={!cursorVisible}
className={classNames(
css.upButton,
selectedIndex === 0 && css.disable
)}
/>
<Container className={css.tVirtualGridListContainer}>
{hotelInfos && hotelInfos.length > 0 && (
<TVirtualGridList
className={css.tVirtualGridList}
@@ -134,8 +160,15 @@ export default function ThemeHotelIndicator() {
renderItem={renderItem}
/>
)}
</div>
<SpottableComponent spotlightDisabled className={css.downButton} />
</Container>
<SpottableComponent
onClick={handleDownClick}
spotlightDisabled={!cursorVisible}
className={classNames(
css.downButton,
hotelInfos.length - 1 === selectedIndex && css.disable
)}
/>
</div>
</div>
</Container>

View File

@@ -60,12 +60,13 @@
}
&.disable {
opacity: 0.1;
background-image: url("../../../../../assets/images/btn/btn-next-thumb-nor.svg");
}
}
> span {
-webkit-text-stroke: 1px #222222;
color: rgba(255, 255, 255, 0.7);
font-family: LGSmartUI;
// .size(@w: 51px , @h: 21px);
-webkit-text-stroke: 1px rgba(255, 255, 255, 0.7);
color: #222222;
font-size: 24px;
font-weight: bold;
line-height: 1.33;
@@ -111,6 +112,10 @@
&:focus {
background-image: url("../../../../../assets/images/btn/btn-bk-up-foc.svg");
}
&.disable {
opacity: 0.1;
background-image: url("../../../../../assets/images/btn/btn-bk-up-nor.svg");
}
}
.downButton {
@@ -124,6 +129,10 @@
&:focus {
background-image: url("../../../../../assets/images/btn/btn-bk-down-foc.svg");
}
&.disable {
opacity: 0.1;
background-image: url("../../../../../assets/images/btn/btn-bk-down-nor.svg");
}
}
.image {

View File

@@ -1,26 +0,0 @@
import React, { useEffect, useState } from "react";
import { useSelector } from "react-redux";
import logo from "../../../../../assets/images/icons/ic-partners-netflix@3x.png";
import css from "./HotelOption.module.less";
export default function HotelOption({ children }) {
const hotelData = useSelector(
(state) => state.home.themeCurationHotelDetailData
);
return (
<div className={css.optionContainer}>
<div className={css.contentHeader}>
<div className={css.topLayer}>
<img src={logo} alt="patncLogoPath" />
<div>IIDIDIDIDID</div>
</div>
<div className={css.title}>HOTEL_NAME_TITLE</div>
</div>
{children}
</div>
);
}

View File

@@ -1,46 +0,0 @@
@import "../../../../style/CommonStyle.module.less";
@import "../../../../style/utils.module.less";
.optionContainer {
.flex(@direction:column ,@justifyCenter:flex-start,@alignCenter:flex-start);
.size(@w: 1026px, @h: 930px);
background-color: @BG_COLOR_01;
padding: 30px 120px 120px 60px;
.topLayer {
width: 100%;
.flex(@direction:row ,@justifyCenter:flex-start);
text-align: left;
color: @COLOR_GRAY03;
font-weight: bold;
font-size: 30px;
img {
width: 42px;
height: 42px;
margin-right: 11px;
}
}
.bottomLayer {
width: 846px;
.flex(@justifyCenter:space-between,@alignCenter:center);
height: 42px;
margin-top: 14px;
> div {
height: 36px;
}
}
.title {
font-weight: bold;
font-size: 36px;
color: @COLOR_GRAY08;
width: 739px;
.elip(@clamp:2);
margin-top: 24px;
font-stretch: normal;
font-style: normal;
line-height: 1.17;
letter-spacing: normal;
text-align: left;
}
}

View File

@@ -1,25 +0,0 @@
import React from "react";
import { useSelector } from "react-redux";
import ThemeHotelIndicator from "../components/indicator/ThemeHotelIndicator";
import HotelOption from "../components/optionTypes/HotelOption";
import ThemeOption from "../components/optionTypes/ThemeOption";
import css from "./ThemeProduct.module.less";
export default function ThemeProduct() {
const productInfos = useSelector(
(state) => state.home.themeCurationDetailInfoData
);
const hotelInfos = useSelector(
(state) => state.home.themeCurationHotelDetailData
);
return (
<div className={css.container}>
<ThemeHotelIndicator hotelInfos={hotelInfos} />
{productInfos.themeInfo?.length > 0 ? <ThemeOption /> : <HotelOption />}
</div>
);
}