Files
parsshop/components/header.tsx
2026-04-07 10:14:56 +03:30

1450 lines
90 KiB
TypeScript
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"use client";
import React, { useState, useEffect, useRef } from 'react';
import { usePathname, useRouter } from 'next/navigation';
import Link from 'next/link';
import Image from 'next/image';
import { ShoppingCart, Trash2, Search, X, ChevronDown, Home, ShoppingBag, Wallet, MapPin, Headphones, IdCard, LogOut } from "lucide-react";
import { useCart } from './context/cartcontext';
import { products } from '@/lib/data';
import '@/public/src/css/header.css';
import { registerUser } from '@/public/src/services/auth/api';
import { loginUser } from '@/public/src/services/auth/api';
import { logoutUser } from '@/public/src/services/auth/api';
import { useCategories } from './context/categoryprovider';
import { getCartApi } from '@/public/src/services/cart/api';
const topBarLinks = [
{ label: "بخش صنعتی", href: "/" },
{ label: "بخش خودرویی", href: "/automotive" },
];
const mainNavLinks = [
{ label: "صفحه اصلی", href: "/" },
{ label: "محصولات", href: "/products" },
{ label: "مقالات", href: "/blog" },
{ label: "درباره ما", href: "/about" },
{ label: "تماس با ما", href: "/contact" },
];
type FloatingInputProps = {
name?: string;
value: string;
onChange: (e: React.ChangeEvent<HTMLInputElement>) => void;
label: string;
type?: string;
dir?: "rtl" | "ltr";
inputMode?: React.HTMLAttributes<HTMLInputElement>["inputMode"];
autoComplete?: string;
className?: string;
leftSlot?: React.ReactNode;
rightSlot?: React.ReactNode;
};
function FloatingInput({
name,
value,
onChange,
label,
type = "text",
dir = "rtl",
inputMode,
autoComplete,
className = "",
leftSlot,
rightSlot,
}: FloatingInputProps) {
const hasLeftSlot = Boolean(leftSlot);
const hasRightSlot = Boolean(rightSlot);
return (
<label className="relative block w-full">
{leftSlot ? (
<div className="pointer-events-none absolute left-4 top-1/2 z-10 -translate-y-1/2">
{leftSlot}
</div>
) : null}
{rightSlot ? (
<div className="absolute right-4 top-1/2 z-10 -translate-y-1/2">
{rightSlot}
</div>
) : null}
<input
name={name}
value={value}
onChange={onChange}
type={type}
dir={dir}
inputMode={inputMode}
autoComplete={autoComplete}
placeholder=" "
className={`peer w-full rounded-2xl border border-gray-200 bg-gray-50 py-4 text-sm text-[#1A2332] outline-none transition placeholder:text-gray-400 focus:border-[#ffb900] focus:bg-white ${hasLeftSlot ? "pl-24" : "pl-4"} ${hasRightSlot ? "pr-12" : "pr-4"} ${className}`}
/>
<span
className={`pointer-events-none absolute top-4 z-10 origin-right rounded-full bg-white px-2 text-sm text-gray-400 transition-all duration-200 peer-focus:top-0 peer-focus:-translate-y-1/2 peer-focus:scale-90 peer-focus:text-[#1A2332] peer-[:not(:placeholder-shown)]:top-0 peer-[:not(:placeholder-shown)]:-translate-y-1/2 peer-[:not(:placeholder-shown)]:scale-90 ${hasRightSlot ? "right-12" : "right-3"}`}
>
{label}
</span>
</label>
);
}
function IranPhoneAdornment() {
return (
<div dir="ltr" className="flex items-center gap-2 text-sm text-gray-500">
<span className="text-base leading-none">🇮🇷</span>
<span className="font-medium">+98</span>
</div>
);
}
const dashboardMenuItems = [
{ id: "dash", label: "پیشخوان", icon: Home, href: "/dashboard?tab=dash" },
{ id: "orders", label: "سفارش‌های من", icon: ShoppingBag, href: "/dashboard?tab=orders" },
{ id: "wallet", label: "کیف پول", icon: Wallet, href: "/dashboard?tab=wallet" },
{ id: "address", label: "آدرس‌ها", icon: MapPin, href: "/dashboard?tab=address" },
{ id: "tickets", label: "تیکت پشتیبانی", icon: Headphones, href: "/dashboard?tab=tickets" },
{ id: "profile", label: "مشخصات حساب", icon: IdCard, href: "/dashboard?tab=profile" },
];
export function Header() {
const [menuOpen, setMenuOpen] = useState(false);
const pathname = usePathname();
const { cart, removeFromCart } = useCart();
const [searchTerm, setSearchTerm] = useState('');
const [showResults, setShowResults] = useState(false);
const [filteredProducts, setFilteredProducts] = useState<any[]>([]);
const searchRef = useRef<HTMLDivElement>(null);
const router = useRouter();
const [isOpen, setIsOpen] = useState(false);
const [formType, setFormType] = useState("mobile");
const [activeTab, setActiveTab] = useState("login");
const [registerError, setRegisterError] = useState("");
const [loginError, setLoginError] = useState("");
const [registerUsernameError, setRegisterUsernameError] = useState("");
const [loginUsernameError, setLoginUsernameError] = useState("");
const { rootCategories } = useCategories();
const [user, setUser] = useState<{ username: string; displayName: string } | null>(null);
const [userMenuOpen, setUserMenuOpen] = useState(false);
const [showPassword, setShowPassword] = useState(false);
const [showLoginPassword, setShowLoginPassword] = useState(false);
const [loginMobile, setLoginMobile] = useState("");
const [showRegisterSuccessDialog, setShowRegisterSuccessDialog] = useState(false);
const [isOptimistic, setIsOptimistic] = useState(false);
// ۱. افکت اول: وقتی کانتکست لوکال (cart) با کلیک کاربر آپدیت می‌شود،
// منو را به حالت Optimistic می‌بریم تا تغییرات را درجا نشان دهد.
useEffect(() => {
setIsOptimistic(true);
// بعد از ۱.۵ ثانیه (زمانی که قاعدتاً API سرور کارش تمام شده) به حالت عادی برمی‌گردد
const timer = setTimeout(() => setIsOptimistic(false), 1500);
return () => clearTimeout(timer);
}, [cart]);
// ۲. افکت دوم: دریافت اطلاعات سرور در پس‌زمینه بدون رفرش صفحه
useEffect(() => {
const fetchServerData = async () => {
const token = localStorage.getItem('accessToken');
if (token) {
setIsLoggedIn(true);
try {
const data = await getCartApi();
if (data) {
setServerCartItems(data.items || []);
setServerSummary(data.summary || null);
}
} catch (error) {
console.error("خطا در همگام‌سازی سبد خرید سرور:", error);
}
}
};
// گوش دادن به سیگنالی که از ProductCard ارسال می‌شود
window.addEventListener('cartUpdated', fetchServerData);
// فراخوانی در لود اولیه
fetchServerData();
return () => window.removeEventListener('cartUpdated', fetchServerData);
}, []);
// محاسبه قیمت کل لوکال (برای زمانی که کاربر لاگین نیست یا در حالت Optimistic هستیم)
const localTotalPrice = cart.reduce((total, item) => {
const price = item.price ? Number(item.price.toString().replace(/,/g, '')) : 0;
return total + (price * item.quantity);
}, 0);
const [loginForm, setLoginForm] = useState({
username: "",
password: "",
});
const [registerForm, setRegisterForm] = useState({
phone: "",
fullName: "",
username: "",
password: "",
});
const usernamePattern = /^[A-Za-z0-9]*$/;
const usernameErrorMessage = "نام کاربری فقط باید با حروف انگلیسی و عدد وارد شود";
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
if (e.target.name === "username") {
if (!usernamePattern.test(e.target.value)) {
setRegisterUsernameError(usernameErrorMessage);
return;
}
setRegisterUsernameError("");
}
setRegisterForm({
...registerForm,
[e.target.name]: e.target.value,
});
};
useEffect(() => {
const token = localStorage.getItem("accessToken");
const username = localStorage.getItem("username");
const fullName = localStorage.getItem("fullName");
if (token && username) {
setUser({ username, displayName: fullName || username });
}
}, []);
const handleRegister = async () => {
setRegisterError("");
const phone = registerForm.phone.trim();
const username = registerForm.username.trim();
const password = registerForm.password.trim();
const fullName = registerForm.fullName.trim();
if (!usernamePattern.test(username)) {
setRegisterUsernameError(usernameErrorMessage);
return;
}
// ✅ بررسی خالی بودن فیلدها
if (!phone || !username || !password || !fullName) {
setRegisterError("لطفاً فیلدها را پر کنید");
return;
}
try {
const payload = {
phone,
username,
password,
fullName,
};
const res = await registerUser(payload);
const role = res.data?.user?.role;
const displayName = res.data?.user?.fullName || fullName || username;
localStorage.setItem("accessToken", res.data.accessToken);
localStorage.setItem("refreshToken", res.data.refreshToken);
localStorage.setItem("username", username);
localStorage.setItem("fullName", displayName);
localStorage.setItem("role", role.toLowerCase());
console.log(res);
setUser({ username, displayName });
setIsOpen(false);
setShowRegisterSuccessDialog(true);
} catch (error: any) {
const message = error?.message?.toLowerCase() || "";
const usernameDuplicate = message.includes("username");
const phoneDuplicate = message.includes("phone");
if (usernameDuplicate && phoneDuplicate) {
setRegisterError("نام کاربری و شماره موبایل قبلاً ثبت شده‌اند");
}
else if (usernameDuplicate) {
setRegisterError("این نام کاربری قبلاً ثبت شده است");
}
else if (phoneDuplicate) {
setRegisterError("این شماره موبایل قبلاً ثبت شده است");
}
else {
setRegisterError("خطا در ثبت نام");
}
}
};
const handleLogin = async () => {
setLoginError("");
const username = loginForm.username.trim();
const password = loginForm.password.trim();
if (!usernamePattern.test(username)) {
setLoginUsernameError(usernameErrorMessage);
return;
}
if (!username || !password) {
setLoginError("لطفاً نام کاربری و رمز عبور را وارد کنید");
return;
}
try {
const res = await loginUser({ username, password });
const role = res.data?.user?.role;
const displayName = res.data?.user?.fullName || username;
localStorage.setItem("role", role.toLowerCase());
localStorage.setItem("accessToken", res.data.accessToken);
localStorage.setItem("refreshToken", res.data.refreshToken);
localStorage.setItem("username", username);
localStorage.setItem("fullName", displayName);
console.log(res);
setUser({ username, displayName });
setIsOpen(false);
router.push("/dashboard?success=login");
} catch (error: any) {
const msg = error?.message?.toLowerCase() || "";
console.log("LOGIN ERROR RAW:", msg); // این خیلی مهمه
// 1) اول بررسی کنیم که نام کاربری وجود ندارد
if (
msg.includes("not found") ||
msg.includes("user") && msg.includes("not") ||
msg.includes("username") && msg.includes("not")
) {
setLoginError("این نام کاربری وجود ندارد");
return;
}
// 2) سپس رمز عبور اشتباه
if (
msg.includes("password") ||
msg.includes("invalid") ||
msg.includes("incorrect")
) {
setLoginError("رمز عبور اشتباه است");
return;
}
// 3) خطای عمومی
setLoginError("خطا در ورود. لطفاً دوباره تلاش کنید.");
}
};
const clearAuthState = () => {
localStorage.removeItem("accessToken");
localStorage.removeItem("refreshToken");
localStorage.removeItem("username");
localStorage.removeItem("fullName");
localStorage.removeItem("role");
setUser(null);
};
const handleLogout = async () => {
const token = localStorage.getItem("accessToken");
try {
if (token) {
await logoutUser(token);
}
} catch (error) {
console.error("Logout failed:", error);
} finally {
clearAuthState();
setUserMenuOpen(false);
router.push("/");
}
};
const parsePrice = (priceStr?: number | null) => {
if (!priceStr) return 0;
return Number(priceStr.toString().replace(/,/g, ''));
};
const totalPrice = cart.reduce((total, item) => total + (parsePrice(item.price) * item.quantity), 0);
useEffect(() => {
const handleClickOutside = (event: MouseEvent) => {
if (searchRef.current && !searchRef.current.contains(event.target as Node)) {
setShowResults(false);
}
};
document.addEventListener('mousedown', handleClickOutside);
return () => document.removeEventListener('mousedown', handleClickOutside);
}, []);
useEffect(() => {
if (searchTerm.trim().length > 1) {
const results = products.filter(p =>
p.title.toLowerCase().includes(searchTerm.toLowerCase()) ||
p.brand?.toLowerCase().includes(searchTerm.toLowerCase()) ||
p.d?.toLowerCase().includes(searchTerm.toLowerCase()) ||
p.l?.toLowerCase().includes(searchTerm.toLowerCase())
).slice(0, 6);
setFilteredProducts(results);
setShowResults(true);
} else {
setFilteredProducts([]);
setShowResults(false);
}
}, [searchTerm]);
const handleSearch = (e: React.FormEvent) => {
e.preventDefault();
if (searchTerm.trim()) {
setShowResults(false);
router.push(`/search?q=${encodeURIComponent(searchTerm)}`);
}
};
const [isLoggedIn, setIsLoggedIn] = useState(false);
const [serverCartItems, setServerCartItems] = useState<any[]>([]);
const [serverSummary, setServerSummary] = useState<any>(null);
// // درون کامپوننت هدر شما
// useEffect(() => {
// const fetchServerData = async () => {
// const token = localStorage.getItem('accessToken');
// if (token) {
// setIsLoggedIn(true);
// try {
// const data = await getCartApi();
// if (data) {
// setServerCartItems(data.items || []);
// setServerSummary(data.summary || null);
// }
// } catch (error) {
// console.error("خطا در همگام‌سازی سبد خرید سرور:", error);
// }
// }
// };
// // --- این تابع جدید را اضافه کنید ---
// const handleCartClear = () => {
// setServerCartItems([]); // درجا لیست منو را خالی می‌کند
// setServerSummary(null);
// };
// // گوش دادن به رویدادها
// window.addEventListener('cartUpdated', fetchServerData);
// window.addEventListener('cartCleared', handleCartClear); // لیسنر جدید
// fetchServerData();
// return () => {
// window.removeEventListener('cartUpdated', fetchServerData);
// window.removeEventListener('cartCleared', handleCartClear); // کلین‌آپ لیسنر جدید
// };
// }, []);
// دریافت اطلاعات سبد خرید از سرور
useEffect(() => {
const fetchServerCart = async () => {
const token = localStorage.getItem('accessToken');
if (token) {
setIsLoggedIn(true);
try {
const data = await getCartApi();
if (data) {
setServerCartItems(data.items || []);
setServerSummary(data.summary || null);
}
} catch (error) {
console.error("خطا در دریافت سبد خرید منو:", error);
}
} else {
setIsLoggedIn(false);
}
};
// --- این تابع جدید را اضافه کنید ---
const handleCartClear = () => {
setServerCartItems([]); // درجا لیست منو را خالی می‌کند
setServerSummary(null);
};
// گوش دادن به رویدادها
window.addEventListener('cartUpdated', fetchServerCart);
window.addEventListener('cartCleared', handleCartClear); // لیسنر جدید
fetchServerCart();
return () => {
window.removeEventListener('cartUpdated', fetchServerCart);
window.removeEventListener('cartCleared', handleCartClear); // کلین‌آپ لیسنر جدید
};
// در صورت نیاز به آپدیت شدن دراپ‌داون با هر تغییر، می‌توانید این تابع را به یک Event یا Context متصل کنید
}, []);
// --- متغیرهای هوشمند برای جایگزینی در UI ---
// const displayCart = isLoggedIn
// ? serverCartItems.map(item => ({
// id: item.product?.id || item.productId,
// title: item.product?.title || "بدون نام",
// brand: item.product?.brand || "متفرقه",
// price: item.unitPrice || item.product?.price || 0,
// quantity: item.quantity || 1,
// image: item.product?.mainImageUrl || item.product?.image || "/placeholder.png"
// }))
// : cart; // cart از useCart() می‌آید
// const displayTotalQuantity = isLoggedIn && serverSummary
// ? serverSummary.totalQuantity || serverSummary.itemsCount || 0
// : cart.reduce((total, item) => total + item.quantity, 0);
// const displayTotalPrice = isLoggedIn && serverSummary
// ? serverSummary.totalPrice || serverSummary.total || 0
// : totalPrice;
// --- متغیرهای هوشمند اصلاح شده ---
// اگر لاگین باشیم و در لحظه‌ی کلیک (Optimistic) نباشیم، دیتای سرور را نشان می‌دهد
// در غیر این صورت (برای نمایش آنی) دیتای لوکال را نشان می‌دهد.
const displayCart = (isLoggedIn && !isOptimistic)
? serverCartItems.map(item => ({
id: item.product?.id || item.productId,
title: item.product?.title || "بدون نام",
brand: item.product?.brand || "متفرقه",
price: item.unitPrice || item.product?.price || 0,
quantity: item.quantity || 1,
image: item.product?.mainImageUrl || item.product?.image || "/placeholder.png"
}))
: cart;
const displayTotalQuantity = (isLoggedIn && !isOptimistic) && serverSummary
? serverSummary.totalQuantity || serverSummary.itemsCount || 0
: cart.reduce((total, item) => total + item.quantity, 0);
const displayTotalPrice = (isLoggedIn && !isOptimistic) && serverSummary
? serverSummary.totalPrice || serverSummary.total || 0
: localTotalPrice;
return (
<header>
<div>
{/* ... کدهای مربوط به mobile slider, top bar, main bar ... */}
{/* overlay */}
{menuOpen && (
<div
className="fixed inset-0 bg-black/40 z-40 md:hidden"
onClick={() => setMenuOpen(false)}
/>
)}
{/* mobile slider */}
<div
className={`fixed top-0 right-0 h-full w-[240px] max-w-[90vw] bg-white z-50 transform transition-transform duration-300 md:hidden
${menuOpen ? "translate-x-0" : "translate-x-full"}`}
>
<div className="p-6 flex flex-col gap-6">
{mainNavLinks.map((link) => (
<a
key={link.label}
href={link.href}
className="text-sm text-gray-700"
onClick={() => setMenuOpen(false)}
>
{link.label}
</a>
))}
<button className="inline-flex items-center justify-center px-6 py-2 rounded-xl border-1 border-[#ffb900] text-[#ffb900] text-xs tracking-wide focus:outline-none focus:ring-2 focus:ring-[#e6d3a3]/50">
استعلام قیمت
</button>
{/* mobile contact */}
<div className="mt-6 border-t pt-4 flex flex-col gap-4 md:hidden">
<div className="flex items-center gap-2 text-gray-700 text-xs">
<svg xmlns="http://www.w3.org/2000/svg" className="w-4 h-4 text-amber-400" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2}>
<path strokeLinecap="round" strokeLinejoin="round" d="M12 11.5a2.5 2.5 0 100-5 2.5 2.5 0 000 5z" />
<path strokeLinecap="round" strokeLinejoin="round" d="M19.5 11.5c0 6-7.5 10-7.5 10s-7.5-4-7.5-10a7.5 7.5 0 1115 0z" />
</svg>
<span className="whitespace-nowrap">شیراز، معالیآباد</span>
</div>
<a href="tel:07112345678" className="flex items-center gap-2 text-gray-700 hover:text-amber-500 transition text-xs">
<svg xmlns="http://www.w3.org/2000/svg" className="w-4 h-4 text-amber-400" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2}>
<path strokeLinecap="round" strokeLinejoin="round" d="M2.25 6.75c0 7.87 6.38 14.25 14.25 14.25.62 0 1.12-.5 1.12-1.12v-2.26c0-.53-.37-.99-.88-1.1l-2.77-.6a1.12 1.12 0 00-1.17.54l-.66 1.16a12.04 12.04 0 01-5.54-5.54l1.16-.66c.4-.23.6-.7.54-1.17l-.6-2.77a1.12 1.12 0 00-1.1-.88H3.37c-.62 0-1.12.5-1.12 1.12z" />
</svg>
<span dir="ltr">07112345678</span>
</a>
</div>
</div>
</div>
{/* top bar */}
<div className="bg-[#1a2332] text-white text-sm ">
<div className="container max-w-6xl mx-auto px-4 flex flex-wrap md:flex-nowrap justify-between items-center gap-2 md:gap-0">
{/* links */}
<div className="flex flex-wrap items-center gap-1 md:gap-4 w-full md:w-auto md:justify-start">
{topBarLinks.map((link) => {
// --- منطق جدید برای فعال بودن ---
let isActive = false;
if (link.href === "/automotive") {
// بخش خودرویی فقط زمانی فعال است که آدرس با /automotive شروع شود
isActive = pathname?.startsWith("/automotive");
} else if (link.href === "/") {
// بخش صنعتی در تمام صفحات (جز خودرویی) همیشه فعال می‌ماند
isActive = !pathname?.startsWith("/automotive");
}
// ---------------------------------
const baseClasses = "hover:text-amber-300 transition duration-200 px-3 md:px-6 py-2 text-xs";
const activeClasses = isActive ? "text-amber-400 border-t-2 border-amber-400 ac" : "text-white";
return (
<a
key={link.href}
href={link.href}
className={`${baseClasses} ${activeClasses}`}
>
{link.label}
</a>
);
})}
</div>
{/* contact */}
<div className="flex flex-wrap hidden md:flex md:flex-nowrap justify-center md:justify-end items-center gap-3 md:gap-6 text-sm text-white w-full md:w-auto">
<div className="flex items-center gap-2">
<svg xmlns="http://www.w3.org/2000/svg" className="w-4 h-4 text-amber-400" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2}>
<path strokeLinecap="round" strokeLinejoin="round" d="M12 11.5a2.5 2.5 0 100-5 2.5 2.5 0 000 5z" />
<path strokeLinecap="round" strokeLinejoin="round" d="M19.5 11.5c0 6-7.5 10-7.5 10s-7.5-4-7.5-10a7.5 7.5 0 1115 0z" />
</svg>
<span className="whitespace-nowrap text-xs">شیراز، معالیآباد</span>
</div>
<div>
<a href="tel:07112345678" className="flex items-center gap-2 hover:text-amber-300 transition">
<svg xmlns="http://www.w3.org/2000/svg" className="w-4 h-4 text-amber-400" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2}>
<path strokeLinecap="round" strokeLinejoin="round" d="M2.25 6.75c0 7.87 6.38 14.25 14.25 14.25.62 0 1.12-.5 1.12-1.12v-2.26c0-.53-.37-.99-.88-1.1l-2.77-.6a1.12 1.12 0 00-1.17.54l-.66 1.16a12.04 12.04 0 01-5.54-5.54l1.16-.66c.4-.23.6-.7.54-1.17l-.6-2.77a1.12 1.12 0 00-1.1-.88H3.37c-.62 0-1.12.5-1.12 1.12z" />
</svg>
<span className="whitespace-nowrap font-medium text-xs" dir="ltr">07112345678</span>
</a>
</div>
</div>
</div>
</div>
{/* main bar */}
<div className="bg-white border-b-2 border-b-[#f4f4f4] py-4">
<div className="container max-w-6xl mx-auto px-3 flex justify-between items-center flex-wrap gap-2 min-w-0">
{/* logo */}
<div className="items-center hidden md:flex md:order-1 order-2 space-x-2 rtl:space-x-reverse min-w-[100px] md:min-w-[150px]">
<div className="text-3xl font-bold text-green-500">B</div>
<span className="text-xl font-semibold text-[#1a2332]">Bearing Site</span>
</div>
{/* hamburger */}
<button className="md:hidden order-1" onClick={() => setMenuOpen(true)}>
<svg xmlns="http://www.w3.org/2000/svg" className="w-6 h-6 text-gray-800" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2}>
<path strokeLinecap="round" strokeLinejoin="round" d="M4 6h16M4 12h16M4 18h16" />
</svg>
</button>
{/* search */}
<div ref={searchRef} className="relative flex order-4 md:order-2 w-full md:w-[35%] min-w-0">
<form onSubmit={handleSearch} className="w-full">
<div className="flex flex-row-reverse w-full border border-gray-300 rounded-3xl overflow-hidden focus-within:ring-2 focus-within:ring-blue-500 bg-white shadow-sm transition-all">
<button type="submit" className="bg-gray-800 p-2.5 text-white hover:bg-gray-700 transition">
<Search size={20} />
</button>
<input
type="text"
placeholder="جستجوی قطعه، کد، یا دسته‌بندی..."
value={searchTerm}
onChange={(e) => setSearchTerm(e.target.value)}
onFocus={() => searchTerm.length > 1 && setShowResults(true)}
className="w-full p-3 text-gray-800 placeholder-gray-400 focus:outline-none text-xs font-medium"
/>
{searchTerm && (
<button
onClick={() => setSearchTerm('')}
className=" text-gray-400 mr-4 hover:text-gray-600"
>
<X size={14} />
</button>
)}
</div>
</form>
{/* دراپ‌داون نتایج لحظه‌ای */}
{showResults && filteredProducts.length > 0 && (
<div className="absolute top-full left-0 right-0 mt-2 bg-white border border-gray-200 rounded-2xl shadow-xl z-[100] overflow-hidden animate-in fade-in slide-in-from-top-2 duration-200">
<div className="p-2 flex flex-col">
{filteredProducts.map((product) => {
const productSlug = product.title.replace(/\s+/g, '-');
return (
<Link
key={product.id}
href={`/products/${product.id}/${encodeURIComponent(productSlug)}`}
onClick={() => setShowResults(false)}
className="flex items-center gap-3 p-2 hover:bg-gray-50 rounded-xl transition group"
>
<div className="bg-gray-100 p-1 rounded-lg shrink-0 w-10 h-10 flex items-center justify-center">
<Image src={product.image} alt={product.title} width={32} height={32} className="object-contain" />
</div>
<div className="flex-1 min-w-0 text-right">
<p className="text-[11px] font-bold text-gray-800 truncate group-hover:text-blue-600 transition-colors">{product.title}</p>
<p className="text-[9px] text-gray-500">{product.brand}</p>
</div>
<div className="text-[10px] font-bold text-gray-700 bg-gray-50 px-2 py-1 rounded-md shrink-0">
{product.price ? `${Number(product.price.toString().replace(/,/g, '')).toLocaleString('fa-IR')} ت` : 'استعلام'}
</div>
</Link>
);
})}
</div>
<button onClick={handleSearch} className="w-full bg-gray-50 py-2.5 text-[11px] text-blue-600 font-bold border-t border-gray-100 hover:bg-blue-50 transition-colors">
مشاهده تمام نتایج برای "{searchTerm}"
</button>
</div>
)}
</div>
{/* User/Cart Actions */}
<div className='flex items-center order-3 gap-2'>
{/* دراپ‌داون سبد خرید */}
<div className="relative group before:absolute before:-inset-x-5 before:-inset-y-3 before:content-['']">
<Link href="/cart" className="flex items-center justify-center p-2.5 bg-white border border-gray-300/60 rounded-xl text-gray-700 hover:bg-gray-50 transition relative z-10">
<ShoppingCart className="w-4 h-4 text-gray-500" strokeWidth={1.8} />
{displayCart.length > 0 && (
<span className="absolute -top-1.5 -right-1.5 bg-[#f92a35] text-white text-[10px] font-bold w-4 h-4 flex items-center justify-center rounded-full shadow-sm">
{displayTotalQuantity}
</span>
)}
</Link>
<div className="absolute top-full left-0 w-full h-3 bg-transparent hidden group-hover:block"></div>
<div className="absolute top-[calc(100%+12px)] left-0 w-80 bg-white border border-gray-200 rounded-2xl shadow-xl hidden group-hover:flex flex-col overflow-hidden z-50">
{displayCart.length === 0 ? (
<div className="p-6 text-center text-sm text-gray-500 flex flex-col items-center gap-2">
<ShoppingCart className="w-8 h-8 text-gray-200" />
<span>سبد خرید شما خالی است</span>
</div>
) : (
<>
<div className="flex justify-between items-center p-4 border-b border-gray-100 bg-gray-50/50">
<span className="text-xs font-semibold text-gray-500">{displayCart.length} کالا</span>
<Link href="/cart" className="text-xs text-blue-500 hover:text-blue-700 font-medium transition">مشاهده سبد خرید</Link>
</div>
<div className="max-h-64 overflow-y-auto p-2 flex flex-col gap-1 custom-scrollbar">
{displayCart.slice(0, 3).map((item) => {
const itemTotal = item.price ? (Number(item.price.toString().replace(/,/g, '')) * item.quantity).toLocaleString('fa-IR') : null;
return (
<div key={item.id} className="flex items-center gap-3 p-2 hover:bg-gray-50 rounded-xl transition group/item relative">
<div className="bg-white border border-gray-100 p-1 rounded-lg shrink-0">
<Image src={item.image} alt={item.title} width={40} height={40} className="object-contain w-10 h-10" />
</div>
<div className="flex-1 min-w-0">
<h4 className="text-xs font-semibold text-gray-800 truncate">{item.title}</h4>
<div className="flex items-center gap-2 mt-1">
<span className="text-[10px] text-gray-500 font-medium">{itemTotal ? `${itemTotal} تومان` : 'استعلام'}</span>
<span className="text-[9px] font-bold text-blue-600 bg-blue-50 px-1.5 py-0.5 rounded-md border border-blue-100">{item.quantity} عدد</span>
</div>
</div>
<button
onClick={(e) => { e.preventDefault(); e.stopPropagation(); removeFromCart(item.id); }}
className="text-gray-300 hover:text-red-500 transition p-1.5 opacity-0 group-hover/item:opacity-100"
title="حذف"
>
<Trash2 size={14} />
</button>
</div>
)
})}
{displayCart.length > 3 && (<p className="text-center text-[10px] text-gray-400 py-2 border-t border-gray-50 mt-1"> و {displayCart.length - 3} کالای دیگر...</p>)}
</div>
<div className="p-4 bg-white border-t border-gray-100">
<div className="flex justify-between items-center mb-3">
<span className="text-xs text-gray-500">مبلغ قابل پرداخت:</span>
<span className="text-sm font-bold text-gray-800">{displayTotalPrice > 0 ? `${displayTotalPrice.toLocaleString('fa-IR')} تومان` : 'استعلام'}</span>
</div>
<Link href="/cart" className="flex items-center justify-center w-full py-2 bg-[#ffb900] hover:bg-[#e6a600] text-black text-xs font-semibold rounded-xl transition-colors">ثبت سفارش</Link>
</div>
</>
)}
</div>
</div>
{!user ? (
<button
onClick={() => setIsOpen(true)}
className="flex cursor-pointer items-center gap-2 px-3 py-2.5 bg-white border border-gray-300/60 rounded-xl text-xs text-gray-700 hover:bg-gray-50 transition"
>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" className="w-4 h-4 text-gray-500">
<path strokeLinecap="round" strokeLinejoin="round" d="M15.75 6a3.75 3.75 0 11-7.5 0 3.75 3.75 0 017.5 0zM4.5 20.25a7.5 7.5 0 0115 0" />
</svg>
<span>ورود / عضویت</span>
</button>
) : (
<div className="relative">
<button
onClick={() => setUserMenuOpen((prev) => !prev)}
className="flex cursor-pointer items-center gap-2 px-3 py-2.5 bg-white border border-gray-300/60 rounded-xl text-xs text-gray-700 hover:bg-gray-50 transition"
>
<svg xmlns="http://www.w3.org/2000/svg" className="w-4 h-4 text-gray-500" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={1.8} d="M5.121 17.804A9 9 0 1118.879 17.804M15 11a3 3 0 11-6 0 3 3 0 016 0z" />
</svg>
<span>{user.displayName}</span>
<ChevronDown className={`h-3.5 w-3.5 text-gray-400 transition-transform ${userMenuOpen ? "rotate-180" : ""}`} />
</button>
{userMenuOpen && (
<div className="absolute z-100 left-0 mt-2 w-56 overflow-hidden rounded-2xl border border-gray-200 bg-white p-2 text-xs shadow-lg">
<div className="mb-2 border-b border-gray-100 px-3 pb-2 text-right">
<p className="font-semibold text-[#1A2332]">{user.displayName}</p>
<p className="mt-1 text-[11px] text-gray-500">دسترسی سریع به بخشهای پیشخوان</p>
</div>
<div className="flex flex-col gap-1">
{dashboardMenuItems.map((item) => (
<button
key={item.id}
onClick={() => {
setUserMenuOpen(false);
router.push(item.href);
}}
className="flex w-full cursor-pointer items-center gap-3 rounded-xl px-3 py-2.5 text-right text-gray-700 hover:bg-gray-50 hover:text-[#1A2332]"
>
<item.icon className="h-4 w-4 text-gray-400" />
<span>{item.label}</span>
</button>
))}
</div>
<div className="mt-2 border-t border-gray-100 pt-2">
<button
onClick={() => {
setUserMenuOpen(false);
handleLogout();
}}
className="flex w-full cursor-pointer items-center gap-3 rounded-xl px-3 py-2.5 text-right text-red-500 hover:bg-red-50"
>
<LogOut className="h-4 w-4" />
<span>خروج</span>
</button>
</div>
</div>
)}
</div>
)}
{isOpen && (
<div className="fixed inset-0 z-50 flex items-center justify-center p-4 bg-[#1A2332]/40 backdrop-blur-sm transition-opacity" dir="rtl">
<div
className="absolute inset-0"
onClick={() => setIsOpen(false)}
></div>
<div className="relative w-full max-w-sm bg-white rounded-3xl shadow-2xl p-8">
{/* دکمه بستن */}
<button
onClick={() => setIsOpen(false)}
className="absolute cursor-pointer top-4 left-5 text-gray-400 hover:text-gray-700 transition"
>
</button>
<div className="flex flex-col items-center mt-2 w-full">
{/* Tabs */}
<div className="flex w-full bg-gray-100 rounded-xl p-1 mb-6">
<button
onClick={() => setActiveTab("login")}
className={`flex-1 cursor-pointer py-2 text-sm rounded-lg transition ${activeTab === "login"
? "bg-white shadow text-[#1A2332] font-semibold"
: "text-gray-500"
}`}
>
ورود
</button>
<button
onClick={() => setActiveTab("register")}
className={`flex-1 cursor-pointer py-2 text-sm rounded-lg transition ${activeTab === "register"
? "bg-white shadow text-[#1A2332] font-semibold"
: "text-gray-500"
}`}
>
ثبت نام
</button>
</div>
{/* ---------------- LOGIN ---------------- */}
{activeTab === "login" && (
<div className="w-full space-y-5">
<div className="rounded-2xl border border-[#ffde7a] bg-[linear-gradient(135deg,#fff8dd_0%,#fffdf6_100%)] px-4 py-4 text-right">
<p className="text-base font-semibold text-[#1A2332]">ورود سریع به حساب کاربری</p>
<p className="mt-1 text-xs leading-6 text-gray-600">
سفارشها، وضعیت خرید و اطلاعات حسابتان را یکجا و بدون دردسر مدیریت کنید.
</p>
</div>
{formType === "mobile" && (
<div className="w-full space-y-4">
<FloatingInput
value={loginMobile}
onChange={(e) => setLoginMobile(e.target.value)}
type="tel"
dir="ltr"
inputMode="tel"
autoComplete="tel"
label="شماره موبایل"
className="text-left tracking-[0.18em]"
leftSlot={<IranPhoneAdornment />}
/>
<button className="w-full cursor-pointer rounded-2xl bg-[#ffb900] py-3.5 text-sm font-semibold text-[#1A2332] hover:bg-[#e5a600]">
ورود
</button>
<button
onClick={() => setFormType("password")}
className="w-full cursor-pointer text-xs text-gray-500 hover:text-[#1A2332]"
>
ورود با نام کاربری و رمز عبور
</button>
</div>
)}
{formType === "password" && (
<div className="w-full space-y-4">
<p className="text-xs leading-6 text-gray-500">
خوش برگشتی. برای ادامه، نام کاربری و رمز عبورت را وارد کن.
</p>
<FloatingInput
value={loginForm.username}
onChange={(e) => {
const username = e.target.value;
if (!usernamePattern.test(username)) {
setLoginUsernameError(usernameErrorMessage);
return;
}
setLoginUsernameError("");
setLoginForm((prev) => ({
...prev,
username,
}));
}}
type="text"
dir="ltr"
autoComplete="username"
label="نام کاربری"
className="text-left"
/>
{loginUsernameError && (
<div className="mt-1 text-right text-xs text-red-500">
{loginUsernameError}
</div>
)}
<FloatingInput
value={loginForm.password}
onChange={(e) => {
const password = e.target.value;
setLoginForm((prev) => ({
...prev,
password,
}));
if (!password) {
setShowLoginPassword(false);
}
}}
type={showLoginPassword ? "text" : "password"}
dir="ltr"
autoComplete="current-password"
label="رمز عبور"
className="text-left"
rightSlot={loginForm.password ? (
<button
type="button"
onClick={() => setShowLoginPassword(!showLoginPassword)}
className="cursor-pointer p-1 text-gray-500 hover:text-gray-700"
>
{showLoginPassword ? (
<svg xmlns="http://www.w3.org/2000/svg" className="h-5 w-5" fill="none"
viewBox="0 0 24 24" stroke="currentColor" strokeWidth="1.8">
<path strokeLinecap="round" strokeLinejoin="round"
d="M3 3l18 18M10.477 10.477A3 3 0 0113.5 13.5m-7.09-2.664A9.956 9.956 0 003 12s2.91-6 9-6a9.953 9.953 0 016.328 2.318M15.54 15.54A9.953 9.953 0 0112 18c-6.09 0-9-6-9-6a9.956 9.956 0 012.41-3.868" />
</svg>
) : (
<svg xmlns="http://www.w3.org/2000/svg" className="h-5 w-5" fill="none"
viewBox="0 0 24 24" stroke="currentColor" strokeWidth="1.8">
<path strokeLinecap="round" strokeLinejoin="round"
d="M2.458 12C3.732 7.943 7.523 5 12 5c4.477 0 8.268 2.943 9.542 7-1.274 4.057-5.065 7-9.542 7-4.477 0-8.268-2.943-9.542-7z" />
<path strokeLinecap="round" strokeLinejoin="round"
d="M15 12a3 3 0 11-6 0 3 3 0 016 0z" />
</svg>
)}
</button>
) : undefined}
/>
<button onClick={handleLogin} className="w-full cursor-pointer rounded-2xl bg-[#ffb900] py-3.5 text-sm font-semibold text-[#1A2332] hover:bg-[#e5a600]">
ورود
</button>
{loginError && (
<div className="mt-2 text-center text-sm text-red-500">
{loginError}
</div>
)}
<button
onClick={() => setFormType("mobile")}
className="w-full cursor-pointer text-xs text-gray-500 hover:text-[#1A2332]"
>
ورود با شماره موبایل
</button>
</div>
)}
</div>
)}
{false && activeTab === "login" && (
<div className="w-full">
{/* فرم موبایل */}
{formType === "mobile" && (
<div className="w-full space-y-4">
<input
type="tel"
placeholder="شماره موبایل"
className="w-full px-4 py-3.5 bg-gray-50 border border-gray-200 rounded-2xl text-sm text-right focus:outline-none focus:border-[#ffb900]"
/>
<button className="w-full cursor-pointer py-3.5 bg-[#ffb900] hover:bg-[#e5a600] text-[#1A2332] font-semibold rounded-2xl text-sm">
ورود
</button>
<button
onClick={() => setFormType("password")}
className="w-full cursor-pointer text-xs text-gray-500 hover:text-[#1A2332]"
>
ورود با نام کاربری و رمز عبور
</button>
</div>
)}
{/* فرم یوزر پس */}
{formType === "password" && (
<div className="w-full space-y-4">
<input
type="text"
value={loginForm.username}
onChange={(e) =>
setLoginForm((prev) => ({
...prev,
username: e.target.value,
}))
}
placeholder="نام کاربری"
className="w-full px-4 py-3.5 bg-gray-50 border border-gray-200 rounded-2xl text-sm text-right focus:outline-none focus:border-[#ffb900]"
/>
<div className="relative w-full">
<input
type={showLoginPassword ? "text" : "password"} // تغییر نوع بر اساس state
value={loginForm.password}
onChange={(e) =>
setLoginForm((prev) => ({
...prev,
password: e.target.value,
}))
}
placeholder="رمز عبور"
className="w-full px-4 pl-4 py-3.5 bg-gray-50 border border-gray-200 rounded-2xl text-sm text-right focus:outline-none focus:border-[#ffb900]"
/>
<button
type="button"
onClick={() => setShowLoginPassword(!showLoginPassword)}
className="absolute cursor-pointer left-4 top-1/2 -translate-y-1/2 text-gray-500 hover:text-gray-700 p-1" // پدینگ اضافه شد تا کلیک راحت‌تر باشد
>
{showLoginPassword ? (
// آیکون چشم خط خورده (eye-off)
<svg xmlns="http://www.w3.org/2000/svg" className="w-5 h-5" fill="none"
viewBox="0 0 24 24" stroke="currentColor" strokeWidth="1.8">
<path strokeLinecap="round" strokeLinejoin="round"
d="M3 3l18 18M10.477 10.477A3 3 0 0113.5 13.5m-7.09-2.664A9.956 9.956 0 003 12s2.91-6 9-6a9.953 9.953 0 016.328 2.318M15.54 15.54A9.953 9.953 0 0112 18c-6.09 0-9-6-9-6a9.956 9.956 0 012.41-3.868" />
</svg>
) : (
// آیکون چشم باز (eye)
<svg xmlns="http://www.w3.org/2000/svg" className="w-5 h-5" fill="none"
viewBox="0 0 24 24" stroke="currentColor" strokeWidth="1.8">
<path strokeLinecap="round" strokeLinejoin="round"
d="M2.458 12C3.732 7.943 7.523 5 12 5c4.477 0 8.268 2.943 9.542 7-1.274 4.057-5.065 7-9.542 7-4.477 0-8.268-2.943-9.542-7z" />
<path strokeLinecap="round" strokeLinejoin="round"
d="M15 12a3 3 0 11-6 0 3 3 0 016 0z" />
</svg>
)}
</button>
</div>
<button onClick={handleLogin} className="w-full cursor-pointer py-3.5 bg-[#ffb900] hover:bg-[#e5a600] text-[#1A2332] font-semibold rounded-2xl text-sm">
ورود
</button>
{loginError && (
<div className="text-red-500 text-sm text-center mt-2">
{loginError}
</div>
)}
<button
onClick={() => setFormType("mobile")}
className="w-full cursor-pointer text-xs text-gray-500 hover:text-[#1A2332]"
>
ورود با شماره موبایل
</button>
</div>
)}
</div>
)}
{/* ---------------- REGISTER ---------------- */}
{activeTab === "register" && (
<div className="w-full space-y-4">
<div className="rounded-2xl border border-gray-200 bg-gray-50 px-4 py-4 text-right">
<p className="text-base font-semibold text-[#1A2332]">چند قدم تا شروع خرید هوشمند</p>
<p className="mt-1 text-xs leading-6 text-gray-600">
با ساخت حساب، پیگیری سفارشها و دسترسی سریع به سبد خرید همیشه همراهت میماند.
</p>
</div>
<FloatingInput
name="phone"
value={registerForm.phone}
onChange={handleChange}
type="tel"
dir="ltr"
inputMode="tel"
autoComplete="tel"
label="شماره موبایل"
className="text-left tracking-[0.18em]"
leftSlot={<IranPhoneAdornment />}
/>
<FloatingInput
name="fullName"
value={registerForm.fullName}
onChange={handleChange}
type="text"
autoComplete="name"
label="نام و نام خانوادگی"
/>
<FloatingInput
name="username"
value={registerForm.username}
onChange={handleChange}
type="text"
dir="ltr"
autoComplete="username"
label="نام کاربری"
className="text-left"
/>
{registerUsernameError && (
<div className="mt-1 text-right text-xs text-red-500">
{registerUsernameError}
</div>
)}
<FloatingInput
name="password"
value={registerForm.password}
onChange={(e) => {
handleChange(e);
if (!e.target.value) {
setShowPassword(false);
}
}}
type={showPassword ? "text" : "password"}
dir="ltr"
autoComplete="new-password"
label="رمز عبور"
className="text-left"
rightSlot={registerForm.password ? (
<button
type="button"
onClick={() => setShowPassword(!showPassword)}
className="cursor-pointer text-gray-500 hover:text-gray-700"
>
{showPassword ? (
<svg xmlns="http://www.w3.org/2000/svg" className="h-5 w-5" fill="none"
viewBox="0 0 24 24" stroke="currentColor" strokeWidth="1.8">
<path strokeLinecap="round" strokeLinejoin="round"
d="M3 3l18 18M10.477 10.477A3 3 0 0113.5 13.5m-7.09-2.664A9.956 9.956 0 003 12s2.91-6 9-6a9.953 9.953 0 016.328 2.318M15.54 15.54A9.953 9.953 0 0112 18c-6.09 0-9-6-9-6a9.956 9.956 0 012.41-3.868" />
</svg>
) : (
<svg xmlns="http://www.w3.org/2000/svg" className="h-5 w-5" fill="none"
viewBox="0 0 24 24" stroke="currentColor" strokeWidth="1.8">
<path strokeLinecap="round" strokeLinejoin="round"
d="M2.458 12C3.732 7.943 7.523 5 12 5c4.477 0 8.268 2.943 9.542 7-1.274 4.057-5.065 7-9.542 7-4.477 0-8.268-2.943-9.542-7z" />
<path strokeLinecap="round" strokeLinejoin="round"
d="M15 12a3 3 0 11-6 0 3 3 0 016 0z" />
</svg>
)}
</button>
) : undefined}
/>
<p className="text-xs leading-6 text-gray-500">
با ثبتنام، تجربه خرید سریعتر و دسترسی راحتتر به حساب کاربری برایت فعال میشود.
</p>
<button
onClick={handleRegister}
className="w-full cursor-pointer rounded-2xl bg-[#ffb900] py-3.5 text-sm font-semibold text-[#1A2332] hover:bg-[#e5a600]"
>
ثبت نام
</button>
{registerError && (
<div className="mt-2 text-center text-sm text-red-500">
{registerError}
</div>
)}
</div>
)}
{false && activeTab === "register" && (
<div className="w-full space-y-4">
<input
name="phone"
value={registerForm.phone}
onChange={handleChange}
type="tel"
placeholder="شماره موبایل"
className="w-full px-4 py-3.5 bg-gray-50 border border-gray-200 rounded-2xl text-sm text-right focus:outline-none focus:border-[#ffb900]"
/>
<input
name="fullName"
value={registerForm.fullName}
onChange={handleChange}
type="text"
placeholder="نام"
className="w-full px-4 py-3.5 bg-gray-50 border border-gray-200 rounded-2xl text-sm text-right focus:outline-none focus:border-[#ffb900]"
/>
<input
name="username"
value={registerForm.username}
onChange={handleChange}
type="text"
placeholder="نام کاربری"
className='w-full px-4 py-3.5 bg-gray-50 border border-gray-200 rounded-2xl text-sm text-right focus:outline-none focus:border-[#ffb900]'
/>
<div className="relative w-full">
<input
name="password"
value={registerForm.password}
onChange={handleChange}
type={showPassword ? "text" : "password"}
placeholder="رمز عبور"
className="w-full px-4 py-3.5 bg-gray-50 border border-gray-200 rounded-2xl text-sm text-right focus:outline-none focus:border-[#ffb900]"
/>
<button
type="button"
onClick={() => setShowPassword(!showPassword)}
className="absolute cursor-pointer left-4 top-1/2 -translate-y-1/2 text-gray-500 hover:text-gray-700"
>
{showPassword ? (
// eye-off icon
<svg xmlns="http://www.w3.org/2000/svg" className="w-5 h-5" fill="none"
viewBox="0 0 24 24" stroke="currentColor" strokeWidth="1.8">
<path strokeLinecap="round" strokeLinejoin="round"
d="M3 3l18 18M10.477 10.477A3 3 0 0113.5 13.5m-7.09-2.664A9.956 9.956 0 003 12s2.91-6 9-6a9.953 9.953 0 016.328 2.318M15.54 15.54A9.953 9.953 0 0112 18c-6.09 0-9-6-9-6a9.956 9.956 0 012.41-3.868" />
</svg>
) : (
// eye icon
<svg xmlns="http://www.w3.org/2000/svg" className="w-5 h-5" fill="none"
viewBox="0 0 24 24" stroke="currentColor" strokeWidth="1.8">
<path strokeLinecap="round" strokeLinejoin="round"
d="M2.458 12C3.732 7.943 7.523 5 12 5c4.477 0 8.268 2.943 9.542 7-1.274 4.057-5.065 7-9.542 7-4.477 0-8.268-2.943-9.542-7z" />
<path strokeLinecap="round" strokeLinejoin="round"
d="M15 12a3 3 0 11-6 0 3 3 0 016 0z" />
</svg>
)}
</button>
</div>
{/* <input
name="confirmPassword"
value={registerForm.confirmPassword}
onChange={handleChange}
type="password"
placeholder="تکرار رمز عبور"
className="w-full px-4 py-3.5 bg-gray-50 border border-gray-200 rounded-2xl text-sm text-right focus:outline-none focus:border-[#ffb900]"
/> */}
<button
onClick={handleRegister}
className="w-full cursor-pointer py-3.5 bg-[#ffb900] hover:bg-[#e5a600] text-[#1A2332] font-semibold rounded-2xl text-sm"
>
ثبت نام
</button>
{registerError && (
<div className="text-red-500 text-sm text-center mt-2">
{registerError}
</div>
)}
</div>
)}
</div>
</div>
</div>
)}
{showRegisterSuccessDialog && (
<div className="fixed inset-0 z-[60] flex items-center justify-center bg-[#1A2332]/45 p-4 backdrop-blur-sm" dir="rtl">
<div
className="absolute inset-0"
onClick={() => setShowRegisterSuccessDialog(false)}
></div>
<div className="relative w-full max-w-sm rounded-3xl bg-white p-8 shadow-2xl">
<button
onClick={() => setShowRegisterSuccessDialog(false)}
className="absolute left-5 top-4 cursor-pointer text-gray-400 transition hover:text-gray-700"
>
<X className="h-5 w-5" />
</button>
<div className="text-right">
<div className="mb-5 flex h-14 w-14 items-center justify-center rounded-2xl bg-[#fff4cc] text-[#c78a00]">
<svg xmlns="http://www.w3.org/2000/svg" className="h-7 w-7" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth="1.8">
<path strokeLinecap="round" strokeLinejoin="round" d="M5 13l4 4L19 7" />
</svg>
</div>
<h3 className="text-xl font-bold text-[#1A2332]">تشکر از ثبت نام</h3>
<p className="mt-2 text-sm leading-7 text-gray-600">
حساب کاربری شما با موفقیت ساخته شد. حالا میتوانید وارد پیشخوان کاربری شوید و اطلاعات حساب و سفارشها را مدیریت کنید.
</p>
<div className="mt-6 flex flex-col gap-3">
<Link
href="/dashboard"
onClick={() => setShowRegisterSuccessDialog(false)}
className="flex items-center justify-center rounded-2xl bg-[#ffb900] px-4 py-3 text-sm font-semibold text-[#1A2332] hover:bg-[#e5a600]"
>
ورود به پیشخوان کاربری
</Link>
<button
onClick={() => setShowRegisterSuccessDialog(false)}
className="rounded-2xl border border-gray-200 px-4 py-3 text-sm font-medium text-gray-600 hover:bg-gray-50"
>
بستن
</button>
</div>
</div>
</div>
</div>
)}
</div>
</div>
</div>
{/* nav -- این بخش تغییر کرده است */}
<div className='justify-center flex'>
<div className='flex max-w-6xl container mx-auto px-4 justify-between py-2 items-center'>
<nav className="hidden md:flex items-center space-x-6 rtl:space-x-4 text-gray-700 text-xs w-full lg:w-auto lg:order-none">
{/* لینک صفحه اصلی */}
<Link href="/" className="hover:text-blue-600 transition duration-200 font-medium">صفحه اصلی</Link>
<div className="relative group">
<div className="flex items-center gap-1 cursor-pointer hover:text-blue-600 transition duration-200 font-medium">
<span>دسته بندی محصولات</span>
<ChevronDown size={14} className="transition-transform duration-200 group-hover:rotate-180" />
</div>
<div className="absolute top-full right-0 w-full h-4 bg-transparent hidden group-hover:block"></div>
<div className="absolute top-[calc(100%+16px)] right-0 w-56 bg-white border border-gray-200 rounded-xl shadow-lg p-2 opacity-0 invisible group-hover:opacity-100 group-hover:visible transition-all duration-200 flex flex-col gap-1 z-50">
{rootCategories.map(cat => (
<Link className='className="block w-full text-right px-3 py-2 text-xs font-medium text-gray-600 hover:bg-gray-100 hover:text-blue-600 rounded-md transition-colors'
href={`/category/${cat.slug}`} key={cat.id}>
{cat.name}
</Link>
))}
</div>
</div>
{/* نمایش بقیه لینک‌ها */}
{mainNavLinks.filter(link => link.href !== "/").map((link) => (
<Link key={link.label} href={link.href} className="hover:text-blue-600 transition duration-200 font-medium">
{link.label}
</Link>
))}
</nav>
<div className="text-xl text-gray-700 cursor-pointer hidden md:block">
<button className="inline-flex items-center justify-center px-6 py-2 rounded-xl border-1 border-[#ffb900] text-[#ffb900] text-xs tracking-wide focus:outline-none focus:ring-2 focus:ring-[#e6d3a3]/50">
استعلام قیمت
</button>
</div>
</div>
</div>
</div>
</header>
);
}