import clsx from "clsx"; import { Calendar, ChevronRight, LogIn, Menu, MessageSquare, Settings, Tv, 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 { FriendMenu } from "~/features/friends/components/FriendMenu"; import type { RootLoaderData } from "~/root"; import { EVENTS_PAGE, FRIENDS_PAGE, navIconUrl, SETTINGS_PAGE, userPage, } from "~/utils/urls"; import { Avatar } from "./Avatar"; import { EventsList } from "./EventsList"; import { SendouButton } from "./elements/Button"; import { Image } from "./Image"; import { MOCK_TOTAL_UNREAD } from "./layout/ChatSidebar"; import { LogInButtonContainer } from "./layout/LogInButtonContainer"; import { NotificationContent, useNotifications, } from "./layout/NotificationPopover"; import { navItems } from "./layout/nav-items"; import styles from "./MobileNav.module.css"; import { NotificationDot } from "./NotificationDot"; import { StreamListItems } from "./StreamListItems"; type SidebarData = RootLoaderData["sidebar"] | undefined; type PanelType = "closed" | "menu" | "friends" | "tourneys" | "you"; export function MobileNav({ sidebarData }: { sidebarData: SidebarData }) { const [activePanel, setActivePanel] = React.useState("closed"); const user = useUser(); const { unseenIds } = useNotifications(); const hasUnseenNotifications = unseenIds.length > 0; const hasFriendInSendouQ = sidebarData?.friends.some((f) => f.subtitle === "SendouQ") ?? false; const closePanel = () => setActivePanel("closed"); return (
{activePanel === "menu" ? ( ) : null} {activePanel === "friends" ? ( ) : null} {activePanel === "tourneys" ? ( ) : null} {activePanel === "you" ? : null}
); } function MobileTabBar({ activePanel, onTabPress, isLoggedIn, hasUnseenNotifications, hasFriendInSendouQ, }: { activePanel: PanelType; onTabPress: (panel: PanelType) => void; isLoggedIn: boolean; hasUnseenNotifications: boolean; hasFriendInSendouQ: boolean; }) { const { t } = useTranslation(["front", "common"]); return ( ); } function MobileTab({ icon, label, isActive, onPress, showNotificationDot, unreadCount, }: { icon: React.ReactNode; label: string; isActive: boolean; onPress: () => void; showNotificationDot?: boolean; unreadCount?: number; }) { return ( ); } function MobilePanel({ title, onClose, children, }: { title: string; onClose: () => void; children: React.ReactNode; }) { return (

{title}

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

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

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

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

{streams.length === 0 ? (
{t("front:sideNav.noStreams")}
) : null}
); } function FriendsPanel({ friends, onClose, }: { friends: NonNullable["friends"]; onClose: () => void; }) { const { t } = useTranslation(["front", "common"]); const user = useUser(); return ( {friends.length > 0 ? ( friends.map((friend) => ( )) ) : (
{user ? t("front:sideNav.friends.noFriends") : t("front:sideNav.friends.notLoggedIn")}
)} {t("common:actions.viewAll")}
); } function TourneysPanel({ events, onClose, }: { events: NonNullable["events"]; onClose: () => void; }) { const { t } = useTranslation(["front", "common"]); return ( {t("common:actions.viewAll")} ); } 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 ? ( ) : null}
); }