ifixkart-storefront/components/WishlistModal.tsx

148 lines
5.9 KiB
TypeScript

"use client";
import React from 'react';
import { Heart, X, ShoppingCart } from 'lucide-react';
import Link from 'next/link';
import { useCartStore } from '@/store/cartStore';
import { getImageUrl, formatCurrency } from '@/lib/utils';
interface WishlistModalProps {
onClose: () => void;
}
export const WishlistModal: React.FC<WishlistModalProps> = ({ onClose }) => {
// Read directly from Zustand store — no localStorage mismatch
const wishlist = useCartStore((state) => state.wishlist);
const toggleWishlist = useCartStore((state) => state.toggleWishlist);
const addToCart = useCartStore((state) => state.addToCart);
React.useEffect(() => {
document.body.style.overflow = 'hidden';
const handleKeyDown = (e: KeyboardEvent) => {
if (e.key === 'Escape') onClose();
};
document.addEventListener('keydown', handleKeyDown);
return () => {
document.body.style.overflow = '';
document.removeEventListener('keydown', handleKeyDown);
};
}, [onClose]);
const handleMoveToCart = (product: any) => {
const variant = product.variants?.[0];
if (variant) {
addToCart(product, variant, 1);
toggleWishlist(product); // remove from wishlist
}
};
const getPrice = (product: any): number => {
return product.variants?.[0]?.price ?? 0;
};
const getImage = (product: any): string => {
const img = product.variants?.[0]?.images?.[0] ?? product.image ?? '';
return getImageUrl(img);
};
return (
<div
onClick={onClose}
className="fixed inset-0 bg-black/75 backdrop-blur-xs flex items-center justify-center z-[200] p-4 font-sans animate-in fade-in duration-200"
>
<div
onClick={(e) => e.stopPropagation()}
className="bg-white w-full max-w-[740px] rounded-2xl shadow-2xl overflow-hidden relative flex flex-col max-h-[85vh] text-left"
>
{/* Header */}
<div className="bg-[#1E1E1E] text-white px-7 py-4 flex items-center justify-between">
<h2 className="text-[16px] font-bold tracking-wide">
Wishlist ({wishlist.length})
</h2>
<button
onClick={onClose}
className="w-9 h-9 rounded-full flex items-center justify-center text-gray-400 hover:text-white transition-colors cursor-pointer -mr-2"
title="Close"
>
<X size={19} className="stroke-[2.5]" />
</button>
</div>
{/* Wishlist Items */}
{wishlist.length === 0 ? (
<div className="flex flex-col items-center justify-center py-20 text-gray-500 flex-grow bg-[#F8F9FB]">
<Heart size={40} className="text-gray-300 mb-3 stroke-[1.5]" />
<p className="text-[13px] font-semibold">Your wishlist is empty!</p>
<p className="text-[11px] text-gray-400 mt-1">Add items from the store to see them here.</p>
</div>
) : (
<div className="overflow-y-auto divide-y divide-gray-150 max-h-[495px] bg-white px-7 border-b border-gray-100">
{wishlist.map((product) => {
const price = getPrice(product);
const imgSrc = getImage(product);
const slug = product.slug ?? product.product_id;
return (
<div key={product.product_id} className="py-5 flex items-center gap-5 justify-between">
<div className="flex items-center gap-4 flex-grow min-w-0">
{/* Product Image */}
{imgSrc ? (
<img
src={imgSrc}
alt={product.name}
className="w-[72px] h-[72px] object-contain rounded-xl border border-gray-150 bg-white p-2 flex-shrink-0 shadow-xs"
/>
) : (
<div className="w-[72px] h-[72px] bg-gray-100 rounded-xl flex items-center justify-center text-gray-400 text-[10px] font-semibold flex-shrink-0">
No Image
</div>
)}
<div className="min-w-0 pr-2">
{/* Product Name */}
<Link
href={`/products/${slug}`}
onClick={onClose}
className="text-[15px] font-bold text-[#0073EC] hover:text-black line-clamp-1 block transition-colors leading-snug mb-1"
>
{product.name}
</Link>
{/* Price */}
<p className="text-[14.5px] font-extrabold text-gray-950 mb-1">
{formatCurrency(price)}
</p>
{/* SKU */}
<p className="text-xs text-gray-400 font-medium">
SKU: {product.variants?.[0]?.sku ?? '—'}
</p>
</div>
</div>
{/* Actions */}
<div className="flex items-center gap-3.5 flex-shrink-0">
<button
onClick={() => handleMoveToCart(product)}
className="bg-[#0073EC] hover:bg-black text-white text-[12.5px] font-bold px-5 py-3 rounded-xl transition-colors cursor-pointer select-none shadow-xs whitespace-nowrap flex items-center gap-2"
>
<ShoppingCart size={13} />
Move to Cart
</button>
<button
onClick={() => toggleWishlist(product)}
className="w-9 h-9 rounded-full flex items-center justify-center text-gray-400 hover:text-red-500 transition-colors cursor-pointer -mr-2"
title="Remove from Wishlist"
>
<X size={18} className="stroke-[2.5]" />
</button>
</div>
</div>
);
})}
</div>
)}
</div>
</div>
);
};