'use client'; import { useMemo, useState } from 'react'; import Image from 'next/image'; import { usePreviewStepLocalizedContent, useFunnel, } from '@funnelsgrove/runtime'; import type { FunnelStepMeta } from '@funnelsgrove/runtime'; import { emailCaptureContent } from '@/steps/content/email-capture.content'; import { getStepContentLocale } from '@/runtime/step-content-context'; import { funnelManifest } from '@/config/funnel.manifest'; export const stepEmailCaptureId = 'email-capture'; export const stepEmailCapture: FunnelStepMeta = { id: stepEmailCaptureId, name: 'email-capture', type: 'form_input', figmaNodeId: 'template-31-email-capture', title: 'Email Capture', description: 'Canonical unique email identity used before checkout and returning-subscriber lookup.', actionBar: { hidden: true, }, }; export function StepEmailCapture() { const { user, attributes, submitEmailCapture } = useFunnel(); const content = usePreviewStepLocalizedContent( stepEmailCaptureId, emailCaptureContent, getStepContentLocale(attributes), ); const [email, setEmail] = useState(user.email); const [error, setError] = useState(null); const [submitting, setSubmitting] = useState(false); const previewAsset = funnelManifest.assets.emailCapturePreview; const isValidEmail = useMemo(() => /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email), [email]); const handleSubmit = async () => { if (!isValidEmail || submitting) { return; } setSubmitting(true); setError(null); try { await submitEmailCapture(email); } catch (submitError) { const message = submitError instanceof Error ? submitError.message : content.saveErrorMessage; setError(message); } finally { setSubmitting(false); } }; return ( <>

{content.kicker}

{content.title}

{content.description}

{error ?

{error}

: null}
); } const stepEmailCaptureStyles = ` .template-email-capture-step { position: absolute; inset: 0; display: flex; flex-direction: column; gap: 24px; padding: 96px var(--padding) 32px; background: #f5f7fa; color: #262729; overflow-y: auto; } .template-email-capture-copy { display: flex; flex-direction: column; gap: 12px; } .template-email-capture-preview { width: 120px; height: 90px; object-fit: contain; } .template-email-capture-kicker { margin: 0; color: #556070; font-size: 13px; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase; } .template-email-capture-title { margin: 0; font-size: 32px; font-weight: 800; line-height: 1.08; letter-spacing: -0.03em; } .template-email-capture-text { margin: 0; color: #5d6674; font-size: 16px; line-height: 1.5; } .template-email-capture-field-wrap { display: flex; flex-direction: column; gap: 10px; } .template-email-capture-label { color: #262729; font-size: 14px; font-weight: 600; } .template-email-capture-field { width: 100%; height: 52px; border: 1px solid rgb(17 17 19 / 16%); border-radius: 14px; background: #fff; padding: 0 16px; color: #262729; font-size: 16px; font-weight: 400; } .template-email-capture-field::placeholder { color: rgb(17 17 19 / 42%); } .template-email-capture-field:focus { outline: none; border-color: rgb(67 97 238 / 52%); box-shadow: 0 0 0 4px rgb(67 97 238 / 10%); } .template-email-capture-error { margin: -8px 0 0; color: #c43737; font-size: 14px; font-weight: 600; line-height: 1.35; } .template-email-capture-action { margin-top: auto; padding-top: 8px; } `;