import React, { useCallback, useEffect, useMemo, useRef, useState, } from "react"; import classNames from "classnames"; import { useDispatch, useSelector } from "react-redux"; import { panel_names } from "../../utils/Config"; import TabItem from "./TabItem"; import css from "./TabLayout.module.less"; //enact import Skinnable from "@enact/sandstone/Skinnable"; import Spotlight from "@enact/spotlight"; import SpotlightContainerDecorator from "@enact/spotlight/SpotlightContainerDecorator"; import { Cancelable } from "@enact/ui/Cancelable"; //아이콘 import { Job } from "@enact/core/util"; //이미지 import shoptimeFullIcon from "../../../assets/icons/ic-lnb-logo-shoptime@3x.png"; import shopTimeIcon from "../../../assets/icons/ic-lnb-shoptime-symbol@3x.png"; import CartIcon from "./iconComponents/CartIcon"; import CategoryIcon from "./iconComponents/CategoryIcon"; import FeaturedBrandIcon from "./iconComponents/FeaturedBrandIcon"; import HomeIcon from "./iconComponents/HomeIcon"; import HotPicksIcon from "./iconComponents/HotPicksIcon"; import MyPageIcon from "./iconComponents/MyPageIcon"; import OnSaleIcon from "./iconComponents/OnSaleIcon"; import SearchIcon from "./iconComponents/SearchIcon"; import TrendingNowIcon from "./iconComponents/TrendingNowIcon"; //이미지 import { resetPanels } from "../../features/panels/panelsSlice"; const Container = SpotlightContainerDecorator( { enterTo: "default-element" }, "div" ); const MainContainer = SpotlightContainerDecorator( { enterTo: "last-focused", continue5WayHold: true }, "div" ); const CancelableDiv = Cancelable( { modal: true, onCancel: "handleCancel" }, Skinnable(Container) ); class TabMenuItem { constructor(icons = "", title = "", target, children = []) { this.icons = icons; this.title = title; this.target = target; this.children = []; //TabMenuItem if (children && children.length > 0) { for (let i = 0; i < children.length; i++) { const tabmenu = new TabMenuItem( children[i].icons, children[i].title, children[i].target, children[i].children ); this.children.push(tabmenu); } } } hasChildren = () => { return this.children.length > 0; }; getChildren = () => { return this.children; }; } const deActivateTabJabFunc = (func) => { func(); }; let deActivateTabJob = new Job(deActivateTabJabFunc, 2000); const COLLABSED_MAIN = 0; const ACTIVATED_MAIN = 1; const ACTIVATED_SUB = 2; const EXTRA_AREA = 3; const MAIN_TITLE = 0; const SUB_TITLE = 1; const PANELS_HAS_TAB = [ panel_names.CART_PANEL, panel_names.CATEGORY_PANEL, panel_names.FEATURED_BRANDS_PANEL, panel_names.HOME_PANEL, panel_names.HOT_PICKS_PANEL, panel_names.MY_PAGE_PANEL, panel_names.ON_SALE_PANEL, panel_names.SEARCH_PANEL, panel_names.TRENDING_NOW_PANEL, ]; export default function TabLayout({ topPanelName, onTabActivated }) { const dispatch = useDispatch(); const [mainExpanded, setMainExpanded] = useState(false); const [mainSelectedIndex, setMainSelectedIndex] = useState(-1); const [tabs, setTabs] = useState([]); const [tabFocused, setTabFocused] = useState([false, false, false]); //COLLABSED_MAIN, ACTIVATED_MAIN, ACTIVATED_SUB const panelSwitching = useRef(null); const { cursorVisible } = useSelector((state) => state.common.appStatus); const data = useSelector((state) => state.home.menuData?.data); const menuItems = useMemo( () => [ { icons: CategoryIcon, title: "", children: [ { title: "", target: [{ name: panel_names.CATEGORY_PANEL }], }, ], }, { icons: MyPageIcon, title: "", children: [ { title: "", target: [{ name: panel_names.MY_PAGE_PANEL }], }, ], }, { icons: SearchIcon, title: "", children: [ { title: "12323232", target: [{ name: panel_names.SEARCH_PANEL }], }, ], }, { icons: HomeIcon, title: "", children: [ { title: "43534543", target: [{ name: panel_names.HOME_PANEL }], }, ], }, { icons: FeaturedBrandIcon, title: "", children: [ { title: "dsadasd", target: [{ name: panel_names.FEATURED_BRANDS_PANEL }], }, ], }, { icons: OnSaleIcon, title: "", children: [ { title: "", target: [{ name: panel_names.ON_SALE_PANEL }], }, ], }, { icons: TrendingNowIcon, title: "", children: [ { title: "", target: [{ name: panel_names.TRENDING_NOW_PANEL }], }, ], }, { icons: HotPicksIcon, title: "", children: [ { title: "", target: [{ name: panel_names.HOT_PICKS_PANEL }], }, ], }, { icons: CartIcon, title: "", children: [ { title: "", target: [{ name: panel_names.CART_PANEL }], }, ], }, //메뉴 추가 필요 20240112 chw ], [data] ); const getMenuData = (type) => { let result = []; switch (type) { case "gnb": data?.gnb.map((item) => { result.push(item.menuNm); }); console.log("#result", result); return result; case "homeCategory": return "123123"; case "msgInfos": return result; case "mypage": return result; case "shortCategory": return result; case "shortFeaturedBrands": return result; } }; const dataDivide = () => { if (data) { // console.log("data", data); // Object.keys(data).map((key) => { // title = getMenuData(key); // return title; // }); const title = getMenuData("gnb"); // const subTitle = getMenuData(menu); for (let i = 0; i < menuItems.length; i++) { menuItems[i].title = title[i]; menuItems[i].children.title = title[i]; } } console.log("#menuItems", menuItems); return menuItems; }; const makeTabmenu = useCallback(() => { const t = []; for (let i = 0; i < menuItems.length; i++) { const tabmenu = new TabMenuItem( menuItems[i].icons, menuItems[i].title, menuItems[i].target, menuItems[i].children ); t.push(tabmenu); } return t; }, [data]); useEffect(() => { dataDivide(); setTabs(makeTabmenu()); }, [data]); const deActivateTab = useCallback(() => { setTabFocused([false, false, false, false]); setMainSelectedIndex(-1); setMainExpanded(false); }, []); const onTabHasFocus = useCallback( (type) => (event) => { switch (type) { case COLLABSED_MAIN: case ACTIVATED_MAIN: { if (!cursorVisible) { const parent = event.target.parentNode; const children = parent.childNodes; const index = Array.prototype.indexOf.call(children, event.target); setMainExpanded(true); setMainSelectedIndex(index); } else { if (!panelSwitching.current) { setMainExpanded(true); } } break; } case ACTIVATED_SUB: { setMainExpanded(false); break; } case EXTRA_AREA: { if (cursorVisible) { deActivateTabJob.start(deActivateTab); return; } } } setTabFocused((prevState) => { const prev = [...prevState]; prev[type] = true; return prev; }); }, [cursorVisible, deActivateTab] ); const onTabBlur = useCallback( (type) => (event) => { switch (type) { case ACTIVATED_MAIN: { if (!cursorVisible) { setMainExpanded(false); } break; } case ACTIVATED_SUB: { if (!cursorVisible) { } break; } case EXTRA_AREA: { if (cursorVisible) { deActivateTabJob.stop(); return; } } } setTabFocused((prevState) => { const prev = [...prevState]; prev[type] = true; return prev; }); }, [cursorVisible] ); const handleNavigation = useCallback( ({ index, target }) => { setMainSelectedIndex(index); if (target) { dispatch(resetPanels(target)); deActivateTab(); // panelSwitching.current = true; // panelSwitchingJob.start(panelSwitching); } else if (cursorVisible) { setMainExpanded(true); } }, [deActivateTab, dispatch] ); const onClickSubItem = useCallback( ({ index, target }) => { if (target) { dispatch(resetPanels(target)); deActivateTab(); panelSwitching.current = true; // panelSwitchingJob.start(panelSwitching); } }, [dispatch, deActivateTab] ); const onClickExtraArea = useCallback( ({ index, target }) => { deActivateTabJob.startAfter(100, deActivateTab); }, [dispatch, deActivateTab] ); const tabActivated = useMemo(() => { return mainExpanded || mainSelectedIndex >= 0; }, [mainExpanded, mainSelectedIndex]); const showTab = useMemo(() => { if (!topPanelName || PANELS_HAS_TAB.indexOf(topPanelName) >= 0) { return true; } return false; }, [topPanelName]); const showSubTab = useMemo(() => { if ( tabActivated && tabs[mainSelectedIndex] && tabs[mainSelectedIndex].hasChildren() ) { return true; } return false; }, [tabActivated, tabs, mainSelectedIndex]); const backKeyHandler = useCallback( (ev) => { if (tabActivated) { deActivateTab(); ev.stopPropagation(); ev.preventDefault(); return true; } }, [tabActivated, deActivateTab] ); useEffect(() => { if (tabActivated) { setTimeout(() => { Spotlight.focus("activatedMain"); }, 0); } if (onTabActivated) { onTabActivated(tabActivated && showTab); } }, [tabActivated, showTab]); useEffect(() => {}, [showSubTab, mainSelectedIndex]); if (!showTab) { return null; } return (