first commit

This commit is contained in:
2026-03-10 14:47:34 +05:30
commit c504876102
198 changed files with 17343 additions and 0 deletions

View File

@@ -0,0 +1,353 @@
// 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;