first commit
This commit is contained in:
117
src/components/product/ProductDetails.jsx
Normal file
117
src/components/product/ProductDetails.jsx
Normal file
@@ -0,0 +1,117 @@
|
||||
import { useParams } from "react-router-dom";
|
||||
import { useEffect } from "react";
|
||||
import { useDispatch } 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 { data, isLoading, isError } = useGetProductBySlugQuery(slug);
|
||||
const { data: wishlistData } = useGetWishlistQuery();
|
||||
|
||||
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;
|
||||
Reference in New Issue
Block a user