UNPKG

payload-plugin-newsletter

Version:

Complete newsletter management plugin for Payload CMS with subscriber management, magic link authentication, and email service integration

196 lines (192 loc) 6.26 kB
"use client"; "use client"; // src/admin/components/BroadcastInlinePreview.tsx import { useState, useCallback } from "react"; import { useFormFields } from "@payloadcms/ui"; import { Fragment, jsx, jsxs } from "react/jsx-runtime"; var BroadcastInlinePreview = () => { const [preview, setPreview] = useState(""); const [loading, setLoading] = useState(false); const [showPreview, setShowPreview] = useState(false); const [error, setError] = useState(null); const fields = useFormFields(([fields2]) => fields2); const generatePreview = useCallback(async () => { try { setLoading(true); setError(null); const contentField = fields?.["contentSection.content"]; const contentValue = contentField?.value; if (!contentValue) { setError("No content available to preview"); setLoading(false); return; } const documentData = {}; Object.entries(fields || {}).forEach(([key, field]) => { if (field && typeof field === "object" && "value" in field) { documentData[key] = field.value; } }); const response = await fetch("/api/broadcasts/preview", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ content: contentValue, documentData // Pass all form data }) }); if (!response.ok) { throw new Error(`Preview failed: ${response.statusText}`); } const data = await response.json(); setPreview(data.html || ""); setShowPreview(true); } catch (err) { console.error("Preview generation error:", err); setError(err instanceof Error ? err.message : "Failed to generate preview"); } finally { setLoading(false); } }, [fields]); return /* @__PURE__ */ jsxs("div", { className: "field-type", children: [ /* @__PURE__ */ jsx("div", { className: "field-label", children: "Email Preview" }), !showPreview ? /* @__PURE__ */ jsxs("div", { className: "preview-controls", children: [ /* @__PURE__ */ jsx( "button", { type: "button", onClick: generatePreview, disabled: loading, className: "btn btn--style-primary btn--icon-style-without-border btn--size-small", style: { marginBottom: "1rem" }, children: loading ? "Generating Preview..." : "Generate Preview" } ), error && /* @__PURE__ */ jsx("div", { className: "error-message", style: { color: "#dc2626", marginTop: "0.5rem" }, children: error }) ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [ /* @__PURE__ */ jsxs("div", { className: "preview-controls", style: { marginBottom: "1rem" }, children: [ /* @__PURE__ */ jsx( "button", { type: "button", onClick: () => setShowPreview(false), className: "btn btn--style-secondary btn--icon-style-without-border btn--size-small", style: { marginRight: "0.5rem" }, children: "Hide Preview" } ), /* @__PURE__ */ jsx( "button", { type: "button", onClick: generatePreview, disabled: loading, className: "btn btn--style-primary btn--icon-style-without-border btn--size-small", children: loading ? "Regenerating..." : "Refresh Preview" } ) ] }), /* @__PURE__ */ jsx("div", { className: "email-preview-container", children: /* @__PURE__ */ jsx( "iframe", { srcDoc: preview, style: { width: "100%", height: "600px", border: "1px solid #e5e7eb", borderRadius: "0.375rem", backgroundColor: "white" }, title: "Email Preview" } ) }) ] }) ] }); }; // src/admin/components/StatusBadge.tsx import { jsx as jsx2 } from "react/jsx-runtime"; var StatusBadge = (props) => { const status = props.cellData || "draft"; const getStatusColor = (status2) => { switch (status2) { case "sent": return "#22c55e"; case "scheduled": return "#3b82f6"; case "draft": return "#6b7280"; case "failed": return "#ef4444"; default: return "#6b7280"; } }; const getStatusLabel = (status2) => { switch (status2) { case "sent": return "Sent"; case "scheduled": return "Scheduled"; case "draft": return "Draft"; case "failed": return "Failed"; default: return status2; } }; return /* @__PURE__ */ jsx2( "span", { style: { display: "inline-block", padding: "4px 8px", borderRadius: "12px", fontSize: "12px", fontWeight: "500", color: "#fff", backgroundColor: getStatusColor(status), textTransform: "capitalize" }, children: getStatusLabel(status) } ); }; // src/admin/components/EmailPreview.tsx import { jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime"; var EmailPreview = ({ content, subject, preheader }) => { return /* @__PURE__ */ jsxs2("div", { className: "email-preview", style: { padding: "1rem" }, children: [ /* @__PURE__ */ jsxs2("div", { style: { marginBottom: "1rem" }, children: [ /* @__PURE__ */ jsx3("strong", { children: "Subject:" }), " ", subject || "No subject" ] }), preheader && /* @__PURE__ */ jsxs2("div", { style: { marginBottom: "1rem", color: "#666" }, children: [ /* @__PURE__ */ jsx3("strong", { children: "Preheader:" }), " ", preheader ] }), /* @__PURE__ */ jsxs2("div", { style: { border: "1px solid #e0e0e0", borderRadius: "4px", padding: "1rem", backgroundColor: "#f9f9f9" }, children: [ /* @__PURE__ */ jsx3("div", { children: "Email content will be rendered here" }), content && /* @__PURE__ */ jsxs2("div", { style: { marginTop: "1rem", fontSize: "14px", color: "#666" }, children: [ "Content type: ", typeof content ] }) ] }) ] }); }; export { BroadcastInlinePreview, EmailPreview, StatusBadge };