Initial commit of project structure
This commit is contained in:
109
Pottery-website/components/Header.tsx
Normal file
109
Pottery-website/components/Header.tsx
Normal file
@@ -0,0 +1,109 @@
|
||||
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;
|
||||
Reference in New Issue
Block a user