Files
vaishnavi-ecommerce-website/src/components/navbar/Wishlist.jsx
2026-03-10 14:47:34 +05:30

354 lines
12 KiB
JavaScript
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// import React, { useState } from "react";
// import {
// useGetWishlistQuery,
// useRemoveFromWishlistMutation,
// } from "../../features/wishlist/wishlistApi";
// import WishlistEmpty from "./WishlistEmpty";
// import AddToCart from "../../pages/Cart/AddToCart";
// import { useAddToCartMutation } from "../../features/cart/cartAPI";
// import { useNavigate } from "react-router-dom";
// const Wishlist = () => {
// const navigate = useNavigate();
// const [addToCart] = useAddToCartMutation();
// const { data, isLoading, isError } = useGetWishlistQuery();
// const [removeFromWishlist] = useRemoveFromWishlistMutation();
// const [confirmModal, setConfirmModal] = useState({
// show: false,
// productId: null,
// productName: "",
// });
// const wishlistItems = data?.data?.wishlist || [];
// // Loading
// if (isLoading)
// return (
// <p className="text-center mt-20 text-xl font-medium text-gray-600">
// Loading your wishlist...
// </p>
// );
// if (isError) return <WishlistEmpty />;
// // Empty
// if (wishlistItems.length === 0) return <WishlistEmpty />;
// const handleRemove = async (productId) => {
// try {
// await removeFromWishlist(productId).unwrap();
// setConfirmModal({ show: false, productId: null, productName: "" });
// } catch (error) {
// console.log("Remove failed", error);
// }
// };
// const fallbackImage = "/default-product.png";
// return (
// <div className="max-w-7xl mx-auto px-4 py-12 mt-24 bg-gradient-to-br from-gray-50 to-gray-100">
// <h1 className="text-2xl font-extrabold mb-10 text-center text-gray-800 tracking-tight">
// My Wishlist
// </h1>
// <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-6">
// {wishlistItems.map((item) => {
// const image =
// item?.product?.images?.gallery?.[0] ||
// item?.product?.variants?.[0]?.images?.[0] ||
// fallbackImage;
// return (
// <div
// key={item.id}
// className="bg-white rounded-2xl shadow-md hover:shadow-lg flex flex-col"
// >
// {/* Product Image */}
// <div className="relative h-44 bg-gray-100 overflow-hidden group">
// <img
// src={image}
// onError={(e) => (e.target.src = fallbackImage)}
// alt={item?.product?.name || "Product"}
// className="object-cover h-full w-full transition-transform duration-500 group-hover:scale-105"
// />
// {/* Remove Button */}
// <button
// onClick={() =>
// setConfirmModal({
// show: true,
// productId: item.productId,
// productName: item?.product?.name || "this product",
// })
// }
// className="absolute top-3 right-3 bg-white shadow p-1.5 rounded-full hover:bg-red-500 hover:text-white transition-all text-sm"
// >
// ✖
// </button>
// </div>
// {/* Product Info */}
// <div className="p-4 flex flex-col flex-1">
// <h2 className="text-md font-semibold text-gray-800 mb-1 truncate">
// {item?.product?.name || "Unknown Product"}
// </h2>
// {/* Price */}
// {item?.product?.basePrice && (
// <p className="text-lg font-bold text-primary-dark mb-1">
// ₹ {item.product.basePrice.toLocaleString()}
// </p>
// )}
// {/* Added Date */}
// <p className="text-gray-500 text-xs mb-3">
// Added on{" "}
// <span className="font-medium">
// {new Date(item.createdAt).toLocaleDateString()}
// </span>
// </p>
// {/* Add To Cart Component */}
// {/* Buttons */}
// <div className="mt-auto flex justify-end w-full">
// <button
// className="text-primary-default font-semibold text-sm underline hover:text-primary-dark transition-colors"
// onClick={async () => {
// const token = localStorage.getItem("token");
// if (!token) {
// alert("Please login first to add product to cart");
// navigate("/login");
// return;
// }
// try {
// // 1⃣ Add to Cart API call
// await addToCart({
// productId: item.productId,
// quantity: 1,
// }).unwrap();
// // 2⃣ Remove from Wishlist API call
// await removeFromWishlist(item.productId).unwrap();
// // 3⃣ Redirect to Cart page
// navigate("/cart");
// } catch (err) {
// console.log("Error:", err);
// }
// }}
// >
// Add To Bag
// </button>
// </div>
// </div>
// </div>
// );
// })}
// </div>
// {/* Confirmation Modal */}
// {confirmModal.show && (
// <div className="fixed inset-0 bg-black bg-opacity-40 flex items-center justify-center z-50">
// <div className="bg-white rounded-xl shadow-lg p-8 w-96 sm:w-4/5 max-w-md text-center">
// <h3 className="text-base font-semibold mb-6">
// Are you sure you want to delete <br />
// <span className="text-amber-800">
// {confirmModal.productName}
// </span>{" "}
// from your wishlist?
// </h3>
// <div className="flex justify-center gap-6 mt-6">
// <button
// onClick={() => handleRemove(confirmModal.productId)}
// className="px-6 py-3 bg-primary-default text-white rounded-lg font-semibold hover:bg-primary-dark transition"
// >
// Yes
// </button>
// <button
// onClick={() =>
// setConfirmModal({
// show: false,
// productId: null,
// productName: "",
// })
// }
// className="px-6 py-3 bg-gray-300 text-gray-800 rounded-lg font-semibold hover:bg-gray-400 transition"
// >
// No
// </button>
// </div>
// </div>
// </div>
// )}
// </div>
// );
// };
// export default Wishlist;
import React, { useState } from "react";
import {
useGetWishlistQuery,
useRemoveFromWishlistMutation,
} from "../../features/wishlist/wishlistApi";
import { useAddToCartMutation } from "../../features/cart/cartAPI";
import WishlistEmpty from "./WishlistEmpty";
import { useNavigate } from "react-router-dom";
const Wishlist = () => {
const navigate = useNavigate();
const { data, isLoading, isError } = useGetWishlistQuery();
const [addToCart] = useAddToCartMutation();
const [removeFromWishlist] = useRemoveFromWishlistMutation();
const [confirm, setConfirm] = useState(null);
const wishlist = data?.data?.wishlist || [];
const fallbackImage = "/default-product.png";
if (isLoading) {
return (
<div className="mt-32 text-center text-gray-500 text-lg">
Loading wishlist
</div>
);
}
if (isError || wishlist.length === 0) {
return <WishlistEmpty />;
}
const handleAddToCart = async (item) => {
const token = localStorage.getItem("token");
if (!token) {
alert("Please login first to add product to cart");
navigate("/login");
return;
}
try {
await addToCart({
productId: item.productId,
quantity: 1,
}).unwrap();
await removeFromWishlist(item.productId).unwrap();
navigate("/cart");
} catch (err) {
console.error(err);
}
};
return (
<div className="max-w-7xl mx-auto px-4 py-12 mt-32 bg-gradient-to-br from-gray-50 to-gray-100">
<h1 className="text-2xl font-semibold text-gray-600 mb-10">
My Wishlist ({wishlist.length} items)
</h1>
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-8">
{wishlist.map((item) => {
const image =
item?.product?.images?.gallery?.[0] ||
item?.product?.variants?.[0]?.images?.[0] ||
fallbackImage;
return (
<div
key={item.id}
className="border border-gray-200 rounded-lg bg-white"
>
{/* Image */}
<div className="relative h-56 bg-gray-50">
<img
src={image}
onError={(e) => (e.target.src = fallbackImage)}
alt={item?.product?.name}
className="h-full w-full object-contain p-6"
/>
{/* Remove */}
<button
onClick={() => setConfirm(item)}
className="absolute top-3 right-3 text-gray-400
hover:text-gray-700 text-sm"
>
Remove
</button>
</div>
{/* Content */}
<div className="px-5 py-4 space-y-2">
<p className="text-sm text-gray-500">
{item?.product?.category || "Product"}
</p>
<h2 className="text-base font-medium text-gray-900 line-clamp-2">
{item?.product?.name}
</h2>
<div className="flex items-center justify-between pt-3">
<p className="text-lg font-semibold text-gray-900">
{item?.product?.basePrice?.toLocaleString()}
</p>
<button
onClick={() => handleAddToCart(item)}
className="px-4 py-2 text-sm font-medium
border border-gray-900
text-gray-900
hover:bg-gray-900 hover:text-white
transition"
>
Add to Cart
</button>
</div>
</div>
</div>
);
})}
</div>
{/* Confirm Modal */}
{confirm && (
<div className="fixed inset-0 bg-black/30 flex items-center justify-center z-50">
<div className="bg-white w-96 rounded-lg p-6">
<h3 className="text-lg font-medium text-gray-900 mb-4">
Remove item?
</h3>
<p className="text-sm text-gray-500 mb-6">
Are you sure you want to remove{" "}
<span className="font-medium text-gray-900">
{confirm.product?.name}
</span>{" "}
from your wishlist?
</p>
<div className="flex justify-end gap-3">
<button
onClick={() => setConfirm(null)}
className="px-4 py-2 text-sm border border-gray-300"
>
Cancel
</button>
<button
onClick={async () => {
await removeFromWishlist(confirm.productId).unwrap();
setConfirm(null);
}}
className="px-4 py-2 text-sm bg-gray-900 text-white"
>
Remove
</button>
</div>
</div>
</div>
)}
</div>
);
};
export default Wishlist;