import { useState, useEffect } from 'react'; import { createPortal } from 'react-dom'; interface Props { productId: number; size?: 'sm' | 'md'; } export default function WatchlistButton({ productId, size = 'sm' }: Props) { const [isOnList, setIsOnList] = useState(false); const [loading, setLoading] = useState(false); const [user, setUser] = useState<{ id: string; email: string } | null>(null); const [showModal, setShowModal] = useState(false); const [email, setEmail] = useState(''); const [message, setMessage] = useState(''); const [targetPrice, setTargetPrice] = useState(''); useEffect(() => { // Check session fetch('/api/auth/session') .then(r => r.json()) .then(data => { if (data.user) { setUser(data.user); // Check if product is on watchlist fetch('/api/watchlist') .then(r => r.json()) .then(wl => { if (wl.items?.some((i: any) => i.product_id === productId)) { setIsOnList(true); } }) .catch(() => {}); } }) .catch(() => {}); }, [productId]); const handleClick = async (e: React.MouseEvent) => { e.preventDefault(); e.stopPropagation(); if (!user) { setShowModal(true); return; } setLoading(true); try { if (isOnList) { await fetch('/api/watchlist', { method: 'DELETE', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ product_id: productId }), }); setIsOnList(false); if ((window as any).__showToast) (window as any).__showToast('Verwijderd van watchlist', 'info'); } else { await fetch('/api/watchlist', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ product_id: productId, target_price: targetPrice ? parseFloat(targetPrice) : null, }), }); setIsOnList(true); if ((window as any).__showToast) (window as any).__showToast('Toegevoegd aan watchlist!', 'success'); } } catch {} setLoading(false); }; const handleRegister = async (e: React.FormEvent) => { e.preventDefault(); setLoading(true); setMessage(''); try { const res = await fetch('/api/auth/register', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ email }), }); const data = await res.json(); if (data.ok) { setMessage('Check je email! 📧'); } else if (data.error?.includes('al geregistreerd')) { // Try login instead const loginRes = await fetch('/api/auth/login', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ email }), }); const loginData = await loginRes.json(); setMessage(loginData.message || 'Check je email voor de inloglink!'); } else { setMessage(data.error || 'Er ging iets mis'); } } catch { setMessage('Er ging iets mis'); } setLoading(false); }; const iconSize = size === 'sm' ? 'w-5 h-5' : 'w-6 h-6'; const btnSize = size === 'sm' ? 'p-1.5' : 'p-2'; return ( <> {/* Email registration modal — Portal to body to escape card overflow */} {showModal && typeof document !== 'undefined' && createPortal(
{ if (e.target === e.currentTarget) setShowModal(false); }} >
e.stopPropagation()}>

Sneaker volgen

Voer je email in om deze sneaker op je watchlist te zetten en prijsalerts te ontvangen.

setEmail(e.target.value)} placeholder="je@email.nl" required className="mb-3 w-full rounded-lg border border-white/10 bg-white/5 px-4 py-2.5 text-white placeholder-white/30 focus:border-[#00FF6A]/50 focus:outline-none" />

Prijsalert (optioneel)

Mail mij onder € setTargetPrice(e.target.value)} placeholder="0,00" step="0.01" min="0" className="w-24 rounded-lg border border-white/10 bg-white/5 px-3 py-1.5 text-white placeholder-white/30 focus:border-[#00FF6A]/50 focus:outline-none" />
{message && (

{message}

)}
, document.body )} ); }