import { ComponentConfig } from "@reacteditor/core"; import { useState } from "react"; import { Mail } from "lucide-react"; import { cn } from "~/editor/lib/utils"; import { Typography } from "~/editor/theme/Typography"; export type NewsletterCtaProps = { tagline: string; heading: string; subheading: string; buttonLabel: string; endpoint: string; imageUrl: string; layout: "split" | "stacked"; }; function NewsletterCta({ tagline, heading, subheading, buttonLabel, endpoint, imageUrl, layout, }: NewsletterCtaProps) { const [email, setEmail] = useState(""); const [submitted, setSubmitted] = useState(false); const [submitting, setSubmitting] = useState(false); const submit = async (e: React.FormEvent) => { e.preventDefault(); if (!email) return; setSubmitting(true); try { if (endpoint) { await fetch(endpoint, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ email }), }); } setSubmitted(true); } catch { setSubmitted(true); } finally { setSubmitting(false); } }; const Form = (
setEmail(e.target.value)} placeholder="you@example.com" className="flex-1 bg-transparent py-3 text-sm placeholder:text-muted-foreground focus:outline-none" />
); if (layout === "split") { return (
{imageUrl ? ( ) : null}
{tagline ? (

{tagline}

) : null} {heading} {subheading ? ( {subheading} ) : null}
{submitted ? (

Thanks — we'll be in touch.

) : ( Form )}
); } return (
{tagline ? (

{tagline}

) : null} {heading} {subheading ? ( {subheading} ) : null}
{submitted ? (

Thanks — we'll be in touch.

) : ( Form )}
); } export const newsletterCtaEditor: ComponentConfig = { label: "Newsletter", icon: , category: "content", defaultProps: { tagline: "Stay in the loop", heading: "Letters from the studio", subheading: "New collections, mill stories, and the occasional invitation to in-person events. Twice a month.", buttonLabel: "Subscribe", endpoint: "", imageUrl: "https://images.unsplash.com/photo-1469334031218-e382a71b716b?auto=format&fit=crop&w=1800&q=80", layout: "split", }, fields: { tagline: { label: "Tagline", type: "text", contentEditable: true }, heading: { label: "Heading", type: "text", contentEditable: true }, subheading: { label: "Subheading", type: "textarea", contentEditable: true }, buttonLabel: { label: "Button label", type: "text", contentEditable: true }, endpoint: { label: "Submit endpoint", type: "text" }, imageUrl: { label: "Image URL", type: "text" }, layout: { label: "Layout", type: "radio", options: [ { label: "Split (image + form)", value: "split" }, { label: "Stacked (centered)", value: "stacked" }, ], }, }, render: (props) => , };