| import { useState, useEffect } from 'react'; |
| import { Link, useLocation } from 'react-router-dom'; |
| import { motion, AnimatePresence } from 'framer-motion'; |
| import { Menu, X, ChevronDown, TestTube, Heart, Brain, Dna, Activity, Shield, Users, Zap } from 'lucide-react'; |
| import { Button } from '@/components/ui/button'; |
|
|
| const Navbar = () => { |
| const [isOpen, setIsOpen] = useState(false); |
| const [isScrolled, setIsScrolled] = useState(false); |
| const [testsDropdownOpen, setTestsDropdownOpen] = useState(false); |
| const location = useLocation(); |
|
|
| useEffect(() => { |
| const handleScroll = () => { |
| setIsScrolled(window.scrollY > 10); |
| }; |
| window.addEventListener('scroll', handleScroll); |
| return () => { |
| window.removeEventListener('scroll', handleScroll); |
| }; |
| }, []); |
|
|
| const navigationItems = [ |
| { name: 'Home', href: '/' }, |
| { name: 'About Us', href: '/about-us' }, |
| { name: 'Our Solutions', href: '/our-solutions' }, |
| { |
| name: 'Tests', |
| href: '/tests', |
| hasDropdown: true, |
| dropdownItems: [ |
| { name: 'View All Tests', href: '/tests', icon: TestTube }, |
| { |
| name: 'Browse by Category', |
| subItems: [ |
| { name: 'Heart Health', href: '/tests?category=heart-health', icon: Heart }, |
| { name: 'Brain Health', href: '/tests?category=brain-health', icon: Brain }, |
| { name: 'Genetic & Inherited', href: '/tests?category=genetic-inherited', icon: Dna }, |
| { name: 'Digestive Health', href: '/tests?category=digestive-health', icon: Activity }, |
| { name: 'Immune System', href: '/tests?category=immune-system', icon: Shield }, |
| { name: 'Women\'s Health', href: '/tests?category=womens-health', icon: Users } |
| ] |
| } |
| ] |
| }, |
| { name: 'Contact Us', href: '/contact-us' } |
| ]; |
|
|
| return ( |
| <nav className={`fixed top-0 left-0 right-0 z-50 transition-all duration-500 ${ |
| isScrolled |
| ? 'bg-white/95 backdrop-blur-xl shadow-2xl border-b border-gray-200/50' |
| : 'bg-transparent' |
| }`}> |
| <div className="container mx-auto px-4 sm:px-6 lg:px-8"> |
| <div className="flex justify-between items-center h-20"> |
| {/* Logo */} |
| <Link to="/" className="flex items-center group"> |
| <motion.div |
| className="flex items-center gap-3" |
| whileHover={{ scale: 1.05 }} |
| transition={{ duration: 0.2 }} |
| > |
| <img |
| src="/Cellmolecules Logo No bg.png" |
| alt="Cellmolecules Scientific" |
| className="h-16 w-auto" |
| /> |
| </motion.div> |
| </Link> |
| |
| {/* Desktop Navigation */} |
| <div className="hidden lg:flex items-center space-x-1"> |
| {navigationItems.map((item) => ( |
| <div key={item.name} className="relative"> |
| {item.hasDropdown ? ( |
| <div |
| className="relative" |
| onMouseEnter={() => setTestsDropdownOpen(true)} |
| onMouseLeave={() => setTestsDropdownOpen(false)} |
| > |
| <button |
| className={`font-semibold px-4 py-2 rounded-xl transition-all duration-300 flex items-center gap-1 ${ |
| isScrolled || testsDropdownOpen |
| ? 'text-gray-800 hover:text-blue-600 hover:bg-blue-50' |
| : 'text-gray-700 hover:text-gray-900 hover:bg-white/50' |
| }`} |
| > |
| {item.name} |
| <ChevronDown className={`h-4 w-4 transition-transform duration-300 ${testsDropdownOpen ? 'rotate-180' : ''}`} /> |
| </button> |
| |
| <AnimatePresence> |
| {testsDropdownOpen && ( |
| <motion.div |
| initial={{ opacity: 0, y: 10, scale: 0.98 }} |
| animate={{ opacity: 1, y: 0, scale: 1 }} |
| exit={{ opacity: 0, y: 10, scale: 0.98 }} |
| transition={{ duration: 0.2, ease: "easeOut" }} |
| className="absolute top-full left-0 mt-3 w-[540px] bg-white/95 backdrop-blur-xl rounded-3xl shadow-2xl border border-gray-200/50 p-6 z-50" |
| > |
| <div className="space-y-4"> |
| {item.dropdownItems?.map((dropdownItem, index) => ( |
| <div key={dropdownItem.name}> |
| {dropdownItem.subItems ? ( |
| <div> |
| <div className="text-gray-500 font-semibold mb-3 text-sm uppercase tracking-wider px-2"> |
| {dropdownItem.name} |
| </div> |
| <div className="grid grid-cols-2 gap-2"> |
| {dropdownItem.subItems.map((subItem) => { |
| const IconComponent = subItem.icon; |
| return ( |
| <Link |
| key={subItem.name} |
| to={subItem.href} |
| className="group flex items-center p-3 text-sm text-gray-800 hover:text-blue-600 hover:bg-gradient-to-r hover:from-blue-50 hover:to-purple-50 rounded-xl transition-all duration-300" |
| > |
| <IconComponent className="h-5 w-5 mr-3 text-gray-400 group-hover:text-blue-600 transition-colors" /> |
| <span className="font-semibold">{subItem.name}</span> |
| </Link> |
| ); |
| })} |
| </div> |
| </div> |
| ) : ( |
| <div> |
| {index > 0 && <div className="border-t border-gray-100 my-3" />} |
| <Link |
| to={dropdownItem.href} |
| className="group flex items-center p-3 text-gray-800 hover:text-blue-600 hover:bg-gradient-to-r hover:from-blue-50 hover:to-purple-50 rounded-xl transition-all duration-300 font-semibold text-base" |
| > |
| {dropdownItem.icon && ( |
| <dropdownItem.icon className="h-6 w-6 mr-4 text-blue-600" /> |
| )} |
| <span className="flex-grow">{dropdownItem.name}</span> |
| </Link> |
| </div> |
| )} |
| </div> |
| ))} |
| </div> |
| </motion.div> |
| )} |
| </AnimatePresence> |
| </div> |
| ) : ( |
| <Link |
| to={item.href} |
| className={`font-semibold px-4 py-2 rounded-xl transition-all duration-300 relative ${ |
| isScrolled |
| ? 'text-gray-800 hover:text-blue-600 hover:bg-blue-50' |
| : 'text-gray-700 hover:text-gray-900 hover:bg-white/50' |
| } ${location.pathname === item.href ? 'text-blue-600 bg-blue-50' : ''}`} |
| > |
| {item.name} |
| {location.pathname === item.href && ( |
| <motion.div |
| className="absolute bottom-0 left-0 right-0 h-0.5 bg-gradient-to-r from-blue-500 to-purple-600 rounded-full" |
| layoutId="underline" |
| initial={false} |
| /> |
| )} |
| </Link> |
| )} |
| </div> |
| ))} |
| </div> |
| |
| {/* Right side buttons */} |
| <div className="hidden lg:flex items-center space-x-3"> |
| <Button |
| className="navbar-cta-secondary" |
| > |
| Login |
| </Button> |
| <Button |
| className="navbar-cta-primary" |
| > |
| Book a Test |
| </Button> |
| </div> |
| |
| {/* Mobile menu button */} |
| <button |
| onClick={() => setIsOpen(!isOpen)} |
| className={`lg:hidden p-2 rounded-xl focus:outline-none transition-all duration-300 ${ |
| isScrolled |
| ? 'text-gray-800 hover:bg-gray-100' |
| : 'text-gray-700 hover:bg-white/50' |
| }`} |
| > |
| {isOpen ? <X className="h-6 w-6" /> : <Menu className="h-6 w-6" />} |
| </button> |
| </div> |
| </div> |
| |
| {/* Mobile Navigation */} |
| <AnimatePresence> |
| {isOpen && ( |
| <motion.div |
| initial={{ opacity: 0, height: 0 }} |
| animate={{ opacity: 1, height: "auto" }} |
| exit={{ opacity: 0, height: 0 }} |
| className="lg:hidden bg-white/95 backdrop-blur-xl border-t border-gray-200/50" |
| > |
| <div className="px-5 py-6 space-y-2"> |
| {navigationItems.map((item) => ( |
| <div key={item.name}> |
| {item.hasDropdown ? ( |
| <div className="space-y-2"> |
| <p className="font-semibold text-gray-800 py-2">{item.name}</p> |
| <div className="ml-4 space-y-1"> |
| {item.dropdownItems?.map(dropdownItem => ( |
| <div key={dropdownItem.name}> |
| {dropdownItem.subItems ? ( |
| <> |
| <p className="font-medium text-gray-600 py-2 text-sm">{dropdownItem.name}</p> |
| <div className="ml-4 space-y-1"> |
| {dropdownItem.subItems.map(subItem => ( |
| <Link |
| to={subItem.href} |
| className="block text-gray-500 hover:text-blue-600 py-2 text-sm transition-colors" |
| onClick={() => setIsOpen(false)} |
| > |
| {subItem.name} |
| </Link> |
| ))} |
| </div> |
| </> |
| ) : ( |
| <Link |
| to={dropdownItem.href} |
| className="block text-gray-800 hover:text-blue-600 py-2 font-semibold transition-colors" |
| onClick={() => setIsOpen(false)} |
| > |
| {dropdownItem.name} |
| </Link> |
| )} |
| </div> |
| ))} |
| </div> |
| </div> |
| ) : ( |
| <Link |
| to={item.href} |
| className={`block py-2 font-semibold transition-colors ${ |
| location.pathname === item.href |
| ? 'text-blue-600' |
| : 'text-gray-800 hover:text-blue-600' |
| }`} |
| onClick={() => setIsOpen(false)} |
| > |
| {item.name} |
| </Link> |
| )} |
| </div> |
| ))} |
| |
| {/* Mobile CTA buttons */} |
| <div className="pt-4 space-y-3"> |
| <Button className="w-full navbar-cta-secondary"> |
| Login |
| </Button> |
| <Button className="w-full navbar-cta-primary"> |
| Book a Test |
| </Button> |
| </div> |
| </div> |
| </motion.div> |
| )} |
| </AnimatePresence> |
| </nav> |
| ); |
| }; |
|
|
| export default Navbar; |
|
|