"use client"; import { useEffect, useMemo, useState } from "react"; type AncillaryPage = { id: string; seoTitle: string | null; seoDescription: string | null; content: string | null; }; function stripHtml(input: string) { return input.replace(/<[^>]*>/g, "").trim(); } function parseEditorJsText(raw: string | null | undefined): string { if (!raw) return ""; try { const json = JSON.parse(raw) as { blocks?: Array<{ type?: string; data?: { text?: string } }>; }; const blocks = Array.isArray(json?.blocks) ? json.blocks : []; const paragraph = blocks.find((b) => b?.type === "paragraph"); const html = paragraph?.data?.text || ""; return stripHtml(html); } catch { return stripHtml(raw); } } const DISMISS_KEY = "saleor_template_basic.newsletter_popup_dismissed_at"; const DEFAULT_DELAY_MS = 2500; const DEFAULT_TTL_DAYS = 14; export default function NewsletterPopup() { const [open, setOpen] = useState(false); const [page, setPage] = useState(null); const [email, setEmail] = useState(""); const [submitting, setSubmitting] = useState(false); const [error, setError] = useState(null); const [success, setSuccess] = useState(false); const title = page?.seoTitle || "Newsletter"; const description = useMemo(() => parseEditorJsText(page?.content), [page]); useEffect(() => { const shouldShow = () => { try { const raw = localStorage.getItem(DISMISS_KEY); if (!raw) return true; const dismissedAt = Number(raw); if (!Number.isFinite(dismissedAt)) return true; const ttlMs = DEFAULT_TTL_DAYS * 24 * 60 * 60 * 1000; return Date.now() - dismissedAt > ttlMs; } catch { return true; } }; if (!shouldShow()) return; const t = window.setTimeout(() => { fetch("/api/page/newsletter") .then(async (r) => { if (!r.ok) return null; return (await r.json()) as AncillaryPage; }) .then((p) => { if (!p) return; setPage(p); setOpen(true); }) .catch(() => { // If Saleor isn't configured or page isn't present, do nothing. }); }, DEFAULT_DELAY_MS); return () => window.clearTimeout(t); }, []); const close = () => { setOpen(false); try { localStorage.setItem(DISMISS_KEY, String(Date.now())); } catch { // ignore } }; const submit = async () => { setSubmitting(true); setError(null); setSuccess(false); try { const resp = await fetch("/api/form-submission", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ formType: "newsletter", pageSlug: "newsletter", data: { email }, timestamp: new Date().toISOString(), }), }); if (!resp.ok) { const j = (await resp.json().catch(() => null)) as { message?: string } | null; throw new Error(j?.message || "Failed to subscribe"); } setSuccess(true); setEmail(""); // Dismiss for longer after a successful subscription. try { localStorage.setItem(DISMISS_KEY, String(Date.now())); } catch { // ignore } } catch (e) { setError(e instanceof Error ? e.message : "Failed to subscribe"); } finally { setSubmitting(false); } }; if (!open) return null; return (
setEmail(e.target.value)} type="email" placeholder="you@example.com" className="mt-2 w-full rounded-md border border-gray-300 px-3 py-2 text-sm outline-none focus:ring-2 focus:ring-[var(--color-primary-600)]" /> {error ? (

{error}

) : null} {success ? (

Subscribed. Thank you.

) : null}
); }