new web sayt
This commit is contained in:
117
components/Navbar.tsx
Normal file
117
components/Navbar.tsx
Normal file
@@ -0,0 +1,117 @@
|
||||
"use client";
|
||||
|
||||
import { useState } from "react";
|
||||
import Link from "next/link";
|
||||
import { usePathname } from "next/navigation";
|
||||
import { Menu, X } from "lucide-react";
|
||||
import { motion } from "framer-motion";
|
||||
import { useTranslations } from "next-intl";
|
||||
|
||||
interface NavLink {
|
||||
id: string;
|
||||
labelKey: string;
|
||||
href: string;
|
||||
}
|
||||
|
||||
interface NavbarProps {
|
||||
logoText?: string;
|
||||
}
|
||||
|
||||
export function Navbar({ logoText = "FIRMA" }: NavbarProps) {
|
||||
const [isOpen, setIsOpen] = useState(false);
|
||||
const t = useTranslations();
|
||||
const pathname = usePathname();
|
||||
|
||||
const navLinks: NavLink[] = [
|
||||
{ id: "about", labelKey: "nav.about", href: "#about" },
|
||||
{ id: "products", labelKey: "nav.products", href: "#products" },
|
||||
{ id: "faq", labelKey: "nav.faq", href: "#faq" },
|
||||
{ id: "contact", labelKey: "nav.contact", href: "#contact" },
|
||||
];
|
||||
|
||||
const locale = pathname.split("/")[1];
|
||||
const otherLocale = locale === "uz" ? "ru" : "uz";
|
||||
const otherPath = pathname.replace(`/${locale}`, `/${otherLocale}`);
|
||||
|
||||
const handleScroll = (href: string) => {
|
||||
if (href.startsWith("#")) {
|
||||
const element = document.querySelector(href);
|
||||
if (element) {
|
||||
element.scrollIntoView({ behavior: "smooth" });
|
||||
}
|
||||
}
|
||||
setIsOpen(false);
|
||||
};
|
||||
|
||||
return (
|
||||
<nav className="sticky top-0 z-50 bg-white/80 backdrop-blur-md border-b border-gray-200">
|
||||
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<div className="flex justify-between items-center h-16">
|
||||
{/* Logo */}
|
||||
<motion.div whileHover={{ scale: 1.05 }} whileTap={{ scale: 0.95 }}>
|
||||
<Link
|
||||
href={`/${locale}`}
|
||||
className="text-2xl font-bold bg-gradient-to-r from-blue-600 to-blue-800 bg-clip-text text-transparent"
|
||||
>
|
||||
{logoText}
|
||||
</Link>
|
||||
</motion.div>
|
||||
|
||||
{/* Desktop Menu */}
|
||||
<div className="hidden md:flex items-center gap-8">
|
||||
{navLinks.map((link) => (
|
||||
<motion.button
|
||||
key={link.id}
|
||||
whileHover={{ color: "#2563eb" }}
|
||||
onClick={() => handleScroll(link.href)}
|
||||
className="text-gray-700 hover:text-blue-600 transition-colors"
|
||||
>
|
||||
{t(link.labelKey)}
|
||||
</motion.button>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* Language & Mobile Menu */}
|
||||
<div className="flex items-center gap-4">
|
||||
<motion.a
|
||||
href={otherPath}
|
||||
whileHover={{ scale: 1.1 }}
|
||||
whileTap={{ scale: 0.95 }}
|
||||
className="px-3 py-1 bg-blue-600 text-white rounded-full text-sm font-medium hover:bg-blue-700 transition-colors"
|
||||
>
|
||||
{otherLocale.toUpperCase()}
|
||||
</motion.a>
|
||||
|
||||
{/* Mobile Menu Button */}
|
||||
<button
|
||||
onClick={() => setIsOpen(!isOpen)}
|
||||
className="md:hidden p-2 rounded-lg hover:bg-gray-100"
|
||||
>
|
||||
{isOpen ? <X size={24} /> : <Menu size={24} />}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Mobile Menu */}
|
||||
{isOpen && (
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: -10 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
exit={{ opacity: 0, y: -10 }}
|
||||
className="md:hidden pb-4 space-y-2"
|
||||
>
|
||||
{navLinks.map((link) => (
|
||||
<button
|
||||
key={link.id}
|
||||
onClick={() => handleScroll(link.href)}
|
||||
className="block w-full text-left px-4 py-2 text-gray-700 hover:bg-blue-50 rounded-lg transition-colors"
|
||||
>
|
||||
{t(link.labelKey)}
|
||||
</button>
|
||||
))}
|
||||
</motion.div>
|
||||
)}
|
||||
</div>
|
||||
</nav>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user