import { useState, useEffect } from 'react'; declare global { interface Window { dataLayer: Record[]; } } function pushIdentify(email: string, authLevel: 'full' | 'soft' = 'soft') { if (typeof window === 'undefined') return; window.dataLayer = window.dataLayer || []; window.dataLayer.push({ event: 'user_identified', user_email: email, auth_level: authLevel }); } interface Props { productId: number; currentLowestPrice: number; productName: string; productSlug?: string; } export default function PriceAlertForm({ productId, currentLowestPrice, productName, productSlug }: Props) { const [user, setUser] = useState<{ id: string; email: string } | null>(null); const [email, setEmail] = useState(''); const [targetPrice, setTargetPrice] = useState( (Math.floor(currentLowestPrice * 0.9 * 100) / 100).toFixed(2).replace('.', ',') ); const [loading, setLoading] = useState(false); const [success, setSuccess] = useState(false); const [message, setMessage] = useState(''); const [isOnWatchlist, setIsOnWatchlist] = useState(false); const [expanded, setExpanded] = useState(false); const [verifiedBanner, setVerifiedBanner] = useState(false); const [consent, setConsent] = useState(false); // Detect ?verified=1 in URL useEffect(() => { const params = new URLSearchParams(window.location.search); if (params.get('verified') === '1') { setVerifiedBanner(true); // Clean up URL params.delete('verified'); const newUrl = params.toString() ? `${window.location.pathname}?${params.toString()}` : window.location.pathname; window.history.replaceState({}, '', newUrl); } }, []); // Read sp_email cookie to pre-fill for returning visitors useEffect(() => { if (!email) { const match = document.cookie.match(/(?:^|;\s*)sp_email=([^;]+)/); if (match) setEmail(decodeURIComponent(match[1])); } }, []); useEffect(() => { const getSession = (window as any).__spSession || (() => fetch('/api/auth/session').then(r => r.json())); getSession() .then((data: any) => { if (data.user) { setUser(data.user); setEmail(data.user.email); // Identify in dataLayer now that we know the email from the session document.cookie = `sp_email=${encodeURIComponent(data.user.email)}; Max-Age=${365 * 86400}; Path=/; SameSite=Lax`; pushIdentify(data.user.email, 'full'); // Check if already on watchlist fetch('/api/watchlist') .then(r => r.json()) .then(wl => { const item = wl.items?.find((i: any) => i.product_id === productId); if (item) { setIsOnWatchlist(true); if (item.target_price) { setTargetPrice(item.target_price.toFixed(2).replace('.', ',')); } } }) .catch(() => {}); } }) .catch(() => {}); }, [productId]); const parsePrice = (val: string) => parseFloat(val.replace(',', '.')); const handleSubmit = async (e: React.FormEvent) => { e.preventDefault(); setLoading(true); setMessage(''); const price = parsePrice(targetPrice); if (isNaN(price) || price <= 0) { setMessage('Voer een geldig bedrag in'); setLoading(false); return; } try { // Persist email + identify — runs for every submit regardless of auth state if (email) { document.cookie = `sp_email=${encodeURIComponent(email)}; Max-Age=${365 * 86400}; Path=/; SameSite=Lax`; pushIdentify(email, user ? 'full' : 'soft'); } // If no user, register first if (!user) { const returnTo = productSlug ? `/sneakers/${productSlug}` : undefined; const regRes = await fetch('/api/auth/register', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ email, return_to: returnTo }), }); const regData = await regRes.json(); if (regData.error && !regData.error.includes('al geregistreerd')) { setMessage(regData.error); setLoading(false); return; } // If already registered, send login link if (regData.error?.includes('al geregistreerd')) { await fetch('/api/auth/login', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ email }), }); } setSuccess(true); setMessage('Check je email om je account te bevestigen. Daarna is je prijsalert actief!'); setLoading(false); return; } // User is logged in — add to watchlist with target price const res = await fetch('/api/watchlist', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ product_id: productId, target_price: price, }), }); if (res.ok) { setSuccess(true); setIsOnWatchlist(true); setMessage(`Je ontvangt een mail als de prijs onder €${targetPrice} komt`); } else { const data = await res.json(); setMessage(data.error || 'Er ging iets mis'); } } catch { setMessage('Er ging iets mis, probeer het opnieuw'); } setLoading(false); }; if (verifiedBanner) { return (

Email bevestigd!

Je prijsalert voor {productName} is nu actief. We mailen je zodra de prijs daalt!

); } if (success && isOnWatchlist) { return (

Prijsalert actief

We mailen je zodra de {productName} onder{' '} €{targetPrice} zakt.

); } return (
{expanded && (
Huidige laagste prijs: €{currentLowestPrice.toFixed(2).replace('.', ',')}
setTargetPrice(e.target.value)} className="w-full rounded-xl border border-border bg-bg-elevated pl-8 pr-4 py-3 text-lg font-bold placeholder-text-muted focus:border-accent/50 focus:outline-none" placeholder="0,00" required />
{!user && ( <>
setEmail(e.target.value)} placeholder="je@email.nl" required className="w-full rounded-xl border border-border bg-bg-elevated px-4 py-3 placeholder-text-muted focus:border-accent/50 focus:outline-none" />
)} {message && (

{message}

)}
)}
); }