diff --git a/components/ui/FloatingNavbar.tsx b/components/ui/FloatingNavbar.tsx index 4abb6e4..660ecde 100644 --- a/components/ui/FloatingNavbar.tsx +++ b/components/ui/FloatingNavbar.tsx @@ -8,8 +8,11 @@ import { } from "framer-motion"; import Link from "next/link"; import { cn } from "@/lib/utils"; +import Image from "next/image"; +import { usePathname } from "next/navigation"; +import MobileNavModal from "./MobileNavModal"; +import { HiMenu } from "react-icons/hi"; -// Accept props correctly (function parameter was broken) interface NavItem { name: string; link: string; @@ -23,54 +26,197 @@ interface Props { const FloatingNavbar: React.FC = ({ navItems, className }) => { const { scrollYProgress } = useScroll(); + + // set true for the initial state so that nav bar is visible in the hero section const [visible, setVisible] = useState(true); + const [isScrolled, setIsScrolled] = useState(false); + const [mobileNavOpen, setMobileNavOpen] = useState(false); useMotionValueEvent(scrollYProgress, "change", (current) => { + // Check if current is not undefined and is a number if (typeof current === "number") { - const previous = scrollYProgress.getPrevious(); - const direction = current - (previous ?? 0); + let direction = current! - scrollYProgress.getPrevious()!; if (scrollYProgress.get() < 0.05) { + // also set true for the initial state setVisible(true); + setIsScrolled(false); } else { - setVisible(direction < 0); + if (direction < 0) { + setVisible(true); + } + setIsScrolled(true); } } }); + const pathname = usePathname(); + const isDashboard = pathname?.startsWith("/dashboard"); + const isAdminDashboard = pathname === "/dashboard/admin"; return ( - - - {navItems.map((navItem, idx) => ( - + + + {/* Elixir text on the left */} + + Elixir Logo + Elixir + + {/* Hamburger icon for mobile */} +
+ +
+ {/* Navigation items in the center (hidden on mobile) */} + + {navItems.map((navItem: any, idx: number) => ( + + + {navItem.icon} + + {navItem.name} + + + + ))} + + {/* Login button on the right (hidden on mobile) */} + - {navItem.icon} - {navItem.name} - - ))} -
-
+
+ {!isDashboard ? ( + <> + + Login + + + ) : isAdminDashboard ? ( +
+ Admin +
+ ) : ( +
+ User +
+ )} +
+ + + +
+
+ {/* Mobile Navigation Modal */} + setMobileNavOpen(false)} + navItems={navItems} + /> + ); }; - export default FloatingNavbar; diff --git a/components/ui/MobileNavModal.tsx b/components/ui/MobileNavModal.tsx new file mode 100644 index 0000000..3e9fdaf --- /dev/null +++ b/components/ui/MobileNavModal.tsx @@ -0,0 +1,148 @@ +import React from "react"; +import { motion, AnimatePresence } from "framer-motion"; +import { cn } from "@/lib/utils"; +import Link from "next/link"; +import { usePathname } from "next/navigation"; +import Image from "next/image"; +import { HiX, HiArrowRight } from "react-icons/hi"; + +interface NavItem { + name: string; + link: string; + icon?: JSX.Element; +} + +interface MobileNavModalProps { + open: boolean; + onClose: () => void; + navItems: NavItem[]; +} + +const overlayVariants = { + hidden: { opacity: 0 }, + visible: { opacity: 1 }, +}; + +const modalVariants = { + hidden: { y: "100%", opacity: 0 }, + visible: { y: 0, opacity: 1 }, +}; + +const MobileNavModal: React.FC = ({ + open, + onClose, + navItems, +}) => { + const pathname = usePathname(); + const isDashboard = pathname?.startsWith("/dashboard"); + const isAdminDashboard = pathname === "/dashboard/admin"; + + return ( + + {open && ( + <> + {/* Overlay */} + + {/* Modal */} + + {/* Logo/brand and close button row */} +
+
+ Elixir Logo + + Elixir + +
+ +
+ {/* Nav items */} + + {/* Login/Dashboard button */} +
+ {!isDashboard ? ( + + Login + + {/* Blue highlight at the bottom center */} + + + ) : isAdminDashboard ? ( +
+ Admin + +
+ ) : ( +
+ User + +
+ )} +
+
+ + )} +
+ ); +}; + +export default MobileNavModal;