Remove email outbox collection and process job; refactor email templates with rich text support and slug generation

This commit is contained in:
2025-09-13 12:11:35 +02:00
parent ed9d979d3e
commit 3868e74770
34 changed files with 2674 additions and 374 deletions

View File

@@ -1,6 +1,7 @@
import { CollectionConfig } from 'payload/types'
import type { CollectionConfig, RichTextField } from 'payload'
import { lexicalEditor } from '@payloadcms/richtext-lexical'
const EmailTemplates: CollectionConfig = {
export const createEmailTemplatesCollection = (editor?: RichTextField['editor']): CollectionConfig => ({
slug: 'email-templates',
admin: {
useAsTitle: 'name',
@@ -22,84 +23,50 @@ const EmailTemplates: CollectionConfig = {
description: 'A descriptive name for this email template',
},
},
{
name: 'slug',
type: 'text',
required: true,
unique: true,
admin: {
description: 'Unique identifier for this template (e.g., "welcome-email", "password-reset")',
},
hooks: {
beforeChange: [
({ value }) => {
if (value) {
return value.toLowerCase().replace(/[^a-z0-9]/g, '-').replace(/-+/g, '-').replace(/^-|-$/g, '')
}
return value
},
],
},
},
{
name: 'subject',
type: 'text',
required: true,
admin: {
description: 'Email subject line (supports Handlebars variables)',
description: 'Email subject line. You can use Handlebars variables like {{firstName}} or {{siteName}}.',
},
},
{
name: 'htmlTemplate',
type: 'textarea',
name: 'content',
type: 'richText',
required: true,
editor: editor || lexicalEditor({
features: ({ defaultFeatures }) => [
...defaultFeatures,
],
}),
admin: {
description: 'HTML email template (supports Handlebars syntax)',
rows: 10,
},
},
{
name: 'textTemplate',
type: 'textarea',
admin: {
description: 'Plain text email template (supports Handlebars syntax)',
rows: 8,
},
},
{
name: 'variables',
type: 'array',
admin: {
description: 'Define variables that can be used in this template',
},
fields: [
{
name: 'name',
type: 'text',
required: true,
admin: {
description: 'Variable name (e.g., "firstName", "orderTotal")',
},
},
{
name: 'type',
type: 'select',
required: true,
options: [
{ label: 'Text', value: 'text' },
{ label: 'Number', value: 'number' },
{ label: 'Boolean', value: 'boolean' },
{ label: 'Date', value: 'date' },
],
defaultValue: 'text',
},
{
name: 'required',
type: 'checkbox',
defaultValue: false,
admin: {
description: 'Is this variable required when sending emails?',
},
},
{
name: 'description',
type: 'text',
admin: {
description: 'Optional description of what this variable represents',
},
},
],
},
{
name: 'previewData',
type: 'json',
admin: {
description: 'Sample data for previewing this template (JSON format)',
description: 'Email content with rich text formatting. Supports Handlebars variables like {{firstName}} and helpers like {{formatDate createdAt "long"}}. Content is converted to HTML and plain text automatically.',
},
},
],
timestamps: true,
}
})
// Default export for backward compatibility
const EmailTemplates = createEmailTemplatesCollection()
export default EmailTemplates

View File

@@ -1,11 +1,12 @@
import { CollectionConfig } from 'payload/types'
import type { CollectionConfig } from 'payload'
const EmailOutbox: CollectionConfig = {
slug: 'email-outbox',
const Emails: CollectionConfig = {
slug: 'emails',
admin: {
useAsTitle: 'subject',
defaultColumns: ['subject', 'to', 'status', 'scheduledAt', 'sentAt'],
group: 'Mailing',
description: 'Email delivery and status tracking',
},
access: {
read: () => true,
@@ -17,7 +18,7 @@ const EmailOutbox: CollectionConfig = {
{
name: 'template',
type: 'relationship',
relationTo: 'email-templates',
relationTo: 'email-templates' as const,
admin: {
description: 'Email template used (optional if custom content provided)',
},
@@ -26,22 +27,25 @@ const EmailOutbox: CollectionConfig = {
name: 'to',
type: 'text',
required: true,
hasMany: true,
admin: {
description: 'Recipient email address(es), comma-separated',
description: 'Recipient email addresses',
},
},
{
name: 'cc',
type: 'text',
hasMany: true,
admin: {
description: 'CC email address(es), comma-separated',
description: 'CC email addresses',
},
},
{
name: 'bcc',
type: 'text',
hasMany: true,
admin: {
description: 'BCC email address(es), comma-separated',
description: 'BCC email addresses',
},
},
{
@@ -161,20 +165,20 @@ const EmailOutbox: CollectionConfig = {
},
],
timestamps: true,
indexes: [
{
fields: {
status: 1,
scheduledAt: 1,
},
},
{
fields: {
priority: -1,
createdAt: 1,
},
},
],
// indexes: [
// {
// fields: {
// status: 1,
// scheduledAt: 1,
// },
// },
// {
// fields: {
// priority: -1,
// createdAt: 1,
// },
// },
// ],
}
export default EmailOutbox
export default Emails