'use client' import { submitCampaignNewsletter } from '@/app/(frontend)/actions/submitCampaignNewsletter' import { CitySelect } from '@/components/CitySelect' import { EmailInput } from '@/components/EmailInput' import { NameInput } from '@/components/NameInput' import { PhoneInput } from '@/components/PhoneInput' import { StateSelect } from '@/components/StateSelect' import { Button } from '@/components/ui/button' import { Checkbox } from '@/components/ui/Checkbox' import { Field, FieldDescription, FieldError, FieldGroup } from '@/components/ui/field' import { Textarea } from '@/components/ui/textarea' import { trackMetaLead } from '@/lib/facebookPixel' import { CampaignNewsletterInput, campaignNewsletterSchema } from '@/lib/schemas/campaignNewsletter' import { zodResolver } from '@hookform/resolvers/zod' import { CheckIcon } from 'lucide-react' import { useState, useTransition } from 'react' import { FormProvider, SubmitHandler, useForm, useWatch } from 'react-hook-form' /** S10 — stable `content_name` for the `Lead` fired on a successful capture. */ const NEWSLETTER_LEAD_CONTENT_NAME = 'novidades-da-campanha' interface CampaignNewsletterFormProps { pixelId?: string onSubmit: () => void } /** * S9 — public capture of campaign "novidades" on the home: name + WhatsApp * required, email/state/city/comment optional, engagement-level toggle * pre-selected ("Quero fazer parte do time"). Success swaps the form for an * in-place confirmation (the seam where S10 fires `Lead`). */ const CampaignNewsletterForm = ({ pixelId, onSubmit }: CampaignNewsletterFormProps) => { const methods = useForm({ resolver: zodResolver(campaignNewsletterSchema), defaultValues: { name: '', phone: '', email: '', state: undefined, city: '', comment: '', campaignLevel: 'time', }, }) const [isSubmitting, startTransition] = useTransition() const handleSubmit: SubmitHandler = (input) => { startTransition(async () => { try { await submitCampaignNewsletter(input) // S10 — exactly one `Lead` per successful capture, never on page load // (petition precedent). The inner guard keeps a tracking hiccup (e.g. // `crypto.randomUUID` on a non-secure context) from turning an // already-committed capture into the error UI; `trackMetaLead` // no-ops safely without fbq. if (pixelId) { try { trackMetaLead(pixelId, NEWSLETTER_LEAD_CONTENT_NAME, crypto.randomUUID()) } catch { // tracking is invisible to the visitor } } methods.reset() onSubmit() } catch (error) { console.log(error) methods.setError('root', { message: 'Falha ao enviar. Tente novamente.', }) } }) } const campaignLevel = useWatch({ control: methods.control, name: 'campaignLevel' }) return (