first commit
This commit is contained in:
@@ -0,0 +1,163 @@
|
||||
"use client";
|
||||
|
||||
import { motion, AnimatePresence, useScroll } from "framer-motion";
|
||||
import { useState, useEffect } from "react";
|
||||
import Link from "next/link";
|
||||
import { usePathname } from "next/navigation";
|
||||
import type { Locale } from "@/i18n-config";
|
||||
|
||||
const expo = [0.16, 1, 0.3, 1] as [number, number, number, number];
|
||||
|
||||
export default function Header({ lang, dict }: { lang: Locale; dict: any }) {
|
||||
const [menuOpen, setMenuOpen] = useState(false);
|
||||
const [scrolled, setScrolled] = useState(false);
|
||||
const pathname = usePathname();
|
||||
|
||||
const { scrollY } = useScroll();
|
||||
|
||||
useEffect(() => {
|
||||
const unsub = scrollY.on("change", (v) => setScrolled(v > 40));
|
||||
return () => unsub();
|
||||
}, [scrollY]);
|
||||
|
||||
const links = [
|
||||
{ name: dict.services, href: `/${lang}/services` },
|
||||
{ name: dict.work, href: `/${lang}/work` },
|
||||
{ name: dict.process, href: `/${lang}/process` },
|
||||
{ name: dict.blog, href: `/${lang}/blog` },
|
||||
{ name: dict.partners, href: `/${lang}/partners` },
|
||||
{ name: dict.faq, href: `/${lang}/faq` },
|
||||
];
|
||||
|
||||
const otherLang = lang === "tr" ? "en" : "tr";
|
||||
|
||||
return (
|
||||
<>
|
||||
<motion.header
|
||||
className={`fixed top-0 left-0 right-0 z-50 transition-all duration-300 ${
|
||||
scrolled
|
||||
? "bg-[#F4F0E8]/90 backdrop-blur-md border-b border-[#C8C2B8]"
|
||||
: "bg-transparent"
|
||||
}`}
|
||||
initial={{ y: -80, opacity: 0 }}
|
||||
animate={{ y: 0, opacity: 1 }}
|
||||
transition={{ duration: 0.8, ease: expo }}
|
||||
>
|
||||
<div className="max-w-7xl mx-auto px-6 h-16 flex items-center justify-between">
|
||||
|
||||
{/* Logo */}
|
||||
<Link href={`/${lang}`} className="flex items-center gap-3 cursor-pointer group">
|
||||
<div className="w-8 h-8 bg-[#FFE600] border-2 border-[#0A0A0A] flex items-center justify-center font-display font-black text-[13px] text-[#0A0A0A] group-hover:bg-[#FF4500] transition-colors duration-200">
|
||||
A
|
||||
</div>
|
||||
<span className="font-display font-black tracking-tight text-[15px] text-[#0A0A0A] uppercase">
|
||||
{dict.brandName}<span className="text-[#A0998E] font-medium">{dict.brandSub}</span>
|
||||
</span>
|
||||
</Link>
|
||||
|
||||
{/* Desktop nav */}
|
||||
<nav className="hidden md:flex items-center gap-8">
|
||||
{links.map(item => {
|
||||
const isActive = pathname === item.href;
|
||||
return (
|
||||
<Link
|
||||
key={item.name}
|
||||
href={item.href}
|
||||
className={`font-mono text-[10px] tracking-[0.2em] uppercase transition-colors duration-200 ${
|
||||
isActive ? "text-[#0A0A0A] font-bold" : "text-[#A0998E] hover:text-[#0A0A0A]"
|
||||
}`}
|
||||
>
|
||||
{item.name}
|
||||
</Link>
|
||||
);
|
||||
})}
|
||||
</nav>
|
||||
|
||||
{/* Right: lang + CTA */}
|
||||
<div className="hidden md:flex items-center gap-4">
|
||||
<Link
|
||||
href={pathname.replace(`/${lang}`, `/${otherLang}`)}
|
||||
className="font-mono text-[10px] tracking-[0.2em] uppercase text-[#A0998E] hover:text-[#0A0A0A] transition-colors duration-200 border border-[#C8C2B8] hover:border-[#0A0A0A] px-3 py-2"
|
||||
>
|
||||
{otherLang.toUpperCase()}
|
||||
</Link>
|
||||
<Link
|
||||
href={`/${lang}/contact`}
|
||||
className="btn-brutal btn-brutal-yellow flex items-center gap-2 px-5 py-2.5 font-display font-black text-[11px] tracking-widest uppercase cursor-pointer"
|
||||
>
|
||||
{dict.quote}
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
{/* Mobile hamburger */}
|
||||
<button
|
||||
className="md:hidden flex flex-col justify-center items-center gap-1.5 w-10 h-10 cursor-pointer border border-[#C8C2B8] hover:border-[#0A0A0A] transition-colors"
|
||||
onClick={() => setMenuOpen(!menuOpen)}
|
||||
aria-label="Toggle Menu"
|
||||
>
|
||||
<motion.span
|
||||
className="h-[1.5px] w-5 bg-[#0A0A0A] block"
|
||||
animate={{ rotate: menuOpen ? 45 : 0, y: menuOpen ? 4.5 : 0 }}
|
||||
transition={{ duration: 0.2 }}
|
||||
/>
|
||||
<motion.span
|
||||
className="h-[1.5px] w-5 bg-[#0A0A0A] block"
|
||||
animate={{ opacity: menuOpen ? 0 : 1, scaleX: menuOpen ? 0 : 1 }}
|
||||
transition={{ duration: 0.2 }}
|
||||
/>
|
||||
<motion.span
|
||||
className="h-[1.5px] w-5 bg-[#0A0A0A] block"
|
||||
animate={{ rotate: menuOpen ? -45 : 0, y: menuOpen ? -4.5 : 0 }}
|
||||
transition={{ duration: 0.2 }}
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
</motion.header>
|
||||
|
||||
{/* Mobile menu overlay */}
|
||||
<AnimatePresence>
|
||||
{menuOpen && (
|
||||
<motion.div
|
||||
className="fixed inset-0 z-40 bg-[#F4F0E8] flex flex-col"
|
||||
initial={{ clipPath: "inset(0 0 100% 0)" }}
|
||||
animate={{ clipPath: "inset(0 0 0% 0)" }}
|
||||
exit={{ clipPath: "inset(0 0 100% 0)" }}
|
||||
transition={{ duration: 0.5, ease: expo }}
|
||||
>
|
||||
<div className="max-w-7xl mx-auto px-6 pt-20 pb-12 flex flex-col h-full">
|
||||
<nav className="flex flex-col gap-1 flex-1 justify-center">
|
||||
{links.map((item, idx) => (
|
||||
<motion.div
|
||||
key={item.name}
|
||||
initial={{ x: -30, opacity: 0 }}
|
||||
animate={{ x: 0, opacity: 1 }}
|
||||
exit={{ x: -30, opacity: 0 }}
|
||||
transition={{ delay: idx * 0.07, duration: 0.4 }}
|
||||
>
|
||||
<Link
|
||||
href={item.href}
|
||||
className="block font-display font-black text-5xl uppercase text-[#C8C2B8] hover:text-[#0A0A0A] transition-colors duration-200 py-2"
|
||||
onClick={() => setMenuOpen(false)}
|
||||
>
|
||||
{item.name}
|
||||
</Link>
|
||||
</motion.div>
|
||||
))}
|
||||
</nav>
|
||||
|
||||
<div className="border-t border-[#C8C2B8] pt-8">
|
||||
<Link
|
||||
href={`/${lang}/contact`}
|
||||
className="btn-brutal btn-brutal-yellow inline-flex items-center gap-3 px-8 py-4 font-display font-black text-[13px] tracking-widest uppercase cursor-pointer"
|
||||
onClick={() => setMenuOpen(false)}
|
||||
>
|
||||
{dict.quote}
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
</motion.div>
|
||||
)}
|
||||
</AnimatePresence>
|
||||
</>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user