This commit is contained in:
hamid zarghami
2025-09-20 11:36:18 +03:30
parent 5adf5fe461
commit 40c3729d65
5 changed files with 173 additions and 9 deletions
+155 -4
View File
@@ -6,17 +6,20 @@ import { NextPage } from 'next'
import Image from 'next/image'
import { useSearchParams } from 'next/navigation'
import { useEffect, useState } from 'react';
import { useGetCompare } from './hooks/useCompareData'
import { useGetCompare, useSearchCompareProduct } from './hooks/useCompareData'
import { useLocalCart } from '@/app/product/hooks/useLocalCart'
import { toast } from '@/components/Toast'
import { CompareProduct } from './types/Types'
import { useSharedStore } from '@/share/store/sharedStore'
import DefaulModal from '@/components/DefaulModal'
const ComparePage: NextPage = () => {
const [productIds, setProductIds] = useState<string[]>([]);
const [isCompareModalOpen, setIsCompareModalOpen] = useState(false);
const search = useSearchParams()
const { data, isLoading } = useGetCompare(productIds)
const { data: searchData } = useSearchCompareProduct(productIds[0])
const { addToLocalCart } = useLocalCart()
const { isLogin } = useSharedStore()
@@ -34,10 +37,58 @@ const ComparePage: NextPage = () => {
toast('محصول به سبد خرید اضافه شد', 'success')
}
const handleProductClick = (productId: number) => {
const productIdStr = productId.toString()
// بررسی اینکه محصول قبلاً اضافه نشده باشد
if (productIds.includes(productIdStr)) {
toast('این محصول قبلاً در لیست مقایسه اضافه شده است', 'error')
return
}
// اضافه کردن محصول به لیست مقایسه
const newProductIds = [...productIds, productIdStr]
console.log('New product IDs:', newProductIds)
setProductIds(newProductIds)
// به‌روزرسانی URL با محصولات جدید
const url = new URL(window.location.href)
url.searchParams.set('productIds', newProductIds.join(','))
url.searchParams.delete('productId') // حذف productId قدیمی
window.history.pushState({}, '', url.toString())
setIsCompareModalOpen(false)
toast('محصول به لیست مقایسه اضافه شد', 'success')
}
useEffect(() => {
const productId = search.get('productId')
if (productId) {
setProductIds([productId]);
const productIdsParam = search.get('productIds')
console.log('URL params - productId:', productId, 'productIds:', productIdsParam)
if (productIdsParam) {
// اگر productIds در URL موجود است، آن را استفاده کن
const ids = productIdsParam.split(',').filter(id => id.trim())
console.log('Parsed product IDs:', ids)
setProductIds(ids)
// حذف productId قدیمی از URL
if (productId) {
const url = new URL(window.location.href)
url.searchParams.delete('productId')
window.history.replaceState({}, '', url.toString())
}
} else if (productId) {
// اگر فقط productId موجود است، آن را به productIds تبدیل کن
console.log('Single product ID:', productId)
setProductIds([productId])
// URL را به productIds تبدیل کن
const url = new URL(window.location.href)
url.searchParams.delete('productId')
url.searchParams.set('productIds', productId)
window.history.replaceState({}, '', url.toString())
}
}, [search]);
@@ -74,7 +125,7 @@ const ComparePage: NextPage = () => {
return (
<Layout>
<div className='mt-24 px-20'>
<div className='flex border-b border-border'>
<div className='flex items-center border-b border-border'>
{products.map((product, index) => (
<div key={product._id} className={`w-[300px] flex flex-col justify-center items-center ${index < products.length - 1 ? 'border-l border-border' : ''} pb-5`}>
<Image
@@ -104,6 +155,10 @@ const ComparePage: NextPage = () => {
</div>
</div>
))}
<Button variant={'outline'} onClick={() => setIsCompareModalOpen(true)}>
افزودن به مقایسه
</Button>
</div>
<div className='mt-8'>
@@ -127,6 +182,102 @@ const ComparePage: NextPage = () => {
</div>
))}
</div>
{/* مودال انتخاب کالا برای مقایسه */}
<DefaulModal
open={isCompareModalOpen}
close={() => setIsCompareModalOpen(false)}
isHeader={true}
title_header="انتخاب کالا برای مقایسه"
width={800}
>
<div className="space-y-6">
{/* نوار جستجو */}
<div className="flex items-center gap-4">
<div className="text-sm text-gray-600 whitespace-nowrap">
759 كالا
</div>
<div className="flex-1 relative">
<input
type="text"
placeholder="نام یا کد کالا را وارد کنید"
className="w-full px-4 py-3 pr-12 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 text-sm"
/>
<div className="absolute left-3 top-1/2 transform -translate-y-1/2">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
<circle cx="11" cy="11" r="8" />
<path d="m21 21-4.35-4.35" />
</svg>
</div>
</div>
</div>
{/* عنوان برترین کالاها */}
<div className="text-sm font-medium text-gray-800">
برترین کالاها برای مقایسه
</div>
{/* لیست محصولات */}
<div className="grid grid-cols-3 gap-3 max-h-80 overflow-y-auto">
{searchData?.results?.products?.slice(0, 6).map((product: CompareProduct) => (
<div
key={product._id}
className="border border-gray-200 rounded-lg p-3 hover:shadow-md transition-shadow bg-white cursor-pointer"
onClick={() => handleProductClick(product._id)}
>
<div className="flex flex-col items-center text-center space-y-2">
{/* تصویر محصول */}
<div className="w-full h-24 relative">
<Image
src={product.imagesUrl.cover}
alt={product.title_fa}
fill
className="object-cover rounded-lg"
/>
</div>
{/* متن ذخیره سازی */}
<div className="text-xs text-blue-600 font-medium">
ذخیره سازی
</div>
{/* نام محصول */}
<h3 className="text-xs font-medium text-gray-900 leading-tight">
{product.title_fa}
</h3>
{/* ستاره‌ها */}
<div className="flex items-center gap-1">
{[...Array(5)].map((_, i) => (
<svg key={i} width="10" height="10" viewBox="0 0 24 24" fill={i < 3.5 ? "#FFD700" : "#E5E7EB"} className="w-2.5 h-2.5">
<path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z" />
</svg>
))}
</div>
{/* قیمت */}
<div className="text-xs font-medium text-gray-900">
{product.default_variant.price.selling_price.toLocaleString()} <span className="text-[10px]">تومان</span>
</div>
{/* آیکون قلب */}
<button
className="p-1 hover:bg-gray-100 rounded-full transition-colors"
onClick={(e) => {
e.stopPropagation()
// TODO: اضافه کردن به علاقه‌مندی‌ها
}}
>
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
<path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z" />
</svg>
</button>
</div>
</div>
))}
</div>
</div>
</DefaulModal>
</Layout>
)
}
+12 -1
View File
@@ -5,7 +5,18 @@ import { CompareResponse } from "../types/Types";
export const getCompare = async (
productIds: string[]
): Promise<CompareResponse> => {
const { data } = await axios.get(`/product/compare?productIds=${productIds}`);
console.log("API call - productIds:", productIds);
// روش اول: ارسال آرایه به صورت جداگانه
const params = new URLSearchParams();
productIds.forEach((id) => {
params.append("productIds", id);
});
console.log("Final URL:", `/product/compare?${params.toString()}`);
const { data } = await axios.get(`/product/compare?${params.toString()}`);
console.log("API response:", data);
return data;
};
+3 -1
View File
@@ -1,5 +1,6 @@
import { useMutation, useQuery } from "@tanstack/react-query";
import * as api from "../service/Service";
import { useSharedStore } from "@/share/store/sharedStore";
export const useGetDetailProduct = (id: string) => {
return useQuery({
@@ -26,10 +27,11 @@ export const useAddQuestion = () => {
};
export const useCheckWishProduct = (productId: string, variantId: string) => {
const { isLogin } = useSharedStore();
return useQuery({
queryKey: ["check-wish-product", productId, variantId],
queryFn: () => api.checkWishProduct(productId, variantId),
enabled: !!productId && !!variantId,
enabled: !!productId && !!variantId && isLogin,
});
};
+1 -1
View File
@@ -73,7 +73,7 @@ axiosInstance.interceptors.response.use(
console.error("Token refresh failed:", refreshError);
await removeToken();
await removeRefreshToken();
window.location.href = `/`;
// window.location.href = `/`;
return Promise.reject(refreshError);
} finally {
window.isRefreshingToken = false;
+2 -2
View File
@@ -1,6 +1,6 @@
export const TOKEN_NAME = "sh_token";
export const REFRESH_TOKEN_NAME = "sh_refresh_token";
export const BASE_URL = "https://shop-api.dev.danakcorp.com";
// export const BASE_URL = "https://api.shinan.ir";
// export const BASE_URL = "https://shop-api.dev.danakcorp.com";
export const BASE_URL = "http://192.168.1.111:4000";
export const PRIMARY_COLOR = "#015699";