119 lines
3.6 KiB
JavaScript
119 lines
3.6 KiB
JavaScript
import { useParams } from "react-router-dom";
|
|
import { useEffect } from "react";
|
|
import { useDispatch, useSelector } from "react-redux";
|
|
import Breadcrumb from "../../components/ui/Breadcrumb";
|
|
import ProductImages from "./ProductImages";
|
|
import ProductInfo from "./ProductInfo";
|
|
import ScrollToTop from "../ui/ScrollToTop";
|
|
import { RatingPage } from "../../pages/RatingPage";
|
|
import { useGetProductBySlugQuery } from "../../features/products/productsAPI";
|
|
import {
|
|
useAddToWishlistMutation,
|
|
useRemoveFromWishlistMutation,
|
|
useGetWishlistQuery,
|
|
} from "../../features/wishlist/wishlistApi";
|
|
import { addRecentProduct } from "../../features/recentlyViewed/recentlyViewedApi";
|
|
import RecommendedProducts from "./RecommendedProducts";
|
|
import RecommendedForYou from "../home/RecommendedForYou/RecommendedForYou";
|
|
|
|
const ProductDetails = () => {
|
|
const { slug } = useParams();
|
|
const dispatch = useDispatch();
|
|
const token = useSelector((state) => state.auth.token);
|
|
|
|
const { data, isLoading, isError } = useGetProductBySlugQuery(slug);
|
|
const { data: wishlistData } = useGetWishlistQuery(undefined, { skip: !token });
|
|
|
|
const [addToWishlist] = useAddToWishlistMutation();
|
|
const [removeFromWishlist] = useRemoveFromWishlistMutation();
|
|
// const product = data?.data?.product;
|
|
|
|
// ✅ Track product view with proper error handling
|
|
useEffect(() => {
|
|
if (data?.data?.product) {
|
|
const product = data.data.product;
|
|
|
|
// ✅ Ensure all required fields exist and are valid
|
|
const productToSave = {
|
|
id: product._id,
|
|
name: product.name || "Unnamed Product",
|
|
image:
|
|
product.images?.primary ||
|
|
(Array.isArray(product.images?.gallery) &&
|
|
product.images.gallery[0]) ||
|
|
product.image ||
|
|
"/placeholder.jpg",
|
|
price:
|
|
product.basePrice != null && !isNaN(product.basePrice)
|
|
? parseFloat(product.basePrice)
|
|
: 0,
|
|
url: `/product/${slug}`,
|
|
};
|
|
console.log("Recently viewed product:", productToSave);
|
|
|
|
// ✅ Debug log to see what's being saved
|
|
console.log("Saving product to recently viewed:", productToSave);
|
|
|
|
dispatch(addRecentProduct(productToSave));
|
|
}
|
|
}, [data, dispatch, slug]);
|
|
|
|
if (isLoading) return <p className="mt-20 text-center">Loading product...</p>;
|
|
if (isError || !data?.data?.product)
|
|
return <p className="mt-20 text-center">Product not found</p>;
|
|
|
|
const product = data.data.product;
|
|
|
|
const wishlistIds =
|
|
wishlistData?.data?.wishlist?.map(
|
|
(item) => item.product?._id || item.productId,
|
|
) || [];
|
|
|
|
const isWishlisted = wishlistIds.includes(product._id);
|
|
|
|
const toggleWishlist = async () => {
|
|
try {
|
|
if (isWishlisted) {
|
|
await removeFromWishlist(product._id).unwrap();
|
|
} else {
|
|
await addToWishlist(product._id).unwrap();
|
|
}
|
|
} catch (err) {
|
|
console.error("Wishlist error:", err);
|
|
}
|
|
};
|
|
|
|
return (
|
|
<div className="px-5 md:px-20 py-10 mt-24">
|
|
<Breadcrumb />
|
|
|
|
<div className="flex flex-col md:flex-row gap-10">
|
|
<div className="md:w-4/5">
|
|
<ProductImages
|
|
product={product}
|
|
isWishlisted={isWishlisted}
|
|
onToggleWishlist={toggleWishlist}
|
|
/>
|
|
<ScrollToTop />
|
|
</div>
|
|
|
|
<div className="md:w-1/2">
|
|
<ProductInfo
|
|
product={product}
|
|
isWishlisted={isWishlisted}
|
|
onToggleWishlist={toggleWishlist}
|
|
/>
|
|
</div>
|
|
</div>
|
|
<RecommendedProducts />
|
|
<RecommendedForYou />
|
|
|
|
<div className="mt-16">
|
|
<RatingPage />
|
|
</div>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default ProductDetails;
|