diff --git a/com.twin.app.shoptime/src/views/FeaturedBrandsPanel/ShopByShow/ShopByShow.figma.jsx b/com.twin.app.shoptime/src/views/FeaturedBrandsPanel/ShopByShow/ShopByShow.figma.jsx new file mode 100644 index 00000000..a9d22878 --- /dev/null +++ b/com.twin.app.shoptime/src/views/FeaturedBrandsPanel/ShopByShow/ShopByShow.figma.jsx @@ -0,0 +1,79 @@ +
+
+
+
Chef Gadget's
+
+
+
+ Chef Gadget's featured product +
+
+
+ Bravo's Top Chef product +
+
+
+
Bravo's Top Chef
+
+
+
$32.98
+
$150.00
+
+
+
+ Top Chef Knife Tote Bag +
+
Top Chef Knife Tote Bag
+
+
+
$32.98
+
$150.00
+
+
+
+
+ Salt, Maldon Traditional product on sale 17% +
+
17%
+
+
+
+
Salt, Maldon Traditional
+
+
+
$32.98
+
$150.00
+
+
+
+ Fish Grill Pan +
+
Fish Grill Pan
+
+
+
$32.98
+
$150.00
+
+
+
+ Product +
+
Productl Nameytg Product
 Name Producthlyg()...
+
+
+
$32.98
+
$150.00
+
+
+
+ Product +
+
Productl Nameytg Product
 Name Producthlyg()...
