added price filter, changed mobile filter ui
This commit is contained in:
@@ -12,17 +12,16 @@ import {
|
||||
import ReviewSection from "../../components/Review/index";
|
||||
import { Modal } from "antd";
|
||||
|
||||
import { debounce } from "lodash";
|
||||
import {
|
||||
useAddFavoriteMutation,
|
||||
useRemoveFavoriteMutation,
|
||||
} from "../../app/api/favoritesApi";
|
||||
import { useGetFavoritesQuery } from "../../app/api/favoritesApi";
|
||||
import { useCart } from "../../app/api/useCart";
|
||||
import {
|
||||
useAddToCartMutation,
|
||||
useUpdateCartItemMutation,
|
||||
useRemoveFromCartMutation,
|
||||
useGetCartQuery,
|
||||
} from "../../app/api/cartApi";
|
||||
import ImageCarousel from "../../components/ProductCard/imageCarousel/index";
|
||||
import Loader from "../../components/Loader/index";
|
||||
@@ -49,52 +48,38 @@ const ProductPage = ({
|
||||
error: similarProductsError,
|
||||
isLoading: similarProductsLoading,
|
||||
} = useGetRelatedProductsQuery(productId);
|
||||
const [quantity, setQuantity] = useState(0);
|
||||
const product = productResponse?.data;
|
||||
const similarProducts = similarProductsResponse?.data;
|
||||
const [stockErrorModalVisible, setStockErrorModalVisible] = useState(false);
|
||||
const [addFavorite] = useAddFavoriteMutation();
|
||||
const [removeFavorite] = useRemoveFavoriteMutation();
|
||||
const { data: favoriteProducts = [], refetch } = useGetFavoritesQuery();
|
||||
const { data: favoriteProducts = [] } = useGetFavoritesQuery();
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
const [localIsFavorite, setLocalIsFavorite] = useState(
|
||||
favoriteProducts.some((fav) => fav.product?.id === product?.id),
|
||||
);
|
||||
const { data: cartData } = useGetCartQuery(undefined, {
|
||||
selectFromResult: (result) => ({
|
||||
data: result.data,
|
||||
}),
|
||||
});
|
||||
|
||||
const { getCartItem } = useCart();
|
||||
|
||||
const [addToCart] = useAddToCartMutation();
|
||||
const [updateCartItem] = useUpdateCartItemMutation();
|
||||
const [removeFromCart] = useRemoveFromCartMutation();
|
||||
const [localQuantity, setLocalQuantity] = useState(0);
|
||||
const getCartItem = () => {
|
||||
if (!cartData?.data || typeof cartData.data !== "object") {
|
||||
return null;
|
||||
}
|
||||
|
||||
const allCartItems = Object.values(cartData.data).flat();
|
||||
|
||||
return allCartItems.find(
|
||||
(item) =>
|
||||
item.product?.id === product?.id || item.product_id === product?.id,
|
||||
);
|
||||
};
|
||||
|
||||
const cartItem = getCartItem();
|
||||
const [pendingQuantity, setPendingQuantity] = useState(0);
|
||||
|
||||
useEffect(() => {
|
||||
if (cartItem) {
|
||||
setLocalQuantity(cartItem.quantity || cartItem.product_quantity || 0);
|
||||
setPendingQuantity(cartItem.quantity || cartItem.product_quantity || 0);
|
||||
} else {
|
||||
setLocalQuantity(0);
|
||||
setPendingQuantity(0);
|
||||
}
|
||||
}, [cartData, cartItem]);
|
||||
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(
|
||||
@@ -104,78 +89,55 @@ const ProductPage = ({
|
||||
}
|
||||
}, [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 (localIsFavorite) {
|
||||
const result = await removeFavorite(product.id).unwrap();
|
||||
if (result === "Removed" || result?.status === "success") {
|
||||
setLocalIsFavorite(false);
|
||||
}
|
||||
if (originalState) {
|
||||
await removeFavorite(product.id).unwrap();
|
||||
} else {
|
||||
const result = await addFavorite(product.id).unwrap();
|
||||
if (result === "Added" || result?.status === "success") {
|
||||
setLocalIsFavorite(true);
|
||||
}
|
||||
await addFavorite(product.id).unwrap();
|
||||
}
|
||||
// Refetch after changing favorite status
|
||||
await refetch();
|
||||
} 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();
|
||||
|
||||
// Check if stock is available
|
||||
if (product.stock <= 0) {
|
||||
setStockErrorModalVisible(true);
|
||||
return;
|
||||
}
|
||||
|
||||
setLocalQuantity((prev) => prev + 1);
|
||||
setPendingQuantity((prev) => prev + 1);
|
||||
setLocalQuantity(1);
|
||||
setPendingQuantity(1);
|
||||
|
||||
try {
|
||||
await addToCart({ productId: product.id, quantity: 1 }).unwrap();
|
||||
} catch (error) {
|
||||
console.error("Failed to add to cart:", error);
|
||||
setLocalQuantity((prev) => prev - 1);
|
||||
setPendingQuantity((prev) => prev - 1);
|
||||
setLocalQuantity(0);
|
||||
setPendingQuantity(0);
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
const updateCart = debounce(async () => {
|
||||
if (pendingQuantity !== localQuantity) {
|
||||
try {
|
||||
await updateCartItem({
|
||||
productId: product.id,
|
||||
quantity: pendingQuantity,
|
||||
}).unwrap();
|
||||
} catch (error) {
|
||||
console.error("Failed to update cart item:", error);
|
||||
}
|
||||
}
|
||||
}, 500);
|
||||
|
||||
updateCart();
|
||||
|
||||
return () => updateCart.cancel();
|
||||
}, [pendingQuantity]);
|
||||
|
||||
const handleQuantityIncrease = (event) => {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
|
||||
if (isLoading) return;
|
||||
|
||||
if (localQuantity >= product.stock) {
|
||||
@@ -187,11 +149,9 @@ const ProductPage = ({
|
||||
setPendingQuantity((prev) => prev + 1);
|
||||
};
|
||||
|
||||
// Update quantity decrease handler
|
||||
const handleQuantityDecrease = (event) => {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
|
||||
if (isLoading) return;
|
||||
|
||||
if (pendingQuantity <= 1) {
|
||||
@@ -200,6 +160,9 @@ const ProductPage = ({
|
||||
setIsLoading(true);
|
||||
removeFromCart({ productId: product.id })
|
||||
.unwrap()
|
||||
.then(() => {
|
||||
// Success handled by hook
|
||||
})
|
||||
.catch(() => {
|
||||
setLocalQuantity(1);
|
||||
setPendingQuantity(1);
|
||||
@@ -213,33 +176,37 @@ const ProductPage = ({
|
||||
}
|
||||
};
|
||||
|
||||
// ✅ Debounced Cart Update
|
||||
useEffect(() => {
|
||||
const updateCart = async () => {
|
||||
if (pendingQuantity !== quantity && pendingQuantity > 0) {
|
||||
try {
|
||||
setIsLoading(true);
|
||||
await updateCartItem({
|
||||
productId: product.id,
|
||||
quantity: pendingQuantity,
|
||||
}).unwrap();
|
||||
} catch (error) {
|
||||
console.error("Failed to update cart item:", error);
|
||||
setLocalQuantity(quantity);
|
||||
setPendingQuantity(quantity);
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
}
|
||||
};
|
||||
const serverQty = parseInt(
|
||||
cartItem?.quantity || cartItem?.product_quantity || 0,
|
||||
10,
|
||||
);
|
||||
|
||||
const debouncedUpdate = debounce(updateCart, 300);
|
||||
|
||||
if (pendingQuantity !== quantity) {
|
||||
debouncedUpdate();
|
||||
// Sadece miktar değiştiyse ve 0'dan büyükse güncelle (0 ise Remove triggerlanır)
|
||||
if (pendingQuantity === serverQty || pendingQuantity <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
return () => debouncedUpdate.cancel();
|
||||
}, [pendingQuantity, quantity, product, updateCartItem]);
|
||||
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);
|
||||
// Hata durumunda geri al
|
||||
setLocalQuantity(serverQty);
|
||||
setPendingQuantity(serverQty);
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
}, 500);
|
||||
|
||||
return () => clearTimeout(handler);
|
||||
}, [pendingQuantity, cartItem, product?.id, updateCartItem]);
|
||||
|
||||
if (productLoading || similarProductsLoading) return <Loader />;
|
||||
if (productError || similarProductsError)
|
||||
|
||||
Reference in New Issue
Block a user