embedingHF's picture
Upload folder using huggingface_hub
84fc8e7 verified
Raw
History Blame Contribute Delete
8.83 kB
import { useState, useEffect } from "react";
import { Menu, X, Download, ShieldCheck } from "lucide-react";
import { motion, AnimatePresence } from "motion/react";
import { Link, useLocation } from "react-router-dom";
interface NavbarProps {
downloadUrl: string;
}
export default function Navbar({ downloadUrl }: NavbarProps) {
const [isOpen, setIsOpen] = useState(false);
const [isScrolled, setIsScrolled] = useState(false);
const location = useLocation();
const navItems = [
{ name: "Home", path: "/" },
{ name: "Features Specs", path: "/features" },
{ name: "FAQ Hub", path: "/faq" },
{ name: "Support Us", path: "/support" },
{ name: "Contact Specialist", path: "/contact" },
];
useEffect(() => {
const handleScroll = () => {
setIsScrolled(window.scrollY > 20);
};
window.addEventListener("scroll", handleScroll);
return () => window.removeEventListener("scroll", handleScroll);
}, []);
// Close mobile navigation drawer whenever path shifts
useEffect(() => {
setIsOpen(false);
window.scrollTo(0, 0);
}, [location.pathname]);
const activePath = location.pathname;
return (
<>
<nav
id="main-nav"
className={`fixed top-0 left-0 right-0 z-50 transition-all duration-300 ${
isScrolled
? "py-3 px-4 md:px-8 bg-white/80 backdrop-blur-md shadow-sm border-b border-slate-100"
: "py-5 px-4 md:px-8 bg-transparent"
}`}
>
<div className="max-w-7xl mx-auto flex items-center justify-between">
{/* Logo */}
<Link
to="/"
className="flex items-center space-x-2 group focus:outline-none cursor-pointer"
id="nav-logo-btn"
>
<div className="w-10 h-10 rounded-xl bg-gradient-to-tr from-violet-600 to-indigo-600 flex items-center justify-center shadow-md shadow-violet-500/20 group-hover:scale-105 transition-transform duration-300">
<ShieldCheck className="w-5 h-5 text-white" />
</div>
<div className="text-left">
<span className="block font-display font-medium text-lg text-slate-900 tracking-tight">
Lumina Convert
</span>
<span className="block text-[10px] font-mono tracking-wider text-violet-600 -mt-1 font-semibold uppercase">
All File Converter
</span>
</div>
</Link>
{/* Desktop Nav Items */}
<div className="hidden md:flex items-center space-x-8">
<div className="flex items-center space-x-6">
{navItems.map((item) => (
<Link
key={item.path}
to={item.path}
id={`nav-item-${item.name.toLowerCase().replace(/\s+/g, "-")}`}
className={`text-sm font-semibold tracking-wide transition-colors cursor-pointer relative py-1.5 focus:outline-none ${
activePath === item.path
? "text-violet-600 font-bold"
: "text-slate-600 hover:text-slate-900"
}`}
>
<span>{item.name}</span>
{activePath === item.path && (
<motion.div
layoutId="activeIndicator"
className="absolute bottom-0 left-0 right-0 h-0.5 bg-violet-600 rounded-full"
transition={{ type: "spring", stiffness: 380, damping: 30 }}
/>
)}
</Link>
))}
</div>
{/* Premium CTA Button */}
<a
href={downloadUrl}
download
id="navbar-download-btn"
className="inline-flex items-center justify-center space-x-2 px-6 py-2.5 rounded-full bg-slate-900 text-white text-sm font-semibold shadow-md shadow-slate-900/10 hover:bg-violet-600 hover:shadow-violet-500/20 active:scale-95 transition-all duration-300 cursor-pointer"
>
<Download className="w-4 h-4" />
<span>Download Free</span>
</a>
</div>
{/* Mobile Menu Button */}
<div className="flex md:hidden items-center space-x-2">
<a
href={downloadUrl}
download
id="navbar-download-mobile-btn"
className="p-2.5 rounded-full bg-slate-900 text-white shadow-sm hover:bg-violet-600 transition-colors cursor-pointer"
title="Download Converter"
>
<Download className="w-4 h-4" />
</a>
<button
onClick={() => setIsOpen(!isOpen)}
id="mobile-menu-toggle-btn"
className="p-2 text-slate-700 hover:text-slate-900 focus:outline-none cursor-pointer"
aria-label="Toggle navigation menu"
>
{isOpen ? <X className="w-6 h-6" /> : <Menu className="w-6 h-6" />}
</button>
</div>
</div>
</nav>
{/* Mobile Drawer Overlay */}
<AnimatePresence>
{isOpen && (
<>
{/* Backdrop */}
<motion.div
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
onClick={() => setIsOpen(false)}
className="fixed inset-0 bg-slate-900/20 backdrop-blur-sm z-40 md:hidden"
/>
{/* Sidebar drawer */}
<motion.div
initial={{ x: "100%" }}
animate={{ x: 0 }}
exit={{ x: "100%" }}
transition={{ type: "spring", damping: 25, stiffness: 200 }}
className="fixed right-0 top-0 bottom-0 w-72 bg-white z-50 p-6 shadow-2xl flex flex-col justify-between border-l border-slate-100 md:hidden"
>
<div>
<div className="flex items-center justify-between mb-8">
<div className="flex items-center space-x-2">
<div className="w-8 h-8 rounded-lg bg-gradient-to-tr from-violet-600 to-indigo-600 flex items-center justify-center shadow-md">
<ShieldCheck className="w-4 h-4 text-white" />
</div>
<span className="font-display font-semibold text-slate-900">Lumina Convert</span>
</div>
<button
onClick={() => setIsOpen(false)}
id="mobile-drawer-close-btn"
className="p-1 rounded-full hover:bg-slate-100 text-slate-500 cursor-pointer"
>
<X className="w-5 h-5" />
</button>
</div>
<div className="flex flex-col space-y-2">
{navItems.map((item) => (
<Link
key={item.path}
to={item.path}
id={`mobile-nav-item-${item.name.toLowerCase().replace(/\s+/g, "-")}`}
className={`text-left py-3 px-4 rounded-xl text-sm font-semibold tracking-wide transition-colors cursor-pointer flex justify-between items-center ${
activePath === item.path
? "bg-violet-50 text-violet-600 font-bold"
: "text-slate-600 hover:bg-slate-50"
}`}
>
<span>{item.name}</span>
{activePath === item.path && (
<div className="w-1.5 h-1.5 rounded-full bg-violet-600" />
)}
</Link>
))}
</div>
</div>
<div className="space-y-4">
<div className="p-4 rounded-2xl bg-slate-50 border border-slate-100">
<h4 className="text-xs font-mono font-bold uppercase tracking-wider text-slate-500 mb-1">
v1.4.2 Standalone
</h4>
<p className="text-[11px] text-slate-600 mb-3">Offline GPU acceleration included.</p>
<a
href={downloadUrl}
download
id="mobile-drawer-download-cta"
className="w-full inline-flex items-center justify-center space-x-2 py-3 rounded-xl bg-violet-600 text-white font-medium text-xs shadow-md hover:bg-violet-700 active:scale-95 transition-all cursor-pointer"
>
<Download className="w-4 h-4" />
<span>Download Installer</span>
</a>
</div>
</div>
</motion.div>
</>
)}
</AnimatePresence>
</>
);
}