hotschpotsh/Pottery-website/components/Header.tsx

109 lines
4.9 KiB
TypeScript

import React, { useState, useEffect } from 'react';
import { NAV_ITEMS } from '../constants';
import { motion, AnimatePresence } from 'framer-motion';
import { Link } from 'react-router-dom';
const Header: React.FC = () => {
const [isMenuOpen, setIsMenuOpen] = useState(false);
const [scrolled, setScrolled] = useState(false);
useEffect(() => {
const handleScroll = () => {
setScrolled(window.scrollY > 50);
};
window.addEventListener('scroll', handleScroll);
return () => window.removeEventListener('scroll', handleScroll);
}, []);
return (
<header
className={`fixed top-0 w-full z-50 transition-all duration-500 ${scrolled
? 'bg-white/80 dark:bg-black/80 backdrop-blur-xl py-2 border-b border-stone-200/50 dark:border-stone-800/50'
: 'bg-transparent py-6'
}`}
>
<div className="max-w-[1920px] mx-auto px-6 md:px-12">
<div className="flex justify-between items-center h-20">
{/* Mobile Menu Button */}
<div className="flex items-center md:hidden">
<button
className="text-text-main dark:text-white p-2 hover:bg-stone-100 dark:hover:bg-stone-800 rounded-full transition-colors"
type="button"
onClick={() => setIsMenuOpen(!isMenuOpen)}
>
<span className="material-symbols-outlined">menu</span>
</button>
</div>
{/* Logo */}
<div className="flex-shrink-0 relative group cursor-pointer">
<Link className="font-display text-4xl md:text-5xl font-light tracking-widest uppercase text-text-main dark:text-white" to="/">
HOTCHPOTSH
</Link>
{/* Subtle glow effect on hover */}
<div className="absolute -inset-4 bg-white/20 blur-xl opacity-0 group-hover:opacity-100 transition-opacity duration-500 rounded-full" />
</div>
{/* Desktop Nav */}
<nav className="hidden md:flex space-x-12">
{NAV_ITEMS.map((item) => (
<Link
key={item.label}
className="group relative text-xs uppercase tracking-[0.2em] text-text-main dark:text-white hover:text-black dark:hover:text-white transition-colors duration-300 py-2"
to={item.label === 'Collections' ? '/collections' : item.label === 'Atelier' ? '/atelier' : '/editorial'}
>
{item.label}
{/* Underline Reveal Animation */}
<span className="absolute bottom-0 left-0 w-0 h-[1px] bg-black dark:bg-white transition-all duration-300 group-hover:w-full" />
</Link>
))}
</nav>
{/* Icons */}
<div className="flex items-center space-x-6 text-text-main dark:text-white">
<button className="hover:scale-110 transition-transform duration-300 hidden sm:block p-2">
<span className="material-symbols-outlined text-xl font-light">search</span>
</button>
<a className="hover:scale-110 transition-transform duration-300 relative group p-2" href="#">
<span className="material-symbols-outlined text-xl font-light">shopping_bag</span>
<span className="absolute top-0 right-0 bg-black dark:bg-white text-white dark:text-black text-[9px] w-4 h-4 flex items-center justify-center rounded-full opacity-0 scale-50 group-hover:opacity-100 group-hover:scale-100 transition-all duration-300">2</span>
</a>
</div>
</div>
</div>
{/* Mobile Menu Overlay */}
<AnimatePresence>
{isMenuOpen && (
<motion.div
initial={{ opacity: 0, height: 0 }}
animate={{ opacity: 1, height: 'auto' }}
exit={{ opacity: 0, height: 0 }}
className="md:hidden absolute top-full left-0 w-full bg-white/95 dark:bg-black/95 backdrop-blur-xl border-b border-stone-200 dark:border-stone-800 shadow-2xl overflow-hidden"
>
<div className="flex flex-col p-8 space-y-6">
{NAV_ITEMS.map((item, idx) => (
<Link
key={item.label}
to={item.label === 'Collections' ? '/collections' : item.label === 'Atelier' ? '/atelier' : '/editorial'}
className="text-lg uppercase tracking-[0.2em] text-text-main dark:text-white hover:pl-4 transition-all duration-300 border-l-2 border-transparent hover:border-black dark:hover:border-white"
onClick={() => setIsMenuOpen(false)}
>
<motion.span
initial={{ x: -20, opacity: 0 }}
animate={{ x: 0, opacity: 1 }}
transition={{ delay: idx * 0.1 }}
>
{item.label}
</motion.span>
</Link>
))}
</div>
</motion.div>
)}
</AnimatePresence>
</header>
);
};
export default Header;