fitmate-landing/components/Navbar.tsx
2025-11-20 22:22:22 +07:00

124 lines
4.5 KiB
TypeScript

import React, { useState, useEffect } from 'react';
import { Menu, X, Activity } from 'lucide-react';
import { NavItem } from '../types';
const NAV_ITEMS: NavItem[] = [
{ label: 'Features', href: '#features' },
{ label: 'The Logic', href: '#logic' },
{ label: 'Reviews', href: '#reviews' },
{ label: 'Pricing', href: '#pricing' },
{ label: 'FAQ', href: '#faq' },
];
export const Navbar: React.FC = () => {
const [isScrolled, setIsScrolled] = useState(false);
const [isMobileMenuOpen, setIsMobileMenuOpen] = useState(false);
useEffect(() => {
const handleScroll = () => {
setIsScrolled(window.scrollY > 20);
};
window.addEventListener('scroll', handleScroll);
return () => window.removeEventListener('scroll', handleScroll);
}, []);
const handleScrollTo = (id: string) => {
setIsMobileMenuOpen(false);
const element = document.querySelector(id);
if (element) {
element.scrollIntoView({ behavior: 'smooth' });
}
};
return (
<nav
className={`fixed top-0 left-0 right-0 z-[100] transition-all duration-500 ${
isScrolled
? 'bg-black/60 backdrop-blur-xl border-b border-white/5 py-4'
: 'bg-transparent border-b border-transparent py-6'
}`}
>
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div className="flex items-center justify-between">
{/* Logo */}
<div className="flex items-center gap-2 cursor-pointer" onClick={() => window.scrollTo({ top: 0, behavior: 'smooth' })}>
<div className="w-8 h-8 rounded-lg bg-white text-black flex items-center justify-center shadow-[0_0_15px_rgba(255,255,255,0.3)]">
<Activity className="w-5 h-5" strokeWidth={3} />
</div>
<span className="text-xl font-bold tracking-tight text-white">
FitMate
</span>
</div>
{/* Desktop Links */}
<div className="hidden md:flex items-center gap-8">
{NAV_ITEMS.map((item) => (
<a
key={item.label}
href={item.href}
className="text-sm font-medium text-gray-400 hover:text-white transition-colors relative group"
>
{item.label}
<span className="absolute -bottom-1 left-0 w-0 h-px bg-primary-400 transition-all duration-300 group-hover:w-full" />
</a>
))}
</div>
{/* Desktop CTA */}
<div className="hidden md:block">
<button
onClick={() => handleScrollTo('#pricing')}
className="bg-white/10 hover:bg-white text-white hover:text-black border border-white/10 hover:border-white px-6 py-2 rounded-full text-sm font-semibold transition-all duration-300 backdrop-blur-md"
>
Build Your Plan
</button>
</div>
{/* Mobile Toggle */}
<div className="md:hidden">
<button
onClick={() => setIsMobileMenuOpen(!isMobileMenuOpen)}
className="text-gray-300 hover:text-white p-2"
>
{isMobileMenuOpen ? <X size={24} /> : <Menu size={24} />}
</button>
</div>
</div>
</div>
{/* Mobile Menu */}
{isMobileMenuOpen && (
<div className="md:hidden fixed inset-0 bg-black/95 backdrop-blur-2xl z-[101] flex flex-col">
<div className="flex justify-end p-6 border-b border-white/10">
<button onClick={() => setIsMobileMenuOpen(false)} className="text-white p-2 bg-white/5 rounded-full">
<X size={24} />
</button>
</div>
<div className="flex-1 flex flex-col items-center justify-center space-y-8 px-6">
{NAV_ITEMS.map((item) => (
<a
key={item.label}
href={item.href}
onClick={(e) => {
e.preventDefault();
handleScrollTo(item.href);
}}
className="text-4xl font-bold text-white hover:text-primary-400 transition-colors"
>
{item.label}
</a>
))}
<div className="pt-8 w-full max-w-xs">
<button
onClick={() => handleScrollTo('#pricing')}
className="w-full bg-white text-black px-6 py-5 rounded-2xl text-xl font-bold hover:scale-105 transition-transform"
>
Build Your Plan
</button>
</div>
</div>
</div>
)}
</nav>
);
};