354 lines
12 KiB
JavaScript
354 lines
12 KiB
JavaScript
// 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;
|