import clsx from "clsx"; import { Bell, Calendar, LogIn, Menu, Settings, User, Users, X, } from "lucide-react"; import * as React from "react"; import { Dialog, Modal, ModalOverlay } from "react-aria-components"; import { useTranslation } from "react-i18next"; import { Link } from "react-router"; import { useUser } from "~/features/auth/core/user"; import type { loader as sidebarLoader } from "~/features/sidebar/routes/sidebar"; import { navIconUrl, SETTINGS_PAGE, userPage } from "~/utils/urls"; import { Avatar } from "./Avatar"; import { SendouButton } from "./elements/Button"; import { Image } from "./Image"; import { TwitchIcon } from "./icons/Twitch"; import { LogInButtonContainer } from "./layout/LogInButtonContainer"; import { NotificationContent, useNotifications, } from "./layout/NotificationPopover"; import { navItems } from "./layout/nav-items"; import styles from "./MobileNav.module.css"; import { SideNavLink } from "./SideNav"; type SidebarData = Awaited> | undefined; type PanelType = "closed" | "menu" | "friends" | "tourneys" | "you"; export function MobileNav({ sidebarData }: { sidebarData: SidebarData }) { const [activePanel, setActivePanel] = React.useState("closed"); const user = useUser(); const hasActiveMatch = Boolean(sidebarData?.matchStatus); const hasTournamentMatch = Boolean(sidebarData?.tournamentMatchStatus); const closePanel = () => setActivePanel("closed"); return (
{activePanel === "menu" ? ( ) : null} {activePanel === "friends" ? ( ) : null} {activePanel === "tourneys" ? ( ) : null} {activePanel === "you" ? : null}
); } function MobileTabBar({ activePanel, onTabPress, isLoggedIn, hasActiveMatch, matchUrl, hasTournamentMatch, tournamentMatchStatus, }: { activePanel: PanelType; onTabPress: (panel: PanelType) => void; isLoggedIn: boolean; hasActiveMatch: boolean; matchUrl?: string; hasTournamentMatch: boolean; tournamentMatchStatus?: NonNullable["tournamentMatchStatus"]; }) { const { t } = useTranslation(["front", "common"]); return ( ); } function MobileTab({ icon, label, isActive, onPress, }: { icon: React.ReactNode; label: string; isActive: boolean; onPress: () => void; }) { return ( ); } function MobilePanel({ title, onClose, children, }: { title: string; onClose: () => void; children: React.ReactNode; }) { return (

{title}

} variant="minimal" onPress={onClose} />
{children}
); } function MenuOverlay({ streams, onClose, }: { streams: NonNullable["streams"]; onClose: () => void; }) { const { t } = useTranslation(["front", "common"]); return (

{t("front:mobileNav.menu")}

} variant="minimal" onPress={onClose} />

{t("front:sideNav.streams")}

    {streams.map((stream) => (
  • {stream.name}
    {stream.subtitle ? ( {stream.subtitle} ) : null} {stream.badge ? ( {stream.badge} ) : null}
  • ))}
); } function FriendsPanel({ friends, onClose, }: { friends: NonNullable["friends"]; onClose: () => void; }) { const { t } = useTranslation(["front"]); return ( {friends.map((friend) => ( {friend.name} ))} ); } function TourneysPanel({ tournaments, onClose, }: { tournaments: NonNullable["tournaments"]; onClose: () => void; }) { const { t } = useTranslation(["front"]); return ( {tournaments.length > 0 ? ( tournaments.map((tournament) => ( {tournament.name} )) ) : (
{t("front:sideNav.noEvents")}
)}
); } function YouPanel({ onClose }: { onClose: () => void }) { const { t } = useTranslation(["front", "common"]); const user = useUser(); const { notifications, unseenIds } = useNotifications(); if (!user) { return null; } return ( {user.username} {notifications ? (

{t("common:notifications.title")} {unseenIds.length > 0 ? ( {unseenIds.length} ) : null}

) : null}
  • {t("common:pages.settings")}
); }