Chandima Prabhath
Track bun.lockb with Git LFS
cc2caf9
raw
history blame
5.9 kB
import React, { useState, useEffect, useRef } from 'react';
import { Link, useNavigate } from 'react-router-dom';
import { Search, Bell, User, Menu, X } from 'lucide-react';
import { motion, AnimatePresence } from 'framer-motion';
const Navbar = () => {
const [isScrolled, setIsScrolled] = useState(false);
const [isMenuOpen, setIsMenuOpen] = useState(false);
const [searchVisible, setSearchVisible] = useState(false);
const [searchTerm, setSearchTerm] = useState('');
const searchInputRef = useRef<HTMLInputElement>(null);
const navigate = useNavigate();
useEffect(() => {
const handleScroll = () => {
if (window.scrollY > 50) {
setIsScrolled(true);
} else {
setIsScrolled(false);
}
};
window.addEventListener('scroll', handleScroll);
return () => {
window.removeEventListener('scroll', handleScroll);
};
}, []);
// Focus the search input when it becomes visible
useEffect(() => {
if (searchVisible && searchInputRef.current) {
setTimeout(() => {
searchInputRef.current?.focus();
}, 200);
}
}, [searchVisible]);
const toggleMenu = () => {
setIsMenuOpen(!isMenuOpen);
};
const toggleSearch = () => {
setSearchVisible(!searchVisible);
};
const handleSearchSubmit = (e: React.FormEvent) => {
e.preventDefault();
if (searchTerm.trim()) {
navigate(`/search?q=${encodeURIComponent(searchTerm)}`);
setSearchVisible(false);
setSearchTerm('');
}
};
return (
<nav
className={`fixed top-0 left-0 w-full z-50 transition-all duration-300 px-4 sm:px-6 ${
isScrolled ? 'bg-theme-background-dark shadow-lg py-2' : 'bg-gradient-to-b from-black/80 to-transparent py-4'
}`}
>
<div className="flex items-center justify-between">
{/* Logo */}
<Link to="/" className="flex items-center">
<h1 className="text-theme-primary text-2xl sm:text-3xl font-bold">NEXORA</h1>
</Link>
{/* Desktop Nav Links */}
<div className="hidden md:flex items-center space-x-6">
<Link to="/" className="text-white hover:text-theme-primary transition-colors">Home</Link>
<Link to="/movies" className="text-white hover:text-theme-primary transition-colors">Movies</Link>
<Link to="/tv-shows" className="text-white hover:text-theme-primary transition-colors">TV Shows</Link>
<Link to="/my-list" className="text-white hover:text-theme-primary transition-colors">My List</Link>
</div>
{/* Right side icons */}
<div className="flex items-center space-x-4">
{/* Search bar with animation */}
<div className="relative flex items-center">
<AnimatePresence>
{searchVisible ? (
<motion.form
onSubmit={handleSearchSubmit}
className="flex items-center"
initial={{ width: 0, opacity: 0 }}
animate={{ width: 200, opacity: 1 }}
exit={{ width: 0, opacity: 0 }}
transition={{ duration: 0.2 }}
>
<input
ref={searchInputRef}
type="text"
placeholder="Titles, people, genres"
className="bg-theme-background-dark border border-theme-border rounded px-3 py-1
focus:outline-none focus:border-theme-primary text-white w-full"
value={searchTerm}
onChange={(e) => setSearchTerm(e.target.value)}
/>
<button
type="button"
onClick={toggleSearch}
className="ml-2 text-white hover:text-theme-primary"
>
<X className="w-5 h-5" />
</button>
</motion.form>
) : (
<button
onClick={toggleSearch}
className="hover:text-theme-primary transition-colors"
>
<Search className="w-5 h-5" />
</button>
)}
</AnimatePresence>
</div>
<button className="hover:text-theme-primary transition-colors hidden sm:block">
<Bell className="w-5 h-5" />
</button>
<Link to="/profile" className="hover:text-theme-primary transition-colors hidden sm:block">
<User className="w-5 h-5" />
</Link>
{/* Mobile menu button */}
<button onClick={toggleMenu} className="md:hidden hover:text-theme-primary">
<Menu className="w-6 h-6" />
</button>
</div>
</div>
{/* Mobile menu */}
<AnimatePresence>
{isMenuOpen && (
<motion.div
className="md:hidden absolute top-full left-0 right-0 bg-theme-background-dark/95 border-t border-theme-border"
initial={{ opacity: 0, height: 0 }}
animate={{ opacity: 1, height: 'auto' }}
exit={{ opacity: 0, height: 0 }}
transition={{ duration: 0.3 }}
>
<div className="flex flex-col p-4 space-y-3">
<Link to="/" className="text-white py-2 hover:text-theme-primary">Home</Link>
<Link to="/movies" className="text-white py-2 hover:text-theme-primary">Movies</Link>
<Link to="/tv-shows" className="text-white py-2 hover:text-theme-primary">TV Shows</Link>
<Link to="/my-list" className="text-white py-2 hover:text-theme-primary">My List</Link>
<Link to="/profile" className="text-white py-2 hover:text-theme-primary">Profile</Link>
</div>
</motion.div>
)}
</AnimatePresence>
</nav>
);
};
export default Navbar;