Paul's Task

Paul has to invite me a beer
mail@pastecode.io avatar
unknown
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
                )}
        </>
    );
};