From 645827ce54128e4d3a5f3946648e23f5ebd714a1 Mon Sep 17 00:00:00 2001 From: "younghoon100.park" Date: Tue, 30 Jan 2024 18:01:22 +0900 Subject: [PATCH] =?UTF-8?q?[FeaturedBrandsPanel]=20=20LiveVideoCard=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80=20=EB=B0=8F=20=EB=B0=98=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Detail Notes : 1. LiveVideoCard.jsx 추가 및 반영 --- .../FeaturedBrandsPanel.jsx | 24 ++- .../LiveChannels/LiveChannels.jsx | 141 ++++++++++-------- .../LiveChannels/LiveChannels.module.less | 17 --- .../LiveVideoCard/LiveVideoCard.jsx | 79 ++++++++++ .../LiveVideoCard/LiveVideoCard.module.less | 77 ++++++++++ .../LiveVideoCard/package.json | 6 + 6 files changed, 260 insertions(+), 84 deletions(-) create mode 100644 com.twin.app.shoptime/src/views/FeaturedBrandsPanel/LiveVideoCard/LiveVideoCard.jsx create mode 100644 com.twin.app.shoptime/src/views/FeaturedBrandsPanel/LiveVideoCard/LiveVideoCard.module.less create mode 100644 com.twin.app.shoptime/src/views/FeaturedBrandsPanel/LiveVideoCard/package.json diff --git a/com.twin.app.shoptime/src/views/FeaturedBrandsPanel/FeaturedBrandsPanel.jsx b/com.twin.app.shoptime/src/views/FeaturedBrandsPanel/FeaturedBrandsPanel.jsx index a9dc523c..072a9725 100644 --- a/com.twin.app.shoptime/src/views/FeaturedBrandsPanel/FeaturedBrandsPanel.jsx +++ b/com.twin.app.shoptime/src/views/FeaturedBrandsPanel/FeaturedBrandsPanel.jsx @@ -2,9 +2,11 @@ import React, { useEffect, useState } from "react"; import { useDispatch, useSelector } from "react-redux"; -import SectionTitle from "../../components/SectionTitle/SectionTitle"; import TPanel from "../../components/TPanel/TPanel"; -import { getBrandLayoutInfo, getBrandLiveChannelInfo } from "../../features/brand/brandsSlice"; +import { + getBrandLayoutInfo, + getBrandLiveChannelInfo, +} from "../../features/brand/brandsSlice"; import Banner from "./Banner/Banner"; import css from "./FeaturedBrandsPanel.module.less"; import LiveChannels from "./LiveChannels/LiveChannels"; @@ -19,9 +21,13 @@ export default function FeaturedBrandsPanel() { const brandInfo = useSelector((state) => state.brand.brandInfoData.brandInfo); - const brandTopImgInfo = useSelector((state) => state.brand.brandLayoutInfoData.brandTopImgInfo); + const brandTopImgInfo = useSelector( + (state) => state.brand.brandLayoutInfoData.brandTopImgInfo + ); - const brandChanInfo = useSelector((state) => state.brand.brandLiveChannelInfoData.brandChanInfo); + const brandChanInfo = useSelector( + (state) => state.brand.brandLiveChannelInfoData.brandChanInfo + ); const brandChannelCnt = useSelector( (state) => state.brand.brandLiveChannelInfoData.brandChannelCnt ); @@ -56,12 +62,18 @@ export default function FeaturedBrandsPanel() { )} {selectedBrandInfo && ( - + )}
{brandChanInfo && ( - + )}
diff --git a/com.twin.app.shoptime/src/views/FeaturedBrandsPanel/LiveChannels/LiveChannels.jsx b/com.twin.app.shoptime/src/views/FeaturedBrandsPanel/LiveChannels/LiveChannels.jsx index b1d07981..cfaf97fc 100644 --- a/com.twin.app.shoptime/src/views/FeaturedBrandsPanel/LiveChannels/LiveChannels.jsx +++ b/com.twin.app.shoptime/src/views/FeaturedBrandsPanel/LiveChannels/LiveChannels.jsx @@ -1,16 +1,13 @@ import Scroller from "@enact/sandstone/Scroller"; -import SpotlightContainerDecorator from "@enact/spotlight/SpotlightContainerDecorator"; -import Spottable from "@enact/spotlight/Spottable"; import SectionTitle from "../../../components/SectionTitle/SectionTitle"; import TItemCard from "../../../components/TItemCard/TItemCard"; import { $L } from "../../../utils/helperMethods"; +import LiveVideoCard from "../LiveVideoCard/LiveVideoCard"; import css from "./LiveChannels.module.less"; const LIVE_CHANNELS_STRING = "LIVE CHANNELS"; -const SpottableComponent = Spottable("div"); - export default function LiveChannels({ brandChanInfo, brandChannelCnt }) { const { alamDispFlag, @@ -60,65 +57,87 @@ export default function LiveChannels({ brandChanInfo, brandChannelCnt }) { // } return ( -
- + <> + {brandChannelCnt > 0 && ( +
+ - {brandChannelCnt === 1 && ( -
- Live 영상 - -
    - {brandProductInfo && - brandProductInfo.map( - ({ prdtId, prdtImgUrl, prdtNm, priceInfo, soldoutFlag }) => { - return ( - - ); - } - )} -
-
+ {brandChannelCnt === 1 && ( +
+ + +
    + {brandProductInfo && + brandProductInfo.map( + ({ + prdtId, + prdtImgUrl, + prdtNm, + priceInfo, + soldoutFlag, + }) => { + return ( + + ); + } + )} +
+
+
+ )} + + {brandChannelCnt > 1 && ( +
+ {"brandChannelCnt(영상의 수)가 1보다 클 경우, type = vertical"} +
    + {brandProductInfo && + brandProductInfo.map( + ({ + prdtId, + prdtImgUrl, + prdtNm, + priceInfo, + soldoutFlag, + }) => { + return ( + + ); + } + )} +
+
+ )}
)} - - {brandChannelCnt > 1 && ( -
- {"brandChannelCnt(영상의 수)가 1보다 클 경우, type = vertical"} -
    - {brandProductInfo && - brandProductInfo.map( - ({ prdtId, prdtImgUrl, prdtNm, priceInfo, soldoutFlag }) => { - return ( - - ); - } - )} -
-
- )} -
+ ); } diff --git a/com.twin.app.shoptime/src/views/FeaturedBrandsPanel/LiveChannels/LiveChannels.module.less b/com.twin.app.shoptime/src/views/FeaturedBrandsPanel/LiveChannels/LiveChannels.module.less index 68817cfd..5a033925 100644 --- a/com.twin.app.shoptime/src/views/FeaturedBrandsPanel/LiveChannels/LiveChannels.module.less +++ b/com.twin.app.shoptime/src/views/FeaturedBrandsPanel/LiveChannels/LiveChannels.module.less @@ -12,23 +12,6 @@ display: flex; width: @globalWidth; - // live container - > div:nth-child(1) { - .size(@w: 1002px, @h: 564px); - margin-right: 18px; - background-color: gainsboro; - border: solid 1px transparent; - border-radius: 12px; - - /* focused */ - &:focus-within { - // live container - border: solid 1px @PRIMARY_COLOR_RED; - box-shadow: inset 0 0 0 4px @PRIMARY_COLOR_RED, - 0 0 50px 0 rgba(0, 0, 0, 0.5); - } - } - // product scroll container > .scroller { width: 720px; diff --git a/com.twin.app.shoptime/src/views/FeaturedBrandsPanel/LiveVideoCard/LiveVideoCard.jsx b/com.twin.app.shoptime/src/views/FeaturedBrandsPanel/LiveVideoCard/LiveVideoCard.jsx new file mode 100644 index 00000000..f820cbec --- /dev/null +++ b/com.twin.app.shoptime/src/views/FeaturedBrandsPanel/LiveVideoCard/LiveVideoCard.jsx @@ -0,0 +1,79 @@ +import { memo, useCallback, useState } from "react"; + +import Spottable from "@enact/spotlight/Spottable"; + +import IcWarning from "../../../../assets/icon/ic-warning.svg"; +import IcLiveShow from "../../../../assets/icon/tag/tag-liveshow.svg"; +import VideoOverlayWithPhoneNumber from "../../../components/VideoOverlayWithPhoneNumber/VideoOverlayWithPhoneNumber"; +import { $L } from "../../../utils/helperMethods"; +import css from "./LiveVideoCard.module.less"; + +const SpottableComponent = Spottable("div"); + +const LIVE_SHOW_STRING = "Live Show"; +const WARNING_STRING = "Warning"; +const WARNING_MESSAGE = + "This program was previously recorded. Offers, pricing, and availability may have changed."; + +export default memo(function LiveVideoCard({ + endTime, + liveChannelCount, + onVideoCardBlur, + onVideoCardClick, + onVideoCardFocus, + startTime, + thumbnailSource, + title, + ...rest +}) { + const [isFocused, setIsFocused] = useState(false); + + const handleBlur = useCallback(() => { + setIsFocused(false); + onVideoCardBlur && onVideoCardBlur(); + }, [onVideoCardBlur]); + + const handleClick = useCallback(() => { + onVideoCardClick && onVideoCardClick(); + }, [onVideoCardClick]); + + const handleFocus = useCallback(() => { + setIsFocused(true); + onVideoCardFocus && onVideoCardFocus(); + }, [onVideoCardFocus]); + + return ( + + {title} + +
+
+ {LIVE_SHOW_STRING} +
+

{title}

+ +
+
+ {liveChannelCount && liveChannelCount === 1 && ( +
+ {WARNING_STRING} + {$L(WARNING_MESSAGE)} +
+ )} +
+ + +
+ ); +}); diff --git a/com.twin.app.shoptime/src/views/FeaturedBrandsPanel/LiveVideoCard/LiveVideoCard.module.less b/com.twin.app.shoptime/src/views/FeaturedBrandsPanel/LiveVideoCard/LiveVideoCard.module.less new file mode 100644 index 00000000..30cefa5a --- /dev/null +++ b/com.twin.app.shoptime/src/views/FeaturedBrandsPanel/LiveVideoCard/LiveVideoCard.module.less @@ -0,0 +1,77 @@ +@import "../../../style/CommonStyle.module.less"; +@import "../../../style/utils.module.less"; + +.container { + /* normal */ + position: relative; + z-index: 10; + .size(@w: 1002px, @h: 564px); + margin-right: 18px; + border: 4px solid transparent; + border-radius: 12px; + overflow: hidden; + + // image(thumbnail) area + > img { + width: 100%; + } + + // contents area + > div:nth-child(2) { + .position(@position: absolute, @top: 0, @right: 0, @left: 0); + .flex(@direction: column, @justifyCenter: space-between, @alignCenter: flex-start); + .size(@w: 100%, @h: 100%); + background-image: linear-gradient(to top, transparent 55%, @COLOR_BLACK); + + // top part of video + > div:nth-child(1) { + .flex(@justifyCenter: flex-start); + gap: 12px; + width: 100%; + padding: 18px; + color: @COLOR_WHITE; + + img { + .size(@w: 108px, @h: 48px); + } + + div { + h3 { + .font(@fontFamily: @baseFontBold, @fontSize: 30px); + .elip(@clamp:1); + word-break: break-all; + } + + time { + .font(@fontFamily: @baseFont, @fontSize: 24px); + } + } + } + + // bottom part of video + > div:nth-child(2) { + .flex(@justifyCenter: flex-start); + gap: 12px; + padding: 6px 18px 18px; + .size(@w: 100%, @h: 54px); + background-color: rgba(0, 0, 0, 0.9); + .font(@fontFamily: @baseFont, @fontSize: 20px); + color: @COLOR_GRAY04; + + img { + .size(@w: 18px, @h: 18px); + } + } + } + + /* focused */ + &:focus-within { + border: 4px solid @PRIMARY_COLOR_RED; + .focusDropShadow(); + } +} + +.callToOrder { + bottom: 64px; + left: 18px; +} diff --git a/com.twin.app.shoptime/src/views/FeaturedBrandsPanel/LiveVideoCard/package.json b/com.twin.app.shoptime/src/views/FeaturedBrandsPanel/LiveVideoCard/package.json new file mode 100644 index 00000000..815bce99 --- /dev/null +++ b/com.twin.app.shoptime/src/views/FeaturedBrandsPanel/LiveVideoCard/package.json @@ -0,0 +1,6 @@ +{ + "main": "LiveVideoCard.jsx", + "styles": [ + "LiveVideoCard.module.less" + ] +}