Paul's Task
Paul has to invite me a beerunknown
tsx
6 months ago
20 kB
6
Indexable
Never
import { useEffect } from "react"; import List from "@mui/material/List"; import ListItem from "@mui/material/ListItem"; import ListItemButton from "@mui/material/ListItemButton"; import ListItemIcon from "@mui/material/ListItemIcon"; import ListItemText from "@mui/material/ListItemText"; import { dividerState, textColorState } from "@/lib/store"; import Link from "next/link"; import MenuPopup from "../menu-popup/MenuPopup"; import { useRecoilValue } from "recoil"; import { useState } from "react"; import { createPortal } from "react-dom"; import styles from "./Menu.module.scss"; import { Chip, Divider, Typography } from "@mui/material"; import ChevronRightIcon from "@mui/icons-material/ChevronRight"; import { useMedia } from "react-use"; const menuList = [ { icon: "fak fa-markets-overview", text: "Markets Overview", link: "/markets-overview", }, { icon: "fak fa-stock-data-sets", text: "Stock Data Sets", submenu: [ { icon: "fal fa-chart-line-down", href: "/short-interest", text: "Shorts", }, { icon: "fak fa-stock-options", href: "/options", text: "Options", }, { icon: "fal fa-users", href: "/insiders", text: "Insiders", }, { icon: "fal fa-user-tie", href: "/analysts", text: "Analysts", }, { icon: "fal fa-newspaper", href: "/news", text: "News", }, { icon: "fal fa-calendar-alt", href: "/events", text: "Company Events", }, { icon: "fal fa-list-ol", href: "/holdings", text: "Holdings", }, { icon: "fal fa-chart-pie-alt", href: "/dividend", text: "Dividends", }, { icon: "fak fa-ipos-deals", href: "/ipo-deals", text: "IPOs & Deals", }, { icon: "fak fa-corporate-actions", href: "/coming-soon", text: "Corporate Actions", }, { icon: "fal fa-balance-scale", href: "/index-rebalance", text: "Index Rebalance", }, { icon: "fak fa-credit-default-swaps", href: "/cds", text: "Credit Default Swaps", }, ], }, { link: "/market-sentiment", icon: "fak fa-data-sentiment", text: "Market Sentiment", }, { link: "/money-flow", icon: "fak fa-passive-money-flow", text: "Passive Money Flow", }, { link: "/index-rebalance", icon: "fal fa-balance-scale", text: "Index Rebalance", }, { link: "/stock-movers", icon: "fak fa-charts", text: "Stock Movers", }, { link: "/stock-stamps", icon: "fak fa-stock-stamps", text: "Stock Stamps", }, { link: "/portfolio", icon: "fak fa-portfolio", text: "My Portfolio", }, { link: "/my-universe", icon: "fak fa-my-universe", text: "My Stocks", }, { icon: "fal fa-newspaper", link: "/news", text: "News", }, { icon: "fal fa-calendar-alt", text: "Events", submenu: [ { icon: "fal fa-calendar-alt", text: "Company Events", href: "/events", }, { icon: "fal fa-calendar-alt", text: "Macro Events", href: "/macro", }, ], }, { link: "/trading-signals", icon: "fak fa-trading-signals", text: "Trading Signals", submenu: [ { icon: "fak fa-trading-signals", href: "/trading-signals", text: "Stock Signals", }, { icon: "fak fa-trading-signals", href: "/trading-signals", text: "Index Signals", }, { icon: "fak fa-trading-signals", href: "/trading-signals", text: "Commodity Signals", }, { icon: "fak fa-trading-signals", href: "/trading-signals", text: "Currency Signals", }, { icon: "fak fa-trading-signals", href: "/trading-signals", text: "Cryptocurrency Signals", }, ], }, { link: "/stock-scores", icon: "fak fa-stock-scores", text: "Stock Scores", }, { link: "/sector-scores", icon: "fak fa-sector-scores", text: "Sector Scores", }, { link: "/cds", icon: "fak fa-credit-default-swaps", text: "Credit Default Swaps", }, { link: "/indexes", icon: "fal fa-university", text: "Index", submenu: [ { icon: "fal fa-university", href: "/indexes", text: "Overview", }, { icon: "fal fa-university", href: "/indexes", text: "Index Rebalance", }, { icon: "fal fa-university", href: "/indexes", text: "Index Creator", }, { icon: "fal fa-university", href: "/indexes", text: "Index Trading Signals", }, { icon: "fal fa-university", href: "/indexes", text: "Short Index", }, ], }, { link: "/commodities", icon: "fak fa-commodities", text: "Commodity", submenu: [ { icon: "fak fa-commodities", href: "/commodities", text: "Overview", }, { icon: "fak fa-commodities", href: "/commodities", text: "Commodity Stock Correlation", }, { icon: "fak fa-commodities", href: "/commodities", text: "Currency Trading Signals", }, ], }, { link: "/currencies", icon: "fal fa-coins", text: "Currency", submenu: [ { icon: "fal fa-coins", href: "/currencies", text: "Overview", }, { icon: "fal fa-coins", href: "/currencies", text: "Currency Stock Correlation", }, { icon: "fal fa-coins", href: "/currencies", text: "Currency Trading Signals", }, { icon: "fak fa-crypto-currencies", href: "/cryptocurrencies", text: "Cryptocurrency Overview", }, { icon: "fak fa-crypto-currencies", href: "/cryptocurrencies", text: "Cryptocurrency Trading Signals", }, ], }, { link: "/etfs", icon: "fak fa-etfs", text: "ETFs", submenu: [ { icon: "fak fa-etfs", href: "/etfs", text: "ETF Overview", }, { icon: "fak fa-etfs", href: "/etfs", text: "ETF Fund Flow", }, { icon: "fak fa-etfs", href: "/etfs", text: "ETF Trading Signals", }, { icon: "fak fa-etfs", href: "/etfs", text: "ETF Shorts", }, ], }, { icon: "fak fa-stock-trading-signals", text: "Charts & Screening", submenu: [ { icon: "fak fa-stock-trading-signals", href: "/charts", text: "Charts", }, { icon: "fak fa-stock-trading-signals", href: "/screening", text: "Screening", }, ], }, { link: "", icon: "", text: "Popular", }, { icon: "fal fa-chart-line-down", text: "Shorts", submenu: [ { icon: "fal fa-chart-line-down", text: "Short Sentiment", href: "/coming-soon", }, { icon: "fal fa-chart-line-down", text: "Short by Index", href: "/coming-soon", }, { icon: "fal fa-chart-line-down", text: "Short Stock Extremes", href: "/coming-soon", }, { icon: "fal fa-chart-line-down", text: "Short Sector Averages", href: "/coming-soon", }, { icon: "fal fa-chart-line-down", text: "Short Changes", href: "/coming-soon", }, { icon: "fal fa-chart-line-down", text: "European Short Flags", href: "/coming-soon", }, ], }, { icon: "fak fa-stock-options", text: "Options", submenu: [ { icon: "fak fa-stock-options", text: "Options Extremes", href: "/options", }, { icon: "fak fa-stock-options", text: "Interesting Options Flow", href: "/options", }, { icon: "fak fa-stock-options", text: "Options Flow Sentiment", href: "/options", }, ], }, { icon: "fal fa-users", text: "Insiders", link: "/insiders", }, { icon: "fal fa-user-tie", text: "Analysts", link: "/analysts", }, ]; export const MenuListItems = ({ isIconOnly = false }: { isIconOnly?: boolean }) => { const [selectedItem, setSelectedItem] = useState(undefined); const [minMenuHovered, setMinMenuHovered] = useState(false); const [fontSize, setFontSize] = useState<string>(); const [padding, setPadding] = useState<number>(1); const isnotMobile = useMedia("(min-width: 768px)"); const textColor = useRecoilValue(textColorState); const dividerColor = useRecoilValue(dividerState); const handleHover = (key: number, isMinMenu?: boolean) => { setSelectedItem(key); setMinMenuHovered(isMinMenu); }; useEffect(() => { const list = document.getElementById("list"); const observer = new ResizeObserver((entries) => { if (isnotMobile) { for (let key in entries) { const isSmall = entries[key].contentRect.height < 750; const isMedium = entries[key].contentRect.height < 820; const isBig = entries[key].contentRect.height < 920; // @ts-ignore setFontSize(isSmall ? "11px" : isMedium ? "12px" : isBig ? "13px" : "14px"); setPadding(isSmall ? 0.525 : isBig ? 0.65 : 0.775); } } else { setFontSize("12px"); setPadding(0.75); } }); if (list !== null) { observer.observe(list); } return () => { observer.disconnect(); }; }, [isnotMobile]); return ( <> <div className={styles.MenuOverlay} onMouseEnter={() => setSelectedItem(undefined)}></div> <List sx={{ textAlign: "center", paddingY: 0.5 }} className={styles.list} id="list"> {menuList.map((item, index, to) => !isIconOnly ? ( item.text === "Popular" ? ( <> <Divider sx={{ "&::before, &::after": { borderColor: dividerColor, }, }} > <Chip label="Popular" sx={{ backgroundColor: dividerColor, color: textColor, mt: 1, mb: 1 }} /> </Divider> </> ) : ( <ListItem disablePadding key={index} onMouseOver={() => handleHover(index)} id={`menu-item-${index}`} className={styles.mainLink}> {!item.submenu ? ( <Link href={item.link} passHref> <ListItemButton sx={{ padding: padding }}> <ListItemIcon> <div className={item.icon} style={{ color: textColor, fontSize: `calc(${fontSize} + 5px)` }} /> </ListItemIcon> <ListItemText sx={{ margin: 0 }}> <Typography variant="h5userMenu"> {item.text} </Typography> </ListItemText> </ListItemButton> </Link> ) : !isnotMobile ? ( <ListItemButton onClick={(e: React.KeyboardEvent | React.MouseEvent) => e.stopPropagation()} sx={{ padding: padding }}> <ListItemIcon> <div className={item.icon} style={{ color: textColor, fontSize: `calc(${fontSize} + 5px)` }} /> </ListItemIcon> <ListItemText sx={{ margin: 0 }}> <Typography variant="h5userMenu">{item.text}</Typography> </ListItemText> <ChevronRightIcon sx={{ color: textColor, fontSize: `calc(${fontSize} + 5px)` }} /> </ListItemButton> ) : selectedItem && menuList[selectedItem].submenu ? ( <Link href={menuList[selectedItem].submenu[0].href} passHref> {/* the following code is the same as the one below, but enclosed in a link */} <ListItemButton onClick={(e: React.KeyboardEvent | React.MouseEvent) => e.stopPropagation()} sx={{ padding: padding }}> <ListItemIcon> <div className={item.icon} style={{ color: textColor, fontSize: `calc(${fontSize} + 5px)` }} /> </ListItemIcon> <ListItemText sx={{ margin: 0 }}> <Typography variant="h5userMenu">{item.text}</Typography> </ListItemText> <ChevronRightIcon sx={{ color: textColor, fontSize: `calc(${fontSize} + 5px)` }} /> </ListItemButton> </Link> ) : ( <> {/* Popular menu items */} <ListItemButton onClick={(e: React.KeyboardEvent | React.MouseEvent) => e.stopPropagation()} sx={{ padding: padding }}> <ListItemIcon> <div className={item.icon} style={{ color: textColor, fontSize: `calc(${fontSize} + 5px)` }} /> </ListItemIcon> <ListItemText sx={{ margin: 0 }}> <Typography variant="h5userMenu">{item.text}</Typography> </ListItemText> <ChevronRightIcon sx={{ color: textColor, fontSize: `calc(${fontSize} + 5px)` }} /> </ListItemButton> </> )} </ListItem> ) ) : ( <ListItem disablePadding key={index} onMouseOver={() => handleHover(index, true)} id={`small-menu-item-${index}`}> {!item.submenu ? ( <Link href={item.link} passHref> <ListItemButton sx={{ padding: padding }}> <ListItemIcon> <div className={item.icon} style={{ color: textColor, fontSize: `calc(${fontSize} + 5px)` }} /> </ListItemIcon> </ListItemButton> </Link> ) : ( <> {selectedItem && menuList[selectedItem].submenu ? ( <Link href={menuList[selectedItem].submenu[0].href} passHref> <ListItemButton onClick={(e: React.KeyboardEvent | React.MouseEvent) => e.stopPropagation()} sx={{ padding: padding }}> <ListItemIcon> <div className={item.icon} style={{ color: textColor, fontSize: `calc(${fontSize} + 5px)` }} /> </ListItemIcon> </ListItemButton> </Link> ) : ( <ListItemButton onClick={(e: React.KeyboardEvent | React.MouseEvent) => e.stopPropagation()} sx={{ padding: padding }}> <ListItemIcon> <div className={item.icon} style={{ color: textColor, fontSize: `calc(${fontSize} + 5px)` }} /> </ListItemIcon> </ListItemButton> )} </> )} </ListItem> ) )} </List> {selectedItem !== undefined && menuList[selectedItem].submenu !== undefined && createPortal( <MenuPopup links={menuList[selectedItem].submenu} index={selectedItem} parentId={minMenuHovered ? "small-menu-item-" : "menu-item-"} fontSize={fontSize} padding={padding} />, minMenuHovered ? document.getElementById("sideMenu") : document.getElementById("menu") || document.body )} </> ); };