Files
shahikitchen-prod/components/WishlistDrawer.tsx
T

172 lines
6.6 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
'use client';
import Link from 'next/link';
import { Heart, ShoppingBag } from 'lucide-react';
import { useWishlist } from '@/presentation/providers/wishlist-provider';
import { useCart } from '@/presentation/providers/cart-provider';
import { useLanguage } from '@/presentation/providers/language-provider';
import { getTranslation } from '@/presentation/i18n/translations';
import { getMenuPosterSrc, applyNextImageFallback, getMenuPosterCandidates } from '@/lib/assets';
import { getMenuItemById } from '@/lib/menu-data';
import { buildCartLineFromMenuItem } from '@/application/cart/cart-line-builder';
export default function WishlistDrawer() {
const {
items,
isOpen,
closeWishlist,
removeFromWishlist,
clearWishlist,
} = useWishlist();
const { addToCart } = useCart();
const { language } = useLanguage();
const t = getTranslation(language);
if (!isOpen) return null;
const handleAddToCart = (item: (typeof items)[number]) => {
const menuItem = getMenuItemById(item.id);
addToCart(menuItem ? buildCartLineFromMenuItem(menuItem) : {
id: item.id,
name: item.name,
price: item.price,
image: item.image,
pricingMode: 'standard',
});
};
return (
<>
<div
className="fixed inset-0 bg-black/40 z-[985]"
onClick={closeWishlist}
/>
<div className="fixed top-0 right-0 h-full w-full max-w-md bg-[#F8F5F0] z-[985] shadow-2xl flex flex-col">
<div className="flex items-center justify-between p-6 border-b border-[#EDE6D9]">
<div className="flex items-center gap-3">
<Heart className="h-5 w-5 text-[#c99a2e] fill-[#c99a2e]/20" />
<h2 className="text-2xl tracking-[-0.5px] text-[#101724]">{t.wishlistDrawer.title}</h2>
{items.length > 0 && (
<span className="text-xs px-2.5 py-0.5 rounded-full bg-[#EDE6D9] text-[#6B665F]">
{items.length} {items.length === 1 ? t.wishlistDrawer.item : t.wishlistDrawer.items}
</span>
)}
</div>
<div className="flex items-center gap-3">
{items.length > 0 && (
<button
onClick={clearWishlist}
className="text-xs text-[#B38B4D] hover:underline"
>
{t.wishlistDrawer.clear}
</button>
)}
<button
onClick={closeWishlist}
className="text-[#6B665F] hover:text-[#2C2A26] text-2xl leading-none pl-1"
aria-label="Close wishlist"
>
×
</button>
</div>
</div>
<div className="flex-1 overflow-y-auto p-6">
{items.length === 0 ? (
<div className="flex flex-col items-center justify-center h-full text-center">
<Heart className="h-16 w-16 text-[#c99a2e]/30 mb-4" />
<p className="text-lg text-[#6B665F]">{t.wishlistDrawer.empty}</p>
<Link
href="/menu"
onClick={closeWishlist}
className="mt-6 text-[#B38B4D] hover:underline"
>
{t.wishlistDrawer.browseMenu}
</Link>
</div>
) : (
<div className="space-y-5">
{items.map((item) => (
<div
key={item.id}
className="flex gap-4 rounded-2xl border border-[#EDE6D9] bg-white p-4"
>
<div className="h-20 w-20 shrink-0 overflow-hidden rounded-xl bg-[#F2EDE4]">
<img
src={getMenuPosterSrc(item)}
alt={item.name}
className="h-full w-full object-cover"
loading="lazy"
onError={(e) => {
applyNextImageFallback(
e.target as HTMLImageElement,
getMenuPosterCandidates(item),
(e.target as HTMLImageElement).src
);
}}
/>
</div>
<div className="flex-1 min-w-0">
<div className="flex justify-between gap-2">
<h4 className="font-medium tracking-[-0.3px] text-[#101724] truncate">
{item.name}
</h4>
<span className="shrink-0 text-right font-medium text-[#B38B4D] tabular-nums text-sm leading-tight">
{(() => {
const menuItem = getMenuItemById(item.id);
if (menuItem?.pricing === 'weight') {
return (
<>
<span className="block">{menuItem.pricePerHalfKg} kr / ½ kg</span>
<span className="block text-xs text-[#8A8478]">{menuItem.pricePerKg} {t.menu.perKg}</span>
</>
);
}
return <span>{item.price} kr</span>;
})()}
</span>
</div>
<div className="flex items-center gap-2 mt-3">
<button
onClick={() => handleAddToCart(item)}
className="inline-flex items-center gap-1.5 rounded-full bg-gradient-to-r from-[#c99a2e] to-[#d4a73d] px-4 py-2 text-xs font-bold text-[#241806] transition-all hover:scale-[1.02] active:scale-[0.98]"
>
<ShoppingBag className="h-3.5 w-3.5" />
{t.wishlistDrawer.addToCart}
</button>
<button
onClick={() => removeFromWishlist(item.id)}
className="text-xs text-[#B38B4D] hover:underline ml-auto"
>
{t.wishlistDrawer.remove}
</button>
</div>
</div>
</div>
))}
</div>
)}
</div>
{items.length > 0 && (
<div className="p-6 border-t border-[#EDE6D9] bg-white">
<p className="text-xs text-center text-[#6B665F] mb-4">
{t.wishlistDrawer.hint}
</p>
<Link
href="/menu"
onClick={closeWishlist}
className="block w-full text-center text-sm text-[#B38B4D] hover:underline"
>
{t.wishlistDrawer.continueBrowsing}
</Link>
</div>
)}
</div>
</>
);
}