login , register api / category provider api
This commit is contained in:
@@ -3,13 +3,13 @@ import React, { useState, useEffect, useRef } from 'react';
|
||||
import { usePathname, useRouter } from 'next/navigation';
|
||||
import Link from 'next/link';
|
||||
import Image from 'next/image';
|
||||
import { registerUser } from '@/public/src/services/auth/api';
|
||||
import { Category } from '@/public/src/types/categories';
|
||||
|
||||
import { ShoppingCart, Trash2, Search, X, ChevronDown } 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 { useCategories } from './context/categoryprovider';
|
||||
|
||||
const topBarLinks = [
|
||||
{ label: "بخش صنعتی", href: "/" },
|
||||
@@ -25,7 +25,7 @@ const mainNavLinks = [
|
||||
];
|
||||
|
||||
|
||||
export function Header({ categories }: { categories: Category[] }) {
|
||||
export function Header() {
|
||||
const [menuOpen, setMenuOpen] = useState(false);
|
||||
const pathname = usePathname();
|
||||
const { cart, removeFromCart } = useCart();
|
||||
@@ -34,54 +34,143 @@ export function Header({ categories }: { categories: Category[] }) {
|
||||
const [filteredProducts, setFilteredProducts] = useState<any[]>([]);
|
||||
const searchRef = useRef<HTMLDivElement>(null);
|
||||
const router = useRouter();
|
||||
const safeCategories = categories || [];
|
||||
const [isOpen, setIsOpen] = useState(false);
|
||||
const [formType, setFormType] = useState("mobile");
|
||||
const [activeTab, setActiveTab] = useState("login");
|
||||
const [registerForm, setRegisterForm] = useState({
|
||||
phone: "",
|
||||
const [registerError, setRegisterError] = useState("");
|
||||
const [loginError, setLoginError] = useState("");
|
||||
const { rootCategories } = useCategories();
|
||||
const [loginForm, setLoginForm] = useState({
|
||||
username: "",
|
||||
firstName: "",
|
||||
lastName: "",
|
||||
password: "",
|
||||
confirmPassword: "",
|
||||
});
|
||||
|
||||
const handleRegisterChange = (e: any) => {
|
||||
const { name, value } = e.target;
|
||||
const [registerForm, setRegisterForm] = useState({
|
||||
phone: "",
|
||||
fullName: "",
|
||||
username: "",
|
||||
password: "",
|
||||
});
|
||||
|
||||
setRegisterForm((prev) => ({
|
||||
...prev,
|
||||
[name]: value,
|
||||
}));
|
||||
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
setRegisterForm({
|
||||
...registerForm,
|
||||
[e.target.name]: e.target.value,
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
|
||||
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 (!phone || !username || !password || !fullName) {
|
||||
setRegisterError("لطفاً فیلدها را پر کنید");
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
const payload = {
|
||||
phone: registerForm.phone,
|
||||
username: registerForm.username,
|
||||
password: registerForm.password,
|
||||
phone,
|
||||
username,
|
||||
password,
|
||||
fullName,
|
||||
};
|
||||
|
||||
const res = await registerUser(payload);
|
||||
|
||||
console.log("ثبت نام موفق", res);
|
||||
localStorage.setItem("accessToken", res.data.accessToken);
|
||||
localStorage.setItem("refreshToken", res.data.refreshToken);
|
||||
|
||||
} catch (err) {
|
||||
console.log("خطا:", err);
|
||||
setIsOpen(false);
|
||||
router.push("/dashboard");
|
||||
|
||||
} 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 rootCategories = safeCategories.filter(cat => cat.parent === null);
|
||||
const handleLogin = async () => {
|
||||
setLoginError("");
|
||||
|
||||
const username = loginForm.username.trim();
|
||||
const password = loginForm.password.trim();
|
||||
|
||||
if (!username || !password) {
|
||||
setLoginError("لطفاً نام کاربری و رمز عبور را وارد کنید");
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const res = await loginUser({ username, password });
|
||||
|
||||
localStorage.setItem("accessToken", res.data.accessToken);
|
||||
localStorage.setItem("refreshToken", res.data.refreshToken);
|
||||
setIsOpen(false);
|
||||
router.push("/dashboard");
|
||||
|
||||
} 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 parsePrice = (priceStr?: string | 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(() => {
|
||||
@@ -422,7 +511,7 @@ export function Header({ categories }: { categories: Category[] }) {
|
||||
|
||||
<button
|
||||
onClick={() => setActiveTab("register")}
|
||||
className={`flex-1 py-2 text-sm rounded-lg transition ${activeTab === "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"
|
||||
}`}
|
||||
@@ -467,19 +556,38 @@ export function Header({ categories }: { categories: Category[] }) {
|
||||
|
||||
<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]"
|
||||
/>
|
||||
|
||||
<input
|
||||
type="password"
|
||||
value={loginForm.password}
|
||||
onChange={(e) =>
|
||||
setLoginForm((prev) => ({
|
||||
...prev,
|
||||
password: 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]"
|
||||
/>
|
||||
|
||||
<button className="w-full cursor-pointer py-3.5 bg-[#ffb900] hover:bg-[#e5a600] text-[#1A2332] font-semibold rounded-2xl text-sm">
|
||||
<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")}
|
||||
@@ -495,40 +603,30 @@ export function Header({ categories }: { categories: Category[] }) {
|
||||
)}
|
||||
|
||||
{/* ---------------- REGISTER ---------------- */}
|
||||
|
||||
{activeTab === "register" && (
|
||||
<div className="w-full space-y-4">
|
||||
|
||||
<input
|
||||
name="phone"
|
||||
value={registerForm.phone}
|
||||
onChange={handleRegisterChange}
|
||||
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="firstName"
|
||||
value={registerForm.firstName}
|
||||
onChange={handleRegisterChange}
|
||||
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="lastName"
|
||||
value={registerForm.lastName}
|
||||
onChange={handleRegisterChange}
|
||||
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={handleRegisterChange}
|
||||
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]'
|
||||
@@ -536,20 +634,19 @@ export function Header({ categories }: { categories: Category[] }) {
|
||||
<input
|
||||
name="password"
|
||||
value={registerForm.password}
|
||||
onChange={handleRegisterChange}
|
||||
type="password"
|
||||
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]"
|
||||
/>
|
||||
|
||||
<input
|
||||
{/* <input
|
||||
name="confirmPassword"
|
||||
value={registerForm.confirmPassword}
|
||||
onChange={handleRegisterChange}
|
||||
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}
|
||||
@@ -558,6 +655,11 @@ export function Header({ categories }: { categories: Category[] }) {
|
||||
ثبت نام
|
||||
</button>
|
||||
|
||||
{registerError && (
|
||||
<div className="text-red-500 text-sm text-center mt-2">
|
||||
{registerError}
|
||||
</div>
|
||||
)}
|
||||
|
||||
</div>
|
||||
)}
|
||||
@@ -590,21 +692,13 @@ export function Header({ categories }: { categories: Category[] }) {
|
||||
|
||||
<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.length > 0 ? (
|
||||
rootCategories.map((category) => (
|
||||
<Link
|
||||
key={category.id}
|
||||
href={`/category/${category.slug}`}
|
||||
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"
|
||||
>
|
||||
{category.name}
|
||||
</Link>
|
||||
))
|
||||
) : (
|
||||
<div className="text-center text-xs text-gray-500 py-2">
|
||||
در حال بارگذاری...
|
||||
</div>
|
||||
)}
|
||||
|
||||
{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>
|
||||
|
||||
Reference in New Issue
Block a user