import { useState, useEffect, useRef, useLayoutEffect } from "react"; import { Link } from "react-router-dom"; import { getFullApiUrl } from "../utils/apiConfig"; import { motion } from "framer-motion"; import { Heart, Eye, Star, ShoppingBag, ShoppingCart } from "lucide-react"; import "../styles/ProductList.css"; import { useCreateWishlistItemMutation, useDeleteWishlistItemsMutation, useGetWishlistsQuery, useGetCartsQuery, useCreateCartSnapshotMutation, useUpdateCartSnapshotMutation, } from "../store/slices/userApiSlice"; import { notifyCartAction, notifyWishlistAction, } from "../utils/notificationService"; import { useSelector } from "react-redux"; import { toast } from "react-toastify"; import { useNavigate } from "react-router-dom"; export default function ItemSection() { const [products, setProducts] = useState([]); const [loading, setLoading] = useState(true); const { userInfo, loading: authLoading, isLoggedIn, } = useSelector((state) => state.auth); const navigate = useNavigate(); const [createWishlistItem] = useCreateWishlistItemMutation(); const [deleteWishlistItems] = useDeleteWishlistItemsMutation(); const { data: wishlistData, isLoading: wishlistLoading, refetch: refetchWishlist, } = useGetWishlistsQuery(undefined, { skip: !isLoggedIn, }); const wishlistProductIds = new Set( (wishlistData?.wishlist || []).map((p) => p.productId), ); const { data: cartsData, refetch: refetchCarts } = useGetCartsQuery( undefined, { skip: !isLoggedIn, }, ); const [createCartSnapshot] = useCreateCartSnapshotMutation(); const [updateCartSnapshot] = useUpdateCartSnapshotMutation(); const cartItems = cartsData?.carts?.[0]?.cartItems || []; useEffect(() => { fetch( `${getFullApiUrl()}/products`, ) .then((res) => res.json()) .then((data) => { setProducts(data.products); setLoading(false); }) .catch(() => { setLoading(false); console.error("Failed to fetch products"); }); }, []); const groupByCategory = () => { const grouped = {}; if (!Array.isArray(products)) return grouped; products.forEach((product) => { if (!grouped[product.category]) { grouped[product.category] = []; } if (grouped[product.category].length < 4) { grouped[product.category].push(product); } }); return grouped; }; const groupedProducts = groupByCategory(); const toggleWishlist = async (productId, product) => { if (authLoading) { toast.info("Checking login status..."); return; } if (!isLoggedIn) { toast.error("You must be logged in to add to wishlist!", { autoClose: 2000, }); setTimeout(() => navigate("/login"), 1500); return; } try { const isWishlisted = wishlistProductIds.has(productId); if (!isWishlisted) { await createWishlistItem({ productId }).unwrap(); notifyWishlistAction("add", product); } else { await deleteWishlistItems({ productIds: [productId] }).unwrap(); notifyWishlistAction("remove", product); } refetchWishlist(); window.dispatchEvent(new Event("wishlist-updated")); } catch (error) { console.error("Error toggling wishlist:", error); notifyWishlistAction("failed", product); } }; const isInCart = (productId) => { return cartItems.some((item) => item.productId === productId); }; const getCartItemQty = (productId) => { const item = cartItems.find((item) => item.productId === productId); return item ? item.qty : 0; }; const handleAddToCart = async (product) => { if (authLoading) { toast.info("Checking login status..."); return; } if (!isLoggedIn) { toast.error("You must be logged in to add to cart!", { autoClose: 2000 }); setTimeout(() => navigate("/login"), 1500); return; } try { const existingItem = cartItems.find( (item) => item.productId === product._id, ); let updatedCartItems; if (existingItem) { updatedCartItems = cartItems.map((item) => item.productId === product._id ? { ...item, qty: item.qty + 1 } : item, ); await updateCartSnapshot({ createdAt: cartsData?.carts?.[0]?.createdAt, update: { cartItems: updatedCartItems, amount: calculateCartAmount(updatedCartItems), status: "pending", }, }); notifyCartAction("update", product); } else if (!cartsData?.carts || cartsData.carts.length === 0) { updatedCartItems = [ { productId: product._id, name: product.name, price: product.price, qty: 1, category: product.category, seller: product.seller, stock: product.stock, image: product.images && product.images[0] ? product.images[0].image : "", ratings: product.ratings, }, ]; await createCartSnapshot({ cart: { cartItems: updatedCartItems, amount: calculateCartAmount(updatedCartItems), status: "pending", }, }); notifyCartAction("add", product); } else { updatedCartItems = [ ...cartItems, { productId: product._id, name: product.name, price: product.price, qty: 1, category: product.category, seller: product.seller, stock: product.stock, image: product.images && product.images[0] ? product.images[0].image : "", ratings: product.ratings, }, ]; await updateCartSnapshot({ createdAt: cartsData?.carts?.[0]?.createdAt, update: { cartItems: updatedCartItems, amount: calculateCartAmount(updatedCartItems), status: "pending", }, }); notifyCartAction("add", product); } refetchCarts(); window.dispatchEvent(new Event("cart-updated")); } catch (error) { console.error("Error adding to cart:", error); notifyCartAction("failed", product); } }; function calculateCartAmount(cartItems) { return cartItems.reduce((acc, item) => acc + item.price * item.qty, 0); } const renderStars = (rating) => { const stars = []; const fullStars = Math.floor(rating); const decimalPart = rating - fullStars; for (let i = 0; i < 5; i++) { if (i < fullStars) { stars.push(); } else if (i === fullStars && decimalPart > 0) { stars.push(); } else { stars.push(); } } return stars; }; const isMobile = typeof window !== "undefined" && window.innerWidth <= 768; if (loading) { return ( <>
{[...Array(4)].map((_, i) => ( ))}
Loading Products...
); } return ( <>
{ } { }
{[...Array(10)].map((_, i) => ( ))}
Discover Amazing Products Explore our curated collection of Premium products View All Products
{ } {Object.keys(groupedProducts).map((category, categoryIndex) => (

{category}

{(groupedProducts[category] || []).map((product) => (
{ }
{ } toggleWishlist(product._id, product)} whileHover={{ scale: 1.2 }} whileTap={{ scale: 0.8 }} > { }
{ }

{product.name}

{renderStars( typeof product.ratings === "number" ? product.ratings : 0, )}
( {typeof product.ratings === "number" ? product.ratings.toFixed(1) : "0.0"} )
{typeof product.price === "number" && !isNaN(product.price) ? product.price.toLocaleString() : "N/A"}
{window.innerWidth <= 600 ? product.description.length > 30 ? product.description.slice(0, 25) + "..." : product.description : product.description.slice(0, 50) + (product.description.length > 50 ? "..." : "")}
View
{ }
handleAddToCart(product)} whileHover={{ scale: 1.1 }} whileTap={{ scale: 0.9 }} > {isInCart(product._id) ? ( In Cart ({getCartItemQty(product._id)}) ) : ( Add to Cart )}
))}
))}
); }