payload-plugin-newsletter 0.20.3 → 0.20.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +65 -0
- package/dist/admin.d.ts +25 -0
- package/dist/admin.js +92 -11
- package/dist/collections.cjs +1 -0
- package/dist/collections.cjs.map +1 -1
- package/dist/collections.js +1 -0
- package/dist/collections.js.map +1 -1
- package/dist/server.js +1 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,68 @@
|
|
|
1
|
+
## [0.20.5] - 2025-08-01
|
|
2
|
+
|
|
3
|
+
### Fixed
|
|
4
|
+
- **Manual Preview Button** - Replaced automatic preview with manual "Generate Preview" button
|
|
5
|
+
- Fixed content access issue where preview couldn't find content due to field group separation
|
|
6
|
+
- Changed from `data.content` to `fields?.contentSection?.content` using `useFormFields` hook
|
|
7
|
+
- Removed automatic hot-reloading in favor of user-controlled preview generation
|
|
8
|
+
- Added "Hide Preview" and "Refresh Preview" buttons for better control
|
|
9
|
+
- Preview now correctly accesses content from nested field groups
|
|
10
|
+
|
|
11
|
+
### Enhanced
|
|
12
|
+
- **Better Error Handling** - Clear error messages when no content is available
|
|
13
|
+
- **Improved UX** - Manual preview button prevents excessive API calls during content editing
|
|
14
|
+
- **Proper Form Data Access** - Uses Payload's `useFormFields` hook to access all form fields across groups
|
|
15
|
+
|
|
16
|
+
### Technical Changes
|
|
17
|
+
- Component now implements `UIFieldClientComponent` interface from Payload
|
|
18
|
+
- Removed automatic `useEffect` triggers and debouncing
|
|
19
|
+
- Fixed field path from `data.content` to `fields?.contentSection?.content`
|
|
20
|
+
- Maintains 600px iframe height for consistent preview display
|
|
21
|
+
|
|
22
|
+
## [0.20.4] - 2025-07-31
|
|
23
|
+
|
|
24
|
+
### Added
|
|
25
|
+
- **Email Preview Functionality Restored** - Full email preview functionality in admin interface
|
|
26
|
+
- Interactive preview component with live content updates
|
|
27
|
+
- Real-time iframe rendering of email HTML using the preview endpoint
|
|
28
|
+
- Debounced API calls to prevent excessive requests during content editing
|
|
29
|
+
- Auto-resizing iframe that adjusts to email content height
|
|
30
|
+
- Comprehensive error handling with user-friendly error messages
|
|
31
|
+
- Loading states and empty content placeholders for better UX
|
|
32
|
+
- Subject line display in preview header
|
|
33
|
+
- Preview updates automatically when content, subject, or preheader changes
|
|
34
|
+
|
|
35
|
+
### Enhanced
|
|
36
|
+
- **BroadcastInlinePreview Component**
|
|
37
|
+
- Replaced placeholder component with fully functional preview
|
|
38
|
+
- Added React hooks for state management (useState, useEffect, useRef)
|
|
39
|
+
- Integrated with existing `/api/broadcasts/preview` endpoint
|
|
40
|
+
- Added proper TypeScript types and interfaces
|
|
41
|
+
- Includes responsive iframe with cross-origin safety measures
|
|
42
|
+
- 500ms debounce to optimize API calls during content editing
|
|
43
|
+
|
|
44
|
+
### Fixed
|
|
45
|
+
- **Preview Endpoint Response Format** - Updated to include both `html` and `preview.html` fields for compatibility
|
|
46
|
+
- **ESLint Compliance** - Resolved all linting errors in admin components
|
|
47
|
+
- **Admin Bundle Integrity** - Maintained separation of server dependencies while restoring functionality
|
|
48
|
+
|
|
49
|
+
### Technical Changes
|
|
50
|
+
- Updated admin component exports to use direct type imports from components
|
|
51
|
+
- Removed redundant admin/types.ts file in favor of component-level type exports
|
|
52
|
+
- Enhanced preview endpoint to return HTML in multiple response formats
|
|
53
|
+
- Added proper error boundaries and loading states in preview component
|
|
54
|
+
- Maintained all architectural improvements from v0.20.3 bundle separation
|
|
55
|
+
|
|
56
|
+
### Validation
|
|
57
|
+
- ✅ Preview component fetches and displays email HTML correctly
|
|
58
|
+
- ✅ Preview updates in real-time as content changes
|
|
59
|
+
- ✅ Error states handled gracefully with retry capability
|
|
60
|
+
- ✅ Loading states provide good user experience
|
|
61
|
+
- ✅ Admin bundle contains no server dependencies
|
|
62
|
+
- ✅ All linting errors resolved
|
|
63
|
+
- ✅ Build and bundle validation passes
|
|
64
|
+
- ✅ TypeScript types are properly exported and available
|
|
65
|
+
|
|
1
66
|
## [0.20.3] - 2025-07-31
|
|
2
67
|
|
|
3
68
|
### Fixed
|
package/dist/admin.d.ts
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { UIFieldClientComponent } from 'payload';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
|
|
4
|
+
declare const BroadcastInlinePreview: UIFieldClientComponent;
|
|
5
|
+
interface BroadcastInlinePreviewProps {
|
|
6
|
+
data?: any;
|
|
7
|
+
field?: any;
|
|
8
|
+
path?: string;
|
|
9
|
+
schemaPath?: string;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
interface StatusBadgeProps {
|
|
13
|
+
cellData?: string;
|
|
14
|
+
rowData?: any;
|
|
15
|
+
}
|
|
16
|
+
declare const StatusBadge: React.FC<StatusBadgeProps>;
|
|
17
|
+
|
|
18
|
+
interface EmailPreviewProps {
|
|
19
|
+
content?: any;
|
|
20
|
+
subject?: string;
|
|
21
|
+
preheader?: string;
|
|
22
|
+
}
|
|
23
|
+
declare const EmailPreview: React.FC<EmailPreviewProps>;
|
|
24
|
+
|
|
25
|
+
export { BroadcastInlinePreview, type BroadcastInlinePreviewProps, EmailPreview, type EmailPreviewProps, StatusBadge, type StatusBadgeProps };
|
package/dist/admin.js
CHANGED
|
@@ -2,17 +2,98 @@
|
|
|
2
2
|
"use client";
|
|
3
3
|
|
|
4
4
|
// src/admin/components/BroadcastInlinePreview.tsx
|
|
5
|
-
import {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
5
|
+
import { useState, useCallback } from "react";
|
|
6
|
+
import { useFormFields } from "@payloadcms/ui";
|
|
7
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
8
|
+
var BroadcastInlinePreview = () => {
|
|
9
|
+
const [preview, setPreview] = useState("");
|
|
10
|
+
const [loading, setLoading] = useState(false);
|
|
11
|
+
const [showPreview, setShowPreview] = useState(false);
|
|
12
|
+
const [error, setError] = useState(null);
|
|
13
|
+
const fields = useFormFields(([fields2]) => fields2);
|
|
14
|
+
const generatePreview = useCallback(async () => {
|
|
15
|
+
try {
|
|
16
|
+
setLoading(true);
|
|
17
|
+
setError(null);
|
|
18
|
+
const contentSection = fields?.contentSection;
|
|
19
|
+
const contentValue = contentSection?.content?.value;
|
|
20
|
+
if (!contentValue) {
|
|
21
|
+
setError("No content available to preview");
|
|
22
|
+
setLoading(false);
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
const response = await fetch("/api/broadcasts/preview", {
|
|
26
|
+
method: "POST",
|
|
27
|
+
headers: { "Content-Type": "application/json" },
|
|
28
|
+
body: JSON.stringify({ content: contentValue })
|
|
29
|
+
});
|
|
30
|
+
if (!response.ok) {
|
|
31
|
+
throw new Error(`Preview failed: ${response.statusText}`);
|
|
32
|
+
}
|
|
33
|
+
const data = await response.json();
|
|
34
|
+
setPreview(data.html || "");
|
|
35
|
+
setShowPreview(true);
|
|
36
|
+
} catch (err) {
|
|
37
|
+
console.error("Preview generation error:", err);
|
|
38
|
+
setError(err instanceof Error ? err.message : "Failed to generate preview");
|
|
39
|
+
} finally {
|
|
40
|
+
setLoading(false);
|
|
41
|
+
}
|
|
42
|
+
}, [fields]);
|
|
43
|
+
return /* @__PURE__ */ jsxs("div", { className: "field-type", children: [
|
|
44
|
+
/* @__PURE__ */ jsx("div", { className: "field-label", children: "Email Preview" }),
|
|
45
|
+
!showPreview ? /* @__PURE__ */ jsxs("div", { className: "preview-controls", children: [
|
|
46
|
+
/* @__PURE__ */ jsx(
|
|
47
|
+
"button",
|
|
48
|
+
{
|
|
49
|
+
type: "button",
|
|
50
|
+
onClick: generatePreview,
|
|
51
|
+
disabled: loading,
|
|
52
|
+
className: "btn btn--style-primary btn--icon-style-without-border btn--size-small",
|
|
53
|
+
style: { marginBottom: "1rem" },
|
|
54
|
+
children: loading ? "Generating Preview..." : "Generate Preview"
|
|
55
|
+
}
|
|
56
|
+
),
|
|
57
|
+
error && /* @__PURE__ */ jsx("div", { className: "error-message", style: { color: "#dc2626", marginTop: "0.5rem" }, children: error })
|
|
58
|
+
] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
59
|
+
/* @__PURE__ */ jsxs("div", { className: "preview-controls", style: { marginBottom: "1rem" }, children: [
|
|
60
|
+
/* @__PURE__ */ jsx(
|
|
61
|
+
"button",
|
|
62
|
+
{
|
|
63
|
+
type: "button",
|
|
64
|
+
onClick: () => setShowPreview(false),
|
|
65
|
+
className: "btn btn--style-secondary btn--icon-style-without-border btn--size-small",
|
|
66
|
+
style: { marginRight: "0.5rem" },
|
|
67
|
+
children: "Hide Preview"
|
|
68
|
+
}
|
|
69
|
+
),
|
|
70
|
+
/* @__PURE__ */ jsx(
|
|
71
|
+
"button",
|
|
72
|
+
{
|
|
73
|
+
type: "button",
|
|
74
|
+
onClick: generatePreview,
|
|
75
|
+
disabled: loading,
|
|
76
|
+
className: "btn btn--style-primary btn--icon-style-without-border btn--size-small",
|
|
77
|
+
children: loading ? "Regenerating..." : "Refresh Preview"
|
|
78
|
+
}
|
|
79
|
+
)
|
|
80
|
+
] }),
|
|
81
|
+
/* @__PURE__ */ jsx("div", { className: "email-preview-container", children: /* @__PURE__ */ jsx(
|
|
82
|
+
"iframe",
|
|
83
|
+
{
|
|
84
|
+
srcDoc: preview,
|
|
85
|
+
style: {
|
|
86
|
+
width: "100%",
|
|
87
|
+
height: "600px",
|
|
88
|
+
border: "1px solid #e5e7eb",
|
|
89
|
+
borderRadius: "0.375rem",
|
|
90
|
+
backgroundColor: "white"
|
|
91
|
+
},
|
|
92
|
+
title: "Email Preview"
|
|
93
|
+
}
|
|
94
|
+
) })
|
|
95
|
+
] })
|
|
96
|
+
] });
|
|
16
97
|
};
|
|
17
98
|
|
|
18
99
|
// src/admin/components/StatusBadge.tsx
|
package/dist/collections.cjs
CHANGED