import React, { useState, useEffect } from "react"; import { useParams, useNavigate, Link } from "react-router-dom"; import styles from "./ProductPage.module.scss"; import { IoMdHeartEmpty, IoMdHeart } from "react-icons/io"; import { FaShoppingCart } from "react-icons/fa"; import ProductCard from "../../components/ProductCard/index"; import { useTranslation } from "react-i18next"; import { useGetProductByIdQuery, useGetRelatedProductsQuery, } from "../../app/api/categories"; import ReviewSection from "../../components/Review/index"; import { Modal } from "antd"; import { useAddFavoriteMutation, useRemoveFavoriteMutation, } from "../../app/api/favoritesApi"; import { useGetFavoritesQuery } from "../../app/api/favoritesApi"; import { useCart } from "../../app/api/useCart"; import { useAddToCartMutation, useUpdateCartItemMutation, useRemoveFromCartMutation, } from "../../app/api/cartApi"; import ImageCarousel from "../../components/ProductCard/imageCarousel/index"; import Loader from "../../components/Loader/index"; import { Result, Button } from "antd"; import { div } from "framer-motion/client"; import PendingPriceBadge from "../../components/PendingPriceBadge"; const isPriceZero = (price) => !price || parseFloat(price) === 0; const ProductPage = ({ productProp, showAddToCart = true, showFavoriteButton = true, onAddToCart, onToggleFavorite, isFavorite = false, }) => { const navigate = useNavigate(); const { productId } = useParams(); const { t } = useTranslation(); const { data: productResponse, error: productError, isLoading: productLoading, } = useGetProductByIdQuery(productId); const { data: similarProductsResponse, error: similarProductsError, isLoading: similarProductsLoading, } = useGetRelatedProductsQuery(productId); const product = productResponse?.data; const similarProducts = similarProductsResponse?.data; const [stockErrorModalVisible, setStockErrorModalVisible] = useState(false); const [addFavorite] = useAddFavoriteMutation(); const [removeFavorite] = useRemoveFavoriteMutation(); const { data: favoriteProducts = [] } = useGetFavoritesQuery(); const [isLoading, setIsLoading] = useState(false); const [localIsFavorite, setLocalIsFavorite] = useState( favoriteProducts.some((fav) => fav.product?.id === product?.id), ); const [isDescExpanded, setIsDescExpanded] = useState(false); const [showReadMore, setShowReadMore] = useState(false); const descRef = React.useRef(null); const productInfoRef = React.useRef(null); useEffect(() => { if (!product?.description) return; const plainText = product.description.replace(/<[^>]*>/g, "").trim(); setShowReadMore(plainText.length > 300); }, [product?.description]); const { getCartItem } = useCart(); const [addToCart] = useAddToCartMutation(); const [updateCartItem] = useUpdateCartItemMutation(); const [removeFromCart] = useRemoveFromCartMutation(); const [localQuantity, setLocalQuantity] = useState(0); const [pendingQuantity, setPendingQuantity] = useState(0); const cartItem = getCartItem(product?.id || productId); // ✅ Sync local state with server cart useEffect(() => { const qty = parseInt( cartItem?.quantity || cartItem?.product_quantity || 0, 10, ); setLocalQuantity(qty); setPendingQuantity(qty); }, [cartItem]); // ✅ Sync favorite status useEffect(() => { if (Array.isArray(favoriteProducts)) { const isFav = favoriteProducts.some( (fav) => fav.product?.id === product?.id, ); setLocalIsFavorite(isFav); } }, [favoriteProducts, product?.id]); // ✅ Toggle Favorite const handleToggleFavorite = async (event) => { event.preventDefault(); event.stopPropagation(); if (isLoading) return; setIsLoading(true); const originalState = localIsFavorite; setLocalIsFavorite(!originalState); // Optimistic Update try { if (originalState) { await removeFavorite(product.id).unwrap(); } else { await addFavorite(product.id).unwrap(); } } catch (error) { console.error("Failed to toggle favorite:", error); setLocalIsFavorite(originalState); // Rollback } finally { setIsLoading(false); } }; // ✅ Add to Cart (Initial) const handleAddToCart = async (event) => { event.preventDefault(); event.stopPropagation(); if (product.stock <= 0) { setStockErrorModalVisible(true); return; } setLocalQuantity(1); setPendingQuantity(1); try { await addToCart({ productId: product.id, quantity: 1 }).unwrap(); } catch (error) { console.error("Failed to add to cart:", error); setLocalQuantity(0); setPendingQuantity(0); } }; const handleQuantityIncrease = (event) => { event.preventDefault(); event.stopPropagation(); if (isLoading) return; if (localQuantity >= product.stock) { setStockErrorModalVisible(true); return; } setLocalQuantity((prev) => prev + 1); setPendingQuantity((prev) => prev + 1); }; const handleQuantityDecrease = (event) => { event.preventDefault(); event.stopPropagation(); if (isLoading) return; if (pendingQuantity <= 1) { setPendingQuantity(0); setLocalQuantity(0); setIsLoading(true); removeFromCart({ productId: product.id }) .unwrap() .then(() => { // Success handled by hook }) .catch(() => { setLocalQuantity(1); setPendingQuantity(1); }) .finally(() => { setIsLoading(false); }); } else { setLocalQuantity((prev) => prev - 1); setPendingQuantity((prev) => prev - 1); } }; // ✅ Debounced Cart Update useEffect(() => { const serverQty = parseInt( cartItem?.quantity || cartItem?.product_quantity || 0, 10, ); if (pendingQuantity === serverQty || pendingQuantity <= 0) { return; } const handler = setTimeout(async () => { try { setIsLoading(true); await updateCartItem({ productId: product.id, quantity: pendingQuantity, }).unwrap(); } catch (error) { console.error("Failed to update cart item:", error); setLocalQuantity(serverQty); setPendingQuantity(serverQty); } finally { setIsLoading(false); } }, 500); return () => clearTimeout(handler); }, [pendingQuantity, cartItem, product?.id, updateCartItem]); if (productLoading || similarProductsLoading) return ; if (productError || similarProductsError) return ( navigate("/")}> Baş sahypa gidiň } /> ); if (!product) return
Can not find product
; const categoryName = product.categories?.[0]?.name || "Category"; const categoryId = product.categories?.[0]?.id; const handleCategoryClick = (categoryId) => { navigate(`/category/${categoryId}`); }; // ── Cart + favorite butonları (desktop purchase card + mobile bar'da ortak) ── const CartButtons = () => (
{showFavoriteButton && ( )} {showAddToCart && ( <> {localQuantity > 0 ? (
{localQuantity}
) : ( )} )}
); return (
{/* Breadcrumb */}
handleCategoryClick(categoryId)}> {categoryName} / {product?.name || "Product"}
{/* ── 3 kolon ana section ── */}
{/* KOLON 1: Resim */}
{/* KOLON 2: İsim + Meta + Description */}
{/* Meta tablo */}

