import { useMatchRoute, useNavigate } from "@tanstack/react-router"; import { useTranslation } from "react-i18next"; import { AnimatePresence } from "motion/react"; import GlassSurface from "@components/surface/GlassSurface"; import classes from "./Navigation.module.css"; import ShopRoute from "@/routes/shop"; import ApiaryRoute from "@/routes/apiary"; import GameRoute from "@/routes/game"; import CashdeskRoute from "@/routes/cashdesk"; import RouletteRoute from "@/routes/roulette"; import TasksRoute from "@/routes/tasks"; import EarningsRoute from "@/routes/earnings"; import { useCallback, useEffect, useRef, useState } from "react"; import shopIcon from "./assets/shop.svg"; import apiaryIcon from "./assets/apiary.svg"; import gameIcon from "./assets/game.svg"; import cashdeskIcon from "./assets/cashdesk.svg"; import menuIcon from "./assets/menu.svg"; import rouletteIcon from "./assets/roulette.svg"; import tasksIcon from "./assets/tasks.svg"; import earningsIcon from "./assets/earnings.svg"; const BAR_HEIGHT = 64; const ACTIVE_BAR_HEIGHT = 74; const OFFSCREEN_BAR_OFFSET = 20; const NAV_ITEMS = [ { key: "nav.shop", route: ShopRoute, icon: shopIcon }, { key: "nav.apiary", route: ApiaryRoute, icon: apiaryIcon }, { key: "nav.game", route: GameRoute, icon: gameIcon }, { key: "nav.cashdesk", route: CashdeskRoute, icon: cashdeskIcon }, { key: "nav.menu", isMenu: true, icon: menuIcon }, ]; const HORIZONTAL_ENTRANCE_DELAYS = [0.2, 0.1, 0, 0.1, 0.2]; const MENU_ITEMS = [ { key: "nav.roulette", route: RouletteRoute, icon: rouletteIcon, delay: 0.1 }, { key: "nav.tasks", route: TasksRoute, icon: tasksIcon, delay: 0.05 }, { key: "nav.earnings", route: EarningsRoute, icon: earningsIcon, delay: 0 }, ]; type BarProps = { labelKey: string; icon: string; active: boolean; entranceDelay: number; onClick: () => void; }; function NavBar({ labelKey, icon, active, entranceDelay, onClick }: BarProps) { const { t } = useTranslation(); const isInitial = useRef(true); useEffect(() => { isInitial.current = false; }, []); return (
{t(labelKey)}
); } type MenuBarProps = { labelKey: string; icon: string; delay: number; onClick: () => void; }; const MENU_SPRING = { type: "spring" as const, stiffness: 400, damping: 20 }; function MenuBar({ labelKey, icon, delay, onClick }: MenuBarProps) { const { t } = useTranslation(); return (
{t(labelKey)}
); } export default function Navigation() { const matchRoute = useMatchRoute(); const navigate = useNavigate(); const [menuOpen, setMenuOpen] = useState(false); const navRef = useRef(null); const handleOutsideClick = useCallback((e: MouseEvent) => { if (navRef.current && !navRef.current.contains(e.target as Node)) { setMenuOpen(false); } }, []); useEffect(() => { if (menuOpen) { document.addEventListener("click", handleOutsideClick); return () => document.removeEventListener("click", handleOutsideClick); } }, [menuOpen, handleOutsideClick]); return (
{menuOpen && MENU_ITEMS.map((item) => ( { setMenuOpen(false); navigate({ to: item.route.to }); }} /> ))}
); }