+
+
+
$32.98
+
$150.00
+
+
+
+
\ No newline at end of file diff --git a/com.twin.app.shoptime/src/views/FeaturedBrandsPanel/ShopByShow/ShopByShowList/ShopByShowContents/ShopByShowContents.module.less b/com.twin.app.shoptime/src/views/FeaturedBrandsPanel/ShopByShow/ShopByShowList/ShopByShowContents/ShopByShowContents.module.less index e0fbf7b0..11ef6a5c 100644 --- a/com.twin.app.shoptime/src/views/FeaturedBrandsPanel/ShopByShow/ShopByShowList/ShopByShowContents/ShopByShowContents.module.less +++ b/com.twin.app.shoptime/src/views/FeaturedBrandsPanel/ShopByShow/ShopByShowList/ShopByShowContents/ShopByShowContents.module.less @@ -3,7 +3,6 @@ .container { padding-left: 60px; - margin-bottom: 12px; > h3 { position: relative; @@ -18,10 +17,6 @@ } } -.container:last-child { - margin-bottom: 0; -} - .tVirtualGridList { padding-right: 18px; .size(@h: 438px); diff --git a/com.twin.app.shoptime/src/views/FeaturedBrandsPanel/ShopByShow/ShopByShowList/ShopByShowList.jsx b/com.twin.app.shoptime/src/views/FeaturedBrandsPanel/ShopByShow/ShopByShowList/ShopByShowList.jsx index 13c1deff..f1cc3bfa 100644 --- a/com.twin.app.shoptime/src/views/FeaturedBrandsPanel/ShopByShow/ShopByShowList/ShopByShowList.jsx +++ b/com.twin.app.shoptime/src/views/FeaturedBrandsPanel/ShopByShow/ShopByShowList/ShopByShowList.jsx @@ -22,7 +22,7 @@ import { getBrandShopByShow } from '../../../../actions/brandActions'; import useScrollTo from '../../../../hooks/useScrollTo'; import css from './ShopByShowList.module.less'; import ShopByShowNav from './ShopByShowNav/ShopByShowNav'; -import ShopByShowContents from './ShopByShowContents/ShopByShowContents'; +import ShopByShowSection from './ShopByShowSection/ShopByShowSection'; const Container = SpotlightContainerDecorator( { leaveFor: { right: "" }, enterTo: "last-focused" }, @@ -42,14 +42,9 @@ export default function ShopByShowList({ const dispatch = useDispatch(); const panelInfo = useSelector((state) => state.panels.panels[0]?.panelInfo); const scrollLeftJob = useRef(new Job((func) => func(), 0)); - const [selectedClctId, setSelectedClctId] = useState(null); const brandShopByShowClctInfos = brandShopByShowContsInfo?.brandShopByShowClctInfos || []; - const filteredCollections = selectedClctId - ? brandShopByShowClctInfos.filter(({ clctId }) => clctId === selectedClctId) - : brandShopByShowClctInfos; - useEffect(() => { if (panelInfo?.section !== "shop-by-show" || !panelInfo?.x) { return; @@ -78,7 +73,7 @@ export default function ShopByShowList({ scrollLeft(); }, [scrollLeft, selectedPatnrId]); - const handleTabClick = useCallback((contsId) => { + const handleContsIdChange = useCallback((contsId) => { dispatch(getBrandShopByShow({ patnrId: selectedPatnrId, contsId })); }, [selectedPatnrId, dispatch]); @@ -94,30 +89,16 @@ export default function ShopByShowList({ id={"shop-by-show-list-id"} spotlightId={"shop-by-show-list-id"} > -
- {brandShopByShowContsList && brandShopByShowContsList.map((item) => ( - - ))} -
- - {filteredCollections.map((collection, collIdx) => ( - ( + ))} diff --git a/com.twin.app.shoptime/src/views/FeaturedBrandsPanel/ShopByShow/ShopByShowList/ShopByShowList.module.less b/com.twin.app.shoptime/src/views/FeaturedBrandsPanel/ShopByShow/ShopByShowList/ShopByShowList.module.less index f59b43ed..967308aa 100644 --- a/com.twin.app.shoptime/src/views/FeaturedBrandsPanel/ShopByShow/ShopByShowList/ShopByShowList.module.less +++ b/com.twin.app.shoptime/src/views/FeaturedBrandsPanel/ShopByShow/ShopByShowList/ShopByShowList.module.less @@ -6,54 +6,8 @@ flex-direction: column; position: relative; width: 100%; -} -.tabsContainer { - display: flex; - gap: 12px; - padding: 0 60px 24px 60px; - overflow-x: auto; - overflow-y: hidden; - margin-bottom: 12px; - - &::-webkit-scrollbar { - height: 4px; - } - - &::-webkit-scrollbar-track { - background: transparent; - } - - &::-webkit-scrollbar-thumb { - background: #ccc; - border-radius: 2px; - } -} - -.tabButton { - flex-shrink: 0; - padding: 8px 16px; - background-color: transparent; - border: 1px solid #ccc; - border-radius: 4px; - color: #666; - cursor: pointer; - font-size: 14px; - transition: all 0.3s ease; - - &:hover { - border-color: #000; - color: #000; - } - - &.active { - background-color: #000; - border-color: #000; - color: #fff; - } - - &:focus { - outline: none; - box-shadow: 0 0 0 2px rgba(0, 0, 0, 0.2); + > nav { + margin-bottom: 30px; } } diff --git a/com.twin.app.shoptime/src/views/FeaturedBrandsPanel/ShopByShow/ShopByShowList/ShopByShowNav/ShopByShowNav.jsx b/com.twin.app.shoptime/src/views/FeaturedBrandsPanel/ShopByShow/ShopByShowList/ShopByShowNav/ShopByShowNav.jsx index 22bef593..db3f2598 100644 --- a/com.twin.app.shoptime/src/views/FeaturedBrandsPanel/ShopByShow/ShopByShowList/ShopByShowNav/ShopByShowNav.jsx +++ b/com.twin.app.shoptime/src/views/FeaturedBrandsPanel/ShopByShow/ShopByShowList/ShopByShowNav/ShopByShowNav.jsx @@ -12,23 +12,20 @@ const Container = SpotlightContainerDecorator( "nav" ); -const STRING_CONF = { - ALL: "ALL", -}; export default memo(function ShopByShowNav({ - brandShopByShowClctInfos, + brandShopByShowContsList, + brandShopByShowContsInfo, handleItemFocus, - selectedClctId, - setSelectedClctId, + onContsIdChange, }) { const { getScrollTo, scrollLeft } = useScrollTo(); const handleClick = useCallback( - (clctId, clctNm) => () => { - setSelectedClctId(clctId); + (contsId) => () => { + onContsIdChange(contsId); }, - [setSelectedClctId] + [onContsIdChange] ); const handleFocus = useCallback(() => { @@ -37,41 +34,26 @@ export default memo(function ShopByShowNav({ } }, [handleItemFocus]); - const selectedText = !selectedClctId ? "Selected " : ""; - const allLabelText = selectedText + "ALL 1 of " + (brandShopByShowClctInfos?.length + 1 || 1); - return (
    -
  • - - ALL - -
  • - {brandShopByShowClctInfos && - brandShopByShowClctInfos.map(({ clctId, clctNm }, index) => ( -
  • + {brandShopByShowContsList && + brandShopByShowContsList.map(({ contsId, contsNm }, index) => ( +
  • - {clctNm} + {contsNm}
  • ))} diff --git a/com.twin.app.shoptime/src/views/FeaturedBrandsPanel/ShopByShow/ShopByShowList/ShopByShowSection/ShopByShowImageCard/ShopByShowImageCard.jsx b/com.twin.app.shoptime/src/views/FeaturedBrandsPanel/ShopByShow/ShopByShowList/ShopByShowSection/ShopByShowImageCard/ShopByShowImageCard.jsx new file mode 100644 index 00000000..91957e61 --- /dev/null +++ b/com.twin.app.shoptime/src/views/FeaturedBrandsPanel/ShopByShow/ShopByShowList/ShopByShowSection/ShopByShowImageCard/ShopByShowImageCard.jsx @@ -0,0 +1,22 @@ +import React, { memo } from "react"; + +import Spottable from "@enact/spotlight/Spottable"; + +import CustomImage from "../../../../../../../components/CustomImage/CustomImage"; +import css from "./ShopByShowImageCard.module.less"; + +const SpottableComponent = Spottable("figure"); + +export default memo(function ShopByShowImageCard({ + imageAlt, + imageSource, + ariaLabel, + ...rest +}) { + delete rest.clctNm; + return ( + + + + ); +}); diff --git a/com.twin.app.shoptime/src/views/FeaturedBrandsPanel/ShopByShow/ShopByShowList/ShopByShowSection/ShopByShowImageCard/ShopByShowImageCard.module.less b/com.twin.app.shoptime/src/views/FeaturedBrandsPanel/ShopByShow/ShopByShowList/ShopByShowSection/ShopByShowImageCard/ShopByShowImageCard.module.less new file mode 100644 index 00000000..5ea26357 --- /dev/null +++ b/com.twin.app.shoptime/src/views/FeaturedBrandsPanel/ShopByShow/ShopByShowList/ShopByShowSection/ShopByShowImageCard/ShopByShowImageCard.module.less @@ -0,0 +1,22 @@ +@import "../../../../../../../style/CommonStyle.module.less"; +@import "../../../../../../../style/utils.module.less"; + +.card { + position: relative; + .size(@w: 665px, @h:438px); + padding: 18px; + background-color: @COLOR_WHITE; + border: solid 1px @COLOR_GRAY02; + border-radius: 12px; + + img { + .size(@w: 629px, @h:402px); + object-fit: cover; + } + + &:focus { + &::after { + .focused(@boxShadow: 22px, @borderRadius: 12px); + } + } +} diff --git a/com.twin.app.shoptime/src/views/FeaturedBrandsPanel/ShopByShow/ShopByShowList/ShopByShowSection/ShopByShowProductList/ShopByShowProductList.jsx b/com.twin.app.shoptime/src/views/FeaturedBrandsPanel/ShopByShow/ShopByShowList/ShopByShowSection/ShopByShowProductList/ShopByShowProductList.jsx new file mode 100644 index 00000000..962eea4a --- /dev/null +++ b/com.twin.app.shoptime/src/views/FeaturedBrandsPanel/ShopByShow/ShopByShowList/ShopByShowSection/ShopByShowProductList/ShopByShowProductList.jsx @@ -0,0 +1,165 @@ +import React, { useCallback, useRef, useEffect } from "react"; + +import { useDispatch, useSelector } from "react-redux"; + +import { Job } from "@enact/core/util"; +import Spotlight from "@enact/spotlight"; + +import { pushPanel, updatePanel } from "../../../../../../../actions/panelActions"; +import TItemCardNew, { removeDotAndColon } from "../../../../../../../components/TItemCard/TItemCard.new"; +import TVirtualGridList from "../../../../../../../components/TVirtualGridList/TVirtualGridList"; +import useScrollTo from "../../../../../../../hooks/useScrollTo"; +import { + LOG_CONTEXT_NAME, + LOG_MESSAGE_ID, + panel_names, +} from "../../../../../../../utils/Config"; +import { getTranslate3dValueByDirection } from "../../../../../../../utils/helperMethods"; +import css from "./ShopByShowProductList.module.less"; + +export default function ShopByShowProductList({ + brandProductInfos, + contentsIndex, + handleFocus, + selectedPatnrId, + spotlightId, + shelfOrder, + shelfTitle, + clctNm, +}) { + const { getScrollTo, scrollLeft } = useScrollTo(); + + const dispatch = useDispatch(); + + const panelInfo = useSelector((state) => state.panels.panels[0]?.panelInfo); + + const scrollLeftJob = useRef(new Job((func) => func(), 0)); + + useEffect(() => { + if ( + panelInfo?.section !== "shop-by-show" || + !panelInfo?.x || + panelInfo?.exprOrd !== contentsIndex + 1 + ) { + return; + } + + const scrollLeftJobValue = scrollLeftJob.current; + const { x } = panelInfo; + + scrollLeftJobValue.start(() => scrollLeft({ x })); + + return () => scrollLeftJobValue.stop(); + }, [panelInfo, scrollLeft, contentsIndex]); + + useEffect(() => { + scrollLeft(); + }, [scrollLeft, selectedPatnrId]); + + const handleClick = useCallback( + (patnrId, prdtId) => (e) => { + const tItemCard = e.currentTarget; + + const lastFocusedTarget = Spotlight.getCurrent(); + const lastFocusedTargetId = lastFocusedTarget?.getAttribute("data-spotlight-id"); + const exprOrd = parseInt( + lastFocusedTarget?.getAttribute("data-exposure-order") + ); + + const xContainer = tItemCard?.parentNode?.parentNode; + + if (exprOrd && lastFocusedTargetId && xContainer) { + const section = "shop-by-show"; + const x = getTranslate3dValueByDirection(xContainer); + + dispatch( + updatePanel({ + name: panel_names.FEATURED_BRANDS_PANEL, + panelInfo: { + exprOrd, + lastFocusedTargetId, + patnrId, + section, + x, + }, + }) + ); + } + + dispatch( + pushPanel({ + name: panel_names.DETAIL_PANEL, + panelInfo: { patnrId, prdtId }, + }) + ); + }, + [dispatch] + ); + + const renderItem = useCallback( + ({ index, ...rest }) => { + if (!brandProductInfos || !brandProductInfos[index]) { + return null; + } + + const product = brandProductInfos[index]; + const { + prdtImgUrl, + prdtOfferId, + patnrId = "21", + prdtNm, + prdtId, + prdtPrice, + patncNm, + brndNm, + lgCatNm, + euEnrgLblInfos, + } = product; + + return ( + + ); + }, + [brandProductInfos, contentsIndex, handleClick, handleFocus] + ); + + return ( +
    + {brandProductInfos && ( + + )} +
    + ); +} diff --git a/com.twin.app.shoptime/src/views/FeaturedBrandsPanel/ShopByShow/ShopByShowList/ShopByShowSection/ShopByShowProductList/ShopByShowProductList.module.less b/com.twin.app.shoptime/src/views/FeaturedBrandsPanel/ShopByShow/ShopByShowList/ShopByShowSection/ShopByShowProductList/ShopByShowProductList.module.less new file mode 100644 index 00000000..04ca71ca --- /dev/null +++ b/com.twin.app.shoptime/src/views/FeaturedBrandsPanel/ShopByShow/ShopByShowList/ShopByShowSection/ShopByShowProductList/ShopByShowProductList.module.less @@ -0,0 +1,30 @@ +@import "../../../../../../../style/utils.module.less"; + +.container { + .flex(); + overflow: hidden; + .size(@w: calc(100% - 665px), @h: 482px); + padding: 0 18px; + + // tVirtualGridListContainer + > div:nth-child(1) { + .size(@w: 100%, @h: inherit); + + > div:nth-child(1) { + padding: 22px 0; + } + + > div:nth-child(3) { + right: -18px; + } + } +} + +.tVirtualGridList { + padding-right: 18px; + .size(@h: 438px); + + > div:nth-child(3) { + right: -18px; + } +} diff --git a/com.twin.app.shoptime/src/views/FeaturedBrandsPanel/ShopByShow/ShopByShowList/ShopByShowSection/ShopByShowSection.jsx b/com.twin.app.shoptime/src/views/FeaturedBrandsPanel/ShopByShow/ShopByShowList/ShopByShowSection/ShopByShowSection.jsx new file mode 100644 index 00000000..713abdf4 --- /dev/null +++ b/com.twin.app.shoptime/src/views/FeaturedBrandsPanel/ShopByShow/ShopByShowList/ShopByShowSection/ShopByShowSection.jsx @@ -0,0 +1,152 @@ +import React, { memo, useCallback } from "react"; + +import Spotlight from "@enact/spotlight"; +import SpotlightContainerDecorator from "@enact/spotlight/SpotlightContainerDecorator"; + +import TItemCardNew, { removeDotAndColon } from "../../../../../components/TItemCard/TItemCard.new"; +import TVirtualGridList from "../../../../../components/TVirtualGridList/TVirtualGridList"; +import useScrollTo from "../../../../../hooks/useScrollTo"; +import { + LOG_CONTEXT_NAME, + LOG_MESSAGE_ID, + panel_names, +} from "../../../../../utils/Config"; +import { getTranslate3dValueByDirection } from "../../../../../utils/helperMethods"; +import { pushPanel, updatePanel } from "../../../../../actions/panelActions"; +import { useDispatch } from "react-redux"; +import css from "./ShopByShowSection.module.less"; + +const Container = SpotlightContainerDecorator( + { leaveFor: { right: "" }, enterTo: null }, + "div" +); + +const ShopByShowSection = memo(({ + clctNm, + brandProductInfos, + contentsIndex, + handleItemFocus, + selectedPatnrId, + spotlightId, + shelfOrder, + shelfTitle, +}) => { + const { getScrollTo } = useScrollTo(); + const dispatch = useDispatch(); + + const handleClick = useCallback( + (patnrId, prdtId) => (e) => { + const tItemCard = e.currentTarget; + const lastFocusedTarget = Spotlight.getCurrent(); + const lastFocusedTargetId = lastFocusedTarget?.getAttribute("data-spotlight-id"); + const xContainer = tItemCard?.parentNode?.parentNode; + + if (lastFocusedTargetId && xContainer) { + const section = "shop-by-show"; + const x = getTranslate3dValueByDirection(xContainer); + + dispatch( + updatePanel({ + name: panel_names.FEATURED_BRANDS_PANEL, + panelInfo: { + lastFocusedTargetId, + patnrId, + section, + x, + }, + }) + ); + } + + dispatch( + pushPanel({ + name: panel_names.DETAIL_PANEL, + panelInfo: { patnrId, prdtId }, + }) + ); + }, + [dispatch] + ); + + const handleFocus = useCallback(() => { + if (handleItemFocus) { + handleItemFocus(); + } + }, [handleItemFocus]); + + const renderItem = useCallback( + ({ index, ...rest }) => { + if (!brandProductInfos || !brandProductInfos[index]) { + return null; + } + + const product = brandProductInfos[index]; + const { + prdtImgUrl, + prdtOfferId, + patnrId = "21", + prdtNm, + prdtId, + prdtPrice, + patncNm, + brndNm, + lgCatNm, + euEnrgLblInfos, + } = product; + + return ( + + ); + }, + [brandProductInfos, handleClick, handleFocus] + ); + + if (!brandProductInfos || brandProductInfos.length === 0) { + return null; + } + + return ( + +

    {clctNm}

    + + +
    + ); +}); + +export default ShopByShowSection; diff --git a/com.twin.app.shoptime/src/views/FeaturedBrandsPanel/ShopByShow/ShopByShowList/ShopByShowSection/ShopByShowSection.module.less b/com.twin.app.shoptime/src/views/FeaturedBrandsPanel/ShopByShow/ShopByShowList/ShopByShowSection/ShopByShowSection.module.less new file mode 100644 index 00000000..7a86b2b0 --- /dev/null +++ b/com.twin.app.shoptime/src/views/FeaturedBrandsPanel/ShopByShow/ShopByShowList/ShopByShowSection/ShopByShowSection.module.less @@ -0,0 +1,38 @@ +@import "../../../../../style/CommonStyle.module.less"; +@import "../../../../../style/utils.module.less"; + +.container { + padding-left: 60px; + margin-bottom: 40px; + + &:last-child { + margin-bottom: 0; + } +} + +.sectionTitle { + position: relative; + .font(@fontFamily: @arialFontBold, @fontSize: 42px); + color: @COLOR_GRAY08; + margin-bottom: 20px; + display: flex; + align-items: center; + gap: 12px; + + &::before { + content: ""; + width: 6px; + height: 36px; + background-color: #C70850; + flex-shrink: 0; + } +} + +.tVirtualGridList { + padding-right: 18px; + .size(@h: 438px); + + > div:nth-child(3) { + right: -18px; + } +}