{product.name}

{/*
{t("product.productCode")} {product.id}
{product.barcode && (
{t("product.barCode")} {product.barcode}
)} */} {product.brand?.name && ( {t("order.brand")} {product.brand.name} )} {product.channel?.[0]?.name && ( {t("order.channel")} {product.channel[0].name} )} {product.properties?.length > 0 && ( product.properties.map((prop, index) => (
{prop.name} {prop.value}
)) )}
{/* Description card */} {product.description && (

{t("product.description")}

{showReadMore && !isDescExpanded && ( )} {showReadMore && isDescExpanded && ( )}
)}
{/* KOLON 3: Satın alma kartı (sadece desktop/tablet) */}
{/* Fiyat */}
{t("product.price")}:
{isPriceZero(product.price_amount) ? ( {t("cart.pendingPriceTitle")} ) : ( <> {product.price_amount} m. {product.old_price_amount && ( {product.old_price_amount} m. )} )}
{/* Butonlar */}
{/* ── Mobile sticky bar ── */}
{isPriceZero(product.price_amount) ? ( {t("cart.pendingPriceTitle")} ) : ( <> {product.price_amount} m. {product.old_price_amount && ( {product.old_price_amount} m. )} )}
{/* Reviews */} {/* Similar Products */}

{t("product.similarProducts")}

{Array.isArray(similarProducts) && similarProducts.map((product) => ( ))}
{/* Stock modal */} setStockErrorModalVisible(false)} onCancel={() => setStockErrorModalVisible(false)} okText={t("common.ok")} footer={[ , ]} >

{t("common.not_enough_stock", { available: product.stock, requested: localQuantity + 1, })}

); }; export default ProductPage;